diff options
author | David S. Miller <davem@davemloft.net> | 2012-08-22 17:21:38 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-08-22 17:21:38 -0400 |
commit | 1304a7343b30fc4f16045412efdbb4179a3d9255 (patch) | |
tree | 83d667ac4f62e30f70305ce4cc7e030e3465f92e | |
parent | 1d76efe1577b4323609b1bcbfafa8b731eda071a (diff) | |
parent | 23dcfa61bac244e1200ff9ad19c6e9144dcb6bb5 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
886 files changed, 12050 insertions, 7460 deletions
diff --git a/Documentation/ABI/testing/sysfs-platform-ideapad-laptop b/Documentation/ABI/testing/sysfs-platform-ideapad-laptop index 814b01354c41..b31e782bd985 100644 --- a/Documentation/ABI/testing/sysfs-platform-ideapad-laptop +++ b/Documentation/ABI/testing/sysfs-platform-ideapad-laptop | |||
@@ -5,4 +5,15 @@ Contact: "Ike Panhc <ike.pan@canonical.com>" | |||
5 | Description: | 5 | Description: |
6 | Control the power of camera module. 1 means on, 0 means off. | 6 | Control the power of camera module. 1 means on, 0 means off. |
7 | 7 | ||
8 | What: /sys/devices/platform/ideapad/fan_mode | ||
9 | Date: June 2012 | ||
10 | KernelVersion: 3.6 | ||
11 | Contact: "Maxim Mikityanskiy <maxtram95@gmail.com>" | ||
12 | Description: | ||
13 | Change fan mode | ||
14 | There are four available modes: | ||
15 | * 0 -> Super Silent Mode | ||
16 | * 1 -> Standard Mode | ||
17 | * 2 -> Dust Cleaning | ||
18 | * 4 -> Efficient Thermal Dissipation Mode | ||
8 | 19 | ||
diff --git a/Documentation/DocBook/filesystems.tmpl b/Documentation/DocBook/filesystems.tmpl index 3fca32c41927..25b58efd955d 100644 --- a/Documentation/DocBook/filesystems.tmpl +++ b/Documentation/DocBook/filesystems.tmpl | |||
@@ -224,8 +224,8 @@ all your transactions. | |||
224 | </para> | 224 | </para> |
225 | 225 | ||
226 | <para> | 226 | <para> |
227 | Then at umount time , in your put_super() (2.4) or write_super() (2.5) | 227 | Then at umount time , in your put_super() you can then call journal_destroy() |
228 | you can then call journal_destroy() to clean up your in-core journal object. | 228 | to clean up your in-core journal object. |
229 | </para> | 229 | </para> |
230 | 230 | ||
231 | <para> | 231 | <para> |
diff --git a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml index 720395127904..701138f1209d 100644 --- a/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml +++ b/Documentation/DocBook/media/v4l/vidioc-g-tuner.xml | |||
@@ -125,7 +125,7 @@ the structure refers to a radio tuner the | |||
125 | <constant>V4L2_TUNER_CAP_NORM</constant> flags can't be used.</para> | 125 | <constant>V4L2_TUNER_CAP_NORM</constant> flags can't be used.</para> |
126 | <para>If multiple frequency bands are supported, then | 126 | <para>If multiple frequency bands are supported, then |
127 | <structfield>capability</structfield> is the union of all | 127 | <structfield>capability</structfield> is the union of all |
128 | <structfield>capability></structfield> fields of each &v4l2-frequency-band;. | 128 | <structfield>capability</structfield> fields of each &v4l2-frequency-band;. |
129 | </para></entry> | 129 | </para></entry> |
130 | </row> | 130 | </row> |
131 | <row> | 131 | <row> |
diff --git a/Documentation/devicetree/bindings/arm/mrvl/intc.txt b/Documentation/devicetree/bindings/arm/mrvl/intc.txt index 80b9a94d9a23..8b53273cb22f 100644 --- a/Documentation/devicetree/bindings/arm/mrvl/intc.txt +++ b/Documentation/devicetree/bindings/arm/mrvl/intc.txt | |||
@@ -38,3 +38,23 @@ Example: | |||
38 | reg-names = "mux status", "mux mask"; | 38 | reg-names = "mux status", "mux mask"; |
39 | mrvl,intc-nr-irqs = <2>; | 39 | mrvl,intc-nr-irqs = <2>; |
40 | }; | 40 | }; |
41 | |||
42 | * Marvell Orion Interrupt controller | ||
43 | |||
44 | Required properties | ||
45 | - compatible : Should be "marvell,orion-intc". | ||
46 | - #interrupt-cells: Specifies the number of cells needed to encode an | ||
47 | interrupt source. Supported value is <1>. | ||
48 | - interrupt-controller : Declare this node to be an interrupt controller. | ||
49 | - reg : Interrupt mask address. A list of 4 byte ranges, one per controller. | ||
50 | One entry in the list represents 32 interrupts. | ||
51 | |||
52 | Example: | ||
53 | |||
54 | intc: interrupt-controller { | ||
55 | compatible = "marvell,orion-intc", "marvell,intc"; | ||
56 | interrupt-controller; | ||
57 | #interrupt-cells = <1>; | ||
58 | reg = <0xfed20204 0x04>, | ||
59 | <0xfed20214 0x04>; | ||
60 | }; | ||
diff --git a/Documentation/devicetree/bindings/ata/marvell.txt b/Documentation/devicetree/bindings/ata/marvell.txt new file mode 100644 index 000000000000..b5cdd20cde9c --- /dev/null +++ b/Documentation/devicetree/bindings/ata/marvell.txt | |||
@@ -0,0 +1,16 @@ | |||
1 | * Marvell Orion SATA | ||
2 | |||
3 | Required Properties: | ||
4 | - compatibility : "marvell,orion-sata" | ||
5 | - reg : Address range of controller | ||
6 | - interrupts : Interrupt controller is using | ||
7 | - nr-ports : Number of SATA ports in use. | ||
8 | |||
9 | Example: | ||
10 | |||
11 | sata@80000 { | ||
12 | compatible = "marvell,orion-sata"; | ||
13 | reg = <0x80000 0x5000>; | ||
14 | interrupts = <21>; | ||
15 | nr-ports = <2>; | ||
16 | } | ||
diff --git a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt index 05428f39d9ac..e13787498bcf 100644 --- a/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt +++ b/Documentation/devicetree/bindings/gpio/mrvl-gpio.txt | |||
@@ -27,3 +27,26 @@ Example: | |||
27 | interrupt-controller; | 27 | interrupt-controller; |
28 | #interrupt-cells = <1>; | 28 | #interrupt-cells = <1>; |
29 | }; | 29 | }; |
30 | |||
31 | * Marvell Orion GPIO Controller | ||
32 | |||
33 | Required properties: | ||
34 | - compatible : Should be "marvell,orion-gpio" | ||
35 | - reg : Address and length of the register set for controller. | ||
36 | - gpio-controller : So we know this is a gpio controller. | ||
37 | - ngpio : How many gpios this controller has. | ||
38 | - interrupts : Up to 4 Interrupts for the controller. | ||
39 | |||
40 | Optional properties: | ||
41 | - mask-offset : For SMP Orions, offset for Nth CPU | ||
42 | |||
43 | Example: | ||
44 | |||
45 | gpio0: gpio@10100 { | ||
46 | compatible = "marvell,orion-gpio"; | ||
47 | #gpio-cells = <2>; | ||
48 | gpio-controller; | ||
49 | reg = <0x10100 0x40>; | ||
50 | ngpio = <32>; | ||
51 | interrupts = <35>, <36>, <37>, <38>; | ||
52 | }; | ||
diff --git a/Documentation/devicetree/bindings/regulator/tps6586x.txt b/Documentation/devicetree/bindings/regulator/tps6586x.txt index d156e1b5db12..da80c2ae0915 100644 --- a/Documentation/devicetree/bindings/regulator/tps6586x.txt +++ b/Documentation/devicetree/bindings/regulator/tps6586x.txt | |||
@@ -9,9 +9,9 @@ Required properties: | |||
9 | - regulators: list of regulators provided by this controller, must have | 9 | - regulators: list of regulators provided by this controller, must have |
10 | property "regulator-compatible" to match their hardware counterparts: | 10 | property "regulator-compatible" to match their hardware counterparts: |
11 | sm[0-2], ldo[0-9] and ldo_rtc | 11 | sm[0-2], ldo[0-9] and ldo_rtc |
12 | - sm0-supply: The input supply for the SM0. | 12 | - vin-sm0-supply: The input supply for the SM0. |
13 | - sm1-supply: The input supply for the SM1. | 13 | - vin-sm1-supply: The input supply for the SM1. |
14 | - sm2-supply: The input supply for the SM2. | 14 | - vin-sm2-supply: The input supply for the SM2. |
15 | - vinldo01-supply: The input supply for the LDO1 and LDO2 | 15 | - vinldo01-supply: The input supply for the LDO1 and LDO2 |
16 | - vinldo23-supply: The input supply for the LDO2 and LDO3 | 16 | - vinldo23-supply: The input supply for the LDO2 and LDO3 |
17 | - vinldo4-supply: The input supply for the LDO4 | 17 | - vinldo4-supply: The input supply for the LDO4 |
@@ -30,9 +30,9 @@ Example: | |||
30 | #gpio-cells = <2>; | 30 | #gpio-cells = <2>; |
31 | gpio-controller; | 31 | gpio-controller; |
32 | 32 | ||
33 | sm0-supply = <&some_reg>; | 33 | vin-sm0-supply = <&some_reg>; |
34 | sm1-supply = <&some_reg>; | 34 | vin-sm1-supply = <&some_reg>; |
35 | sm2-supply = <&some_reg>; | 35 | vin-sm2-supply = <&some_reg>; |
36 | vinldo01-supply = <...>; | 36 | vinldo01-supply = <...>; |
37 | vinldo23-supply = <...>; | 37 | vinldo23-supply = <...>; |
38 | vinldo4-supply = <...>; | 38 | vinldo4-supply = <...>; |
diff --git a/Documentation/devicetree/bindings/watchdog/marvel.txt b/Documentation/devicetree/bindings/watchdog/marvel.txt new file mode 100644 index 000000000000..0b2503ab0a05 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/marvel.txt | |||
@@ -0,0 +1,14 @@ | |||
1 | * Marvell Orion Watchdog Time | ||
2 | |||
3 | Required Properties: | ||
4 | |||
5 | - Compatibility : "marvell,orion-wdt" | ||
6 | - reg : Address of the timer registers | ||
7 | |||
8 | Example: | ||
9 | |||
10 | wdt@20300 { | ||
11 | compatible = "marvell,orion-wdt"; | ||
12 | reg = <0x20300 0x28>; | ||
13 | status = "okay"; | ||
14 | }; | ||
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking index 0f103e39b4f6..e540a24e5d06 100644 --- a/Documentation/filesystems/Locking +++ b/Documentation/filesystems/Locking | |||
@@ -114,7 +114,6 @@ prototypes: | |||
114 | int (*drop_inode) (struct inode *); | 114 | int (*drop_inode) (struct inode *); |
115 | void (*evict_inode) (struct inode *); | 115 | void (*evict_inode) (struct inode *); |
116 | void (*put_super) (struct super_block *); | 116 | void (*put_super) (struct super_block *); |
117 | void (*write_super) (struct super_block *); | ||
118 | int (*sync_fs)(struct super_block *sb, int wait); | 117 | int (*sync_fs)(struct super_block *sb, int wait); |
119 | int (*freeze_fs) (struct super_block *); | 118 | int (*freeze_fs) (struct super_block *); |
120 | int (*unfreeze_fs) (struct super_block *); | 119 | int (*unfreeze_fs) (struct super_block *); |
@@ -136,7 +135,6 @@ write_inode: | |||
136 | drop_inode: !!!inode->i_lock!!! | 135 | drop_inode: !!!inode->i_lock!!! |
137 | evict_inode: | 136 | evict_inode: |
138 | put_super: write | 137 | put_super: write |
139 | write_super: read | ||
140 | sync_fs: read | 138 | sync_fs: read |
141 | freeze_fs: write | 139 | freeze_fs: write |
142 | unfreeze_fs: write | 140 | unfreeze_fs: write |
diff --git a/Documentation/filesystems/porting b/Documentation/filesystems/porting index 2bef2b3843d1..0742feebc6e2 100644 --- a/Documentation/filesystems/porting +++ b/Documentation/filesystems/porting | |||
@@ -94,9 +94,8 @@ protected. | |||
94 | --- | 94 | --- |
95 | [mandatory] | 95 | [mandatory] |
96 | 96 | ||
97 | BKL is also moved from around sb operations. ->write_super() Is now called | 97 | BKL is also moved from around sb operations. BKL should have been shifted into |
98 | without BKL held. BKL should have been shifted into individual fs sb_op | 98 | individual fs sb_op functions. If you don't need it, remove it. |
99 | functions. If you don't need it, remove it. | ||
100 | 99 | ||
101 | --- | 100 | --- |
102 | [informational] | 101 | [informational] |
diff --git a/Documentation/filesystems/vfat.txt b/Documentation/filesystems/vfat.txt index ead764b2728f..de1e6c4dccff 100644 --- a/Documentation/filesystems/vfat.txt +++ b/Documentation/filesystems/vfat.txt | |||
@@ -137,6 +137,17 @@ errors=panic|continue|remount-ro | |||
137 | without doing anything or remount the partition in | 137 | without doing anything or remount the partition in |
138 | read-only mode (default behavior). | 138 | read-only mode (default behavior). |
139 | 139 | ||
140 | discard -- If set, issues discard/TRIM commands to the block | ||
141 | device when blocks are freed. This is useful for SSD devices | ||
142 | and sparse/thinly-provisoned LUNs. | ||
143 | |||
144 | nfs -- This option maintains an index (cache) of directory | ||
145 | inodes by i_logstart which is used by the nfs-related code to | ||
146 | improve look-ups. | ||
147 | |||
148 | Enable this only if you want to export the FAT filesystem | ||
149 | over NFS | ||
150 | |||
140 | <bool>: 0,1,yes,no,true,false | 151 | <bool>: 0,1,yes,no,true,false |
141 | 152 | ||
142 | TODO | 153 | TODO |
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt index 065aa2dc0835..2ee133e030c3 100644 --- a/Documentation/filesystems/vfs.txt +++ b/Documentation/filesystems/vfs.txt | |||
@@ -216,7 +216,6 @@ struct super_operations { | |||
216 | void (*drop_inode) (struct inode *); | 216 | void (*drop_inode) (struct inode *); |
217 | void (*delete_inode) (struct inode *); | 217 | void (*delete_inode) (struct inode *); |
218 | void (*put_super) (struct super_block *); | 218 | void (*put_super) (struct super_block *); |
219 | void (*write_super) (struct super_block *); | ||
220 | int (*sync_fs)(struct super_block *sb, int wait); | 219 | int (*sync_fs)(struct super_block *sb, int wait); |
221 | int (*freeze_fs) (struct super_block *); | 220 | int (*freeze_fs) (struct super_block *); |
222 | int (*unfreeze_fs) (struct super_block *); | 221 | int (*unfreeze_fs) (struct super_block *); |
@@ -273,9 +272,6 @@ or bottom half). | |||
273 | put_super: called when the VFS wishes to free the superblock | 272 | put_super: called when the VFS wishes to free the superblock |
274 | (i.e. unmount). This is called with the superblock lock held | 273 | (i.e. unmount). This is called with the superblock lock held |
275 | 274 | ||
276 | write_super: called when the VFS superblock needs to be written to | ||
277 | disc. This method is optional | ||
278 | |||
279 | sync_fs: called when VFS is writing out all dirty data associated with | 275 | sync_fs: called when VFS is writing out all dirty data associated with |
280 | a superblock. The second parameter indicates whether the method | 276 | a superblock. The second parameter indicates whether the method |
281 | should wait until the write out has been completed. Optional. | 277 | should wait until the write out has been completed. Optional. |
diff --git a/Documentation/laptops/laptop-mode.txt b/Documentation/laptops/laptop-mode.txt index 0bf25eebce94..4ebbfc3f1c6e 100644 --- a/Documentation/laptops/laptop-mode.txt +++ b/Documentation/laptops/laptop-mode.txt | |||
@@ -262,9 +262,9 @@ MINIMUM_BATTERY_MINUTES=10 | |||
262 | 262 | ||
263 | # | 263 | # |
264 | # Allowed dirty background ratio, in percent. Once DIRTY_RATIO has been | 264 | # Allowed dirty background ratio, in percent. Once DIRTY_RATIO has been |
265 | # exceeded, the kernel will wake pdflush which will then reduce the amount | 265 | # exceeded, the kernel will wake flusher threads which will then reduce the |
266 | # of dirty memory to dirty_background_ratio. Set this nice and low, so once | 266 | # amount of dirty memory to dirty_background_ratio. Set this nice and low, |
267 | # some writeout has commenced, we do a lot of it. | 267 | # so once some writeout has commenced, we do a lot of it. |
268 | # | 268 | # |
269 | #DIRTY_BACKGROUND_RATIO=5 | 269 | #DIRTY_BACKGROUND_RATIO=5 |
270 | 270 | ||
@@ -384,9 +384,9 @@ CPU_MAXFREQ=${CPU_MAXFREQ:-'slowest'} | |||
384 | 384 | ||
385 | # | 385 | # |
386 | # Allowed dirty background ratio, in percent. Once DIRTY_RATIO has been | 386 | # Allowed dirty background ratio, in percent. Once DIRTY_RATIO has been |
387 | # exceeded, the kernel will wake pdflush which will then reduce the amount | 387 | # exceeded, the kernel will wake flusher threads which will then reduce the |
388 | # of dirty memory to dirty_background_ratio. Set this nice and low, so once | 388 | # amount of dirty memory to dirty_background_ratio. Set this nice and low, |
389 | # some writeout has commenced, we do a lot of it. | 389 | # so once some writeout has commenced, we do a lot of it. |
390 | # | 390 | # |
391 | DIRTY_BACKGROUND_RATIO=${DIRTY_BACKGROUND_RATIO:-'5'} | 391 | DIRTY_BACKGROUND_RATIO=${DIRTY_BACKGROUND_RATIO:-'5'} |
392 | 392 | ||
diff --git a/Documentation/networking/netconsole.txt b/Documentation/networking/netconsole.txt index 8d022073e3ef..2e9e0ae2cd45 100644 --- a/Documentation/networking/netconsole.txt +++ b/Documentation/networking/netconsole.txt | |||
@@ -51,8 +51,23 @@ Built-in netconsole starts immediately after the TCP stack is | |||
51 | initialized and attempts to bring up the supplied dev at the supplied | 51 | initialized and attempts to bring up the supplied dev at the supplied |
52 | address. | 52 | address. |
53 | 53 | ||
54 | The remote host can run either 'netcat -u -l -p <port>', | 54 | The remote host has several options to receive the kernel messages, |
55 | 'nc -l -u <port>' or syslogd. | 55 | for example: |
56 | |||
57 | 1) syslogd | ||
58 | |||
59 | 2) netcat | ||
60 | |||
61 | On distributions using a BSD-based netcat version (e.g. Fedora, | ||
62 | openSUSE and Ubuntu) the listening port must be specified without | ||
63 | the -p switch: | ||
64 | |||
65 | 'nc -u -l -p <port>' / 'nc -u -l <port>' or | ||
66 | 'netcat -u -l -p <port>' / 'netcat -u -l <port>' | ||
67 | |||
68 | 3) socat | ||
69 | |||
70 | 'socat udp-recv:<port> -' | ||
56 | 71 | ||
57 | Dynamic reconfiguration: | 72 | Dynamic reconfiguration: |
58 | ======================== | 73 | ======================== |
diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index e40f4b4e1977..1479aca23744 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt | |||
@@ -840,9 +840,9 @@ static unsigned long i2c_pin_configs[] = { | |||
840 | 840 | ||
841 | static struct pinctrl_map __initdata mapping[] = { | 841 | static struct pinctrl_map __initdata mapping[] = { |
842 | PIN_MAP_MUX_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", "i2c0"), | 842 | PIN_MAP_MUX_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", "i2c0"), |
843 | PIN_MAP_MUX_CONFIGS_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", i2c_grp_configs), | 843 | PIN_MAP_CONFIGS_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", i2c_grp_configs), |
844 | PIN_MAP_MUX_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0scl", i2c_pin_configs), | 844 | PIN_MAP_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0scl", i2c_pin_configs), |
845 | PIN_MAP_MUX_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0sda", i2c_pin_configs), | 845 | PIN_MAP_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0sda", i2c_pin_configs), |
846 | }; | 846 | }; |
847 | 847 | ||
848 | Finally, some devices expect the mapping table to contain certain specific | 848 | Finally, some devices expect the mapping table to contain certain specific |
diff --git a/Documentation/security/Yama.txt b/Documentation/security/Yama.txt index e369de2d48cd..dd908cf64ecf 100644 --- a/Documentation/security/Yama.txt +++ b/Documentation/security/Yama.txt | |||
@@ -46,14 +46,13 @@ restrictions, it can call prctl(PR_SET_PTRACER, PR_SET_PTRACER_ANY, ...) | |||
46 | so that any otherwise allowed process (even those in external pid namespaces) | 46 | so that any otherwise allowed process (even those in external pid namespaces) |
47 | may attach. | 47 | may attach. |
48 | 48 | ||
49 | These restrictions do not change how ptrace via PTRACE_TRACEME operates. | 49 | The sysctl settings (writable only with CAP_SYS_PTRACE) are: |
50 | |||
51 | The sysctl settings are: | ||
52 | 50 | ||
53 | 0 - classic ptrace permissions: a process can PTRACE_ATTACH to any other | 51 | 0 - classic ptrace permissions: a process can PTRACE_ATTACH to any other |
54 | process running under the same uid, as long as it is dumpable (i.e. | 52 | process running under the same uid, as long as it is dumpable (i.e. |
55 | did not transition uids, start privileged, or have called | 53 | did not transition uids, start privileged, or have called |
56 | prctl(PR_SET_DUMPABLE...) already). | 54 | prctl(PR_SET_DUMPABLE...) already). Similarly, PTRACE_TRACEME is |
55 | unchanged. | ||
57 | 56 | ||
58 | 1 - restricted ptrace: a process must have a predefined relationship | 57 | 1 - restricted ptrace: a process must have a predefined relationship |
59 | with the inferior it wants to call PTRACE_ATTACH on. By default, | 58 | with the inferior it wants to call PTRACE_ATTACH on. By default, |
@@ -61,12 +60,13 @@ The sysctl settings are: | |||
61 | classic criteria is also met. To change the relationship, an | 60 | classic criteria is also met. To change the relationship, an |
62 | inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare | 61 | inferior can call prctl(PR_SET_PTRACER, debugger, ...) to declare |
63 | an allowed debugger PID to call PTRACE_ATTACH on the inferior. | 62 | an allowed debugger PID to call PTRACE_ATTACH on the inferior. |
63 | Using PTRACE_TRACEME is unchanged. | ||
64 | 64 | ||
65 | 2 - admin-only attach: only processes with CAP_SYS_PTRACE may use ptrace | 65 | 2 - admin-only attach: only processes with CAP_SYS_PTRACE may use ptrace |
66 | with PTRACE_ATTACH. | 66 | with PTRACE_ATTACH, or through children calling PTRACE_TRACEME. |
67 | 67 | ||
68 | 3 - no attach: no processes may use ptrace with PTRACE_ATTACH. Once set, | 68 | 3 - no attach: no processes may use ptrace with PTRACE_ATTACH nor via |
69 | this sysctl cannot be changed to a lower value. | 69 | PTRACE_TRACEME. Once set, this sysctl value cannot be changed. |
70 | 70 | ||
71 | The original children-only logic was based on the restrictions in grsecurity. | 71 | The original children-only logic was based on the restrictions in grsecurity. |
72 | 72 | ||
diff --git a/Documentation/sysctl/vm.txt b/Documentation/sysctl/vm.txt index dcc2a94ae34e..078701fdbd4d 100644 --- a/Documentation/sysctl/vm.txt +++ b/Documentation/sysctl/vm.txt | |||
@@ -76,8 +76,8 @@ huge pages although processes will also directly compact memory as required. | |||
76 | 76 | ||
77 | dirty_background_bytes | 77 | dirty_background_bytes |
78 | 78 | ||
79 | Contains the amount of dirty memory at which the pdflush background writeback | 79 | Contains the amount of dirty memory at which the background kernel |
80 | daemon will start writeback. | 80 | flusher threads will start writeback. |
81 | 81 | ||
82 | Note: dirty_background_bytes is the counterpart of dirty_background_ratio. Only | 82 | Note: dirty_background_bytes is the counterpart of dirty_background_ratio. Only |
83 | one of them may be specified at a time. When one sysctl is written it is | 83 | one of them may be specified at a time. When one sysctl is written it is |
@@ -89,7 +89,7 @@ other appears as 0 when read. | |||
89 | dirty_background_ratio | 89 | dirty_background_ratio |
90 | 90 | ||
91 | Contains, as a percentage of total system memory, the number of pages at which | 91 | Contains, as a percentage of total system memory, the number of pages at which |
92 | the pdflush background writeback daemon will start writing out dirty data. | 92 | the background kernel flusher threads will start writing out dirty data. |
93 | 93 | ||
94 | ============================================================== | 94 | ============================================================== |
95 | 95 | ||
@@ -112,9 +112,9 @@ retained. | |||
112 | dirty_expire_centisecs | 112 | dirty_expire_centisecs |
113 | 113 | ||
114 | This tunable is used to define when dirty data is old enough to be eligible | 114 | This tunable is used to define when dirty data is old enough to be eligible |
115 | for writeout by the pdflush daemons. It is expressed in 100'ths of a second. | 115 | for writeout by the kernel flusher threads. It is expressed in 100'ths |
116 | Data which has been dirty in-memory for longer than this interval will be | 116 | of a second. Data which has been dirty in-memory for longer than this |
117 | written out next time a pdflush daemon wakes up. | 117 | interval will be written out next time a flusher thread wakes up. |
118 | 118 | ||
119 | ============================================================== | 119 | ============================================================== |
120 | 120 | ||
@@ -128,7 +128,7 @@ data. | |||
128 | 128 | ||
129 | dirty_writeback_centisecs | 129 | dirty_writeback_centisecs |
130 | 130 | ||
131 | The pdflush writeback daemons will periodically wake up and write `old' data | 131 | The kernel flusher threads will periodically wake up and write `old' data |
132 | out to disk. This tunable expresses the interval between those wakeups, in | 132 | out to disk. This tunable expresses the interval between those wakeups, in |
133 | 100'ths of a second. | 133 | 100'ths of a second. |
134 | 134 | ||
diff --git a/Documentation/vm/hugetlbpage.txt b/Documentation/vm/hugetlbpage.txt index f8551b3879f8..4ac359b7aa17 100644 --- a/Documentation/vm/hugetlbpage.txt +++ b/Documentation/vm/hugetlbpage.txt | |||
@@ -299,11 +299,17 @@ map_hugetlb.c. | |||
299 | ******************************************************************* | 299 | ******************************************************************* |
300 | 300 | ||
301 | /* | 301 | /* |
302 | * hugepage-shm: see Documentation/vm/hugepage-shm.c | 302 | * map_hugetlb: see tools/testing/selftests/vm/map_hugetlb.c |
303 | */ | 303 | */ |
304 | 304 | ||
305 | ******************************************************************* | 305 | ******************************************************************* |
306 | 306 | ||
307 | /* | 307 | /* |
308 | * hugepage-mmap: see Documentation/vm/hugepage-mmap.c | 308 | * hugepage-shm: see tools/testing/selftests/vm/hugepage-shm.c |
309 | */ | ||
310 | |||
311 | ******************************************************************* | ||
312 | |||
313 | /* | ||
314 | * hugepage-mmap: see tools/testing/selftests/vm/hugepage-mmap.c | ||
309 | */ | 315 | */ |
diff --git a/Documentation/w1/slaves/w1_therm b/Documentation/w1/slaves/w1_therm index 0403aaaba878..874a8ca93feb 100644 --- a/Documentation/w1/slaves/w1_therm +++ b/Documentation/w1/slaves/w1_therm | |||
@@ -3,6 +3,7 @@ Kernel driver w1_therm | |||
3 | 3 | ||
4 | Supported chips: | 4 | Supported chips: |
5 | * Maxim ds18*20 based temperature sensors. | 5 | * Maxim ds18*20 based temperature sensors. |
6 | * Maxim ds1825 based temperature sensors. | ||
6 | 7 | ||
7 | Author: Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 8 | Author: Evgeniy Polyakov <johnpol@2ka.mipt.ru> |
8 | 9 | ||
@@ -15,6 +16,7 @@ supported family codes: | |||
15 | W1_THERM_DS18S20 0x10 | 16 | W1_THERM_DS18S20 0x10 |
16 | W1_THERM_DS1822 0x22 | 17 | W1_THERM_DS1822 0x22 |
17 | W1_THERM_DS18B20 0x28 | 18 | W1_THERM_DS18B20 0x28 |
19 | W1_THERM_DS1825 0x3B | ||
18 | 20 | ||
19 | Support is provided through the sysfs w1_slave file. Each open and | 21 | Support is provided through the sysfs w1_slave file. Each open and |
20 | read sequence will initiate a temperature conversion then provide two | 22 | read sequence will initiate a temperature conversion then provide two |
diff --git a/MAINTAINERS b/MAINTAINERS index 94b823f71e94..fdc0119963e7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -827,24 +827,24 @@ F: arch/arm/mach-pxa/colibri-pxa270-income.c | |||
827 | 827 | ||
828 | ARM/INTEL IOP32X ARM ARCHITECTURE | 828 | ARM/INTEL IOP32X ARM ARCHITECTURE |
829 | M: Lennert Buytenhek <kernel@wantstofly.org> | 829 | M: Lennert Buytenhek <kernel@wantstofly.org> |
830 | M: Dan Williams <dan.j.williams@intel.com> | 830 | M: Dan Williams <djbw@fb.com> |
831 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 831 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
832 | S: Maintained | 832 | S: Maintained |
833 | 833 | ||
834 | ARM/INTEL IOP33X ARM ARCHITECTURE | 834 | ARM/INTEL IOP33X ARM ARCHITECTURE |
835 | M: Dan Williams <dan.j.williams@intel.com> | 835 | M: Dan Williams <djbw@fb.com> |
836 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 836 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
837 | S: Maintained | 837 | S: Maintained |
838 | 838 | ||
839 | ARM/INTEL IOP13XX ARM ARCHITECTURE | 839 | ARM/INTEL IOP13XX ARM ARCHITECTURE |
840 | M: Lennert Buytenhek <kernel@wantstofly.org> | 840 | M: Lennert Buytenhek <kernel@wantstofly.org> |
841 | M: Dan Williams <dan.j.williams@intel.com> | 841 | M: Dan Williams <djbw@fb.com> |
842 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 842 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
843 | S: Maintained | 843 | S: Maintained |
844 | 844 | ||
845 | ARM/INTEL IQ81342EX MACHINE SUPPORT | 845 | ARM/INTEL IQ81342EX MACHINE SUPPORT |
846 | M: Lennert Buytenhek <kernel@wantstofly.org> | 846 | M: Lennert Buytenhek <kernel@wantstofly.org> |
847 | M: Dan Williams <dan.j.williams@intel.com> | 847 | M: Dan Williams <djbw@fb.com> |
848 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 848 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
849 | S: Maintained | 849 | S: Maintained |
850 | 850 | ||
@@ -869,7 +869,7 @@ F: drivers/pcmcia/pxa2xx_stargate2.c | |||
869 | 869 | ||
870 | ARM/INTEL XSC3 (MANZANO) ARM CORE | 870 | ARM/INTEL XSC3 (MANZANO) ARM CORE |
871 | M: Lennert Buytenhek <kernel@wantstofly.org> | 871 | M: Lennert Buytenhek <kernel@wantstofly.org> |
872 | M: Dan Williams <dan.j.williams@intel.com> | 872 | M: Dan Williams <djbw@fb.com> |
873 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 873 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
874 | S: Maintained | 874 | S: Maintained |
875 | 875 | ||
@@ -925,14 +925,14 @@ S: Maintained | |||
925 | 925 | ||
926 | ARM/NOMADIK ARCHITECTURE | 926 | ARM/NOMADIK ARCHITECTURE |
927 | M: Alessandro Rubini <rubini@unipv.it> | 927 | M: Alessandro Rubini <rubini@unipv.it> |
928 | M: Linus Walleij <linus.walleij@stericsson.com> | 928 | M: Linus Walleij <linus.walleij@linaro.org> |
929 | M: STEricsson <STEricsson_nomadik_linux@list.st.com> | 929 | M: STEricsson <STEricsson_nomadik_linux@list.st.com> |
930 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 930 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
931 | S: Maintained | 931 | S: Maintained |
932 | F: arch/arm/mach-nomadik/ | 932 | F: arch/arm/mach-nomadik/ |
933 | F: arch/arm/plat-nomadik/ | 933 | F: arch/arm/plat-nomadik/ |
934 | F: drivers/i2c/busses/i2c-nomadik.c | 934 | F: drivers/i2c/busses/i2c-nomadik.c |
935 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git | 935 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-nomadik.git |
936 | 936 | ||
937 | ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT | 937 | ARM/OPENMOKO NEO FREERUNNER (GTA02) MACHINE SUPPORT |
938 | M: Nelson Castillo <arhuaco@freaks-unidos.net> | 938 | M: Nelson Castillo <arhuaco@freaks-unidos.net> |
@@ -1146,7 +1146,7 @@ F: drivers/usb/host/ehci-w90x900.c | |||
1146 | F: drivers/video/nuc900fb.c | 1146 | F: drivers/video/nuc900fb.c |
1147 | 1147 | ||
1148 | ARM/U300 MACHINE SUPPORT | 1148 | ARM/U300 MACHINE SUPPORT |
1149 | M: Linus Walleij <linus.walleij@stericsson.com> | 1149 | M: Linus Walleij <linus.walleij@linaro.org> |
1150 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 1150 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
1151 | S: Supported | 1151 | S: Supported |
1152 | F: arch/arm/mach-u300/ | 1152 | F: arch/arm/mach-u300/ |
@@ -1161,15 +1161,20 @@ T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git | |||
1161 | 1161 | ||
1162 | ARM/Ux500 ARM ARCHITECTURE | 1162 | ARM/Ux500 ARM ARCHITECTURE |
1163 | M: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> | 1163 | M: Srinidhi Kasagar <srinidhi.kasagar@stericsson.com> |
1164 | M: Linus Walleij <linus.walleij@stericsson.com> | 1164 | M: Linus Walleij <linus.walleij@linaro.org> |
1165 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 1165 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
1166 | S: Maintained | 1166 | S: Maintained |
1167 | F: arch/arm/mach-ux500/ | 1167 | F: arch/arm/mach-ux500/ |
1168 | F: drivers/clocksource/clksrc-dbx500-prcmu.c | ||
1168 | F: drivers/dma/ste_dma40* | 1169 | F: drivers/dma/ste_dma40* |
1170 | F: drivers/hwspinlock/u8500_hsem.c | ||
1169 | F: drivers/mfd/abx500* | 1171 | F: drivers/mfd/abx500* |
1170 | F: drivers/mfd/ab8500* | 1172 | F: drivers/mfd/ab8500* |
1171 | F: drivers/mfd/stmpe* | 1173 | F: drivers/mfd/dbx500* |
1174 | F: drivers/mfd/db8500* | ||
1175 | F: drivers/pinctrl/pinctrl-nomadik* | ||
1172 | F: drivers/rtc/rtc-ab8500.c | 1176 | F: drivers/rtc/rtc-ab8500.c |
1177 | F: drivers/rtc/rtc-pl031.c | ||
1173 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git | 1178 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-stericsson.git |
1174 | 1179 | ||
1175 | ARM/VFP SUPPORT | 1180 | ARM/VFP SUPPORT |
@@ -1227,9 +1232,9 @@ S: Maintained | |||
1227 | F: drivers/hwmon/asb100.c | 1232 | F: drivers/hwmon/asb100.c |
1228 | 1233 | ||
1229 | ASYNCHRONOUS TRANSFERS/TRANSFORMS (IOAT) API | 1234 | ASYNCHRONOUS TRANSFERS/TRANSFORMS (IOAT) API |
1230 | M: Dan Williams <dan.j.williams@intel.com> | 1235 | M: Dan Williams <djbw@fb.com> |
1231 | W: http://sourceforge.net/projects/xscaleiop | 1236 | W: http://sourceforge.net/projects/xscaleiop |
1232 | S: Supported | 1237 | S: Maintained |
1233 | F: Documentation/crypto/async-tx-api.txt | 1238 | F: Documentation/crypto/async-tx-api.txt |
1234 | F: crypto/async_tx/ | 1239 | F: crypto/async_tx/ |
1235 | F: drivers/dma/ | 1240 | F: drivers/dma/ |
@@ -2212,7 +2217,7 @@ S: Maintained | |||
2212 | F: drivers/scsi/tmscsim.* | 2217 | F: drivers/scsi/tmscsim.* |
2213 | 2218 | ||
2214 | DC395x SCSI driver | 2219 | DC395x SCSI driver |
2215 | M: Oliver Neukum <oliver@neukum.name> | 2220 | M: Oliver Neukum <oliver@neukum.org> |
2216 | M: Ali Akcaagac <aliakc@web.de> | 2221 | M: Ali Akcaagac <aliakc@web.de> |
2217 | M: Jamie Lenehan <lenehan@twibble.org> | 2222 | M: Jamie Lenehan <lenehan@twibble.org> |
2218 | W: http://twibble.org/dist/dc395x/ | 2223 | W: http://twibble.org/dist/dc395x/ |
@@ -2359,7 +2364,7 @@ T: git git://git.linaro.org/people/sumitsemwal/linux-dma-buf.git | |||
2359 | 2364 | ||
2360 | DMA GENERIC OFFLOAD ENGINE SUBSYSTEM | 2365 | DMA GENERIC OFFLOAD ENGINE SUBSYSTEM |
2361 | M: Vinod Koul <vinod.koul@intel.com> | 2366 | M: Vinod Koul <vinod.koul@intel.com> |
2362 | M: Dan Williams <dan.j.williams@intel.com> | 2367 | M: Dan Williams <djbw@fb.com> |
2363 | S: Supported | 2368 | S: Supported |
2364 | F: drivers/dma/ | 2369 | F: drivers/dma/ |
2365 | F: include/linux/dma* | 2370 | F: include/linux/dma* |
@@ -3094,7 +3099,7 @@ F: include/linux/gigaset_dev.h | |||
3094 | 3099 | ||
3095 | GPIO SUBSYSTEM | 3100 | GPIO SUBSYSTEM |
3096 | M: Grant Likely <grant.likely@secretlab.ca> | 3101 | M: Grant Likely <grant.likely@secretlab.ca> |
3097 | M: Linus Walleij <linus.walleij@stericsson.com> | 3102 | M: Linus Walleij <linus.walleij@linaro.org> |
3098 | S: Maintained | 3103 | S: Maintained |
3099 | T: git git://git.secretlab.ca/git/linux-2.6.git | 3104 | T: git git://git.secretlab.ca/git/linux-2.6.git |
3100 | F: Documentation/gpio.txt | 3105 | F: Documentation/gpio.txt |
@@ -3547,7 +3552,6 @@ K: \b(ABS|SYN)_MT_ | |||
3547 | 3552 | ||
3548 | INTEL C600 SERIES SAS CONTROLLER DRIVER | 3553 | INTEL C600 SERIES SAS CONTROLLER DRIVER |
3549 | M: Intel SCU Linux support <intel-linux-scu@intel.com> | 3554 | M: Intel SCU Linux support <intel-linux-scu@intel.com> |
3550 | M: Dan Williams <dan.j.williams@intel.com> | ||
3551 | M: Dave Jiang <dave.jiang@intel.com> | 3555 | M: Dave Jiang <dave.jiang@intel.com> |
3552 | M: Ed Nadolski <edmund.nadolski@intel.com> | 3556 | M: Ed Nadolski <edmund.nadolski@intel.com> |
3553 | L: linux-scsi@vger.kernel.org | 3557 | L: linux-scsi@vger.kernel.org |
@@ -3590,8 +3594,8 @@ F: arch/x86/kernel/microcode_core.c | |||
3590 | F: arch/x86/kernel/microcode_intel.c | 3594 | F: arch/x86/kernel/microcode_intel.c |
3591 | 3595 | ||
3592 | INTEL I/OAT DMA DRIVER | 3596 | INTEL I/OAT DMA DRIVER |
3593 | M: Dan Williams <dan.j.williams@intel.com> | 3597 | M: Dan Williams <djbw@fb.com> |
3594 | S: Supported | 3598 | S: Maintained |
3595 | F: drivers/dma/ioat* | 3599 | F: drivers/dma/ioat* |
3596 | 3600 | ||
3597 | INTEL IOMMU (VT-d) | 3601 | INTEL IOMMU (VT-d) |
@@ -3603,8 +3607,8 @@ F: drivers/iommu/intel-iommu.c | |||
3603 | F: include/linux/intel-iommu.h | 3607 | F: include/linux/intel-iommu.h |
3604 | 3608 | ||
3605 | INTEL IOP-ADMA DMA DRIVER | 3609 | INTEL IOP-ADMA DMA DRIVER |
3606 | M: Dan Williams <dan.j.williams@intel.com> | 3610 | M: Dan Williams <djbw@fb.com> |
3607 | S: Maintained | 3611 | S: Odd fixes |
3608 | F: drivers/dma/iop-adma.c | 3612 | F: drivers/dma/iop-adma.c |
3609 | 3613 | ||
3610 | INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT | 3614 | INTEL IXP4XX QMGR, NPE, ETHERNET and HSS SUPPORT |
@@ -4533,7 +4537,7 @@ S: Supported | |||
4533 | F: arch/microblaze/ | 4537 | F: arch/microblaze/ |
4534 | 4538 | ||
4535 | MICROTEK X6 SCANNER | 4539 | MICROTEK X6 SCANNER |
4536 | M: Oliver Neukum <oliver@neukum.name> | 4540 | M: Oliver Neukum <oliver@neukum.org> |
4537 | S: Maintained | 4541 | S: Maintained |
4538 | F: drivers/usb/image/microtek.* | 4542 | F: drivers/usb/image/microtek.* |
4539 | 4543 | ||
@@ -5329,14 +5333,15 @@ PIN CONTROL SUBSYSTEM | |||
5329 | M: Linus Walleij <linus.walleij@linaro.org> | 5333 | M: Linus Walleij <linus.walleij@linaro.org> |
5330 | S: Maintained | 5334 | S: Maintained |
5331 | F: drivers/pinctrl/ | 5335 | F: drivers/pinctrl/ |
5336 | F: include/linux/pinctrl/ | ||
5332 | 5337 | ||
5333 | PIN CONTROLLER - ST SPEAR | 5338 | PIN CONTROLLER - ST SPEAR |
5334 | M: Viresh Kumar <viresh.linux@gmail.com> | 5339 | M: Viresh Kumar <viresh.linux@gmail.com> |
5335 | L: spear-devel@list.st.com | 5340 | L: spear-devel@list.st.com |
5336 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 5341 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
5337 | W: http://www.st.com/spear | 5342 | W: http://www.st.com/spear |
5338 | S: Maintained | 5343 | S: Maintained |
5339 | F: driver/pinctrl/spear/ | 5344 | F: drivers/pinctrl/spear/ |
5340 | 5345 | ||
5341 | PKTCDVD DRIVER | 5346 | PKTCDVD DRIVER |
5342 | M: Peter Osterlund <petero2@telia.com> | 5347 | M: Peter Osterlund <petero2@telia.com> |
@@ -7071,7 +7076,7 @@ F: include/linux/mtd/ubi.h | |||
7071 | F: include/mtd/ubi-user.h | 7076 | F: include/mtd/ubi-user.h |
7072 | 7077 | ||
7073 | USB ACM DRIVER | 7078 | USB ACM DRIVER |
7074 | M: Oliver Neukum <oliver@neukum.name> | 7079 | M: Oliver Neukum <oliver@neukum.org> |
7075 | L: linux-usb@vger.kernel.org | 7080 | L: linux-usb@vger.kernel.org |
7076 | S: Maintained | 7081 | S: Maintained |
7077 | F: Documentation/usb/acm.txt | 7082 | F: Documentation/usb/acm.txt |
@@ -7092,7 +7097,7 @@ S: Supported | |||
7092 | F: drivers/block/ub.c | 7097 | F: drivers/block/ub.c |
7093 | 7098 | ||
7094 | USB CDC ETHERNET DRIVER | 7099 | USB CDC ETHERNET DRIVER |
7095 | M: Oliver Neukum <oliver@neukum.name> | 7100 | M: Oliver Neukum <oliver@neukum.org> |
7096 | L: linux-usb@vger.kernel.org | 7101 | L: linux-usb@vger.kernel.org |
7097 | S: Maintained | 7102 | S: Maintained |
7098 | F: drivers/net/usb/cdc_*.c | 7103 | F: drivers/net/usb/cdc_*.c |
@@ -7165,7 +7170,7 @@ F: drivers/usb/host/isp116x* | |||
7165 | F: include/linux/usb/isp116x.h | 7170 | F: include/linux/usb/isp116x.h |
7166 | 7171 | ||
7167 | USB KAWASAKI LSI DRIVER | 7172 | USB KAWASAKI LSI DRIVER |
7168 | M: Oliver Neukum <oliver@neukum.name> | 7173 | M: Oliver Neukum <oliver@neukum.org> |
7169 | L: linux-usb@vger.kernel.org | 7174 | L: linux-usb@vger.kernel.org |
7170 | S: Maintained | 7175 | S: Maintained |
7171 | F: drivers/usb/serial/kl5kusb105.* | 7176 | F: drivers/usb/serial/kl5kusb105.* |
@@ -7283,6 +7288,12 @@ W: http://www.connecttech.com | |||
7283 | S: Supported | 7288 | S: Supported |
7284 | F: drivers/usb/serial/whiteheat* | 7289 | F: drivers/usb/serial/whiteheat* |
7285 | 7290 | ||
7291 | USB SMSC75XX ETHERNET DRIVER | ||
7292 | M: Steve Glendinning <steve.glendinning@shawell.net> | ||
7293 | L: netdev@vger.kernel.org | ||
7294 | S: Maintained | ||
7295 | F: drivers/net/usb/smsc75xx.* | ||
7296 | |||
7286 | USB SMSC95XX ETHERNET DRIVER | 7297 | USB SMSC95XX ETHERNET DRIVER |
7287 | M: Steve Glendinning <steve.glendinning@shawell.net> | 7298 | M: Steve Glendinning <steve.glendinning@shawell.net> |
7288 | L: netdev@vger.kernel.org | 7299 | L: netdev@vger.kernel.org |
@@ -7665,23 +7676,28 @@ S: Supported | |||
7665 | F: Documentation/hwmon/wm83?? | 7676 | F: Documentation/hwmon/wm83?? |
7666 | F: arch/arm/mach-s3c64xx/mach-crag6410* | 7677 | F: arch/arm/mach-s3c64xx/mach-crag6410* |
7667 | F: drivers/clk/clk-wm83*.c | 7678 | F: drivers/clk/clk-wm83*.c |
7679 | F: drivers/extcon/extcon-arizona.c | ||
7668 | F: drivers/leds/leds-wm83*.c | 7680 | F: drivers/leds/leds-wm83*.c |
7669 | F: drivers/gpio/gpio-*wm*.c | 7681 | F: drivers/gpio/gpio-*wm*.c |
7682 | F: drivers/gpio/gpio-arizona.c | ||
7670 | F: drivers/hwmon/wm83??-hwmon.c | 7683 | F: drivers/hwmon/wm83??-hwmon.c |
7671 | F: drivers/input/misc/wm831x-on.c | 7684 | F: drivers/input/misc/wm831x-on.c |
7672 | F: drivers/input/touchscreen/wm831x-ts.c | 7685 | F: drivers/input/touchscreen/wm831x-ts.c |
7673 | F: drivers/input/touchscreen/wm97*.c | 7686 | F: drivers/input/touchscreen/wm97*.c |
7674 | F: drivers/mfd/wm8*.c | 7687 | F: drivers/mfd/arizona* |
7688 | F: drivers/mfd/wm*.c | ||
7675 | F: drivers/power/wm83*.c | 7689 | F: drivers/power/wm83*.c |
7676 | F: drivers/rtc/rtc-wm83*.c | 7690 | F: drivers/rtc/rtc-wm83*.c |
7677 | F: drivers/regulator/wm8*.c | 7691 | F: drivers/regulator/wm8*.c |
7678 | F: drivers/video/backlight/wm83*_bl.c | 7692 | F: drivers/video/backlight/wm83*_bl.c |
7679 | F: drivers/watchdog/wm83*_wdt.c | 7693 | F: drivers/watchdog/wm83*_wdt.c |
7694 | F: include/linux/mfd/arizona/ | ||
7680 | F: include/linux/mfd/wm831x/ | 7695 | F: include/linux/mfd/wm831x/ |
7681 | F: include/linux/mfd/wm8350/ | 7696 | F: include/linux/mfd/wm8350/ |
7682 | F: include/linux/mfd/wm8400* | 7697 | F: include/linux/mfd/wm8400* |
7683 | F: include/linux/wm97xx.h | 7698 | F: include/linux/wm97xx.h |
7684 | F: include/sound/wm????.h | 7699 | F: include/sound/wm????.h |
7700 | F: sound/soc/codecs/arizona.? | ||
7685 | F: sound/soc/codecs/wm* | 7701 | F: sound/soc/codecs/wm* |
7686 | 7702 | ||
7687 | WORKQUEUE | 7703 | WORKQUEUE |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 3 | 1 | VERSION = 3 |
2 | PATCHLEVEL = 5 | 2 | PATCHLEVEL = 6 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = | 4 | EXTRAVERSION = -rc2 |
5 | NAME = Saber-toothed Squirrel | 5 | NAME = Saber-toothed Squirrel |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/alpha/Kconfig b/arch/alpha/Kconfig index d5b9b5e645cc..9944dedee5b1 100644 --- a/arch/alpha/Kconfig +++ b/arch/alpha/Kconfig | |||
@@ -18,6 +18,8 @@ config ALPHA | |||
18 | select ARCH_HAVE_NMI_SAFE_CMPXCHG | 18 | select ARCH_HAVE_NMI_SAFE_CMPXCHG |
19 | select GENERIC_SMP_IDLE_THREAD | 19 | select GENERIC_SMP_IDLE_THREAD |
20 | select GENERIC_CMOS_UPDATE | 20 | select GENERIC_CMOS_UPDATE |
21 | select GENERIC_STRNCPY_FROM_USER | ||
22 | select GENERIC_STRNLEN_USER | ||
21 | help | 23 | help |
22 | The Alpha is a 64-bit general-purpose processor designed and | 24 | The Alpha is a 64-bit general-purpose processor designed and |
23 | marketed by the Digital Equipment Corporation of blessed memory, | 25 | marketed by the Digital Equipment Corporation of blessed memory, |
diff --git a/arch/alpha/include/asm/atomic.h b/arch/alpha/include/asm/atomic.h index 3bb7ffeae3bc..c2cbe4fc391c 100644 --- a/arch/alpha/include/asm/atomic.h +++ b/arch/alpha/include/asm/atomic.h | |||
@@ -14,8 +14,8 @@ | |||
14 | */ | 14 | */ |
15 | 15 | ||
16 | 16 | ||
17 | #define ATOMIC_INIT(i) ( (atomic_t) { (i) } ) | 17 | #define ATOMIC_INIT(i) { (i) } |
18 | #define ATOMIC64_INIT(i) ( (atomic64_t) { (i) } ) | 18 | #define ATOMIC64_INIT(i) { (i) } |
19 | 19 | ||
20 | #define atomic_read(v) (*(volatile int *)&(v)->counter) | 20 | #define atomic_read(v) (*(volatile int *)&(v)->counter) |
21 | #define atomic64_read(v) (*(volatile long *)&(v)->counter) | 21 | #define atomic64_read(v) (*(volatile long *)&(v)->counter) |
diff --git a/arch/alpha/include/asm/fpu.h b/arch/alpha/include/asm/fpu.h index db00f7885faa..e477bcd5b94a 100644 --- a/arch/alpha/include/asm/fpu.h +++ b/arch/alpha/include/asm/fpu.h | |||
@@ -1,7 +1,9 @@ | |||
1 | #ifndef __ASM_ALPHA_FPU_H | 1 | #ifndef __ASM_ALPHA_FPU_H |
2 | #define __ASM_ALPHA_FPU_H | 2 | #define __ASM_ALPHA_FPU_H |
3 | 3 | ||
4 | #ifdef __KERNEL__ | ||
4 | #include <asm/special_insns.h> | 5 | #include <asm/special_insns.h> |
6 | #endif | ||
5 | 7 | ||
6 | /* | 8 | /* |
7 | * Alpha floating-point control register defines: | 9 | * Alpha floating-point control register defines: |
diff --git a/arch/alpha/include/asm/ptrace.h b/arch/alpha/include/asm/ptrace.h index fd698a174f26..b87755a19554 100644 --- a/arch/alpha/include/asm/ptrace.h +++ b/arch/alpha/include/asm/ptrace.h | |||
@@ -76,7 +76,10 @@ struct switch_stack { | |||
76 | #define task_pt_regs(task) \ | 76 | #define task_pt_regs(task) \ |
77 | ((struct pt_regs *) (task_stack_page(task) + 2*PAGE_SIZE) - 1) | 77 | ((struct pt_regs *) (task_stack_page(task) + 2*PAGE_SIZE) - 1) |
78 | 78 | ||
79 | #define force_successful_syscall_return() (task_pt_regs(current)->r0 = 0) | 79 | #define current_pt_regs() \ |
80 | ((struct pt_regs *) ((char *)current_thread_info() + 2*PAGE_SIZE) - 1) | ||
81 | |||
82 | #define force_successful_syscall_return() (current_pt_regs()->r0 = 0) | ||
80 | 83 | ||
81 | #endif | 84 | #endif |
82 | 85 | ||
diff --git a/arch/alpha/include/asm/socket.h b/arch/alpha/include/asm/socket.h index dcb221a4b5be..7d2f75be932e 100644 --- a/arch/alpha/include/asm/socket.h +++ b/arch/alpha/include/asm/socket.h | |||
@@ -76,9 +76,11 @@ | |||
76 | /* Instruct lower device to use last 4-bytes of skb data as FCS */ | 76 | /* Instruct lower device to use last 4-bytes of skb data as FCS */ |
77 | #define SO_NOFCS 43 | 77 | #define SO_NOFCS 43 |
78 | 78 | ||
79 | #ifdef __KERNEL__ | ||
79 | /* O_NONBLOCK clashes with the bits used for socket types. Therefore we | 80 | /* O_NONBLOCK clashes with the bits used for socket types. Therefore we |
80 | * have to define SOCK_NONBLOCK to a different value here. | 81 | * have to define SOCK_NONBLOCK to a different value here. |
81 | */ | 82 | */ |
82 | #define SOCK_NONBLOCK 0x40000000 | 83 | #define SOCK_NONBLOCK 0x40000000 |
84 | #endif /* __KERNEL__ */ | ||
83 | 85 | ||
84 | #endif /* _ASM_SOCKET_H */ | 86 | #endif /* _ASM_SOCKET_H */ |
diff --git a/arch/alpha/include/asm/uaccess.h b/arch/alpha/include/asm/uaccess.h index b49ec2f8d6e3..766fdfde2b7a 100644 --- a/arch/alpha/include/asm/uaccess.h +++ b/arch/alpha/include/asm/uaccess.h | |||
@@ -433,36 +433,12 @@ clear_user(void __user *to, long len) | |||
433 | #undef __module_address | 433 | #undef __module_address |
434 | #undef __module_call | 434 | #undef __module_call |
435 | 435 | ||
436 | /* Returns: -EFAULT if exception before terminator, N if the entire | 436 | #define user_addr_max() \ |
437 | buffer filled, else strlen. */ | 437 | (segment_eq(get_fs(), USER_DS) ? TASK_SIZE : ~0UL) |
438 | 438 | ||
439 | extern long __strncpy_from_user(char *__to, const char __user *__from, long __to_len); | 439 | extern long strncpy_from_user(char *dest, const char __user *src, long count); |
440 | 440 | extern __must_check long strlen_user(const char __user *str); | |
441 | extern inline long | 441 | extern __must_check long strnlen_user(const char __user *str, long n); |
442 | strncpy_from_user(char *to, const char __user *from, long n) | ||
443 | { | ||
444 | long ret = -EFAULT; | ||
445 | if (__access_ok((unsigned long)from, 0, get_fs())) | ||
446 | ret = __strncpy_from_user(to, from, n); | ||
447 | return ret; | ||
448 | } | ||
449 | |||
450 | /* Returns: 0 if bad, string length+1 (memory size) of string if ok */ | ||
451 | extern long __strlen_user(const char __user *); | ||
452 | |||
453 | extern inline long strlen_user(const char __user *str) | ||
454 | { | ||
455 | return access_ok(VERIFY_READ,str,0) ? __strlen_user(str) : 0; | ||
456 | } | ||
457 | |||
458 | /* Returns: 0 if exception before NUL or reaching the supplied limit (N), | ||
459 | * a value greater than N if the limit would be exceeded, else strlen. */ | ||
460 | extern long __strnlen_user(const char __user *, long); | ||
461 | |||
462 | extern inline long strnlen_user(const char __user *str, long n) | ||
463 | { | ||
464 | return access_ok(VERIFY_READ,str,0) ? __strnlen_user(str, n) : 0; | ||
465 | } | ||
466 | 442 | ||
467 | /* | 443 | /* |
468 | * About the exception table: | 444 | * About the exception table: |
diff --git a/arch/alpha/include/asm/unistd.h b/arch/alpha/include/asm/unistd.h index 633b23b0664a..a31a78eac9b9 100644 --- a/arch/alpha/include/asm/unistd.h +++ b/arch/alpha/include/asm/unistd.h | |||
@@ -465,10 +465,12 @@ | |||
465 | #define __NR_setns 501 | 465 | #define __NR_setns 501 |
466 | #define __NR_accept4 502 | 466 | #define __NR_accept4 502 |
467 | #define __NR_sendmmsg 503 | 467 | #define __NR_sendmmsg 503 |
468 | #define __NR_process_vm_readv 504 | ||
469 | #define __NR_process_vm_writev 505 | ||
468 | 470 | ||
469 | #ifdef __KERNEL__ | 471 | #ifdef __KERNEL__ |
470 | 472 | ||
471 | #define NR_SYSCALLS 504 | 473 | #define NR_SYSCALLS 506 |
472 | 474 | ||
473 | #define __ARCH_WANT_OLD_READDIR | 475 | #define __ARCH_WANT_OLD_READDIR |
474 | #define __ARCH_WANT_STAT64 | 476 | #define __ARCH_WANT_STAT64 |
diff --git a/arch/alpha/include/asm/word-at-a-time.h b/arch/alpha/include/asm/word-at-a-time.h new file mode 100644 index 000000000000..6b340d0f1521 --- /dev/null +++ b/arch/alpha/include/asm/word-at-a-time.h | |||
@@ -0,0 +1,55 @@ | |||
1 | #ifndef _ASM_WORD_AT_A_TIME_H | ||
2 | #define _ASM_WORD_AT_A_TIME_H | ||
3 | |||
4 | #include <asm/compiler.h> | ||
5 | |||
6 | /* | ||
7 | * word-at-a-time interface for Alpha. | ||
8 | */ | ||
9 | |||
10 | /* | ||
11 | * We do not use the word_at_a_time struct on Alpha, but it needs to be | ||
12 | * implemented to humour the generic code. | ||
13 | */ | ||
14 | struct word_at_a_time { | ||
15 | const unsigned long unused; | ||
16 | }; | ||
17 | |||
18 | #define WORD_AT_A_TIME_CONSTANTS { 0 } | ||
19 | |||
20 | /* Return nonzero if val has a zero */ | ||
21 | static inline unsigned long has_zero(unsigned long val, unsigned long *bits, const struct word_at_a_time *c) | ||
22 | { | ||
23 | unsigned long zero_locations = __kernel_cmpbge(0, val); | ||
24 | *bits = zero_locations; | ||
25 | return zero_locations; | ||
26 | } | ||
27 | |||
28 | static inline unsigned long prep_zero_mask(unsigned long val, unsigned long bits, const struct word_at_a_time *c) | ||
29 | { | ||
30 | return bits; | ||
31 | } | ||
32 | |||
33 | #define create_zero_mask(bits) (bits) | ||
34 | |||
35 | static inline unsigned long find_zero(unsigned long bits) | ||
36 | { | ||
37 | #if defined(CONFIG_ALPHA_EV6) && defined(CONFIG_ALPHA_EV67) | ||
38 | /* Simple if have CIX instructions */ | ||
39 | return __kernel_cttz(bits); | ||
40 | #else | ||
41 | unsigned long t1, t2, t3; | ||
42 | /* Retain lowest set bit only */ | ||
43 | bits &= -bits; | ||
44 | /* Binary search for lowest set bit */ | ||
45 | t1 = bits & 0xf0; | ||
46 | t2 = bits & 0xcc; | ||
47 | t3 = bits & 0xaa; | ||
48 | if (t1) t1 = 4; | ||
49 | if (t2) t2 = 2; | ||
50 | if (t3) t3 = 1; | ||
51 | return t1 + t2 + t3; | ||
52 | #endif | ||
53 | } | ||
54 | |||
55 | #endif /* _ASM_WORD_AT_A_TIME_H */ | ||
diff --git a/arch/alpha/kernel/alpha_ksyms.c b/arch/alpha/kernel/alpha_ksyms.c index d96e742d4dc2..15fa821d09cd 100644 --- a/arch/alpha/kernel/alpha_ksyms.c +++ b/arch/alpha/kernel/alpha_ksyms.c | |||
@@ -52,7 +52,6 @@ EXPORT_SYMBOL(alpha_write_fp_reg_s); | |||
52 | 52 | ||
53 | /* entry.S */ | 53 | /* entry.S */ |
54 | EXPORT_SYMBOL(kernel_thread); | 54 | EXPORT_SYMBOL(kernel_thread); |
55 | EXPORT_SYMBOL(kernel_execve); | ||
56 | 55 | ||
57 | /* Networking helper routines. */ | 56 | /* Networking helper routines. */ |
58 | EXPORT_SYMBOL(csum_tcpudp_magic); | 57 | EXPORT_SYMBOL(csum_tcpudp_magic); |
@@ -74,8 +73,6 @@ EXPORT_SYMBOL(alpha_fp_emul); | |||
74 | */ | 73 | */ |
75 | EXPORT_SYMBOL(__copy_user); | 74 | EXPORT_SYMBOL(__copy_user); |
76 | EXPORT_SYMBOL(__do_clear_user); | 75 | EXPORT_SYMBOL(__do_clear_user); |
77 | EXPORT_SYMBOL(__strncpy_from_user); | ||
78 | EXPORT_SYMBOL(__strnlen_user); | ||
79 | 76 | ||
80 | /* | 77 | /* |
81 | * SMP-specific symbols. | 78 | * SMP-specific symbols. |
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index 6d159cee5f2f..ec0da0567ab5 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S | |||
@@ -663,58 +663,6 @@ kernel_thread: | |||
663 | br ret_to_kernel | 663 | br ret_to_kernel |
664 | .end kernel_thread | 664 | .end kernel_thread |
665 | 665 | ||
666 | /* | ||
667 | * kernel_execve(path, argv, envp) | ||
668 | */ | ||
669 | .align 4 | ||
670 | .globl kernel_execve | ||
671 | .ent kernel_execve | ||
672 | kernel_execve: | ||
673 | /* We can be called from a module. */ | ||
674 | ldgp $gp, 0($27) | ||
675 | lda $sp, -(32+SIZEOF_PT_REGS+8)($sp) | ||
676 | .frame $sp, 32+SIZEOF_PT_REGS+8, $26, 0 | ||
677 | stq $26, 0($sp) | ||
678 | stq $16, 8($sp) | ||
679 | stq $17, 16($sp) | ||
680 | stq $18, 24($sp) | ||
681 | .prologue 1 | ||
682 | |||
683 | lda $16, 32($sp) | ||
684 | lda $17, 0 | ||
685 | lda $18, SIZEOF_PT_REGS | ||
686 | bsr $26, memset !samegp | ||
687 | |||
688 | /* Avoid the HAE being gratuitously wrong, which would cause us | ||
689 | to do the whole turn off interrupts thing and restore it. */ | ||
690 | ldq $2, alpha_mv+HAE_CACHE | ||
691 | stq $2, 152+32($sp) | ||
692 | |||
693 | ldq $16, 8($sp) | ||
694 | ldq $17, 16($sp) | ||
695 | ldq $18, 24($sp) | ||
696 | lda $19, 32($sp) | ||
697 | bsr $26, do_execve !samegp | ||
698 | |||
699 | ldq $26, 0($sp) | ||
700 | bne $0, 1f /* error! */ | ||
701 | |||
702 | /* Move the temporary pt_regs struct from its current location | ||
703 | to the top of the kernel stack frame. See copy_thread for | ||
704 | details for a normal process. */ | ||
705 | lda $16, 0x4000 - SIZEOF_PT_REGS($8) | ||
706 | lda $17, 32($sp) | ||
707 | lda $18, SIZEOF_PT_REGS | ||
708 | bsr $26, memmove !samegp | ||
709 | |||
710 | /* Take that over as our new stack frame and visit userland! */ | ||
711 | lda $sp, 0x4000 - SIZEOF_PT_REGS($8) | ||
712 | br $31, ret_from_sys_call | ||
713 | |||
714 | 1: lda $sp, 32+SIZEOF_PT_REGS+8($sp) | ||
715 | ret | ||
716 | .end kernel_execve | ||
717 | |||
718 | 666 | ||
719 | /* | 667 | /* |
720 | * Special system calls. Most of these are special in that they either | 668 | * Special system calls. Most of these are special in that they either |
@@ -797,115 +745,6 @@ sys_rt_sigreturn: | |||
797 | .end sys_rt_sigreturn | 745 | .end sys_rt_sigreturn |
798 | 746 | ||
799 | .align 4 | 747 | .align 4 |
800 | .globl sys_sethae | ||
801 | .ent sys_sethae | ||
802 | sys_sethae: | ||
803 | .prologue 0 | ||
804 | stq $16, 152($sp) | ||
805 | ret | ||
806 | .end sys_sethae | ||
807 | |||
808 | .align 4 | ||
809 | .globl osf_getpriority | ||
810 | .ent osf_getpriority | ||
811 | osf_getpriority: | ||
812 | lda $sp, -16($sp) | ||
813 | stq $26, 0($sp) | ||
814 | .prologue 0 | ||
815 | |||
816 | jsr $26, sys_getpriority | ||
817 | |||
818 | ldq $26, 0($sp) | ||
819 | blt $0, 1f | ||
820 | |||
821 | /* Return value is the unbiased priority, i.e. 20 - prio. | ||
822 | This does result in negative return values, so signal | ||
823 | no error by writing into the R0 slot. */ | ||
824 | lda $1, 20 | ||
825 | stq $31, 16($sp) | ||
826 | subl $1, $0, $0 | ||
827 | unop | ||
828 | |||
829 | 1: lda $sp, 16($sp) | ||
830 | ret | ||
831 | .end osf_getpriority | ||
832 | |||
833 | .align 4 | ||
834 | .globl sys_getxuid | ||
835 | .ent sys_getxuid | ||
836 | sys_getxuid: | ||
837 | .prologue 0 | ||
838 | ldq $2, TI_TASK($8) | ||
839 | ldq $3, TASK_CRED($2) | ||
840 | ldl $0, CRED_UID($3) | ||
841 | ldl $1, CRED_EUID($3) | ||
842 | stq $1, 80($sp) | ||
843 | ret | ||
844 | .end sys_getxuid | ||
845 | |||
846 | .align 4 | ||
847 | .globl sys_getxgid | ||
848 | .ent sys_getxgid | ||
849 | sys_getxgid: | ||
850 | .prologue 0 | ||
851 | ldq $2, TI_TASK($8) | ||
852 | ldq $3, TASK_CRED($2) | ||
853 | ldl $0, CRED_GID($3) | ||
854 | ldl $1, CRED_EGID($3) | ||
855 | stq $1, 80($sp) | ||
856 | ret | ||
857 | .end sys_getxgid | ||
858 | |||
859 | .align 4 | ||
860 | .globl sys_getxpid | ||
861 | .ent sys_getxpid | ||
862 | sys_getxpid: | ||
863 | .prologue 0 | ||
864 | ldq $2, TI_TASK($8) | ||
865 | |||
866 | /* See linux/kernel/timer.c sys_getppid for discussion | ||
867 | about this loop. */ | ||
868 | ldq $3, TASK_GROUP_LEADER($2) | ||
869 | ldq $4, TASK_REAL_PARENT($3) | ||
870 | ldl $0, TASK_TGID($2) | ||
871 | 1: ldl $1, TASK_TGID($4) | ||
872 | #ifdef CONFIG_SMP | ||
873 | mov $4, $5 | ||
874 | mb | ||
875 | ldq $3, TASK_GROUP_LEADER($2) | ||
876 | ldq $4, TASK_REAL_PARENT($3) | ||
877 | cmpeq $4, $5, $5 | ||
878 | beq $5, 1b | ||
879 | #endif | ||
880 | stq $1, 80($sp) | ||
881 | ret | ||
882 | .end sys_getxpid | ||
883 | |||
884 | .align 4 | ||
885 | .globl sys_alpha_pipe | ||
886 | .ent sys_alpha_pipe | ||
887 | sys_alpha_pipe: | ||
888 | lda $sp, -16($sp) | ||
889 | stq $26, 0($sp) | ||
890 | .prologue 0 | ||
891 | |||
892 | mov $31, $17 | ||
893 | lda $16, 8($sp) | ||
894 | jsr $26, do_pipe_flags | ||
895 | |||
896 | ldq $26, 0($sp) | ||
897 | bne $0, 1f | ||
898 | |||
899 | /* The return values are in $0 and $20. */ | ||
900 | ldl $1, 12($sp) | ||
901 | ldl $0, 8($sp) | ||
902 | |||
903 | stq $1, 80+16($sp) | ||
904 | 1: lda $sp, 16($sp) | ||
905 | ret | ||
906 | .end sys_alpha_pipe | ||
907 | |||
908 | .align 4 | ||
909 | .globl sys_execve | 748 | .globl sys_execve |
910 | .ent sys_execve | 749 | .ent sys_execve |
911 | sys_execve: | 750 | sys_execve: |
diff --git a/arch/alpha/kernel/osf_sys.c b/arch/alpha/kernel/osf_sys.c index 98a103621af6..bc1acdda7a5e 100644 --- a/arch/alpha/kernel/osf_sys.c +++ b/arch/alpha/kernel/osf_sys.c | |||
@@ -1404,3 +1404,52 @@ SYSCALL_DEFINE3(osf_writev, unsigned long, fd, | |||
1404 | } | 1404 | } |
1405 | 1405 | ||
1406 | #endif | 1406 | #endif |
1407 | |||
1408 | SYSCALL_DEFINE2(osf_getpriority, int, which, int, who) | ||
1409 | { | ||
1410 | int prio = sys_getpriority(which, who); | ||
1411 | if (prio >= 0) { | ||
1412 | /* Return value is the unbiased priority, i.e. 20 - prio. | ||
1413 | This does result in negative return values, so signal | ||
1414 | no error */ | ||
1415 | force_successful_syscall_return(); | ||
1416 | prio = 20 - prio; | ||
1417 | } | ||
1418 | return prio; | ||
1419 | } | ||
1420 | |||
1421 | SYSCALL_DEFINE0(getxuid) | ||
1422 | { | ||
1423 | current_pt_regs()->r20 = sys_geteuid(); | ||
1424 | return sys_getuid(); | ||
1425 | } | ||
1426 | |||
1427 | SYSCALL_DEFINE0(getxgid) | ||
1428 | { | ||
1429 | current_pt_regs()->r20 = sys_getegid(); | ||
1430 | return sys_getgid(); | ||
1431 | } | ||
1432 | |||
1433 | SYSCALL_DEFINE0(getxpid) | ||
1434 | { | ||
1435 | current_pt_regs()->r20 = sys_getppid(); | ||
1436 | return sys_getpid(); | ||
1437 | } | ||
1438 | |||
1439 | SYSCALL_DEFINE0(alpha_pipe) | ||
1440 | { | ||
1441 | int fd[2]; | ||
1442 | int res = do_pipe_flags(fd, 0); | ||
1443 | if (!res) { | ||
1444 | /* The return values are in $0 and $20. */ | ||
1445 | current_pt_regs()->r20 = fd[1]; | ||
1446 | res = fd[0]; | ||
1447 | } | ||
1448 | return res; | ||
1449 | } | ||
1450 | |||
1451 | SYSCALL_DEFINE1(sethae, unsigned long, val) | ||
1452 | { | ||
1453 | current_pt_regs()->hae = val; | ||
1454 | return 0; | ||
1455 | } | ||
diff --git a/arch/alpha/kernel/process.c b/arch/alpha/kernel/process.c index 153d3fce3e8e..d6fde98b74b3 100644 --- a/arch/alpha/kernel/process.c +++ b/arch/alpha/kernel/process.c | |||
@@ -455,3 +455,22 @@ get_wchan(struct task_struct *p) | |||
455 | } | 455 | } |
456 | return pc; | 456 | return pc; |
457 | } | 457 | } |
458 | |||
459 | int kernel_execve(const char *path, const char *const argv[], const char *const envp[]) | ||
460 | { | ||
461 | /* Avoid the HAE being gratuitously wrong, which would cause us | ||
462 | to do the whole turn off interrupts thing and restore it. */ | ||
463 | struct pt_regs regs = {.hae = alpha_mv.hae_cache}; | ||
464 | int err = do_execve(path, argv, envp, ®s); | ||
465 | if (!err) { | ||
466 | struct pt_regs *p = current_pt_regs(); | ||
467 | /* copy regs to normal position and off to userland we go... */ | ||
468 | *p = regs; | ||
469 | __asm__ __volatile__ ( | ||
470 | "mov %0, $sp;" | ||
471 | "br $31, ret_from_sys_call" | ||
472 | : : "r"(p)); | ||
473 | } | ||
474 | return err; | ||
475 | } | ||
476 | EXPORT_SYMBOL(kernel_execve); | ||
diff --git a/arch/alpha/kernel/systbls.S b/arch/alpha/kernel/systbls.S index 87835235f114..2ac6b45c3e00 100644 --- a/arch/alpha/kernel/systbls.S +++ b/arch/alpha/kernel/systbls.S | |||
@@ -111,7 +111,7 @@ sys_call_table: | |||
111 | .quad sys_socket | 111 | .quad sys_socket |
112 | .quad sys_connect | 112 | .quad sys_connect |
113 | .quad sys_accept | 113 | .quad sys_accept |
114 | .quad osf_getpriority /* 100 */ | 114 | .quad sys_osf_getpriority /* 100 */ |
115 | .quad sys_send | 115 | .quad sys_send |
116 | .quad sys_recv | 116 | .quad sys_recv |
117 | .quad sys_sigreturn | 117 | .quad sys_sigreturn |
@@ -522,6 +522,8 @@ sys_call_table: | |||
522 | .quad sys_setns | 522 | .quad sys_setns |
523 | .quad sys_accept4 | 523 | .quad sys_accept4 |
524 | .quad sys_sendmmsg | 524 | .quad sys_sendmmsg |
525 | .quad sys_process_vm_readv | ||
526 | .quad sys_process_vm_writev /* 505 */ | ||
525 | 527 | ||
526 | .size sys_call_table, . - sys_call_table | 528 | .size sys_call_table, . - sys_call_table |
527 | .type sys_call_table, @object | 529 | .type sys_call_table, @object |
diff --git a/arch/alpha/lib/Makefile b/arch/alpha/lib/Makefile index c0a83ab62b78..59660743237c 100644 --- a/arch/alpha/lib/Makefile +++ b/arch/alpha/lib/Makefile | |||
@@ -31,8 +31,6 @@ lib-y = __divqu.o __remqu.o __divlu.o __remlu.o \ | |||
31 | $(ev6-y)memchr.o \ | 31 | $(ev6-y)memchr.o \ |
32 | $(ev6-y)copy_user.o \ | 32 | $(ev6-y)copy_user.o \ |
33 | $(ev6-y)clear_user.o \ | 33 | $(ev6-y)clear_user.o \ |
34 | $(ev6-y)strncpy_from_user.o \ | ||
35 | $(ev67-y)strlen_user.o \ | ||
36 | $(ev6-y)csum_ipv6_magic.o \ | 34 | $(ev6-y)csum_ipv6_magic.o \ |
37 | $(ev6-y)clear_page.o \ | 35 | $(ev6-y)clear_page.o \ |
38 | $(ev6-y)copy_page.o \ | 36 | $(ev6-y)copy_page.o \ |
diff --git a/arch/alpha/lib/ev6-strncpy_from_user.S b/arch/alpha/lib/ev6-strncpy_from_user.S deleted file mode 100644 index d2e28178cacc..000000000000 --- a/arch/alpha/lib/ev6-strncpy_from_user.S +++ /dev/null | |||
@@ -1,424 +0,0 @@ | |||
1 | /* | ||
2 | * arch/alpha/lib/ev6-strncpy_from_user.S | ||
3 | * 21264 version contributed by Rick Gorton <rick.gorton@alpha-processor.com> | ||
4 | * | ||
5 | * Just like strncpy except in the return value: | ||
6 | * | ||
7 | * -EFAULT if an exception occurs before the terminator is copied. | ||
8 | * N if the buffer filled. | ||
9 | * | ||
10 | * Otherwise the length of the string is returned. | ||
11 | * | ||
12 | * Much of the information about 21264 scheduling/coding comes from: | ||
13 | * Compiler Writer's Guide for the Alpha 21264 | ||
14 | * abbreviated as 'CWG' in other comments here | ||
15 | * ftp.digital.com/pub/Digital/info/semiconductor/literature/dsc-library.html | ||
16 | * Scheduling notation: | ||
17 | * E - either cluster | ||
18 | * U - upper subcluster; U0 - subcluster U0; U1 - subcluster U1 | ||
19 | * L - lower subcluster; L0 - subcluster L0; L1 - subcluster L1 | ||
20 | * A bunch of instructions got moved and temp registers were changed | ||
21 | * to aid in scheduling. Control flow was also re-arranged to eliminate | ||
22 | * branches, and to provide longer code sequences to enable better scheduling. | ||
23 | * A total rewrite (using byte load/stores for start & tail sequences) | ||
24 | * is desirable, but very difficult to do without a from-scratch rewrite. | ||
25 | * Save that for the future. | ||
26 | */ | ||
27 | |||
28 | |||
29 | #include <asm/errno.h> | ||
30 | #include <asm/regdef.h> | ||
31 | |||
32 | |||
33 | /* Allow an exception for an insn; exit if we get one. */ | ||
34 | #define EX(x,y...) \ | ||
35 | 99: x,##y; \ | ||
36 | .section __ex_table,"a"; \ | ||
37 | .long 99b - .; \ | ||
38 | lda $31, $exception-99b($0); \ | ||
39 | .previous | ||
40 | |||
41 | |||
42 | .set noat | ||
43 | .set noreorder | ||
44 | .text | ||
45 | |||
46 | .globl __strncpy_from_user | ||
47 | .ent __strncpy_from_user | ||
48 | .frame $30, 0, $26 | ||
49 | .prologue 0 | ||
50 | |||
51 | .align 4 | ||
52 | __strncpy_from_user: | ||
53 | and a0, 7, t3 # E : find dest misalignment | ||
54 | beq a2, $zerolength # U : | ||
55 | |||
56 | /* Are source and destination co-aligned? */ | ||
57 | mov a0, v0 # E : save the string start | ||
58 | xor a0, a1, t4 # E : | ||
59 | EX( ldq_u t1, 0(a1) ) # L : Latency=3 load first quadword | ||
60 | ldq_u t0, 0(a0) # L : load first (partial) aligned dest quadword | ||
61 | |||
62 | addq a2, t3, a2 # E : bias count by dest misalignment | ||
63 | subq a2, 1, a3 # E : | ||
64 | addq zero, 1, t10 # E : | ||
65 | and t4, 7, t4 # E : misalignment between the two | ||
66 | |||
67 | and a3, 7, t6 # E : number of tail bytes | ||
68 | sll t10, t6, t10 # E : t10 = bitmask of last count byte | ||
69 | bne t4, $unaligned # U : | ||
70 | lda t2, -1 # E : build a mask against false zero | ||
71 | |||
72 | /* | ||
73 | * We are co-aligned; take care of a partial first word. | ||
74 | * On entry to this basic block: | ||
75 | * t0 == the first destination word for masking back in | ||
76 | * t1 == the first source word. | ||
77 | */ | ||
78 | |||
79 | srl a3, 3, a2 # E : a2 = loop counter = (count - 1)/8 | ||
80 | addq a1, 8, a1 # E : | ||
81 | mskqh t2, a1, t2 # U : detection in the src word | ||
82 | nop | ||
83 | |||
84 | /* Create the 1st output word and detect 0's in the 1st input word. */ | ||
85 | mskqh t1, a1, t3 # U : | ||
86 | mskql t0, a1, t0 # U : assemble the first output word | ||
87 | ornot t1, t2, t2 # E : | ||
88 | nop | ||
89 | |||
90 | cmpbge zero, t2, t8 # E : bits set iff null found | ||
91 | or t0, t3, t0 # E : | ||
92 | beq a2, $a_eoc # U : | ||
93 | bne t8, $a_eos # U : 2nd branch in a quad. Bad. | ||
94 | |||
95 | /* On entry to this basic block: | ||
96 | * t0 == a source quad not containing a null. | ||
97 | * a0 - current aligned destination address | ||
98 | * a1 - current aligned source address | ||
99 | * a2 - count of quadwords to move. | ||
100 | * NOTE: Loop improvement - unrolling this is going to be | ||
101 | * a huge win, since we're going to stall otherwise. | ||
102 | * Fix this later. For _really_ large copies, look | ||
103 | * at using wh64 on a look-ahead basis. See the code | ||
104 | * in clear_user.S and copy_user.S. | ||
105 | * Presumably, since (a0) and (a1) do not overlap (by C definition) | ||
106 | * Lots of nops here: | ||
107 | * - Separate loads from stores | ||
108 | * - Keep it to 1 branch/quadpack so the branch predictor | ||
109 | * can train. | ||
110 | */ | ||
111 | $a_loop: | ||
112 | stq_u t0, 0(a0) # L : | ||
113 | addq a0, 8, a0 # E : | ||
114 | nop | ||
115 | subq a2, 1, a2 # E : | ||
116 | |||
117 | EX( ldq_u t0, 0(a1) ) # L : | ||
118 | addq a1, 8, a1 # E : | ||
119 | cmpbge zero, t0, t8 # E : Stall 2 cycles on t0 | ||
120 | beq a2, $a_eoc # U : | ||
121 | |||
122 | beq t8, $a_loop # U : | ||
123 | nop | ||
124 | nop | ||
125 | nop | ||
126 | |||
127 | /* Take care of the final (partial) word store. At this point | ||
128 | * the end-of-count bit is set in t8 iff it applies. | ||
129 | * | ||
130 | * On entry to this basic block we have: | ||
131 | * t0 == the source word containing the null | ||
132 | * t8 == the cmpbge mask that found it. | ||
133 | */ | ||
134 | $a_eos: | ||
135 | negq t8, t12 # E : find low bit set | ||
136 | and t8, t12, t12 # E : | ||
137 | |||
138 | /* We're doing a partial word store and so need to combine | ||
139 | our source and original destination words. */ | ||
140 | ldq_u t1, 0(a0) # L : | ||
141 | subq t12, 1, t6 # E : | ||
142 | |||
143 | or t12, t6, t8 # E : | ||
144 | zapnot t0, t8, t0 # U : clear src bytes > null | ||
145 | zap t1, t8, t1 # U : clear dst bytes <= null | ||
146 | or t0, t1, t0 # E : | ||
147 | |||
148 | stq_u t0, 0(a0) # L : | ||
149 | br $finish_up # L0 : | ||
150 | nop | ||
151 | nop | ||
152 | |||
153 | /* Add the end-of-count bit to the eos detection bitmask. */ | ||
154 | .align 4 | ||
155 | $a_eoc: | ||
156 | or t10, t8, t8 | ||
157 | br $a_eos | ||
158 | nop | ||
159 | nop | ||
160 | |||
161 | |||
162 | /* The source and destination are not co-aligned. Align the destination | ||
163 | and cope. We have to be very careful about not reading too much and | ||
164 | causing a SEGV. */ | ||
165 | |||
166 | .align 4 | ||
167 | $u_head: | ||
168 | /* We know just enough now to be able to assemble the first | ||
169 | full source word. We can still find a zero at the end of it | ||
170 | that prevents us from outputting the whole thing. | ||
171 | |||
172 | On entry to this basic block: | ||
173 | t0 == the first dest word, unmasked | ||
174 | t1 == the shifted low bits of the first source word | ||
175 | t6 == bytemask that is -1 in dest word bytes */ | ||
176 | |||
177 | EX( ldq_u t2, 8(a1) ) # L : load second src word | ||
178 | addq a1, 8, a1 # E : | ||
179 | mskql t0, a0, t0 # U : mask trailing garbage in dst | ||
180 | extqh t2, a1, t4 # U : | ||
181 | |||
182 | or t1, t4, t1 # E : first aligned src word complete | ||
183 | mskqh t1, a0, t1 # U : mask leading garbage in src | ||
184 | or t0, t1, t0 # E : first output word complete | ||
185 | or t0, t6, t6 # E : mask original data for zero test | ||
186 | |||
187 | cmpbge zero, t6, t8 # E : | ||
188 | beq a2, $u_eocfin # U : | ||
189 | bne t8, $u_final # U : bad news - 2nd branch in a quad | ||
190 | lda t6, -1 # E : mask out the bits we have | ||
191 | |||
192 | mskql t6, a1, t6 # U : already seen | ||
193 | stq_u t0, 0(a0) # L : store first output word | ||
194 | or t6, t2, t2 # E : | ||
195 | cmpbge zero, t2, t8 # E : find nulls in second partial | ||
196 | |||
197 | addq a0, 8, a0 # E : | ||
198 | subq a2, 1, a2 # E : | ||
199 | bne t8, $u_late_head_exit # U : | ||
200 | nop | ||
201 | |||
202 | /* Finally, we've got all the stupid leading edge cases taken care | ||
203 | of and we can set up to enter the main loop. */ | ||
204 | |||
205 | extql t2, a1, t1 # U : position hi-bits of lo word | ||
206 | EX( ldq_u t2, 8(a1) ) # L : read next high-order source word | ||
207 | addq a1, 8, a1 # E : | ||
208 | cmpbge zero, t2, t8 # E : | ||
209 | |||
210 | beq a2, $u_eoc # U : | ||
211 | bne t8, $u_eos # U : | ||
212 | nop | ||
213 | nop | ||
214 | |||
215 | /* Unaligned copy main loop. In order to avoid reading too much, | ||
216 | the loop is structured to detect zeros in aligned source words. | ||
217 | This has, unfortunately, effectively pulled half of a loop | ||
218 | iteration out into the head and half into the tail, but it does | ||
219 | prevent nastiness from accumulating in the very thing we want | ||
220 | to run as fast as possible. | ||
221 | |||
222 | On entry to this basic block: | ||
223 | t1 == the shifted high-order bits from the previous source word | ||
224 | t2 == the unshifted current source word | ||
225 | |||
226 | We further know that t2 does not contain a null terminator. */ | ||
227 | |||
228 | /* | ||
229 | * Extra nops here: | ||
230 | * separate load quads from store quads | ||
231 | * only one branch/quad to permit predictor training | ||
232 | */ | ||
233 | |||
234 | .align 4 | ||
235 | $u_loop: | ||
236 | extqh t2, a1, t0 # U : extract high bits for current word | ||
237 | addq a1, 8, a1 # E : | ||
238 | extql t2, a1, t3 # U : extract low bits for next time | ||
239 | addq a0, 8, a0 # E : | ||
240 | |||
241 | or t0, t1, t0 # E : current dst word now complete | ||
242 | EX( ldq_u t2, 0(a1) ) # L : load high word for next time | ||
243 | subq a2, 1, a2 # E : | ||
244 | nop | ||
245 | |||
246 | stq_u t0, -8(a0) # L : save the current word | ||
247 | mov t3, t1 # E : | ||
248 | cmpbge zero, t2, t8 # E : test new word for eos | ||
249 | beq a2, $u_eoc # U : | ||
250 | |||
251 | beq t8, $u_loop # U : | ||
252 | nop | ||
253 | nop | ||
254 | nop | ||
255 | |||
256 | /* We've found a zero somewhere in the source word we just read. | ||
257 | If it resides in the lower half, we have one (probably partial) | ||
258 | word to write out, and if it resides in the upper half, we | ||
259 | have one full and one partial word left to write out. | ||
260 | |||
261 | On entry to this basic block: | ||
262 | t1 == the shifted high-order bits from the previous source word | ||
263 | t2 == the unshifted current source word. */ | ||
264 | .align 4 | ||
265 | $u_eos: | ||
266 | extqh t2, a1, t0 # U : | ||
267 | or t0, t1, t0 # E : first (partial) source word complete | ||
268 | cmpbge zero, t0, t8 # E : is the null in this first bit? | ||
269 | nop | ||
270 | |||
271 | bne t8, $u_final # U : | ||
272 | stq_u t0, 0(a0) # L : the null was in the high-order bits | ||
273 | addq a0, 8, a0 # E : | ||
274 | subq a2, 1, a2 # E : | ||
275 | |||
276 | .align 4 | ||
277 | $u_late_head_exit: | ||
278 | extql t2, a1, t0 # U : | ||
279 | cmpbge zero, t0, t8 # E : | ||
280 | or t8, t10, t6 # E : | ||
281 | cmoveq a2, t6, t8 # E : | ||
282 | |||
283 | /* Take care of a final (probably partial) result word. | ||
284 | On entry to this basic block: | ||
285 | t0 == assembled source word | ||
286 | t8 == cmpbge mask that found the null. */ | ||
287 | .align 4 | ||
288 | $u_final: | ||
289 | negq t8, t6 # E : isolate low bit set | ||
290 | and t6, t8, t12 # E : | ||
291 | ldq_u t1, 0(a0) # L : | ||
292 | subq t12, 1, t6 # E : | ||
293 | |||
294 | or t6, t12, t8 # E : | ||
295 | zapnot t0, t8, t0 # U : kill source bytes > null | ||
296 | zap t1, t8, t1 # U : kill dest bytes <= null | ||
297 | or t0, t1, t0 # E : | ||
298 | |||
299 | stq_u t0, 0(a0) # E : | ||
300 | br $finish_up # U : | ||
301 | nop | ||
302 | nop | ||
303 | |||
304 | .align 4 | ||
305 | $u_eoc: # end-of-count | ||
306 | extqh t2, a1, t0 # U : | ||
307 | or t0, t1, t0 # E : | ||
308 | cmpbge zero, t0, t8 # E : | ||
309 | nop | ||
310 | |||
311 | .align 4 | ||
312 | $u_eocfin: # end-of-count, final word | ||
313 | or t10, t8, t8 # E : | ||
314 | br $u_final # U : | ||
315 | nop | ||
316 | nop | ||
317 | |||
318 | /* Unaligned copy entry point. */ | ||
319 | .align 4 | ||
320 | $unaligned: | ||
321 | |||
322 | srl a3, 3, a2 # U : a2 = loop counter = (count - 1)/8 | ||
323 | and a0, 7, t4 # E : find dest misalignment | ||
324 | and a1, 7, t5 # E : find src misalignment | ||
325 | mov zero, t0 # E : | ||
326 | |||
327 | /* Conditionally load the first destination word and a bytemask | ||
328 | with 0xff indicating that the destination byte is sacrosanct. */ | ||
329 | |||
330 | mov zero, t6 # E : | ||
331 | beq t4, 1f # U : | ||
332 | ldq_u t0, 0(a0) # L : | ||
333 | lda t6, -1 # E : | ||
334 | |||
335 | mskql t6, a0, t6 # E : | ||
336 | nop | ||
337 | nop | ||
338 | nop | ||
339 | |||
340 | .align 4 | ||
341 | 1: | ||
342 | subq a1, t4, a1 # E : sub dest misalignment from src addr | ||
343 | /* If source misalignment is larger than dest misalignment, we need | ||
344 | extra startup checks to avoid SEGV. */ | ||
345 | cmplt t4, t5, t12 # E : | ||
346 | extql t1, a1, t1 # U : shift src into place | ||
347 | lda t2, -1 # E : for creating masks later | ||
348 | |||
349 | beq t12, $u_head # U : | ||
350 | mskqh t2, t5, t2 # U : begin src byte validity mask | ||
351 | cmpbge zero, t1, t8 # E : is there a zero? | ||
352 | nop | ||
353 | |||
354 | extql t2, a1, t2 # U : | ||
355 | or t8, t10, t5 # E : test for end-of-count too | ||
356 | cmpbge zero, t2, t3 # E : | ||
357 | cmoveq a2, t5, t8 # E : Latency=2, extra map slot | ||
358 | |||
359 | nop # E : goes with cmov | ||
360 | andnot t8, t3, t8 # E : | ||
361 | beq t8, $u_head # U : | ||
362 | nop | ||
363 | |||
364 | /* At this point we've found a zero in the first partial word of | ||
365 | the source. We need to isolate the valid source data and mask | ||
366 | it into the original destination data. (Incidentally, we know | ||
367 | that we'll need at least one byte of that original dest word.) */ | ||
368 | |||
369 | ldq_u t0, 0(a0) # L : | ||
370 | negq t8, t6 # E : build bitmask of bytes <= zero | ||
371 | mskqh t1, t4, t1 # U : | ||
372 | and t6, t8, t12 # E : | ||
373 | |||
374 | subq t12, 1, t6 # E : | ||
375 | or t6, t12, t8 # E : | ||
376 | zapnot t2, t8, t2 # U : prepare source word; mirror changes | ||
377 | zapnot t1, t8, t1 # U : to source validity mask | ||
378 | |||
379 | andnot t0, t2, t0 # E : zero place for source to reside | ||
380 | or t0, t1, t0 # E : and put it there | ||
381 | stq_u t0, 0(a0) # L : | ||
382 | nop | ||
383 | |||
384 | .align 4 | ||
385 | $finish_up: | ||
386 | zapnot t0, t12, t4 # U : was last byte written null? | ||
387 | and t12, 0xf0, t3 # E : binary search for the address of the | ||
388 | cmovne t4, 1, t4 # E : Latency=2, extra map slot | ||
389 | nop # E : with cmovne | ||
390 | |||
391 | and t12, 0xcc, t2 # E : last byte written | ||
392 | and t12, 0xaa, t1 # E : | ||
393 | cmovne t3, 4, t3 # E : Latency=2, extra map slot | ||
394 | nop # E : with cmovne | ||
395 | |||
396 | bic a0, 7, t0 | ||
397 | cmovne t2, 2, t2 # E : Latency=2, extra map slot | ||
398 | nop # E : with cmovne | ||
399 | nop | ||
400 | |||
401 | cmovne t1, 1, t1 # E : Latency=2, extra map slot | ||
402 | nop # E : with cmovne | ||
403 | addq t0, t3, t0 # E : | ||
404 | addq t1, t2, t1 # E : | ||
405 | |||
406 | addq t0, t1, t0 # E : | ||
407 | addq t0, t4, t0 # add one if we filled the buffer | ||
408 | subq t0, v0, v0 # find string length | ||
409 | ret # L0 : | ||
410 | |||
411 | .align 4 | ||
412 | $zerolength: | ||
413 | nop | ||
414 | nop | ||
415 | nop | ||
416 | clr v0 | ||
417 | |||
418 | $exception: | ||
419 | nop | ||
420 | nop | ||
421 | nop | ||
422 | ret | ||
423 | |||
424 | .end __strncpy_from_user | ||
diff --git a/arch/alpha/lib/ev67-strlen_user.S b/arch/alpha/lib/ev67-strlen_user.S deleted file mode 100644 index 57e0d77b81a6..000000000000 --- a/arch/alpha/lib/ev67-strlen_user.S +++ /dev/null | |||
@@ -1,107 +0,0 @@ | |||
1 | /* | ||
2 | * arch/alpha/lib/ev67-strlen_user.S | ||
3 | * 21264 version contributed by Rick Gorton <rick.gorton@api-networks.com> | ||
4 | * | ||
5 | * Return the length of the string including the NULL terminator | ||
6 | * (strlen+1) or zero if an error occurred. | ||
7 | * | ||
8 | * In places where it is critical to limit the processing time, | ||
9 | * and the data is not trusted, strnlen_user() should be used. | ||
10 | * It will return a value greater than its second argument if | ||
11 | * that limit would be exceeded. This implementation is allowed | ||
12 | * to access memory beyond the limit, but will not cross a page | ||
13 | * boundary when doing so. | ||
14 | * | ||
15 | * Much of the information about 21264 scheduling/coding comes from: | ||
16 | * Compiler Writer's Guide for the Alpha 21264 | ||
17 | * abbreviated as 'CWG' in other comments here | ||
18 | * ftp.digital.com/pub/Digital/info/semiconductor/literature/dsc-library.html | ||
19 | * Scheduling notation: | ||
20 | * E - either cluster | ||
21 | * U - upper subcluster; U0 - subcluster U0; U1 - subcluster U1 | ||
22 | * L - lower subcluster; L0 - subcluster L0; L1 - subcluster L1 | ||
23 | * Try not to change the actual algorithm if possible for consistency. | ||
24 | */ | ||
25 | |||
26 | #include <asm/regdef.h> | ||
27 | |||
28 | |||
29 | /* Allow an exception for an insn; exit if we get one. */ | ||
30 | #define EX(x,y...) \ | ||
31 | 99: x,##y; \ | ||
32 | .section __ex_table,"a"; \ | ||
33 | .long 99b - .; \ | ||
34 | lda v0, $exception-99b(zero); \ | ||
35 | .previous | ||
36 | |||
37 | |||
38 | .set noreorder | ||
39 | .set noat | ||
40 | .text | ||
41 | |||
42 | .globl __strlen_user | ||
43 | .ent __strlen_user | ||
44 | .frame sp, 0, ra | ||
45 | |||
46 | .align 4 | ||
47 | __strlen_user: | ||
48 | ldah a1, 32767(zero) # do not use plain strlen_user() for strings | ||
49 | # that might be almost 2 GB long; you should | ||
50 | # be using strnlen_user() instead | ||
51 | nop | ||
52 | nop | ||
53 | nop | ||
54 | |||
55 | .globl __strnlen_user | ||
56 | |||
57 | .align 4 | ||
58 | __strnlen_user: | ||
59 | .prologue 0 | ||
60 | EX( ldq_u t0, 0(a0) ) # L : load first quadword (a0 may be misaligned) | ||
61 | lda t1, -1(zero) # E : | ||
62 | |||
63 | insqh t1, a0, t1 # U : | ||
64 | andnot a0, 7, v0 # E : | ||
65 | or t1, t0, t0 # E : | ||
66 | subq a0, 1, a0 # E : get our +1 for the return | ||
67 | |||
68 | cmpbge zero, t0, t1 # E : t1 <- bitmask: bit i == 1 <==> i-th byte == 0 | ||
69 | subq a1, 7, t2 # E : | ||
70 | subq a0, v0, t0 # E : | ||
71 | bne t1, $found # U : | ||
72 | |||
73 | addq t2, t0, t2 # E : | ||
74 | addq a1, 1, a1 # E : | ||
75 | nop # E : | ||
76 | nop # E : | ||
77 | |||
78 | .align 4 | ||
79 | $loop: ble t2, $limit # U : | ||
80 | EX( ldq t0, 8(v0) ) # L : | ||
81 | nop # E : | ||
82 | nop # E : | ||
83 | |||
84 | cmpbge zero, t0, t1 # E : | ||
85 | subq t2, 8, t2 # E : | ||
86 | addq v0, 8, v0 # E : addr += 8 | ||
87 | beq t1, $loop # U : | ||
88 | |||
89 | $found: cttz t1, t2 # U0 : | ||
90 | addq v0, t2, v0 # E : | ||
91 | subq v0, a0, v0 # E : | ||
92 | ret # L0 : | ||
93 | |||
94 | $exception: | ||
95 | nop | ||
96 | nop | ||
97 | nop | ||
98 | ret | ||
99 | |||
100 | .align 4 # currently redundant | ||
101 | $limit: | ||
102 | nop | ||
103 | nop | ||
104 | subq a1, t2, v0 | ||
105 | ret | ||
106 | |||
107 | .end __strlen_user | ||
diff --git a/arch/alpha/lib/strlen_user.S b/arch/alpha/lib/strlen_user.S deleted file mode 100644 index 508a18e96479..000000000000 --- a/arch/alpha/lib/strlen_user.S +++ /dev/null | |||
@@ -1,91 +0,0 @@ | |||
1 | /* | ||
2 | * arch/alpha/lib/strlen_user.S | ||
3 | * | ||
4 | * Return the length of the string including the NUL terminator | ||
5 | * (strlen+1) or zero if an error occurred. | ||
6 | * | ||
7 | * In places where it is critical to limit the processing time, | ||
8 | * and the data is not trusted, strnlen_user() should be used. | ||
9 | * It will return a value greater than its second argument if | ||
10 | * that limit would be exceeded. This implementation is allowed | ||
11 | * to access memory beyond the limit, but will not cross a page | ||
12 | * boundary when doing so. | ||
13 | */ | ||
14 | |||
15 | #include <asm/regdef.h> | ||
16 | |||
17 | |||
18 | /* Allow an exception for an insn; exit if we get one. */ | ||
19 | #define EX(x,y...) \ | ||
20 | 99: x,##y; \ | ||
21 | .section __ex_table,"a"; \ | ||
22 | .long 99b - .; \ | ||
23 | lda v0, $exception-99b(zero); \ | ||
24 | .previous | ||
25 | |||
26 | |||
27 | .set noreorder | ||
28 | .set noat | ||
29 | .text | ||
30 | |||
31 | .globl __strlen_user | ||
32 | .ent __strlen_user | ||
33 | .frame sp, 0, ra | ||
34 | |||
35 | .align 3 | ||
36 | __strlen_user: | ||
37 | ldah a1, 32767(zero) # do not use plain strlen_user() for strings | ||
38 | # that might be almost 2 GB long; you should | ||
39 | # be using strnlen_user() instead | ||
40 | |||
41 | .globl __strnlen_user | ||
42 | |||
43 | .align 3 | ||
44 | __strnlen_user: | ||
45 | .prologue 0 | ||
46 | |||
47 | EX( ldq_u t0, 0(a0) ) # load first quadword (a0 may be misaligned) | ||
48 | lda t1, -1(zero) | ||
49 | insqh t1, a0, t1 | ||
50 | andnot a0, 7, v0 | ||
51 | or t1, t0, t0 | ||
52 | subq a0, 1, a0 # get our +1 for the return | ||
53 | cmpbge zero, t0, t1 # t1 <- bitmask: bit i == 1 <==> i-th byte == 0 | ||
54 | subq a1, 7, t2 | ||
55 | subq a0, v0, t0 | ||
56 | bne t1, $found | ||
57 | |||
58 | addq t2, t0, t2 | ||
59 | addq a1, 1, a1 | ||
60 | |||
61 | .align 3 | ||
62 | $loop: ble t2, $limit | ||
63 | EX( ldq t0, 8(v0) ) | ||
64 | subq t2, 8, t2 | ||
65 | addq v0, 8, v0 # addr += 8 | ||
66 | cmpbge zero, t0, t1 | ||
67 | beq t1, $loop | ||
68 | |||
69 | $found: negq t1, t2 # clear all but least set bit | ||
70 | and t1, t2, t1 | ||
71 | |||
72 | and t1, 0xf0, t2 # binary search for that set bit | ||
73 | and t1, 0xcc, t3 | ||
74 | and t1, 0xaa, t4 | ||
75 | cmovne t2, 4, t2 | ||
76 | cmovne t3, 2, t3 | ||
77 | cmovne t4, 1, t4 | ||
78 | addq t2, t3, t2 | ||
79 | addq v0, t4, v0 | ||
80 | addq v0, t2, v0 | ||
81 | nop # dual issue next two on ev4 and ev5 | ||
82 | subq v0, a0, v0 | ||
83 | $exception: | ||
84 | ret | ||
85 | |||
86 | .align 3 # currently redundant | ||
87 | $limit: | ||
88 | subq a1, t2, v0 | ||
89 | ret | ||
90 | |||
91 | .end __strlen_user | ||
diff --git a/arch/alpha/lib/strncpy_from_user.S b/arch/alpha/lib/strncpy_from_user.S deleted file mode 100644 index 73ee21160ff7..000000000000 --- a/arch/alpha/lib/strncpy_from_user.S +++ /dev/null | |||
@@ -1,339 +0,0 @@ | |||
1 | /* | ||
2 | * arch/alpha/lib/strncpy_from_user.S | ||
3 | * Contributed by Richard Henderson (rth@tamu.edu) | ||
4 | * | ||
5 | * Just like strncpy except in the return value: | ||
6 | * | ||
7 | * -EFAULT if an exception occurs before the terminator is copied. | ||
8 | * N if the buffer filled. | ||
9 | * | ||
10 | * Otherwise the length of the string is returned. | ||
11 | */ | ||
12 | |||
13 | |||
14 | #include <asm/errno.h> | ||
15 | #include <asm/regdef.h> | ||
16 | |||
17 | |||
18 | /* Allow an exception for an insn; exit if we get one. */ | ||
19 | #define EX(x,y...) \ | ||
20 | 99: x,##y; \ | ||
21 | .section __ex_table,"a"; \ | ||
22 | .long 99b - .; \ | ||
23 | lda $31, $exception-99b($0); \ | ||
24 | .previous | ||
25 | |||
26 | |||
27 | .set noat | ||
28 | .set noreorder | ||
29 | .text | ||
30 | |||
31 | .globl __strncpy_from_user | ||
32 | .ent __strncpy_from_user | ||
33 | .frame $30, 0, $26 | ||
34 | .prologue 0 | ||
35 | |||
36 | .align 3 | ||
37 | $aligned: | ||
38 | /* On entry to this basic block: | ||
39 | t0 == the first destination word for masking back in | ||
40 | t1 == the first source word. */ | ||
41 | |||
42 | /* Create the 1st output word and detect 0's in the 1st input word. */ | ||
43 | lda t2, -1 # e1 : build a mask against false zero | ||
44 | mskqh t2, a1, t2 # e0 : detection in the src word | ||
45 | mskqh t1, a1, t3 # e0 : | ||
46 | ornot t1, t2, t2 # .. e1 : | ||
47 | mskql t0, a1, t0 # e0 : assemble the first output word | ||
48 | cmpbge zero, t2, t8 # .. e1 : bits set iff null found | ||
49 | or t0, t3, t0 # e0 : | ||
50 | beq a2, $a_eoc # .. e1 : | ||
51 | bne t8, $a_eos # .. e1 : | ||
52 | |||
53 | /* On entry to this basic block: | ||
54 | t0 == a source word not containing a null. */ | ||
55 | |||
56 | $a_loop: | ||
57 | stq_u t0, 0(a0) # e0 : | ||
58 | addq a0, 8, a0 # .. e1 : | ||
59 | EX( ldq_u t0, 0(a1) ) # e0 : | ||
60 | addq a1, 8, a1 # .. e1 : | ||
61 | subq a2, 1, a2 # e0 : | ||
62 | cmpbge zero, t0, t8 # .. e1 (stall) | ||
63 | beq a2, $a_eoc # e1 : | ||
64 | beq t8, $a_loop # e1 : | ||
65 | |||
66 | /* Take care of the final (partial) word store. At this point | ||
67 | the end-of-count bit is set in t8 iff it applies. | ||
68 | |||
69 | On entry to this basic block we have: | ||
70 | t0 == the source word containing the null | ||
71 | t8 == the cmpbge mask that found it. */ | ||
72 | |||
73 | $a_eos: | ||
74 | negq t8, t12 # e0 : find low bit set | ||
75 | and t8, t12, t12 # e1 (stall) | ||
76 | |||
77 | /* For the sake of the cache, don't read a destination word | ||
78 | if we're not going to need it. */ | ||
79 | and t12, 0x80, t6 # e0 : | ||
80 | bne t6, 1f # .. e1 (zdb) | ||
81 | |||
82 | /* We're doing a partial word store and so need to combine | ||
83 | our source and original destination words. */ | ||
84 | ldq_u t1, 0(a0) # e0 : | ||
85 | subq t12, 1, t6 # .. e1 : | ||
86 | or t12, t6, t8 # e0 : | ||
87 | unop # | ||
88 | zapnot t0, t8, t0 # e0 : clear src bytes > null | ||
89 | zap t1, t8, t1 # .. e1 : clear dst bytes <= null | ||
90 | or t0, t1, t0 # e1 : | ||
91 | |||
92 | 1: stq_u t0, 0(a0) | ||
93 | br $finish_up | ||
94 | |||
95 | /* Add the end-of-count bit to the eos detection bitmask. */ | ||
96 | $a_eoc: | ||
97 | or t10, t8, t8 | ||
98 | br $a_eos | ||
99 | |||
100 | /*** The Function Entry Point ***/ | ||
101 | .align 3 | ||
102 | __strncpy_from_user: | ||
103 | mov a0, v0 # save the string start | ||
104 | beq a2, $zerolength | ||
105 | |||
106 | /* Are source and destination co-aligned? */ | ||
107 | xor a0, a1, t1 # e0 : | ||
108 | and a0, 7, t0 # .. e1 : find dest misalignment | ||
109 | and t1, 7, t1 # e0 : | ||
110 | addq a2, t0, a2 # .. e1 : bias count by dest misalignment | ||
111 | subq a2, 1, a2 # e0 : | ||
112 | and a2, 7, t2 # e1 : | ||
113 | srl a2, 3, a2 # e0 : a2 = loop counter = (count - 1)/8 | ||
114 | addq zero, 1, t10 # .. e1 : | ||
115 | sll t10, t2, t10 # e0 : t10 = bitmask of last count byte | ||
116 | bne t1, $unaligned # .. e1 : | ||
117 | |||
118 | /* We are co-aligned; take care of a partial first word. */ | ||
119 | |||
120 | EX( ldq_u t1, 0(a1) ) # e0 : load first src word | ||
121 | addq a1, 8, a1 # .. e1 : | ||
122 | |||
123 | beq t0, $aligned # avoid loading dest word if not needed | ||
124 | ldq_u t0, 0(a0) # e0 : | ||
125 | br $aligned # .. e1 : | ||
126 | |||
127 | |||
128 | /* The source and destination are not co-aligned. Align the destination | ||
129 | and cope. We have to be very careful about not reading too much and | ||
130 | causing a SEGV. */ | ||
131 | |||
132 | .align 3 | ||
133 | $u_head: | ||
134 | /* We know just enough now to be able to assemble the first | ||
135 | full source word. We can still find a zero at the end of it | ||
136 | that prevents us from outputting the whole thing. | ||
137 | |||
138 | On entry to this basic block: | ||
139 | t0 == the first dest word, unmasked | ||
140 | t1 == the shifted low bits of the first source word | ||
141 | t6 == bytemask that is -1 in dest word bytes */ | ||
142 | |||
143 | EX( ldq_u t2, 8(a1) ) # e0 : load second src word | ||
144 | addq a1, 8, a1 # .. e1 : | ||
145 | mskql t0, a0, t0 # e0 : mask trailing garbage in dst | ||
146 | extqh t2, a1, t4 # e0 : | ||
147 | or t1, t4, t1 # e1 : first aligned src word complete | ||
148 | mskqh t1, a0, t1 # e0 : mask leading garbage in src | ||
149 | or t0, t1, t0 # e0 : first output word complete | ||
150 | or t0, t6, t6 # e1 : mask original data for zero test | ||
151 | cmpbge zero, t6, t8 # e0 : | ||
152 | beq a2, $u_eocfin # .. e1 : | ||
153 | bne t8, $u_final # e1 : | ||
154 | |||
155 | lda t6, -1 # e1 : mask out the bits we have | ||
156 | mskql t6, a1, t6 # e0 : already seen | ||
157 | stq_u t0, 0(a0) # e0 : store first output word | ||
158 | or t6, t2, t2 # .. e1 : | ||
159 | cmpbge zero, t2, t8 # e0 : find nulls in second partial | ||
160 | addq a0, 8, a0 # .. e1 : | ||
161 | subq a2, 1, a2 # e0 : | ||
162 | bne t8, $u_late_head_exit # .. e1 : | ||
163 | |||
164 | /* Finally, we've got all the stupid leading edge cases taken care | ||
165 | of and we can set up to enter the main loop. */ | ||
166 | |||
167 | extql t2, a1, t1 # e0 : position hi-bits of lo word | ||
168 | EX( ldq_u t2, 8(a1) ) # .. e1 : read next high-order source word | ||
169 | addq a1, 8, a1 # e0 : | ||
170 | cmpbge zero, t2, t8 # e1 (stall) | ||
171 | beq a2, $u_eoc # e1 : | ||
172 | bne t8, $u_eos # e1 : | ||
173 | |||
174 | /* Unaligned copy main loop. In order to avoid reading too much, | ||
175 | the loop is structured to detect zeros in aligned source words. | ||
176 | This has, unfortunately, effectively pulled half of a loop | ||
177 | iteration out into the head and half into the tail, but it does | ||
178 | prevent nastiness from accumulating in the very thing we want | ||
179 | to run as fast as possible. | ||
180 | |||
181 | On entry to this basic block: | ||
182 | t1 == the shifted high-order bits from the previous source word | ||
183 | t2 == the unshifted current source word | ||
184 | |||
185 | We further know that t2 does not contain a null terminator. */ | ||
186 | |||
187 | .align 3 | ||
188 | $u_loop: | ||
189 | extqh t2, a1, t0 # e0 : extract high bits for current word | ||
190 | addq a1, 8, a1 # .. e1 : | ||
191 | extql t2, a1, t3 # e0 : extract low bits for next time | ||
192 | addq a0, 8, a0 # .. e1 : | ||
193 | or t0, t1, t0 # e0 : current dst word now complete | ||
194 | EX( ldq_u t2, 0(a1) ) # .. e1 : load high word for next time | ||
195 | stq_u t0, -8(a0) # e0 : save the current word | ||
196 | mov t3, t1 # .. e1 : | ||
197 | subq a2, 1, a2 # e0 : | ||
198 | cmpbge zero, t2, t8 # .. e1 : test new word for eos | ||
199 | beq a2, $u_eoc # e1 : | ||
200 | beq t8, $u_loop # e1 : | ||
201 | |||
202 | /* We've found a zero somewhere in the source word we just read. | ||
203 | If it resides in the lower half, we have one (probably partial) | ||
204 | word to write out, and if it resides in the upper half, we | ||
205 | have one full and one partial word left to write out. | ||
206 | |||
207 | On entry to this basic block: | ||
208 | t1 == the shifted high-order bits from the previous source word | ||
209 | t2 == the unshifted current source word. */ | ||
210 | $u_eos: | ||
211 | extqh t2, a1, t0 # e0 : | ||
212 | or t0, t1, t0 # e1 : first (partial) source word complete | ||
213 | |||
214 | cmpbge zero, t0, t8 # e0 : is the null in this first bit? | ||
215 | bne t8, $u_final # .. e1 (zdb) | ||
216 | |||
217 | stq_u t0, 0(a0) # e0 : the null was in the high-order bits | ||
218 | addq a0, 8, a0 # .. e1 : | ||
219 | subq a2, 1, a2 # e1 : | ||
220 | |||
221 | $u_late_head_exit: | ||
222 | extql t2, a1, t0 # .. e0 : | ||
223 | cmpbge zero, t0, t8 # e0 : | ||
224 | or t8, t10, t6 # e1 : | ||
225 | cmoveq a2, t6, t8 # e0 : | ||
226 | nop # .. e1 : | ||
227 | |||
228 | /* Take care of a final (probably partial) result word. | ||
229 | On entry to this basic block: | ||
230 | t0 == assembled source word | ||
231 | t8 == cmpbge mask that found the null. */ | ||
232 | $u_final: | ||
233 | negq t8, t6 # e0 : isolate low bit set | ||
234 | and t6, t8, t12 # e1 : | ||
235 | |||
236 | and t12, 0x80, t6 # e0 : avoid dest word load if we can | ||
237 | bne t6, 1f # .. e1 (zdb) | ||
238 | |||
239 | ldq_u t1, 0(a0) # e0 : | ||
240 | subq t12, 1, t6 # .. e1 : | ||
241 | or t6, t12, t8 # e0 : | ||
242 | zapnot t0, t8, t0 # .. e1 : kill source bytes > null | ||
243 | zap t1, t8, t1 # e0 : kill dest bytes <= null | ||
244 | or t0, t1, t0 # e1 : | ||
245 | |||
246 | 1: stq_u t0, 0(a0) # e0 : | ||
247 | br $finish_up | ||
248 | |||
249 | $u_eoc: # end-of-count | ||
250 | extqh t2, a1, t0 | ||
251 | or t0, t1, t0 | ||
252 | cmpbge zero, t0, t8 | ||
253 | |||
254 | $u_eocfin: # end-of-count, final word | ||
255 | or t10, t8, t8 | ||
256 | br $u_final | ||
257 | |||
258 | /* Unaligned copy entry point. */ | ||
259 | .align 3 | ||
260 | $unaligned: | ||
261 | |||
262 | EX( ldq_u t1, 0(a1) ) # e0 : load first source word | ||
263 | |||
264 | and a0, 7, t4 # .. e1 : find dest misalignment | ||
265 | and a1, 7, t5 # e0 : find src misalignment | ||
266 | |||
267 | /* Conditionally load the first destination word and a bytemask | ||
268 | with 0xff indicating that the destination byte is sacrosanct. */ | ||
269 | |||
270 | mov zero, t0 # .. e1 : | ||
271 | mov zero, t6 # e0 : | ||
272 | beq t4, 1f # .. e1 : | ||
273 | ldq_u t0, 0(a0) # e0 : | ||
274 | lda t6, -1 # .. e1 : | ||
275 | mskql t6, a0, t6 # e0 : | ||
276 | 1: | ||
277 | subq a1, t4, a1 # .. e1 : sub dest misalignment from src addr | ||
278 | |||
279 | /* If source misalignment is larger than dest misalignment, we need | ||
280 | extra startup checks to avoid SEGV. */ | ||
281 | |||
282 | cmplt t4, t5, t12 # e1 : | ||
283 | extql t1, a1, t1 # .. e0 : shift src into place | ||
284 | lda t2, -1 # e0 : for creating masks later | ||
285 | beq t12, $u_head # e1 : | ||
286 | |||
287 | mskqh t2, t5, t2 # e0 : begin src byte validity mask | ||
288 | cmpbge zero, t1, t8 # .. e1 : is there a zero? | ||
289 | extql t2, a1, t2 # e0 : | ||
290 | or t8, t10, t5 # .. e1 : test for end-of-count too | ||
291 | cmpbge zero, t2, t3 # e0 : | ||
292 | cmoveq a2, t5, t8 # .. e1 : | ||
293 | andnot t8, t3, t8 # e0 : | ||
294 | beq t8, $u_head # .. e1 (zdb) | ||
295 | |||
296 | /* At this point we've found a zero in the first partial word of | ||
297 | the source. We need to isolate the valid source data and mask | ||
298 | it into the original destination data. (Incidentally, we know | ||
299 | that we'll need at least one byte of that original dest word.) */ | ||
300 | |||
301 | ldq_u t0, 0(a0) # e0 : | ||
302 | negq t8, t6 # .. e1 : build bitmask of bytes <= zero | ||
303 | mskqh t1, t4, t1 # e0 : | ||
304 | and t6, t8, t12 # .. e1 : | ||
305 | subq t12, 1, t6 # e0 : | ||
306 | or t6, t12, t8 # e1 : | ||
307 | |||
308 | zapnot t2, t8, t2 # e0 : prepare source word; mirror changes | ||
309 | zapnot t1, t8, t1 # .. e1 : to source validity mask | ||
310 | |||
311 | andnot t0, t2, t0 # e0 : zero place for source to reside | ||
312 | or t0, t1, t0 # e1 : and put it there | ||
313 | stq_u t0, 0(a0) # e0 : | ||
314 | |||
315 | $finish_up: | ||
316 | zapnot t0, t12, t4 # was last byte written null? | ||
317 | cmovne t4, 1, t4 | ||
318 | |||
319 | and t12, 0xf0, t3 # binary search for the address of the | ||
320 | and t12, 0xcc, t2 # last byte written | ||
321 | and t12, 0xaa, t1 | ||
322 | bic a0, 7, t0 | ||
323 | cmovne t3, 4, t3 | ||
324 | cmovne t2, 2, t2 | ||
325 | cmovne t1, 1, t1 | ||
326 | addq t0, t3, t0 | ||
327 | addq t1, t2, t1 | ||
328 | addq t0, t1, t0 | ||
329 | addq t0, t4, t0 # add one if we filled the buffer | ||
330 | |||
331 | subq t0, v0, v0 # find string length | ||
332 | ret | ||
333 | |||
334 | $zerolength: | ||
335 | clr v0 | ||
336 | $exception: | ||
337 | ret | ||
338 | |||
339 | .end __strncpy_from_user | ||
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c index 5eecab1a84ef..0c4132dd3507 100644 --- a/arch/alpha/mm/fault.c +++ b/arch/alpha/mm/fault.c | |||
@@ -89,6 +89,8 @@ do_page_fault(unsigned long address, unsigned long mmcsr, | |||
89 | const struct exception_table_entry *fixup; | 89 | const struct exception_table_entry *fixup; |
90 | int fault, si_code = SEGV_MAPERR; | 90 | int fault, si_code = SEGV_MAPERR; |
91 | siginfo_t info; | 91 | siginfo_t info; |
92 | unsigned int flags = (FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE | | ||
93 | (cause > 0 ? FAULT_FLAG_WRITE : 0)); | ||
92 | 94 | ||
93 | /* As of EV6, a load into $31/$f31 is a prefetch, and never faults | 95 | /* As of EV6, a load into $31/$f31 is a prefetch, and never faults |
94 | (or is suppressed by the PALcode). Support that for older CPUs | 96 | (or is suppressed by the PALcode). Support that for older CPUs |
@@ -114,6 +116,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr, | |||
114 | goto vmalloc_fault; | 116 | goto vmalloc_fault; |
115 | #endif | 117 | #endif |
116 | 118 | ||
119 | retry: | ||
117 | down_read(&mm->mmap_sem); | 120 | down_read(&mm->mmap_sem); |
118 | vma = find_vma(mm, address); | 121 | vma = find_vma(mm, address); |
119 | if (!vma) | 122 | if (!vma) |
@@ -144,8 +147,11 @@ do_page_fault(unsigned long address, unsigned long mmcsr, | |||
144 | /* If for any reason at all we couldn't handle the fault, | 147 | /* If for any reason at all we couldn't handle the fault, |
145 | make sure we exit gracefully rather than endlessly redo | 148 | make sure we exit gracefully rather than endlessly redo |
146 | the fault. */ | 149 | the fault. */ |
147 | fault = handle_mm_fault(mm, vma, address, cause > 0 ? FAULT_FLAG_WRITE : 0); | 150 | fault = handle_mm_fault(mm, vma, address, flags); |
148 | up_read(&mm->mmap_sem); | 151 | |
152 | if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) | ||
153 | return; | ||
154 | |||
149 | if (unlikely(fault & VM_FAULT_ERROR)) { | 155 | if (unlikely(fault & VM_FAULT_ERROR)) { |
150 | if (fault & VM_FAULT_OOM) | 156 | if (fault & VM_FAULT_OOM) |
151 | goto out_of_memory; | 157 | goto out_of_memory; |
@@ -153,10 +159,26 @@ do_page_fault(unsigned long address, unsigned long mmcsr, | |||
153 | goto do_sigbus; | 159 | goto do_sigbus; |
154 | BUG(); | 160 | BUG(); |
155 | } | 161 | } |
156 | if (fault & VM_FAULT_MAJOR) | 162 | |
157 | current->maj_flt++; | 163 | if (flags & FAULT_FLAG_ALLOW_RETRY) { |
158 | else | 164 | if (fault & VM_FAULT_MAJOR) |
159 | current->min_flt++; | 165 | current->maj_flt++; |
166 | else | ||
167 | current->min_flt++; | ||
168 | if (fault & VM_FAULT_RETRY) { | ||
169 | flags &= ~FAULT_FLAG_ALLOW_RETRY; | ||
170 | |||
171 | /* No need to up_read(&mm->mmap_sem) as we would | ||
172 | * have already released it in __lock_page_or_retry | ||
173 | * in mm/filemap.c. | ||
174 | */ | ||
175 | |||
176 | goto retry; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | up_read(&mm->mmap_sem); | ||
181 | |||
160 | return; | 182 | return; |
161 | 183 | ||
162 | /* Something tried to access memory that isn't in our memory map. | 184 | /* Something tried to access memory that isn't in our memory map. |
@@ -186,12 +208,14 @@ do_page_fault(unsigned long address, unsigned long mmcsr, | |||
186 | /* We ran out of memory, or some other thing happened to us that | 208 | /* We ran out of memory, or some other thing happened to us that |
187 | made us unable to handle the page fault gracefully. */ | 209 | made us unable to handle the page fault gracefully. */ |
188 | out_of_memory: | 210 | out_of_memory: |
211 | up_read(&mm->mmap_sem); | ||
189 | if (!user_mode(regs)) | 212 | if (!user_mode(regs)) |
190 | goto no_context; | 213 | goto no_context; |
191 | pagefault_out_of_memory(); | 214 | pagefault_out_of_memory(); |
192 | return; | 215 | return; |
193 | 216 | ||
194 | do_sigbus: | 217 | do_sigbus: |
218 | up_read(&mm->mmap_sem); | ||
195 | /* Send a sigbus, regardless of whether we were in kernel | 219 | /* Send a sigbus, regardless of whether we were in kernel |
196 | or user mode. */ | 220 | or user mode. */ |
197 | info.si_signo = SIGBUS; | 221 | info.si_signo = SIGBUS; |
diff --git a/arch/alpha/oprofile/common.c b/arch/alpha/oprofile/common.c index a0a5d27aa215..b8ce18f485d3 100644 --- a/arch/alpha/oprofile/common.c +++ b/arch/alpha/oprofile/common.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/smp.h> | 12 | #include <linux/smp.h> |
13 | #include <linux/errno.h> | 13 | #include <linux/errno.h> |
14 | #include <asm/ptrace.h> | 14 | #include <asm/ptrace.h> |
15 | #include <asm/special_insns.h> | ||
15 | 16 | ||
16 | #include "op_impl.h" | 17 | #include "op_impl.h" |
17 | 18 | ||
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 7980873525b2..6d6e18fee9fe 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -38,7 +38,6 @@ config ARM | |||
38 | select HARDIRQS_SW_RESEND | 38 | select HARDIRQS_SW_RESEND |
39 | select GENERIC_IRQ_PROBE | 39 | select GENERIC_IRQ_PROBE |
40 | select GENERIC_IRQ_SHOW | 40 | select GENERIC_IRQ_SHOW |
41 | select GENERIC_IRQ_PROBE | ||
42 | select ARCH_WANT_IPC_PARSE_VERSION | 41 | select ARCH_WANT_IPC_PARSE_VERSION |
43 | select HARDIRQS_SW_RESEND | 42 | select HARDIRQS_SW_RESEND |
44 | select CPU_PM if (SUSPEND || CPU_IDLE) | 43 | select CPU_PM if (SUSPEND || CPU_IDLE) |
@@ -126,11 +125,6 @@ config TRACE_IRQFLAGS_SUPPORT | |||
126 | bool | 125 | bool |
127 | default y | 126 | default y |
128 | 127 | ||
129 | config GENERIC_LOCKBREAK | ||
130 | bool | ||
131 | default y | ||
132 | depends on SMP && PREEMPT | ||
133 | |||
134 | config RWSEM_GENERIC_SPINLOCK | 128 | config RWSEM_GENERIC_SPINLOCK |
135 | bool | 129 | bool |
136 | default y | 130 | default y |
@@ -1151,6 +1145,7 @@ config PLAT_ORION | |||
1151 | bool | 1145 | bool |
1152 | select CLKSRC_MMIO | 1146 | select CLKSRC_MMIO |
1153 | select GENERIC_IRQ_CHIP | 1147 | select GENERIC_IRQ_CHIP |
1148 | select IRQ_DOMAIN | ||
1154 | select COMMON_CLK | 1149 | select COMMON_CLK |
1155 | 1150 | ||
1156 | config PLAT_PXA | 1151 | config PLAT_PXA |
diff --git a/arch/arm/boot/dts/armada-xp.dtsi b/arch/arm/boot/dts/armada-xp.dtsi index e1fa7e6edfe8..71d6b5d0daf1 100644 --- a/arch/arm/boot/dts/armada-xp.dtsi +++ b/arch/arm/boot/dts/armada-xp.dtsi | |||
@@ -12,7 +12,7 @@ | |||
12 | * License version 2. This program is licensed "as is" without any | 12 | * License version 2. This program is licensed "as is" without any |
13 | * warranty of any kind, whether express or implied. | 13 | * warranty of any kind, whether express or implied. |
14 | * | 14 | * |
15 | * Contains definitions specific to the Armada 370 SoC that are not | 15 | * Contains definitions specific to the Armada XP SoC that are not |
16 | * common to all Armada SoCs. | 16 | * common to all Armada SoCs. |
17 | */ | 17 | */ |
18 | 18 | ||
diff --git a/arch/arm/boot/dts/imx23.dtsi b/arch/arm/boot/dts/imx23.dtsi index a874dbfb5ae6..e6138310e5ce 100644 --- a/arch/arm/boot/dts/imx23.dtsi +++ b/arch/arm/boot/dts/imx23.dtsi | |||
@@ -51,11 +51,11 @@ | |||
51 | 51 | ||
52 | dma-apbh@80004000 { | 52 | dma-apbh@80004000 { |
53 | compatible = "fsl,imx23-dma-apbh"; | 53 | compatible = "fsl,imx23-dma-apbh"; |
54 | reg = <0x80004000 2000>; | 54 | reg = <0x80004000 0x2000>; |
55 | }; | 55 | }; |
56 | 56 | ||
57 | ecc@80008000 { | 57 | ecc@80008000 { |
58 | reg = <0x80008000 2000>; | 58 | reg = <0x80008000 0x2000>; |
59 | status = "disabled"; | 59 | status = "disabled"; |
60 | }; | 60 | }; |
61 | 61 | ||
@@ -63,7 +63,7 @@ | |||
63 | compatible = "fsl,imx23-gpmi-nand"; | 63 | compatible = "fsl,imx23-gpmi-nand"; |
64 | #address-cells = <1>; | 64 | #address-cells = <1>; |
65 | #size-cells = <1>; | 65 | #size-cells = <1>; |
66 | reg = <0x8000c000 2000>, <0x8000a000 2000>; | 66 | reg = <0x8000c000 0x2000>, <0x8000a000 0x2000>; |
67 | reg-names = "gpmi-nand", "bch"; | 67 | reg-names = "gpmi-nand", "bch"; |
68 | interrupts = <13>, <56>; | 68 | interrupts = <13>, <56>; |
69 | interrupt-names = "gpmi-dma", "bch"; | 69 | interrupt-names = "gpmi-dma", "bch"; |
@@ -72,14 +72,14 @@ | |||
72 | }; | 72 | }; |
73 | 73 | ||
74 | ssp0: ssp@80010000 { | 74 | ssp0: ssp@80010000 { |
75 | reg = <0x80010000 2000>; | 75 | reg = <0x80010000 0x2000>; |
76 | interrupts = <15 14>; | 76 | interrupts = <15 14>; |
77 | fsl,ssp-dma-channel = <1>; | 77 | fsl,ssp-dma-channel = <1>; |
78 | status = "disabled"; | 78 | status = "disabled"; |
79 | }; | 79 | }; |
80 | 80 | ||
81 | etm@80014000 { | 81 | etm@80014000 { |
82 | reg = <0x80014000 2000>; | 82 | reg = <0x80014000 0x2000>; |
83 | status = "disabled"; | 83 | status = "disabled"; |
84 | }; | 84 | }; |
85 | 85 | ||
@@ -87,7 +87,7 @@ | |||
87 | #address-cells = <1>; | 87 | #address-cells = <1>; |
88 | #size-cells = <0>; | 88 | #size-cells = <0>; |
89 | compatible = "fsl,imx23-pinctrl", "simple-bus"; | 89 | compatible = "fsl,imx23-pinctrl", "simple-bus"; |
90 | reg = <0x80018000 2000>; | 90 | reg = <0x80018000 0x2000>; |
91 | 91 | ||
92 | gpio0: gpio@0 { | 92 | gpio0: gpio@0 { |
93 | compatible = "fsl,imx23-gpio", "fsl,mxs-gpio"; | 93 | compatible = "fsl,imx23-gpio", "fsl,mxs-gpio"; |
@@ -273,32 +273,32 @@ | |||
273 | }; | 273 | }; |
274 | 274 | ||
275 | emi@80020000 { | 275 | emi@80020000 { |
276 | reg = <0x80020000 2000>; | 276 | reg = <0x80020000 0x2000>; |
277 | status = "disabled"; | 277 | status = "disabled"; |
278 | }; | 278 | }; |
279 | 279 | ||
280 | dma-apbx@80024000 { | 280 | dma-apbx@80024000 { |
281 | compatible = "fsl,imx23-dma-apbx"; | 281 | compatible = "fsl,imx23-dma-apbx"; |
282 | reg = <0x80024000 2000>; | 282 | reg = <0x80024000 0x2000>; |
283 | }; | 283 | }; |
284 | 284 | ||
285 | dcp@80028000 { | 285 | dcp@80028000 { |
286 | reg = <0x80028000 2000>; | 286 | reg = <0x80028000 0x2000>; |
287 | status = "disabled"; | 287 | status = "disabled"; |
288 | }; | 288 | }; |
289 | 289 | ||
290 | pxp@8002a000 { | 290 | pxp@8002a000 { |
291 | reg = <0x8002a000 2000>; | 291 | reg = <0x8002a000 0x2000>; |
292 | status = "disabled"; | 292 | status = "disabled"; |
293 | }; | 293 | }; |
294 | 294 | ||
295 | ocotp@8002c000 { | 295 | ocotp@8002c000 { |
296 | reg = <0x8002c000 2000>; | 296 | reg = <0x8002c000 0x2000>; |
297 | status = "disabled"; | 297 | status = "disabled"; |
298 | }; | 298 | }; |
299 | 299 | ||
300 | axi-ahb@8002e000 { | 300 | axi-ahb@8002e000 { |
301 | reg = <0x8002e000 2000>; | 301 | reg = <0x8002e000 0x2000>; |
302 | status = "disabled"; | 302 | status = "disabled"; |
303 | }; | 303 | }; |
304 | 304 | ||
@@ -310,14 +310,14 @@ | |||
310 | }; | 310 | }; |
311 | 311 | ||
312 | ssp1: ssp@80034000 { | 312 | ssp1: ssp@80034000 { |
313 | reg = <0x80034000 2000>; | 313 | reg = <0x80034000 0x2000>; |
314 | interrupts = <2 20>; | 314 | interrupts = <2 20>; |
315 | fsl,ssp-dma-channel = <2>; | 315 | fsl,ssp-dma-channel = <2>; |
316 | status = "disabled"; | 316 | status = "disabled"; |
317 | }; | 317 | }; |
318 | 318 | ||
319 | tvenc@80038000 { | 319 | tvenc@80038000 { |
320 | reg = <0x80038000 2000>; | 320 | reg = <0x80038000 0x2000>; |
321 | status = "disabled"; | 321 | status = "disabled"; |
322 | }; | 322 | }; |
323 | }; | 323 | }; |
@@ -330,37 +330,37 @@ | |||
330 | ranges; | 330 | ranges; |
331 | 331 | ||
332 | clkctl@80040000 { | 332 | clkctl@80040000 { |
333 | reg = <0x80040000 2000>; | 333 | reg = <0x80040000 0x2000>; |
334 | status = "disabled"; | 334 | status = "disabled"; |
335 | }; | 335 | }; |
336 | 336 | ||
337 | saif0: saif@80042000 { | 337 | saif0: saif@80042000 { |
338 | reg = <0x80042000 2000>; | 338 | reg = <0x80042000 0x2000>; |
339 | status = "disabled"; | 339 | status = "disabled"; |
340 | }; | 340 | }; |
341 | 341 | ||
342 | power@80044000 { | 342 | power@80044000 { |
343 | reg = <0x80044000 2000>; | 343 | reg = <0x80044000 0x2000>; |
344 | status = "disabled"; | 344 | status = "disabled"; |
345 | }; | 345 | }; |
346 | 346 | ||
347 | saif1: saif@80046000 { | 347 | saif1: saif@80046000 { |
348 | reg = <0x80046000 2000>; | 348 | reg = <0x80046000 0x2000>; |
349 | status = "disabled"; | 349 | status = "disabled"; |
350 | }; | 350 | }; |
351 | 351 | ||
352 | audio-out@80048000 { | 352 | audio-out@80048000 { |
353 | reg = <0x80048000 2000>; | 353 | reg = <0x80048000 0x2000>; |
354 | status = "disabled"; | 354 | status = "disabled"; |
355 | }; | 355 | }; |
356 | 356 | ||
357 | audio-in@8004c000 { | 357 | audio-in@8004c000 { |
358 | reg = <0x8004c000 2000>; | 358 | reg = <0x8004c000 0x2000>; |
359 | status = "disabled"; | 359 | status = "disabled"; |
360 | }; | 360 | }; |
361 | 361 | ||
362 | lradc@80050000 { | 362 | lradc@80050000 { |
363 | reg = <0x80050000 2000>; | 363 | reg = <0x80050000 0x2000>; |
364 | status = "disabled"; | 364 | status = "disabled"; |
365 | }; | 365 | }; |
366 | 366 | ||
@@ -370,26 +370,26 @@ | |||
370 | }; | 370 | }; |
371 | 371 | ||
372 | i2c@80058000 { | 372 | i2c@80058000 { |
373 | reg = <0x80058000 2000>; | 373 | reg = <0x80058000 0x2000>; |
374 | status = "disabled"; | 374 | status = "disabled"; |
375 | }; | 375 | }; |
376 | 376 | ||
377 | rtc@8005c000 { | 377 | rtc@8005c000 { |
378 | compatible = "fsl,imx23-rtc", "fsl,stmp3xxx-rtc"; | 378 | compatible = "fsl,imx23-rtc", "fsl,stmp3xxx-rtc"; |
379 | reg = <0x8005c000 2000>; | 379 | reg = <0x8005c000 0x2000>; |
380 | interrupts = <22>; | 380 | interrupts = <22>; |
381 | }; | 381 | }; |
382 | 382 | ||
383 | pwm: pwm@80064000 { | 383 | pwm: pwm@80064000 { |
384 | compatible = "fsl,imx23-pwm"; | 384 | compatible = "fsl,imx23-pwm"; |
385 | reg = <0x80064000 2000>; | 385 | reg = <0x80064000 0x2000>; |
386 | #pwm-cells = <2>; | 386 | #pwm-cells = <2>; |
387 | fsl,pwm-number = <5>; | 387 | fsl,pwm-number = <5>; |
388 | status = "disabled"; | 388 | status = "disabled"; |
389 | }; | 389 | }; |
390 | 390 | ||
391 | timrot@80068000 { | 391 | timrot@80068000 { |
392 | reg = <0x80068000 2000>; | 392 | reg = <0x80068000 0x2000>; |
393 | status = "disabled"; | 393 | status = "disabled"; |
394 | }; | 394 | }; |
395 | 395 | ||
@@ -429,7 +429,7 @@ | |||
429 | ranges; | 429 | ranges; |
430 | 430 | ||
431 | usbctrl@80080000 { | 431 | usbctrl@80080000 { |
432 | reg = <0x80080000 0x10000>; | 432 | reg = <0x80080000 0x40000>; |
433 | status = "disabled"; | 433 | status = "disabled"; |
434 | }; | 434 | }; |
435 | }; | 435 | }; |
diff --git a/arch/arm/boot/dts/imx27-3ds.dts b/arch/arm/boot/dts/imx27-3ds.dts index d3f8296e19e0..0a8978a40ece 100644 --- a/arch/arm/boot/dts/imx27-3ds.dts +++ b/arch/arm/boot/dts/imx27-3ds.dts | |||
@@ -27,7 +27,7 @@ | |||
27 | status = "okay"; | 27 | status = "okay"; |
28 | }; | 28 | }; |
29 | 29 | ||
30 | uart@1000a000 { | 30 | uart1: serial@1000a000 { |
31 | fsl,uart-has-rtscts; | 31 | fsl,uart-has-rtscts; |
32 | status = "okay"; | 32 | status = "okay"; |
33 | }; | 33 | }; |
diff --git a/arch/arm/boot/dts/imx27.dtsi b/arch/arm/boot/dts/imx27.dtsi index 00bae3aad5ab..5303ab680a34 100644 --- a/arch/arm/boot/dts/imx27.dtsi +++ b/arch/arm/boot/dts/imx27.dtsi | |||
@@ -19,6 +19,12 @@ | |||
19 | serial3 = &uart4; | 19 | serial3 = &uart4; |
20 | serial4 = &uart5; | 20 | serial4 = &uart5; |
21 | serial5 = &uart6; | 21 | serial5 = &uart6; |
22 | gpio0 = &gpio1; | ||
23 | gpio1 = &gpio2; | ||
24 | gpio2 = &gpio3; | ||
25 | gpio3 = &gpio4; | ||
26 | gpio4 = &gpio5; | ||
27 | gpio5 = &gpio6; | ||
22 | }; | 28 | }; |
23 | 29 | ||
24 | avic: avic-interrupt-controller@e0000000 { | 30 | avic: avic-interrupt-controller@e0000000 { |
diff --git a/arch/arm/boot/dts/imx28.dtsi b/arch/arm/boot/dts/imx28.dtsi index 787efac68da8..3fa6d190fab4 100644 --- a/arch/arm/boot/dts/imx28.dtsi +++ b/arch/arm/boot/dts/imx28.dtsi | |||
@@ -57,18 +57,18 @@ | |||
57 | }; | 57 | }; |
58 | 58 | ||
59 | hsadc@80002000 { | 59 | hsadc@80002000 { |
60 | reg = <0x80002000 2000>; | 60 | reg = <0x80002000 0x2000>; |
61 | interrupts = <13 87>; | 61 | interrupts = <13 87>; |
62 | status = "disabled"; | 62 | status = "disabled"; |
63 | }; | 63 | }; |
64 | 64 | ||
65 | dma-apbh@80004000 { | 65 | dma-apbh@80004000 { |
66 | compatible = "fsl,imx28-dma-apbh"; | 66 | compatible = "fsl,imx28-dma-apbh"; |
67 | reg = <0x80004000 2000>; | 67 | reg = <0x80004000 0x2000>; |
68 | }; | 68 | }; |
69 | 69 | ||
70 | perfmon@80006000 { | 70 | perfmon@80006000 { |
71 | reg = <0x80006000 800>; | 71 | reg = <0x80006000 0x800>; |
72 | interrupts = <27>; | 72 | interrupts = <27>; |
73 | status = "disabled"; | 73 | status = "disabled"; |
74 | }; | 74 | }; |
@@ -77,7 +77,7 @@ | |||
77 | compatible = "fsl,imx28-gpmi-nand"; | 77 | compatible = "fsl,imx28-gpmi-nand"; |
78 | #address-cells = <1>; | 78 | #address-cells = <1>; |
79 | #size-cells = <1>; | 79 | #size-cells = <1>; |
80 | reg = <0x8000c000 2000>, <0x8000a000 2000>; | 80 | reg = <0x8000c000 0x2000>, <0x8000a000 0x2000>; |
81 | reg-names = "gpmi-nand", "bch"; | 81 | reg-names = "gpmi-nand", "bch"; |
82 | interrupts = <88>, <41>; | 82 | interrupts = <88>, <41>; |
83 | interrupt-names = "gpmi-dma", "bch"; | 83 | interrupt-names = "gpmi-dma", "bch"; |
@@ -86,28 +86,28 @@ | |||
86 | }; | 86 | }; |
87 | 87 | ||
88 | ssp0: ssp@80010000 { | 88 | ssp0: ssp@80010000 { |
89 | reg = <0x80010000 2000>; | 89 | reg = <0x80010000 0x2000>; |
90 | interrupts = <96 82>; | 90 | interrupts = <96 82>; |
91 | fsl,ssp-dma-channel = <0>; | 91 | fsl,ssp-dma-channel = <0>; |
92 | status = "disabled"; | 92 | status = "disabled"; |
93 | }; | 93 | }; |
94 | 94 | ||
95 | ssp1: ssp@80012000 { | 95 | ssp1: ssp@80012000 { |
96 | reg = <0x80012000 2000>; | 96 | reg = <0x80012000 0x2000>; |
97 | interrupts = <97 83>; | 97 | interrupts = <97 83>; |
98 | fsl,ssp-dma-channel = <1>; | 98 | fsl,ssp-dma-channel = <1>; |
99 | status = "disabled"; | 99 | status = "disabled"; |
100 | }; | 100 | }; |
101 | 101 | ||
102 | ssp2: ssp@80014000 { | 102 | ssp2: ssp@80014000 { |
103 | reg = <0x80014000 2000>; | 103 | reg = <0x80014000 0x2000>; |
104 | interrupts = <98 84>; | 104 | interrupts = <98 84>; |
105 | fsl,ssp-dma-channel = <2>; | 105 | fsl,ssp-dma-channel = <2>; |
106 | status = "disabled"; | 106 | status = "disabled"; |
107 | }; | 107 | }; |
108 | 108 | ||
109 | ssp3: ssp@80016000 { | 109 | ssp3: ssp@80016000 { |
110 | reg = <0x80016000 2000>; | 110 | reg = <0x80016000 0x2000>; |
111 | interrupts = <99 85>; | 111 | interrupts = <99 85>; |
112 | fsl,ssp-dma-channel = <3>; | 112 | fsl,ssp-dma-channel = <3>; |
113 | status = "disabled"; | 113 | status = "disabled"; |
@@ -117,7 +117,7 @@ | |||
117 | #address-cells = <1>; | 117 | #address-cells = <1>; |
118 | #size-cells = <0>; | 118 | #size-cells = <0>; |
119 | compatible = "fsl,imx28-pinctrl", "simple-bus"; | 119 | compatible = "fsl,imx28-pinctrl", "simple-bus"; |
120 | reg = <0x80018000 2000>; | 120 | reg = <0x80018000 0x2000>; |
121 | 121 | ||
122 | gpio0: gpio@0 { | 122 | gpio0: gpio@0 { |
123 | compatible = "fsl,imx28-gpio", "fsl,mxs-gpio"; | 123 | compatible = "fsl,imx28-gpio", "fsl,mxs-gpio"; |
@@ -510,96 +510,96 @@ | |||
510 | }; | 510 | }; |
511 | 511 | ||
512 | digctl@8001c000 { | 512 | digctl@8001c000 { |
513 | reg = <0x8001c000 2000>; | 513 | reg = <0x8001c000 0x2000>; |
514 | interrupts = <89>; | 514 | interrupts = <89>; |
515 | status = "disabled"; | 515 | status = "disabled"; |
516 | }; | 516 | }; |
517 | 517 | ||
518 | etm@80022000 { | 518 | etm@80022000 { |
519 | reg = <0x80022000 2000>; | 519 | reg = <0x80022000 0x2000>; |
520 | status = "disabled"; | 520 | status = "disabled"; |
521 | }; | 521 | }; |
522 | 522 | ||
523 | dma-apbx@80024000 { | 523 | dma-apbx@80024000 { |
524 | compatible = "fsl,imx28-dma-apbx"; | 524 | compatible = "fsl,imx28-dma-apbx"; |
525 | reg = <0x80024000 2000>; | 525 | reg = <0x80024000 0x2000>; |
526 | }; | 526 | }; |
527 | 527 | ||
528 | dcp@80028000 { | 528 | dcp@80028000 { |
529 | reg = <0x80028000 2000>; | 529 | reg = <0x80028000 0x2000>; |
530 | interrupts = <52 53 54>; | 530 | interrupts = <52 53 54>; |
531 | status = "disabled"; | 531 | status = "disabled"; |
532 | }; | 532 | }; |
533 | 533 | ||
534 | pxp@8002a000 { | 534 | pxp@8002a000 { |
535 | reg = <0x8002a000 2000>; | 535 | reg = <0x8002a000 0x2000>; |
536 | interrupts = <39>; | 536 | interrupts = <39>; |
537 | status = "disabled"; | 537 | status = "disabled"; |
538 | }; | 538 | }; |
539 | 539 | ||
540 | ocotp@8002c000 { | 540 | ocotp@8002c000 { |
541 | reg = <0x8002c000 2000>; | 541 | reg = <0x8002c000 0x2000>; |
542 | status = "disabled"; | 542 | status = "disabled"; |
543 | }; | 543 | }; |
544 | 544 | ||
545 | axi-ahb@8002e000 { | 545 | axi-ahb@8002e000 { |
546 | reg = <0x8002e000 2000>; | 546 | reg = <0x8002e000 0x2000>; |
547 | status = "disabled"; | 547 | status = "disabled"; |
548 | }; | 548 | }; |
549 | 549 | ||
550 | lcdif@80030000 { | 550 | lcdif@80030000 { |
551 | compatible = "fsl,imx28-lcdif"; | 551 | compatible = "fsl,imx28-lcdif"; |
552 | reg = <0x80030000 2000>; | 552 | reg = <0x80030000 0x2000>; |
553 | interrupts = <38 86>; | 553 | interrupts = <38 86>; |
554 | status = "disabled"; | 554 | status = "disabled"; |
555 | }; | 555 | }; |
556 | 556 | ||
557 | can0: can@80032000 { | 557 | can0: can@80032000 { |
558 | compatible = "fsl,imx28-flexcan", "fsl,p1010-flexcan"; | 558 | compatible = "fsl,imx28-flexcan", "fsl,p1010-flexcan"; |
559 | reg = <0x80032000 2000>; | 559 | reg = <0x80032000 0x2000>; |
560 | interrupts = <8>; | 560 | interrupts = <8>; |
561 | status = "disabled"; | 561 | status = "disabled"; |
562 | }; | 562 | }; |
563 | 563 | ||
564 | can1: can@80034000 { | 564 | can1: can@80034000 { |
565 | compatible = "fsl,imx28-flexcan", "fsl,p1010-flexcan"; | 565 | compatible = "fsl,imx28-flexcan", "fsl,p1010-flexcan"; |
566 | reg = <0x80034000 2000>; | 566 | reg = <0x80034000 0x2000>; |
567 | interrupts = <9>; | 567 | interrupts = <9>; |
568 | status = "disabled"; | 568 | status = "disabled"; |
569 | }; | 569 | }; |
570 | 570 | ||
571 | simdbg@8003c000 { | 571 | simdbg@8003c000 { |
572 | reg = <0x8003c000 200>; | 572 | reg = <0x8003c000 0x200>; |
573 | status = "disabled"; | 573 | status = "disabled"; |
574 | }; | 574 | }; |
575 | 575 | ||
576 | simgpmisel@8003c200 { | 576 | simgpmisel@8003c200 { |
577 | reg = <0x8003c200 100>; | 577 | reg = <0x8003c200 0x100>; |
578 | status = "disabled"; | 578 | status = "disabled"; |
579 | }; | 579 | }; |
580 | 580 | ||
581 | simsspsel@8003c300 { | 581 | simsspsel@8003c300 { |
582 | reg = <0x8003c300 100>; | 582 | reg = <0x8003c300 0x100>; |
583 | status = "disabled"; | 583 | status = "disabled"; |
584 | }; | 584 | }; |
585 | 585 | ||
586 | simmemsel@8003c400 { | 586 | simmemsel@8003c400 { |
587 | reg = <0x8003c400 100>; | 587 | reg = <0x8003c400 0x100>; |
588 | status = "disabled"; | 588 | status = "disabled"; |
589 | }; | 589 | }; |
590 | 590 | ||
591 | gpiomon@8003c500 { | 591 | gpiomon@8003c500 { |
592 | reg = <0x8003c500 100>; | 592 | reg = <0x8003c500 0x100>; |
593 | status = "disabled"; | 593 | status = "disabled"; |
594 | }; | 594 | }; |
595 | 595 | ||
596 | simenet@8003c700 { | 596 | simenet@8003c700 { |
597 | reg = <0x8003c700 100>; | 597 | reg = <0x8003c700 0x100>; |
598 | status = "disabled"; | 598 | status = "disabled"; |
599 | }; | 599 | }; |
600 | 600 | ||
601 | armjtag@8003c800 { | 601 | armjtag@8003c800 { |
602 | reg = <0x8003c800 100>; | 602 | reg = <0x8003c800 0x100>; |
603 | status = "disabled"; | 603 | status = "disabled"; |
604 | }; | 604 | }; |
605 | }; | 605 | }; |
@@ -612,45 +612,45 @@ | |||
612 | ranges; | 612 | ranges; |
613 | 613 | ||
614 | clkctl@80040000 { | 614 | clkctl@80040000 { |
615 | reg = <0x80040000 2000>; | 615 | reg = <0x80040000 0x2000>; |
616 | status = "disabled"; | 616 | status = "disabled"; |
617 | }; | 617 | }; |
618 | 618 | ||
619 | saif0: saif@80042000 { | 619 | saif0: saif@80042000 { |
620 | compatible = "fsl,imx28-saif"; | 620 | compatible = "fsl,imx28-saif"; |
621 | reg = <0x80042000 2000>; | 621 | reg = <0x80042000 0x2000>; |
622 | interrupts = <59 80>; | 622 | interrupts = <59 80>; |
623 | fsl,saif-dma-channel = <4>; | 623 | fsl,saif-dma-channel = <4>; |
624 | status = "disabled"; | 624 | status = "disabled"; |
625 | }; | 625 | }; |
626 | 626 | ||
627 | power@80044000 { | 627 | power@80044000 { |
628 | reg = <0x80044000 2000>; | 628 | reg = <0x80044000 0x2000>; |
629 | status = "disabled"; | 629 | status = "disabled"; |
630 | }; | 630 | }; |
631 | 631 | ||
632 | saif1: saif@80046000 { | 632 | saif1: saif@80046000 { |
633 | compatible = "fsl,imx28-saif"; | 633 | compatible = "fsl,imx28-saif"; |
634 | reg = <0x80046000 2000>; | 634 | reg = <0x80046000 0x2000>; |
635 | interrupts = <58 81>; | 635 | interrupts = <58 81>; |
636 | fsl,saif-dma-channel = <5>; | 636 | fsl,saif-dma-channel = <5>; |
637 | status = "disabled"; | 637 | status = "disabled"; |
638 | }; | 638 | }; |
639 | 639 | ||
640 | lradc@80050000 { | 640 | lradc@80050000 { |
641 | reg = <0x80050000 2000>; | 641 | reg = <0x80050000 0x2000>; |
642 | status = "disabled"; | 642 | status = "disabled"; |
643 | }; | 643 | }; |
644 | 644 | ||
645 | spdif@80054000 { | 645 | spdif@80054000 { |
646 | reg = <0x80054000 2000>; | 646 | reg = <0x80054000 0x2000>; |
647 | interrupts = <45 66>; | 647 | interrupts = <45 66>; |
648 | status = "disabled"; | 648 | status = "disabled"; |
649 | }; | 649 | }; |
650 | 650 | ||
651 | rtc@80056000 { | 651 | rtc@80056000 { |
652 | compatible = "fsl,imx28-rtc", "fsl,stmp3xxx-rtc"; | 652 | compatible = "fsl,imx28-rtc", "fsl,stmp3xxx-rtc"; |
653 | reg = <0x80056000 2000>; | 653 | reg = <0x80056000 0x2000>; |
654 | interrupts = <29>; | 654 | interrupts = <29>; |
655 | }; | 655 | }; |
656 | 656 | ||
@@ -658,7 +658,7 @@ | |||
658 | #address-cells = <1>; | 658 | #address-cells = <1>; |
659 | #size-cells = <0>; | 659 | #size-cells = <0>; |
660 | compatible = "fsl,imx28-i2c"; | 660 | compatible = "fsl,imx28-i2c"; |
661 | reg = <0x80058000 2000>; | 661 | reg = <0x80058000 0x2000>; |
662 | interrupts = <111 68>; | 662 | interrupts = <111 68>; |
663 | clock-frequency = <100000>; | 663 | clock-frequency = <100000>; |
664 | status = "disabled"; | 664 | status = "disabled"; |
@@ -668,7 +668,7 @@ | |||
668 | #address-cells = <1>; | 668 | #address-cells = <1>; |
669 | #size-cells = <0>; | 669 | #size-cells = <0>; |
670 | compatible = "fsl,imx28-i2c"; | 670 | compatible = "fsl,imx28-i2c"; |
671 | reg = <0x8005a000 2000>; | 671 | reg = <0x8005a000 0x2000>; |
672 | interrupts = <110 69>; | 672 | interrupts = <110 69>; |
673 | clock-frequency = <100000>; | 673 | clock-frequency = <100000>; |
674 | status = "disabled"; | 674 | status = "disabled"; |
@@ -676,14 +676,14 @@ | |||
676 | 676 | ||
677 | pwm: pwm@80064000 { | 677 | pwm: pwm@80064000 { |
678 | compatible = "fsl,imx28-pwm", "fsl,imx23-pwm"; | 678 | compatible = "fsl,imx28-pwm", "fsl,imx23-pwm"; |
679 | reg = <0x80064000 2000>; | 679 | reg = <0x80064000 0x2000>; |
680 | #pwm-cells = <2>; | 680 | #pwm-cells = <2>; |
681 | fsl,pwm-number = <8>; | 681 | fsl,pwm-number = <8>; |
682 | status = "disabled"; | 682 | status = "disabled"; |
683 | }; | 683 | }; |
684 | 684 | ||
685 | timrot@80068000 { | 685 | timrot@80068000 { |
686 | reg = <0x80068000 2000>; | 686 | reg = <0x80068000 0x2000>; |
687 | status = "disabled"; | 687 | status = "disabled"; |
688 | }; | 688 | }; |
689 | 689 | ||
diff --git a/arch/arm/boot/dts/imx51-babbage.dts b/arch/arm/boot/dts/imx51-babbage.dts index de065b5976e6..cd86177a3ea2 100644 --- a/arch/arm/boot/dts/imx51-babbage.dts +++ b/arch/arm/boot/dts/imx51-babbage.dts | |||
@@ -53,7 +53,7 @@ | |||
53 | spi-max-frequency = <6000000>; | 53 | spi-max-frequency = <6000000>; |
54 | reg = <0>; | 54 | reg = <0>; |
55 | interrupt-parent = <&gpio1>; | 55 | interrupt-parent = <&gpio1>; |
56 | interrupts = <8>; | 56 | interrupts = <8 0x4>; |
57 | 57 | ||
58 | regulators { | 58 | regulators { |
59 | sw1_reg: sw1 { | 59 | sw1_reg: sw1 { |
diff --git a/arch/arm/boot/dts/imx51.dtsi b/arch/arm/boot/dts/imx51.dtsi index 53cbaa3d4f90..aba28dc87fc8 100644 --- a/arch/arm/boot/dts/imx51.dtsi +++ b/arch/arm/boot/dts/imx51.dtsi | |||
@@ -17,6 +17,10 @@ | |||
17 | serial0 = &uart1; | 17 | serial0 = &uart1; |
18 | serial1 = &uart2; | 18 | serial1 = &uart2; |
19 | serial2 = &uart3; | 19 | serial2 = &uart3; |
20 | gpio0 = &gpio1; | ||
21 | gpio1 = &gpio2; | ||
22 | gpio2 = &gpio3; | ||
23 | gpio3 = &gpio4; | ||
20 | }; | 24 | }; |
21 | 25 | ||
22 | tzic: tz-interrupt-controller@e0000000 { | 26 | tzic: tz-interrupt-controller@e0000000 { |
diff --git a/arch/arm/boot/dts/imx53-ard.dts b/arch/arm/boot/dts/imx53-ard.dts index 5b8eafcdbeec..da895e93a999 100644 --- a/arch/arm/boot/dts/imx53-ard.dts +++ b/arch/arm/boot/dts/imx53-ard.dts | |||
@@ -64,12 +64,32 @@ | |||
64 | reg = <0xf4000000 0x2000000>; | 64 | reg = <0xf4000000 0x2000000>; |
65 | phy-mode = "mii"; | 65 | phy-mode = "mii"; |
66 | interrupt-parent = <&gpio2>; | 66 | interrupt-parent = <&gpio2>; |
67 | interrupts = <31>; | 67 | interrupts = <31 0x8>; |
68 | reg-io-width = <4>; | 68 | reg-io-width = <4>; |
69 | /* | ||
70 | * VDD33A and VDDVARIO of LAN9220 are supplied by | ||
71 | * SW4_3V3 of LTC3589. Before the regulator driver | ||
72 | * for this PMIC is available, we use a fixed dummy | ||
73 | * 3V3 regulator to get LAN9220 driver probing work. | ||
74 | */ | ||
75 | vdd33a-supply = <®_3p3v>; | ||
76 | vddvario-supply = <®_3p3v>; | ||
69 | smsc,irq-push-pull; | 77 | smsc,irq-push-pull; |
70 | }; | 78 | }; |
71 | }; | 79 | }; |
72 | 80 | ||
81 | regulators { | ||
82 | compatible = "simple-bus"; | ||
83 | |||
84 | reg_3p3v: 3p3v { | ||
85 | compatible = "regulator-fixed"; | ||
86 | regulator-name = "3P3V"; | ||
87 | regulator-min-microvolt = <3300000>; | ||
88 | regulator-max-microvolt = <3300000>; | ||
89 | regulator-always-on; | ||
90 | }; | ||
91 | }; | ||
92 | |||
73 | gpio-keys { | 93 | gpio-keys { |
74 | compatible = "gpio-keys"; | 94 | compatible = "gpio-keys"; |
75 | 95 | ||
diff --git a/arch/arm/boot/dts/imx53.dtsi b/arch/arm/boot/dts/imx53.dtsi index fc79cdc4b4e6..cd37165edce5 100644 --- a/arch/arm/boot/dts/imx53.dtsi +++ b/arch/arm/boot/dts/imx53.dtsi | |||
@@ -19,6 +19,13 @@ | |||
19 | serial2 = &uart3; | 19 | serial2 = &uart3; |
20 | serial3 = &uart4; | 20 | serial3 = &uart4; |
21 | serial4 = &uart5; | 21 | serial4 = &uart5; |
22 | gpio0 = &gpio1; | ||
23 | gpio1 = &gpio2; | ||
24 | gpio2 = &gpio3; | ||
25 | gpio3 = &gpio4; | ||
26 | gpio4 = &gpio5; | ||
27 | gpio5 = &gpio6; | ||
28 | gpio6 = &gpio7; | ||
22 | }; | 29 | }; |
23 | 30 | ||
24 | tzic: tz-interrupt-controller@0fffc000 { | 31 | tzic: tz-interrupt-controller@0fffc000 { |
diff --git a/arch/arm/boot/dts/imx6q-sabrelite.dts b/arch/arm/boot/dts/imx6q-sabrelite.dts index d42e851ceb97..72f30f3e6171 100644 --- a/arch/arm/boot/dts/imx6q-sabrelite.dts +++ b/arch/arm/boot/dts/imx6q-sabrelite.dts | |||
@@ -53,6 +53,7 @@ | |||
53 | fsl,pins = < | 53 | fsl,pins = < |
54 | 144 0x80000000 /* MX6Q_PAD_EIM_D22__GPIO_3_22 */ | 54 | 144 0x80000000 /* MX6Q_PAD_EIM_D22__GPIO_3_22 */ |
55 | 121 0x80000000 /* MX6Q_PAD_EIM_D19__GPIO_3_19 */ | 55 | 121 0x80000000 /* MX6Q_PAD_EIM_D19__GPIO_3_19 */ |
56 | 953 0x80000000 /* MX6Q_PAD_GPIO_0__CCM_CLKO */ | ||
56 | >; | 57 | >; |
57 | }; | 58 | }; |
58 | }; | 59 | }; |
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi index 3d3c64b014e6..fd57079f71a9 100644 --- a/arch/arm/boot/dts/imx6q.dtsi +++ b/arch/arm/boot/dts/imx6q.dtsi | |||
@@ -19,6 +19,13 @@ | |||
19 | serial2 = &uart3; | 19 | serial2 = &uart3; |
20 | serial3 = &uart4; | 20 | serial3 = &uart4; |
21 | serial4 = &uart5; | 21 | serial4 = &uart5; |
22 | gpio0 = &gpio1; | ||
23 | gpio1 = &gpio2; | ||
24 | gpio2 = &gpio3; | ||
25 | gpio3 = &gpio4; | ||
26 | gpio4 = &gpio5; | ||
27 | gpio5 = &gpio6; | ||
28 | gpio6 = &gpio7; | ||
22 | }; | 29 | }; |
23 | 30 | ||
24 | cpus { | 31 | cpus { |
diff --git a/arch/arm/boot/dts/kirkwood-dns320.dts b/arch/arm/boot/dts/kirkwood-dns320.dts index 9a33077130e8..5bb0bf39d3b8 100644 --- a/arch/arm/boot/dts/kirkwood-dns320.dts +++ b/arch/arm/boot/dts/kirkwood-dns320.dts | |||
@@ -1,6 +1,6 @@ | |||
1 | /dts-v1/; | 1 | /dts-v1/; |
2 | 2 | ||
3 | /include/ "kirkwood.dtsi" | 3 | /include/ "kirkwood-dnskw.dtsi" |
4 | 4 | ||
5 | / { | 5 | / { |
6 | model = "D-Link DNS-320 NAS (Rev A1)"; | 6 | model = "D-Link DNS-320 NAS (Rev A1)"; |
@@ -15,6 +15,31 @@ | |||
15 | bootargs = "console=ttyS0,115200n8 earlyprintk"; | 15 | bootargs = "console=ttyS0,115200n8 earlyprintk"; |
16 | }; | 16 | }; |
17 | 17 | ||
18 | gpio-leds { | ||
19 | compatible = "gpio-leds"; | ||
20 | blue-power { | ||
21 | label = "dns320:blue:power"; | ||
22 | gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */ | ||
23 | linux,default-trigger = "default-on"; | ||
24 | }; | ||
25 | blue-usb { | ||
26 | label = "dns320:blue:usb"; | ||
27 | gpios = <&gpio1 11 1>; /* GPIO 43 Active Low */ | ||
28 | }; | ||
29 | orange-l_hdd { | ||
30 | label = "dns320:orange:l_hdd"; | ||
31 | gpios = <&gpio0 28 1>; /* GPIO 28 Active Low */ | ||
32 | }; | ||
33 | orange-r_hdd { | ||
34 | label = "dns320:orange:r_hdd"; | ||
35 | gpios = <&gpio0 27 1>; /* GPIO 27 Active Low */ | ||
36 | }; | ||
37 | orange-usb { | ||
38 | label = "dns320:orange:usb"; | ||
39 | gpios = <&gpio1 3 1>; /* GPIO 35 Active Low */ | ||
40 | }; | ||
41 | }; | ||
42 | |||
18 | ocp@f1000000 { | 43 | ocp@f1000000 { |
19 | serial@12000 { | 44 | serial@12000 { |
20 | clock-frequency = <166666667>; | 45 | clock-frequency = <166666667>; |
@@ -25,40 +50,5 @@ | |||
25 | clock-frequency = <166666667>; | 50 | clock-frequency = <166666667>; |
26 | status = "okay"; | 51 | status = "okay"; |
27 | }; | 52 | }; |
28 | |||
29 | nand@3000000 { | ||
30 | status = "okay"; | ||
31 | |||
32 | partition@0 { | ||
33 | label = "u-boot"; | ||
34 | reg = <0x0000000 0x100000>; | ||
35 | read-only; | ||
36 | }; | ||
37 | |||
38 | partition@100000 { | ||
39 | label = "uImage"; | ||
40 | reg = <0x0100000 0x500000>; | ||
41 | }; | ||
42 | |||
43 | partition@600000 { | ||
44 | label = "ramdisk"; | ||
45 | reg = <0x0600000 0x500000>; | ||
46 | }; | ||
47 | |||
48 | partition@b00000 { | ||
49 | label = "image"; | ||
50 | reg = <0x0b00000 0x6600000>; | ||
51 | }; | ||
52 | |||
53 | partition@7100000 { | ||
54 | label = "mini firmware"; | ||
55 | reg = <0x7100000 0xa00000>; | ||
56 | }; | ||
57 | |||
58 | partition@7b00000 { | ||
59 | label = "config"; | ||
60 | reg = <0x7b00000 0x500000>; | ||
61 | }; | ||
62 | }; | ||
63 | }; | 53 | }; |
64 | }; | 54 | }; |
diff --git a/arch/arm/boot/dts/kirkwood-dns325.dts b/arch/arm/boot/dts/kirkwood-dns325.dts index 16734c1b5dfe..d430713ea9b9 100644 --- a/arch/arm/boot/dts/kirkwood-dns325.dts +++ b/arch/arm/boot/dts/kirkwood-dns325.dts | |||
@@ -1,6 +1,6 @@ | |||
1 | /dts-v1/; | 1 | /dts-v1/; |
2 | 2 | ||
3 | /include/ "kirkwood.dtsi" | 3 | /include/ "kirkwood-dnskw.dtsi" |
4 | 4 | ||
5 | / { | 5 | / { |
6 | model = "D-Link DNS-325 NAS (Rev A1)"; | 6 | model = "D-Link DNS-325 NAS (Rev A1)"; |
@@ -15,45 +15,43 @@ | |||
15 | bootargs = "console=ttyS0,115200n8 earlyprintk"; | 15 | bootargs = "console=ttyS0,115200n8 earlyprintk"; |
16 | }; | 16 | }; |
17 | 17 | ||
18 | ocp@f1000000 { | 18 | gpio-leds { |
19 | serial@12000 { | 19 | compatible = "gpio-leds"; |
20 | clock-frequency = <200000000>; | 20 | white-power { |
21 | status = "okay"; | 21 | label = "dns325:white:power"; |
22 | gpios = <&gpio0 26 1>; /* GPIO 26 Active Low */ | ||
23 | linux,default-trigger = "default-on"; | ||
24 | }; | ||
25 | white-usb { | ||
26 | label = "dns325:white:usb"; | ||
27 | gpios = <&gpio1 11 1>; /* GPIO 43 Active Low */ | ||
28 | }; | ||
29 | red-l_hdd { | ||
30 | label = "dns325:red:l_hdd"; | ||
31 | gpios = <&gpio0 28 1>; /* GPIO 28 Active Low */ | ||
22 | }; | 32 | }; |
33 | red-r_hdd { | ||
34 | label = "dns325:red:r_hdd"; | ||
35 | gpios = <&gpio0 27 1>; /* GPIO 27 Active Low */ | ||
36 | }; | ||
37 | red-usb { | ||
38 | label = "dns325:red:usb"; | ||
39 | gpios = <&gpio0 29 1>; /* GPIO 29 Active Low */ | ||
40 | }; | ||
41 | }; | ||
23 | 42 | ||
24 | nand@3000000 { | 43 | ocp@f1000000 { |
44 | i2c@11000 { | ||
25 | status = "okay"; | 45 | status = "okay"; |
26 | 46 | ||
27 | partition@0 { | 47 | lm75: lm75@48 { |
28 | label = "u-boot"; | 48 | compatible = "national,lm75"; |
29 | reg = <0x0000000 0x100000>; | 49 | reg = <0x48>; |
30 | read-only; | ||
31 | }; | ||
32 | |||
33 | partition@100000 { | ||
34 | label = "uImage"; | ||
35 | reg = <0x0100000 0x500000>; | ||
36 | }; | ||
37 | |||
38 | partition@600000 { | ||
39 | label = "ramdisk"; | ||
40 | reg = <0x0600000 0x500000>; | ||
41 | }; | ||
42 | |||
43 | partition@b00000 { | ||
44 | label = "image"; | ||
45 | reg = <0x0b00000 0x6600000>; | ||
46 | }; | ||
47 | |||
48 | partition@7100000 { | ||
49 | label = "mini firmware"; | ||
50 | reg = <0x7100000 0xa00000>; | ||
51 | }; | ||
52 | |||
53 | partition@7b00000 { | ||
54 | label = "config"; | ||
55 | reg = <0x7b00000 0x500000>; | ||
56 | }; | 50 | }; |
57 | }; | 51 | }; |
52 | serial@12000 { | ||
53 | clock-frequency = <200000000>; | ||
54 | status = "okay"; | ||
55 | }; | ||
58 | }; | 56 | }; |
59 | }; | 57 | }; |
diff --git a/arch/arm/boot/dts/kirkwood-dnskw.dtsi b/arch/arm/boot/dts/kirkwood-dnskw.dtsi new file mode 100644 index 000000000000..7408655f91b5 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-dnskw.dtsi | |||
@@ -0,0 +1,69 @@ | |||
1 | /include/ "kirkwood.dtsi" | ||
2 | |||
3 | / { | ||
4 | model = "D-Link DNS NASes (kirkwood-based)"; | ||
5 | compatible = "dlink,dns-kirkwood", "marvell,kirkwood-88f6281", "marvell,kirkwood"; | ||
6 | |||
7 | gpio_keys { | ||
8 | compatible = "gpio-keys"; | ||
9 | #address-cells = <1>; | ||
10 | #size-cells = <0>; | ||
11 | button@1 { | ||
12 | label = "Power button"; | ||
13 | linux,code = <116>; | ||
14 | gpios = <&gpio1 2 1>; | ||
15 | }; | ||
16 | button@2 { | ||
17 | label = "USB unmount button"; | ||
18 | linux,code = <161>; | ||
19 | gpios = <&gpio1 15 1>; | ||
20 | }; | ||
21 | button@3 { | ||
22 | label = "Reset button"; | ||
23 | linux,code = <0x198>; | ||
24 | gpios = <&gpio1 16 1>; | ||
25 | }; | ||
26 | }; | ||
27 | |||
28 | ocp@f1000000 { | ||
29 | sata@80000 { | ||
30 | status = "okay"; | ||
31 | nr-ports = <2>; | ||
32 | }; | ||
33 | |||
34 | nand@3000000 { | ||
35 | status = "okay"; | ||
36 | |||
37 | partition@0 { | ||
38 | label = "u-boot"; | ||
39 | reg = <0x0000000 0x100000>; | ||
40 | read-only; | ||
41 | }; | ||
42 | |||
43 | partition@100000 { | ||
44 | label = "uImage"; | ||
45 | reg = <0x0100000 0x500000>; | ||
46 | }; | ||
47 | |||
48 | partition@600000 { | ||
49 | label = "ramdisk"; | ||
50 | reg = <0x0600000 0x500000>; | ||
51 | }; | ||
52 | |||
53 | partition@b00000 { | ||
54 | label = "image"; | ||
55 | reg = <0x0b00000 0x6600000>; | ||
56 | }; | ||
57 | |||
58 | partition@7100000 { | ||
59 | label = "mini firmware"; | ||
60 | reg = <0x7100000 0xa00000>; | ||
61 | }; | ||
62 | |||
63 | partition@7b00000 { | ||
64 | label = "config"; | ||
65 | reg = <0x7b00000 0x500000>; | ||
66 | }; | ||
67 | }; | ||
68 | }; | ||
69 | }; | ||
diff --git a/arch/arm/boot/dts/kirkwood-dreamplug.dts b/arch/arm/boot/dts/kirkwood-dreamplug.dts index 78b0f06a09a2..26e281fbf6bc 100644 --- a/arch/arm/boot/dts/kirkwood-dreamplug.dts +++ b/arch/arm/boot/dts/kirkwood-dreamplug.dts | |||
@@ -20,5 +20,55 @@ | |||
20 | clock-frequency = <200000000>; | 20 | clock-frequency = <200000000>; |
21 | status = "ok"; | 21 | status = "ok"; |
22 | }; | 22 | }; |
23 | |||
24 | spi@10600 { | ||
25 | status = "okay"; | ||
26 | |||
27 | m25p40@0 { | ||
28 | #address-cells = <1>; | ||
29 | #size-cells = <1>; | ||
30 | compatible = "mx25l1606e"; | ||
31 | reg = <0>; | ||
32 | spi-max-frequency = <50000000>; | ||
33 | mode = <0>; | ||
34 | |||
35 | partition@0 { | ||
36 | reg = <0x0 0x80000>; | ||
37 | label = "u-boot"; | ||
38 | }; | ||
39 | |||
40 | partition@100000 { | ||
41 | reg = <0x100000 0x10000>; | ||
42 | label = "u-boot env"; | ||
43 | }; | ||
44 | |||
45 | partition@180000 { | ||
46 | reg = <0x180000 0x10000>; | ||
47 | label = "dtb"; | ||
48 | }; | ||
49 | }; | ||
50 | }; | ||
51 | |||
52 | sata@80000 { | ||
53 | status = "okay"; | ||
54 | nr-ports = <1>; | ||
55 | }; | ||
56 | }; | ||
57 | |||
58 | gpio-leds { | ||
59 | compatible = "gpio-leds"; | ||
60 | |||
61 | bluetooth { | ||
62 | label = "dreamplug:blue:bluetooth"; | ||
63 | gpios = <&gpio1 15 1>; | ||
64 | }; | ||
65 | wifi { | ||
66 | label = "dreamplug:green:wifi"; | ||
67 | gpios = <&gpio1 16 1>; | ||
68 | }; | ||
69 | wifi-ap { | ||
70 | label = "dreamplug:green:wifi_ap"; | ||
71 | gpios = <&gpio1 17 1>; | ||
72 | }; | ||
23 | }; | 73 | }; |
24 | }; | 74 | }; |
diff --git a/arch/arm/boot/dts/kirkwood-goflexnet.dts b/arch/arm/boot/dts/kirkwood-goflexnet.dts new file mode 100644 index 000000000000..7c8238fbb6f9 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-goflexnet.dts | |||
@@ -0,0 +1,99 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "kirkwood.dtsi" | ||
4 | |||
5 | / { | ||
6 | model = "Seagate GoFlex Net"; | ||
7 | compatible = "seagate,goflexnet", "marvell,kirkwood-88f6281", "marvell,kirkwood"; | ||
8 | |||
9 | memory { | ||
10 | device_type = "memory"; | ||
11 | reg = <0x00000000 0x8000000>; | ||
12 | }; | ||
13 | |||
14 | chosen { | ||
15 | bootargs = "console=ttyS0,115200n8 earlyprintk root=/dev/sda1 rootdelay=10"; | ||
16 | }; | ||
17 | |||
18 | ocp@f1000000 { | ||
19 | serial@12000 { | ||
20 | clock-frequency = <200000000>; | ||
21 | status = "ok"; | ||
22 | }; | ||
23 | |||
24 | nand@3000000 { | ||
25 | status = "okay"; | ||
26 | |||
27 | partition@0 { | ||
28 | label = "u-boot"; | ||
29 | reg = <0x0000000 0x100000>; | ||
30 | read-only; | ||
31 | }; | ||
32 | |||
33 | partition@100000 { | ||
34 | label = "uImage"; | ||
35 | reg = <0x0100000 0x400000>; | ||
36 | }; | ||
37 | |||
38 | partition@500000 { | ||
39 | label = "pogoplug"; | ||
40 | reg = <0x0500000 0x2000000>; | ||
41 | }; | ||
42 | |||
43 | partition@2500000 { | ||
44 | label = "root"; | ||
45 | reg = <0x02500000 0xd800000>; | ||
46 | }; | ||
47 | }; | ||
48 | sata@80000 { | ||
49 | status = "okay"; | ||
50 | nr-ports = <2>; | ||
51 | }; | ||
52 | |||
53 | }; | ||
54 | gpio-leds { | ||
55 | compatible = "gpio-leds"; | ||
56 | |||
57 | health { | ||
58 | label = "status:green:health"; | ||
59 | gpios = <&gpio1 14 1>; | ||
60 | linux,default-trigger = "default-on"; | ||
61 | }; | ||
62 | fault { | ||
63 | label = "status:orange:fault"; | ||
64 | gpios = <&gpio1 15 1>; | ||
65 | }; | ||
66 | left0 { | ||
67 | label = "status:white:left0"; | ||
68 | gpios = <&gpio1 10 0>; | ||
69 | }; | ||
70 | left1 { | ||
71 | label = "status:white:left1"; | ||
72 | gpios = <&gpio1 11 0>; | ||
73 | }; | ||
74 | left2 { | ||
75 | label = "status:white:left2"; | ||
76 | gpios = <&gpio1 12 0>; | ||
77 | }; | ||
78 | left3 { | ||
79 | label = "status:white:left3"; | ||
80 | gpios = <&gpio1 13 0>; | ||
81 | }; | ||
82 | right0 { | ||
83 | label = "status:white:right0"; | ||
84 | gpios = <&gpio1 6 0>; | ||
85 | }; | ||
86 | right1 { | ||
87 | label = "status:white:right1"; | ||
88 | gpios = <&gpio1 7 0>; | ||
89 | }; | ||
90 | right2 { | ||
91 | label = "status:white:right2"; | ||
92 | gpios = <&gpio1 8 0>; | ||
93 | }; | ||
94 | right3 { | ||
95 | label = "status:white:right3"; | ||
96 | gpios = <&gpio1 9 0>; | ||
97 | }; | ||
98 | }; | ||
99 | }; | ||
diff --git a/arch/arm/boot/dts/kirkwood-ib62x0.dts b/arch/arm/boot/dts/kirkwood-ib62x0.dts index f59dcf6dc45f..66794ed75ff1 100644 --- a/arch/arm/boot/dts/kirkwood-ib62x0.dts +++ b/arch/arm/boot/dts/kirkwood-ib62x0.dts | |||
@@ -21,6 +21,11 @@ | |||
21 | status = "okay"; | 21 | status = "okay"; |
22 | }; | 22 | }; |
23 | 23 | ||
24 | sata@80000 { | ||
25 | status = "okay"; | ||
26 | nr-ports = <2>; | ||
27 | }; | ||
28 | |||
24 | nand@3000000 { | 29 | nand@3000000 { |
25 | status = "okay"; | 30 | status = "okay"; |
26 | 31 | ||
@@ -41,4 +46,37 @@ | |||
41 | 46 | ||
42 | }; | 47 | }; |
43 | }; | 48 | }; |
49 | |||
50 | gpio_keys { | ||
51 | compatible = "gpio-keys"; | ||
52 | #address-cells = <1>; | ||
53 | #size-cells = <0>; | ||
54 | button@1 { | ||
55 | label = "USB Copy"; | ||
56 | linux,code = <133>; | ||
57 | gpios = <&gpio0 29 1>; | ||
58 | }; | ||
59 | button@2 { | ||
60 | label = "Reset"; | ||
61 | linux,code = <0x198>; | ||
62 | gpios = <&gpio0 28 1>; | ||
63 | }; | ||
64 | }; | ||
65 | gpio-leds { | ||
66 | compatible = "gpio-leds"; | ||
67 | |||
68 | green-os { | ||
69 | label = "ib62x0:green:os"; | ||
70 | gpios = <&gpio0 25 0>; | ||
71 | linux,default-trigger = "default-on"; | ||
72 | }; | ||
73 | red-os { | ||
74 | label = "ib62x0:red:os"; | ||
75 | gpios = <&gpio0 22 0>; | ||
76 | }; | ||
77 | usb-copy { | ||
78 | label = "ib62x0:red:usb_copy"; | ||
79 | gpios = <&gpio0 27 0>; | ||
80 | }; | ||
81 | }; | ||
44 | }; | 82 | }; |
diff --git a/arch/arm/boot/dts/kirkwood-iconnect.dts b/arch/arm/boot/dts/kirkwood-iconnect.dts index 026a1f82d813..52d947045106 100644 --- a/arch/arm/boot/dts/kirkwood-iconnect.dts +++ b/arch/arm/boot/dts/kirkwood-iconnect.dts | |||
@@ -18,9 +18,51 @@ | |||
18 | }; | 18 | }; |
19 | 19 | ||
20 | ocp@f1000000 { | 20 | ocp@f1000000 { |
21 | i2c@11000 { | ||
22 | status = "okay"; | ||
23 | |||
24 | lm63: lm63@4c { | ||
25 | compatible = "national,lm63"; | ||
26 | reg = <0x4c>; | ||
27 | }; | ||
28 | }; | ||
21 | serial@12000 { | 29 | serial@12000 { |
22 | clock-frequency = <200000000>; | 30 | clock-frequency = <200000000>; |
23 | status = "ok"; | 31 | status = "ok"; |
24 | }; | 32 | }; |
25 | }; | 33 | }; |
34 | gpio-leds { | ||
35 | compatible = "gpio-leds"; | ||
36 | |||
37 | led-level { | ||
38 | label = "led_level"; | ||
39 | gpios = <&gpio1 9 0>; | ||
40 | linux,default-trigger = "default-on"; | ||
41 | }; | ||
42 | power-blue { | ||
43 | label = "power:blue"; | ||
44 | gpios = <&gpio1 11 0>; | ||
45 | linux,default-trigger = "timer"; | ||
46 | }; | ||
47 | usb1 { | ||
48 | label = "usb1:blue"; | ||
49 | gpios = <&gpio1 12 0>; | ||
50 | }; | ||
51 | usb2 { | ||
52 | label = "usb2:blue"; | ||
53 | gpios = <&gpio1 13 0>; | ||
54 | }; | ||
55 | usb3 { | ||
56 | label = "usb3:blue"; | ||
57 | gpios = <&gpio1 14 0>; | ||
58 | }; | ||
59 | usb4 { | ||
60 | label = "usb4:blue"; | ||
61 | gpios = <&gpio1 15 0>; | ||
62 | }; | ||
63 | otb { | ||
64 | label = "otb:blue"; | ||
65 | gpios = <&gpio1 16 0>; | ||
66 | }; | ||
67 | }; | ||
26 | }; | 68 | }; |
diff --git a/arch/arm/boot/dts/kirkwood-lschlv2.dts b/arch/arm/boot/dts/kirkwood-lschlv2.dts new file mode 100644 index 000000000000..9510c9ea666c --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-lschlv2.dts | |||
@@ -0,0 +1,20 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "kirkwood-lsxl.dtsi" | ||
4 | |||
5 | / { | ||
6 | model = "Buffalo Linkstation LS-CHLv2"; | ||
7 | compatible = "buffalo,lschlv2", "buffalo,lsxl", "marvell,kirkwood-88f6281", "marvell,kirkwood"; | ||
8 | |||
9 | memory { | ||
10 | device_type = "memory"; | ||
11 | reg = <0x00000000 0x4000000>; | ||
12 | }; | ||
13 | |||
14 | ocp@f1000000 { | ||
15 | serial@12000 { | ||
16 | clock-frequency = <166666667>; | ||
17 | status = "okay"; | ||
18 | }; | ||
19 | }; | ||
20 | }; | ||
diff --git a/arch/arm/boot/dts/kirkwood-lsxhl.dts b/arch/arm/boot/dts/kirkwood-lsxhl.dts new file mode 100644 index 000000000000..739019c4cba9 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-lsxhl.dts | |||
@@ -0,0 +1,20 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "kirkwood-lsxl.dtsi" | ||
4 | |||
5 | / { | ||
6 | model = "Buffalo Linkstation LS-XHL"; | ||
7 | compatible = "buffalo,lsxhl", "buffalo,lsxl", "marvell,kirkwood-88f6281", "marvell,kirkwood"; | ||
8 | |||
9 | memory { | ||
10 | device_type = "memory"; | ||
11 | reg = <0x00000000 0x10000000>; | ||
12 | }; | ||
13 | |||
14 | ocp@f1000000 { | ||
15 | serial@12000 { | ||
16 | clock-frequency = <200000000>; | ||
17 | status = "okay"; | ||
18 | }; | ||
19 | }; | ||
20 | }; | ||
diff --git a/arch/arm/boot/dts/kirkwood-lsxl.dtsi b/arch/arm/boot/dts/kirkwood-lsxl.dtsi new file mode 100644 index 000000000000..8ac51c08269d --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-lsxl.dtsi | |||
@@ -0,0 +1,95 @@ | |||
1 | /include/ "kirkwood.dtsi" | ||
2 | |||
3 | / { | ||
4 | chosen { | ||
5 | bootargs = "console=ttyS0,115200n8 earlyprintk"; | ||
6 | }; | ||
7 | |||
8 | ocp@f1000000 { | ||
9 | sata@80000 { | ||
10 | status = "okay"; | ||
11 | nr-ports = <1>; | ||
12 | }; | ||
13 | |||
14 | spi@10600 { | ||
15 | status = "okay"; | ||
16 | |||
17 | m25p40@0 { | ||
18 | #address-cells = <1>; | ||
19 | #size-cells = <1>; | ||
20 | compatible = "m25p40"; | ||
21 | reg = <0>; | ||
22 | spi-max-frequency = <25000000>; | ||
23 | mode = <0>; | ||
24 | |||
25 | partition@0 { | ||
26 | reg = <0x0 0x60000>; | ||
27 | label = "uboot"; | ||
28 | read-only; | ||
29 | }; | ||
30 | |||
31 | partition@60000 { | ||
32 | reg = <0x60000 0x10000>; | ||
33 | label = "dtb"; | ||
34 | read-only; | ||
35 | }; | ||
36 | |||
37 | partition@70000 { | ||
38 | reg = <0x70000 0x10000>; | ||
39 | label = "uboot_env"; | ||
40 | }; | ||
41 | }; | ||
42 | }; | ||
43 | }; | ||
44 | |||
45 | gpio_keys { | ||
46 | compatible = "gpio-keys"; | ||
47 | #address-cells = <1>; | ||
48 | #size-cells = <0>; | ||
49 | button@1 { | ||
50 | label = "Function Button"; | ||
51 | linux,code = <132>; | ||
52 | gpios = <&gpio1 9 1>; | ||
53 | }; | ||
54 | button@2 { | ||
55 | label = "Power-on Switch"; | ||
56 | linux,code = <116>; | ||
57 | gpios = <&gpio1 10 1>; | ||
58 | }; | ||
59 | button@3 { | ||
60 | label = "Power-auto Switch"; | ||
61 | linux,code = <142>; | ||
62 | gpios = <&gpio1 11 1>; | ||
63 | }; | ||
64 | }; | ||
65 | |||
66 | gpio_leds { | ||
67 | compatible = "gpio-leds"; | ||
68 | |||
69 | led@1 { | ||
70 | label = "lschlv2:blue:func"; | ||
71 | gpios = <&gpio1 4 1>; | ||
72 | }; | ||
73 | |||
74 | led@2 { | ||
75 | label = "lschlv2:red:alarm"; | ||
76 | gpios = <&gpio1 5 1>; | ||
77 | }; | ||
78 | |||
79 | led@3 { | ||
80 | label = "lschlv2:amber:info"; | ||
81 | gpios = <&gpio1 6 1>; | ||
82 | }; | ||
83 | |||
84 | led@4 { | ||
85 | label = "lschlv2:blue:power"; | ||
86 | gpios = <&gpio1 7 1>; | ||
87 | linux,default-trigger = "default-on"; | ||
88 | }; | ||
89 | |||
90 | led@5 { | ||
91 | label = "lschlv2:red:func"; | ||
92 | gpios = <&gpio1 16 1>; | ||
93 | }; | ||
94 | }; | ||
95 | }; | ||
diff --git a/arch/arm/boot/dts/kirkwood-ts219-6281.dts b/arch/arm/boot/dts/kirkwood-ts219-6281.dts new file mode 100644 index 000000000000..ccbf32757800 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-ts219-6281.dts | |||
@@ -0,0 +1,21 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "kirkwood-ts219.dtsi" | ||
4 | |||
5 | / { | ||
6 | gpio_keys { | ||
7 | compatible = "gpio-keys"; | ||
8 | #address-cells = <1>; | ||
9 | #size-cells = <0>; | ||
10 | button@1 { | ||
11 | label = "USB Copy"; | ||
12 | linux,code = <133>; | ||
13 | gpios = <&gpio0 15 1>; | ||
14 | }; | ||
15 | button@2 { | ||
16 | label = "Reset"; | ||
17 | linux,code = <0x198>; | ||
18 | gpios = <&gpio0 16 1>; | ||
19 | }; | ||
20 | }; | ||
21 | }; \ No newline at end of file | ||
diff --git a/arch/arm/boot/dts/kirkwood-ts219-6282.dts b/arch/arm/boot/dts/kirkwood-ts219-6282.dts new file mode 100644 index 000000000000..fbe9932161a1 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-ts219-6282.dts | |||
@@ -0,0 +1,21 @@ | |||
1 | /dts-v1/; | ||
2 | |||
3 | /include/ "kirkwood-ts219.dtsi" | ||
4 | |||
5 | / { | ||
6 | gpio_keys { | ||
7 | compatible = "gpio-keys"; | ||
8 | #address-cells = <1>; | ||
9 | #size-cells = <0>; | ||
10 | button@1 { | ||
11 | label = "USB Copy"; | ||
12 | linux,code = <133>; | ||
13 | gpios = <&gpio1 11 1>; | ||
14 | }; | ||
15 | button@2 { | ||
16 | label = "Reset"; | ||
17 | linux,code = <0x198>; | ||
18 | gpios = <&gpio1 5 1>; | ||
19 | }; | ||
20 | }; | ||
21 | }; \ No newline at end of file | ||
diff --git a/arch/arm/boot/dts/kirkwood-ts219.dtsi b/arch/arm/boot/dts/kirkwood-ts219.dtsi new file mode 100644 index 000000000000..64ea27cb3298 --- /dev/null +++ b/arch/arm/boot/dts/kirkwood-ts219.dtsi | |||
@@ -0,0 +1,78 @@ | |||
1 | /include/ "kirkwood.dtsi" | ||
2 | |||
3 | / { | ||
4 | model = "QNAP TS219 family"; | ||
5 | compatible = "qnap,ts219", "marvell,kirkwood"; | ||
6 | |||
7 | memory { | ||
8 | device_type = "memory"; | ||
9 | reg = <0x00000000 0x20000000>; | ||
10 | }; | ||
11 | |||
12 | chosen { | ||
13 | bootargs = "console=ttyS0,115200n8"; | ||
14 | }; | ||
15 | |||
16 | ocp@f1000000 { | ||
17 | i2c@11000 { | ||
18 | status = "okay"; | ||
19 | clock-frequency = <400000>; | ||
20 | |||
21 | s35390a: s35390a@30 { | ||
22 | compatible = "s35390a"; | ||
23 | reg = <0x30>; | ||
24 | }; | ||
25 | }; | ||
26 | serial@12000 { | ||
27 | clock-frequency = <200000000>; | ||
28 | status = "okay"; | ||
29 | }; | ||
30 | serial@12100 { | ||
31 | clock-frequency = <200000000>; | ||
32 | status = "okay"; | ||
33 | }; | ||
34 | spi@10600 { | ||
35 | status = "okay"; | ||
36 | |||
37 | m25p128@0 { | ||
38 | #address-cells = <1>; | ||
39 | #size-cells = <1>; | ||
40 | compatible = "m25p128"; | ||
41 | reg = <0>; | ||
42 | spi-max-frequency = <20000000>; | ||
43 | mode = <0>; | ||
44 | |||
45 | partition@0000000 { | ||
46 | reg = <0x00000000 0x00080000>; | ||
47 | label = "U-Boot"; | ||
48 | }; | ||
49 | |||
50 | partition@00200000 { | ||
51 | reg = <0x00200000 0x00200000>; | ||
52 | label = "Kernel"; | ||
53 | }; | ||
54 | |||
55 | partition@00400000 { | ||
56 | reg = <0x00400000 0x00900000>; | ||
57 | label = "RootFS1"; | ||
58 | }; | ||
59 | partition@00d00000 { | ||
60 | reg = <0x00d00000 0x00300000>; | ||
61 | label = "RootFS2"; | ||
62 | }; | ||
63 | partition@00040000 { | ||
64 | reg = <0x00080000 0x00040000>; | ||
65 | label = "U-Boot Config"; | ||
66 | }; | ||
67 | partition@000c0000 { | ||
68 | reg = <0x000c0000 0x00140000>; | ||
69 | label = "NAS Config"; | ||
70 | }; | ||
71 | }; | ||
72 | }; | ||
73 | sata@80000 { | ||
74 | status = "okay"; | ||
75 | nr-ports = <2>; | ||
76 | }; | ||
77 | }; | ||
78 | }; | ||
diff --git a/arch/arm/boot/dts/kirkwood.dtsi b/arch/arm/boot/dts/kirkwood.dtsi index f95dbc190ab6..cef9616f330a 100644 --- a/arch/arm/boot/dts/kirkwood.dtsi +++ b/arch/arm/boot/dts/kirkwood.dtsi | |||
@@ -2,6 +2,15 @@ | |||
2 | 2 | ||
3 | / { | 3 | / { |
4 | compatible = "marvell,kirkwood"; | 4 | compatible = "marvell,kirkwood"; |
5 | interrupt-parent = <&intc>; | ||
6 | |||
7 | intc: interrupt-controller { | ||
8 | compatible = "marvell,orion-intc", "marvell,intc"; | ||
9 | interrupt-controller; | ||
10 | #interrupt-cells = <1>; | ||
11 | reg = <0xf1020204 0x04>, | ||
12 | <0xf1020214 0x04>; | ||
13 | }; | ||
5 | 14 | ||
6 | ocp@f1000000 { | 15 | ocp@f1000000 { |
7 | compatible = "simple-bus"; | 16 | compatible = "simple-bus"; |
@@ -9,6 +18,24 @@ | |||
9 | #address-cells = <1>; | 18 | #address-cells = <1>; |
10 | #size-cells = <1>; | 19 | #size-cells = <1>; |
11 | 20 | ||
21 | gpio0: gpio@10100 { | ||
22 | compatible = "marvell,orion-gpio"; | ||
23 | #gpio-cells = <2>; | ||
24 | gpio-controller; | ||
25 | reg = <0x10100 0x40>; | ||
26 | ngpio = <32>; | ||
27 | interrupts = <35>, <36>, <37>, <38>; | ||
28 | }; | ||
29 | |||
30 | gpio1: gpio@10140 { | ||
31 | compatible = "marvell,orion-gpio"; | ||
32 | #gpio-cells = <2>; | ||
33 | gpio-controller; | ||
34 | reg = <0x10140 0x40>; | ||
35 | ngpio = <18>; | ||
36 | interrupts = <39>, <40>, <41>; | ||
37 | }; | ||
38 | |||
12 | serial@12000 { | 39 | serial@12000 { |
13 | compatible = "ns16550a"; | 40 | compatible = "ns16550a"; |
14 | reg = <0x12000 0x100>; | 41 | reg = <0x12000 0x100>; |
@@ -33,6 +60,29 @@ | |||
33 | interrupts = <53>; | 60 | interrupts = <53>; |
34 | }; | 61 | }; |
35 | 62 | ||
63 | spi@10600 { | ||
64 | compatible = "marvell,orion-spi"; | ||
65 | #address-cells = <1>; | ||
66 | #size-cells = <0>; | ||
67 | cell-index = <0>; | ||
68 | interrupts = <23>; | ||
69 | reg = <0x10600 0x28>; | ||
70 | status = "disabled"; | ||
71 | }; | ||
72 | |||
73 | wdt@20300 { | ||
74 | compatible = "marvell,orion-wdt"; | ||
75 | reg = <0x20300 0x28>; | ||
76 | status = "okay"; | ||
77 | }; | ||
78 | |||
79 | sata@80000 { | ||
80 | compatible = "marvell,orion-sata"; | ||
81 | reg = <0x80000 0x5000>; | ||
82 | interrupts = <21>; | ||
83 | status = "disabled"; | ||
84 | }; | ||
85 | |||
36 | nand@3000000 { | 86 | nand@3000000 { |
37 | #address-cells = <1>; | 87 | #address-cells = <1>; |
38 | #size-cells = <1>; | 88 | #size-cells = <1>; |
@@ -45,5 +95,15 @@ | |||
45 | /* set partition map and/or chip-delay in board dts */ | 95 | /* set partition map and/or chip-delay in board dts */ |
46 | status = "disabled"; | 96 | status = "disabled"; |
47 | }; | 97 | }; |
98 | |||
99 | i2c@11000 { | ||
100 | compatible = "marvell,mv64xxx-i2c"; | ||
101 | reg = <0x11000 0x20>; | ||
102 | #address-cells = <1>; | ||
103 | #size-cells = <0>; | ||
104 | interrupts = <29>; | ||
105 | clock-frequency = <100000>; | ||
106 | status = "disabled"; | ||
107 | }; | ||
48 | }; | 108 | }; |
49 | }; | 109 | }; |
diff --git a/arch/arm/configs/imx_v6_v7_defconfig b/arch/arm/configs/imx_v6_v7_defconfig index f725b9637b33..3c9f32f9b6b4 100644 --- a/arch/arm/configs/imx_v6_v7_defconfig +++ b/arch/arm/configs/imx_v6_v7_defconfig | |||
@@ -192,6 +192,7 @@ CONFIG_RTC_DRV_MC13XXX=y | |||
192 | CONFIG_RTC_DRV_MXC=y | 192 | CONFIG_RTC_DRV_MXC=y |
193 | CONFIG_DMADEVICES=y | 193 | CONFIG_DMADEVICES=y |
194 | CONFIG_IMX_SDMA=y | 194 | CONFIG_IMX_SDMA=y |
195 | CONFIG_MXS_DMA=y | ||
195 | CONFIG_COMMON_CLK_DEBUG=y | 196 | CONFIG_COMMON_CLK_DEBUG=y |
196 | # CONFIG_IOMMU_SUPPORT is not set | 197 | # CONFIG_IOMMU_SUPPORT is not set |
197 | CONFIG_EXT2_FS=y | 198 | CONFIG_EXT2_FS=y |
diff --git a/arch/arm/configs/mxs_defconfig b/arch/arm/configs/mxs_defconfig index ccdb6357fb74..4edcfb4e4dee 100644 --- a/arch/arm/configs/mxs_defconfig +++ b/arch/arm/configs/mxs_defconfig | |||
@@ -34,7 +34,6 @@ CONFIG_NO_HZ=y | |||
34 | CONFIG_HIGH_RES_TIMERS=y | 34 | CONFIG_HIGH_RES_TIMERS=y |
35 | CONFIG_PREEMPT_VOLUNTARY=y | 35 | CONFIG_PREEMPT_VOLUNTARY=y |
36 | CONFIG_AEABI=y | 36 | CONFIG_AEABI=y |
37 | CONFIG_DEFAULT_MMAP_MIN_ADDR=65536 | ||
38 | CONFIG_AUTO_ZRELADDR=y | 37 | CONFIG_AUTO_ZRELADDR=y |
39 | CONFIG_FPE_NWFPE=y | 38 | CONFIG_FPE_NWFPE=y |
40 | CONFIG_NET=y | 39 | CONFIG_NET=y |
diff --git a/arch/arm/configs/tct_hammer_defconfig b/arch/arm/configs/tct_hammer_defconfig index 1d24f8458bef..71277a1591ba 100644 --- a/arch/arm/configs/tct_hammer_defconfig +++ b/arch/arm/configs/tct_hammer_defconfig | |||
@@ -7,7 +7,7 @@ CONFIG_SYSFS_DEPRECATED_V2=y | |||
7 | CONFIG_BLK_DEV_INITRD=y | 7 | CONFIG_BLK_DEV_INITRD=y |
8 | CONFIG_EXPERT=y | 8 | CONFIG_EXPERT=y |
9 | # CONFIG_KALLSYMS is not set | 9 | # CONFIG_KALLSYMS is not set |
10 | # CONFIG_BUG is not set | 10 | # CONFIG_BUGVERBOSE is not set |
11 | # CONFIG_ELF_CORE is not set | 11 | # CONFIG_ELF_CORE is not set |
12 | # CONFIG_SHMEM is not set | 12 | # CONFIG_SHMEM is not set |
13 | CONFIG_SLOB=y | 13 | CONFIG_SLOB=y |
diff --git a/arch/arm/include/asm/pgtable.h b/arch/arm/include/asm/pgtable.h index f66626d71e7d..41dc31f834c3 100644 --- a/arch/arm/include/asm/pgtable.h +++ b/arch/arm/include/asm/pgtable.h | |||
@@ -195,6 +195,18 @@ static inline pte_t *pmd_page_vaddr(pmd_t pmd) | |||
195 | 195 | ||
196 | #define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) | 196 | #define pte_clear(mm,addr,ptep) set_pte_ext(ptep, __pte(0), 0) |
197 | 197 | ||
198 | #define pte_none(pte) (!pte_val(pte)) | ||
199 | #define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT) | ||
200 | #define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY)) | ||
201 | #define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) | ||
202 | #define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) | ||
203 | #define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN)) | ||
204 | #define pte_special(pte) (0) | ||
205 | |||
206 | #define pte_present_user(pte) \ | ||
207 | ((pte_val(pte) & (L_PTE_PRESENT | L_PTE_USER)) == \ | ||
208 | (L_PTE_PRESENT | L_PTE_USER)) | ||
209 | |||
198 | #if __LINUX_ARM_ARCH__ < 6 | 210 | #if __LINUX_ARM_ARCH__ < 6 |
199 | static inline void __sync_icache_dcache(pte_t pteval) | 211 | static inline void __sync_icache_dcache(pte_t pteval) |
200 | { | 212 | { |
@@ -206,25 +218,15 @@ extern void __sync_icache_dcache(pte_t pteval); | |||
206 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | 218 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, |
207 | pte_t *ptep, pte_t pteval) | 219 | pte_t *ptep, pte_t pteval) |
208 | { | 220 | { |
209 | if (addr >= TASK_SIZE) | 221 | unsigned long ext = 0; |
210 | set_pte_ext(ptep, pteval, 0); | 222 | |
211 | else { | 223 | if (addr < TASK_SIZE && pte_present_user(pteval)) { |
212 | __sync_icache_dcache(pteval); | 224 | __sync_icache_dcache(pteval); |
213 | set_pte_ext(ptep, pteval, PTE_EXT_NG); | 225 | ext |= PTE_EXT_NG; |
214 | } | 226 | } |
215 | } | ||
216 | 227 | ||
217 | #define pte_none(pte) (!pte_val(pte)) | 228 | set_pte_ext(ptep, pteval, ext); |
218 | #define pte_present(pte) (pte_val(pte) & L_PTE_PRESENT) | 229 | } |
219 | #define pte_write(pte) (!(pte_val(pte) & L_PTE_RDONLY)) | ||
220 | #define pte_dirty(pte) (pte_val(pte) & L_PTE_DIRTY) | ||
221 | #define pte_young(pte) (pte_val(pte) & L_PTE_YOUNG) | ||
222 | #define pte_exec(pte) (!(pte_val(pte) & L_PTE_XN)) | ||
223 | #define pte_special(pte) (0) | ||
224 | |||
225 | #define pte_present_user(pte) \ | ||
226 | ((pte_val(pte) & (L_PTE_PRESENT | L_PTE_USER)) == \ | ||
227 | (L_PTE_PRESENT | L_PTE_USER)) | ||
228 | 230 | ||
229 | #define PTE_BIT_FUNC(fn,op) \ | 231 | #define PTE_BIT_FUNC(fn,op) \ |
230 | static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } | 232 | static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } |
@@ -251,13 +253,13 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | |||
251 | * | 253 | * |
252 | * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 | 254 | * 3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 |
253 | * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 | 255 | * 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 |
254 | * <--------------- offset --------------------> <- type --> 0 0 0 | 256 | * <--------------- offset ----------------------> < type -> 0 0 0 |
255 | * | 257 | * |
256 | * This gives us up to 63 swap files and 32GB per swap file. Note that | 258 | * This gives us up to 31 swap files and 64GB per swap file. Note that |
257 | * the offset field is always non-zero. | 259 | * the offset field is always non-zero. |
258 | */ | 260 | */ |
259 | #define __SWP_TYPE_SHIFT 3 | 261 | #define __SWP_TYPE_SHIFT 3 |
260 | #define __SWP_TYPE_BITS 6 | 262 | #define __SWP_TYPE_BITS 5 |
261 | #define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) | 263 | #define __SWP_TYPE_MASK ((1 << __SWP_TYPE_BITS) - 1) |
262 | #define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) | 264 | #define __SWP_OFFSET_SHIFT (__SWP_TYPE_BITS + __SWP_TYPE_SHIFT) |
263 | 265 | ||
diff --git a/arch/arm/include/asm/sched_clock.h b/arch/arm/include/asm/sched_clock.h index e3f757263438..05b8e82ec9f5 100644 --- a/arch/arm/include/asm/sched_clock.h +++ b/arch/arm/include/asm/sched_clock.h | |||
@@ -10,5 +10,7 @@ | |||
10 | 10 | ||
11 | extern void sched_clock_postinit(void); | 11 | extern void sched_clock_postinit(void); |
12 | extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); | 12 | extern void setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate); |
13 | extern void setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, | ||
14 | unsigned long rate); | ||
13 | 15 | ||
14 | #endif | 16 | #endif |
diff --git a/arch/arm/kernel/sched_clock.c b/arch/arm/kernel/sched_clock.c index 27d186abbc06..f4515393248d 100644 --- a/arch/arm/kernel/sched_clock.c +++ b/arch/arm/kernel/sched_clock.c | |||
@@ -21,6 +21,8 @@ struct clock_data { | |||
21 | u32 epoch_cyc_copy; | 21 | u32 epoch_cyc_copy; |
22 | u32 mult; | 22 | u32 mult; |
23 | u32 shift; | 23 | u32 shift; |
24 | bool suspended; | ||
25 | bool needs_suspend; | ||
24 | }; | 26 | }; |
25 | 27 | ||
26 | static void sched_clock_poll(unsigned long wrap_ticks); | 28 | static void sched_clock_poll(unsigned long wrap_ticks); |
@@ -49,6 +51,9 @@ static unsigned long long cyc_to_sched_clock(u32 cyc, u32 mask) | |||
49 | u64 epoch_ns; | 51 | u64 epoch_ns; |
50 | u32 epoch_cyc; | 52 | u32 epoch_cyc; |
51 | 53 | ||
54 | if (cd.suspended) | ||
55 | return cd.epoch_ns; | ||
56 | |||
52 | /* | 57 | /* |
53 | * Load the epoch_cyc and epoch_ns atomically. We do this by | 58 | * Load the epoch_cyc and epoch_ns atomically. We do this by |
54 | * ensuring that we always write epoch_cyc, epoch_ns and | 59 | * ensuring that we always write epoch_cyc, epoch_ns and |
@@ -98,6 +103,13 @@ static void sched_clock_poll(unsigned long wrap_ticks) | |||
98 | update_sched_clock(); | 103 | update_sched_clock(); |
99 | } | 104 | } |
100 | 105 | ||
106 | void __init setup_sched_clock_needs_suspend(u32 (*read)(void), int bits, | ||
107 | unsigned long rate) | ||
108 | { | ||
109 | setup_sched_clock(read, bits, rate); | ||
110 | cd.needs_suspend = true; | ||
111 | } | ||
112 | |||
101 | void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) | 113 | void __init setup_sched_clock(u32 (*read)(void), int bits, unsigned long rate) |
102 | { | 114 | { |
103 | unsigned long r, w; | 115 | unsigned long r, w; |
@@ -169,11 +181,23 @@ void __init sched_clock_postinit(void) | |||
169 | static int sched_clock_suspend(void) | 181 | static int sched_clock_suspend(void) |
170 | { | 182 | { |
171 | sched_clock_poll(sched_clock_timer.data); | 183 | sched_clock_poll(sched_clock_timer.data); |
184 | if (cd.needs_suspend) | ||
185 | cd.suspended = true; | ||
172 | return 0; | 186 | return 0; |
173 | } | 187 | } |
174 | 188 | ||
189 | static void sched_clock_resume(void) | ||
190 | { | ||
191 | if (cd.needs_suspend) { | ||
192 | cd.epoch_cyc = read_sched_clock(); | ||
193 | cd.epoch_cyc_copy = cd.epoch_cyc; | ||
194 | cd.suspended = false; | ||
195 | } | ||
196 | } | ||
197 | |||
175 | static struct syscore_ops sched_clock_ops = { | 198 | static struct syscore_ops sched_clock_ops = { |
176 | .suspend = sched_clock_suspend, | 199 | .suspend = sched_clock_suspend, |
200 | .resume = sched_clock_resume, | ||
177 | }; | 201 | }; |
178 | 202 | ||
179 | static int __init sched_clock_syscore_init(void) | 203 | static int __init sched_clock_syscore_init(void) |
diff --git a/arch/arm/kernel/topology.c b/arch/arm/kernel/topology.c index 198b08456e90..26c12c6440fc 100644 --- a/arch/arm/kernel/topology.c +++ b/arch/arm/kernel/topology.c | |||
@@ -321,7 +321,7 @@ void store_cpu_topology(unsigned int cpuid) | |||
321 | * init_cpu_topology is called at boot when only one cpu is running | 321 | * init_cpu_topology is called at boot when only one cpu is running |
322 | * which prevent simultaneous write access to cpu_topology array | 322 | * which prevent simultaneous write access to cpu_topology array |
323 | */ | 323 | */ |
324 | void init_cpu_topology(void) | 324 | void __init init_cpu_topology(void) |
325 | { | 325 | { |
326 | unsigned int cpu; | 326 | unsigned int cpu; |
327 | 327 | ||
diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 2473fd1fd51c..af72969820b4 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile | |||
@@ -16,13 +16,30 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ | |||
16 | call_with_stack.o | 16 | call_with_stack.o |
17 | 17 | ||
18 | mmu-y := clear_user.o copy_page.o getuser.o putuser.o | 18 | mmu-y := clear_user.o copy_page.o getuser.o putuser.o |
19 | mmu-y += copy_from_user.o copy_to_user.o | 19 | |
20 | # the code in uaccess.S is not preemption safe and | ||
21 | # probably faster on ARMv3 only | ||
22 | ifeq ($(CONFIG_PREEMPT),y) | ||
23 | mmu-y += copy_from_user.o copy_to_user.o | ||
24 | else | ||
25 | ifneq ($(CONFIG_CPU_32v3),y) | ||
26 | mmu-y += copy_from_user.o copy_to_user.o | ||
27 | else | ||
28 | mmu-y += uaccess.o | ||
29 | endif | ||
30 | endif | ||
20 | 31 | ||
21 | # using lib_ here won't override already available weak symbols | 32 | # using lib_ here won't override already available weak symbols |
22 | obj-$(CONFIG_UACCESS_WITH_MEMCPY) += uaccess_with_memcpy.o | 33 | obj-$(CONFIG_UACCESS_WITH_MEMCPY) += uaccess_with_memcpy.o |
23 | 34 | ||
24 | lib-$(CONFIG_MMU) += $(mmu-y) | 35 | lib-$(CONFIG_MMU) += $(mmu-y) |
25 | lib-y += io-readsw-armv4.o io-writesw-armv4.o | 36 | |
37 | ifeq ($(CONFIG_CPU_32v3),y) | ||
38 | lib-y += io-readsw-armv3.o io-writesw-armv3.o | ||
39 | else | ||
40 | lib-y += io-readsw-armv4.o io-writesw-armv4.o | ||
41 | endif | ||
42 | |||
26 | lib-$(CONFIG_ARCH_RPC) += ecard.o io-acorn.o floppydma.o | 43 | lib-$(CONFIG_ARCH_RPC) += ecard.o io-acorn.o floppydma.o |
27 | lib-$(CONFIG_ARCH_SHARK) += io-shark.o | 44 | lib-$(CONFIG_ARCH_SHARK) += io-shark.o |
28 | 45 | ||
diff --git a/arch/arm/lib/io-readsw-armv3.S b/arch/arm/lib/io-readsw-armv3.S new file mode 100644 index 000000000000..88487c8c4f23 --- /dev/null +++ b/arch/arm/lib/io-readsw-armv3.S | |||
@@ -0,0 +1,106 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/lib/io-readsw-armv3.S | ||
3 | * | ||
4 | * Copyright (C) 1995-2000 Russell King | ||
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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/linkage.h> | ||
11 | #include <asm/assembler.h> | ||
12 | |||
13 | .Linsw_bad_alignment: | ||
14 | adr r0, .Linsw_bad_align_msg | ||
15 | mov r2, lr | ||
16 | b panic | ||
17 | .Linsw_bad_align_msg: | ||
18 | .asciz "insw: bad buffer alignment (0x%p, lr=0x%08lX)\n" | ||
19 | .align | ||
20 | |||
21 | .Linsw_align: tst r1, #1 | ||
22 | bne .Linsw_bad_alignment | ||
23 | |||
24 | ldr r3, [r0] | ||
25 | strb r3, [r1], #1 | ||
26 | mov r3, r3, lsr #8 | ||
27 | strb r3, [r1], #1 | ||
28 | |||
29 | subs r2, r2, #1 | ||
30 | moveq pc, lr | ||
31 | |||
32 | ENTRY(__raw_readsw) | ||
33 | teq r2, #0 @ do we have to check for the zero len? | ||
34 | moveq pc, lr | ||
35 | tst r1, #3 | ||
36 | bne .Linsw_align | ||
37 | |||
38 | .Linsw_aligned: mov ip, #0xff | ||
39 | orr ip, ip, ip, lsl #8 | ||
40 | stmfd sp!, {r4, r5, r6, lr} | ||
41 | |||
42 | subs r2, r2, #8 | ||
43 | bmi .Lno_insw_8 | ||
44 | |||
45 | .Linsw_8_lp: ldr r3, [r0] | ||
46 | and r3, r3, ip | ||
47 | ldr r4, [r0] | ||
48 | orr r3, r3, r4, lsl #16 | ||
49 | |||
50 | ldr r4, [r0] | ||
51 | and r4, r4, ip | ||
52 | ldr r5, [r0] | ||
53 | orr r4, r4, r5, lsl #16 | ||
54 | |||
55 | ldr r5, [r0] | ||
56 | and r5, r5, ip | ||
57 | ldr r6, [r0] | ||
58 | orr r5, r5, r6, lsl #16 | ||
59 | |||
60 | ldr r6, [r0] | ||
61 | and r6, r6, ip | ||
62 | ldr lr, [r0] | ||
63 | orr r6, r6, lr, lsl #16 | ||
64 | |||
65 | stmia r1!, {r3 - r6} | ||
66 | |||
67 | subs r2, r2, #8 | ||
68 | bpl .Linsw_8_lp | ||
69 | |||
70 | tst r2, #7 | ||
71 | ldmeqfd sp!, {r4, r5, r6, pc} | ||
72 | |||
73 | .Lno_insw_8: tst r2, #4 | ||
74 | beq .Lno_insw_4 | ||
75 | |||
76 | ldr r3, [r0] | ||
77 | and r3, r3, ip | ||
78 | ldr r4, [r0] | ||
79 | orr r3, r3, r4, lsl #16 | ||
80 | |||
81 | ldr r4, [r0] | ||
82 | and r4, r4, ip | ||
83 | ldr r5, [r0] | ||
84 | orr r4, r4, r5, lsl #16 | ||
85 | |||
86 | stmia r1!, {r3, r4} | ||
87 | |||
88 | .Lno_insw_4: tst r2, #2 | ||
89 | beq .Lno_insw_2 | ||
90 | |||
91 | ldr r3, [r0] | ||
92 | and r3, r3, ip | ||
93 | ldr r4, [r0] | ||
94 | orr r3, r3, r4, lsl #16 | ||
95 | |||
96 | str r3, [r1], #4 | ||
97 | |||
98 | .Lno_insw_2: tst r2, #1 | ||
99 | ldrne r3, [r0] | ||
100 | strneb r3, [r1], #1 | ||
101 | movne r3, r3, lsr #8 | ||
102 | strneb r3, [r1] | ||
103 | |||
104 | ldmfd sp!, {r4, r5, r6, pc} | ||
105 | |||
106 | |||
diff --git a/arch/arm/lib/io-writesw-armv3.S b/arch/arm/lib/io-writesw-armv3.S new file mode 100644 index 000000000000..49b800419e32 --- /dev/null +++ b/arch/arm/lib/io-writesw-armv3.S | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/lib/io-writesw-armv3.S | ||
3 | * | ||
4 | * Copyright (C) 1995-2000 Russell King | ||
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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | */ | ||
10 | #include <linux/linkage.h> | ||
11 | #include <asm/assembler.h> | ||
12 | |||
13 | .Loutsw_bad_alignment: | ||
14 | adr r0, .Loutsw_bad_align_msg | ||
15 | mov r2, lr | ||
16 | b panic | ||
17 | .Loutsw_bad_align_msg: | ||
18 | .asciz "outsw: bad buffer alignment (0x%p, lr=0x%08lX)\n" | ||
19 | .align | ||
20 | |||
21 | .Loutsw_align: tst r1, #1 | ||
22 | bne .Loutsw_bad_alignment | ||
23 | |||
24 | add r1, r1, #2 | ||
25 | |||
26 | ldr r3, [r1, #-4] | ||
27 | mov r3, r3, lsr #16 | ||
28 | orr r3, r3, r3, lsl #16 | ||
29 | str r3, [r0] | ||
30 | subs r2, r2, #1 | ||
31 | moveq pc, lr | ||
32 | |||
33 | ENTRY(__raw_writesw) | ||
34 | teq r2, #0 @ do we have to check for the zero len? | ||
35 | moveq pc, lr | ||
36 | tst r1, #3 | ||
37 | bne .Loutsw_align | ||
38 | |||
39 | stmfd sp!, {r4, r5, r6, lr} | ||
40 | |||
41 | subs r2, r2, #8 | ||
42 | bmi .Lno_outsw_8 | ||
43 | |||
44 | .Loutsw_8_lp: ldmia r1!, {r3, r4, r5, r6} | ||
45 | |||
46 | mov ip, r3, lsl #16 | ||
47 | orr ip, ip, ip, lsr #16 | ||
48 | str ip, [r0] | ||
49 | |||
50 | mov ip, r3, lsr #16 | ||
51 | orr ip, ip, ip, lsl #16 | ||
52 | str ip, [r0] | ||
53 | |||
54 | mov ip, r4, lsl #16 | ||
55 | orr ip, ip, ip, lsr #16 | ||
56 | str ip, [r0] | ||
57 | |||
58 | mov ip, r4, lsr #16 | ||
59 | orr ip, ip, ip, lsl #16 | ||
60 | str ip, [r0] | ||
61 | |||
62 | mov ip, r5, lsl #16 | ||
63 | orr ip, ip, ip, lsr #16 | ||
64 | str ip, [r0] | ||
65 | |||
66 | mov ip, r5, lsr #16 | ||
67 | orr ip, ip, ip, lsl #16 | ||
68 | str ip, [r0] | ||
69 | |||
70 | mov ip, r6, lsl #16 | ||
71 | orr ip, ip, ip, lsr #16 | ||
72 | str ip, [r0] | ||
73 | |||
74 | mov ip, r6, lsr #16 | ||
75 | orr ip, ip, ip, lsl #16 | ||
76 | str ip, [r0] | ||
77 | |||
78 | subs r2, r2, #8 | ||
79 | bpl .Loutsw_8_lp | ||
80 | |||
81 | tst r2, #7 | ||
82 | ldmeqfd sp!, {r4, r5, r6, pc} | ||
83 | |||
84 | .Lno_outsw_8: tst r2, #4 | ||
85 | beq .Lno_outsw_4 | ||
86 | |||
87 | ldmia r1!, {r3, r4} | ||
88 | |||
89 | mov ip, r3, lsl #16 | ||
90 | orr ip, ip, ip, lsr #16 | ||
91 | str ip, [r0] | ||
92 | |||
93 | mov ip, r3, lsr #16 | ||
94 | orr ip, ip, ip, lsl #16 | ||
95 | str ip, [r0] | ||
96 | |||
97 | mov ip, r4, lsl #16 | ||
98 | orr ip, ip, ip, lsr #16 | ||
99 | str ip, [r0] | ||
100 | |||
101 | mov ip, r4, lsr #16 | ||
102 | orr ip, ip, ip, lsl #16 | ||
103 | str ip, [r0] | ||
104 | |||
105 | .Lno_outsw_4: tst r2, #2 | ||
106 | beq .Lno_outsw_2 | ||
107 | |||
108 | ldr r3, [r1], #4 | ||
109 | |||
110 | mov ip, r3, lsl #16 | ||
111 | orr ip, ip, ip, lsr #16 | ||
112 | str ip, [r0] | ||
113 | |||
114 | mov ip, r3, lsr #16 | ||
115 | orr ip, ip, ip, lsl #16 | ||
116 | str ip, [r0] | ||
117 | |||
118 | .Lno_outsw_2: tst r2, #1 | ||
119 | |||
120 | ldrne r3, [r1] | ||
121 | |||
122 | movne ip, r3, lsl #16 | ||
123 | orrne ip, ip, ip, lsr #16 | ||
124 | strne ip, [r0] | ||
125 | |||
126 | ldmfd sp!, {r4, r5, r6, pc} | ||
diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S new file mode 100644 index 000000000000..5c908b1cb8ed --- /dev/null +++ b/arch/arm/lib/uaccess.S | |||
@@ -0,0 +1,564 @@ | |||
1 | /* | ||
2 | * linux/arch/arm/lib/uaccess.S | ||
3 | * | ||
4 | * Copyright (C) 1995, 1996,1997,1998 Russell King | ||
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 version 2 as | ||
8 | * published by the Free Software Foundation. | ||
9 | * | ||
10 | * Routines to block copy data to/from user memory | ||
11 | * These are highly optimised both for the 4k page size | ||
12 | * and for various alignments. | ||
13 | */ | ||
14 | #include <linux/linkage.h> | ||
15 | #include <asm/assembler.h> | ||
16 | #include <asm/errno.h> | ||
17 | #include <asm/domain.h> | ||
18 | |||
19 | .text | ||
20 | |||
21 | #define PAGE_SHIFT 12 | ||
22 | |||
23 | /* Prototype: int __copy_to_user(void *to, const char *from, size_t n) | ||
24 | * Purpose : copy a block to user memory from kernel memory | ||
25 | * Params : to - user memory | ||
26 | * : from - kernel memory | ||
27 | * : n - number of bytes to copy | ||
28 | * Returns : Number of bytes NOT copied. | ||
29 | */ | ||
30 | |||
31 | .Lc2u_dest_not_aligned: | ||
32 | rsb ip, ip, #4 | ||
33 | cmp ip, #2 | ||
34 | ldrb r3, [r1], #1 | ||
35 | USER( TUSER( strb) r3, [r0], #1) @ May fault | ||
36 | ldrgeb r3, [r1], #1 | ||
37 | USER( TUSER( strgeb) r3, [r0], #1) @ May fault | ||
38 | ldrgtb r3, [r1], #1 | ||
39 | USER( TUSER( strgtb) r3, [r0], #1) @ May fault | ||
40 | sub r2, r2, ip | ||
41 | b .Lc2u_dest_aligned | ||
42 | |||
43 | ENTRY(__copy_to_user) | ||
44 | stmfd sp!, {r2, r4 - r7, lr} | ||
45 | cmp r2, #4 | ||
46 | blt .Lc2u_not_enough | ||
47 | ands ip, r0, #3 | ||
48 | bne .Lc2u_dest_not_aligned | ||
49 | .Lc2u_dest_aligned: | ||
50 | |||
51 | ands ip, r1, #3 | ||
52 | bne .Lc2u_src_not_aligned | ||
53 | /* | ||
54 | * Seeing as there has to be at least 8 bytes to copy, we can | ||
55 | * copy one word, and force a user-mode page fault... | ||
56 | */ | ||
57 | |||
58 | .Lc2u_0fupi: subs r2, r2, #4 | ||
59 | addmi ip, r2, #4 | ||
60 | bmi .Lc2u_0nowords | ||
61 | ldr r3, [r1], #4 | ||
62 | USER( TUSER( str) r3, [r0], #4) @ May fault | ||
63 | mov ip, r0, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction | ||
64 | rsb ip, ip, #0 | ||
65 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
66 | beq .Lc2u_0fupi | ||
67 | /* | ||
68 | * ip = max no. of bytes to copy before needing another "strt" insn | ||
69 | */ | ||
70 | cmp r2, ip | ||
71 | movlt ip, r2 | ||
72 | sub r2, r2, ip | ||
73 | subs ip, ip, #32 | ||
74 | blt .Lc2u_0rem8lp | ||
75 | |||
76 | .Lc2u_0cpy8lp: ldmia r1!, {r3 - r6} | ||
77 | stmia r0!, {r3 - r6} @ Shouldnt fault | ||
78 | ldmia r1!, {r3 - r6} | ||
79 | subs ip, ip, #32 | ||
80 | stmia r0!, {r3 - r6} @ Shouldnt fault | ||
81 | bpl .Lc2u_0cpy8lp | ||
82 | |||
83 | .Lc2u_0rem8lp: cmn ip, #16 | ||
84 | ldmgeia r1!, {r3 - r6} | ||
85 | stmgeia r0!, {r3 - r6} @ Shouldnt fault | ||
86 | tst ip, #8 | ||
87 | ldmneia r1!, {r3 - r4} | ||
88 | stmneia r0!, {r3 - r4} @ Shouldnt fault | ||
89 | tst ip, #4 | ||
90 | ldrne r3, [r1], #4 | ||
91 | TUSER( strne) r3, [r0], #4 @ Shouldnt fault | ||
92 | ands ip, ip, #3 | ||
93 | beq .Lc2u_0fupi | ||
94 | .Lc2u_0nowords: teq ip, #0 | ||
95 | beq .Lc2u_finished | ||
96 | .Lc2u_nowords: cmp ip, #2 | ||
97 | ldrb r3, [r1], #1 | ||
98 | USER( TUSER( strb) r3, [r0], #1) @ May fault | ||
99 | ldrgeb r3, [r1], #1 | ||
100 | USER( TUSER( strgeb) r3, [r0], #1) @ May fault | ||
101 | ldrgtb r3, [r1], #1 | ||
102 | USER( TUSER( strgtb) r3, [r0], #1) @ May fault | ||
103 | b .Lc2u_finished | ||
104 | |||
105 | .Lc2u_not_enough: | ||
106 | movs ip, r2 | ||
107 | bne .Lc2u_nowords | ||
108 | .Lc2u_finished: mov r0, #0 | ||
109 | ldmfd sp!, {r2, r4 - r7, pc} | ||
110 | |||
111 | .Lc2u_src_not_aligned: | ||
112 | bic r1, r1, #3 | ||
113 | ldr r7, [r1], #4 | ||
114 | cmp ip, #2 | ||
115 | bgt .Lc2u_3fupi | ||
116 | beq .Lc2u_2fupi | ||
117 | .Lc2u_1fupi: subs r2, r2, #4 | ||
118 | addmi ip, r2, #4 | ||
119 | bmi .Lc2u_1nowords | ||
120 | mov r3, r7, pull #8 | ||
121 | ldr r7, [r1], #4 | ||
122 | orr r3, r3, r7, push #24 | ||
123 | USER( TUSER( str) r3, [r0], #4) @ May fault | ||
124 | mov ip, r0, lsl #32 - PAGE_SHIFT | ||
125 | rsb ip, ip, #0 | ||
126 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
127 | beq .Lc2u_1fupi | ||
128 | cmp r2, ip | ||
129 | movlt ip, r2 | ||
130 | sub r2, r2, ip | ||
131 | subs ip, ip, #16 | ||
132 | blt .Lc2u_1rem8lp | ||
133 | |||
134 | .Lc2u_1cpy8lp: mov r3, r7, pull #8 | ||
135 | ldmia r1!, {r4 - r7} | ||
136 | subs ip, ip, #16 | ||
137 | orr r3, r3, r4, push #24 | ||
138 | mov r4, r4, pull #8 | ||
139 | orr r4, r4, r5, push #24 | ||
140 | mov r5, r5, pull #8 | ||
141 | orr r5, r5, r6, push #24 | ||
142 | mov r6, r6, pull #8 | ||
143 | orr r6, r6, r7, push #24 | ||
144 | stmia r0!, {r3 - r6} @ Shouldnt fault | ||
145 | bpl .Lc2u_1cpy8lp | ||
146 | |||
147 | .Lc2u_1rem8lp: tst ip, #8 | ||
148 | movne r3, r7, pull #8 | ||
149 | ldmneia r1!, {r4, r7} | ||
150 | orrne r3, r3, r4, push #24 | ||
151 | movne r4, r4, pull #8 | ||
152 | orrne r4, r4, r7, push #24 | ||
153 | stmneia r0!, {r3 - r4} @ Shouldnt fault | ||
154 | tst ip, #4 | ||
155 | movne r3, r7, pull #8 | ||
156 | ldrne r7, [r1], #4 | ||
157 | orrne r3, r3, r7, push #24 | ||
158 | TUSER( strne) r3, [r0], #4 @ Shouldnt fault | ||
159 | ands ip, ip, #3 | ||
160 | beq .Lc2u_1fupi | ||
161 | .Lc2u_1nowords: mov r3, r7, get_byte_1 | ||
162 | teq ip, #0 | ||
163 | beq .Lc2u_finished | ||
164 | cmp ip, #2 | ||
165 | USER( TUSER( strb) r3, [r0], #1) @ May fault | ||
166 | movge r3, r7, get_byte_2 | ||
167 | USER( TUSER( strgeb) r3, [r0], #1) @ May fault | ||
168 | movgt r3, r7, get_byte_3 | ||
169 | USER( TUSER( strgtb) r3, [r0], #1) @ May fault | ||
170 | b .Lc2u_finished | ||
171 | |||
172 | .Lc2u_2fupi: subs r2, r2, #4 | ||
173 | addmi ip, r2, #4 | ||
174 | bmi .Lc2u_2nowords | ||
175 | mov r3, r7, pull #16 | ||
176 | ldr r7, [r1], #4 | ||
177 | orr r3, r3, r7, push #16 | ||
178 | USER( TUSER( str) r3, [r0], #4) @ May fault | ||
179 | mov ip, r0, lsl #32 - PAGE_SHIFT | ||
180 | rsb ip, ip, #0 | ||
181 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
182 | beq .Lc2u_2fupi | ||
183 | cmp r2, ip | ||
184 | movlt ip, r2 | ||
185 | sub r2, r2, ip | ||
186 | subs ip, ip, #16 | ||
187 | blt .Lc2u_2rem8lp | ||
188 | |||
189 | .Lc2u_2cpy8lp: mov r3, r7, pull #16 | ||
190 | ldmia r1!, {r4 - r7} | ||
191 | subs ip, ip, #16 | ||
192 | orr r3, r3, r4, push #16 | ||
193 | mov r4, r4, pull #16 | ||
194 | orr r4, r4, r5, push #16 | ||
195 | mov r5, r5, pull #16 | ||
196 | orr r5, r5, r6, push #16 | ||
197 | mov r6, r6, pull #16 | ||
198 | orr r6, r6, r7, push #16 | ||
199 | stmia r0!, {r3 - r6} @ Shouldnt fault | ||
200 | bpl .Lc2u_2cpy8lp | ||
201 | |||
202 | .Lc2u_2rem8lp: tst ip, #8 | ||
203 | movne r3, r7, pull #16 | ||
204 | ldmneia r1!, {r4, r7} | ||
205 | orrne r3, r3, r4, push #16 | ||
206 | movne r4, r4, pull #16 | ||
207 | orrne r4, r4, r7, push #16 | ||
208 | stmneia r0!, {r3 - r4} @ Shouldnt fault | ||
209 | tst ip, #4 | ||
210 | movne r3, r7, pull #16 | ||
211 | ldrne r7, [r1], #4 | ||
212 | orrne r3, r3, r7, push #16 | ||
213 | TUSER( strne) r3, [r0], #4 @ Shouldnt fault | ||
214 | ands ip, ip, #3 | ||
215 | beq .Lc2u_2fupi | ||
216 | .Lc2u_2nowords: mov r3, r7, get_byte_2 | ||
217 | teq ip, #0 | ||
218 | beq .Lc2u_finished | ||
219 | cmp ip, #2 | ||
220 | USER( TUSER( strb) r3, [r0], #1) @ May fault | ||
221 | movge r3, r7, get_byte_3 | ||
222 | USER( TUSER( strgeb) r3, [r0], #1) @ May fault | ||
223 | ldrgtb r3, [r1], #0 | ||
224 | USER( TUSER( strgtb) r3, [r0], #1) @ May fault | ||
225 | b .Lc2u_finished | ||
226 | |||
227 | .Lc2u_3fupi: subs r2, r2, #4 | ||
228 | addmi ip, r2, #4 | ||
229 | bmi .Lc2u_3nowords | ||
230 | mov r3, r7, pull #24 | ||
231 | ldr r7, [r1], #4 | ||
232 | orr r3, r3, r7, push #8 | ||
233 | USER( TUSER( str) r3, [r0], #4) @ May fault | ||
234 | mov ip, r0, lsl #32 - PAGE_SHIFT | ||
235 | rsb ip, ip, #0 | ||
236 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
237 | beq .Lc2u_3fupi | ||
238 | cmp r2, ip | ||
239 | movlt ip, r2 | ||
240 | sub r2, r2, ip | ||
241 | subs ip, ip, #16 | ||
242 | blt .Lc2u_3rem8lp | ||
243 | |||
244 | .Lc2u_3cpy8lp: mov r3, r7, pull #24 | ||
245 | ldmia r1!, {r4 - r7} | ||
246 | subs ip, ip, #16 | ||
247 | orr r3, r3, r4, push #8 | ||
248 | mov r4, r4, pull #24 | ||
249 | orr r4, r4, r5, push #8 | ||
250 | mov r5, r5, pull #24 | ||
251 | orr r5, r5, r6, push #8 | ||
252 | mov r6, r6, pull #24 | ||
253 | orr r6, r6, r7, push #8 | ||
254 | stmia r0!, {r3 - r6} @ Shouldnt fault | ||
255 | bpl .Lc2u_3cpy8lp | ||
256 | |||
257 | .Lc2u_3rem8lp: tst ip, #8 | ||
258 | movne r3, r7, pull #24 | ||
259 | ldmneia r1!, {r4, r7} | ||
260 | orrne r3, r3, r4, push #8 | ||
261 | movne r4, r4, pull #24 | ||
262 | orrne r4, r4, r7, push #8 | ||
263 | stmneia r0!, {r3 - r4} @ Shouldnt fault | ||
264 | tst ip, #4 | ||
265 | movne r3, r7, pull #24 | ||
266 | ldrne r7, [r1], #4 | ||
267 | orrne r3, r3, r7, push #8 | ||
268 | TUSER( strne) r3, [r0], #4 @ Shouldnt fault | ||
269 | ands ip, ip, #3 | ||
270 | beq .Lc2u_3fupi | ||
271 | .Lc2u_3nowords: mov r3, r7, get_byte_3 | ||
272 | teq ip, #0 | ||
273 | beq .Lc2u_finished | ||
274 | cmp ip, #2 | ||
275 | USER( TUSER( strb) r3, [r0], #1) @ May fault | ||
276 | ldrgeb r3, [r1], #1 | ||
277 | USER( TUSER( strgeb) r3, [r0], #1) @ May fault | ||
278 | ldrgtb r3, [r1], #0 | ||
279 | USER( TUSER( strgtb) r3, [r0], #1) @ May fault | ||
280 | b .Lc2u_finished | ||
281 | ENDPROC(__copy_to_user) | ||
282 | |||
283 | .pushsection .fixup,"ax" | ||
284 | .align 0 | ||
285 | 9001: ldmfd sp!, {r0, r4 - r7, pc} | ||
286 | .popsection | ||
287 | |||
288 | /* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n); | ||
289 | * Purpose : copy a block from user memory to kernel memory | ||
290 | * Params : to - kernel memory | ||
291 | * : from - user memory | ||
292 | * : n - number of bytes to copy | ||
293 | * Returns : Number of bytes NOT copied. | ||
294 | */ | ||
295 | .Lcfu_dest_not_aligned: | ||
296 | rsb ip, ip, #4 | ||
297 | cmp ip, #2 | ||
298 | USER( TUSER( ldrb) r3, [r1], #1) @ May fault | ||
299 | strb r3, [r0], #1 | ||
300 | USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault | ||
301 | strgeb r3, [r0], #1 | ||
302 | USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault | ||
303 | strgtb r3, [r0], #1 | ||
304 | sub r2, r2, ip | ||
305 | b .Lcfu_dest_aligned | ||
306 | |||
307 | ENTRY(__copy_from_user) | ||
308 | stmfd sp!, {r0, r2, r4 - r7, lr} | ||
309 | cmp r2, #4 | ||
310 | blt .Lcfu_not_enough | ||
311 | ands ip, r0, #3 | ||
312 | bne .Lcfu_dest_not_aligned | ||
313 | .Lcfu_dest_aligned: | ||
314 | ands ip, r1, #3 | ||
315 | bne .Lcfu_src_not_aligned | ||
316 | |||
317 | /* | ||
318 | * Seeing as there has to be at least 8 bytes to copy, we can | ||
319 | * copy one word, and force a user-mode page fault... | ||
320 | */ | ||
321 | |||
322 | .Lcfu_0fupi: subs r2, r2, #4 | ||
323 | addmi ip, r2, #4 | ||
324 | bmi .Lcfu_0nowords | ||
325 | USER( TUSER( ldr) r3, [r1], #4) | ||
326 | str r3, [r0], #4 | ||
327 | mov ip, r1, lsl #32 - PAGE_SHIFT @ On each page, use a ld/st??t instruction | ||
328 | rsb ip, ip, #0 | ||
329 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
330 | beq .Lcfu_0fupi | ||
331 | /* | ||
332 | * ip = max no. of bytes to copy before needing another "strt" insn | ||
333 | */ | ||
334 | cmp r2, ip | ||
335 | movlt ip, r2 | ||
336 | sub r2, r2, ip | ||
337 | subs ip, ip, #32 | ||
338 | blt .Lcfu_0rem8lp | ||
339 | |||
340 | .Lcfu_0cpy8lp: ldmia r1!, {r3 - r6} @ Shouldnt fault | ||
341 | stmia r0!, {r3 - r6} | ||
342 | ldmia r1!, {r3 - r6} @ Shouldnt fault | ||
343 | subs ip, ip, #32 | ||
344 | stmia r0!, {r3 - r6} | ||
345 | bpl .Lcfu_0cpy8lp | ||
346 | |||
347 | .Lcfu_0rem8lp: cmn ip, #16 | ||
348 | ldmgeia r1!, {r3 - r6} @ Shouldnt fault | ||
349 | stmgeia r0!, {r3 - r6} | ||
350 | tst ip, #8 | ||
351 | ldmneia r1!, {r3 - r4} @ Shouldnt fault | ||
352 | stmneia r0!, {r3 - r4} | ||
353 | tst ip, #4 | ||
354 | TUSER( ldrne) r3, [r1], #4 @ Shouldnt fault | ||
355 | strne r3, [r0], #4 | ||
356 | ands ip, ip, #3 | ||
357 | beq .Lcfu_0fupi | ||
358 | .Lcfu_0nowords: teq ip, #0 | ||
359 | beq .Lcfu_finished | ||
360 | .Lcfu_nowords: cmp ip, #2 | ||
361 | USER( TUSER( ldrb) r3, [r1], #1) @ May fault | ||
362 | strb r3, [r0], #1 | ||
363 | USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault | ||
364 | strgeb r3, [r0], #1 | ||
365 | USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault | ||
366 | strgtb r3, [r0], #1 | ||
367 | b .Lcfu_finished | ||
368 | |||
369 | .Lcfu_not_enough: | ||
370 | movs ip, r2 | ||
371 | bne .Lcfu_nowords | ||
372 | .Lcfu_finished: mov r0, #0 | ||
373 | add sp, sp, #8 | ||
374 | ldmfd sp!, {r4 - r7, pc} | ||
375 | |||
376 | .Lcfu_src_not_aligned: | ||
377 | bic r1, r1, #3 | ||
378 | USER( TUSER( ldr) r7, [r1], #4) @ May fault | ||
379 | cmp ip, #2 | ||
380 | bgt .Lcfu_3fupi | ||
381 | beq .Lcfu_2fupi | ||
382 | .Lcfu_1fupi: subs r2, r2, #4 | ||
383 | addmi ip, r2, #4 | ||
384 | bmi .Lcfu_1nowords | ||
385 | mov r3, r7, pull #8 | ||
386 | USER( TUSER( ldr) r7, [r1], #4) @ May fault | ||
387 | orr r3, r3, r7, push #24 | ||
388 | str r3, [r0], #4 | ||
389 | mov ip, r1, lsl #32 - PAGE_SHIFT | ||
390 | rsb ip, ip, #0 | ||
391 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
392 | beq .Lcfu_1fupi | ||
393 | cmp r2, ip | ||
394 | movlt ip, r2 | ||
395 | sub r2, r2, ip | ||
396 | subs ip, ip, #16 | ||
397 | blt .Lcfu_1rem8lp | ||
398 | |||
399 | .Lcfu_1cpy8lp: mov r3, r7, pull #8 | ||
400 | ldmia r1!, {r4 - r7} @ Shouldnt fault | ||
401 | subs ip, ip, #16 | ||
402 | orr r3, r3, r4, push #24 | ||
403 | mov r4, r4, pull #8 | ||
404 | orr r4, r4, r5, push #24 | ||
405 | mov r5, r5, pull #8 | ||
406 | orr r5, r5, r6, push #24 | ||
407 | mov r6, r6, pull #8 | ||
408 | orr r6, r6, r7, push #24 | ||
409 | stmia r0!, {r3 - r6} | ||
410 | bpl .Lcfu_1cpy8lp | ||
411 | |||
412 | .Lcfu_1rem8lp: tst ip, #8 | ||
413 | movne r3, r7, pull #8 | ||
414 | ldmneia r1!, {r4, r7} @ Shouldnt fault | ||
415 | orrne r3, r3, r4, push #24 | ||
416 | movne r4, r4, pull #8 | ||
417 | orrne r4, r4, r7, push #24 | ||
418 | stmneia r0!, {r3 - r4} | ||
419 | tst ip, #4 | ||
420 | movne r3, r7, pull #8 | ||
421 | USER( TUSER( ldrne) r7, [r1], #4) @ May fault | ||
422 | orrne r3, r3, r7, push #24 | ||
423 | strne r3, [r0], #4 | ||
424 | ands ip, ip, #3 | ||
425 | beq .Lcfu_1fupi | ||
426 | .Lcfu_1nowords: mov r3, r7, get_byte_1 | ||
427 | teq ip, #0 | ||
428 | beq .Lcfu_finished | ||
429 | cmp ip, #2 | ||
430 | strb r3, [r0], #1 | ||
431 | movge r3, r7, get_byte_2 | ||
432 | strgeb r3, [r0], #1 | ||
433 | movgt r3, r7, get_byte_3 | ||
434 | strgtb r3, [r0], #1 | ||
435 | b .Lcfu_finished | ||
436 | |||
437 | .Lcfu_2fupi: subs r2, r2, #4 | ||
438 | addmi ip, r2, #4 | ||
439 | bmi .Lcfu_2nowords | ||
440 | mov r3, r7, pull #16 | ||
441 | USER( TUSER( ldr) r7, [r1], #4) @ May fault | ||
442 | orr r3, r3, r7, push #16 | ||
443 | str r3, [r0], #4 | ||
444 | mov ip, r1, lsl #32 - PAGE_SHIFT | ||
445 | rsb ip, ip, #0 | ||
446 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
447 | beq .Lcfu_2fupi | ||
448 | cmp r2, ip | ||
449 | movlt ip, r2 | ||
450 | sub r2, r2, ip | ||
451 | subs ip, ip, #16 | ||
452 | blt .Lcfu_2rem8lp | ||
453 | |||
454 | |||
455 | .Lcfu_2cpy8lp: mov r3, r7, pull #16 | ||
456 | ldmia r1!, {r4 - r7} @ Shouldnt fault | ||
457 | subs ip, ip, #16 | ||
458 | orr r3, r3, r4, push #16 | ||
459 | mov r4, r4, pull #16 | ||
460 | orr r4, r4, r5, push #16 | ||
461 | mov r5, r5, pull #16 | ||
462 | orr r5, r5, r6, push #16 | ||
463 | mov r6, r6, pull #16 | ||
464 | orr r6, r6, r7, push #16 | ||
465 | stmia r0!, {r3 - r6} | ||
466 | bpl .Lcfu_2cpy8lp | ||
467 | |||
468 | .Lcfu_2rem8lp: tst ip, #8 | ||
469 | movne r3, r7, pull #16 | ||
470 | ldmneia r1!, {r4, r7} @ Shouldnt fault | ||
471 | orrne r3, r3, r4, push #16 | ||
472 | movne r4, r4, pull #16 | ||
473 | orrne r4, r4, r7, push #16 | ||
474 | stmneia r0!, {r3 - r4} | ||
475 | tst ip, #4 | ||
476 | movne r3, r7, pull #16 | ||
477 | USER( TUSER( ldrne) r7, [r1], #4) @ May fault | ||
478 | orrne r3, r3, r7, push #16 | ||
479 | strne r3, [r0], #4 | ||
480 | ands ip, ip, #3 | ||
481 | beq .Lcfu_2fupi | ||
482 | .Lcfu_2nowords: mov r3, r7, get_byte_2 | ||
483 | teq ip, #0 | ||
484 | beq .Lcfu_finished | ||
485 | cmp ip, #2 | ||
486 | strb r3, [r0], #1 | ||
487 | movge r3, r7, get_byte_3 | ||
488 | strgeb r3, [r0], #1 | ||
489 | USER( TUSER( ldrgtb) r3, [r1], #0) @ May fault | ||
490 | strgtb r3, [r0], #1 | ||
491 | b .Lcfu_finished | ||
492 | |||
493 | .Lcfu_3fupi: subs r2, r2, #4 | ||
494 | addmi ip, r2, #4 | ||
495 | bmi .Lcfu_3nowords | ||
496 | mov r3, r7, pull #24 | ||
497 | USER( TUSER( ldr) r7, [r1], #4) @ May fault | ||
498 | orr r3, r3, r7, push #8 | ||
499 | str r3, [r0], #4 | ||
500 | mov ip, r1, lsl #32 - PAGE_SHIFT | ||
501 | rsb ip, ip, #0 | ||
502 | movs ip, ip, lsr #32 - PAGE_SHIFT | ||
503 | beq .Lcfu_3fupi | ||
504 | cmp r2, ip | ||
505 | movlt ip, r2 | ||
506 | sub r2, r2, ip | ||
507 | subs ip, ip, #16 | ||
508 | blt .Lcfu_3rem8lp | ||
509 | |||
510 | .Lcfu_3cpy8lp: mov r3, r7, pull #24 | ||
511 | ldmia r1!, {r4 - r7} @ Shouldnt fault | ||
512 | orr r3, r3, r4, push #8 | ||
513 | mov r4, r4, pull #24 | ||
514 | orr r4, r4, r5, push #8 | ||
515 | mov r5, r5, pull #24 | ||
516 | orr r5, r5, r6, push #8 | ||
517 | mov r6, r6, pull #24 | ||
518 | orr r6, r6, r7, push #8 | ||
519 | stmia r0!, {r3 - r6} | ||
520 | subs ip, ip, #16 | ||
521 | bpl .Lcfu_3cpy8lp | ||
522 | |||
523 | .Lcfu_3rem8lp: tst ip, #8 | ||
524 | movne r3, r7, pull #24 | ||
525 | ldmneia r1!, {r4, r7} @ Shouldnt fault | ||
526 | orrne r3, r3, r4, push #8 | ||
527 | movne r4, r4, pull #24 | ||
528 | orrne r4, r4, r7, push #8 | ||
529 | stmneia r0!, {r3 - r4} | ||
530 | tst ip, #4 | ||
531 | movne r3, r7, pull #24 | ||
532 | USER( TUSER( ldrne) r7, [r1], #4) @ May fault | ||
533 | orrne r3, r3, r7, push #8 | ||
534 | strne r3, [r0], #4 | ||
535 | ands ip, ip, #3 | ||
536 | beq .Lcfu_3fupi | ||
537 | .Lcfu_3nowords: mov r3, r7, get_byte_3 | ||
538 | teq ip, #0 | ||
539 | beq .Lcfu_finished | ||
540 | cmp ip, #2 | ||
541 | strb r3, [r0], #1 | ||
542 | USER( TUSER( ldrgeb) r3, [r1], #1) @ May fault | ||
543 | strgeb r3, [r0], #1 | ||
544 | USER( TUSER( ldrgtb) r3, [r1], #1) @ May fault | ||
545 | strgtb r3, [r0], #1 | ||
546 | b .Lcfu_finished | ||
547 | ENDPROC(__copy_from_user) | ||
548 | |||
549 | .pushsection .fixup,"ax" | ||
550 | .align 0 | ||
551 | /* | ||
552 | * We took an exception. r0 contains a pointer to | ||
553 | * the byte not copied. | ||
554 | */ | ||
555 | 9001: ldr r2, [sp], #4 @ void *to | ||
556 | sub r2, r0, r2 @ bytes copied | ||
557 | ldr r1, [sp], #4 @ unsigned long count | ||
558 | subs r4, r1, r2 @ bytes left to copy | ||
559 | movne r1, r4 | ||
560 | blne __memzero | ||
561 | mov r0, r4 | ||
562 | ldmfd sp!, {r4 - r7, pc} | ||
563 | .popsection | ||
564 | |||
diff --git a/arch/arm/mach-davinci/board-neuros-osd2.c b/arch/arm/mach-davinci/board-neuros-osd2.c index 5de69f2fcca9..f6b9fc70161b 100644 --- a/arch/arm/mach-davinci/board-neuros-osd2.c +++ b/arch/arm/mach-davinci/board-neuros-osd2.c | |||
@@ -162,38 +162,6 @@ static void __init davinci_ntosd2_map_io(void) | |||
162 | dm644x_init(); | 162 | dm644x_init(); |
163 | } | 163 | } |
164 | 164 | ||
165 | /* | ||
166 | I2C initialization | ||
167 | */ | ||
168 | static struct davinci_i2c_platform_data ntosd2_i2c_pdata = { | ||
169 | .bus_freq = 20 /* kHz */, | ||
170 | .bus_delay = 100 /* usec */, | ||
171 | }; | ||
172 | |||
173 | static struct i2c_board_info __initdata ntosd2_i2c_info[] = { | ||
174 | }; | ||
175 | |||
176 | static int ntosd2_init_i2c(void) | ||
177 | { | ||
178 | int status; | ||
179 | |||
180 | davinci_init_i2c(&ntosd2_i2c_pdata); | ||
181 | status = gpio_request(NTOSD2_MSP430_IRQ, ntosd2_i2c_info[0].type); | ||
182 | if (status == 0) { | ||
183 | status = gpio_direction_input(NTOSD2_MSP430_IRQ); | ||
184 | if (status == 0) { | ||
185 | status = gpio_to_irq(NTOSD2_MSP430_IRQ); | ||
186 | if (status > 0) { | ||
187 | ntosd2_i2c_info[0].irq = status; | ||
188 | i2c_register_board_info(1, | ||
189 | ntosd2_i2c_info, | ||
190 | ARRAY_SIZE(ntosd2_i2c_info)); | ||
191 | } | ||
192 | } | ||
193 | } | ||
194 | return status; | ||
195 | } | ||
196 | |||
197 | static struct davinci_mmc_config davinci_ntosd2_mmc_config = { | 165 | static struct davinci_mmc_config davinci_ntosd2_mmc_config = { |
198 | .wires = 4, | 166 | .wires = 4, |
199 | .version = MMC_CTLR_VERSION_1 | 167 | .version = MMC_CTLR_VERSION_1 |
@@ -218,7 +186,6 @@ static __init void davinci_ntosd2_init(void) | |||
218 | { | 186 | { |
219 | struct clk *aemif_clk; | 187 | struct clk *aemif_clk; |
220 | struct davinci_soc_info *soc_info = &davinci_soc_info; | 188 | struct davinci_soc_info *soc_info = &davinci_soc_info; |
221 | int status; | ||
222 | 189 | ||
223 | aemif_clk = clk_get(NULL, "aemif"); | 190 | aemif_clk = clk_get(NULL, "aemif"); |
224 | clk_enable(aemif_clk); | 191 | clk_enable(aemif_clk); |
@@ -242,12 +209,6 @@ static __init void davinci_ntosd2_init(void) | |||
242 | platform_add_devices(davinci_ntosd2_devices, | 209 | platform_add_devices(davinci_ntosd2_devices, |
243 | ARRAY_SIZE(davinci_ntosd2_devices)); | 210 | ARRAY_SIZE(davinci_ntosd2_devices)); |
244 | 211 | ||
245 | /* Initialize I2C interface specific for this board */ | ||
246 | status = ntosd2_init_i2c(); | ||
247 | if (status < 0) | ||
248 | pr_warning("davinci_ntosd2_init: msp430 irq setup failed:" | ||
249 | " %d\n", status); | ||
250 | |||
251 | davinci_serial_init(&uart_config); | 212 | davinci_serial_init(&uart_config); |
252 | dm644x_init_asp(&dm644x_ntosd2_snd_data); | 213 | dm644x_init_asp(&dm644x_ntosd2_snd_data); |
253 | 214 | ||
diff --git a/arch/arm/mach-dove/irq.c b/arch/arm/mach-dove/irq.c index f07fd16e0c9b..9bc97a5baaa8 100644 --- a/arch/arm/mach-dove/irq.c +++ b/arch/arm/mach-dove/irq.c | |||
@@ -20,22 +20,6 @@ | |||
20 | #include <mach/bridge-regs.h> | 20 | #include <mach/bridge-regs.h> |
21 | #include "common.h" | 21 | #include "common.h" |
22 | 22 | ||
23 | static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | ||
24 | { | ||
25 | int irqoff; | ||
26 | BUG_ON(irq < IRQ_DOVE_GPIO_0_7 || irq > IRQ_DOVE_HIGH_GPIO); | ||
27 | |||
28 | irqoff = irq <= IRQ_DOVE_GPIO_16_23 ? irq - IRQ_DOVE_GPIO_0_7 : | ||
29 | 3 + irq - IRQ_DOVE_GPIO_24_31; | ||
30 | |||
31 | orion_gpio_irq_handler(irqoff << 3); | ||
32 | if (irq == IRQ_DOVE_HIGH_GPIO) { | ||
33 | orion_gpio_irq_handler(40); | ||
34 | orion_gpio_irq_handler(48); | ||
35 | orion_gpio_irq_handler(56); | ||
36 | } | ||
37 | } | ||
38 | |||
39 | static void pmu_irq_mask(struct irq_data *d) | 23 | static void pmu_irq_mask(struct irq_data *d) |
40 | { | 24 | { |
41 | int pin = irq_to_pmu(d->irq); | 25 | int pin = irq_to_pmu(d->irq); |
@@ -90,6 +74,27 @@ static void pmu_irq_handler(unsigned int irq, struct irq_desc *desc) | |||
90 | } | 74 | } |
91 | } | 75 | } |
92 | 76 | ||
77 | static int __initdata gpio0_irqs[4] = { | ||
78 | IRQ_DOVE_GPIO_0_7, | ||
79 | IRQ_DOVE_GPIO_8_15, | ||
80 | IRQ_DOVE_GPIO_16_23, | ||
81 | IRQ_DOVE_GPIO_24_31, | ||
82 | }; | ||
83 | |||
84 | static int __initdata gpio1_irqs[4] = { | ||
85 | IRQ_DOVE_HIGH_GPIO, | ||
86 | 0, | ||
87 | 0, | ||
88 | 0, | ||
89 | }; | ||
90 | |||
91 | static int __initdata gpio2_irqs[4] = { | ||
92 | 0, | ||
93 | 0, | ||
94 | 0, | ||
95 | 0, | ||
96 | }; | ||
97 | |||
93 | void __init dove_init_irq(void) | 98 | void __init dove_init_irq(void) |
94 | { | 99 | { |
95 | int i; | 100 | int i; |
@@ -100,19 +105,14 @@ void __init dove_init_irq(void) | |||
100 | /* | 105 | /* |
101 | * Initialize gpiolib for GPIOs 0-71. | 106 | * Initialize gpiolib for GPIOs 0-71. |
102 | */ | 107 | */ |
103 | orion_gpio_init(0, 32, DOVE_GPIO_LO_VIRT_BASE, 0, | 108 | orion_gpio_init(NULL, 0, 32, (void __iomem *)DOVE_GPIO_LO_VIRT_BASE, 0, |
104 | IRQ_DOVE_GPIO_START); | 109 | IRQ_DOVE_GPIO_START, gpio0_irqs); |
105 | irq_set_chained_handler(IRQ_DOVE_GPIO_0_7, gpio_irq_handler); | 110 | |
106 | irq_set_chained_handler(IRQ_DOVE_GPIO_8_15, gpio_irq_handler); | 111 | orion_gpio_init(NULL, 32, 32, (void __iomem *)DOVE_GPIO_HI_VIRT_BASE, 0, |
107 | irq_set_chained_handler(IRQ_DOVE_GPIO_16_23, gpio_irq_handler); | 112 | IRQ_DOVE_GPIO_START + 32, gpio1_irqs); |
108 | irq_set_chained_handler(IRQ_DOVE_GPIO_24_31, gpio_irq_handler); | 113 | |
109 | 114 | orion_gpio_init(NULL, 64, 8, (void __iomem *)DOVE_GPIO2_VIRT_BASE, 0, | |
110 | orion_gpio_init(32, 32, DOVE_GPIO_HI_VIRT_BASE, 0, | 115 | IRQ_DOVE_GPIO_START + 64, gpio2_irqs); |
111 | IRQ_DOVE_GPIO_START + 32); | ||
112 | irq_set_chained_handler(IRQ_DOVE_HIGH_GPIO, gpio_irq_handler); | ||
113 | |||
114 | orion_gpio_init(64, 8, DOVE_GPIO2_VIRT_BASE, 0, | ||
115 | IRQ_DOVE_GPIO_START + 64); | ||
116 | 116 | ||
117 | /* | 117 | /* |
118 | * Mask and clear PMU interrupts | 118 | * Mask and clear PMU interrupts |
diff --git a/arch/arm/mach-exynos/pm_domains.c b/arch/arm/mach-exynos/pm_domains.c index 373c3c00d24c..c0bc83a7663e 100644 --- a/arch/arm/mach-exynos/pm_domains.c +++ b/arch/arm/mach-exynos/pm_domains.c | |||
@@ -115,7 +115,7 @@ static __init int exynos_pm_dt_parse_domains(void) | |||
115 | } | 115 | } |
116 | #endif /* CONFIG_OF */ | 116 | #endif /* CONFIG_OF */ |
117 | 117 | ||
118 | static __init void exynos_pm_add_dev_to_genpd(struct platform_device *pdev, | 118 | static __init __maybe_unused void exynos_pm_add_dev_to_genpd(struct platform_device *pdev, |
119 | struct exynos_pm_domain *pd) | 119 | struct exynos_pm_domain *pd) |
120 | { | 120 | { |
121 | if (pdev->dev.bus) { | 121 | if (pdev->dev.bus) { |
diff --git a/arch/arm/mach-imx/clk-imx27.c b/arch/arm/mach-imx/clk-imx27.c index 7aa6313fb167..f69ca4680049 100644 --- a/arch/arm/mach-imx/clk-imx27.c +++ b/arch/arm/mach-imx/clk-imx27.c | |||
@@ -223,7 +223,7 @@ int __init mx27_clocks_init(unsigned long fref) | |||
223 | clk_register_clkdev(clk[per3_gate], "per", "imx-fb.0"); | 223 | clk_register_clkdev(clk[per3_gate], "per", "imx-fb.0"); |
224 | clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx-fb.0"); | 224 | clk_register_clkdev(clk[lcdc_ipg_gate], "ipg", "imx-fb.0"); |
225 | clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx-fb.0"); | 225 | clk_register_clkdev(clk[lcdc_ahb_gate], "ahb", "imx-fb.0"); |
226 | clk_register_clkdev(clk[csi_ahb_gate], NULL, "mx2-camera.0"); | 226 | clk_register_clkdev(clk[csi_ahb_gate], "ahb", "mx2-camera.0"); |
227 | clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc"); | 227 | clk_register_clkdev(clk[usb_div], "per", "fsl-usb2-udc"); |
228 | clk_register_clkdev(clk[usb_ipg_gate], "ipg", "fsl-usb2-udc"); | 228 | clk_register_clkdev(clk[usb_ipg_gate], "ipg", "fsl-usb2-udc"); |
229 | clk_register_clkdev(clk[usb_ahb_gate], "ahb", "fsl-usb2-udc"); | 229 | clk_register_clkdev(clk[usb_ahb_gate], "ahb", "fsl-usb2-udc"); |
@@ -250,8 +250,10 @@ int __init mx27_clocks_init(unsigned long fref) | |||
250 | clk_register_clkdev(clk[i2c2_ipg_gate], NULL, "imx-i2c.1"); | 250 | clk_register_clkdev(clk[i2c2_ipg_gate], NULL, "imx-i2c.1"); |
251 | clk_register_clkdev(clk[owire_ipg_gate], NULL, "mxc_w1.0"); | 251 | clk_register_clkdev(clk[owire_ipg_gate], NULL, "mxc_w1.0"); |
252 | clk_register_clkdev(clk[kpp_ipg_gate], NULL, "imx-keypad"); | 252 | clk_register_clkdev(clk[kpp_ipg_gate], NULL, "imx-keypad"); |
253 | clk_register_clkdev(clk[emma_ahb_gate], "ahb", "imx-emma"); | 253 | clk_register_clkdev(clk[emma_ahb_gate], "emma-ahb", "mx2-camera.0"); |
254 | clk_register_clkdev(clk[emma_ipg_gate], "ipg", "imx-emma"); | 254 | clk_register_clkdev(clk[emma_ipg_gate], "emma-ipg", "mx2-camera.0"); |
255 | clk_register_clkdev(clk[emma_ahb_gate], "ahb", "m2m-emmaprp.0"); | ||
256 | clk_register_clkdev(clk[emma_ipg_gate], "ipg", "m2m-emmaprp.0"); | ||
255 | clk_register_clkdev(clk[iim_ipg_gate], "iim", NULL); | 257 | clk_register_clkdev(clk[iim_ipg_gate], "iim", NULL); |
256 | clk_register_clkdev(clk[gpio_ipg_gate], "gpio", NULL); | 258 | clk_register_clkdev(clk[gpio_ipg_gate], "gpio", NULL); |
257 | clk_register_clkdev(clk[brom_ahb_gate], "brom", NULL); | 259 | clk_register_clkdev(clk[brom_ahb_gate], "brom", NULL); |
diff --git a/arch/arm/mach-imx/clk-imx31.c b/arch/arm/mach-imx/clk-imx31.c index 8e19e70f90f9..1253af2d9971 100644 --- a/arch/arm/mach-imx/clk-imx31.c +++ b/arch/arm/mach-imx/clk-imx31.c | |||
@@ -130,7 +130,7 @@ int __init mx31_clocks_init(unsigned long fref) | |||
130 | clk_register_clkdev(clk[nfc], NULL, "mxc_nand.0"); | 130 | clk_register_clkdev(clk[nfc], NULL, "mxc_nand.0"); |
131 | clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core"); | 131 | clk_register_clkdev(clk[ipu_gate], NULL, "ipu-core"); |
132 | clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb"); | 132 | clk_register_clkdev(clk[ipu_gate], NULL, "mx3_sdc_fb"); |
133 | clk_register_clkdev(clk[kpp_gate], "kpp", NULL); | 133 | clk_register_clkdev(clk[kpp_gate], NULL, "imx-keypad"); |
134 | clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.0"); | 134 | clk_register_clkdev(clk[usb_div_post], "per", "mxc-ehci.0"); |
135 | clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.0"); | 135 | clk_register_clkdev(clk[usb_gate], "ahb", "mxc-ehci.0"); |
136 | clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0"); | 136 | clk_register_clkdev(clk[ipg], "ipg", "mxc-ehci.0"); |
diff --git a/arch/arm/mach-imx/clk-imx51-imx53.c b/arch/arm/mach-imx/clk-imx51-imx53.c index f6086693ebd2..4bdcaa97bd98 100644 --- a/arch/arm/mach-imx/clk-imx51-imx53.c +++ b/arch/arm/mach-imx/clk-imx51-imx53.c | |||
@@ -303,6 +303,7 @@ static void __init mx5_clocks_common_init(unsigned long rate_ckil, | |||
303 | clk_prepare_enable(clk[aips_tz2]); /* fec */ | 303 | clk_prepare_enable(clk[aips_tz2]); /* fec */ |
304 | clk_prepare_enable(clk[spba]); | 304 | clk_prepare_enable(clk[spba]); |
305 | clk_prepare_enable(clk[emi_fast_gate]); /* fec */ | 305 | clk_prepare_enable(clk[emi_fast_gate]); /* fec */ |
306 | clk_prepare_enable(clk[emi_slow_gate]); /* eim */ | ||
306 | clk_prepare_enable(clk[tmax1]); | 307 | clk_prepare_enable(clk[tmax1]); |
307 | clk_prepare_enable(clk[tmax2]); /* esdhc2, fec */ | 308 | clk_prepare_enable(clk[tmax2]); /* esdhc2, fec */ |
308 | clk_prepare_enable(clk[tmax3]); /* esdhc1, esdhc4 */ | 309 | clk_prepare_enable(clk[tmax3]); /* esdhc1, esdhc4 */ |
diff --git a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c index ebf680bebdf2..3fa6c51390da 100644 --- a/arch/arm/mach-integrator/core.c +++ b/arch/arm/mach-integrator/core.c | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/device.h> | 13 | #include <linux/device.h> |
14 | #include <linux/export.h> | ||
14 | #include <linux/spinlock.h> | 15 | #include <linux/spinlock.h> |
15 | #include <linux/interrupt.h> | 16 | #include <linux/interrupt.h> |
16 | #include <linux/irq.h> | 17 | #include <linux/irq.h> |
diff --git a/arch/arm/mach-integrator/integrator_ap.c b/arch/arm/mach-integrator/integrator_ap.c index 7b1055c8e0b9..3b2267529f5e 100644 --- a/arch/arm/mach-integrator/integrator_ap.c +++ b/arch/arm/mach-integrator/integrator_ap.c | |||
@@ -456,7 +456,7 @@ static void __init ap_init_timer(void) | |||
456 | 456 | ||
457 | clk = clk_get_sys("ap_timer", NULL); | 457 | clk = clk_get_sys("ap_timer", NULL); |
458 | BUG_ON(IS_ERR(clk)); | 458 | BUG_ON(IS_ERR(clk)); |
459 | clk_enable(clk); | 459 | clk_prepare_enable(clk); |
460 | rate = clk_get_rate(clk); | 460 | rate = clk_get_rate(clk); |
461 | 461 | ||
462 | writel(0, TIMER0_VA_BASE + TIMER_CTRL); | 462 | writel(0, TIMER0_VA_BASE + TIMER_CTRL); |
diff --git a/arch/arm/mach-kirkwood/Kconfig b/arch/arm/mach-kirkwood/Kconfig index 199764fe0fb0..ca5c15a4e626 100644 --- a/arch/arm/mach-kirkwood/Kconfig +++ b/arch/arm/mach-kirkwood/Kconfig | |||
@@ -80,6 +80,35 @@ config MACH_IB62X0_DT | |||
80 | RaidSonic IB-NAS6210 & IB-NAS6220 devices, using | 80 | RaidSonic IB-NAS6210 & IB-NAS6220 devices, using |
81 | Flattened Device Tree. | 81 | Flattened Device Tree. |
82 | 82 | ||
83 | config MACH_TS219_DT | ||
84 | bool "Device Tree for QNAP TS-11X, TS-21X NAS" | ||
85 | select ARCH_KIRKWOOD_DT | ||
86 | select ARM_APPENDED_DTB | ||
87 | select ARM_ATAG_DTB_COMPAT | ||
88 | help | ||
89 | Say 'Y' here if you want your kernel to support the QNAP | ||
90 | TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and | ||
91 | TS-219P+ Turbo NAS devices using Fattened Device Tree. | ||
92 | There are two different Device Tree descriptions, depending | ||
93 | on if the device is based on an if the board uses the MV6281 | ||
94 | or MV6282. If you have the wrong one, the buttons will not | ||
95 | work. | ||
96 | |||
97 | config MACH_GOFLEXNET_DT | ||
98 | bool "Seagate GoFlex Net (Flattened Device Tree)" | ||
99 | select ARCH_KIRKWOOD_DT | ||
100 | help | ||
101 | Say 'Y' here if you want your kernel to support the | ||
102 | Seagate GoFlex Net (Flattened Device Tree). | ||
103 | |||
104 | config MACH_LSXL_DT | ||
105 | bool "Buffalo Linkstation LS-XHL, LS-CHLv2 (Flattened Device Tree)" | ||
106 | select ARCH_KIRKWOOD_DT | ||
107 | help | ||
108 | Say 'Y' here if you want your kernel to support the | ||
109 | Buffalo Linkstation LS-XHL & LS-CHLv2 devices, using | ||
110 | Flattened Device Tree. | ||
111 | |||
83 | config MACH_TS219 | 112 | config MACH_TS219 |
84 | bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS" | 113 | bool "QNAP TS-110, TS-119, TS-119P+, TS-210, TS-219, TS-219P and TS-219P+ Turbo NAS" |
85 | help | 114 | help |
diff --git a/arch/arm/mach-kirkwood/Makefile b/arch/arm/mach-kirkwood/Makefile index d2b05907b10e..055c85a1cc46 100644 --- a/arch/arm/mach-kirkwood/Makefile +++ b/arch/arm/mach-kirkwood/Makefile | |||
@@ -25,3 +25,6 @@ obj-$(CONFIG_MACH_DREAMPLUG_DT) += board-dreamplug.o | |||
25 | obj-$(CONFIG_MACH_ICONNECT_DT) += board-iconnect.o | 25 | obj-$(CONFIG_MACH_ICONNECT_DT) += board-iconnect.o |
26 | obj-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += board-dnskw.o | 26 | obj-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += board-dnskw.o |
27 | obj-$(CONFIG_MACH_IB62X0_DT) += board-ib62x0.o | 27 | obj-$(CONFIG_MACH_IB62X0_DT) += board-ib62x0.o |
28 | obj-$(CONFIG_MACH_TS219_DT) += board-ts219.o tsx1x-common.o | ||
29 | obj-$(CONFIG_MACH_GOFLEXNET_DT) += board-goflexnet.o | ||
30 | obj-$(CONFIG_MACH_LSXL_DT) += board-lsxl.o | ||
diff --git a/arch/arm/mach-kirkwood/Makefile.boot b/arch/arm/mach-kirkwood/Makefile.boot index 02edbdf5b065..a5717558ee89 100644 --- a/arch/arm/mach-kirkwood/Makefile.boot +++ b/arch/arm/mach-kirkwood/Makefile.boot | |||
@@ -7,3 +7,7 @@ dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns320.dtb | |||
7 | dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns325.dtb | 7 | dtb-$(CONFIG_MACH_DLINK_KIRKWOOD_DT) += kirkwood-dns325.dtb |
8 | dtb-$(CONFIG_MACH_ICONNECT_DT) += kirkwood-iconnect.dtb | 8 | dtb-$(CONFIG_MACH_ICONNECT_DT) += kirkwood-iconnect.dtb |
9 | dtb-$(CONFIG_MACH_IB62X0_DT) += kirkwood-ib62x0.dtb | 9 | dtb-$(CONFIG_MACH_IB62X0_DT) += kirkwood-ib62x0.dtb |
10 | dtb-$(CONFIG_MACH_TS219_DT) += kirkwood-qnap-ts219.dtb | ||
11 | dtb-$(CONFIG_MACH_GOFLEXNET_DT) += kirkwood-goflexnet.dtb | ||
12 | dtb-$(CONFIG_MACH_LSXL_DT) += kirkwood-lschlv2.dtb | ||
13 | dtb-$(CONFIG_MACH_LSXL_DT) += kirkwood-lsxhl.dtb | ||
diff --git a/arch/arm/mach-kirkwood/board-dnskw.c b/arch/arm/mach-kirkwood/board-dnskw.c index 58c2d68f9443..4ab35065a144 100644 --- a/arch/arm/mach-kirkwood/board-dnskw.c +++ b/arch/arm/mach-kirkwood/board-dnskw.c | |||
@@ -14,13 +14,11 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/i2c.h> | ||
18 | #include <linux/ata_platform.h> | 17 | #include <linux/ata_platform.h> |
19 | #include <linux/mv643xx_eth.h> | 18 | #include <linux/mv643xx_eth.h> |
20 | #include <linux/of.h> | 19 | #include <linux/of.h> |
21 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
22 | #include <linux/input.h> | 21 | #include <linux/input.h> |
23 | #include <linux/gpio_keys.h> | ||
24 | #include <linux/gpio-fan.h> | 22 | #include <linux/gpio-fan.h> |
25 | #include <linux/leds.h> | 23 | #include <linux/leds.h> |
26 | #include <asm/mach-types.h> | 24 | #include <asm/mach-types.h> |
@@ -35,10 +33,6 @@ static struct mv643xx_eth_platform_data dnskw_ge00_data = { | |||
35 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), | 33 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), |
36 | }; | 34 | }; |
37 | 35 | ||
38 | static struct mv_sata_platform_data dnskw_sata_data = { | ||
39 | .n_ports = 2, | ||
40 | }; | ||
41 | |||
42 | static unsigned int dnskw_mpp_config[] __initdata = { | 36 | static unsigned int dnskw_mpp_config[] __initdata = { |
43 | MPP13_UART1_TXD, /* Custom ... */ | 37 | MPP13_UART1_TXD, /* Custom ... */ |
44 | MPP14_UART1_RXD, /* ... Controller (DNS-320 only) */ | 38 | MPP14_UART1_RXD, /* ... Controller (DNS-320 only) */ |
@@ -73,132 +67,6 @@ static unsigned int dnskw_mpp_config[] __initdata = { | |||
73 | 0 | 67 | 0 |
74 | }; | 68 | }; |
75 | 69 | ||
76 | static struct gpio_led dns325_led_pins[] = { | ||
77 | { | ||
78 | .name = "dns325:white:power", | ||
79 | .gpio = 26, | ||
80 | .active_low = 1, | ||
81 | .default_trigger = "default-on", | ||
82 | }, | ||
83 | { | ||
84 | .name = "dns325:white:usb", | ||
85 | .gpio = 43, | ||
86 | .active_low = 1, | ||
87 | }, | ||
88 | { | ||
89 | .name = "dns325:red:l_hdd", | ||
90 | .gpio = 28, | ||
91 | .active_low = 1, | ||
92 | }, | ||
93 | { | ||
94 | .name = "dns325:red:r_hdd", | ||
95 | .gpio = 27, | ||
96 | .active_low = 1, | ||
97 | }, | ||
98 | { | ||
99 | .name = "dns325:red:usb", | ||
100 | .gpio = 29, | ||
101 | .active_low = 1, | ||
102 | }, | ||
103 | }; | ||
104 | |||
105 | static struct gpio_led_platform_data dns325_led_data = { | ||
106 | .num_leds = ARRAY_SIZE(dns325_led_pins), | ||
107 | .leds = dns325_led_pins, | ||
108 | }; | ||
109 | |||
110 | static struct platform_device dns325_led_device = { | ||
111 | .name = "leds-gpio", | ||
112 | .id = -1, | ||
113 | .dev = { | ||
114 | .platform_data = &dns325_led_data, | ||
115 | }, | ||
116 | }; | ||
117 | |||
118 | static struct gpio_led dns320_led_pins[] = { | ||
119 | { | ||
120 | .name = "dns320:blue:power", | ||
121 | .gpio = 26, | ||
122 | .active_low = 1, | ||
123 | .default_trigger = "default-on", | ||
124 | }, | ||
125 | { | ||
126 | .name = "dns320:blue:usb", | ||
127 | .gpio = 43, | ||
128 | .active_low = 1, | ||
129 | }, | ||
130 | { | ||
131 | .name = "dns320:orange:l_hdd", | ||
132 | .gpio = 28, | ||
133 | .active_low = 1, | ||
134 | }, | ||
135 | { | ||
136 | .name = "dns320:orange:r_hdd", | ||
137 | .gpio = 27, | ||
138 | .active_low = 1, | ||
139 | }, | ||
140 | { | ||
141 | .name = "dns320:orange:usb", | ||
142 | .gpio = 35, | ||
143 | .active_low = 1, | ||
144 | }, | ||
145 | }; | ||
146 | |||
147 | static struct gpio_led_platform_data dns320_led_data = { | ||
148 | .num_leds = ARRAY_SIZE(dns320_led_pins), | ||
149 | .leds = dns320_led_pins, | ||
150 | }; | ||
151 | |||
152 | static struct platform_device dns320_led_device = { | ||
153 | .name = "leds-gpio", | ||
154 | .id = -1, | ||
155 | .dev = { | ||
156 | .platform_data = &dns320_led_data, | ||
157 | }, | ||
158 | }; | ||
159 | |||
160 | static struct i2c_board_info dns325_i2c_board_info[] __initdata = { | ||
161 | { | ||
162 | I2C_BOARD_INFO("lm75", 0x48), | ||
163 | }, | ||
164 | /* Something at 0x0c also */ | ||
165 | }; | ||
166 | |||
167 | static struct gpio_keys_button dnskw_button_pins[] = { | ||
168 | { | ||
169 | .code = KEY_POWER, | ||
170 | .gpio = 34, | ||
171 | .desc = "Power button", | ||
172 | .active_low = 1, | ||
173 | }, | ||
174 | { | ||
175 | .code = KEY_EJECTCD, | ||
176 | .gpio = 47, | ||
177 | .desc = "USB unmount button", | ||
178 | .active_low = 1, | ||
179 | }, | ||
180 | { | ||
181 | .code = KEY_RESTART, | ||
182 | .gpio = 48, | ||
183 | .desc = "Reset button", | ||
184 | .active_low = 1, | ||
185 | }, | ||
186 | }; | ||
187 | |||
188 | static struct gpio_keys_platform_data dnskw_button_data = { | ||
189 | .buttons = dnskw_button_pins, | ||
190 | .nbuttons = ARRAY_SIZE(dnskw_button_pins), | ||
191 | }; | ||
192 | |||
193 | static struct platform_device dnskw_button_device = { | ||
194 | .name = "gpio-keys", | ||
195 | .id = -1, | ||
196 | .num_resources = 0, | ||
197 | .dev = { | ||
198 | .platform_data = &dnskw_button_data, | ||
199 | } | ||
200 | }; | ||
201 | |||
202 | /* Fan: ADDA AD045HB-G73 40mm 6000rpm@5v */ | 70 | /* Fan: ADDA AD045HB-G73 40mm 6000rpm@5v */ |
203 | static struct gpio_fan_speed dnskw_fan_speed[] = { | 71 | static struct gpio_fan_speed dnskw_fan_speed[] = { |
204 | { 0, 0 }, | 72 | { 0, 0 }, |
@@ -245,20 +113,9 @@ void __init dnskw_init(void) | |||
245 | 113 | ||
246 | kirkwood_ehci_init(); | 114 | kirkwood_ehci_init(); |
247 | kirkwood_ge00_init(&dnskw_ge00_data); | 115 | kirkwood_ge00_init(&dnskw_ge00_data); |
248 | kirkwood_sata_init(&dnskw_sata_data); | ||
249 | kirkwood_i2c_init(); | ||
250 | 116 | ||
251 | platform_device_register(&dnskw_button_device); | ||
252 | platform_device_register(&dnskw_fan_device); | 117 | platform_device_register(&dnskw_fan_device); |
253 | 118 | ||
254 | if (of_machine_is_compatible("dlink,dns-325")) { | ||
255 | i2c_register_board_info(0, dns325_i2c_board_info, | ||
256 | ARRAY_SIZE(dns325_i2c_board_info)); | ||
257 | platform_device_register(&dns325_led_device); | ||
258 | |||
259 | } else if (of_machine_is_compatible("dlink,dns-320")) | ||
260 | platform_device_register(&dns320_led_device); | ||
261 | |||
262 | /* Register power-off GPIO. */ | 119 | /* Register power-off GPIO. */ |
263 | if (gpio_request(36, "dnskw:power:off") == 0 | 120 | if (gpio_request(36, "dnskw:power:off") == 0 |
264 | && gpio_direction_output(36, 0) == 0) | 121 | && gpio_direction_output(36, 0) == 0) |
diff --git a/arch/arm/mach-kirkwood/board-dreamplug.c b/arch/arm/mach-kirkwood/board-dreamplug.c index 55e357ab2923..aeb234d0d0e3 100644 --- a/arch/arm/mach-kirkwood/board-dreamplug.c +++ b/arch/arm/mach-kirkwood/board-dreamplug.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/kernel.h> | 14 | #include <linux/kernel.h> |
15 | #include <linux/init.h> | 15 | #include <linux/init.h> |
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/mtd/partitions.h> | ||
18 | #include <linux/ata_platform.h> | 17 | #include <linux/ata_platform.h> |
19 | #include <linux/mv643xx_eth.h> | 18 | #include <linux/mv643xx_eth.h> |
20 | #include <linux/of.h> | 19 | #include <linux/of.h> |
@@ -23,7 +22,6 @@ | |||
23 | #include <linux/of_irq.h> | 22 | #include <linux/of_irq.h> |
24 | #include <linux/of_platform.h> | 23 | #include <linux/of_platform.h> |
25 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
26 | #include <linux/leds.h> | ||
27 | #include <linux/mtd/physmap.h> | 25 | #include <linux/mtd/physmap.h> |
28 | #include <linux/spi/flash.h> | 26 | #include <linux/spi/flash.h> |
29 | #include <linux/spi/spi.h> | 27 | #include <linux/spi/spi.h> |
@@ -36,42 +34,6 @@ | |||
36 | #include "common.h" | 34 | #include "common.h" |
37 | #include "mpp.h" | 35 | #include "mpp.h" |
38 | 36 | ||
39 | struct mtd_partition dreamplug_partitions[] = { | ||
40 | { | ||
41 | .name = "u-boot", | ||
42 | .size = SZ_512K, | ||
43 | .offset = 0, | ||
44 | }, | ||
45 | { | ||
46 | .name = "u-boot env", | ||
47 | .size = SZ_64K, | ||
48 | .offset = SZ_512K + SZ_512K, | ||
49 | }, | ||
50 | { | ||
51 | .name = "dtb", | ||
52 | .size = SZ_64K, | ||
53 | .offset = SZ_512K + SZ_512K + SZ_512K, | ||
54 | }, | ||
55 | }; | ||
56 | |||
57 | static const struct flash_platform_data dreamplug_spi_slave_data = { | ||
58 | .type = "mx25l1606e", | ||
59 | .name = "spi_flash", | ||
60 | .parts = dreamplug_partitions, | ||
61 | .nr_parts = ARRAY_SIZE(dreamplug_partitions), | ||
62 | }; | ||
63 | |||
64 | static struct spi_board_info __initdata dreamplug_spi_slave_info[] = { | ||
65 | { | ||
66 | .modalias = "m25p80", | ||
67 | .platform_data = &dreamplug_spi_slave_data, | ||
68 | .irq = -1, | ||
69 | .max_speed_hz = 50000000, | ||
70 | .bus_num = 0, | ||
71 | .chip_select = 0, | ||
72 | }, | ||
73 | }; | ||
74 | |||
75 | static struct mv643xx_eth_platform_data dreamplug_ge00_data = { | 37 | static struct mv643xx_eth_platform_data dreamplug_ge00_data = { |
76 | .phy_addr = MV643XX_ETH_PHY_ADDR(0), | 38 | .phy_addr = MV643XX_ETH_PHY_ADDR(0), |
77 | }; | 39 | }; |
@@ -80,45 +42,10 @@ static struct mv643xx_eth_platform_data dreamplug_ge01_data = { | |||
80 | .phy_addr = MV643XX_ETH_PHY_ADDR(1), | 42 | .phy_addr = MV643XX_ETH_PHY_ADDR(1), |
81 | }; | 43 | }; |
82 | 44 | ||
83 | static struct mv_sata_platform_data dreamplug_sata_data = { | ||
84 | .n_ports = 1, | ||
85 | }; | ||
86 | |||
87 | static struct mvsdio_platform_data dreamplug_mvsdio_data = { | 45 | static struct mvsdio_platform_data dreamplug_mvsdio_data = { |
88 | /* unfortunately the CD signal has not been connected */ | 46 | /* unfortunately the CD signal has not been connected */ |
89 | }; | 47 | }; |
90 | 48 | ||
91 | static struct gpio_led dreamplug_led_pins[] = { | ||
92 | { | ||
93 | .name = "dreamplug:blue:bluetooth", | ||
94 | .gpio = 47, | ||
95 | .active_low = 1, | ||
96 | }, | ||
97 | { | ||
98 | .name = "dreamplug:green:wifi", | ||
99 | .gpio = 48, | ||
100 | .active_low = 1, | ||
101 | }, | ||
102 | { | ||
103 | .name = "dreamplug:green:wifi_ap", | ||
104 | .gpio = 49, | ||
105 | .active_low = 1, | ||
106 | }, | ||
107 | }; | ||
108 | |||
109 | static struct gpio_led_platform_data dreamplug_led_data = { | ||
110 | .leds = dreamplug_led_pins, | ||
111 | .num_leds = ARRAY_SIZE(dreamplug_led_pins), | ||
112 | }; | ||
113 | |||
114 | static struct platform_device dreamplug_leds = { | ||
115 | .name = "leds-gpio", | ||
116 | .id = -1, | ||
117 | .dev = { | ||
118 | .platform_data = &dreamplug_led_data, | ||
119 | } | ||
120 | }; | ||
121 | |||
122 | static unsigned int dreamplug_mpp_config[] __initdata = { | 49 | static unsigned int dreamplug_mpp_config[] __initdata = { |
123 | MPP0_SPI_SCn, | 50 | MPP0_SPI_SCn, |
124 | MPP1_SPI_MOSI, | 51 | MPP1_SPI_MOSI, |
@@ -137,15 +64,8 @@ void __init dreamplug_init(void) | |||
137 | */ | 64 | */ |
138 | kirkwood_mpp_conf(dreamplug_mpp_config); | 65 | kirkwood_mpp_conf(dreamplug_mpp_config); |
139 | 66 | ||
140 | spi_register_board_info(dreamplug_spi_slave_info, | ||
141 | ARRAY_SIZE(dreamplug_spi_slave_info)); | ||
142 | kirkwood_spi_init(); | ||
143 | |||
144 | kirkwood_ehci_init(); | 67 | kirkwood_ehci_init(); |
145 | kirkwood_ge00_init(&dreamplug_ge00_data); | 68 | kirkwood_ge00_init(&dreamplug_ge00_data); |
146 | kirkwood_ge01_init(&dreamplug_ge01_data); | 69 | kirkwood_ge01_init(&dreamplug_ge01_data); |
147 | kirkwood_sata_init(&dreamplug_sata_data); | ||
148 | kirkwood_sdio_init(&dreamplug_mvsdio_data); | 70 | kirkwood_sdio_init(&dreamplug_mvsdio_data); |
149 | |||
150 | platform_device_register(&dreamplug_leds); | ||
151 | } | 71 | } |
diff --git a/arch/arm/mach-kirkwood/board-dt.c b/arch/arm/mach-kirkwood/board-dt.c index edc3f8a9d45e..e4eb450de301 100644 --- a/arch/arm/mach-kirkwood/board-dt.c +++ b/arch/arm/mach-kirkwood/board-dt.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <asm/mach/arch.h> | 18 | #include <asm/mach/arch.h> |
19 | #include <asm/mach/map.h> | 19 | #include <asm/mach/map.h> |
20 | #include <mach/bridge-regs.h> | 20 | #include <mach/bridge-regs.h> |
21 | #include <plat/irq.h> | ||
21 | #include "common.h" | 22 | #include "common.h" |
22 | 23 | ||
23 | static struct of_device_id kirkwood_dt_match_table[] __initdata = { | 24 | static struct of_device_id kirkwood_dt_match_table[] __initdata = { |
@@ -25,6 +26,16 @@ static struct of_device_id kirkwood_dt_match_table[] __initdata = { | |||
25 | { } | 26 | { } |
26 | }; | 27 | }; |
27 | 28 | ||
29 | struct of_dev_auxdata kirkwood_auxdata_lookup[] __initdata = { | ||
30 | OF_DEV_AUXDATA("marvell,orion-spi", 0xf1010600, "orion_spi.0", NULL), | ||
31 | OF_DEV_AUXDATA("marvell,mv64xxx-i2c", 0xf1011000, "mv64xxx_i2c.0", | ||
32 | NULL), | ||
33 | OF_DEV_AUXDATA("marvell,orion-wdt", 0xf1020300, "orion_wdt", NULL), | ||
34 | OF_DEV_AUXDATA("marvell,orion-sata", 0xf1080000, "sata_mv.0", NULL), | ||
35 | OF_DEV_AUXDATA("marvell,orion-nand", 0xf4000000, "orion_nand", NULL), | ||
36 | {}, | ||
37 | }; | ||
38 | |||
28 | static void __init kirkwood_dt_init(void) | 39 | static void __init kirkwood_dt_init(void) |
29 | { | 40 | { |
30 | pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk); | 41 | pr_info("Kirkwood: %s, TCLK=%d.\n", kirkwood_id(), kirkwood_tclk); |
@@ -47,7 +58,6 @@ static void __init kirkwood_dt_init(void) | |||
47 | kirkwood_clk_init(); | 58 | kirkwood_clk_init(); |
48 | 59 | ||
49 | /* internal devices that every board has */ | 60 | /* internal devices that every board has */ |
50 | kirkwood_wdt_init(); | ||
51 | kirkwood_xor0_init(); | 61 | kirkwood_xor0_init(); |
52 | kirkwood_xor1_init(); | 62 | kirkwood_xor1_init(); |
53 | kirkwood_crypto_init(); | 63 | kirkwood_crypto_init(); |
@@ -68,7 +78,17 @@ static void __init kirkwood_dt_init(void) | |||
68 | if (of_machine_is_compatible("raidsonic,ib-nas62x0")) | 78 | if (of_machine_is_compatible("raidsonic,ib-nas62x0")) |
69 | ib62x0_init(); | 79 | ib62x0_init(); |
70 | 80 | ||
71 | of_platform_populate(NULL, kirkwood_dt_match_table, NULL, NULL); | 81 | if (of_machine_is_compatible("qnap,ts219")) |
82 | qnap_dt_ts219_init(); | ||
83 | |||
84 | if (of_machine_is_compatible("seagate,goflexnet")) | ||
85 | goflexnet_init(); | ||
86 | |||
87 | if (of_machine_is_compatible("buffalo,lsxl")) | ||
88 | lsxl_init(); | ||
89 | |||
90 | of_platform_populate(NULL, kirkwood_dt_match_table, | ||
91 | kirkwood_auxdata_lookup, NULL); | ||
72 | } | 92 | } |
73 | 93 | ||
74 | static const char *kirkwood_dt_board_compat[] = { | 94 | static const char *kirkwood_dt_board_compat[] = { |
@@ -77,6 +97,9 @@ static const char *kirkwood_dt_board_compat[] = { | |||
77 | "dlink,dns-325", | 97 | "dlink,dns-325", |
78 | "iom,iconnect", | 98 | "iom,iconnect", |
79 | "raidsonic,ib-nas62x0", | 99 | "raidsonic,ib-nas62x0", |
100 | "qnap,ts219", | ||
101 | "seagate,goflexnet", | ||
102 | "buffalo,lsxl", | ||
80 | NULL | 103 | NULL |
81 | }; | 104 | }; |
82 | 105 | ||
@@ -84,7 +107,7 @@ DT_MACHINE_START(KIRKWOOD_DT, "Marvell Kirkwood (Flattened Device Tree)") | |||
84 | /* Maintainer: Jason Cooper <jason@lakedaemon.net> */ | 107 | /* Maintainer: Jason Cooper <jason@lakedaemon.net> */ |
85 | .map_io = kirkwood_map_io, | 108 | .map_io = kirkwood_map_io, |
86 | .init_early = kirkwood_init_early, | 109 | .init_early = kirkwood_init_early, |
87 | .init_irq = kirkwood_init_irq, | 110 | .init_irq = orion_dt_init_irq, |
88 | .timer = &kirkwood_timer, | 111 | .timer = &kirkwood_timer, |
89 | .init_machine = kirkwood_dt_init, | 112 | .init_machine = kirkwood_dt_init, |
90 | .restart = kirkwood_restart, | 113 | .restart = kirkwood_restart, |
diff --git a/arch/arm/mach-kirkwood/board-goflexnet.c b/arch/arm/mach-kirkwood/board-goflexnet.c new file mode 100644 index 000000000000..413e2c8ef5fe --- /dev/null +++ b/arch/arm/mach-kirkwood/board-goflexnet.c | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * Copyright 2012 (C), Jason Cooper <jason@lakedaemon.net> | ||
3 | * | ||
4 | * arch/arm/mach-kirkwood/board-goflexnet.c | ||
5 | * | ||
6 | * Seagate GoFlext Net Board Init for drivers not converted to | ||
7 | * flattened device tree yet. | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | * | ||
13 | * Copied and modified for Seagate GoFlex Net support by | ||
14 | * Joshua Coombs <josh.coombs@gmail.com> based on ArchLinux ARM's | ||
15 | * GoFlex kernel patches. | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | #include <linux/kernel.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/platform_device.h> | ||
22 | #include <linux/ata_platform.h> | ||
23 | #include <linux/mv643xx_eth.h> | ||
24 | #include <linux/of.h> | ||
25 | #include <linux/of_address.h> | ||
26 | #include <linux/of_fdt.h> | ||
27 | #include <linux/of_irq.h> | ||
28 | #include <linux/of_platform.h> | ||
29 | #include <linux/gpio.h> | ||
30 | #include <asm/mach-types.h> | ||
31 | #include <asm/mach/arch.h> | ||
32 | #include <asm/mach/map.h> | ||
33 | #include <mach/kirkwood.h> | ||
34 | #include <mach/bridge-regs.h> | ||
35 | #include <plat/mvsdio.h> | ||
36 | #include "common.h" | ||
37 | #include "mpp.h" | ||
38 | |||
39 | static struct mv643xx_eth_platform_data goflexnet_ge00_data = { | ||
40 | .phy_addr = MV643XX_ETH_PHY_ADDR(0), | ||
41 | }; | ||
42 | |||
43 | static unsigned int goflexnet_mpp_config[] __initdata = { | ||
44 | MPP29_GPIO, /* USB Power Enable */ | ||
45 | MPP47_GPIO, /* LED Orange */ | ||
46 | MPP46_GPIO, /* LED Green */ | ||
47 | MPP45_GPIO, /* LED Left Capacity 3 */ | ||
48 | MPP44_GPIO, /* LED Left Capacity 2 */ | ||
49 | MPP43_GPIO, /* LED Left Capacity 1 */ | ||
50 | MPP42_GPIO, /* LED Left Capacity 0 */ | ||
51 | MPP41_GPIO, /* LED Right Capacity 3 */ | ||
52 | MPP40_GPIO, /* LED Right Capacity 2 */ | ||
53 | MPP39_GPIO, /* LED Right Capacity 1 */ | ||
54 | MPP38_GPIO, /* LED Right Capacity 0 */ | ||
55 | 0 | ||
56 | }; | ||
57 | |||
58 | void __init goflexnet_init(void) | ||
59 | { | ||
60 | /* | ||
61 | * Basic setup. Needs to be called early. | ||
62 | */ | ||
63 | kirkwood_mpp_conf(goflexnet_mpp_config); | ||
64 | |||
65 | if (gpio_request(29, "USB Power Enable") != 0 || | ||
66 | gpio_direction_output(29, 1) != 0) | ||
67 | pr_err("can't setup GPIO 29 (USB Power Enable)\n"); | ||
68 | kirkwood_ehci_init(); | ||
69 | |||
70 | kirkwood_ge00_init(&goflexnet_ge00_data); | ||
71 | } | ||
diff --git a/arch/arm/mach-kirkwood/board-ib62x0.c b/arch/arm/mach-kirkwood/board-ib62x0.c index eddf1df8891f..cfc47f80e734 100644 --- a/arch/arm/mach-kirkwood/board-ib62x0.c +++ b/arch/arm/mach-kirkwood/board-ib62x0.c | |||
@@ -18,9 +18,7 @@ | |||
18 | #include <linux/ata_platform.h> | 18 | #include <linux/ata_platform.h> |
19 | #include <linux/mv643xx_eth.h> | 19 | #include <linux/mv643xx_eth.h> |
20 | #include <linux/gpio.h> | 20 | #include <linux/gpio.h> |
21 | #include <linux/gpio_keys.h> | ||
22 | #include <linux/input.h> | 21 | #include <linux/input.h> |
23 | #include <linux/leds.h> | ||
24 | #include <asm/mach-types.h> | 22 | #include <asm/mach-types.h> |
25 | #include <asm/mach/arch.h> | 23 | #include <asm/mach/arch.h> |
26 | #include <mach/kirkwood.h> | 24 | #include <mach/kirkwood.h> |
@@ -33,10 +31,6 @@ static struct mv643xx_eth_platform_data ib62x0_ge00_data = { | |||
33 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), | 31 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), |
34 | }; | 32 | }; |
35 | 33 | ||
36 | static struct mv_sata_platform_data ib62x0_sata_data = { | ||
37 | .n_ports = 2, | ||
38 | }; | ||
39 | |||
40 | static unsigned int ib62x0_mpp_config[] __initdata = { | 34 | static unsigned int ib62x0_mpp_config[] __initdata = { |
41 | MPP0_NF_IO2, | 35 | MPP0_NF_IO2, |
42 | MPP1_NF_IO3, | 36 | MPP1_NF_IO3, |
@@ -55,69 +49,6 @@ static unsigned int ib62x0_mpp_config[] __initdata = { | |||
55 | 0 | 49 | 0 |
56 | }; | 50 | }; |
57 | 51 | ||
58 | static struct gpio_led ib62x0_led_pins[] = { | ||
59 | { | ||
60 | .name = "ib62x0:green:os", | ||
61 | .default_trigger = "default-on", | ||
62 | .gpio = 25, | ||
63 | .active_low = 0, | ||
64 | }, | ||
65 | { | ||
66 | .name = "ib62x0:red:os", | ||
67 | .default_trigger = "none", | ||
68 | .gpio = 22, | ||
69 | .active_low = 0, | ||
70 | }, | ||
71 | { | ||
72 | .name = "ib62x0:red:usb_copy", | ||
73 | .default_trigger = "none", | ||
74 | .gpio = 27, | ||
75 | .active_low = 0, | ||
76 | }, | ||
77 | }; | ||
78 | |||
79 | static struct gpio_led_platform_data ib62x0_led_data = { | ||
80 | .leds = ib62x0_led_pins, | ||
81 | .num_leds = ARRAY_SIZE(ib62x0_led_pins), | ||
82 | }; | ||
83 | |||
84 | static struct platform_device ib62x0_led_device = { | ||
85 | .name = "leds-gpio", | ||
86 | .id = -1, | ||
87 | .dev = { | ||
88 | .platform_data = &ib62x0_led_data, | ||
89 | } | ||
90 | }; | ||
91 | |||
92 | static struct gpio_keys_button ib62x0_button_pins[] = { | ||
93 | { | ||
94 | .code = KEY_COPY, | ||
95 | .gpio = 29, | ||
96 | .desc = "USB Copy", | ||
97 | .active_low = 1, | ||
98 | }, | ||
99 | { | ||
100 | .code = KEY_RESTART, | ||
101 | .gpio = 28, | ||
102 | .desc = "Reset", | ||
103 | .active_low = 1, | ||
104 | }, | ||
105 | }; | ||
106 | |||
107 | static struct gpio_keys_platform_data ib62x0_button_data = { | ||
108 | .buttons = ib62x0_button_pins, | ||
109 | .nbuttons = ARRAY_SIZE(ib62x0_button_pins), | ||
110 | }; | ||
111 | |||
112 | static struct platform_device ib62x0_button_device = { | ||
113 | .name = "gpio-keys", | ||
114 | .id = -1, | ||
115 | .num_resources = 0, | ||
116 | .dev = { | ||
117 | .platform_data = &ib62x0_button_data, | ||
118 | } | ||
119 | }; | ||
120 | |||
121 | static void ib62x0_power_off(void) | 52 | static void ib62x0_power_off(void) |
122 | { | 53 | { |
123 | gpio_set_value(IB62X0_GPIO_POWER_OFF, 1); | 54 | gpio_set_value(IB62X0_GPIO_POWER_OFF, 1); |
@@ -132,9 +63,6 @@ void __init ib62x0_init(void) | |||
132 | 63 | ||
133 | kirkwood_ehci_init(); | 64 | kirkwood_ehci_init(); |
134 | kirkwood_ge00_init(&ib62x0_ge00_data); | 65 | kirkwood_ge00_init(&ib62x0_ge00_data); |
135 | kirkwood_sata_init(&ib62x0_sata_data); | ||
136 | platform_device_register(&ib62x0_led_device); | ||
137 | platform_device_register(&ib62x0_button_device); | ||
138 | if (gpio_request(IB62X0_GPIO_POWER_OFF, "ib62x0:power:off") == 0 && | 66 | if (gpio_request(IB62X0_GPIO_POWER_OFF, "ib62x0:power:off") == 0 && |
139 | gpio_direction_output(IB62X0_GPIO_POWER_OFF, 0) == 0) | 67 | gpio_direction_output(IB62X0_GPIO_POWER_OFF, 0) == 0) |
140 | pm_power_off = ib62x0_power_off; | 68 | pm_power_off = ib62x0_power_off; |
diff --git a/arch/arm/mach-kirkwood/board-iconnect.c b/arch/arm/mach-kirkwood/board-iconnect.c index b0d3cc49269d..d7a9198ed300 100644 --- a/arch/arm/mach-kirkwood/board-iconnect.c +++ b/arch/arm/mach-kirkwood/board-iconnect.c | |||
@@ -19,8 +19,6 @@ | |||
19 | #include <linux/mtd/partitions.h> | 19 | #include <linux/mtd/partitions.h> |
20 | #include <linux/mv643xx_eth.h> | 20 | #include <linux/mv643xx_eth.h> |
21 | #include <linux/gpio.h> | 21 | #include <linux/gpio.h> |
22 | #include <linux/leds.h> | ||
23 | #include <linux/i2c.h> | ||
24 | #include <linux/input.h> | 22 | #include <linux/input.h> |
25 | #include <linux/gpio_keys.h> | 23 | #include <linux/gpio_keys.h> |
26 | #include <asm/mach/arch.h> | 24 | #include <asm/mach/arch.h> |
@@ -32,50 +30,6 @@ static struct mv643xx_eth_platform_data iconnect_ge00_data = { | |||
32 | .phy_addr = MV643XX_ETH_PHY_ADDR(11), | 30 | .phy_addr = MV643XX_ETH_PHY_ADDR(11), |
33 | }; | 31 | }; |
34 | 32 | ||
35 | static struct gpio_led iconnect_led_pins[] = { | ||
36 | { | ||
37 | .name = "led_level", | ||
38 | .gpio = 41, | ||
39 | .default_trigger = "default-on", | ||
40 | }, { | ||
41 | .name = "power:blue", | ||
42 | .gpio = 42, | ||
43 | .default_trigger = "timer", | ||
44 | }, { | ||
45 | .name = "power:red", | ||
46 | .gpio = 43, | ||
47 | }, { | ||
48 | .name = "usb1:blue", | ||
49 | .gpio = 44, | ||
50 | }, { | ||
51 | .name = "usb2:blue", | ||
52 | .gpio = 45, | ||
53 | }, { | ||
54 | .name = "usb3:blue", | ||
55 | .gpio = 46, | ||
56 | }, { | ||
57 | .name = "usb4:blue", | ||
58 | .gpio = 47, | ||
59 | }, { | ||
60 | .name = "otb:blue", | ||
61 | .gpio = 48, | ||
62 | }, | ||
63 | }; | ||
64 | |||
65 | static struct gpio_led_platform_data iconnect_led_data = { | ||
66 | .leds = iconnect_led_pins, | ||
67 | .num_leds = ARRAY_SIZE(iconnect_led_pins), | ||
68 | .gpio_blink_set = orion_gpio_led_blink_set, | ||
69 | }; | ||
70 | |||
71 | static struct platform_device iconnect_leds = { | ||
72 | .name = "leds-gpio", | ||
73 | .id = -1, | ||
74 | .dev = { | ||
75 | .platform_data = &iconnect_led_data, | ||
76 | } | ||
77 | }; | ||
78 | |||
79 | static unsigned int iconnect_mpp_config[] __initdata = { | 33 | static unsigned int iconnect_mpp_config[] __initdata = { |
80 | MPP12_GPIO, | 34 | MPP12_GPIO, |
81 | MPP35_GPIO, | 35 | MPP35_GPIO, |
@@ -90,12 +44,6 @@ static unsigned int iconnect_mpp_config[] __initdata = { | |||
90 | 0 | 44 | 0 |
91 | }; | 45 | }; |
92 | 46 | ||
93 | static struct i2c_board_info __initdata iconnect_board_info[] = { | ||
94 | { | ||
95 | I2C_BOARD_INFO("lm63", 0x4c), | ||
96 | }, | ||
97 | }; | ||
98 | |||
99 | static struct mtd_partition iconnect_nand_parts[] = { | 47 | static struct mtd_partition iconnect_nand_parts[] = { |
100 | { | 48 | { |
101 | .name = "flash", | 49 | .name = "flash", |
@@ -142,15 +90,11 @@ void __init iconnect_init(void) | |||
142 | { | 90 | { |
143 | kirkwood_mpp_conf(iconnect_mpp_config); | 91 | kirkwood_mpp_conf(iconnect_mpp_config); |
144 | kirkwood_nand_init(ARRAY_AND_SIZE(iconnect_nand_parts), 25); | 92 | kirkwood_nand_init(ARRAY_AND_SIZE(iconnect_nand_parts), 25); |
145 | kirkwood_i2c_init(); | ||
146 | i2c_register_board_info(0, iconnect_board_info, | ||
147 | ARRAY_SIZE(iconnect_board_info)); | ||
148 | 93 | ||
149 | kirkwood_ehci_init(); | 94 | kirkwood_ehci_init(); |
150 | kirkwood_ge00_init(&iconnect_ge00_data); | 95 | kirkwood_ge00_init(&iconnect_ge00_data); |
151 | 96 | ||
152 | platform_device_register(&iconnect_button_device); | 97 | platform_device_register(&iconnect_button_device); |
153 | platform_device_register(&iconnect_leds); | ||
154 | } | 98 | } |
155 | 99 | ||
156 | static int __init iconnect_pci_init(void) | 100 | static int __init iconnect_pci_init(void) |
diff --git a/arch/arm/mach-kirkwood/board-lsxl.c b/arch/arm/mach-kirkwood/board-lsxl.c new file mode 100644 index 000000000000..83d8975592f8 --- /dev/null +++ b/arch/arm/mach-kirkwood/board-lsxl.c | |||
@@ -0,0 +1,135 @@ | |||
1 | /* | ||
2 | * Copyright 2012 (C), Michael Walle <michael@walle.cc> | ||
3 | * | ||
4 | * arch/arm/mach-kirkwood/board-lsxl.c | ||
5 | * | ||
6 | * Buffalo Linkstation LS-XHL and LS-CHLv2 init for drivers not | ||
7 | * converted to flattened device tree yet. | ||
8 | * | ||
9 | * This file is licensed under the terms of the GNU General Public | ||
10 | * License version 2. This program is licensed "as is" without any | ||
11 | * warranty of any kind, whether express or implied. | ||
12 | */ | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/platform_device.h> | ||
17 | #include <linux/mtd/partitions.h> | ||
18 | #include <linux/ata_platform.h> | ||
19 | #include <linux/spi/flash.h> | ||
20 | #include <linux/spi/spi.h> | ||
21 | #include <linux/mv643xx_eth.h> | ||
22 | #include <linux/gpio.h> | ||
23 | #include <linux/gpio-fan.h> | ||
24 | #include <linux/input.h> | ||
25 | #include <asm/mach-types.h> | ||
26 | #include <asm/mach/arch.h> | ||
27 | #include <mach/kirkwood.h> | ||
28 | #include "common.h" | ||
29 | #include "mpp.h" | ||
30 | |||
31 | static struct mv643xx_eth_platform_data lsxl_ge00_data = { | ||
32 | .phy_addr = MV643XX_ETH_PHY_ADDR(0), | ||
33 | }; | ||
34 | |||
35 | static struct mv643xx_eth_platform_data lsxl_ge01_data = { | ||
36 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), | ||
37 | }; | ||
38 | |||
39 | static unsigned int lsxl_mpp_config[] __initdata = { | ||
40 | MPP10_GPO, /* HDD Power Enable */ | ||
41 | MPP11_GPIO, /* USB Vbus Enable */ | ||
42 | MPP18_GPO, /* FAN High Enable# */ | ||
43 | MPP19_GPO, /* FAN Low Enable# */ | ||
44 | MPP36_GPIO, /* Function Blue LED */ | ||
45 | MPP37_GPIO, /* Alarm LED */ | ||
46 | MPP38_GPIO, /* Info LED */ | ||
47 | MPP39_GPIO, /* Power LED */ | ||
48 | MPP40_GPIO, /* Fan Lock */ | ||
49 | MPP41_GPIO, /* Function Button */ | ||
50 | MPP42_GPIO, /* Power Switch */ | ||
51 | MPP43_GPIO, /* Power Auto Switch */ | ||
52 | MPP48_GPIO, /* Function Red LED */ | ||
53 | 0 | ||
54 | }; | ||
55 | |||
56 | #define LSXL_GPIO_FAN_HIGH 18 | ||
57 | #define LSXL_GPIO_FAN_LOW 19 | ||
58 | #define LSXL_GPIO_FAN_LOCK 40 | ||
59 | |||
60 | static struct gpio_fan_alarm lsxl_alarm = { | ||
61 | .gpio = LSXL_GPIO_FAN_LOCK, | ||
62 | }; | ||
63 | |||
64 | static struct gpio_fan_speed lsxl_speeds[] = { | ||
65 | { | ||
66 | .rpm = 0, | ||
67 | .ctrl_val = 3, | ||
68 | }, { | ||
69 | .rpm = 1500, | ||
70 | .ctrl_val = 1, | ||
71 | }, { | ||
72 | .rpm = 3250, | ||
73 | .ctrl_val = 2, | ||
74 | }, { | ||
75 | .rpm = 5000, | ||
76 | .ctrl_val = 0, | ||
77 | } | ||
78 | }; | ||
79 | |||
80 | static int lsxl_gpio_list[] = { | ||
81 | LSXL_GPIO_FAN_HIGH, LSXL_GPIO_FAN_LOW, | ||
82 | }; | ||
83 | |||
84 | static struct gpio_fan_platform_data lsxl_fan_data = { | ||
85 | .num_ctrl = ARRAY_SIZE(lsxl_gpio_list), | ||
86 | .ctrl = lsxl_gpio_list, | ||
87 | .alarm = &lsxl_alarm, | ||
88 | .num_speed = ARRAY_SIZE(lsxl_speeds), | ||
89 | .speed = lsxl_speeds, | ||
90 | }; | ||
91 | |||
92 | static struct platform_device lsxl_fan_device = { | ||
93 | .name = "gpio-fan", | ||
94 | .id = -1, | ||
95 | .num_resources = 0, | ||
96 | .dev = { | ||
97 | .platform_data = &lsxl_fan_data, | ||
98 | }, | ||
99 | }; | ||
100 | |||
101 | /* | ||
102 | * On the LS-XHL/LS-CHLv2, the shutdown process is following: | ||
103 | * - Userland monitors key events until the power switch goes to off position | ||
104 | * - The board reboots | ||
105 | * - U-boot starts and goes into an idle mode waiting for the user | ||
106 | * to move the switch to ON position | ||
107 | * | ||
108 | */ | ||
109 | static void lsxl_power_off(void) | ||
110 | { | ||
111 | kirkwood_restart('h', NULL); | ||
112 | } | ||
113 | |||
114 | #define LSXL_GPIO_HDD_POWER 10 | ||
115 | #define LSXL_GPIO_USB_POWER 11 | ||
116 | |||
117 | void __init lsxl_init(void) | ||
118 | { | ||
119 | /* | ||
120 | * Basic setup. Needs to be called early. | ||
121 | */ | ||
122 | kirkwood_mpp_conf(lsxl_mpp_config); | ||
123 | |||
124 | /* usb and sata power on */ | ||
125 | gpio_set_value(LSXL_GPIO_USB_POWER, 1); | ||
126 | gpio_set_value(LSXL_GPIO_HDD_POWER, 1); | ||
127 | |||
128 | kirkwood_ehci_init(); | ||
129 | kirkwood_ge00_init(&lsxl_ge00_data); | ||
130 | kirkwood_ge01_init(&lsxl_ge01_data); | ||
131 | platform_device_register(&lsxl_fan_device); | ||
132 | |||
133 | /* register power-off method */ | ||
134 | pm_power_off = lsxl_power_off; | ||
135 | } | ||
diff --git a/arch/arm/mach-kirkwood/board-ts219.c b/arch/arm/mach-kirkwood/board-ts219.c new file mode 100644 index 000000000000..1750e68506c1 --- /dev/null +++ b/arch/arm/mach-kirkwood/board-ts219.c | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * | ||
3 | * QNAP TS-11x/TS-21x Turbo NAS Board Setup via DT | ||
4 | * | ||
5 | * Copyright (C) 2012 Andrew Lunn <andrew@lunn.ch> | ||
6 | * | ||
7 | * Based on the board file ts219-setup.c: | ||
8 | * | ||
9 | * Copyright (C) 2009 Martin Michlmayr <tbm@cyrius.com> | ||
10 | * Copyright (C) 2008 Byron Bradley <byron.bbradley@gmail.com> | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version | ||
15 | * 2 of the License, or (at your option) any later version. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/mv643xx_eth.h> | ||
22 | #include <linux/ata_platform.h> | ||
23 | #include <linux/gpio_keys.h> | ||
24 | #include <linux/input.h> | ||
25 | #include <asm/mach-types.h> | ||
26 | #include <asm/mach/arch.h> | ||
27 | #include <mach/kirkwood.h> | ||
28 | #include "common.h" | ||
29 | #include "mpp.h" | ||
30 | #include "tsx1x-common.h" | ||
31 | |||
32 | static struct mv643xx_eth_platform_data qnap_ts219_ge00_data = { | ||
33 | .phy_addr = MV643XX_ETH_PHY_ADDR(8), | ||
34 | }; | ||
35 | |||
36 | static unsigned int qnap_ts219_mpp_config[] __initdata = { | ||
37 | MPP0_SPI_SCn, | ||
38 | MPP1_SPI_MOSI, | ||
39 | MPP2_SPI_SCK, | ||
40 | MPP3_SPI_MISO, | ||
41 | MPP4_SATA1_ACTn, | ||
42 | MPP5_SATA0_ACTn, | ||
43 | MPP8_TW0_SDA, | ||
44 | MPP9_TW0_SCK, | ||
45 | MPP10_UART0_TXD, | ||
46 | MPP11_UART0_RXD, | ||
47 | MPP13_UART1_TXD, /* PIC controller */ | ||
48 | MPP14_UART1_RXD, /* PIC controller */ | ||
49 | MPP15_GPIO, /* USB Copy button (on devices with 88F6281) */ | ||
50 | MPP16_GPIO, /* Reset button (on devices with 88F6281) */ | ||
51 | MPP36_GPIO, /* RAM: 0: 256 MB, 1: 512 MB */ | ||
52 | MPP37_GPIO, /* Reset button (on devices with 88F6282) */ | ||
53 | MPP43_GPIO, /* USB Copy button (on devices with 88F6282) */ | ||
54 | MPP44_GPIO, /* Board ID: 0: TS-11x, 1: TS-21x */ | ||
55 | 0 | ||
56 | }; | ||
57 | |||
58 | void __init qnap_dt_ts219_init(void) | ||
59 | { | ||
60 | u32 dev, rev; | ||
61 | |||
62 | kirkwood_mpp_conf(qnap_ts219_mpp_config); | ||
63 | |||
64 | kirkwood_pcie_id(&dev, &rev); | ||
65 | if (dev == MV88F6282_DEV_ID) | ||
66 | qnap_ts219_ge00_data.phy_addr = MV643XX_ETH_PHY_ADDR(0); | ||
67 | |||
68 | kirkwood_ge00_init(&qnap_ts219_ge00_data); | ||
69 | kirkwood_ehci_init(); | ||
70 | |||
71 | pm_power_off = qnap_tsx1x_power_off; | ||
72 | } | ||
73 | |||
74 | /* FIXME: Will not work with DT. Maybe use MPP40_GPIO? */ | ||
75 | static int __init ts219_pci_init(void) | ||
76 | { | ||
77 | if (machine_is_ts219()) | ||
78 | kirkwood_pcie_init(KW_PCIE0); | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | subsys_initcall(ts219_pci_init); | ||
diff --git a/arch/arm/mach-kirkwood/common.c b/arch/arm/mach-kirkwood/common.c index c9201539ffbd..c4b64adcbfce 100644 --- a/arch/arm/mach-kirkwood/common.c +++ b/arch/arm/mach-kirkwood/common.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/dma-mapping.h> | 17 | #include <linux/dma-mapping.h> |
18 | #include <linux/clk-provider.h> | 18 | #include <linux/clk-provider.h> |
19 | #include <linux/spinlock.h> | 19 | #include <linux/spinlock.h> |
20 | #include <linux/mv643xx_i2c.h> | ||
20 | #include <net/dsa.h> | 21 | #include <net/dsa.h> |
21 | #include <asm/page.h> | 22 | #include <asm/page.h> |
22 | #include <asm/timex.h> | 23 | #include <asm/timex.h> |
@@ -276,6 +277,7 @@ void __init kirkwood_clk_init(void) | |||
276 | orion_clkdev_add("0", "pcie", pex0); | 277 | orion_clkdev_add("0", "pcie", pex0); |
277 | orion_clkdev_add("1", "pcie", pex1); | 278 | orion_clkdev_add("1", "pcie", pex1); |
278 | orion_clkdev_add(NULL, "kirkwood-i2s", audio); | 279 | orion_clkdev_add(NULL, "kirkwood-i2s", audio); |
280 | orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".0", runit); | ||
279 | 281 | ||
280 | /* Marvell says runit is used by SPI, UART, NAND, TWSI, ..., | 282 | /* Marvell says runit is used by SPI, UART, NAND, TWSI, ..., |
281 | * so should never be gated. | 283 | * so should never be gated. |
diff --git a/arch/arm/mach-kirkwood/common.h b/arch/arm/mach-kirkwood/common.h index 9248fa2c165b..304dd1abfdca 100644 --- a/arch/arm/mach-kirkwood/common.h +++ b/arch/arm/mach-kirkwood/common.h | |||
@@ -58,6 +58,11 @@ void dreamplug_init(void); | |||
58 | #else | 58 | #else |
59 | static inline void dreamplug_init(void) {}; | 59 | static inline void dreamplug_init(void) {}; |
60 | #endif | 60 | #endif |
61 | #ifdef CONFIG_MACH_TS219_DT | ||
62 | void qnap_dt_ts219_init(void); | ||
63 | #else | ||
64 | static inline void qnap_dt_ts219_init(void) {}; | ||
65 | #endif | ||
61 | 66 | ||
62 | #ifdef CONFIG_MACH_DLINK_KIRKWOOD_DT | 67 | #ifdef CONFIG_MACH_DLINK_KIRKWOOD_DT |
63 | void dnskw_init(void); | 68 | void dnskw_init(void); |
@@ -77,6 +82,18 @@ void ib62x0_init(void); | |||
77 | static inline void ib62x0_init(void) {}; | 82 | static inline void ib62x0_init(void) {}; |
78 | #endif | 83 | #endif |
79 | 84 | ||
85 | #ifdef CONFIG_MACH_GOFLEXNET_DT | ||
86 | void goflexnet_init(void); | ||
87 | #else | ||
88 | static inline void goflexnet_init(void) {}; | ||
89 | #endif | ||
90 | |||
91 | #ifdef CONFIG_MACH_LSXL_DT | ||
92 | void lsxl_init(void); | ||
93 | #else | ||
94 | static inline void lsxl_init(void) {}; | ||
95 | #endif | ||
96 | |||
80 | /* early init functions not converted to fdt yet */ | 97 | /* early init functions not converted to fdt yet */ |
81 | char *kirkwood_id(void); | 98 | char *kirkwood_id(void); |
82 | void kirkwood_l2_init(void); | 99 | void kirkwood_l2_init(void); |
diff --git a/arch/arm/mach-kirkwood/irq.c b/arch/arm/mach-kirkwood/irq.c index c4c68e5b94f1..720063ffa19d 100644 --- a/arch/arm/mach-kirkwood/irq.c +++ b/arch/arm/mach-kirkwood/irq.c | |||
@@ -9,20 +9,23 @@ | |||
9 | */ | 9 | */ |
10 | #include <linux/gpio.h> | 10 | #include <linux/gpio.h> |
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | ||
13 | #include <linux/irq.h> | 12 | #include <linux/irq.h> |
14 | #include <linux/io.h> | ||
15 | #include <mach/bridge-regs.h> | 13 | #include <mach/bridge-regs.h> |
16 | #include <plat/irq.h> | 14 | #include <plat/irq.h> |
17 | #include "common.h" | ||
18 | 15 | ||
19 | static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | 16 | static int __initdata gpio0_irqs[4] = { |
20 | { | 17 | IRQ_KIRKWOOD_GPIO_LOW_0_7, |
21 | BUG_ON(irq < IRQ_KIRKWOOD_GPIO_LOW_0_7); | 18 | IRQ_KIRKWOOD_GPIO_LOW_8_15, |
22 | BUG_ON(irq > IRQ_KIRKWOOD_GPIO_HIGH_16_23); | 19 | IRQ_KIRKWOOD_GPIO_LOW_16_23, |
20 | IRQ_KIRKWOOD_GPIO_LOW_24_31, | ||
21 | }; | ||
23 | 22 | ||
24 | orion_gpio_irq_handler((irq - IRQ_KIRKWOOD_GPIO_LOW_0_7) << 3); | 23 | static int __initdata gpio1_irqs[4] = { |
25 | } | 24 | IRQ_KIRKWOOD_GPIO_HIGH_0_7, |
25 | IRQ_KIRKWOOD_GPIO_HIGH_8_15, | ||
26 | IRQ_KIRKWOOD_GPIO_HIGH_16_23, | ||
27 | 0, | ||
28 | }; | ||
26 | 29 | ||
27 | void __init kirkwood_init_irq(void) | 30 | void __init kirkwood_init_irq(void) |
28 | { | 31 | { |
@@ -32,17 +35,8 @@ void __init kirkwood_init_irq(void) | |||
32 | /* | 35 | /* |
33 | * Initialize gpiolib for GPIOs 0-49. | 36 | * Initialize gpiolib for GPIOs 0-49. |
34 | */ | 37 | */ |
35 | orion_gpio_init(0, 32, GPIO_LOW_VIRT_BASE, 0, | 38 | orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_LOW_VIRT_BASE, 0, |
36 | IRQ_KIRKWOOD_GPIO_START); | 39 | IRQ_KIRKWOOD_GPIO_START, gpio0_irqs); |
37 | irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_0_7, gpio_irq_handler); | 40 | orion_gpio_init(NULL, 32, 18, (void __iomem *)GPIO_HIGH_VIRT_BASE, 0, |
38 | irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_8_15, gpio_irq_handler); | 41 | IRQ_KIRKWOOD_GPIO_START + 32, gpio1_irqs); |
39 | irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_16_23, gpio_irq_handler); | ||
40 | irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_LOW_24_31, gpio_irq_handler); | ||
41 | |||
42 | orion_gpio_init(32, 18, GPIO_HIGH_VIRT_BASE, 0, | ||
43 | IRQ_KIRKWOOD_GPIO_START + 32); | ||
44 | irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_0_7, gpio_irq_handler); | ||
45 | irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_8_15, gpio_irq_handler); | ||
46 | irq_set_chained_handler(IRQ_KIRKWOOD_GPIO_HIGH_16_23, | ||
47 | gpio_irq_handler); | ||
48 | } | 42 | } |
diff --git a/arch/arm/mach-mmp/gplugd.c b/arch/arm/mach-mmp/gplugd.c index f516e74ce0d5..5c3d61ee729a 100644 --- a/arch/arm/mach-mmp/gplugd.c +++ b/arch/arm/mach-mmp/gplugd.c | |||
@@ -14,6 +14,7 @@ | |||
14 | #include <asm/mach/arch.h> | 14 | #include <asm/mach/arch.h> |
15 | #include <asm/mach-types.h> | 15 | #include <asm/mach-types.h> |
16 | 16 | ||
17 | #include <mach/irqs.h> | ||
17 | #include <mach/pxa168.h> | 18 | #include <mach/pxa168.h> |
18 | #include <mach/mfp-pxa168.h> | 19 | #include <mach/mfp-pxa168.h> |
19 | 20 | ||
diff --git a/arch/arm/mach-mv78xx0/irq.c b/arch/arm/mach-mv78xx0/irq.c index e421b701663b..eff9a750bbe2 100644 --- a/arch/arm/mach-mv78xx0/irq.c +++ b/arch/arm/mach-mv78xx0/irq.c | |||
@@ -9,19 +9,17 @@ | |||
9 | */ | 9 | */ |
10 | #include <linux/gpio.h> | 10 | #include <linux/gpio.h> |
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | ||
13 | #include <linux/pci.h> | ||
14 | #include <linux/irq.h> | 12 | #include <linux/irq.h> |
15 | #include <mach/bridge-regs.h> | 13 | #include <mach/bridge-regs.h> |
16 | #include <plat/irq.h> | 14 | #include <plat/irq.h> |
17 | #include "common.h" | 15 | #include "common.h" |
18 | 16 | ||
19 | static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | 17 | static int __initdata gpio0_irqs[4] = { |
20 | { | 18 | IRQ_MV78XX0_GPIO_0_7, |
21 | BUG_ON(irq < IRQ_MV78XX0_GPIO_0_7 || irq > IRQ_MV78XX0_GPIO_24_31); | 19 | IRQ_MV78XX0_GPIO_8_15, |
22 | 20 | IRQ_MV78XX0_GPIO_16_23, | |
23 | orion_gpio_irq_handler((irq - IRQ_MV78XX0_GPIO_0_7) << 3); | 21 | IRQ_MV78XX0_GPIO_24_31, |
24 | } | 22 | }; |
25 | 23 | ||
26 | void __init mv78xx0_init_irq(void) | 24 | void __init mv78xx0_init_irq(void) |
27 | { | 25 | { |
@@ -34,11 +32,7 @@ void __init mv78xx0_init_irq(void) | |||
34 | * registers for core #1 are at an offset of 0x18 from those of | 32 | * registers for core #1 are at an offset of 0x18 from those of |
35 | * core #0.) | 33 | * core #0.) |
36 | */ | 34 | */ |
37 | orion_gpio_init(0, 32, GPIO_VIRT_BASE, | 35 | orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_VIRT_BASE, |
38 | mv78xx0_core_index() ? 0x18 : 0, | 36 | mv78xx0_core_index() ? 0x18 : 0, |
39 | IRQ_MV78XX0_GPIO_START); | 37 | IRQ_MV78XX0_GPIO_START, gpio0_irqs); |
40 | irq_set_chained_handler(IRQ_MV78XX0_GPIO_0_7, gpio_irq_handler); | ||
41 | irq_set_chained_handler(IRQ_MV78XX0_GPIO_8_15, gpio_irq_handler); | ||
42 | irq_set_chained_handler(IRQ_MV78XX0_GPIO_16_23, gpio_irq_handler); | ||
43 | irq_set_chained_handler(IRQ_MV78XX0_GPIO_24_31, gpio_irq_handler); | ||
44 | } | 38 | } |
diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig index ccdf83b17cf1..9a8bbda195b2 100644 --- a/arch/arm/mach-mxs/Kconfig +++ b/arch/arm/mach-mxs/Kconfig | |||
@@ -2,9 +2,6 @@ if ARCH_MXS | |||
2 | 2 | ||
3 | source "arch/arm/mach-mxs/devices/Kconfig" | 3 | source "arch/arm/mach-mxs/devices/Kconfig" |
4 | 4 | ||
5 | config MXS_OCOTP | ||
6 | bool | ||
7 | |||
8 | config SOC_IMX23 | 5 | config SOC_IMX23 |
9 | bool | 6 | bool |
10 | select ARM_AMBA | 7 | select ARM_AMBA |
@@ -66,7 +63,6 @@ config MACH_MX28EVK | |||
66 | select MXS_HAVE_PLATFORM_MXS_SAIF | 63 | select MXS_HAVE_PLATFORM_MXS_SAIF |
67 | select MXS_HAVE_PLATFORM_MXS_I2C | 64 | select MXS_HAVE_PLATFORM_MXS_I2C |
68 | select MXS_HAVE_PLATFORM_RTC_STMP3XXX | 65 | select MXS_HAVE_PLATFORM_RTC_STMP3XXX |
69 | select MXS_OCOTP | ||
70 | help | 66 | help |
71 | Include support for MX28EVK platform. This includes specific | 67 | Include support for MX28EVK platform. This includes specific |
72 | configurations for the board and its peripherals. | 68 | configurations for the board and its peripherals. |
@@ -94,7 +90,6 @@ config MODULE_M28 | |||
94 | select MXS_HAVE_PLATFORM_MXS_I2C | 90 | select MXS_HAVE_PLATFORM_MXS_I2C |
95 | select MXS_HAVE_PLATFORM_MXS_MMC | 91 | select MXS_HAVE_PLATFORM_MXS_MMC |
96 | select MXS_HAVE_PLATFORM_MXSFB | 92 | select MXS_HAVE_PLATFORM_MXSFB |
97 | select MXS_OCOTP | ||
98 | 93 | ||
99 | config MODULE_APX4 | 94 | config MODULE_APX4 |
100 | bool | 95 | bool |
@@ -106,7 +101,6 @@ config MODULE_APX4 | |||
106 | select MXS_HAVE_PLATFORM_MXS_I2C | 101 | select MXS_HAVE_PLATFORM_MXS_I2C |
107 | select MXS_HAVE_PLATFORM_MXS_MMC | 102 | select MXS_HAVE_PLATFORM_MXS_MMC |
108 | select MXS_HAVE_PLATFORM_MXS_SAIF | 103 | select MXS_HAVE_PLATFORM_MXS_SAIF |
109 | select MXS_OCOTP | ||
110 | 104 | ||
111 | config MACH_TX28 | 105 | config MACH_TX28 |
112 | bool "Ka-Ro TX28 module" | 106 | bool "Ka-Ro TX28 module" |
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile index e41590ccb437..fed3695a1339 100644 --- a/arch/arm/mach-mxs/Makefile +++ b/arch/arm/mach-mxs/Makefile | |||
@@ -1,7 +1,6 @@ | |||
1 | # Common support | 1 | # Common support |
2 | obj-y := devices.o icoll.o iomux.o system.o timer.o mm.o | 2 | obj-y := devices.o icoll.o iomux.o ocotp.o system.o timer.o mm.o |
3 | 3 | ||
4 | obj-$(CONFIG_MXS_OCOTP) += ocotp.o | ||
5 | obj-$(CONFIG_PM) += pm.o | 4 | obj-$(CONFIG_PM) += pm.o |
6 | 5 | ||
7 | obj-$(CONFIG_MACH_MXS_DT) += mach-mxs.o | 6 | obj-$(CONFIG_MACH_MXS_DT) += mach-mxs.o |
diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig index dd0fbf76ac79..dd2db025f778 100644 --- a/arch/arm/mach-omap2/Kconfig +++ b/arch/arm/mach-omap2/Kconfig | |||
@@ -62,6 +62,7 @@ config ARCH_OMAP4 | |||
62 | select PM_OPP if PM | 62 | select PM_OPP if PM |
63 | select USB_ARCH_HAS_EHCI if USB_SUPPORT | 63 | select USB_ARCH_HAS_EHCI if USB_SUPPORT |
64 | select ARM_CPU_SUSPEND if PM | 64 | select ARM_CPU_SUSPEND if PM |
65 | select ARCH_NEEDS_CPU_IDLE_COUPLED | ||
65 | 66 | ||
66 | config SOC_OMAP5 | 67 | config SOC_OMAP5 |
67 | bool "TI OMAP5" | 68 | bool "TI OMAP5" |
diff --git a/arch/arm/mach-omap2/cpuidle44xx.c b/arch/arm/mach-omap2/cpuidle44xx.c index 02d15bbd4e35..ee05e193fc61 100644 --- a/arch/arm/mach-omap2/cpuidle44xx.c +++ b/arch/arm/mach-omap2/cpuidle44xx.c | |||
@@ -21,6 +21,7 @@ | |||
21 | #include "common.h" | 21 | #include "common.h" |
22 | #include "pm.h" | 22 | #include "pm.h" |
23 | #include "prm.h" | 23 | #include "prm.h" |
24 | #include "clockdomain.h" | ||
24 | 25 | ||
25 | /* Machine specific information */ | 26 | /* Machine specific information */ |
26 | struct omap4_idle_statedata { | 27 | struct omap4_idle_statedata { |
@@ -47,10 +48,14 @@ static struct omap4_idle_statedata omap4_idle_data[] = { | |||
47 | }, | 48 | }, |
48 | }; | 49 | }; |
49 | 50 | ||
50 | static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd; | 51 | static struct powerdomain *mpu_pd, *cpu_pd[NR_CPUS]; |
52 | static struct clockdomain *cpu_clkdm[NR_CPUS]; | ||
53 | |||
54 | static atomic_t abort_barrier; | ||
55 | static bool cpu_done[NR_CPUS]; | ||
51 | 56 | ||
52 | /** | 57 | /** |
53 | * omap4_enter_idle - Programs OMAP4 to enter the specified state | 58 | * omap4_enter_idle_coupled_[simple/coupled] - OMAP4 cpuidle entry functions |
54 | * @dev: cpuidle device | 59 | * @dev: cpuidle device |
55 | * @drv: cpuidle driver | 60 | * @drv: cpuidle driver |
56 | * @index: the index of state to be entered | 61 | * @index: the index of state to be entered |
@@ -59,60 +64,84 @@ static struct powerdomain *mpu_pd, *cpu0_pd, *cpu1_pd; | |||
59 | * specified low power state selected by the governor. | 64 | * specified low power state selected by the governor. |
60 | * Returns the amount of time spent in the low power state. | 65 | * Returns the amount of time spent in the low power state. |
61 | */ | 66 | */ |
62 | static int omap4_enter_idle(struct cpuidle_device *dev, | 67 | static int omap4_enter_idle_simple(struct cpuidle_device *dev, |
68 | struct cpuidle_driver *drv, | ||
69 | int index) | ||
70 | { | ||
71 | local_fiq_disable(); | ||
72 | omap_do_wfi(); | ||
73 | local_fiq_enable(); | ||
74 | |||
75 | return index; | ||
76 | } | ||
77 | |||
78 | static int omap4_enter_idle_coupled(struct cpuidle_device *dev, | ||
63 | struct cpuidle_driver *drv, | 79 | struct cpuidle_driver *drv, |
64 | int index) | 80 | int index) |
65 | { | 81 | { |
66 | struct omap4_idle_statedata *cx = &omap4_idle_data[index]; | 82 | struct omap4_idle_statedata *cx = &omap4_idle_data[index]; |
67 | u32 cpu1_state; | ||
68 | int cpu_id = smp_processor_id(); | 83 | int cpu_id = smp_processor_id(); |
69 | 84 | ||
70 | local_fiq_disable(); | 85 | local_fiq_disable(); |
71 | 86 | ||
72 | /* | 87 | /* |
73 | * CPU0 has to stay ON (i.e in C1) until CPU1 is OFF state. | 88 | * CPU0 has to wait and stay ON until CPU1 is OFF state. |
74 | * This is necessary to honour hardware recommondation | 89 | * This is necessary to honour hardware recommondation |
75 | * of triggeing all the possible low power modes once CPU1 is | 90 | * of triggeing all the possible low power modes once CPU1 is |
76 | * out of coherency and in OFF mode. | 91 | * out of coherency and in OFF mode. |
77 | * Update dev->last_state so that governor stats reflects right | ||
78 | * data. | ||
79 | */ | 92 | */ |
80 | cpu1_state = pwrdm_read_pwrst(cpu1_pd); | 93 | if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) { |
81 | if (cpu1_state != PWRDM_POWER_OFF) { | 94 | while (pwrdm_read_pwrst(cpu_pd[1]) != PWRDM_POWER_OFF) { |
82 | index = drv->safe_state_index; | 95 | cpu_relax(); |
83 | cx = &omap4_idle_data[index]; | 96 | |
97 | /* | ||
98 | * CPU1 could have already entered & exited idle | ||
99 | * without hitting off because of a wakeup | ||
100 | * or a failed attempt to hit off mode. Check for | ||
101 | * that here, otherwise we could spin forever | ||
102 | * waiting for CPU1 off. | ||
103 | */ | ||
104 | if (cpu_done[1]) | ||
105 | goto fail; | ||
106 | |||
107 | } | ||
84 | } | 108 | } |
85 | 109 | ||
86 | if (index > 0) | 110 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id); |
87 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ENTER, &cpu_id); | ||
88 | 111 | ||
89 | /* | 112 | /* |
90 | * Call idle CPU PM enter notifier chain so that | 113 | * Call idle CPU PM enter notifier chain so that |
91 | * VFP and per CPU interrupt context is saved. | 114 | * VFP and per CPU interrupt context is saved. |
92 | */ | 115 | */ |
93 | if (cx->cpu_state == PWRDM_POWER_OFF) | 116 | cpu_pm_enter(); |
94 | cpu_pm_enter(); | 117 | |
95 | 118 | if (dev->cpu == 0) { | |
96 | pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); | 119 | pwrdm_set_logic_retst(mpu_pd, cx->mpu_logic_state); |
97 | omap_set_pwrdm_state(mpu_pd, cx->mpu_state); | 120 | omap_set_pwrdm_state(mpu_pd, cx->mpu_state); |
98 | 121 | ||
99 | /* | 122 | /* |
100 | * Call idle CPU cluster PM enter notifier chain | 123 | * Call idle CPU cluster PM enter notifier chain |
101 | * to save GIC and wakeupgen context. | 124 | * to save GIC and wakeupgen context. |
102 | */ | 125 | */ |
103 | if ((cx->mpu_state == PWRDM_POWER_RET) && | 126 | if ((cx->mpu_state == PWRDM_POWER_RET) && |
104 | (cx->mpu_logic_state == PWRDM_POWER_OFF)) | 127 | (cx->mpu_logic_state == PWRDM_POWER_OFF)) |
105 | cpu_cluster_pm_enter(); | 128 | cpu_cluster_pm_enter(); |
129 | } | ||
106 | 130 | ||
107 | omap4_enter_lowpower(dev->cpu, cx->cpu_state); | 131 | omap4_enter_lowpower(dev->cpu, cx->cpu_state); |
132 | cpu_done[dev->cpu] = true; | ||
133 | |||
134 | /* Wakeup CPU1 only if it is not offlined */ | ||
135 | if (dev->cpu == 0 && cpumask_test_cpu(1, cpu_online_mask)) { | ||
136 | clkdm_wakeup(cpu_clkdm[1]); | ||
137 | clkdm_allow_idle(cpu_clkdm[1]); | ||
138 | } | ||
108 | 139 | ||
109 | /* | 140 | /* |
110 | * Call idle CPU PM exit notifier chain to restore | 141 | * Call idle CPU PM exit notifier chain to restore |
111 | * VFP and per CPU IRQ context. Only CPU0 state is | 142 | * VFP and per CPU IRQ context. |
112 | * considered since CPU1 is managed by CPU hotplug. | ||
113 | */ | 143 | */ |
114 | if (pwrdm_read_prev_pwrst(cpu0_pd) == PWRDM_POWER_OFF) | 144 | cpu_pm_exit(); |
115 | cpu_pm_exit(); | ||
116 | 145 | ||
117 | /* | 146 | /* |
118 | * Call idle CPU cluster PM exit notifier chain | 147 | * Call idle CPU cluster PM exit notifier chain |
@@ -121,8 +150,11 @@ static int omap4_enter_idle(struct cpuidle_device *dev, | |||
121 | if (omap4_mpuss_read_prev_context_state()) | 150 | if (omap4_mpuss_read_prev_context_state()) |
122 | cpu_cluster_pm_exit(); | 151 | cpu_cluster_pm_exit(); |
123 | 152 | ||
124 | if (index > 0) | 153 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); |
125 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_EXIT, &cpu_id); | 154 | |
155 | fail: | ||
156 | cpuidle_coupled_parallel_barrier(dev, &abort_barrier); | ||
157 | cpu_done[dev->cpu] = false; | ||
126 | 158 | ||
127 | local_fiq_enable(); | 159 | local_fiq_enable(); |
128 | 160 | ||
@@ -141,7 +173,7 @@ struct cpuidle_driver omap4_idle_driver = { | |||
141 | .exit_latency = 2 + 2, | 173 | .exit_latency = 2 + 2, |
142 | .target_residency = 5, | 174 | .target_residency = 5, |
143 | .flags = CPUIDLE_FLAG_TIME_VALID, | 175 | .flags = CPUIDLE_FLAG_TIME_VALID, |
144 | .enter = omap4_enter_idle, | 176 | .enter = omap4_enter_idle_simple, |
145 | .name = "C1", | 177 | .name = "C1", |
146 | .desc = "MPUSS ON" | 178 | .desc = "MPUSS ON" |
147 | }, | 179 | }, |
@@ -149,8 +181,8 @@ struct cpuidle_driver omap4_idle_driver = { | |||
149 | /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ | 181 | /* C2 - CPU0 OFF + CPU1 OFF + MPU CSWR */ |
150 | .exit_latency = 328 + 440, | 182 | .exit_latency = 328 + 440, |
151 | .target_residency = 960, | 183 | .target_residency = 960, |
152 | .flags = CPUIDLE_FLAG_TIME_VALID, | 184 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, |
153 | .enter = omap4_enter_idle, | 185 | .enter = omap4_enter_idle_coupled, |
154 | .name = "C2", | 186 | .name = "C2", |
155 | .desc = "MPUSS CSWR", | 187 | .desc = "MPUSS CSWR", |
156 | }, | 188 | }, |
@@ -158,8 +190,8 @@ struct cpuidle_driver omap4_idle_driver = { | |||
158 | /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ | 190 | /* C3 - CPU0 OFF + CPU1 OFF + MPU OSWR */ |
159 | .exit_latency = 460 + 518, | 191 | .exit_latency = 460 + 518, |
160 | .target_residency = 1100, | 192 | .target_residency = 1100, |
161 | .flags = CPUIDLE_FLAG_TIME_VALID, | 193 | .flags = CPUIDLE_FLAG_TIME_VALID | CPUIDLE_FLAG_COUPLED, |
162 | .enter = omap4_enter_idle, | 194 | .enter = omap4_enter_idle_coupled, |
163 | .name = "C3", | 195 | .name = "C3", |
164 | .desc = "MPUSS OSWR", | 196 | .desc = "MPUSS OSWR", |
165 | }, | 197 | }, |
@@ -168,6 +200,16 @@ struct cpuidle_driver omap4_idle_driver = { | |||
168 | .safe_state_index = 0, | 200 | .safe_state_index = 0, |
169 | }; | 201 | }; |
170 | 202 | ||
203 | /* | ||
204 | * For each cpu, setup the broadcast timer because local timers | ||
205 | * stops for the states above C1. | ||
206 | */ | ||
207 | static void omap_setup_broadcast_timer(void *arg) | ||
208 | { | ||
209 | int cpu = smp_processor_id(); | ||
210 | clockevents_notify(CLOCK_EVT_NOTIFY_BROADCAST_ON, &cpu); | ||
211 | } | ||
212 | |||
171 | /** | 213 | /** |
172 | * omap4_idle_init - Init routine for OMAP4 idle | 214 | * omap4_idle_init - Init routine for OMAP4 idle |
173 | * | 215 | * |
@@ -180,19 +222,30 @@ int __init omap4_idle_init(void) | |||
180 | unsigned int cpu_id = 0; | 222 | unsigned int cpu_id = 0; |
181 | 223 | ||
182 | mpu_pd = pwrdm_lookup("mpu_pwrdm"); | 224 | mpu_pd = pwrdm_lookup("mpu_pwrdm"); |
183 | cpu0_pd = pwrdm_lookup("cpu0_pwrdm"); | 225 | cpu_pd[0] = pwrdm_lookup("cpu0_pwrdm"); |
184 | cpu1_pd = pwrdm_lookup("cpu1_pwrdm"); | 226 | cpu_pd[1] = pwrdm_lookup("cpu1_pwrdm"); |
185 | if ((!mpu_pd) || (!cpu0_pd) || (!cpu1_pd)) | 227 | if ((!mpu_pd) || (!cpu_pd[0]) || (!cpu_pd[1])) |
186 | return -ENODEV; | 228 | return -ENODEV; |
187 | 229 | ||
188 | dev = &per_cpu(omap4_idle_dev, cpu_id); | 230 | cpu_clkdm[0] = clkdm_lookup("mpu0_clkdm"); |
189 | dev->cpu = cpu_id; | 231 | cpu_clkdm[1] = clkdm_lookup("mpu1_clkdm"); |
232 | if (!cpu_clkdm[0] || !cpu_clkdm[1]) | ||
233 | return -ENODEV; | ||
234 | |||
235 | /* Configure the broadcast timer on each cpu */ | ||
236 | on_each_cpu(omap_setup_broadcast_timer, NULL, 1); | ||
237 | |||
238 | for_each_cpu(cpu_id, cpu_online_mask) { | ||
239 | dev = &per_cpu(omap4_idle_dev, cpu_id); | ||
240 | dev->cpu = cpu_id; | ||
241 | dev->coupled_cpus = *cpu_online_mask; | ||
190 | 242 | ||
191 | cpuidle_register_driver(&omap4_idle_driver); | 243 | cpuidle_register_driver(&omap4_idle_driver); |
192 | 244 | ||
193 | if (cpuidle_register_device(dev)) { | 245 | if (cpuidle_register_device(dev)) { |
194 | pr_err("%s: CPUidle register device failed\n", __func__); | 246 | pr_err("%s: CPUidle register failed\n", __func__); |
195 | return -EIO; | 247 | return -EIO; |
248 | } | ||
196 | } | 249 | } |
197 | 250 | ||
198 | return 0; | 251 | return 0; |
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 13d20c8a283d..2ff6d41ec6c6 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c | |||
@@ -130,6 +130,7 @@ static struct clock_event_device clockevent_gpt = { | |||
130 | .name = "gp_timer", | 130 | .name = "gp_timer", |
131 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, | 131 | .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT, |
132 | .shift = 32, | 132 | .shift = 32, |
133 | .rating = 300, | ||
133 | .set_next_event = omap2_gp_timer_set_next_event, | 134 | .set_next_event = omap2_gp_timer_set_next_event, |
134 | .set_mode = omap2_gp_timer_set_mode, | 135 | .set_mode = omap2_gp_timer_set_mode, |
135 | }; | 136 | }; |
@@ -223,7 +224,8 @@ static void __init omap2_gp_clockevent_init(int gptimer_id, | |||
223 | clockevent_delta2ns(3, &clockevent_gpt); | 224 | clockevent_delta2ns(3, &clockevent_gpt); |
224 | /* Timer internal resynch latency. */ | 225 | /* Timer internal resynch latency. */ |
225 | 226 | ||
226 | clockevent_gpt.cpumask = cpumask_of(0); | 227 | clockevent_gpt.cpumask = cpu_possible_mask; |
228 | clockevent_gpt.irq = omap_dm_timer_get_irq(&clkev); | ||
227 | clockevents_register_device(&clockevent_gpt); | 229 | clockevents_register_device(&clockevent_gpt); |
228 | 230 | ||
229 | pr_info("OMAP clockevent source: GPTIMER%d at %lu Hz\n", | 231 | pr_info("OMAP clockevent source: GPTIMER%d at %lu Hz\n", |
diff --git a/arch/arm/mach-orion5x/irq.c b/arch/arm/mach-orion5x/irq.c index b1b45fff776e..17da7091d310 100644 --- a/arch/arm/mach-orion5x/irq.c +++ b/arch/arm/mach-orion5x/irq.c | |||
@@ -11,19 +11,16 @@ | |||
11 | */ | 11 | */ |
12 | #include <linux/gpio.h> | 12 | #include <linux/gpio.h> |
13 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
14 | #include <linux/init.h> | ||
15 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
16 | #include <linux/io.h> | ||
17 | #include <mach/bridge-regs.h> | 15 | #include <mach/bridge-regs.h> |
18 | #include <plat/irq.h> | 16 | #include <plat/irq.h> |
19 | #include "common.h" | ||
20 | 17 | ||
21 | static void gpio_irq_handler(unsigned int irq, struct irq_desc *desc) | 18 | static int __initdata gpio0_irqs[4] = { |
22 | { | 19 | IRQ_ORION5X_GPIO_0_7, |
23 | BUG_ON(irq < IRQ_ORION5X_GPIO_0_7 || irq > IRQ_ORION5X_GPIO_24_31); | 20 | IRQ_ORION5X_GPIO_8_15, |
24 | 21 | IRQ_ORION5X_GPIO_16_23, | |
25 | orion_gpio_irq_handler((irq - IRQ_ORION5X_GPIO_0_7) << 3); | 22 | IRQ_ORION5X_GPIO_24_31, |
26 | } | 23 | }; |
27 | 24 | ||
28 | void __init orion5x_init_irq(void) | 25 | void __init orion5x_init_irq(void) |
29 | { | 26 | { |
@@ -32,9 +29,6 @@ void __init orion5x_init_irq(void) | |||
32 | /* | 29 | /* |
33 | * Initialize gpiolib for GPIOs 0-31. | 30 | * Initialize gpiolib for GPIOs 0-31. |
34 | */ | 31 | */ |
35 | orion_gpio_init(0, 32, GPIO_VIRT_BASE, 0, IRQ_ORION5X_GPIO_START); | 32 | orion_gpio_init(NULL, 0, 32, (void __iomem *)GPIO_VIRT_BASE, 0, |
36 | irq_set_chained_handler(IRQ_ORION5X_GPIO_0_7, gpio_irq_handler); | 33 | IRQ_ORION5X_GPIO_START, gpio0_irqs); |
37 | irq_set_chained_handler(IRQ_ORION5X_GPIO_8_15, gpio_irq_handler); | ||
38 | irq_set_chained_handler(IRQ_ORION5X_GPIO_16_23, gpio_irq_handler); | ||
39 | irq_set_chained_handler(IRQ_ORION5X_GPIO_24_31, gpio_irq_handler); | ||
40 | } | 34 | } |
diff --git a/arch/arm/mach-prima2/timer.c b/arch/arm/mach-prima2/timer.c index 0d024b1e916d..f224107de7bc 100644 --- a/arch/arm/mach-prima2/timer.c +++ b/arch/arm/mach-prima2/timer.c | |||
@@ -132,11 +132,11 @@ static void sirfsoc_clocksource_resume(struct clocksource *cs) | |||
132 | { | 132 | { |
133 | int i; | 133 | int i; |
134 | 134 | ||
135 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++) | 135 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT - 2; i++) |
136 | writel_relaxed(sirfsoc_timer_reg_val[i], sirfsoc_timer_base + sirfsoc_timer_reg_list[i]); | 136 | writel_relaxed(sirfsoc_timer_reg_val[i], sirfsoc_timer_base + sirfsoc_timer_reg_list[i]); |
137 | 137 | ||
138 | writel_relaxed(sirfsoc_timer_reg_val[i - 2], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); | 138 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 2], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); |
139 | writel_relaxed(sirfsoc_timer_reg_val[i - 1], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); | 139 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 1], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); |
140 | } | 140 | } |
141 | 141 | ||
142 | static struct clock_event_device sirfsoc_clockevent = { | 142 | static struct clock_event_device sirfsoc_clockevent = { |
diff --git a/arch/arm/mach-pxa/raumfeld.c b/arch/arm/mach-pxa/raumfeld.c index 5905ed130e94..d89d87ae144c 100644 --- a/arch/arm/mach-pxa/raumfeld.c +++ b/arch/arm/mach-pxa/raumfeld.c | |||
@@ -953,12 +953,12 @@ static struct i2c_board_info raumfeld_connector_i2c_board_info __initdata = { | |||
953 | 953 | ||
954 | static struct eeti_ts_platform_data eeti_ts_pdata = { | 954 | static struct eeti_ts_platform_data eeti_ts_pdata = { |
955 | .irq_active_high = 1, | 955 | .irq_active_high = 1, |
956 | .irq_gpio = GPIO_TOUCH_IRQ, | ||
956 | }; | 957 | }; |
957 | 958 | ||
958 | static struct i2c_board_info raumfeld_controller_i2c_board_info __initdata = { | 959 | static struct i2c_board_info raumfeld_controller_i2c_board_info __initdata = { |
959 | .type = "eeti_ts", | 960 | .type = "eeti_ts", |
960 | .addr = 0x0a, | 961 | .addr = 0x0a, |
961 | .irq = PXA_GPIO_TO_IRQ(GPIO_TOUCH_IRQ), | ||
962 | .platform_data = &eeti_ts_pdata, | 962 | .platform_data = &eeti_ts_pdata, |
963 | }; | 963 | }; |
964 | 964 | ||
diff --git a/arch/arm/mach-s3c24xx/Kconfig b/arch/arm/mach-s3c24xx/Kconfig index e24961109b70..d56b0f7f2b20 100644 --- a/arch/arm/mach-s3c24xx/Kconfig +++ b/arch/arm/mach-s3c24xx/Kconfig | |||
@@ -483,7 +483,7 @@ config MACH_NEO1973_GTA02 | |||
483 | select I2C | 483 | select I2C |
484 | select POWER_SUPPLY | 484 | select POWER_SUPPLY |
485 | select MACH_NEO1973 | 485 | select MACH_NEO1973 |
486 | select S3C2410_PWM | 486 | select S3C24XX_PWM |
487 | select S3C_DEV_USB_HOST | 487 | select S3C_DEV_USB_HOST |
488 | help | 488 | help |
489 | Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone | 489 | Say Y here if you are using the Openmoko GTA02 / Freerunner GSM Phone |
@@ -493,7 +493,7 @@ config MACH_RX1950 | |||
493 | select S3C24XX_DCLK | 493 | select S3C24XX_DCLK |
494 | select PM_H1940 if PM | 494 | select PM_H1940 if PM |
495 | select I2C | 495 | select I2C |
496 | select S3C2410_PWM | 496 | select S3C24XX_PWM |
497 | select S3C_DEV_NAND | 497 | select S3C_DEV_NAND |
498 | select S3C2410_IOTIMING if S3C2440_CPUFREQ | 498 | select S3C2410_IOTIMING if S3C2440_CPUFREQ |
499 | select S3C2440_XTAL_16934400 | 499 | select S3C2440_XTAL_16934400 |
diff --git a/arch/arm/mach-sa1100/leds-hackkit.c b/arch/arm/mach-sa1100/leds-hackkit.c index 6a2352436e62..f8e47235babe 100644 --- a/arch/arm/mach-sa1100/leds-hackkit.c +++ b/arch/arm/mach-sa1100/leds-hackkit.c | |||
@@ -10,6 +10,7 @@ | |||
10 | * as cpu led, the green one is used as timer led. | 10 | * as cpu led, the green one is used as timer led. |
11 | */ | 11 | */ |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/io.h> | ||
13 | 14 | ||
14 | #include <mach/hardware.h> | 15 | #include <mach/hardware.h> |
15 | #include <asm/leds.h> | 16 | #include <asm/leds.h> |
diff --git a/arch/arm/mach-tegra/board-harmony-power.c b/arch/arm/mach-tegra/board-harmony-power.c index 8fd387bf31f0..b7344beec102 100644 --- a/arch/arm/mach-tegra/board-harmony-power.c +++ b/arch/arm/mach-tegra/board-harmony-power.c | |||
@@ -51,7 +51,7 @@ static struct regulator_init_data ldo0_data = { | |||
51 | .consumer_supplies = tps658621_ldo0_supply, | 51 | .consumer_supplies = tps658621_ldo0_supply, |
52 | }; | 52 | }; |
53 | 53 | ||
54 | #define HARMONY_REGULATOR_INIT(_id, _name, _supply, _minmv, _maxmv) \ | 54 | #define HARMONY_REGULATOR_INIT(_id, _name, _supply, _minmv, _maxmv, _on)\ |
55 | static struct regulator_init_data _id##_data = { \ | 55 | static struct regulator_init_data _id##_data = { \ |
56 | .supply_regulator = _supply, \ | 56 | .supply_regulator = _supply, \ |
57 | .constraints = { \ | 57 | .constraints = { \ |
@@ -63,21 +63,22 @@ static struct regulator_init_data ldo0_data = { | |||
63 | .valid_ops_mask = (REGULATOR_CHANGE_MODE | \ | 63 | .valid_ops_mask = (REGULATOR_CHANGE_MODE | \ |
64 | REGULATOR_CHANGE_STATUS | \ | 64 | REGULATOR_CHANGE_STATUS | \ |
65 | REGULATOR_CHANGE_VOLTAGE), \ | 65 | REGULATOR_CHANGE_VOLTAGE), \ |
66 | .always_on = _on, \ | ||
66 | }, \ | 67 | }, \ |
67 | } | 68 | } |
68 | 69 | ||
69 | HARMONY_REGULATOR_INIT(sm0, "vdd_sm0", "vdd_sys", 725, 1500); | 70 | HARMONY_REGULATOR_INIT(sm0, "vdd_sm0", "vdd_sys", 725, 1500, 1); |
70 | HARMONY_REGULATOR_INIT(sm1, "vdd_sm1", "vdd_sys", 725, 1500); | 71 | HARMONY_REGULATOR_INIT(sm1, "vdd_sm1", "vdd_sys", 725, 1500, 1); |
71 | HARMONY_REGULATOR_INIT(sm2, "vdd_sm2", "vdd_sys", 3000, 4550); | 72 | HARMONY_REGULATOR_INIT(sm2, "vdd_sm2", "vdd_sys", 3000, 4550, 1); |
72 | HARMONY_REGULATOR_INIT(ldo1, "vdd_ldo1", "vdd_sm2", 725, 1500); | 73 | HARMONY_REGULATOR_INIT(ldo1, "vdd_ldo1", "vdd_sm2", 725, 1500, 1); |
73 | HARMONY_REGULATOR_INIT(ldo2, "vdd_ldo2", "vdd_sm2", 725, 1500); | 74 | HARMONY_REGULATOR_INIT(ldo2, "vdd_ldo2", "vdd_sm2", 725, 1500, 0); |
74 | HARMONY_REGULATOR_INIT(ldo3, "vdd_ldo3", "vdd_sm2", 1250, 3300); | 75 | HARMONY_REGULATOR_INIT(ldo3, "vdd_ldo3", "vdd_sm2", 1250, 3300, 1); |
75 | HARMONY_REGULATOR_INIT(ldo4, "vdd_ldo4", "vdd_sm2", 1700, 2475); | 76 | HARMONY_REGULATOR_INIT(ldo4, "vdd_ldo4", "vdd_sm2", 1700, 2475, 1); |
76 | HARMONY_REGULATOR_INIT(ldo5, "vdd_ldo5", NULL, 1250, 3300); | 77 | HARMONY_REGULATOR_INIT(ldo5, "vdd_ldo5", NULL, 1250, 3300, 1); |
77 | HARMONY_REGULATOR_INIT(ldo6, "vdd_ldo6", "vdd_sm2", 1250, 3300); | 78 | HARMONY_REGULATOR_INIT(ldo6, "vdd_ldo6", "vdd_sm2", 1250, 3300, 0); |
78 | HARMONY_REGULATOR_INIT(ldo7, "vdd_ldo7", "vdd_sm2", 1250, 3300); | 79 | HARMONY_REGULATOR_INIT(ldo7, "vdd_ldo7", "vdd_sm2", 1250, 3300, 0); |
79 | HARMONY_REGULATOR_INIT(ldo8, "vdd_ldo8", "vdd_sm2", 1250, 3300); | 80 | HARMONY_REGULATOR_INIT(ldo8, "vdd_ldo8", "vdd_sm2", 1250, 3300, 0); |
80 | HARMONY_REGULATOR_INIT(ldo9, "vdd_ldo9", "vdd_sm2", 1250, 3300); | 81 | HARMONY_REGULATOR_INIT(ldo9, "vdd_ldo9", "vdd_sm2", 1250, 3300, 1); |
81 | 82 | ||
82 | #define TPS_REG(_id, _data) \ | 83 | #define TPS_REG(_id, _data) \ |
83 | { \ | 84 | { \ |
@@ -119,9 +120,10 @@ static struct i2c_board_info __initdata harmony_regulators[] = { | |||
119 | 120 | ||
120 | int __init harmony_regulator_init(void) | 121 | int __init harmony_regulator_init(void) |
121 | { | 122 | { |
123 | regulator_register_always_on(0, "vdd_sys", | ||
124 | NULL, 0, 5000000); | ||
125 | |||
122 | if (machine_is_harmony()) { | 126 | if (machine_is_harmony()) { |
123 | regulator_register_always_on(0, "vdd_sys", | ||
124 | NULL, 0, 5000000); | ||
125 | i2c_register_board_info(3, harmony_regulators, 1); | 127 | i2c_register_board_info(3, harmony_regulators, 1); |
126 | } else { /* Harmony, booted using device tree */ | 128 | } else { /* Harmony, booted using device tree */ |
127 | struct device_node *np; | 129 | struct device_node *np; |
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c index c2cdf6500f75..4e7d1182e8a3 100644 --- a/arch/arm/mm/dma-mapping.c +++ b/arch/arm/mm/dma-mapping.c | |||
@@ -358,7 +358,7 @@ void __init dma_contiguous_remap(void) | |||
358 | if (end > arm_lowmem_limit) | 358 | if (end > arm_lowmem_limit) |
359 | end = arm_lowmem_limit; | 359 | end = arm_lowmem_limit; |
360 | if (start >= end) | 360 | if (start >= end) |
361 | return; | 361 | continue; |
362 | 362 | ||
363 | map.pfn = __phys_to_pfn(start); | 363 | map.pfn = __phys_to_pfn(start); |
364 | map.virtual = __phys_to_virt(start); | 364 | map.virtual = __phys_to_virt(start); |
@@ -423,7 +423,7 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page) | |||
423 | unsigned int pageno; | 423 | unsigned int pageno; |
424 | unsigned long flags; | 424 | unsigned long flags; |
425 | void *ptr = NULL; | 425 | void *ptr = NULL; |
426 | size_t align; | 426 | unsigned long align_mask; |
427 | 427 | ||
428 | if (!pool->vaddr) { | 428 | if (!pool->vaddr) { |
429 | WARN(1, "coherent pool not initialised!\n"); | 429 | WARN(1, "coherent pool not initialised!\n"); |
@@ -435,11 +435,11 @@ static void *__alloc_from_pool(size_t size, struct page **ret_page) | |||
435 | * small, so align them to their order in pages, minimum is a page | 435 | * small, so align them to their order in pages, minimum is a page |
436 | * size. This helps reduce fragmentation of the DMA space. | 436 | * size. This helps reduce fragmentation of the DMA space. |
437 | */ | 437 | */ |
438 | align = PAGE_SIZE << get_order(size); | 438 | align_mask = (1 << get_order(size)) - 1; |
439 | 439 | ||
440 | spin_lock_irqsave(&pool->lock, flags); | 440 | spin_lock_irqsave(&pool->lock, flags); |
441 | pageno = bitmap_find_next_zero_area(pool->bitmap, pool->nr_pages, | 441 | pageno = bitmap_find_next_zero_area(pool->bitmap, pool->nr_pages, |
442 | 0, count, (1 << align) - 1); | 442 | 0, count, align_mask); |
443 | if (pageno < pool->nr_pages) { | 443 | if (pageno < pool->nr_pages) { |
444 | bitmap_set(pool->bitmap, pageno, count); | 444 | bitmap_set(pool->bitmap, pageno, count); |
445 | ptr = pool->vaddr + PAGE_SIZE * pageno; | 445 | ptr = pool->vaddr + PAGE_SIZE * pageno; |
@@ -648,12 +648,12 @@ void arm_dma_free(struct device *dev, size_t size, void *cpu_addr, | |||
648 | 648 | ||
649 | if (arch_is_coherent() || nommu()) { | 649 | if (arch_is_coherent() || nommu()) { |
650 | __dma_free_buffer(page, size); | 650 | __dma_free_buffer(page, size); |
651 | } else if (__free_from_pool(cpu_addr, size)) { | ||
652 | return; | ||
651 | } else if (!IS_ENABLED(CONFIG_CMA)) { | 653 | } else if (!IS_ENABLED(CONFIG_CMA)) { |
652 | __dma_free_remap(cpu_addr, size); | 654 | __dma_free_remap(cpu_addr, size); |
653 | __dma_free_buffer(page, size); | 655 | __dma_free_buffer(page, size); |
654 | } else { | 656 | } else { |
655 | if (__free_from_pool(cpu_addr, size)) | ||
656 | return; | ||
657 | /* | 657 | /* |
658 | * Non-atomic allocations cannot be freed with IRQs disabled | 658 | * Non-atomic allocations cannot be freed with IRQs disabled |
659 | */ | 659 | */ |
diff --git a/arch/arm/mm/flush.c b/arch/arm/mm/flush.c index 77458548e031..40ca11ed6e5f 100644 --- a/arch/arm/mm/flush.c +++ b/arch/arm/mm/flush.c | |||
@@ -231,8 +231,6 @@ void __sync_icache_dcache(pte_t pteval) | |||
231 | struct page *page; | 231 | struct page *page; |
232 | struct address_space *mapping; | 232 | struct address_space *mapping; |
233 | 233 | ||
234 | if (!pte_present_user(pteval)) | ||
235 | return; | ||
236 | if (cache_is_vipt_nonaliasing() && !pte_exec(pteval)) | 234 | if (cache_is_vipt_nonaliasing() && !pte_exec(pteval)) |
237 | /* only flush non-aliasing VIPT caches for exec mappings */ | 235 | /* only flush non-aliasing VIPT caches for exec mappings */ |
238 | return; | 236 | return; |
diff --git a/arch/arm/mm/tlb-v7.S b/arch/arm/mm/tlb-v7.S index c2021139cb56..ea94765acf9a 100644 --- a/arch/arm/mm/tlb-v7.S +++ b/arch/arm/mm/tlb-v7.S | |||
@@ -38,10 +38,10 @@ ENTRY(v7wbi_flush_user_tlb_range) | |||
38 | dsb | 38 | dsb |
39 | mov r0, r0, lsr #PAGE_SHIFT @ align address | 39 | mov r0, r0, lsr #PAGE_SHIFT @ align address |
40 | mov r1, r1, lsr #PAGE_SHIFT | 40 | mov r1, r1, lsr #PAGE_SHIFT |
41 | #ifdef CONFIG_ARM_ERRATA_720789 | ||
42 | mov r3, #0 | ||
43 | #else | ||
44 | asid r3, r3 @ mask ASID | 41 | asid r3, r3 @ mask ASID |
42 | #ifdef CONFIG_ARM_ERRATA_720789 | ||
43 | ALT_SMP(W(mov) r3, #0 ) | ||
44 | ALT_UP(W(nop) ) | ||
45 | #endif | 45 | #endif |
46 | orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA | 46 | orr r0, r3, r0, lsl #PAGE_SHIFT @ Create initial MVA |
47 | mov r1, r1, lsl #PAGE_SHIFT | 47 | mov r1, r1, lsl #PAGE_SHIFT |
diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c index c2193178210b..3ed1adbc09f8 100644 --- a/arch/arm/plat-mxc/tzic.c +++ b/arch/arm/plat-mxc/tzic.c | |||
@@ -23,6 +23,7 @@ | |||
23 | 23 | ||
24 | #include <mach/hardware.h> | 24 | #include <mach/hardware.h> |
25 | #include <mach/common.h> | 25 | #include <mach/common.h> |
26 | #include <mach/irqs.h> | ||
26 | 27 | ||
27 | #include "irq-common.h" | 28 | #include "irq-common.h" |
28 | 29 | ||
diff --git a/arch/arm/plat-orion/common.c b/arch/arm/plat-orion/common.c index c1793786aea9..d245a87dc014 100644 --- a/arch/arm/plat-orion/common.c +++ b/arch/arm/plat-orion/common.c | |||
@@ -47,6 +47,7 @@ void __init orion_clkdev_init(struct clk *tclk) | |||
47 | orion_clkdev_add(NULL, MV643XX_ETH_NAME ".2", tclk); | 47 | orion_clkdev_add(NULL, MV643XX_ETH_NAME ".2", tclk); |
48 | orion_clkdev_add(NULL, MV643XX_ETH_NAME ".3", tclk); | 48 | orion_clkdev_add(NULL, MV643XX_ETH_NAME ".3", tclk); |
49 | orion_clkdev_add(NULL, "orion_wdt", tclk); | 49 | orion_clkdev_add(NULL, "orion_wdt", tclk); |
50 | orion_clkdev_add(NULL, MV64XXX_I2C_CTLR_NAME ".0", tclk); | ||
50 | } | 51 | } |
51 | 52 | ||
52 | /* Fill in the resources structure and link it into the platform | 53 | /* Fill in the resources structure and link it into the platform |
diff --git a/arch/arm/plat-orion/gpio.c b/arch/arm/plat-orion/gpio.c index af95af257301..dfda74fae6f2 100644 --- a/arch/arm/plat-orion/gpio.c +++ b/arch/arm/plat-orion/gpio.c | |||
@@ -8,15 +8,22 @@ | |||
8 | * warranty of any kind, whether express or implied. | 8 | * warranty of any kind, whether express or implied. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define DEBUG | ||
12 | |||
11 | #include <linux/kernel.h> | 13 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | 14 | #include <linux/init.h> |
13 | #include <linux/irq.h> | 15 | #include <linux/irq.h> |
16 | #include <linux/irqdomain.h> | ||
14 | #include <linux/module.h> | 17 | #include <linux/module.h> |
15 | #include <linux/spinlock.h> | 18 | #include <linux/spinlock.h> |
16 | #include <linux/bitops.h> | 19 | #include <linux/bitops.h> |
17 | #include <linux/io.h> | 20 | #include <linux/io.h> |
18 | #include <linux/gpio.h> | 21 | #include <linux/gpio.h> |
19 | #include <linux/leds.h> | 22 | #include <linux/leds.h> |
23 | #include <linux/of.h> | ||
24 | #include <linux/of_irq.h> | ||
25 | #include <linux/of_address.h> | ||
26 | #include <plat/gpio.h> | ||
20 | 27 | ||
21 | /* | 28 | /* |
22 | * GPIO unit register offsets. | 29 | * GPIO unit register offsets. |
@@ -38,6 +45,7 @@ struct orion_gpio_chip { | |||
38 | unsigned long valid_output; | 45 | unsigned long valid_output; |
39 | int mask_offset; | 46 | int mask_offset; |
40 | int secondary_irq_base; | 47 | int secondary_irq_base; |
48 | struct irq_domain *domain; | ||
41 | }; | 49 | }; |
42 | 50 | ||
43 | static void __iomem *GPIO_OUT(struct orion_gpio_chip *ochip) | 51 | static void __iomem *GPIO_OUT(struct orion_gpio_chip *ochip) |
@@ -222,10 +230,10 @@ static int orion_gpio_to_irq(struct gpio_chip *chip, unsigned pin) | |||
222 | struct orion_gpio_chip *ochip = | 230 | struct orion_gpio_chip *ochip = |
223 | container_of(chip, struct orion_gpio_chip, chip); | 231 | container_of(chip, struct orion_gpio_chip, chip); |
224 | 232 | ||
225 | return ochip->secondary_irq_base + pin; | 233 | return irq_create_mapping(ochip->domain, |
234 | ochip->secondary_irq_base + pin); | ||
226 | } | 235 | } |
227 | 236 | ||
228 | |||
229 | /* | 237 | /* |
230 | * Orion-specific GPIO API extensions. | 238 | * Orion-specific GPIO API extensions. |
231 | */ | 239 | */ |
@@ -353,12 +361,10 @@ static int gpio_irq_set_type(struct irq_data *d, u32 type) | |||
353 | int pin; | 361 | int pin; |
354 | u32 u; | 362 | u32 u; |
355 | 363 | ||
356 | pin = d->irq - gc->irq_base; | 364 | pin = d->hwirq - ochip->secondary_irq_base; |
357 | 365 | ||
358 | u = readl(GPIO_IO_CONF(ochip)) & (1 << pin); | 366 | u = readl(GPIO_IO_CONF(ochip)) & (1 << pin); |
359 | if (!u) { | 367 | if (!u) { |
360 | printk(KERN_ERR "orion gpio_irq_set_type failed " | ||
361 | "(irq %d, pin %d).\n", d->irq, pin); | ||
362 | return -EINVAL; | 368 | return -EINVAL; |
363 | } | 369 | } |
364 | 370 | ||
@@ -397,17 +403,53 @@ static int gpio_irq_set_type(struct irq_data *d, u32 type) | |||
397 | u &= ~(1 << pin); /* rising */ | 403 | u &= ~(1 << pin); /* rising */ |
398 | writel(u, GPIO_IN_POL(ochip)); | 404 | writel(u, GPIO_IN_POL(ochip)); |
399 | } | 405 | } |
400 | |||
401 | return 0; | 406 | return 0; |
402 | } | 407 | } |
403 | 408 | ||
404 | void __init orion_gpio_init(int gpio_base, int ngpio, | 409 | static void gpio_irq_handler(unsigned irq, struct irq_desc *desc) |
405 | u32 base, int mask_offset, int secondary_irq_base) | 410 | { |
411 | struct orion_gpio_chip *ochip = irq_get_handler_data(irq); | ||
412 | u32 cause, type; | ||
413 | int i; | ||
414 | |||
415 | if (ochip == NULL) | ||
416 | return; | ||
417 | |||
418 | cause = readl(GPIO_DATA_IN(ochip)) & readl(GPIO_LEVEL_MASK(ochip)); | ||
419 | cause |= readl(GPIO_EDGE_CAUSE(ochip)) & readl(GPIO_EDGE_MASK(ochip)); | ||
420 | |||
421 | for (i = 0; i < ochip->chip.ngpio; i++) { | ||
422 | int irq; | ||
423 | |||
424 | irq = ochip->secondary_irq_base + i; | ||
425 | |||
426 | if (!(cause & (1 << i))) | ||
427 | continue; | ||
428 | |||
429 | type = irqd_get_trigger_type(irq_get_irq_data(irq)); | ||
430 | if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { | ||
431 | /* Swap polarity (race with GPIO line) */ | ||
432 | u32 polarity; | ||
433 | |||
434 | polarity = readl(GPIO_IN_POL(ochip)); | ||
435 | polarity ^= 1 << i; | ||
436 | writel(polarity, GPIO_IN_POL(ochip)); | ||
437 | } | ||
438 | generic_handle_irq(irq); | ||
439 | } | ||
440 | } | ||
441 | |||
442 | void __init orion_gpio_init(struct device_node *np, | ||
443 | int gpio_base, int ngpio, | ||
444 | void __iomem *base, int mask_offset, | ||
445 | int secondary_irq_base, | ||
446 | int irqs[4]) | ||
406 | { | 447 | { |
407 | struct orion_gpio_chip *ochip; | 448 | struct orion_gpio_chip *ochip; |
408 | struct irq_chip_generic *gc; | 449 | struct irq_chip_generic *gc; |
409 | struct irq_chip_type *ct; | 450 | struct irq_chip_type *ct; |
410 | char gc_label[16]; | 451 | char gc_label[16]; |
452 | int i; | ||
411 | 453 | ||
412 | if (orion_gpio_chip_count == ARRAY_SIZE(orion_gpio_chips)) | 454 | if (orion_gpio_chip_count == ARRAY_SIZE(orion_gpio_chips)) |
413 | return; | 455 | return; |
@@ -426,6 +468,10 @@ void __init orion_gpio_init(int gpio_base, int ngpio, | |||
426 | ochip->chip.base = gpio_base; | 468 | ochip->chip.base = gpio_base; |
427 | ochip->chip.ngpio = ngpio; | 469 | ochip->chip.ngpio = ngpio; |
428 | ochip->chip.can_sleep = 0; | 470 | ochip->chip.can_sleep = 0; |
471 | #ifdef CONFIG_OF | ||
472 | ochip->chip.of_node = np; | ||
473 | #endif | ||
474 | |||
429 | spin_lock_init(&ochip->lock); | 475 | spin_lock_init(&ochip->lock); |
430 | ochip->base = (void __iomem *)base; | 476 | ochip->base = (void __iomem *)base; |
431 | ochip->valid_input = 0; | 477 | ochip->valid_input = 0; |
@@ -435,8 +481,6 @@ void __init orion_gpio_init(int gpio_base, int ngpio, | |||
435 | 481 | ||
436 | gpiochip_add(&ochip->chip); | 482 | gpiochip_add(&ochip->chip); |
437 | 483 | ||
438 | orion_gpio_chip_count++; | ||
439 | |||
440 | /* | 484 | /* |
441 | * Mask and clear GPIO interrupts. | 485 | * Mask and clear GPIO interrupts. |
442 | */ | 486 | */ |
@@ -444,16 +488,28 @@ void __init orion_gpio_init(int gpio_base, int ngpio, | |||
444 | writel(0, GPIO_EDGE_MASK(ochip)); | 488 | writel(0, GPIO_EDGE_MASK(ochip)); |
445 | writel(0, GPIO_LEVEL_MASK(ochip)); | 489 | writel(0, GPIO_LEVEL_MASK(ochip)); |
446 | 490 | ||
447 | gc = irq_alloc_generic_chip("orion_gpio_irq", 2, secondary_irq_base, | 491 | /* Setup the interrupt handlers. Each chip can have up to 4 |
492 | * interrupt handlers, with each handler dealing with 8 GPIO | ||
493 | * pins. */ | ||
494 | |||
495 | for (i = 0; i < 4; i++) { | ||
496 | if (irqs[i]) { | ||
497 | irq_set_handler_data(irqs[i], ochip); | ||
498 | irq_set_chained_handler(irqs[i], gpio_irq_handler); | ||
499 | } | ||
500 | } | ||
501 | |||
502 | gc = irq_alloc_generic_chip("orion_gpio_irq", 2, | ||
503 | secondary_irq_base, | ||
448 | ochip->base, handle_level_irq); | 504 | ochip->base, handle_level_irq); |
449 | gc->private = ochip; | 505 | gc->private = ochip; |
450 | |||
451 | ct = gc->chip_types; | 506 | ct = gc->chip_types; |
452 | ct->regs.mask = ochip->mask_offset + GPIO_LEVEL_MASK_OFF; | 507 | ct->regs.mask = ochip->mask_offset + GPIO_LEVEL_MASK_OFF; |
453 | ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW; | 508 | ct->type = IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW; |
454 | ct->chip.irq_mask = irq_gc_mask_clr_bit; | 509 | ct->chip.irq_mask = irq_gc_mask_clr_bit; |
455 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | 510 | ct->chip.irq_unmask = irq_gc_mask_set_bit; |
456 | ct->chip.irq_set_type = gpio_irq_set_type; | 511 | ct->chip.irq_set_type = gpio_irq_set_type; |
512 | ct->chip.name = ochip->chip.label; | ||
457 | 513 | ||
458 | ct++; | 514 | ct++; |
459 | ct->regs.mask = ochip->mask_offset + GPIO_EDGE_MASK_OFF; | 515 | ct->regs.mask = ochip->mask_offset + GPIO_EDGE_MASK_OFF; |
@@ -464,41 +520,69 @@ void __init orion_gpio_init(int gpio_base, int ngpio, | |||
464 | ct->chip.irq_unmask = irq_gc_mask_set_bit; | 520 | ct->chip.irq_unmask = irq_gc_mask_set_bit; |
465 | ct->chip.irq_set_type = gpio_irq_set_type; | 521 | ct->chip.irq_set_type = gpio_irq_set_type; |
466 | ct->handler = handle_edge_irq; | 522 | ct->handler = handle_edge_irq; |
523 | ct->chip.name = ochip->chip.label; | ||
467 | 524 | ||
468 | irq_setup_generic_chip(gc, IRQ_MSK(ngpio), IRQ_GC_INIT_MASK_CACHE, | 525 | irq_setup_generic_chip(gc, IRQ_MSK(ngpio), IRQ_GC_INIT_MASK_CACHE, |
469 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); | 526 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); |
470 | } | ||
471 | 527 | ||
472 | void orion_gpio_irq_handler(int pinoff) | 528 | /* Setup irq domain on top of the generic chip. */ |
473 | { | 529 | ochip->domain = irq_domain_add_legacy(np, |
474 | struct orion_gpio_chip *ochip; | 530 | ochip->chip.ngpio, |
475 | u32 cause, type; | 531 | ochip->secondary_irq_base, |
476 | int i; | 532 | ochip->secondary_irq_base, |
477 | 533 | &irq_domain_simple_ops, | |
478 | ochip = orion_gpio_chip_find(pinoff); | 534 | ochip); |
479 | if (ochip == NULL) | 535 | if (!ochip->domain) |
480 | return; | 536 | panic("%s: couldn't allocate irq domain (DT).\n", |
481 | 537 | ochip->chip.label); | |
482 | cause = readl(GPIO_DATA_IN(ochip)) & readl(GPIO_LEVEL_MASK(ochip)); | ||
483 | cause |= readl(GPIO_EDGE_CAUSE(ochip)) & readl(GPIO_EDGE_MASK(ochip)); | ||
484 | |||
485 | for (i = 0; i < ochip->chip.ngpio; i++) { | ||
486 | int irq; | ||
487 | 538 | ||
488 | irq = ochip->secondary_irq_base + i; | 539 | orion_gpio_chip_count++; |
540 | } | ||
489 | 541 | ||
490 | if (!(cause & (1 << i))) | 542 | #ifdef CONFIG_OF |
491 | continue; | 543 | static void __init orion_gpio_of_init_one(struct device_node *np, |
544 | int irq_gpio_base) | ||
545 | { | ||
546 | int ngpio, gpio_base, mask_offset; | ||
547 | void __iomem *base; | ||
548 | int ret, i; | ||
549 | int irqs[4]; | ||
550 | int secondary_irq_base; | ||
551 | |||
552 | ret = of_property_read_u32(np, "ngpio", &ngpio); | ||
553 | if (ret) | ||
554 | goto out; | ||
555 | ret = of_property_read_u32(np, "mask-offset", &mask_offset); | ||
556 | if (ret == -EINVAL) | ||
557 | mask_offset = 0; | ||
558 | else | ||
559 | goto out; | ||
560 | base = of_iomap(np, 0); | ||
561 | if (!base) | ||
562 | goto out; | ||
563 | |||
564 | secondary_irq_base = irq_gpio_base + (32 * orion_gpio_chip_count); | ||
565 | gpio_base = 32 * orion_gpio_chip_count; | ||
566 | |||
567 | /* Get the interrupt numbers. Each chip can have up to 4 | ||
568 | * interrupt handlers, with each handler dealing with 8 GPIO | ||
569 | * pins. */ | ||
570 | |||
571 | for (i = 0; i < 4; i++) | ||
572 | irqs[i] = irq_of_parse_and_map(np, i); | ||
573 | |||
574 | orion_gpio_init(np, gpio_base, ngpio, base, mask_offset, | ||
575 | secondary_irq_base, irqs); | ||
576 | return; | ||
577 | out: | ||
578 | pr_err("%s: %s: missing mandatory property\n", __func__, np->name); | ||
579 | } | ||
492 | 580 | ||
493 | type = irqd_get_trigger_type(irq_get_irq_data(irq)); | 581 | void __init orion_gpio_of_init(int irq_gpio_base) |
494 | if ((type & IRQ_TYPE_SENSE_MASK) == IRQ_TYPE_EDGE_BOTH) { | 582 | { |
495 | /* Swap polarity (race with GPIO line) */ | 583 | struct device_node *np; |
496 | u32 polarity; | ||
497 | 584 | ||
498 | polarity = readl(GPIO_IN_POL(ochip)); | 585 | for_each_compatible_node(np, NULL, "marvell,orion-gpio") |
499 | polarity ^= 1 << i; | 586 | orion_gpio_of_init_one(np, irq_gpio_base); |
500 | writel(polarity, GPIO_IN_POL(ochip)); | ||
501 | } | ||
502 | generic_handle_irq(irq); | ||
503 | } | ||
504 | } | 587 | } |
588 | #endif | ||
diff --git a/arch/arm/plat-orion/include/plat/gpio.h b/arch/arm/plat-orion/include/plat/gpio.h index bec0c98ce41f..81c6fc8a7b28 100644 --- a/arch/arm/plat-orion/include/plat/gpio.h +++ b/arch/arm/plat-orion/include/plat/gpio.h | |||
@@ -13,7 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/types.h> | 15 | #include <linux/types.h> |
16 | 16 | #include <linux/irqdomain.h> | |
17 | /* | 17 | /* |
18 | * Orion-specific GPIO API extensions. | 18 | * Orion-specific GPIO API extensions. |
19 | */ | 19 | */ |
@@ -27,13 +27,11 @@ int orion_gpio_led_blink_set(unsigned gpio, int state, | |||
27 | void orion_gpio_set_valid(unsigned pin, int mode); | 27 | void orion_gpio_set_valid(unsigned pin, int mode); |
28 | 28 | ||
29 | /* Initialize gpiolib. */ | 29 | /* Initialize gpiolib. */ |
30 | void __init orion_gpio_init(int gpio_base, int ngpio, | 30 | void __init orion_gpio_init(struct device_node *np, |
31 | u32 base, int mask_offset, int secondary_irq_base); | 31 | int gpio_base, int ngpio, |
32 | 32 | void __iomem *base, int mask_offset, | |
33 | /* | 33 | int secondary_irq_base, |
34 | * GPIO interrupt handling. | 34 | int irq[4]); |
35 | */ | ||
36 | void orion_gpio_irq_handler(int irqoff); | ||
37 | |||
38 | 35 | ||
36 | void __init orion_gpio_of_init(int irq_gpio_base); | ||
39 | #endif | 37 | #endif |
diff --git a/arch/arm/plat-orion/include/plat/irq.h b/arch/arm/plat-orion/include/plat/irq.h index f05eeab94968..50547e417936 100644 --- a/arch/arm/plat-orion/include/plat/irq.h +++ b/arch/arm/plat-orion/include/plat/irq.h | |||
@@ -12,6 +12,5 @@ | |||
12 | #define __PLAT_IRQ_H | 12 | #define __PLAT_IRQ_H |
13 | 13 | ||
14 | void orion_irq_init(unsigned int irq_start, void __iomem *maskaddr); | 14 | void orion_irq_init(unsigned int irq_start, void __iomem *maskaddr); |
15 | 15 | void __init orion_dt_init_irq(void); | |
16 | |||
17 | #endif | 16 | #endif |
diff --git a/arch/arm/plat-orion/irq.c b/arch/arm/plat-orion/irq.c index 2d5b9c1ef389..d751964def4c 100644 --- a/arch/arm/plat-orion/irq.c +++ b/arch/arm/plat-orion/irq.c | |||
@@ -11,8 +11,12 @@ | |||
11 | #include <linux/kernel.h> | 11 | #include <linux/kernel.h> |
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
14 | #include <linux/irqdomain.h> | ||
14 | #include <linux/io.h> | 15 | #include <linux/io.h> |
16 | #include <linux/of_address.h> | ||
17 | #include <linux/of_irq.h> | ||
15 | #include <plat/irq.h> | 18 | #include <plat/irq.h> |
19 | #include <plat/gpio.h> | ||
16 | 20 | ||
17 | void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr) | 21 | void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr) |
18 | { | 22 | { |
@@ -32,3 +36,39 @@ void __init orion_irq_init(unsigned int irq_start, void __iomem *maskaddr) | |||
32 | irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_MASK_CACHE, | 36 | irq_setup_generic_chip(gc, IRQ_MSK(32), IRQ_GC_INIT_MASK_CACHE, |
33 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); | 37 | IRQ_NOREQUEST, IRQ_LEVEL | IRQ_NOPROBE); |
34 | } | 38 | } |
39 | |||
40 | #ifdef CONFIG_OF | ||
41 | static int __init orion_add_irq_domain(struct device_node *np, | ||
42 | struct device_node *interrupt_parent) | ||
43 | { | ||
44 | int i = 0, irq_gpio; | ||
45 | void __iomem *base; | ||
46 | |||
47 | do { | ||
48 | base = of_iomap(np, i); | ||
49 | if (base) { | ||
50 | orion_irq_init(i * 32, base); | ||
51 | i++; | ||
52 | } | ||
53 | } while (base); | ||
54 | |||
55 | irq_domain_add_legacy(np, i * 32, 0, 0, | ||
56 | &irq_domain_simple_ops, NULL); | ||
57 | |||
58 | irq_gpio = i * 32; | ||
59 | orion_gpio_of_init(irq_gpio); | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | static const struct of_device_id orion_irq_match[] = { | ||
65 | { .compatible = "marvell,orion-intc", | ||
66 | .data = orion_add_irq_domain, }, | ||
67 | {}, | ||
68 | }; | ||
69 | |||
70 | void __init orion_dt_init_irq(void) | ||
71 | { | ||
72 | of_irq_init(orion_irq_match); | ||
73 | } | ||
74 | #endif | ||
diff --git a/arch/arm/plat-samsung/Kconfig b/arch/arm/plat-samsung/Kconfig index 7aca31c1df1f..9c3b90c3538e 100644 --- a/arch/arm/plat-samsung/Kconfig +++ b/arch/arm/plat-samsung/Kconfig | |||
@@ -403,7 +403,8 @@ config S5P_DEV_USB_EHCI | |||
403 | 403 | ||
404 | config S3C24XX_PWM | 404 | config S3C24XX_PWM |
405 | bool "PWM device support" | 405 | bool "PWM device support" |
406 | select HAVE_PWM | 406 | select PWM |
407 | select PWM_SAMSUNG | ||
407 | help | 408 | help |
408 | Support for exporting the PWM timer blocks via the pwm device | 409 | Support for exporting the PWM timer blocks via the pwm device |
409 | system | 410 | system |
diff --git a/arch/arm/vfp/vfpmodule.c b/arch/arm/vfp/vfpmodule.c index fb849d044bde..c834b32af275 100644 --- a/arch/arm/vfp/vfpmodule.c +++ b/arch/arm/vfp/vfpmodule.c | |||
@@ -719,8 +719,10 @@ static int __init vfp_init(void) | |||
719 | if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100) | 719 | if ((fmrx(MVFR1) & 0x000fff00) == 0x00011100) |
720 | elf_hwcap |= HWCAP_NEON; | 720 | elf_hwcap |= HWCAP_NEON; |
721 | #endif | 721 | #endif |
722 | #ifdef CONFIG_VFPv3 | ||
722 | if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000) | 723 | if ((fmrx(MVFR1) & 0xf0000000) == 0x10000000) |
723 | elf_hwcap |= HWCAP_VFPv4; | 724 | elf_hwcap |= HWCAP_VFPv4; |
725 | #endif | ||
724 | } | 726 | } |
725 | } | 727 | } |
726 | return 0; | 728 | return 0; |
diff --git a/arch/blackfin/kernel/setup.c b/arch/blackfin/kernel/setup.c index ada8f0fc71e4..fb96e607adcf 100644 --- a/arch/blackfin/kernel/setup.c +++ b/arch/blackfin/kernel/setup.c | |||
@@ -52,7 +52,6 @@ EXPORT_SYMBOL(reserved_mem_dcache_on); | |||
52 | #ifdef CONFIG_MTD_UCLINUX | 52 | #ifdef CONFIG_MTD_UCLINUX |
53 | extern struct map_info uclinux_ram_map; | 53 | extern struct map_info uclinux_ram_map; |
54 | unsigned long memory_mtd_end, memory_mtd_start, mtd_size; | 54 | unsigned long memory_mtd_end, memory_mtd_start, mtd_size; |
55 | unsigned long _ebss; | ||
56 | EXPORT_SYMBOL(memory_mtd_end); | 55 | EXPORT_SYMBOL(memory_mtd_end); |
57 | EXPORT_SYMBOL(memory_mtd_start); | 56 | EXPORT_SYMBOL(memory_mtd_start); |
58 | EXPORT_SYMBOL(mtd_size); | 57 | EXPORT_SYMBOL(mtd_size); |
diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig index 052f81a76239..983c859e40b7 100644 --- a/arch/c6x/Kconfig +++ b/arch/c6x/Kconfig | |||
@@ -6,6 +6,7 @@ | |||
6 | config C6X | 6 | config C6X |
7 | def_bool y | 7 | def_bool y |
8 | select CLKDEV_LOOKUP | 8 | select CLKDEV_LOOKUP |
9 | select GENERIC_ATOMIC64 | ||
9 | select GENERIC_IRQ_SHOW | 10 | select GENERIC_IRQ_SHOW |
10 | select HAVE_ARCH_TRACEHOOK | 11 | select HAVE_ARCH_TRACEHOOK |
11 | select HAVE_DMA_API_DEBUG | 12 | select HAVE_DMA_API_DEBUG |
diff --git a/arch/c6x/include/asm/cache.h b/arch/c6x/include/asm/cache.h index 6d521d96d941..09c5a0f5f4d1 100644 --- a/arch/c6x/include/asm/cache.h +++ b/arch/c6x/include/asm/cache.h | |||
@@ -1,7 +1,7 @@ | |||
1 | /* | 1 | /* |
2 | * Port on Texas Instruments TMS320C6x architecture | 2 | * Port on Texas Instruments TMS320C6x architecture |
3 | * | 3 | * |
4 | * Copyright (C) 2005, 2006, 2009, 2010 Texas Instruments Incorporated | 4 | * Copyright (C) 2005, 2006, 2009, 2010, 2012 Texas Instruments Incorporated |
5 | * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) | 5 | * Author: Aurelien Jacquiot (aurelien.jacquiot@jaluna.com) |
6 | * | 6 | * |
7 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
@@ -16,9 +16,14 @@ | |||
16 | /* | 16 | /* |
17 | * Cache line size | 17 | * Cache line size |
18 | */ | 18 | */ |
19 | #define L1D_CACHE_BYTES 64 | 19 | #define L1D_CACHE_SHIFT 6 |
20 | #define L1P_CACHE_BYTES 32 | 20 | #define L1D_CACHE_BYTES (1 << L1D_CACHE_SHIFT) |
21 | #define L2_CACHE_BYTES 128 | 21 | |
22 | #define L1P_CACHE_SHIFT 5 | ||
23 | #define L1P_CACHE_BYTES (1 << L1P_CACHE_SHIFT) | ||
24 | |||
25 | #define L2_CACHE_SHIFT 7 | ||
26 | #define L2_CACHE_BYTES (1 << L2_CACHE_SHIFT) | ||
22 | 27 | ||
23 | /* | 28 | /* |
24 | * L2 used as cache | 29 | * L2 used as cache |
@@ -29,7 +34,8 @@ | |||
29 | * For practical reasons the L1_CACHE_BYTES defines should not be smaller than | 34 | * For practical reasons the L1_CACHE_BYTES defines should not be smaller than |
30 | * the L2 line size | 35 | * the L2 line size |
31 | */ | 36 | */ |
32 | #define L1_CACHE_BYTES L2_CACHE_BYTES | 37 | #define L1_CACHE_SHIFT L2_CACHE_SHIFT |
38 | #define L1_CACHE_BYTES (1 << L1_CACHE_SHIFT) | ||
33 | 39 | ||
34 | #define L2_CACHE_ALIGN_LOW(x) \ | 40 | #define L2_CACHE_ALIGN_LOW(x) \ |
35 | (((x) & ~(L2_CACHE_BYTES - 1))) | 41 | (((x) & ~(L2_CACHE_BYTES - 1))) |
diff --git a/arch/ia64/configs/generic_defconfig b/arch/ia64/configs/generic_defconfig index 954d81e2e837..7913695b2fcb 100644 --- a/arch/ia64/configs/generic_defconfig +++ b/arch/ia64/configs/generic_defconfig | |||
@@ -234,5 +234,4 @@ CONFIG_CRYPTO_PCBC=m | |||
234 | CONFIG_CRYPTO_MD5=y | 234 | CONFIG_CRYPTO_MD5=y |
235 | # CONFIG_CRYPTO_ANSI_CPRNG is not set | 235 | # CONFIG_CRYPTO_ANSI_CPRNG is not set |
236 | CONFIG_CRC_T10DIF=y | 236 | CONFIG_CRC_T10DIF=y |
237 | CONFIG_MISC_DEVICES=y | ||
238 | CONFIG_INTEL_IOMMU=y | 237 | CONFIG_INTEL_IOMMU=y |
diff --git a/arch/ia64/configs/gensparse_defconfig b/arch/ia64/configs/gensparse_defconfig index 91c41ecfa6d9..f8e913365423 100644 --- a/arch/ia64/configs/gensparse_defconfig +++ b/arch/ia64/configs/gensparse_defconfig | |||
@@ -209,4 +209,3 @@ CONFIG_MAGIC_SYSRQ=y | |||
209 | CONFIG_DEBUG_KERNEL=y | 209 | CONFIG_DEBUG_KERNEL=y |
210 | CONFIG_DEBUG_MUTEXES=y | 210 | CONFIG_DEBUG_MUTEXES=y |
211 | CONFIG_CRYPTO_MD5=y | 211 | CONFIG_CRYPTO_MD5=y |
212 | CONFIG_MISC_DEVICES=y | ||
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 6f38b6120d96..440578850ae5 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
@@ -497,7 +497,7 @@ acpi_numa_processor_affinity_init(struct acpi_srat_cpu_affinity *pa) | |||
497 | srat_num_cpus++; | 497 | srat_num_cpus++; |
498 | } | 498 | } |
499 | 499 | ||
500 | void __init | 500 | int __init |
501 | acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | 501 | acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) |
502 | { | 502 | { |
503 | unsigned long paddr, size; | 503 | unsigned long paddr, size; |
@@ -512,7 +512,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | |||
512 | 512 | ||
513 | /* Ignore disabled entries */ | 513 | /* Ignore disabled entries */ |
514 | if (!(ma->flags & ACPI_SRAT_MEM_ENABLED)) | 514 | if (!(ma->flags & ACPI_SRAT_MEM_ENABLED)) |
515 | return; | 515 | return -1; |
516 | 516 | ||
517 | /* record this node in proximity bitmap */ | 517 | /* record this node in proximity bitmap */ |
518 | pxm_bit_set(pxm); | 518 | pxm_bit_set(pxm); |
@@ -531,6 +531,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | |||
531 | p->size = size; | 531 | p->size = size; |
532 | p->nid = pxm; | 532 | p->nid = pxm; |
533 | num_node_memblks++; | 533 | num_node_memblks++; |
534 | return 0; | ||
534 | } | 535 | } |
535 | 536 | ||
536 | void __init acpi_numa_arch_fixup(void) | 537 | void __init acpi_numa_arch_fixup(void) |
diff --git a/arch/m68k/Kconfig b/arch/m68k/Kconfig index 0b0f8b8c4a26..b22df9410dce 100644 --- a/arch/m68k/Kconfig +++ b/arch/m68k/Kconfig | |||
@@ -5,6 +5,7 @@ config M68K | |||
5 | select HAVE_AOUT if MMU | 5 | select HAVE_AOUT if MMU |
6 | select HAVE_GENERIC_HARDIRQS | 6 | select HAVE_GENERIC_HARDIRQS |
7 | select GENERIC_IRQ_SHOW | 7 | select GENERIC_IRQ_SHOW |
8 | select GENERIC_ATOMIC64 | ||
8 | select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS | 9 | select ARCH_HAVE_NMI_SAFE_CMPXCHG if RMW_INSNS |
9 | select GENERIC_CPU_DEVICES | 10 | select GENERIC_CPU_DEVICES |
10 | select GENERIC_STRNCPY_FROM_USER if MMU | 11 | select GENERIC_STRNCPY_FROM_USER if MMU |
@@ -54,18 +55,6 @@ config ZONE_DMA | |||
54 | bool | 55 | bool |
55 | default y | 56 | default y |
56 | 57 | ||
57 | config CPU_HAS_NO_BITFIELDS | ||
58 | bool | ||
59 | |||
60 | config CPU_HAS_NO_MULDIV64 | ||
61 | bool | ||
62 | |||
63 | config CPU_HAS_ADDRESS_SPACES | ||
64 | bool | ||
65 | |||
66 | config FPU | ||
67 | bool | ||
68 | |||
69 | config HZ | 58 | config HZ |
70 | int | 59 | int |
71 | default 1000 if CLEOPATRA | 60 | default 1000 if CLEOPATRA |
diff --git a/arch/m68k/Kconfig.cpu b/arch/m68k/Kconfig.cpu index 43a9f8f1b8eb..c4eb79edecec 100644 --- a/arch/m68k/Kconfig.cpu +++ b/arch/m68k/Kconfig.cpu | |||
@@ -28,6 +28,7 @@ config COLDFIRE | |||
28 | select CPU_HAS_NO_BITFIELDS | 28 | select CPU_HAS_NO_BITFIELDS |
29 | select CPU_HAS_NO_MULDIV64 | 29 | select CPU_HAS_NO_MULDIV64 |
30 | select GENERIC_CSUM | 30 | select GENERIC_CSUM |
31 | select HAVE_CLK | ||
31 | 32 | ||
32 | endchoice | 33 | endchoice |
33 | 34 | ||
@@ -37,6 +38,7 @@ config M68000 | |||
37 | bool | 38 | bool |
38 | select CPU_HAS_NO_BITFIELDS | 39 | select CPU_HAS_NO_BITFIELDS |
39 | select CPU_HAS_NO_MULDIV64 | 40 | select CPU_HAS_NO_MULDIV64 |
41 | select CPU_HAS_NO_UNALIGNED | ||
40 | select GENERIC_CSUM | 42 | select GENERIC_CSUM |
41 | help | 43 | help |
42 | The Freescale (was Motorola) 68000 CPU is the first generation of | 44 | The Freescale (was Motorola) 68000 CPU is the first generation of |
@@ -48,6 +50,7 @@ config M68000 | |||
48 | config MCPU32 | 50 | config MCPU32 |
49 | bool | 51 | bool |
50 | select CPU_HAS_NO_BITFIELDS | 52 | select CPU_HAS_NO_BITFIELDS |
53 | select CPU_HAS_NO_UNALIGNED | ||
51 | help | 54 | help |
52 | The Freescale (was then Motorola) CPU32 is a CPU core that is | 55 | The Freescale (was then Motorola) CPU32 is a CPU core that is |
53 | based on the 68020 processor. For the most part it is used in | 56 | based on the 68020 processor. For the most part it is used in |
@@ -56,7 +59,6 @@ config MCPU32 | |||
56 | config M68020 | 59 | config M68020 |
57 | bool "68020 support" | 60 | bool "68020 support" |
58 | depends on MMU | 61 | depends on MMU |
59 | select GENERIC_ATOMIC64 | ||
60 | select CPU_HAS_ADDRESS_SPACES | 62 | select CPU_HAS_ADDRESS_SPACES |
61 | help | 63 | help |
62 | If you anticipate running this kernel on a computer with a MC68020 | 64 | If you anticipate running this kernel on a computer with a MC68020 |
@@ -67,7 +69,6 @@ config M68020 | |||
67 | config M68030 | 69 | config M68030 |
68 | bool "68030 support" | 70 | bool "68030 support" |
69 | depends on MMU && !MMU_SUN3 | 71 | depends on MMU && !MMU_SUN3 |
70 | select GENERIC_ATOMIC64 | ||
71 | select CPU_HAS_ADDRESS_SPACES | 72 | select CPU_HAS_ADDRESS_SPACES |
72 | help | 73 | help |
73 | If you anticipate running this kernel on a computer with a MC68030 | 74 | If you anticipate running this kernel on a computer with a MC68030 |
@@ -77,7 +78,6 @@ config M68030 | |||
77 | config M68040 | 78 | config M68040 |
78 | bool "68040 support" | 79 | bool "68040 support" |
79 | depends on MMU && !MMU_SUN3 | 80 | depends on MMU && !MMU_SUN3 |
80 | select GENERIC_ATOMIC64 | ||
81 | select CPU_HAS_ADDRESS_SPACES | 81 | select CPU_HAS_ADDRESS_SPACES |
82 | help | 82 | help |
83 | If you anticipate running this kernel on a computer with a MC68LC040 | 83 | If you anticipate running this kernel on a computer with a MC68LC040 |
@@ -88,7 +88,6 @@ config M68040 | |||
88 | config M68060 | 88 | config M68060 |
89 | bool "68060 support" | 89 | bool "68060 support" |
90 | depends on MMU && !MMU_SUN3 | 90 | depends on MMU && !MMU_SUN3 |
91 | select GENERIC_ATOMIC64 | ||
92 | select CPU_HAS_ADDRESS_SPACES | 91 | select CPU_HAS_ADDRESS_SPACES |
93 | help | 92 | help |
94 | If you anticipate running this kernel on a computer with a MC68060 | 93 | If you anticipate running this kernel on a computer with a MC68060 |
@@ -376,6 +375,18 @@ config NODES_SHIFT | |||
376 | default "3" | 375 | default "3" |
377 | depends on !SINGLE_MEMORY_CHUNK | 376 | depends on !SINGLE_MEMORY_CHUNK |
378 | 377 | ||
378 | config CPU_HAS_NO_BITFIELDS | ||
379 | bool | ||
380 | |||
381 | config CPU_HAS_NO_MULDIV64 | ||
382 | bool | ||
383 | |||
384 | config CPU_HAS_NO_UNALIGNED | ||
385 | bool | ||
386 | |||
387 | config CPU_HAS_ADDRESS_SPACES | ||
388 | bool | ||
389 | |||
379 | config FPU | 390 | config FPU |
380 | bool | 391 | bool |
381 | 392 | ||
diff --git a/arch/m68k/apollo/config.c b/arch/m68k/apollo/config.c index 0a30406b9442..f5565d6eeb8e 100644 --- a/arch/m68k/apollo/config.c +++ b/arch/m68k/apollo/config.c | |||
@@ -177,8 +177,8 @@ irqreturn_t dn_timer_int(int irq, void *dev_id) | |||
177 | 177 | ||
178 | timer_handler(irq, dev_id); | 178 | timer_handler(irq, dev_id); |
179 | 179 | ||
180 | x=*(volatile unsigned char *)(timer+3); | 180 | x = *(volatile unsigned char *)(apollo_timer + 3); |
181 | x=*(volatile unsigned char *)(timer+5); | 181 | x = *(volatile unsigned char *)(apollo_timer + 5); |
182 | 182 | ||
183 | return IRQ_HANDLED; | 183 | return IRQ_HANDLED; |
184 | } | 184 | } |
@@ -186,17 +186,17 @@ irqreturn_t dn_timer_int(int irq, void *dev_id) | |||
186 | void dn_sched_init(irq_handler_t timer_routine) | 186 | void dn_sched_init(irq_handler_t timer_routine) |
187 | { | 187 | { |
188 | /* program timer 1 */ | 188 | /* program timer 1 */ |
189 | *(volatile unsigned char *)(timer+3)=0x01; | 189 | *(volatile unsigned char *)(apollo_timer + 3) = 0x01; |
190 | *(volatile unsigned char *)(timer+1)=0x40; | 190 | *(volatile unsigned char *)(apollo_timer + 1) = 0x40; |
191 | *(volatile unsigned char *)(timer+5)=0x09; | 191 | *(volatile unsigned char *)(apollo_timer + 5) = 0x09; |
192 | *(volatile unsigned char *)(timer+7)=0xc4; | 192 | *(volatile unsigned char *)(apollo_timer + 7) = 0xc4; |
193 | 193 | ||
194 | /* enable IRQ of PIC B */ | 194 | /* enable IRQ of PIC B */ |
195 | *(volatile unsigned char *)(pica+1)&=(~8); | 195 | *(volatile unsigned char *)(pica+1)&=(~8); |
196 | 196 | ||
197 | #if 0 | 197 | #if 0 |
198 | printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3)); | 198 | printk("*(0x10803) %02x\n",*(volatile unsigned char *)(apollo_timer + 0x3)); |
199 | printk("*(0x10803) %02x\n",*(volatile unsigned char *)(timer+0x3)); | 199 | printk("*(0x10803) %02x\n",*(volatile unsigned char *)(apollo_timer + 0x3)); |
200 | #endif | 200 | #endif |
201 | 201 | ||
202 | if (request_irq(IRQ_APOLLO, dn_timer_int, 0, "time", timer_routine)) | 202 | if (request_irq(IRQ_APOLLO, dn_timer_int, 0, "time", timer_routine)) |
diff --git a/arch/m68k/include/asm/Kbuild b/arch/m68k/include/asm/Kbuild index eafa2539a8ee..a74e5d95c384 100644 --- a/arch/m68k/include/asm/Kbuild +++ b/arch/m68k/include/asm/Kbuild | |||
@@ -1,4 +1,29 @@ | |||
1 | include include/asm-generic/Kbuild.asm | 1 | include include/asm-generic/Kbuild.asm |
2 | header-y += cachectl.h | 2 | header-y += cachectl.h |
3 | 3 | ||
4 | generic-y += bitsperlong.h | ||
5 | generic-y += cputime.h | ||
6 | generic-y += device.h | ||
7 | generic-y += emergency-restart.h | ||
8 | generic-y += errno.h | ||
9 | generic-y += futex.h | ||
10 | generic-y += ioctl.h | ||
11 | generic-y += ipcbuf.h | ||
12 | generic-y += irq_regs.h | ||
13 | generic-y += kdebug.h | ||
14 | generic-y += kmap_types.h | ||
15 | generic-y += kvm_para.h | ||
16 | generic-y += local64.h | ||
17 | generic-y += local.h | ||
18 | generic-y += mman.h | ||
19 | generic-y += mutex.h | ||
20 | generic-y += percpu.h | ||
21 | generic-y += resource.h | ||
22 | generic-y += scatterlist.h | ||
23 | generic-y += sections.h | ||
24 | generic-y += siginfo.h | ||
25 | generic-y += statfs.h | ||
26 | generic-y += topology.h | ||
27 | generic-y += types.h | ||
4 | generic-y += word-at-a-time.h | 28 | generic-y += word-at-a-time.h |
29 | generic-y += xor.h | ||
diff --git a/arch/m68k/include/asm/MC68332.h b/arch/m68k/include/asm/MC68332.h deleted file mode 100644 index 6bb8f02685a2..000000000000 --- a/arch/m68k/include/asm/MC68332.h +++ /dev/null | |||
@@ -1,152 +0,0 @@ | |||
1 | |||
2 | /* include/asm-m68knommu/MC68332.h: '332 control registers | ||
3 | * | ||
4 | * Copyright (C) 1998 Kenneth Albanowski <kjahds@kjahds.com>, | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #ifndef _MC68332_H_ | ||
9 | #define _MC68332_H_ | ||
10 | |||
11 | #define BYTE_REF(addr) (*((volatile unsigned char*)addr)) | ||
12 | #define WORD_REF(addr) (*((volatile unsigned short*)addr)) | ||
13 | |||
14 | #define PORTE_ADDR 0xfffa11 | ||
15 | #define PORTE BYTE_REF(PORTE_ADDR) | ||
16 | #define DDRE_ADDR 0xfffa15 | ||
17 | #define DDRE BYTE_REF(DDRE_ADDR) | ||
18 | #define PEPAR_ADDR 0xfffa17 | ||
19 | #define PEPAR BYTE_REF(PEPAR_ADDR) | ||
20 | |||
21 | #define PORTF_ADDR 0xfffa19 | ||
22 | #define PORTF BYTE_REF(PORTF_ADDR) | ||
23 | #define DDRF_ADDR 0xfffa1d | ||
24 | #define DDRF BYTE_REF(DDRF_ADDR) | ||
25 | #define PFPAR_ADDR 0xfffa1f | ||
26 | #define PFPAR BYTE_REF(PFPAR_ADDR) | ||
27 | |||
28 | #define PORTQS_ADDR 0xfffc15 | ||
29 | #define PORTQS BYTE_REF(PORTQS_ADDR) | ||
30 | #define DDRQS_ADDR 0xfffc17 | ||
31 | #define DDRQS BYTE_REF(DDRQS_ADDR) | ||
32 | #define PQSPAR_ADDR 0xfffc16 | ||
33 | #define PQSPAR BYTE_REF(PQSPAR_ADDR) | ||
34 | |||
35 | #define CSPAR0_ADDR 0xFFFA44 | ||
36 | #define CSPAR0 WORD_REF(CSPAR0_ADDR) | ||
37 | #define CSPAR1_ADDR 0xFFFA46 | ||
38 | #define CSPAR1 WORD_REF(CSPAR1_ADDR) | ||
39 | #define CSARBT_ADDR 0xFFFA48 | ||
40 | #define CSARBT WORD_REF(CSARBT_ADDR) | ||
41 | #define CSOPBT_ADDR 0xFFFA4A | ||
42 | #define CSOPBT WORD_REF(CSOPBT_ADDR) | ||
43 | #define CSBAR0_ADDR 0xFFFA4C | ||
44 | #define CSBAR0 WORD_REF(CSBAR0_ADDR) | ||
45 | #define CSOR0_ADDR 0xFFFA4E | ||
46 | #define CSOR0 WORD_REF(CSOR0_ADDR) | ||
47 | #define CSBAR1_ADDR 0xFFFA50 | ||
48 | #define CSBAR1 WORD_REF(CSBAR1_ADDR) | ||
49 | #define CSOR1_ADDR 0xFFFA52 | ||
50 | #define CSOR1 WORD_REF(CSOR1_ADDR) | ||
51 | #define CSBAR2_ADDR 0xFFFA54 | ||
52 | #define CSBAR2 WORD_REF(CSBAR2_ADDR) | ||
53 | #define CSOR2_ADDR 0xFFFA56 | ||
54 | #define CSOR2 WORD_REF(CSOR2_ADDR) | ||
55 | #define CSBAR3_ADDR 0xFFFA58 | ||
56 | #define CSBAR3 WORD_REF(CSBAR3_ADDR) | ||
57 | #define CSOR3_ADDR 0xFFFA5A | ||
58 | #define CSOR3 WORD_REF(CSOR3_ADDR) | ||
59 | #define CSBAR4_ADDR 0xFFFA5C | ||
60 | #define CSBAR4 WORD_REF(CSBAR4_ADDR) | ||
61 | #define CSOR4_ADDR 0xFFFA5E | ||
62 | #define CSOR4 WORD_REF(CSOR4_ADDR) | ||
63 | #define CSBAR5_ADDR 0xFFFA60 | ||
64 | #define CSBAR5 WORD_REF(CSBAR5_ADDR) | ||
65 | #define CSOR5_ADDR 0xFFFA62 | ||
66 | #define CSOR5 WORD_REF(CSOR5_ADDR) | ||
67 | #define CSBAR6_ADDR 0xFFFA64 | ||
68 | #define CSBAR6 WORD_REF(CSBAR6_ADDR) | ||
69 | #define CSOR6_ADDR 0xFFFA66 | ||
70 | #define CSOR6 WORD_REF(CSOR6_ADDR) | ||
71 | #define CSBAR7_ADDR 0xFFFA68 | ||
72 | #define CSBAR7 WORD_REF(CSBAR7_ADDR) | ||
73 | #define CSOR7_ADDR 0xFFFA6A | ||
74 | #define CSOR7 WORD_REF(CSOR7_ADDR) | ||
75 | #define CSBAR8_ADDR 0xFFFA6C | ||
76 | #define CSBAR8 WORD_REF(CSBAR8_ADDR) | ||
77 | #define CSOR8_ADDR 0xFFFA6E | ||
78 | #define CSOR8 WORD_REF(CSOR8_ADDR) | ||
79 | #define CSBAR9_ADDR 0xFFFA70 | ||
80 | #define CSBAR9 WORD_REF(CSBAR9_ADDR) | ||
81 | #define CSOR9_ADDR 0xFFFA72 | ||
82 | #define CSOR9 WORD_REF(CSOR9_ADDR) | ||
83 | #define CSBAR10_ADDR 0xFFFA74 | ||
84 | #define CSBAR10 WORD_REF(CSBAR10_ADDR) | ||
85 | #define CSOR10_ADDR 0xFFFA76 | ||
86 | #define CSOR10 WORD_REF(CSOR10_ADDR) | ||
87 | |||
88 | #define CSOR_MODE_ASYNC 0x0000 | ||
89 | #define CSOR_MODE_SYNC 0x8000 | ||
90 | #define CSOR_MODE_MASK 0x8000 | ||
91 | #define CSOR_BYTE_DISABLE 0x0000 | ||
92 | #define CSOR_BYTE_UPPER 0x4000 | ||
93 | #define CSOR_BYTE_LOWER 0x2000 | ||
94 | #define CSOR_BYTE_BOTH 0x6000 | ||
95 | #define CSOR_BYTE_MASK 0x6000 | ||
96 | #define CSOR_RW_RSVD 0x0000 | ||
97 | #define CSOR_RW_READ 0x0800 | ||
98 | #define CSOR_RW_WRITE 0x1000 | ||
99 | #define CSOR_RW_BOTH 0x1800 | ||
100 | #define CSOR_RW_MASK 0x1800 | ||
101 | #define CSOR_STROBE_DS 0x0400 | ||
102 | #define CSOR_STROBE_AS 0x0000 | ||
103 | #define CSOR_STROBE_MASK 0x0400 | ||
104 | #define CSOR_DSACK_WAIT(x) (wait << 6) | ||
105 | #define CSOR_DSACK_FTERM (14 << 6) | ||
106 | #define CSOR_DSACK_EXTERNAL (15 << 6) | ||
107 | #define CSOR_DSACK_MASK 0x03c0 | ||
108 | #define CSOR_SPACE_CPU 0x0000 | ||
109 | #define CSOR_SPACE_USER 0x0010 | ||
110 | #define CSOR_SPACE_SU 0x0020 | ||
111 | #define CSOR_SPACE_BOTH 0x0030 | ||
112 | #define CSOR_SPACE_MASK 0x0030 | ||
113 | #define CSOR_IPL_ALL 0x0000 | ||
114 | #define CSOR_IPL_PRIORITY(x) (x << 1) | ||
115 | #define CSOR_IPL_MASK 0x000e | ||
116 | #define CSOR_AVEC_ON 0x0001 | ||
117 | #define CSOR_AVEC_OFF 0x0000 | ||
118 | #define CSOR_AVEC_MASK 0x0001 | ||
119 | |||
120 | #define CSBAR_ADDR(x) ((addr >> 11) << 3) | ||
121 | #define CSBAR_ADDR_MASK 0xfff8 | ||
122 | #define CSBAR_BLKSIZE_2K 0x0000 | ||
123 | #define CSBAR_BLKSIZE_8K 0x0001 | ||
124 | #define CSBAR_BLKSIZE_16K 0x0002 | ||
125 | #define CSBAR_BLKSIZE_64K 0x0003 | ||
126 | #define CSBAR_BLKSIZE_128K 0x0004 | ||
127 | #define CSBAR_BLKSIZE_256K 0x0005 | ||
128 | #define CSBAR_BLKSIZE_512K 0x0006 | ||
129 | #define CSBAR_BLKSIZE_1M 0x0007 | ||
130 | #define CSBAR_BLKSIZE_MASK 0x0007 | ||
131 | |||
132 | #define CSPAR_DISC 0 | ||
133 | #define CSPAR_ALT 1 | ||
134 | #define CSPAR_CS8 2 | ||
135 | #define CSPAR_CS16 3 | ||
136 | #define CSPAR_MASK 3 | ||
137 | |||
138 | #define CSPAR0_CSBOOT(x) (x << 0) | ||
139 | #define CSPAR0_CS0(x) (x << 2) | ||
140 | #define CSPAR0_CS1(x) (x << 4) | ||
141 | #define CSPAR0_CS2(x) (x << 6) | ||
142 | #define CSPAR0_CS3(x) (x << 8) | ||
143 | #define CSPAR0_CS4(x) (x << 10) | ||
144 | #define CSPAR0_CS5(x) (x << 12) | ||
145 | |||
146 | #define CSPAR1_CS6(x) (x << 0) | ||
147 | #define CSPAR1_CS7(x) (x << 2) | ||
148 | #define CSPAR1_CS8(x) (x << 4) | ||
149 | #define CSPAR1_CS9(x) (x << 6) | ||
150 | #define CSPAR1_CS10(x) (x << 8) | ||
151 | |||
152 | #endif | ||
diff --git a/arch/m68k/include/asm/apollodma.h b/arch/m68k/include/asm/apollodma.h deleted file mode 100644 index 954adc851adb..000000000000 --- a/arch/m68k/include/asm/apollodma.h +++ /dev/null | |||
@@ -1,248 +0,0 @@ | |||
1 | /* | ||
2 | * linux/include/asm/dma.h: Defines for using and allocating dma channels. | ||
3 | * Written by Hennus Bergman, 1992. | ||
4 | * High DMA channel support & info by Hannu Savolainen | ||
5 | * and John Boyd, Nov. 1992. | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_APOLLO_DMA_H | ||
9 | #define _ASM_APOLLO_DMA_H | ||
10 | |||
11 | #include <asm/apollohw.h> /* need byte IO */ | ||
12 | #include <linux/spinlock.h> /* And spinlocks */ | ||
13 | #include <linux/delay.h> | ||
14 | |||
15 | |||
16 | #define dma_outb(val,addr) (*((volatile unsigned char *)(addr+IO_BASE)) = (val)) | ||
17 | #define dma_inb(addr) (*((volatile unsigned char *)(addr+IO_BASE))) | ||
18 | |||
19 | /* | ||
20 | * NOTES about DMA transfers: | ||
21 | * | ||
22 | * controller 1: channels 0-3, byte operations, ports 00-1F | ||
23 | * controller 2: channels 4-7, word operations, ports C0-DF | ||
24 | * | ||
25 | * - ALL registers are 8 bits only, regardless of transfer size | ||
26 | * - channel 4 is not used - cascades 1 into 2. | ||
27 | * - channels 0-3 are byte - addresses/counts are for physical bytes | ||
28 | * - channels 5-7 are word - addresses/counts are for physical words | ||
29 | * - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries | ||
30 | * - transfer count loaded to registers is 1 less than actual count | ||
31 | * - controller 2 offsets are all even (2x offsets for controller 1) | ||
32 | * - page registers for 5-7 don't use data bit 0, represent 128K pages | ||
33 | * - page registers for 0-3 use bit 0, represent 64K pages | ||
34 | * | ||
35 | * DMA transfers are limited to the lower 16MB of _physical_ memory. | ||
36 | * Note that addresses loaded into registers must be _physical_ addresses, | ||
37 | * not logical addresses (which may differ if paging is active). | ||
38 | * | ||
39 | * Address mapping for channels 0-3: | ||
40 | * | ||
41 | * A23 ... A16 A15 ... A8 A7 ... A0 (Physical addresses) | ||
42 | * | ... | | ... | | ... | | ||
43 | * | ... | | ... | | ... | | ||
44 | * | ... | | ... | | ... | | ||
45 | * P7 ... P0 A7 ... A0 A7 ... A0 | ||
46 | * | Page | Addr MSB | Addr LSB | (DMA registers) | ||
47 | * | ||
48 | * Address mapping for channels 5-7: | ||
49 | * | ||
50 | * A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0 (Physical addresses) | ||
51 | * | ... | \ \ ... \ \ \ ... \ \ | ||
52 | * | ... | \ \ ... \ \ \ ... \ (not used) | ||
53 | * | ... | \ \ ... \ \ \ ... \ | ||
54 | * P7 ... P1 (0) A7 A6 ... A0 A7 A6 ... A0 | ||
55 | * | Page | Addr MSB | Addr LSB | (DMA registers) | ||
56 | * | ||
57 | * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses | ||
58 | * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at | ||
59 | * the hardware level, so odd-byte transfers aren't possible). | ||
60 | * | ||
61 | * Transfer count (_not # bytes_) is limited to 64K, represented as actual | ||
62 | * count - 1 : 64K => 0xFFFF, 1 => 0x0000. Thus, count is always 1 or more, | ||
63 | * and up to 128K bytes may be transferred on channels 5-7 in one operation. | ||
64 | * | ||
65 | */ | ||
66 | |||
67 | #define MAX_DMA_CHANNELS 8 | ||
68 | |||
69 | /* The maximum address that we can perform a DMA transfer to on this platform */#define MAX_DMA_ADDRESS (PAGE_OFFSET+0x1000000) | ||
70 | |||
71 | /* 8237 DMA controllers */ | ||
72 | #define IO_DMA1_BASE 0x10C00 /* 8 bit slave DMA, channels 0..3 */ | ||
73 | #define IO_DMA2_BASE 0x10D00 /* 16 bit master DMA, ch 4(=slave input)..7 */ | ||
74 | |||
75 | /* DMA controller registers */ | ||
76 | #define DMA1_CMD_REG (IO_DMA1_BASE+0x08) /* command register (w) */ | ||
77 | #define DMA1_STAT_REG (IO_DMA1_BASE+0x08) /* status register (r) */ | ||
78 | #define DMA1_REQ_REG (IO_DMA1_BASE+0x09) /* request register (w) */ | ||
79 | #define DMA1_MASK_REG (IO_DMA1_BASE+0x0A) /* single-channel mask (w) */ | ||
80 | #define DMA1_MODE_REG (IO_DMA1_BASE+0x0B) /* mode register (w) */ | ||
81 | #define DMA1_CLEAR_FF_REG (IO_DMA1_BASE+0x0C) /* clear pointer flip-flop (w) */ | ||
82 | #define DMA1_TEMP_REG (IO_DMA1_BASE+0x0D) /* Temporary Register (r) */ | ||
83 | #define DMA1_RESET_REG (IO_DMA1_BASE+0x0D) /* Master Clear (w) */ | ||
84 | #define DMA1_CLR_MASK_REG (IO_DMA1_BASE+0x0E) /* Clear Mask */ | ||
85 | #define DMA1_MASK_ALL_REG (IO_DMA1_BASE+0x0F) /* all-channels mask (w) */ | ||
86 | |||
87 | #define DMA2_CMD_REG (IO_DMA2_BASE+0x10) /* command register (w) */ | ||
88 | #define DMA2_STAT_REG (IO_DMA2_BASE+0x10) /* status register (r) */ | ||
89 | #define DMA2_REQ_REG (IO_DMA2_BASE+0x12) /* request register (w) */ | ||
90 | #define DMA2_MASK_REG (IO_DMA2_BASE+0x14) /* single-channel mask (w) */ | ||
91 | #define DMA2_MODE_REG (IO_DMA2_BASE+0x16) /* mode register (w) */ | ||
92 | #define DMA2_CLEAR_FF_REG (IO_DMA2_BASE+0x18) /* clear pointer flip-flop (w) */ | ||
93 | #define DMA2_TEMP_REG (IO_DMA2_BASE+0x1A) /* Temporary Register (r) */ | ||
94 | #define DMA2_RESET_REG (IO_DMA2_BASE+0x1A) /* Master Clear (w) */ | ||
95 | #define DMA2_CLR_MASK_REG (IO_DMA2_BASE+0x1C) /* Clear Mask */ | ||
96 | #define DMA2_MASK_ALL_REG (IO_DMA2_BASE+0x1E) /* all-channels mask (w) */ | ||
97 | |||
98 | #define DMA_ADDR_0 (IO_DMA1_BASE+0x00) /* DMA address registers */ | ||
99 | #define DMA_ADDR_1 (IO_DMA1_BASE+0x02) | ||
100 | #define DMA_ADDR_2 (IO_DMA1_BASE+0x04) | ||
101 | #define DMA_ADDR_3 (IO_DMA1_BASE+0x06) | ||
102 | #define DMA_ADDR_4 (IO_DMA2_BASE+0x00) | ||
103 | #define DMA_ADDR_5 (IO_DMA2_BASE+0x04) | ||
104 | #define DMA_ADDR_6 (IO_DMA2_BASE+0x08) | ||
105 | #define DMA_ADDR_7 (IO_DMA2_BASE+0x0C) | ||
106 | |||
107 | #define DMA_CNT_0 (IO_DMA1_BASE+0x01) /* DMA count registers */ | ||
108 | #define DMA_CNT_1 (IO_DMA1_BASE+0x03) | ||
109 | #define DMA_CNT_2 (IO_DMA1_BASE+0x05) | ||
110 | #define DMA_CNT_3 (IO_DMA1_BASE+0x07) | ||
111 | #define DMA_CNT_4 (IO_DMA2_BASE+0x02) | ||
112 | #define DMA_CNT_5 (IO_DMA2_BASE+0x06) | ||
113 | #define DMA_CNT_6 (IO_DMA2_BASE+0x0A) | ||
114 | #define DMA_CNT_7 (IO_DMA2_BASE+0x0E) | ||
115 | |||
116 | #define DMA_MODE_READ 0x44 /* I/O to memory, no autoinit, increment, single mode */ | ||
117 | #define DMA_MODE_WRITE 0x48 /* memory to I/O, no autoinit, increment, single mode */ | ||
118 | #define DMA_MODE_CASCADE 0xC0 /* pass thru DREQ->HRQ, DACK<-HLDA only */ | ||
119 | |||
120 | #define DMA_AUTOINIT 0x10 | ||
121 | |||
122 | #define DMA_8BIT 0 | ||
123 | #define DMA_16BIT 1 | ||
124 | #define DMA_BUSMASTER 2 | ||
125 | |||
126 | extern spinlock_t dma_spin_lock; | ||
127 | |||
128 | static __inline__ unsigned long claim_dma_lock(void) | ||
129 | { | ||
130 | unsigned long flags; | ||
131 | spin_lock_irqsave(&dma_spin_lock, flags); | ||
132 | return flags; | ||
133 | } | ||
134 | |||
135 | static __inline__ void release_dma_lock(unsigned long flags) | ||
136 | { | ||
137 | spin_unlock_irqrestore(&dma_spin_lock, flags); | ||
138 | } | ||
139 | |||
140 | /* enable/disable a specific DMA channel */ | ||
141 | static __inline__ void enable_dma(unsigned int dmanr) | ||
142 | { | ||
143 | if (dmanr<=3) | ||
144 | dma_outb(dmanr, DMA1_MASK_REG); | ||
145 | else | ||
146 | dma_outb(dmanr & 3, DMA2_MASK_REG); | ||
147 | } | ||
148 | |||
149 | static __inline__ void disable_dma(unsigned int dmanr) | ||
150 | { | ||
151 | if (dmanr<=3) | ||
152 | dma_outb(dmanr | 4, DMA1_MASK_REG); | ||
153 | else | ||
154 | dma_outb((dmanr & 3) | 4, DMA2_MASK_REG); | ||
155 | } | ||
156 | |||
157 | /* Clear the 'DMA Pointer Flip Flop'. | ||
158 | * Write 0 for LSB/MSB, 1 for MSB/LSB access. | ||
159 | * Use this once to initialize the FF to a known state. | ||
160 | * After that, keep track of it. :-) | ||
161 | * --- In order to do that, the DMA routines below should --- | ||
162 | * --- only be used while holding the DMA lock ! --- | ||
163 | */ | ||
164 | static __inline__ void clear_dma_ff(unsigned int dmanr) | ||
165 | { | ||
166 | if (dmanr<=3) | ||
167 | dma_outb(0, DMA1_CLEAR_FF_REG); | ||
168 | else | ||
169 | dma_outb(0, DMA2_CLEAR_FF_REG); | ||
170 | } | ||
171 | |||
172 | /* set mode (above) for a specific DMA channel */ | ||
173 | static __inline__ void set_dma_mode(unsigned int dmanr, char mode) | ||
174 | { | ||
175 | if (dmanr<=3) | ||
176 | dma_outb(mode | dmanr, DMA1_MODE_REG); | ||
177 | else | ||
178 | dma_outb(mode | (dmanr&3), DMA2_MODE_REG); | ||
179 | } | ||
180 | |||
181 | /* Set transfer address & page bits for specific DMA channel. | ||
182 | * Assumes dma flipflop is clear. | ||
183 | */ | ||
184 | static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a) | ||
185 | { | ||
186 | if (dmanr <= 3) { | ||
187 | dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); | ||
188 | dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE ); | ||
189 | } else { | ||
190 | dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); | ||
191 | dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE ); | ||
192 | } | ||
193 | } | ||
194 | |||
195 | |||
196 | /* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for | ||
197 | * a specific DMA channel. | ||
198 | * You must ensure the parameters are valid. | ||
199 | * NOTE: from a manual: "the number of transfers is one more | ||
200 | * than the initial word count"! This is taken into account. | ||
201 | * Assumes dma flip-flop is clear. | ||
202 | * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7. | ||
203 | */ | ||
204 | static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count) | ||
205 | { | ||
206 | count--; | ||
207 | if (dmanr <= 3) { | ||
208 | dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); | ||
209 | dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE ); | ||
210 | } else { | ||
211 | dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); | ||
212 | dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE ); | ||
213 | } | ||
214 | } | ||
215 | |||
216 | |||
217 | /* Get DMA residue count. After a DMA transfer, this | ||
218 | * should return zero. Reading this while a DMA transfer is | ||
219 | * still in progress will return unpredictable results. | ||
220 | * If called before the channel has been used, it may return 1. | ||
221 | * Otherwise, it returns the number of _bytes_ left to transfer. | ||
222 | * | ||
223 | * Assumes DMA flip-flop is clear. | ||
224 | */ | ||
225 | static __inline__ int get_dma_residue(unsigned int dmanr) | ||
226 | { | ||
227 | unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE | ||
228 | : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE; | ||
229 | |||
230 | /* using short to get 16-bit wrap around */ | ||
231 | unsigned short count; | ||
232 | |||
233 | count = 1 + dma_inb(io_port); | ||
234 | count += dma_inb(io_port) << 8; | ||
235 | |||
236 | return (dmanr<=3)? count : (count<<1); | ||
237 | } | ||
238 | |||
239 | |||
240 | /* These are in kernel/dma.c: */ | ||
241 | extern int request_dma(unsigned int dmanr, const char * device_id); /* reserve a DMA channel */ | ||
242 | extern void free_dma(unsigned int dmanr); /* release it again */ | ||
243 | |||
244 | /* These are in arch/m68k/apollo/dma.c: */ | ||
245 | extern unsigned short dma_map_page(unsigned long phys_addr,int count,int type); | ||
246 | extern void dma_unmap_page(unsigned short dma_addr); | ||
247 | |||
248 | #endif /* _ASM_APOLLO_DMA_H */ | ||
diff --git a/arch/m68k/include/asm/apollohw.h b/arch/m68k/include/asm/apollohw.h index a1373b9aa281..635ef4f89010 100644 --- a/arch/m68k/include/asm/apollohw.h +++ b/arch/m68k/include/asm/apollohw.h | |||
@@ -98,7 +98,7 @@ extern u_long timer_physaddr; | |||
98 | #define cpuctrl (*(volatile unsigned int *)(IO_BASE + cpuctrl_physaddr)) | 98 | #define cpuctrl (*(volatile unsigned int *)(IO_BASE + cpuctrl_physaddr)) |
99 | #define pica (IO_BASE + pica_physaddr) | 99 | #define pica (IO_BASE + pica_physaddr) |
100 | #define picb (IO_BASE + picb_physaddr) | 100 | #define picb (IO_BASE + picb_physaddr) |
101 | #define timer (IO_BASE + timer_physaddr) | 101 | #define apollo_timer (IO_BASE + timer_physaddr) |
102 | #define addr_xlat_map ((unsigned short *)(IO_BASE + 0x17000)) | 102 | #define addr_xlat_map ((unsigned short *)(IO_BASE + 0x17000)) |
103 | 103 | ||
104 | #define isaIO2mem(x) (((((x) & 0x3f8) << 7) | (((x) & 0xfc00) >> 6) | ((x) & 0x7)) + 0x40000 + IO_BASE) | 104 | #define isaIO2mem(x) (((((x) & 0x3f8) << 7) | (((x) & 0xfc00) >> 6) | ((x) & 0x7)) + 0x40000 + IO_BASE) |
diff --git a/arch/m68k/include/asm/bitsperlong.h b/arch/m68k/include/asm/bitsperlong.h deleted file mode 100644 index 6dc0bb0c13b2..000000000000 --- a/arch/m68k/include/asm/bitsperlong.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <asm-generic/bitsperlong.h> | ||
diff --git a/arch/m68k/include/asm/cputime.h b/arch/m68k/include/asm/cputime.h deleted file mode 100644 index c79c5e892305..000000000000 --- a/arch/m68k/include/asm/cputime.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef __M68K_CPUTIME_H | ||
2 | #define __M68K_CPUTIME_H | ||
3 | |||
4 | #include <asm-generic/cputime.h> | ||
5 | |||
6 | #endif /* __M68K_CPUTIME_H */ | ||
diff --git a/arch/m68k/include/asm/delay.h b/arch/m68k/include/asm/delay.h index 9c09becfd4c9..12d8fe4f1d30 100644 --- a/arch/m68k/include/asm/delay.h +++ b/arch/m68k/include/asm/delay.h | |||
@@ -43,7 +43,7 @@ static inline void __delay(unsigned long loops) | |||
43 | extern void __bad_udelay(void); | 43 | extern void __bad_udelay(void); |
44 | 44 | ||
45 | 45 | ||
46 | #if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE) | 46 | #ifdef CONFIG_CPU_HAS_NO_MULDIV64 |
47 | /* | 47 | /* |
48 | * The simpler m68k and ColdFire processors do not have a 32*32->64 | 48 | * The simpler m68k and ColdFire processors do not have a 32*32->64 |
49 | * multiply instruction. So we need to handle them a little differently. | 49 | * multiply instruction. So we need to handle them a little differently. |
diff --git a/arch/m68k/include/asm/device.h b/arch/m68k/include/asm/device.h deleted file mode 100644 index d8f9872b0e2d..000000000000 --- a/arch/m68k/include/asm/device.h +++ /dev/null | |||
@@ -1,7 +0,0 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/arch/m68k/include/asm/emergency-restart.h b/arch/m68k/include/asm/emergency-restart.h deleted file mode 100644 index 108d8c48e42e..000000000000 --- a/arch/m68k/include/asm/emergency-restart.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef _ASM_EMERGENCY_RESTART_H | ||
2 | #define _ASM_EMERGENCY_RESTART_H | ||
3 | |||
4 | #include <asm-generic/emergency-restart.h> | ||
5 | |||
6 | #endif /* _ASM_EMERGENCY_RESTART_H */ | ||
diff --git a/arch/m68k/include/asm/errno.h b/arch/m68k/include/asm/errno.h deleted file mode 100644 index 0d4e188d6ef6..000000000000 --- a/arch/m68k/include/asm/errno.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef _M68K_ERRNO_H | ||
2 | #define _M68K_ERRNO_H | ||
3 | |||
4 | #include <asm-generic/errno.h> | ||
5 | |||
6 | #endif /* _M68K_ERRNO_H */ | ||
diff --git a/arch/m68k/include/asm/futex.h b/arch/m68k/include/asm/futex.h deleted file mode 100644 index 6a332a9f099c..000000000000 --- a/arch/m68k/include/asm/futex.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef _ASM_FUTEX_H | ||
2 | #define _ASM_FUTEX_H | ||
3 | |||
4 | #include <asm-generic/futex.h> | ||
5 | |||
6 | #endif | ||
diff --git a/arch/m68k/include/asm/ioctl.h b/arch/m68k/include/asm/ioctl.h deleted file mode 100644 index b279fe06dfe5..000000000000 --- a/arch/m68k/include/asm/ioctl.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <asm-generic/ioctl.h> | ||
diff --git a/arch/m68k/include/asm/ipcbuf.h b/arch/m68k/include/asm/ipcbuf.h deleted file mode 100644 index 84c7e51cb6d0..000000000000 --- a/arch/m68k/include/asm/ipcbuf.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <asm-generic/ipcbuf.h> | ||
diff --git a/arch/m68k/include/asm/irq_regs.h b/arch/m68k/include/asm/irq_regs.h deleted file mode 100644 index 3dd9c0b70270..000000000000 --- a/arch/m68k/include/asm/irq_regs.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <asm-generic/irq_regs.h> | ||
diff --git a/arch/m68k/include/asm/kdebug.h b/arch/m68k/include/asm/kdebug.h deleted file mode 100644 index 6ece1b037665..000000000000 --- a/arch/m68k/include/asm/kdebug.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <asm-generic/kdebug.h> | ||
diff --git a/arch/m68k/include/asm/kmap_types.h b/arch/m68k/include/asm/kmap_types.h deleted file mode 100644 index 3413cc1390ec..000000000000 --- a/arch/m68k/include/asm/kmap_types.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef __ASM_M68K_KMAP_TYPES_H | ||
2 | #define __ASM_M68K_KMAP_TYPES_H | ||
3 | |||
4 | #include <asm-generic/kmap_types.h> | ||
5 | |||
6 | #endif /* __ASM_M68K_KMAP_TYPES_H */ | ||
diff --git a/arch/m68k/include/asm/kvm_para.h b/arch/m68k/include/asm/kvm_para.h deleted file mode 100644 index 14fab8f0b957..000000000000 --- a/arch/m68k/include/asm/kvm_para.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <asm-generic/kvm_para.h> | ||
diff --git a/arch/m68k/include/asm/local.h b/arch/m68k/include/asm/local.h deleted file mode 100644 index 6c259263e1f0..000000000000 --- a/arch/m68k/include/asm/local.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef _ASM_M68K_LOCAL_H | ||
2 | #define _ASM_M68K_LOCAL_H | ||
3 | |||
4 | #include <asm-generic/local.h> | ||
5 | |||
6 | #endif /* _ASM_M68K_LOCAL_H */ | ||
diff --git a/arch/m68k/include/asm/local64.h b/arch/m68k/include/asm/local64.h deleted file mode 100644 index 36c93b5cc239..000000000000 --- a/arch/m68k/include/asm/local64.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <asm-generic/local64.h> | ||
diff --git a/arch/m68k/include/asm/mac_mouse.h b/arch/m68k/include/asm/mac_mouse.h deleted file mode 100644 index 39a5c292eaee..000000000000 --- a/arch/m68k/include/asm/mac_mouse.h +++ /dev/null | |||
@@ -1,23 +0,0 @@ | |||
1 | #ifndef _ASM_MAC_MOUSE_H | ||
2 | #define _ASM_MAC_MOUSE_H | ||
3 | |||
4 | /* | ||
5 | * linux/include/asm-m68k/mac_mouse.h | ||
6 | * header file for Macintosh ADB mouse driver | ||
7 | * 27-10-97 Michael Schmitz | ||
8 | * copied from: | ||
9 | * header file for Atari Mouse driver | ||
10 | * by Robert de Vries (robert@and.nl) on 19Jul93 | ||
11 | */ | ||
12 | |||
13 | struct mouse_status { | ||
14 | char buttons; | ||
15 | short dx; | ||
16 | short dy; | ||
17 | int ready; | ||
18 | int active; | ||
19 | wait_queue_head_t wait; | ||
20 | struct fasync_struct *fasyncptr; | ||
21 | }; | ||
22 | |||
23 | #endif | ||
diff --git a/arch/m68k/include/asm/mcfmbus.h b/arch/m68k/include/asm/mcfmbus.h deleted file mode 100644 index 319899c47a2c..000000000000 --- a/arch/m68k/include/asm/mcfmbus.h +++ /dev/null | |||
@@ -1,77 +0,0 @@ | |||
1 | /****************************************************************************/ | ||
2 | |||
3 | /* | ||
4 | * mcfmbus.h -- Coldfire MBUS support defines. | ||
5 | * | ||
6 | * (C) Copyright 1999, Martin Floeer (mfloeer@axcent.de) | ||
7 | */ | ||
8 | |||
9 | /****************************************************************************/ | ||
10 | |||
11 | |||
12 | #ifndef mcfmbus_h | ||
13 | #define mcfmbus_h | ||
14 | |||
15 | |||
16 | #define MCFMBUS_BASE 0x280 | ||
17 | #define MCFMBUS_IRQ_VECTOR 0x19 | ||
18 | #define MCFMBUS_IRQ 0x1 | ||
19 | #define MCFMBUS_CLK 0x3f | ||
20 | #define MCFMBUS_IRQ_LEVEL 0x07 /*IRQ Level 1*/ | ||
21 | #define MCFMBUS_ADDRESS 0x01 | ||
22 | |||
23 | |||
24 | /* | ||
25 | * Define the 5307 MBUS register set addresses | ||
26 | */ | ||
27 | |||
28 | #define MCFMBUS_MADR 0x00 | ||
29 | #define MCFMBUS_MFDR 0x04 | ||
30 | #define MCFMBUS_MBCR 0x08 | ||
31 | #define MCFMBUS_MBSR 0x0C | ||
32 | #define MCFMBUS_MBDR 0x10 | ||
33 | |||
34 | |||
35 | #define MCFMBUS_MADR_ADDR(a) (((a)&0x7F)<<0x01) /*Slave Address*/ | ||
36 | |||
37 | #define MCFMBUS_MFDR_MBC(a) ((a)&0x3F) /*M-Bus Clock*/ | ||
38 | |||
39 | /* | ||
40 | * Define bit flags in Control Register | ||
41 | */ | ||
42 | |||
43 | #define MCFMBUS_MBCR_MEN (0x80) /* M-Bus Enable */ | ||
44 | #define MCFMBUS_MBCR_MIEN (0x40) /* M-Bus Interrupt Enable */ | ||
45 | #define MCFMBUS_MBCR_MSTA (0x20) /* Master/Slave Mode Select Bit */ | ||
46 | #define MCFMBUS_MBCR_MTX (0x10) /* Transmit/Rcv Mode Select Bit */ | ||
47 | #define MCFMBUS_MBCR_TXAK (0x08) /* Transmit Acknowledge Enable */ | ||
48 | #define MCFMBUS_MBCR_RSTA (0x04) /* Repeat Start */ | ||
49 | |||
50 | /* | ||
51 | * Define bit flags in Status Register | ||
52 | */ | ||
53 | |||
54 | #define MCFMBUS_MBSR_MCF (0x80) /* Data Transfer Complete */ | ||
55 | #define MCFMBUS_MBSR_MAAS (0x40) /* Addressed as a Slave */ | ||
56 | #define MCFMBUS_MBSR_MBB (0x20) /* Bus Busy */ | ||
57 | #define MCFMBUS_MBSR_MAL (0x10) /* Arbitration Lost */ | ||
58 | #define MCFMBUS_MBSR_SRW (0x04) /* Slave Transmit */ | ||
59 | #define MCFMBUS_MBSR_MIF (0x02) /* M-Bus Interrupt */ | ||
60 | #define MCFMBUS_MBSR_RXAK (0x01) /* No Acknowledge Received */ | ||
61 | |||
62 | /* | ||
63 | * Define bit flags in DATA I/O Register | ||
64 | */ | ||
65 | |||
66 | #define MCFMBUS_MBDR_READ (0x01) /* 1=read 0=write MBUS */ | ||
67 | |||
68 | #define MBUSIOCSCLOCK 1 | ||
69 | #define MBUSIOCGCLOCK 2 | ||
70 | #define MBUSIOCSADDR 3 | ||
71 | #define MBUSIOCGADDR 4 | ||
72 | #define MBUSIOCSSLADDR 5 | ||
73 | #define MBUSIOCGSLADDR 6 | ||
74 | #define MBUSIOCSSUBADDR 7 | ||
75 | #define MBUSIOCGSUBADDR 8 | ||
76 | |||
77 | #endif | ||
diff --git a/arch/m68k/include/asm/mman.h b/arch/m68k/include/asm/mman.h deleted file mode 100644 index 8eebf89f5ab1..000000000000 --- a/arch/m68k/include/asm/mman.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <asm-generic/mman.h> | ||
diff --git a/arch/m68k/include/asm/mutex.h b/arch/m68k/include/asm/mutex.h deleted file mode 100644 index 458c1f7fbc18..000000000000 --- a/arch/m68k/include/asm/mutex.h +++ /dev/null | |||
@@ -1,9 +0,0 @@ | |||
1 | /* | ||
2 | * Pull in the generic implementation for the mutex fastpath. | ||
3 | * | ||
4 | * TODO: implement optimized primitives instead, or leave the generic | ||
5 | * implementation in place, or pick the atomic_xchg() based generic | ||
6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
7 | */ | ||
8 | |||
9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/arch/m68k/include/asm/percpu.h b/arch/m68k/include/asm/percpu.h deleted file mode 100644 index 0859d048faf5..000000000000 --- a/arch/m68k/include/asm/percpu.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef __ASM_M68K_PERCPU_H | ||
2 | #define __ASM_M68K_PERCPU_H | ||
3 | |||
4 | #include <asm-generic/percpu.h> | ||
5 | |||
6 | #endif /* __ASM_M68K_PERCPU_H */ | ||
diff --git a/arch/m68k/include/asm/resource.h b/arch/m68k/include/asm/resource.h deleted file mode 100644 index e7d35019f337..000000000000 --- a/arch/m68k/include/asm/resource.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef _M68K_RESOURCE_H | ||
2 | #define _M68K_RESOURCE_H | ||
3 | |||
4 | #include <asm-generic/resource.h> | ||
5 | |||
6 | #endif /* _M68K_RESOURCE_H */ | ||
diff --git a/arch/m68k/include/asm/sbus.h b/arch/m68k/include/asm/sbus.h deleted file mode 100644 index bfe3ba147f2e..000000000000 --- a/arch/m68k/include/asm/sbus.h +++ /dev/null | |||
@@ -1,45 +0,0 @@ | |||
1 | /* | ||
2 | * some sbus structures and macros to make usage of sbus drivers possible | ||
3 | */ | ||
4 | |||
5 | #ifndef __M68K_SBUS_H | ||
6 | #define __M68K_SBUS_H | ||
7 | |||
8 | struct sbus_dev { | ||
9 | struct { | ||
10 | unsigned int which_io; | ||
11 | unsigned int phys_addr; | ||
12 | } reg_addrs[1]; | ||
13 | }; | ||
14 | |||
15 | /* sbus IO functions stolen from include/asm-sparc/io.h for the serial driver */ | ||
16 | /* No SBUS on the Sun3, kludge -- sam */ | ||
17 | |||
18 | static inline void _sbus_writeb(unsigned char val, unsigned long addr) | ||
19 | { | ||
20 | *(volatile unsigned char *)addr = val; | ||
21 | } | ||
22 | |||
23 | static inline unsigned char _sbus_readb(unsigned long addr) | ||
24 | { | ||
25 | return *(volatile unsigned char *)addr; | ||
26 | } | ||
27 | |||
28 | static inline void _sbus_writel(unsigned long val, unsigned long addr) | ||
29 | { | ||
30 | *(volatile unsigned long *)addr = val; | ||
31 | |||
32 | } | ||
33 | |||
34 | extern inline unsigned long _sbus_readl(unsigned long addr) | ||
35 | { | ||
36 | return *(volatile unsigned long *)addr; | ||
37 | } | ||
38 | |||
39 | |||
40 | #define sbus_readb(a) _sbus_readb((unsigned long)a) | ||
41 | #define sbus_writeb(v, a) _sbus_writeb(v, (unsigned long)a) | ||
42 | #define sbus_readl(a) _sbus_readl((unsigned long)a) | ||
43 | #define sbus_writel(v, a) _sbus_writel(v, (unsigned long)a) | ||
44 | |||
45 | #endif | ||
diff --git a/arch/m68k/include/asm/scatterlist.h b/arch/m68k/include/asm/scatterlist.h deleted file mode 100644 index 312505452a1e..000000000000 --- a/arch/m68k/include/asm/scatterlist.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef _M68K_SCATTERLIST_H | ||
2 | #define _M68K_SCATTERLIST_H | ||
3 | |||
4 | #include <asm-generic/scatterlist.h> | ||
5 | |||
6 | #endif /* !(_M68K_SCATTERLIST_H) */ | ||
diff --git a/arch/m68k/include/asm/sections.h b/arch/m68k/include/asm/sections.h deleted file mode 100644 index 5277e52715ec..000000000000 --- a/arch/m68k/include/asm/sections.h +++ /dev/null | |||
@@ -1,8 +0,0 @@ | |||
1 | #ifndef _ASM_M68K_SECTIONS_H | ||
2 | #define _ASM_M68K_SECTIONS_H | ||
3 | |||
4 | #include <asm-generic/sections.h> | ||
5 | |||
6 | extern char _sbss[], _ebss[]; | ||
7 | |||
8 | #endif /* _ASM_M68K_SECTIONS_H */ | ||
diff --git a/arch/m68k/include/asm/shm.h b/arch/m68k/include/asm/shm.h deleted file mode 100644 index fa56ec84a126..000000000000 --- a/arch/m68k/include/asm/shm.h +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | #ifndef _M68K_SHM_H | ||
2 | #define _M68K_SHM_H | ||
3 | |||
4 | |||
5 | /* format of page table entries that correspond to shared memory pages | ||
6 | currently out in swap space (see also mm/swap.c): | ||
7 | bits 0-1 (PAGE_PRESENT) is = 0 | ||
8 | bits 8..2 (SWP_TYPE) are = SHM_SWP_TYPE | ||
9 | bits 31..9 are used like this: | ||
10 | bits 15..9 (SHM_ID) the id of the shared memory segment | ||
11 | bits 30..16 (SHM_IDX) the index of the page within the shared memory segment | ||
12 | (actually only bits 25..16 get used since SHMMAX is so low) | ||
13 | bit 31 (SHM_READ_ONLY) flag whether the page belongs to a read-only attach | ||
14 | */ | ||
15 | /* on the m68k both bits 0 and 1 must be zero */ | ||
16 | /* format on the sun3 is similar, but bits 30, 31 are set to zero and all | ||
17 | others are reduced by 2. --m */ | ||
18 | |||
19 | #ifndef CONFIG_SUN3 | ||
20 | #define SHM_ID_SHIFT 9 | ||
21 | #else | ||
22 | #define SHM_ID_SHIFT 7 | ||
23 | #endif | ||
24 | #define _SHM_ID_BITS 7 | ||
25 | #define SHM_ID_MASK ((1<<_SHM_ID_BITS)-1) | ||
26 | |||
27 | #define SHM_IDX_SHIFT (SHM_ID_SHIFT+_SHM_ID_BITS) | ||
28 | #define _SHM_IDX_BITS 15 | ||
29 | #define SHM_IDX_MASK ((1<<_SHM_IDX_BITS)-1) | ||
30 | |||
31 | #endif /* _M68K_SHM_H */ | ||
diff --git a/arch/m68k/include/asm/siginfo.h b/arch/m68k/include/asm/siginfo.h deleted file mode 100644 index 851d3d784b53..000000000000 --- a/arch/m68k/include/asm/siginfo.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef _M68K_SIGINFO_H | ||
2 | #define _M68K_SIGINFO_H | ||
3 | |||
4 | #include <asm-generic/siginfo.h> | ||
5 | |||
6 | #endif | ||
diff --git a/arch/m68k/include/asm/statfs.h b/arch/m68k/include/asm/statfs.h deleted file mode 100644 index 08d93f14e061..000000000000 --- a/arch/m68k/include/asm/statfs.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef _M68K_STATFS_H | ||
2 | #define _M68K_STATFS_H | ||
3 | |||
4 | #include <asm-generic/statfs.h> | ||
5 | |||
6 | #endif /* _M68K_STATFS_H */ | ||
diff --git a/arch/m68k/include/asm/topology.h b/arch/m68k/include/asm/topology.h deleted file mode 100644 index ca173e9f26ff..000000000000 --- a/arch/m68k/include/asm/topology.h +++ /dev/null | |||
@@ -1,6 +0,0 @@ | |||
1 | #ifndef _ASM_M68K_TOPOLOGY_H | ||
2 | #define _ASM_M68K_TOPOLOGY_H | ||
3 | |||
4 | #include <asm-generic/topology.h> | ||
5 | |||
6 | #endif /* _ASM_M68K_TOPOLOGY_H */ | ||
diff --git a/arch/m68k/include/asm/types.h b/arch/m68k/include/asm/types.h deleted file mode 100644 index 89705adcbd52..000000000000 --- a/arch/m68k/include/asm/types.h +++ /dev/null | |||
@@ -1,22 +0,0 @@ | |||
1 | #ifndef _M68K_TYPES_H | ||
2 | #define _M68K_TYPES_H | ||
3 | |||
4 | /* | ||
5 | * This file is never included by application software unless | ||
6 | * explicitly requested (e.g., via linux/types.h) in which case the | ||
7 | * application is Linux specific so (user-) name space pollution is | ||
8 | * not a major issue. However, for interoperability, libraries still | ||
9 | * need to be careful to avoid a name clashes. | ||
10 | */ | ||
11 | #include <asm-generic/int-ll64.h> | ||
12 | |||
13 | /* | ||
14 | * These aren't exported outside the kernel to avoid name space clashes | ||
15 | */ | ||
16 | #ifdef __KERNEL__ | ||
17 | |||
18 | #define BITS_PER_LONG 32 | ||
19 | |||
20 | #endif /* __KERNEL__ */ | ||
21 | |||
22 | #endif /* _M68K_TYPES_H */ | ||
diff --git a/arch/m68k/include/asm/unaligned.h b/arch/m68k/include/asm/unaligned.h index f4043ae63db1..2b3ca0bf7a0d 100644 --- a/arch/m68k/include/asm/unaligned.h +++ b/arch/m68k/include/asm/unaligned.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #define _ASM_M68K_UNALIGNED_H | 2 | #define _ASM_M68K_UNALIGNED_H |
3 | 3 | ||
4 | 4 | ||
5 | #if defined(CONFIG_COLDFIRE) || defined(CONFIG_M68000) | 5 | #ifdef CONFIG_CPU_HAS_NO_UNALIGNED |
6 | #include <linux/unaligned/be_struct.h> | 6 | #include <linux/unaligned/be_struct.h> |
7 | #include <linux/unaligned/le_byteshift.h> | 7 | #include <linux/unaligned/le_byteshift.h> |
8 | #include <linux/unaligned/generic.h> | 8 | #include <linux/unaligned/generic.h> |
@@ -12,7 +12,7 @@ | |||
12 | 12 | ||
13 | #else | 13 | #else |
14 | /* | 14 | /* |
15 | * The m68k can do unaligned accesses itself. | 15 | * The m68k can do unaligned accesses itself. |
16 | */ | 16 | */ |
17 | #include <linux/unaligned/access_ok.h> | 17 | #include <linux/unaligned/access_ok.h> |
18 | #include <linux/unaligned/generic.h> | 18 | #include <linux/unaligned/generic.h> |
diff --git a/arch/m68k/include/asm/xor.h b/arch/m68k/include/asm/xor.h deleted file mode 100644 index c82eb12a5b18..000000000000 --- a/arch/m68k/include/asm/xor.h +++ /dev/null | |||
@@ -1 +0,0 @@ | |||
1 | #include <asm-generic/xor.h> | ||
diff --git a/arch/m68k/kernel/setup_no.c b/arch/m68k/kernel/setup_no.c index 7dc186b7a85f..71fb29938dba 100644 --- a/arch/m68k/kernel/setup_no.c +++ b/arch/m68k/kernel/setup_no.c | |||
@@ -218,13 +218,10 @@ void __init setup_arch(char **cmdline_p) | |||
218 | printk(KERN_INFO "Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)\n"); | 218 | printk(KERN_INFO "Motorola M5235EVB support (C)2005 Syn-tech Systems, Inc. (Jate Sujjavanich)\n"); |
219 | #endif | 219 | #endif |
220 | 220 | ||
221 | pr_debug("KERNEL -> TEXT=0x%06x-0x%06x DATA=0x%06x-0x%06x " | 221 | pr_debug("KERNEL -> TEXT=0x%p-0x%p DATA=0x%p-0x%p BSS=0x%p-0x%p\n", |
222 | "BSS=0x%06x-0x%06x\n", (int) &_stext, (int) &_etext, | 222 | _stext, _etext, _sdata, _edata, __bss_start, __bss_stop); |
223 | (int) &_sdata, (int) &_edata, | 223 | pr_debug("MEMORY -> ROMFS=0x%p-0x%06lx MEM=0x%06lx-0x%06lx\n ", |
224 | (int) &_sbss, (int) &_ebss); | 224 | __bss_stop, memory_start, memory_start, memory_end); |
225 | pr_debug("MEMORY -> ROMFS=0x%06x-0x%06x MEM=0x%06x-0x%06x\n ", | ||
226 | (int) &_ebss, (int) memory_start, | ||
227 | (int) memory_start, (int) memory_end); | ||
228 | 225 | ||
229 | /* Keep a copy of command line */ | 226 | /* Keep a copy of command line */ |
230 | *cmdline_p = &command_line[0]; | 227 | *cmdline_p = &command_line[0]; |
diff --git a/arch/m68k/kernel/sys_m68k.c b/arch/m68k/kernel/sys_m68k.c index 8623f8dc16f8..9a5932ec3689 100644 --- a/arch/m68k/kernel/sys_m68k.c +++ b/arch/m68k/kernel/sys_m68k.c | |||
@@ -479,9 +479,13 @@ sys_atomic_cmpxchg_32(unsigned long newval, int oldval, int d3, int d4, int d5, | |||
479 | goto bad_access; | 479 | goto bad_access; |
480 | } | 480 | } |
481 | 481 | ||
482 | mem_value = *mem; | 482 | /* |
483 | * No need to check for EFAULT; we know that the page is | ||
484 | * present and writable. | ||
485 | */ | ||
486 | __get_user(mem_value, mem); | ||
483 | if (mem_value == oldval) | 487 | if (mem_value == oldval) |
484 | *mem = newval; | 488 | __put_user(newval, mem); |
485 | 489 | ||
486 | pte_unmap_unlock(pte, ptl); | 490 | pte_unmap_unlock(pte, ptl); |
487 | up_read(&mm->mmap_sem); | 491 | up_read(&mm->mmap_sem); |
diff --git a/arch/m68k/kernel/vmlinux-nommu.lds b/arch/m68k/kernel/vmlinux-nommu.lds index 40e02d9c38b4..06a763f49fd3 100644 --- a/arch/m68k/kernel/vmlinux-nommu.lds +++ b/arch/m68k/kernel/vmlinux-nommu.lds | |||
@@ -78,9 +78,7 @@ SECTIONS { | |||
78 | __init_end = .; | 78 | __init_end = .; |
79 | } | 79 | } |
80 | 80 | ||
81 | _sbss = .; | ||
82 | BSS_SECTION(0, 0, 0) | 81 | BSS_SECTION(0, 0, 0) |
83 | _ebss = .; | ||
84 | 82 | ||
85 | _end = .; | 83 | _end = .; |
86 | 84 | ||
diff --git a/arch/m68k/kernel/vmlinux-std.lds b/arch/m68k/kernel/vmlinux-std.lds index 63407c836826..d0993594f558 100644 --- a/arch/m68k/kernel/vmlinux-std.lds +++ b/arch/m68k/kernel/vmlinux-std.lds | |||
@@ -31,9 +31,7 @@ SECTIONS | |||
31 | 31 | ||
32 | RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE) | 32 | RW_DATA_SECTION(16, PAGE_SIZE, THREAD_SIZE) |
33 | 33 | ||
34 | _sbss = .; | ||
35 | BSS_SECTION(0, 0, 0) | 34 | BSS_SECTION(0, 0, 0) |
36 | _ebss = .; | ||
37 | 35 | ||
38 | _edata = .; /* End of data section */ | 36 | _edata = .; /* End of data section */ |
39 | 37 | ||
diff --git a/arch/m68k/kernel/vmlinux-sun3.lds b/arch/m68k/kernel/vmlinux-sun3.lds index ad0f46d64c0b..8080469ee6c1 100644 --- a/arch/m68k/kernel/vmlinux-sun3.lds +++ b/arch/m68k/kernel/vmlinux-sun3.lds | |||
@@ -44,9 +44,7 @@ __init_begin = .; | |||
44 | . = ALIGN(PAGE_SIZE); | 44 | . = ALIGN(PAGE_SIZE); |
45 | __init_end = .; | 45 | __init_end = .; |
46 | 46 | ||
47 | _sbss = .; | ||
48 | BSS_SECTION(0, 0, 0) | 47 | BSS_SECTION(0, 0, 0) |
49 | _ebss = .; | ||
50 | 48 | ||
51 | _end = . ; | 49 | _end = . ; |
52 | 50 | ||
diff --git a/arch/m68k/lib/muldi3.c b/arch/m68k/lib/muldi3.c index 79e928a525d0..ee5f0b1b5c5d 100644 --- a/arch/m68k/lib/muldi3.c +++ b/arch/m68k/lib/muldi3.c | |||
@@ -19,7 +19,7 @@ along with GNU CC; see the file COPYING. If not, write to | |||
19 | the Free Software Foundation, 59 Temple Place - Suite 330, | 19 | the Free Software Foundation, 59 Temple Place - Suite 330, |
20 | Boston, MA 02111-1307, USA. */ | 20 | Boston, MA 02111-1307, USA. */ |
21 | 21 | ||
22 | #if defined(CONFIG_M68000) || defined(CONFIG_COLDFIRE) | 22 | #ifdef CONFIG_CPU_HAS_NO_MULDIV64 |
23 | 23 | ||
24 | #define SI_TYPE_SIZE 32 | 24 | #define SI_TYPE_SIZE 32 |
25 | #define __BITS4 (SI_TYPE_SIZE / 4) | 25 | #define __BITS4 (SI_TYPE_SIZE / 4) |
diff --git a/arch/m68k/mm/init_mm.c b/arch/m68k/mm/init_mm.c index f77f258dce3a..282f9de68966 100644 --- a/arch/m68k/mm/init_mm.c +++ b/arch/m68k/mm/init_mm.c | |||
@@ -104,7 +104,7 @@ void __init print_memmap(void) | |||
104 | MLK_ROUNDUP(__init_begin, __init_end), | 104 | MLK_ROUNDUP(__init_begin, __init_end), |
105 | MLK_ROUNDUP(_stext, _etext), | 105 | MLK_ROUNDUP(_stext, _etext), |
106 | MLK_ROUNDUP(_sdata, _edata), | 106 | MLK_ROUNDUP(_sdata, _edata), |
107 | MLK_ROUNDUP(_sbss, _ebss)); | 107 | MLK_ROUNDUP(__bss_start, __bss_stop)); |
108 | } | 108 | } |
109 | 109 | ||
110 | void __init mem_init(void) | 110 | void __init mem_init(void) |
diff --git a/arch/m68k/mm/init_no.c b/arch/m68k/mm/init_no.c index 345ec0d83e3d..688e3664aea0 100644 --- a/arch/m68k/mm/init_no.c +++ b/arch/m68k/mm/init_no.c | |||
@@ -91,7 +91,7 @@ void __init mem_init(void) | |||
91 | totalram_pages = free_all_bootmem(); | 91 | totalram_pages = free_all_bootmem(); |
92 | 92 | ||
93 | codek = (_etext - _stext) >> 10; | 93 | codek = (_etext - _stext) >> 10; |
94 | datak = (_ebss - _sdata) >> 10; | 94 | datak = (__bss_stop - _sdata) >> 10; |
95 | initk = (__init_begin - __init_end) >> 10; | 95 | initk = (__init_begin - __init_end) >> 10; |
96 | 96 | ||
97 | tmp = nr_free_pages() << PAGE_SHIFT; | 97 | tmp = nr_free_pages() << PAGE_SHIFT; |
diff --git a/arch/m68k/platform/68328/head-de2.S b/arch/m68k/platform/68328/head-de2.S index f632fdcb93e9..537d3245b539 100644 --- a/arch/m68k/platform/68328/head-de2.S +++ b/arch/m68k/platform/68328/head-de2.S | |||
@@ -60,8 +60,8 @@ _start: | |||
60 | * Move ROM filesystem above bss :-) | 60 | * Move ROM filesystem above bss :-) |
61 | */ | 61 | */ |
62 | 62 | ||
63 | moveal #_sbss, %a0 /* romfs at the start of bss */ | 63 | moveal #__bss_start, %a0 /* romfs at the start of bss */ |
64 | moveal #_ebss, %a1 /* Set up destination */ | 64 | moveal #__bss_stop, %a1 /* Set up destination */ |
65 | movel %a0, %a2 /* Copy of bss start */ | 65 | movel %a0, %a2 /* Copy of bss start */ |
66 | 66 | ||
67 | movel 8(%a0), %d1 /* Get size of ROMFS */ | 67 | movel 8(%a0), %d1 /* Get size of ROMFS */ |
@@ -84,8 +84,8 @@ _start: | |||
84 | * Initialize BSS segment to 0 | 84 | * Initialize BSS segment to 0 |
85 | */ | 85 | */ |
86 | 86 | ||
87 | lea _sbss, %a0 | 87 | lea __bss_start, %a0 |
88 | lea _ebss, %a1 | 88 | lea __bss_stop, %a1 |
89 | 89 | ||
90 | /* Copy 0 to %a0 until %a0 == %a1 */ | 90 | /* Copy 0 to %a0 until %a0 == %a1 */ |
91 | 2: cmpal %a0, %a1 | 91 | 2: cmpal %a0, %a1 |
diff --git a/arch/m68k/platform/68328/head-pilot.S b/arch/m68k/platform/68328/head-pilot.S index 2ebfd6420818..45a9dad29e3d 100644 --- a/arch/m68k/platform/68328/head-pilot.S +++ b/arch/m68k/platform/68328/head-pilot.S | |||
@@ -110,7 +110,7 @@ L0: | |||
110 | movel #CONFIG_VECTORBASE, %d7 | 110 | movel #CONFIG_VECTORBASE, %d7 |
111 | addl #16, %d7 | 111 | addl #16, %d7 |
112 | moveal %d7, %a0 | 112 | moveal %d7, %a0 |
113 | moveal #_ebss, %a1 | 113 | moveal #__bss_stop, %a1 |
114 | lea %a1@(512), %a2 | 114 | lea %a1@(512), %a2 |
115 | 115 | ||
116 | DBG_PUTC('C') | 116 | DBG_PUTC('C') |
@@ -138,8 +138,8 @@ LD1: | |||
138 | 138 | ||
139 | DBG_PUTC('E') | 139 | DBG_PUTC('E') |
140 | 140 | ||
141 | moveal #_sbss, %a0 | 141 | moveal #__bss_start, %a0 |
142 | moveal #_ebss, %a1 | 142 | moveal #__bss_stop, %a1 |
143 | 143 | ||
144 | /* Copy 0 to %a0 until %a0 == %a1 */ | 144 | /* Copy 0 to %a0 until %a0 == %a1 */ |
145 | L1: | 145 | L1: |
@@ -150,7 +150,7 @@ L1: | |||
150 | DBG_PUTC('F') | 150 | DBG_PUTC('F') |
151 | 151 | ||
152 | /* Copy command line from end of bss to command line */ | 152 | /* Copy command line from end of bss to command line */ |
153 | moveal #_ebss, %a0 | 153 | moveal #__bss_stop, %a0 |
154 | moveal #command_line, %a1 | 154 | moveal #command_line, %a1 |
155 | lea %a1@(512), %a2 | 155 | lea %a1@(512), %a2 |
156 | 156 | ||
@@ -165,7 +165,7 @@ L3: | |||
165 | 165 | ||
166 | movel #_sdata, %d0 | 166 | movel #_sdata, %d0 |
167 | movel %d0, _rambase | 167 | movel %d0, _rambase |
168 | movel #_ebss, %d0 | 168 | movel #__bss_stop, %d0 |
169 | movel %d0, _ramstart | 169 | movel %d0, _ramstart |
170 | 170 | ||
171 | movel %a4, %d0 | 171 | movel %a4, %d0 |
diff --git a/arch/m68k/platform/68328/head-ram.S b/arch/m68k/platform/68328/head-ram.S index 7f1aeeacb219..5189ef926098 100644 --- a/arch/m68k/platform/68328/head-ram.S +++ b/arch/m68k/platform/68328/head-ram.S | |||
@@ -76,8 +76,8 @@ pclp3: | |||
76 | beq pclp3 | 76 | beq pclp3 |
77 | #endif /* DEBUG */ | 77 | #endif /* DEBUG */ |
78 | moveal #0x007ffff0, %ssp | 78 | moveal #0x007ffff0, %ssp |
79 | moveal #_sbss, %a0 | 79 | moveal #__bss_start, %a0 |
80 | moveal #_ebss, %a1 | 80 | moveal #__bss_stop, %a1 |
81 | 81 | ||
82 | /* Copy 0 to %a0 until %a0 >= %a1 */ | 82 | /* Copy 0 to %a0 until %a0 >= %a1 */ |
83 | L1: | 83 | L1: |
diff --git a/arch/m68k/platform/68328/head-rom.S b/arch/m68k/platform/68328/head-rom.S index a5ff96d0295f..3dff98ba2e97 100644 --- a/arch/m68k/platform/68328/head-rom.S +++ b/arch/m68k/platform/68328/head-rom.S | |||
@@ -59,8 +59,8 @@ _stext: movew #0x2700,%sr | |||
59 | cmpal %a1, %a2 | 59 | cmpal %a1, %a2 |
60 | bhi 1b | 60 | bhi 1b |
61 | 61 | ||
62 | moveal #_sbss, %a0 | 62 | moveal #__bss_start, %a0 |
63 | moveal #_ebss, %a1 | 63 | moveal #__bss_stop, %a1 |
64 | /* Copy 0 to %a0 until %a0 == %a1 */ | 64 | /* Copy 0 to %a0 until %a0 == %a1 */ |
65 | 65 | ||
66 | 1: | 66 | 1: |
@@ -70,7 +70,7 @@ _stext: movew #0x2700,%sr | |||
70 | 70 | ||
71 | movel #_sdata, %d0 | 71 | movel #_sdata, %d0 |
72 | movel %d0, _rambase | 72 | movel %d0, _rambase |
73 | movel #_ebss, %d0 | 73 | movel #__bss_stop, %d0 |
74 | movel %d0, _ramstart | 74 | movel %d0, _ramstart |
75 | movel #RAMEND-CONFIG_MEMORY_RESERVE*0x100000, %d0 | 75 | movel #RAMEND-CONFIG_MEMORY_RESERVE*0x100000, %d0 |
76 | movel %d0, _ramend | 76 | movel %d0, _ramend |
diff --git a/arch/m68k/platform/68360/head-ram.S b/arch/m68k/platform/68360/head-ram.S index 8eb94fb6b971..acd213170d80 100644 --- a/arch/m68k/platform/68360/head-ram.S +++ b/arch/m68k/platform/68360/head-ram.S | |||
@@ -219,8 +219,8 @@ LD1: | |||
219 | cmp.l #_edata, %a1 | 219 | cmp.l #_edata, %a1 |
220 | blt LD1 | 220 | blt LD1 |
221 | 221 | ||
222 | moveal #_sbss, %a0 | 222 | moveal #__bss_start, %a0 |
223 | moveal #_ebss, %a1 | 223 | moveal #__bss_stop, %a1 |
224 | 224 | ||
225 | /* Copy 0 to %a0 until %a0 == %a1 */ | 225 | /* Copy 0 to %a0 until %a0 == %a1 */ |
226 | L1: | 226 | L1: |
@@ -234,7 +234,7 @@ load_quicc: | |||
234 | store_ram_size: | 234 | store_ram_size: |
235 | /* Set ram size information */ | 235 | /* Set ram size information */ |
236 | move.l #_sdata, _rambase | 236 | move.l #_sdata, _rambase |
237 | move.l #_ebss, _ramstart | 237 | move.l #__bss_stop, _ramstart |
238 | move.l #RAMEND, %d0 | 238 | move.l #RAMEND, %d0 |
239 | sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/ | 239 | sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/ |
240 | move.l %d0, _ramend /* Different from RAMEND.*/ | 240 | move.l %d0, _ramend /* Different from RAMEND.*/ |
diff --git a/arch/m68k/platform/68360/head-rom.S b/arch/m68k/platform/68360/head-rom.S index 97510e55b802..dfc756d99886 100644 --- a/arch/m68k/platform/68360/head-rom.S +++ b/arch/m68k/platform/68360/head-rom.S | |||
@@ -13,7 +13,7 @@ | |||
13 | */ | 13 | */ |
14 | 14 | ||
15 | .global _stext | 15 | .global _stext |
16 | .global _sbss | 16 | .global __bss_start |
17 | .global _start | 17 | .global _start |
18 | 18 | ||
19 | .global _rambase | 19 | .global _rambase |
@@ -229,8 +229,8 @@ LD1: | |||
229 | cmp.l #_edata, %a1 | 229 | cmp.l #_edata, %a1 |
230 | blt LD1 | 230 | blt LD1 |
231 | 231 | ||
232 | moveal #_sbss, %a0 | 232 | moveal #__bss_start, %a0 |
233 | moveal #_ebss, %a1 | 233 | moveal #__bss_stop, %a1 |
234 | 234 | ||
235 | /* Copy 0 to %a0 until %a0 == %a1 */ | 235 | /* Copy 0 to %a0 until %a0 == %a1 */ |
236 | L1: | 236 | L1: |
@@ -244,7 +244,7 @@ load_quicc: | |||
244 | store_ram_size: | 244 | store_ram_size: |
245 | /* Set ram size information */ | 245 | /* Set ram size information */ |
246 | move.l #_sdata, _rambase | 246 | move.l #_sdata, _rambase |
247 | move.l #_ebss, _ramstart | 247 | move.l #__bss_stop, _ramstart |
248 | move.l #RAMEND, %d0 | 248 | move.l #RAMEND, %d0 |
249 | sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/ | 249 | sub.l #0x1000, %d0 /* Reserve 4K for stack space.*/ |
250 | move.l %d0, _ramend /* Different from RAMEND.*/ | 250 | move.l %d0, _ramend /* Different from RAMEND.*/ |
diff --git a/arch/m68k/platform/coldfire/head.S b/arch/m68k/platform/coldfire/head.S index 4e0c9eb3bd1f..b88f5716f357 100644 --- a/arch/m68k/platform/coldfire/head.S +++ b/arch/m68k/platform/coldfire/head.S | |||
@@ -230,8 +230,8 @@ _vstart: | |||
230 | /* | 230 | /* |
231 | * Move ROM filesystem above bss :-) | 231 | * Move ROM filesystem above bss :-) |
232 | */ | 232 | */ |
233 | lea _sbss,%a0 /* get start of bss */ | 233 | lea __bss_start,%a0 /* get start of bss */ |
234 | lea _ebss,%a1 /* set up destination */ | 234 | lea __bss_stop,%a1 /* set up destination */ |
235 | movel %a0,%a2 /* copy of bss start */ | 235 | movel %a0,%a2 /* copy of bss start */ |
236 | 236 | ||
237 | movel 8(%a0),%d0 /* get size of ROMFS */ | 237 | movel 8(%a0),%d0 /* get size of ROMFS */ |
@@ -249,7 +249,7 @@ _copy_romfs: | |||
249 | bne _copy_romfs | 249 | bne _copy_romfs |
250 | 250 | ||
251 | #else /* CONFIG_ROMFS_FS */ | 251 | #else /* CONFIG_ROMFS_FS */ |
252 | lea _ebss,%a1 | 252 | lea __bss_stop,%a1 |
253 | movel %a1,_ramstart | 253 | movel %a1,_ramstart |
254 | #endif /* CONFIG_ROMFS_FS */ | 254 | #endif /* CONFIG_ROMFS_FS */ |
255 | 255 | ||
@@ -257,8 +257,8 @@ _copy_romfs: | |||
257 | /* | 257 | /* |
258 | * Zero out the bss region. | 258 | * Zero out the bss region. |
259 | */ | 259 | */ |
260 | lea _sbss,%a0 /* get start of bss */ | 260 | lea __bss_start,%a0 /* get start of bss */ |
261 | lea _ebss,%a1 /* get end of bss */ | 261 | lea __bss_stop,%a1 /* get end of bss */ |
262 | clrl %d0 /* set value */ | 262 | clrl %d0 /* set value */ |
263 | _clear_bss: | 263 | _clear_bss: |
264 | movel %d0,(%a0)+ /* clear each word */ | 264 | movel %d0,(%a0)+ /* clear each word */ |
diff --git a/arch/m68k/sun3/prom/init.c b/arch/m68k/sun3/prom/init.c index d8e6349336b4..eeba067d565f 100644 --- a/arch/m68k/sun3/prom/init.c +++ b/arch/m68k/sun3/prom/init.c | |||
@@ -22,57 +22,13 @@ int prom_root_node; | |||
22 | struct linux_nodeops *prom_nodeops; | 22 | struct linux_nodeops *prom_nodeops; |
23 | 23 | ||
24 | /* You must call prom_init() before you attempt to use any of the | 24 | /* You must call prom_init() before you attempt to use any of the |
25 | * routines in the prom library. It returns 0 on success, 1 on | 25 | * routines in the prom library. |
26 | * failure. It gets passed the pointer to the PROM vector. | 26 | * It gets passed the pointer to the PROM vector. |
27 | */ | 27 | */ |
28 | 28 | ||
29 | extern void prom_meminit(void); | ||
30 | extern void prom_ranges_init(void); | ||
31 | |||
32 | void __init prom_init(struct linux_romvec *rp) | 29 | void __init prom_init(struct linux_romvec *rp) |
33 | { | 30 | { |
34 | romvec = rp; | 31 | romvec = rp; |
35 | #ifndef CONFIG_SUN3 | ||
36 | switch(romvec->pv_romvers) { | ||
37 | case 0: | ||
38 | prom_vers = PROM_V0; | ||
39 | break; | ||
40 | case 2: | ||
41 | prom_vers = PROM_V2; | ||
42 | break; | ||
43 | case 3: | ||
44 | prom_vers = PROM_V3; | ||
45 | break; | ||
46 | case 4: | ||
47 | prom_vers = PROM_P1275; | ||
48 | prom_printf("PROMLIB: Sun IEEE Prom not supported yet\n"); | ||
49 | prom_halt(); | ||
50 | break; | ||
51 | default: | ||
52 | prom_printf("PROMLIB: Bad PROM version %d\n", | ||
53 | romvec->pv_romvers); | ||
54 | prom_halt(); | ||
55 | break; | ||
56 | }; | ||
57 | |||
58 | prom_rev = romvec->pv_plugin_revision; | ||
59 | prom_prev = romvec->pv_printrev; | ||
60 | prom_nodeops = romvec->pv_nodeops; | ||
61 | |||
62 | prom_root_node = prom_getsibling(0); | ||
63 | if((prom_root_node == 0) || (prom_root_node == -1)) | ||
64 | prom_halt(); | ||
65 | |||
66 | if((((unsigned long) prom_nodeops) == 0) || | ||
67 | (((unsigned long) prom_nodeops) == -1)) | ||
68 | prom_halt(); | ||
69 | |||
70 | prom_meminit(); | ||
71 | |||
72 | prom_ranges_init(); | ||
73 | #endif | ||
74 | // printk("PROMLIB: Sun Boot Prom Version %d Revision %d\n", | ||
75 | // romvec->pv_romvers, prom_rev); | ||
76 | 32 | ||
77 | /* Initialization successful. */ | 33 | /* Initialization successful. */ |
78 | return; | 34 | return; |
diff --git a/arch/microblaze/include/asm/sections.h b/arch/microblaze/include/asm/sections.h index 4487e150b455..c07ed5d2a820 100644 --- a/arch/microblaze/include/asm/sections.h +++ b/arch/microblaze/include/asm/sections.h | |||
@@ -18,10 +18,6 @@ extern char _ssbss[], _esbss[]; | |||
18 | extern unsigned long __ivt_start[], __ivt_end[]; | 18 | extern unsigned long __ivt_start[], __ivt_end[]; |
19 | extern char _etext[], _stext[]; | 19 | extern char _etext[], _stext[]; |
20 | 20 | ||
21 | # ifdef CONFIG_MTD_UCLINUX | ||
22 | extern char *_ebss; | ||
23 | # endif | ||
24 | |||
25 | extern u32 _fdt_start[], _fdt_end[]; | 21 | extern u32 _fdt_start[], _fdt_end[]; |
26 | 22 | ||
27 | # endif /* !__ASSEMBLY__ */ | 23 | # endif /* !__ASSEMBLY__ */ |
diff --git a/arch/microblaze/kernel/microblaze_ksyms.c b/arch/microblaze/kernel/microblaze_ksyms.c index bb4907c828dc..2b25bcf05c00 100644 --- a/arch/microblaze/kernel/microblaze_ksyms.c +++ b/arch/microblaze/kernel/microblaze_ksyms.c | |||
@@ -21,9 +21,6 @@ | |||
21 | #include <linux/ftrace.h> | 21 | #include <linux/ftrace.h> |
22 | #include <linux/uaccess.h> | 22 | #include <linux/uaccess.h> |
23 | 23 | ||
24 | extern char *_ebss; | ||
25 | EXPORT_SYMBOL_GPL(_ebss); | ||
26 | |||
27 | #ifdef CONFIG_FUNCTION_TRACER | 24 | #ifdef CONFIG_FUNCTION_TRACER |
28 | extern void _mcount(void); | 25 | extern void _mcount(void); |
29 | EXPORT_SYMBOL(_mcount); | 26 | EXPORT_SYMBOL(_mcount); |
diff --git a/arch/microblaze/kernel/setup.c b/arch/microblaze/kernel/setup.c index 16d8dfd9094b..4da971d4392f 100644 --- a/arch/microblaze/kernel/setup.c +++ b/arch/microblaze/kernel/setup.c | |||
@@ -121,7 +121,7 @@ void __init machine_early_init(const char *cmdline, unsigned int ram, | |||
121 | 121 | ||
122 | /* Move ROMFS out of BSS before clearing it */ | 122 | /* Move ROMFS out of BSS before clearing it */ |
123 | if (romfs_size > 0) { | 123 | if (romfs_size > 0) { |
124 | memmove(&_ebss, (int *)romfs_base, romfs_size); | 124 | memmove(&__bss_stop, (int *)romfs_base, romfs_size); |
125 | klimit += romfs_size; | 125 | klimit += romfs_size; |
126 | } | 126 | } |
127 | #endif | 127 | #endif |
@@ -165,7 +165,7 @@ void __init machine_early_init(const char *cmdline, unsigned int ram, | |||
165 | BUG_ON(romfs_size < 0); /* What else can we do? */ | 165 | BUG_ON(romfs_size < 0); /* What else can we do? */ |
166 | 166 | ||
167 | printk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n", | 167 | printk("Moved 0x%08x bytes from 0x%08x to 0x%08x\n", |
168 | romfs_size, romfs_base, (unsigned)&_ebss); | 168 | romfs_size, romfs_base, (unsigned)&__bss_stop); |
169 | 169 | ||
170 | printk("New klimit: 0x%08x\n", (unsigned)klimit); | 170 | printk("New klimit: 0x%08x\n", (unsigned)klimit); |
171 | #endif | 171 | #endif |
diff --git a/arch/microblaze/kernel/vmlinux.lds.S b/arch/microblaze/kernel/vmlinux.lds.S index 109e9d86ade4..936d01a689d7 100644 --- a/arch/microblaze/kernel/vmlinux.lds.S +++ b/arch/microblaze/kernel/vmlinux.lds.S | |||
@@ -131,7 +131,6 @@ SECTIONS { | |||
131 | *(COMMON) | 131 | *(COMMON) |
132 | . = ALIGN (4) ; | 132 | . = ALIGN (4) ; |
133 | __bss_stop = . ; | 133 | __bss_stop = . ; |
134 | _ebss = . ; | ||
135 | } | 134 | } |
136 | . = ALIGN(PAGE_SIZE); | 135 | . = ALIGN(PAGE_SIZE); |
137 | _end = .; | 136 | _end = .; |
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig index 76de6b68487c..107610e01a29 100644 --- a/arch/s390/Kconfig +++ b/arch/s390/Kconfig | |||
@@ -124,6 +124,7 @@ config S390 | |||
124 | select GENERIC_TIME_VSYSCALL | 124 | select GENERIC_TIME_VSYSCALL |
125 | select GENERIC_CLOCKEVENTS | 125 | select GENERIC_CLOCKEVENTS |
126 | select KTIME_SCALAR if 32BIT | 126 | select KTIME_SCALAR if 32BIT |
127 | select HAVE_ARCH_SECCOMP_FILTER | ||
127 | 128 | ||
128 | config SCHED_OMIT_FRAME_POINTER | 129 | config SCHED_OMIT_FRAME_POINTER |
129 | def_bool y | 130 | def_bool y |
diff --git a/arch/s390/include/asm/sparsemem.h b/arch/s390/include/asm/sparsemem.h index 0fb34027d3f6..a60d085ddb4d 100644 --- a/arch/s390/include/asm/sparsemem.h +++ b/arch/s390/include/asm/sparsemem.h | |||
@@ -4,13 +4,11 @@ | |||
4 | #ifdef CONFIG_64BIT | 4 | #ifdef CONFIG_64BIT |
5 | 5 | ||
6 | #define SECTION_SIZE_BITS 28 | 6 | #define SECTION_SIZE_BITS 28 |
7 | #define MAX_PHYSADDR_BITS 46 | ||
8 | #define MAX_PHYSMEM_BITS 46 | 7 | #define MAX_PHYSMEM_BITS 46 |
9 | 8 | ||
10 | #else | 9 | #else |
11 | 10 | ||
12 | #define SECTION_SIZE_BITS 25 | 11 | #define SECTION_SIZE_BITS 25 |
13 | #define MAX_PHYSADDR_BITS 31 | ||
14 | #define MAX_PHYSMEM_BITS 31 | 12 | #define MAX_PHYSMEM_BITS 31 |
15 | 13 | ||
16 | #endif /* CONFIG_64BIT */ | 14 | #endif /* CONFIG_64BIT */ |
diff --git a/arch/s390/include/asm/syscall.h b/arch/s390/include/asm/syscall.h index fb214dd9b7e0..fe7b99759e12 100644 --- a/arch/s390/include/asm/syscall.h +++ b/arch/s390/include/asm/syscall.h | |||
@@ -12,6 +12,7 @@ | |||
12 | #ifndef _ASM_SYSCALL_H | 12 | #ifndef _ASM_SYSCALL_H |
13 | #define _ASM_SYSCALL_H 1 | 13 | #define _ASM_SYSCALL_H 1 |
14 | 14 | ||
15 | #include <linux/audit.h> | ||
15 | #include <linux/sched.h> | 16 | #include <linux/sched.h> |
16 | #include <linux/err.h> | 17 | #include <linux/err.h> |
17 | #include <asm/ptrace.h> | 18 | #include <asm/ptrace.h> |
@@ -87,4 +88,13 @@ static inline void syscall_set_arguments(struct task_struct *task, | |||
87 | regs->orig_gpr2 = args[0]; | 88 | regs->orig_gpr2 = args[0]; |
88 | } | 89 | } |
89 | 90 | ||
91 | static inline int syscall_get_arch(struct task_struct *task, | ||
92 | struct pt_regs *regs) | ||
93 | { | ||
94 | #ifdef CONFIG_COMPAT | ||
95 | if (test_tsk_thread_flag(task, TIF_31BIT)) | ||
96 | return AUDIT_ARCH_S390; | ||
97 | #endif | ||
98 | return sizeof(long) == 8 ? AUDIT_ARCH_S390X : AUDIT_ARCH_S390; | ||
99 | } | ||
90 | #endif /* _ASM_SYSCALL_H */ | 100 | #endif /* _ASM_SYSCALL_H */ |
diff --git a/arch/s390/kernel/compat_linux.c b/arch/s390/kernel/compat_linux.c index d1225089a4bb..f606d935f495 100644 --- a/arch/s390/kernel/compat_linux.c +++ b/arch/s390/kernel/compat_linux.c | |||
@@ -620,7 +620,6 @@ asmlinkage unsigned long old32_mmap(struct mmap_arg_struct_emu31 __user *arg) | |||
620 | return -EFAULT; | 620 | return -EFAULT; |
621 | if (a.offset & ~PAGE_MASK) | 621 | if (a.offset & ~PAGE_MASK) |
622 | return -EINVAL; | 622 | return -EINVAL; |
623 | a.addr = (unsigned long) compat_ptr(a.addr); | ||
624 | return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, | 623 | return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, |
625 | a.offset >> PAGE_SHIFT); | 624 | a.offset >> PAGE_SHIFT); |
626 | } | 625 | } |
@@ -631,7 +630,6 @@ asmlinkage long sys32_mmap2(struct mmap_arg_struct_emu31 __user *arg) | |||
631 | 630 | ||
632 | if (copy_from_user(&a, arg, sizeof(a))) | 631 | if (copy_from_user(&a, arg, sizeof(a))) |
633 | return -EFAULT; | 632 | return -EFAULT; |
634 | a.addr = (unsigned long) compat_ptr(a.addr); | ||
635 | return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); | 633 | return sys_mmap_pgoff(a.addr, a.len, a.prot, a.flags, a.fd, a.offset); |
636 | } | 634 | } |
637 | 635 | ||
diff --git a/arch/s390/kernel/compat_wrapper.S b/arch/s390/kernel/compat_wrapper.S index e835d6d5b7fd..2d82cfcbce5b 100644 --- a/arch/s390/kernel/compat_wrapper.S +++ b/arch/s390/kernel/compat_wrapper.S | |||
@@ -1635,7 +1635,7 @@ ENTRY(compat_sys_process_vm_readv_wrapper) | |||
1635 | llgfr %r6,%r6 # unsigned long | 1635 | llgfr %r6,%r6 # unsigned long |
1636 | llgf %r0,164(%r15) # unsigned long | 1636 | llgf %r0,164(%r15) # unsigned long |
1637 | stg %r0,160(%r15) | 1637 | stg %r0,160(%r15) |
1638 | jg sys_process_vm_readv | 1638 | jg compat_sys_process_vm_readv |
1639 | 1639 | ||
1640 | ENTRY(compat_sys_process_vm_writev_wrapper) | 1640 | ENTRY(compat_sys_process_vm_writev_wrapper) |
1641 | lgfr %r2,%r2 # compat_pid_t | 1641 | lgfr %r2,%r2 # compat_pid_t |
@@ -1645,4 +1645,4 @@ ENTRY(compat_sys_process_vm_writev_wrapper) | |||
1645 | llgfr %r6,%r6 # unsigned long | 1645 | llgfr %r6,%r6 # unsigned long |
1646 | llgf %r0,164(%r15) # unsigned long | 1646 | llgf %r0,164(%r15) # unsigned long |
1647 | stg %r0,160(%r15) | 1647 | stg %r0,160(%r15) |
1648 | jg sys_process_vm_writev | 1648 | jg compat_sys_process_vm_writev |
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index f4eb37680b91..e4be113fbac6 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c | |||
@@ -719,7 +719,11 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) | |||
719 | long ret = 0; | 719 | long ret = 0; |
720 | 720 | ||
721 | /* Do the secure computing check first. */ | 721 | /* Do the secure computing check first. */ |
722 | secure_computing_strict(regs->gprs[2]); | 722 | if (secure_computing(regs->gprs[2])) { |
723 | /* seccomp failures shouldn't expose any additional code. */ | ||
724 | ret = -1; | ||
725 | goto out; | ||
726 | } | ||
723 | 727 | ||
724 | /* | 728 | /* |
725 | * The sysc_tracesys code in entry.S stored the system | 729 | * The sysc_tracesys code in entry.S stored the system |
@@ -745,6 +749,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) | |||
745 | regs->gprs[2], regs->orig_gpr2, | 749 | regs->gprs[2], regs->orig_gpr2, |
746 | regs->gprs[3], regs->gprs[4], | 750 | regs->gprs[3], regs->gprs[4], |
747 | regs->gprs[5]); | 751 | regs->gprs[5]); |
752 | out: | ||
748 | return ret ?: regs->gprs[2]; | 753 | return ret ?: regs->gprs[2]; |
749 | } | 754 | } |
750 | 755 | ||
diff --git a/arch/s390/kernel/sys_s390.c b/arch/s390/kernel/sys_s390.c index b4a29eee41b8..d0964d22adb5 100644 --- a/arch/s390/kernel/sys_s390.c +++ b/arch/s390/kernel/sys_s390.c | |||
@@ -81,11 +81,12 @@ SYSCALL_DEFINE1(s390_personality, unsigned int, personality) | |||
81 | { | 81 | { |
82 | unsigned int ret; | 82 | unsigned int ret; |
83 | 83 | ||
84 | if (current->personality == PER_LINUX32 && personality == PER_LINUX) | 84 | if (personality(current->personality) == PER_LINUX32 && |
85 | personality = PER_LINUX32; | 85 | personality(personality) == PER_LINUX) |
86 | personality |= PER_LINUX32; | ||
86 | ret = sys_personality(personality); | 87 | ret = sys_personality(personality); |
87 | if (ret == PER_LINUX32) | 88 | if (personality(ret) == PER_LINUX32) |
88 | ret = PER_LINUX; | 89 | ret &= ~PER_LINUX32; |
89 | 90 | ||
90 | return ret; | 91 | return ret; |
91 | } | 92 | } |
diff --git a/arch/sh/boards/Kconfig b/arch/sh/boards/Kconfig index 7048c03490d9..fb5805745ace 100644 --- a/arch/sh/boards/Kconfig +++ b/arch/sh/boards/Kconfig | |||
@@ -57,6 +57,7 @@ config SH_7724_SOLUTION_ENGINE | |||
57 | depends on CPU_SUBTYPE_SH7724 | 57 | depends on CPU_SUBTYPE_SH7724 |
58 | select ARCH_REQUIRE_GPIOLIB | 58 | select ARCH_REQUIRE_GPIOLIB |
59 | select SND_SOC_AK4642 if SND_SIMPLE_CARD | 59 | select SND_SOC_AK4642 if SND_SIMPLE_CARD |
60 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
60 | help | 61 | help |
61 | Select 7724 SolutionEngine if configuring for a Hitachi SH7724 | 62 | Select 7724 SolutionEngine if configuring for a Hitachi SH7724 |
62 | evaluation board. | 63 | evaluation board. |
@@ -140,6 +141,7 @@ config SH_RSK | |||
140 | bool "Renesas Starter Kit" | 141 | bool "Renesas Starter Kit" |
141 | depends on CPU_SUBTYPE_SH7201 || CPU_SUBTYPE_SH7203 || \ | 142 | depends on CPU_SUBTYPE_SH7201 || CPU_SUBTYPE_SH7203 || \ |
142 | CPU_SUBTYPE_SH7264 || CPU_SUBTYPE_SH7269 | 143 | CPU_SUBTYPE_SH7264 || CPU_SUBTYPE_SH7269 |
144 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
143 | help | 145 | help |
144 | Select this option if configuring for any of the RSK+ MCU | 146 | Select this option if configuring for any of the RSK+ MCU |
145 | evaluation platforms. | 147 | evaluation platforms. |
@@ -159,6 +161,7 @@ config SH_SDK7786 | |||
159 | select NO_IOPORT if !PCI | 161 | select NO_IOPORT if !PCI |
160 | select ARCH_WANT_OPTIONAL_GPIOLIB | 162 | select ARCH_WANT_OPTIONAL_GPIOLIB |
161 | select HAVE_SRAM_POOL | 163 | select HAVE_SRAM_POOL |
164 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
162 | help | 165 | help |
163 | Select SDK7786 if configuring for a Renesas Technology Europe | 166 | Select SDK7786 if configuring for a Renesas Technology Europe |
164 | SH7786-65nm board. | 167 | SH7786-65nm board. |
@@ -173,6 +176,7 @@ config SH_SH7757LCR | |||
173 | bool "SH7757LCR" | 176 | bool "SH7757LCR" |
174 | depends on CPU_SUBTYPE_SH7757 | 177 | depends on CPU_SUBTYPE_SH7757 |
175 | select ARCH_REQUIRE_GPIOLIB | 178 | select ARCH_REQUIRE_GPIOLIB |
179 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
176 | 180 | ||
177 | config SH_SH7785LCR | 181 | config SH_SH7785LCR |
178 | bool "SH7785LCR" | 182 | bool "SH7785LCR" |
@@ -206,6 +210,7 @@ config SH_MIGOR | |||
206 | bool "Migo-R" | 210 | bool "Migo-R" |
207 | depends on CPU_SUBTYPE_SH7722 | 211 | depends on CPU_SUBTYPE_SH7722 |
208 | select ARCH_REQUIRE_GPIOLIB | 212 | select ARCH_REQUIRE_GPIOLIB |
213 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
209 | help | 214 | help |
210 | Select Migo-R if configuring for the SH7722 Migo-R platform | 215 | Select Migo-R if configuring for the SH7722 Migo-R platform |
211 | by Renesas System Solutions Asia Pte. Ltd. | 216 | by Renesas System Solutions Asia Pte. Ltd. |
@@ -214,6 +219,7 @@ config SH_AP325RXA | |||
214 | bool "AP-325RXA" | 219 | bool "AP-325RXA" |
215 | depends on CPU_SUBTYPE_SH7723 | 220 | depends on CPU_SUBTYPE_SH7723 |
216 | select ARCH_REQUIRE_GPIOLIB | 221 | select ARCH_REQUIRE_GPIOLIB |
222 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
217 | help | 223 | help |
218 | Renesas "AP-325RXA" support. | 224 | Renesas "AP-325RXA" support. |
219 | Compatible with ALGO SYSTEM CO.,LTD. "AP-320A" | 225 | Compatible with ALGO SYSTEM CO.,LTD. "AP-320A" |
@@ -222,6 +228,7 @@ config SH_KFR2R09 | |||
222 | bool "KFR2R09" | 228 | bool "KFR2R09" |
223 | depends on CPU_SUBTYPE_SH7724 | 229 | depends on CPU_SUBTYPE_SH7724 |
224 | select ARCH_REQUIRE_GPIOLIB | 230 | select ARCH_REQUIRE_GPIOLIB |
231 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
225 | help | 232 | help |
226 | "Kit For R2R for 2009" support. | 233 | "Kit For R2R for 2009" support. |
227 | 234 | ||
@@ -230,6 +237,7 @@ config SH_ECOVEC | |||
230 | depends on CPU_SUBTYPE_SH7724 | 237 | depends on CPU_SUBTYPE_SH7724 |
231 | select ARCH_REQUIRE_GPIOLIB | 238 | select ARCH_REQUIRE_GPIOLIB |
232 | select SND_SOC_DA7210 if SND_SIMPLE_CARD | 239 | select SND_SOC_DA7210 if SND_SIMPLE_CARD |
240 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
233 | help | 241 | help |
234 | Renesas "R0P7724LC0011/21RL (EcoVec)" support. | 242 | Renesas "R0P7724LC0011/21RL (EcoVec)" support. |
235 | 243 | ||
@@ -305,6 +313,7 @@ config SH_MAGIC_PANEL_R2 | |||
305 | bool "Magic Panel R2" | 313 | bool "Magic Panel R2" |
306 | depends on CPU_SUBTYPE_SH7720 | 314 | depends on CPU_SUBTYPE_SH7720 |
307 | select ARCH_REQUIRE_GPIOLIB | 315 | select ARCH_REQUIRE_GPIOLIB |
316 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
308 | help | 317 | help |
309 | Select Magic Panel R2 if configuring for Magic Panel R2. | 318 | Select Magic Panel R2 if configuring for Magic Panel R2. |
310 | 319 | ||
@@ -316,6 +325,7 @@ config SH_CAYMAN | |||
316 | config SH_POLARIS | 325 | config SH_POLARIS |
317 | bool "SMSC Polaris" | 326 | bool "SMSC Polaris" |
318 | select CPU_HAS_IPR_IRQ | 327 | select CPU_HAS_IPR_IRQ |
328 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
319 | depends on CPU_SUBTYPE_SH7709 | 329 | depends on CPU_SUBTYPE_SH7709 |
320 | help | 330 | help |
321 | Select if configuring for an SMSC Polaris development board | 331 | Select if configuring for an SMSC Polaris development board |
@@ -323,6 +333,7 @@ config SH_POLARIS | |||
323 | config SH_SH2007 | 333 | config SH_SH2007 |
324 | bool "SH-2007 board" | 334 | bool "SH-2007 board" |
325 | select NO_IOPORT | 335 | select NO_IOPORT |
336 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
326 | depends on CPU_SUBTYPE_SH7780 | 337 | depends on CPU_SUBTYPE_SH7780 |
327 | help | 338 | help |
328 | SH-2007 is a single-board computer based around SH7780 chip | 339 | SH-2007 is a single-board computer based around SH7780 chip |
@@ -334,6 +345,7 @@ config SH_SH2007 | |||
334 | config SH_APSH4A3A | 345 | config SH_APSH4A3A |
335 | bool "AP-SH4A-3A" | 346 | bool "AP-SH4A-3A" |
336 | select SH_ALPHA_BOARD | 347 | select SH_ALPHA_BOARD |
348 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
337 | depends on CPU_SUBTYPE_SH7785 | 349 | depends on CPU_SUBTYPE_SH7785 |
338 | help | 350 | help |
339 | Select AP-SH4A-3A if configuring for an ALPHAPROJECT AP-SH4A-3A. | 351 | Select AP-SH4A-3A if configuring for an ALPHAPROJECT AP-SH4A-3A. |
@@ -342,6 +354,7 @@ config SH_APSH4AD0A | |||
342 | bool "AP-SH4AD-0A" | 354 | bool "AP-SH4AD-0A" |
343 | select SH_ALPHA_BOARD | 355 | select SH_ALPHA_BOARD |
344 | select SYS_SUPPORTS_PCI | 356 | select SYS_SUPPORTS_PCI |
357 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | ||
345 | depends on CPU_SUBTYPE_SH7786 | 358 | depends on CPU_SUBTYPE_SH7786 |
346 | help | 359 | help |
347 | Select AP-SH4AD-0A if configuring for an ALPHAPROJECT AP-SH4AD-0A. | 360 | Select AP-SH4AD-0A if configuring for an ALPHAPROJECT AP-SH4AD-0A. |
diff --git a/arch/sh/boards/board-apsh4a3a.c b/arch/sh/boards/board-apsh4a3a.c index 2823619c6006..0a39c241628a 100644 --- a/arch/sh/boards/board-apsh4a3a.c +++ b/arch/sh/boards/board-apsh4a3a.c | |||
@@ -13,6 +13,8 @@ | |||
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/mtd/physmap.h> | 15 | #include <linux/mtd/physmap.h> |
16 | #include <linux/regulator/fixed.h> | ||
17 | #include <linux/regulator/machine.h> | ||
16 | #include <linux/smsc911x.h> | 18 | #include <linux/smsc911x.h> |
17 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
18 | #include <linux/clk.h> | 20 | #include <linux/clk.h> |
@@ -66,6 +68,12 @@ static struct platform_device nor_flash_device = { | |||
66 | .resource = nor_flash_resources, | 68 | .resource = nor_flash_resources, |
67 | }; | 69 | }; |
68 | 70 | ||
71 | /* Dummy supplies, where voltage doesn't matter */ | ||
72 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
73 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
74 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
75 | }; | ||
76 | |||
69 | static struct resource smsc911x_resources[] = { | 77 | static struct resource smsc911x_resources[] = { |
70 | [0] = { | 78 | [0] = { |
71 | .name = "smsc911x-memory", | 79 | .name = "smsc911x-memory", |
@@ -105,6 +113,8 @@ static struct platform_device *apsh4a3a_devices[] __initdata = { | |||
105 | 113 | ||
106 | static int __init apsh4a3a_devices_setup(void) | 114 | static int __init apsh4a3a_devices_setup(void) |
107 | { | 115 | { |
116 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
117 | |||
108 | return platform_add_devices(apsh4a3a_devices, | 118 | return platform_add_devices(apsh4a3a_devices, |
109 | ARRAY_SIZE(apsh4a3a_devices)); | 119 | ARRAY_SIZE(apsh4a3a_devices)); |
110 | } | 120 | } |
diff --git a/arch/sh/boards/board-apsh4ad0a.c b/arch/sh/boards/board-apsh4ad0a.c index b4d6292a9247..92eac3a99187 100644 --- a/arch/sh/boards/board-apsh4ad0a.c +++ b/arch/sh/boards/board-apsh4ad0a.c | |||
@@ -12,12 +12,20 @@ | |||
12 | #include <linux/init.h> | 12 | #include <linux/init.h> |
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/regulator/fixed.h> | ||
16 | #include <linux/regulator/machine.h> | ||
15 | #include <linux/smsc911x.h> | 17 | #include <linux/smsc911x.h> |
16 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
17 | #include <linux/clk.h> | 19 | #include <linux/clk.h> |
18 | #include <asm/machvec.h> | 20 | #include <asm/machvec.h> |
19 | #include <asm/sizes.h> | 21 | #include <asm/sizes.h> |
20 | 22 | ||
23 | /* Dummy supplies, where voltage doesn't matter */ | ||
24 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
25 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
26 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
27 | }; | ||
28 | |||
21 | static struct resource smsc911x_resources[] = { | 29 | static struct resource smsc911x_resources[] = { |
22 | [0] = { | 30 | [0] = { |
23 | .name = "smsc911x-memory", | 31 | .name = "smsc911x-memory", |
@@ -56,6 +64,8 @@ static struct platform_device *apsh4ad0a_devices[] __initdata = { | |||
56 | 64 | ||
57 | static int __init apsh4ad0a_devices_setup(void) | 65 | static int __init apsh4ad0a_devices_setup(void) |
58 | { | 66 | { |
67 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
68 | |||
59 | return platform_add_devices(apsh4ad0a_devices, | 69 | return platform_add_devices(apsh4ad0a_devices, |
60 | ARRAY_SIZE(apsh4ad0a_devices)); | 70 | ARRAY_SIZE(apsh4ad0a_devices)); |
61 | } | 71 | } |
diff --git a/arch/sh/boards/board-magicpanelr2.c b/arch/sh/boards/board-magicpanelr2.c index 90568f9de3a4..20500858b56c 100644 --- a/arch/sh/boards/board-magicpanelr2.c +++ b/arch/sh/boards/board-magicpanelr2.c | |||
@@ -14,6 +14,8 @@ | |||
14 | #include <linux/platform_device.h> | 14 | #include <linux/platform_device.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <linux/gpio.h> | 16 | #include <linux/gpio.h> |
17 | #include <linux/regulator/fixed.h> | ||
18 | #include <linux/regulator/machine.h> | ||
17 | #include <linux/smsc911x.h> | 19 | #include <linux/smsc911x.h> |
18 | #include <linux/mtd/mtd.h> | 20 | #include <linux/mtd/mtd.h> |
19 | #include <linux/mtd/partitions.h> | 21 | #include <linux/mtd/partitions.h> |
@@ -24,6 +26,12 @@ | |||
24 | #include <asm/heartbeat.h> | 26 | #include <asm/heartbeat.h> |
25 | #include <cpu/sh7720.h> | 27 | #include <cpu/sh7720.h> |
26 | 28 | ||
29 | /* Dummy supplies, where voltage doesn't matter */ | ||
30 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
31 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
32 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
33 | }; | ||
34 | |||
27 | #define LAN9115_READY (__raw_readl(0xA8000084UL) & 0x00000001UL) | 35 | #define LAN9115_READY (__raw_readl(0xA8000084UL) & 0x00000001UL) |
28 | 36 | ||
29 | /* Wait until reset finished. Timeout is 100ms. */ | 37 | /* Wait until reset finished. Timeout is 100ms. */ |
@@ -348,6 +356,8 @@ static struct platform_device *mpr2_devices[] __initdata = { | |||
348 | 356 | ||
349 | static int __init mpr2_devices_setup(void) | 357 | static int __init mpr2_devices_setup(void) |
350 | { | 358 | { |
359 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
360 | |||
351 | return platform_add_devices(mpr2_devices, ARRAY_SIZE(mpr2_devices)); | 361 | return platform_add_devices(mpr2_devices, ARRAY_SIZE(mpr2_devices)); |
352 | } | 362 | } |
353 | device_initcall(mpr2_devices_setup); | 363 | device_initcall(mpr2_devices_setup); |
diff --git a/arch/sh/boards/board-polaris.c b/arch/sh/boards/board-polaris.c index 0978ae2e4847..37a08d094727 100644 --- a/arch/sh/boards/board-polaris.c +++ b/arch/sh/boards/board-polaris.c | |||
@@ -9,6 +9,8 @@ | |||
9 | #include <linux/interrupt.h> | 9 | #include <linux/interrupt.h> |
10 | #include <linux/irq.h> | 10 | #include <linux/irq.h> |
11 | #include <linux/platform_device.h> | 11 | #include <linux/platform_device.h> |
12 | #include <linux/regulator/fixed.h> | ||
13 | #include <linux/regulator/machine.h> | ||
12 | #include <linux/smsc911x.h> | 14 | #include <linux/smsc911x.h> |
13 | #include <linux/io.h> | 15 | #include <linux/io.h> |
14 | #include <asm/irq.h> | 16 | #include <asm/irq.h> |
@@ -22,6 +24,12 @@ | |||
22 | #define AREA5_WAIT_CTRL (0x1C00) | 24 | #define AREA5_WAIT_CTRL (0x1C00) |
23 | #define WAIT_STATES_10 (0x7) | 25 | #define WAIT_STATES_10 (0x7) |
24 | 26 | ||
27 | /* Dummy supplies, where voltage doesn't matter */ | ||
28 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
29 | REGULATOR_SUPPLY("vddvario", "smsc911x.0"), | ||
30 | REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), | ||
31 | }; | ||
32 | |||
25 | static struct resource smsc911x_resources[] = { | 33 | static struct resource smsc911x_resources[] = { |
26 | [0] = { | 34 | [0] = { |
27 | .name = "smsc911x-memory", | 35 | .name = "smsc911x-memory", |
@@ -88,6 +96,8 @@ static int __init polaris_initialise(void) | |||
88 | 96 | ||
89 | printk(KERN_INFO "Configuring Polaris external bus\n"); | 97 | printk(KERN_INFO "Configuring Polaris external bus\n"); |
90 | 98 | ||
99 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
100 | |||
91 | /* Configure area 5 with 2 wait states */ | 101 | /* Configure area 5 with 2 wait states */ |
92 | wcr = __raw_readw(WCR2); | 102 | wcr = __raw_readw(WCR2); |
93 | wcr &= (~AREA5_WAIT_CTRL); | 103 | wcr &= (~AREA5_WAIT_CTRL); |
diff --git a/arch/sh/boards/board-sh2007.c b/arch/sh/boards/board-sh2007.c index b90b78f6a829..1980bb7e5780 100644 --- a/arch/sh/boards/board-sh2007.c +++ b/arch/sh/boards/board-sh2007.c | |||
@@ -6,6 +6,8 @@ | |||
6 | */ | 6 | */ |
7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
8 | #include <linux/irq.h> | 8 | #include <linux/irq.h> |
9 | #include <linux/regulator/fixed.h> | ||
10 | #include <linux/regulator/machine.h> | ||
9 | #include <linux/smsc911x.h> | 11 | #include <linux/smsc911x.h> |
10 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
11 | #include <linux/ata_platform.h> | 13 | #include <linux/ata_platform.h> |
@@ -13,6 +15,14 @@ | |||
13 | #include <asm/machvec.h> | 15 | #include <asm/machvec.h> |
14 | #include <mach/sh2007.h> | 16 | #include <mach/sh2007.h> |
15 | 17 | ||
18 | /* Dummy supplies, where voltage doesn't matter */ | ||
19 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
20 | REGULATOR_SUPPLY("vddvario", "smsc911x.0"), | ||
21 | REGULATOR_SUPPLY("vdd33a", "smsc911x.0"), | ||
22 | REGULATOR_SUPPLY("vddvario", "smsc911x.1"), | ||
23 | REGULATOR_SUPPLY("vdd33a", "smsc911x.1"), | ||
24 | }; | ||
25 | |||
16 | struct smsc911x_platform_config smc911x_info = { | 26 | struct smsc911x_platform_config smc911x_info = { |
17 | .flags = SMSC911X_USE_32BIT, | 27 | .flags = SMSC911X_USE_32BIT, |
18 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | 28 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, |
@@ -98,6 +108,8 @@ static struct platform_device *sh2007_devices[] __initdata = { | |||
98 | 108 | ||
99 | static int __init sh2007_io_init(void) | 109 | static int __init sh2007_io_init(void) |
100 | { | 110 | { |
111 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
112 | |||
101 | platform_add_devices(sh2007_devices, ARRAY_SIZE(sh2007_devices)); | 113 | platform_add_devices(sh2007_devices, ARRAY_SIZE(sh2007_devices)); |
102 | return 0; | 114 | return 0; |
103 | } | 115 | } |
diff --git a/arch/sh/boards/board-sh7757lcr.c b/arch/sh/boards/board-sh7757lcr.c index 5087f8bb4cff..41f86702eb9f 100644 --- a/arch/sh/boards/board-sh7757lcr.c +++ b/arch/sh/boards/board-sh7757lcr.c | |||
@@ -12,6 +12,8 @@ | |||
12 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
13 | #include <linux/gpio.h> | 13 | #include <linux/gpio.h> |
14 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
15 | #include <linux/regulator/fixed.h> | ||
16 | #include <linux/regulator/machine.h> | ||
15 | #include <linux/spi/spi.h> | 17 | #include <linux/spi/spi.h> |
16 | #include <linux/spi/flash.h> | 18 | #include <linux/spi/flash.h> |
17 | #include <linux/io.h> | 19 | #include <linux/io.h> |
@@ -199,6 +201,15 @@ static struct platform_device sh7757_eth_giga1_device = { | |||
199 | }, | 201 | }, |
200 | }; | 202 | }; |
201 | 203 | ||
204 | /* Fixed 3.3V regulator to be used by SDHI0, MMCIF */ | ||
205 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = | ||
206 | { | ||
207 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
208 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
209 | REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), | ||
210 | REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"), | ||
211 | }; | ||
212 | |||
202 | /* SH_MMCIF */ | 213 | /* SH_MMCIF */ |
203 | static struct resource sh_mmcif_resources[] = { | 214 | static struct resource sh_mmcif_resources[] = { |
204 | [0] = { | 215 | [0] = { |
@@ -329,6 +340,9 @@ static struct spi_board_info spi_board_info[] = { | |||
329 | 340 | ||
330 | static int __init sh7757lcr_devices_setup(void) | 341 | static int __init sh7757lcr_devices_setup(void) |
331 | { | 342 | { |
343 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, | ||
344 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | ||
345 | |||
332 | /* RGMII (PTA) */ | 346 | /* RGMII (PTA) */ |
333 | gpio_request(GPIO_FN_ET0_MDC, NULL); | 347 | gpio_request(GPIO_FN_ET0_MDC, NULL); |
334 | gpio_request(GPIO_FN_ET0_MDIO, NULL); | 348 | gpio_request(GPIO_FN_ET0_MDIO, NULL); |
diff --git a/arch/sh/boards/mach-ap325rxa/setup.c b/arch/sh/boards/mach-ap325rxa/setup.c index f33ebf447073..9e963c1d1447 100644 --- a/arch/sh/boards/mach-ap325rxa/setup.c +++ b/arch/sh/boards/mach-ap325rxa/setup.c | |||
@@ -20,6 +20,8 @@ | |||
20 | #include <linux/mtd/sh_flctl.h> | 20 | #include <linux/mtd/sh_flctl.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/i2c.h> | 22 | #include <linux/i2c.h> |
23 | #include <linux/regulator/fixed.h> | ||
24 | #include <linux/regulator/machine.h> | ||
23 | #include <linux/smsc911x.h> | 25 | #include <linux/smsc911x.h> |
24 | #include <linux/gpio.h> | 26 | #include <linux/gpio.h> |
25 | #include <linux/videodev2.h> | 27 | #include <linux/videodev2.h> |
@@ -34,6 +36,12 @@ | |||
34 | #include <asm/suspend.h> | 36 | #include <asm/suspend.h> |
35 | #include <cpu/sh7723.h> | 37 | #include <cpu/sh7723.h> |
36 | 38 | ||
39 | /* Dummy supplies, where voltage doesn't matter */ | ||
40 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
41 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
42 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
43 | }; | ||
44 | |||
37 | static struct smsc911x_platform_config smsc911x_config = { | 45 | static struct smsc911x_platform_config smsc911x_config = { |
38 | .phy_interface = PHY_INTERFACE_MODE_MII, | 46 | .phy_interface = PHY_INTERFACE_MODE_MII, |
39 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | 47 | .irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW, |
@@ -423,6 +431,15 @@ static struct platform_device ceu_device = { | |||
423 | }, | 431 | }, |
424 | }; | 432 | }; |
425 | 433 | ||
434 | /* Fixed 3.3V regulators to be used by SDHI0, SDHI1 */ | ||
435 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = | ||
436 | { | ||
437 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
438 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
439 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), | ||
440 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), | ||
441 | }; | ||
442 | |||
426 | static struct resource sdhi0_cn3_resources[] = { | 443 | static struct resource sdhi0_cn3_resources[] = { |
427 | [0] = { | 444 | [0] = { |
428 | .name = "SDHI0", | 445 | .name = "SDHI0", |
@@ -544,6 +561,10 @@ static int __init ap325rxa_devices_setup(void) | |||
544 | &ap325rxa_sdram_leave_start, | 561 | &ap325rxa_sdram_leave_start, |
545 | &ap325rxa_sdram_leave_end); | 562 | &ap325rxa_sdram_leave_end); |
546 | 563 | ||
564 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, | ||
565 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | ||
566 | regulator_register_fixed(1, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
567 | |||
547 | /* LD3 and LD4 LEDs */ | 568 | /* LD3 and LD4 LEDs */ |
548 | gpio_request(GPIO_PTX5, NULL); /* RUN */ | 569 | gpio_request(GPIO_PTX5, NULL); /* RUN */ |
549 | gpio_direction_output(GPIO_PTX5, 1); | 570 | gpio_direction_output(GPIO_PTX5, 1); |
diff --git a/arch/sh/boards/mach-ecovec24/setup.c b/arch/sh/boards/mach-ecovec24/setup.c index 4158d70c0dea..64559e8af14b 100644 --- a/arch/sh/boards/mach-ecovec24/setup.c +++ b/arch/sh/boards/mach-ecovec24/setup.c | |||
@@ -19,6 +19,8 @@ | |||
19 | #include <linux/interrupt.h> | 19 | #include <linux/interrupt.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | #include <linux/delay.h> | 21 | #include <linux/delay.h> |
22 | #include <linux/regulator/fixed.h> | ||
23 | #include <linux/regulator/machine.h> | ||
22 | #include <linux/usb/r8a66597.h> | 24 | #include <linux/usb/r8a66597.h> |
23 | #include <linux/usb/renesas_usbhs.h> | 25 | #include <linux/usb/renesas_usbhs.h> |
24 | #include <linux/i2c.h> | 26 | #include <linux/i2c.h> |
@@ -242,9 +244,17 @@ static int usbhs_get_id(struct platform_device *pdev) | |||
242 | return gpio_get_value(GPIO_PTB3); | 244 | return gpio_get_value(GPIO_PTB3); |
243 | } | 245 | } |
244 | 246 | ||
247 | static void usbhs_phy_reset(struct platform_device *pdev) | ||
248 | { | ||
249 | /* enable vbus if HOST */ | ||
250 | if (!gpio_get_value(GPIO_PTB3)) | ||
251 | gpio_set_value(GPIO_PTB5, 1); | ||
252 | } | ||
253 | |||
245 | static struct renesas_usbhs_platform_info usbhs_info = { | 254 | static struct renesas_usbhs_platform_info usbhs_info = { |
246 | .platform_callback = { | 255 | .platform_callback = { |
247 | .get_id = usbhs_get_id, | 256 | .get_id = usbhs_get_id, |
257 | .phy_reset = usbhs_phy_reset, | ||
248 | }, | 258 | }, |
249 | .driver_param = { | 259 | .driver_param = { |
250 | .buswait_bwait = 4, | 260 | .buswait_bwait = 4, |
@@ -518,10 +528,86 @@ static struct i2c_board_info ts_i2c_clients = { | |||
518 | .irq = IRQ0, | 528 | .irq = IRQ0, |
519 | }; | 529 | }; |
520 | 530 | ||
531 | static struct regulator_consumer_supply cn12_power_consumers[] = | ||
532 | { | ||
533 | REGULATOR_SUPPLY("vmmc", "sh_mmcif.0"), | ||
534 | REGULATOR_SUPPLY("vqmmc", "sh_mmcif.0"), | ||
535 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), | ||
536 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), | ||
537 | }; | ||
538 | |||
539 | static struct regulator_init_data cn12_power_init_data = { | ||
540 | .constraints = { | ||
541 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
542 | }, | ||
543 | .num_consumer_supplies = ARRAY_SIZE(cn12_power_consumers), | ||
544 | .consumer_supplies = cn12_power_consumers, | ||
545 | }; | ||
546 | |||
547 | static struct fixed_voltage_config cn12_power_info = { | ||
548 | .supply_name = "CN12 SD/MMC Vdd", | ||
549 | .microvolts = 3300000, | ||
550 | .gpio = GPIO_PTB7, | ||
551 | .enable_high = 1, | ||
552 | .init_data = &cn12_power_init_data, | ||
553 | }; | ||
554 | |||
555 | static struct platform_device cn12_power = { | ||
556 | .name = "reg-fixed-voltage", | ||
557 | .id = 0, | ||
558 | .dev = { | ||
559 | .platform_data = &cn12_power_info, | ||
560 | }, | ||
561 | }; | ||
562 | |||
521 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) | 563 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) |
522 | /* SDHI0 */ | 564 | /* SDHI0 */ |
565 | static struct regulator_consumer_supply sdhi0_power_consumers[] = | ||
566 | { | ||
567 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
568 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
569 | }; | ||
570 | |||
571 | static struct regulator_init_data sdhi0_power_init_data = { | ||
572 | .constraints = { | ||
573 | .valid_ops_mask = REGULATOR_CHANGE_STATUS, | ||
574 | }, | ||
575 | .num_consumer_supplies = ARRAY_SIZE(sdhi0_power_consumers), | ||
576 | .consumer_supplies = sdhi0_power_consumers, | ||
577 | }; | ||
578 | |||
579 | static struct fixed_voltage_config sdhi0_power_info = { | ||
580 | .supply_name = "CN11 SD/MMC Vdd", | ||
581 | .microvolts = 3300000, | ||
582 | .gpio = GPIO_PTB6, | ||
583 | .enable_high = 1, | ||
584 | .init_data = &sdhi0_power_init_data, | ||
585 | }; | ||
586 | |||
587 | static struct platform_device sdhi0_power = { | ||
588 | .name = "reg-fixed-voltage", | ||
589 | .id = 1, | ||
590 | .dev = { | ||
591 | .platform_data = &sdhi0_power_info, | ||
592 | }, | ||
593 | }; | ||
594 | |||
523 | static void sdhi0_set_pwr(struct platform_device *pdev, int state) | 595 | static void sdhi0_set_pwr(struct platform_device *pdev, int state) |
524 | { | 596 | { |
597 | static int power_gpio = -EINVAL; | ||
598 | |||
599 | if (power_gpio < 0) { | ||
600 | int ret = gpio_request(GPIO_PTB6, NULL); | ||
601 | if (!ret) { | ||
602 | power_gpio = GPIO_PTB6; | ||
603 | gpio_direction_output(power_gpio, 0); | ||
604 | } | ||
605 | } | ||
606 | |||
607 | /* | ||
608 | * Toggle the GPIO regardless, whether we managed to grab it above or | ||
609 | * the fixed regulator driver did. | ||
610 | */ | ||
525 | gpio_set_value(GPIO_PTB6, state); | 611 | gpio_set_value(GPIO_PTB6, state); |
526 | } | 612 | } |
527 | 613 | ||
@@ -562,13 +648,27 @@ static struct platform_device sdhi0_device = { | |||
562 | }, | 648 | }, |
563 | }; | 649 | }; |
564 | 650 | ||
565 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) | 651 | static void cn12_set_pwr(struct platform_device *pdev, int state) |
566 | /* SDHI1 */ | ||
567 | static void sdhi1_set_pwr(struct platform_device *pdev, int state) | ||
568 | { | 652 | { |
653 | static int power_gpio = -EINVAL; | ||
654 | |||
655 | if (power_gpio < 0) { | ||
656 | int ret = gpio_request(GPIO_PTB7, NULL); | ||
657 | if (!ret) { | ||
658 | power_gpio = GPIO_PTB7; | ||
659 | gpio_direction_output(power_gpio, 0); | ||
660 | } | ||
661 | } | ||
662 | |||
663 | /* | ||
664 | * Toggle the GPIO regardless, whether we managed to grab it above or | ||
665 | * the fixed regulator driver did. | ||
666 | */ | ||
569 | gpio_set_value(GPIO_PTB7, state); | 667 | gpio_set_value(GPIO_PTB7, state); |
570 | } | 668 | } |
571 | 669 | ||
670 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) | ||
671 | /* SDHI1 */ | ||
572 | static int sdhi1_get_cd(struct platform_device *pdev) | 672 | static int sdhi1_get_cd(struct platform_device *pdev) |
573 | { | 673 | { |
574 | return !gpio_get_value(GPIO_PTW7); | 674 | return !gpio_get_value(GPIO_PTW7); |
@@ -579,7 +679,7 @@ static struct sh_mobile_sdhi_info sdhi1_info = { | |||
579 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, | 679 | .dma_slave_rx = SHDMA_SLAVE_SDHI1_RX, |
580 | .tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD | | 680 | .tmio_caps = MMC_CAP_SDIO_IRQ | MMC_CAP_POWER_OFF_CARD | |
581 | MMC_CAP_NEEDS_POLL, | 681 | MMC_CAP_NEEDS_POLL, |
582 | .set_pwr = sdhi1_set_pwr, | 682 | .set_pwr = cn12_set_pwr, |
583 | .get_cd = sdhi1_get_cd, | 683 | .get_cd = sdhi1_get_cd, |
584 | }; | 684 | }; |
585 | 685 | ||
@@ -899,14 +999,9 @@ static struct platform_device vou_device = { | |||
899 | 999 | ||
900 | #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) | 1000 | #if defined(CONFIG_MMC_SH_MMCIF) || defined(CONFIG_MMC_SH_MMCIF_MODULE) |
901 | /* SH_MMCIF */ | 1001 | /* SH_MMCIF */ |
902 | static void mmcif_set_pwr(struct platform_device *pdev, int state) | ||
903 | { | ||
904 | gpio_set_value(GPIO_PTB7, state); | ||
905 | } | ||
906 | |||
907 | static void mmcif_down_pwr(struct platform_device *pdev) | 1002 | static void mmcif_down_pwr(struct platform_device *pdev) |
908 | { | 1003 | { |
909 | gpio_set_value(GPIO_PTB7, 0); | 1004 | cn12_set_pwr(pdev, 0); |
910 | } | 1005 | } |
911 | 1006 | ||
912 | static struct resource sh_mmcif_resources[] = { | 1007 | static struct resource sh_mmcif_resources[] = { |
@@ -929,7 +1024,7 @@ static struct resource sh_mmcif_resources[] = { | |||
929 | }; | 1024 | }; |
930 | 1025 | ||
931 | static struct sh_mmcif_plat_data sh_mmcif_plat = { | 1026 | static struct sh_mmcif_plat_data sh_mmcif_plat = { |
932 | .set_pwr = mmcif_set_pwr, | 1027 | .set_pwr = cn12_set_pwr, |
933 | .down_pwr = mmcif_down_pwr, | 1028 | .down_pwr = mmcif_down_pwr, |
934 | .sup_pclk = 0, /* SH7724: Max Pclk/2 */ | 1029 | .sup_pclk = 0, /* SH7724: Max Pclk/2 */ |
935 | .caps = MMC_CAP_4_BIT_DATA | | 1030 | .caps = MMC_CAP_4_BIT_DATA | |
@@ -960,7 +1055,9 @@ static struct platform_device *ecovec_devices[] __initdata = { | |||
960 | &ceu0_device, | 1055 | &ceu0_device, |
961 | &ceu1_device, | 1056 | &ceu1_device, |
962 | &keysc_device, | 1057 | &keysc_device, |
1058 | &cn12_power, | ||
963 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) | 1059 | #if defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) |
1060 | &sdhi0_power, | ||
964 | &sdhi0_device, | 1061 | &sdhi0_device, |
965 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) | 1062 | #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE) |
966 | &sdhi1_device, | 1063 | &sdhi1_device, |
@@ -1258,8 +1355,6 @@ static int __init arch_setup(void) | |||
1258 | gpio_request(GPIO_FN_SDHI0D2, NULL); | 1355 | gpio_request(GPIO_FN_SDHI0D2, NULL); |
1259 | gpio_request(GPIO_FN_SDHI0D1, NULL); | 1356 | gpio_request(GPIO_FN_SDHI0D1, NULL); |
1260 | gpio_request(GPIO_FN_SDHI0D0, NULL); | 1357 | gpio_request(GPIO_FN_SDHI0D0, NULL); |
1261 | gpio_request(GPIO_PTB6, NULL); | ||
1262 | gpio_direction_output(GPIO_PTB6, 0); | ||
1263 | #else | 1358 | #else |
1264 | /* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */ | 1359 | /* enable MSIOF0 on CN11 (needs DS2.4 set to OFF) */ |
1265 | gpio_request(GPIO_FN_MSIOF0_TXD, NULL); | 1360 | gpio_request(GPIO_FN_MSIOF0_TXD, NULL); |
@@ -1288,8 +1383,6 @@ static int __init arch_setup(void) | |||
1288 | gpio_request(GPIO_FN_MMC_D0, NULL); | 1383 | gpio_request(GPIO_FN_MMC_D0, NULL); |
1289 | gpio_request(GPIO_FN_MMC_CLK, NULL); | 1384 | gpio_request(GPIO_FN_MMC_CLK, NULL); |
1290 | gpio_request(GPIO_FN_MMC_CMD, NULL); | 1385 | gpio_request(GPIO_FN_MMC_CMD, NULL); |
1291 | gpio_request(GPIO_PTB7, NULL); | ||
1292 | gpio_direction_output(GPIO_PTB7, 0); | ||
1293 | 1386 | ||
1294 | cn12_enabled = true; | 1387 | cn12_enabled = true; |
1295 | #elif defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) | 1388 | #elif defined(CONFIG_MMC_SDHI) || defined(CONFIG_MMC_SDHI_MODULE) |
@@ -1301,8 +1394,6 @@ static int __init arch_setup(void) | |||
1301 | gpio_request(GPIO_FN_SDHI1D2, NULL); | 1394 | gpio_request(GPIO_FN_SDHI1D2, NULL); |
1302 | gpio_request(GPIO_FN_SDHI1D1, NULL); | 1395 | gpio_request(GPIO_FN_SDHI1D1, NULL); |
1303 | gpio_request(GPIO_FN_SDHI1D0, NULL); | 1396 | gpio_request(GPIO_FN_SDHI1D0, NULL); |
1304 | gpio_request(GPIO_PTB7, NULL); | ||
1305 | gpio_direction_output(GPIO_PTB7, 0); | ||
1306 | 1397 | ||
1307 | /* Card-detect, used on CN12 with SDHI1 */ | 1398 | /* Card-detect, used on CN12 with SDHI1 */ |
1308 | gpio_request(GPIO_PTW7, NULL); | 1399 | gpio_request(GPIO_PTW7, NULL); |
diff --git a/arch/sh/boards/mach-kfr2r09/setup.c b/arch/sh/boards/mach-kfr2r09/setup.c index 43a179ce9afc..f2a4304fbe23 100644 --- a/arch/sh/boards/mach-kfr2r09/setup.c +++ b/arch/sh/boards/mach-kfr2r09/setup.c | |||
@@ -21,6 +21,8 @@ | |||
21 | #include <linux/input.h> | 21 | #include <linux/input.h> |
22 | #include <linux/input/sh_keysc.h> | 22 | #include <linux/input/sh_keysc.h> |
23 | #include <linux/i2c.h> | 23 | #include <linux/i2c.h> |
24 | #include <linux/regulator/fixed.h> | ||
25 | #include <linux/regulator/machine.h> | ||
24 | #include <linux/usb/r8a66597.h> | 26 | #include <linux/usb/r8a66597.h> |
25 | #include <linux/videodev2.h> | 27 | #include <linux/videodev2.h> |
26 | #include <linux/sh_intc.h> | 28 | #include <linux/sh_intc.h> |
@@ -341,6 +343,13 @@ static struct platform_device kfr2r09_camera = { | |||
341 | }, | 343 | }, |
342 | }; | 344 | }; |
343 | 345 | ||
346 | /* Fixed 3.3V regulator to be used by SDHI0 */ | ||
347 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = | ||
348 | { | ||
349 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
350 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
351 | }; | ||
352 | |||
344 | static struct resource kfr2r09_sh_sdhi0_resources[] = { | 353 | static struct resource kfr2r09_sh_sdhi0_resources[] = { |
345 | [0] = { | 354 | [0] = { |
346 | .name = "SDHI0", | 355 | .name = "SDHI0", |
@@ -523,6 +532,9 @@ static int __init kfr2r09_devices_setup(void) | |||
523 | &kfr2r09_sdram_leave_start, | 532 | &kfr2r09_sdram_leave_start, |
524 | &kfr2r09_sdram_leave_end); | 533 | &kfr2r09_sdram_leave_end); |
525 | 534 | ||
535 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, | ||
536 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | ||
537 | |||
526 | /* enable SCIF1 serial port for YC401 console support */ | 538 | /* enable SCIF1 serial port for YC401 console support */ |
527 | gpio_request(GPIO_FN_SCIF1_RXD, NULL); | 539 | gpio_request(GPIO_FN_SCIF1_RXD, NULL); |
528 | gpio_request(GPIO_FN_SCIF1_TXD, NULL); | 540 | gpio_request(GPIO_FN_SCIF1_TXD, NULL); |
diff --git a/arch/sh/boards/mach-migor/setup.c b/arch/sh/boards/mach-migor/setup.c index a8a1ca741c85..8b73194ed2ce 100644 --- a/arch/sh/boards/mach-migor/setup.c +++ b/arch/sh/boards/mach-migor/setup.c | |||
@@ -17,6 +17,8 @@ | |||
17 | #include <linux/mtd/physmap.h> | 17 | #include <linux/mtd/physmap.h> |
18 | #include <linux/mtd/nand.h> | 18 | #include <linux/mtd/nand.h> |
19 | #include <linux/i2c.h> | 19 | #include <linux/i2c.h> |
20 | #include <linux/regulator/fixed.h> | ||
21 | #include <linux/regulator/machine.h> | ||
20 | #include <linux/smc91x.h> | 22 | #include <linux/smc91x.h> |
21 | #include <linux/delay.h> | 23 | #include <linux/delay.h> |
22 | #include <linux/clk.h> | 24 | #include <linux/clk.h> |
@@ -386,6 +388,13 @@ static struct platform_device migor_ceu_device = { | |||
386 | }, | 388 | }, |
387 | }; | 389 | }; |
388 | 390 | ||
391 | /* Fixed 3.3V regulator to be used by SDHI0 */ | ||
392 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = | ||
393 | { | ||
394 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
395 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
396 | }; | ||
397 | |||
389 | static struct resource sdhi_cn9_resources[] = { | 398 | static struct resource sdhi_cn9_resources[] = { |
390 | [0] = { | 399 | [0] = { |
391 | .name = "SDHI", | 400 | .name = "SDHI", |
@@ -498,6 +507,10 @@ static int __init migor_devices_setup(void) | |||
498 | &migor_sdram_enter_end, | 507 | &migor_sdram_enter_end, |
499 | &migor_sdram_leave_start, | 508 | &migor_sdram_leave_start, |
500 | &migor_sdram_leave_end); | 509 | &migor_sdram_leave_end); |
510 | |||
511 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, | ||
512 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | ||
513 | |||
501 | /* Let D11 LED show STATUS0 */ | 514 | /* Let D11 LED show STATUS0 */ |
502 | gpio_request(GPIO_FN_STATUS0, NULL); | 515 | gpio_request(GPIO_FN_STATUS0, NULL); |
503 | 516 | ||
diff --git a/arch/sh/boards/mach-rsk/setup.c b/arch/sh/boards/mach-rsk/setup.c index 895f030070d3..2685ea03b064 100644 --- a/arch/sh/boards/mach-rsk/setup.c +++ b/arch/sh/boards/mach-rsk/setup.c | |||
@@ -16,9 +16,17 @@ | |||
16 | #include <linux/mtd/partitions.h> | 16 | #include <linux/mtd/partitions.h> |
17 | #include <linux/mtd/physmap.h> | 17 | #include <linux/mtd/physmap.h> |
18 | #include <linux/mtd/map.h> | 18 | #include <linux/mtd/map.h> |
19 | #include <linux/regulator/fixed.h> | ||
20 | #include <linux/regulator/machine.h> | ||
19 | #include <asm/machvec.h> | 21 | #include <asm/machvec.h> |
20 | #include <asm/io.h> | 22 | #include <asm/io.h> |
21 | 23 | ||
24 | /* Dummy supplies, where voltage doesn't matter */ | ||
25 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
26 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
27 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
28 | }; | ||
29 | |||
22 | static const char *part_probes[] = { "cmdlinepart", NULL }; | 30 | static const char *part_probes[] = { "cmdlinepart", NULL }; |
23 | 31 | ||
24 | static struct mtd_partition rsk_partitions[] = { | 32 | static struct mtd_partition rsk_partitions[] = { |
@@ -67,6 +75,8 @@ static struct platform_device *rsk_devices[] __initdata = { | |||
67 | 75 | ||
68 | static int __init rsk_devices_setup(void) | 76 | static int __init rsk_devices_setup(void) |
69 | { | 77 | { |
78 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
79 | |||
70 | return platform_add_devices(rsk_devices, | 80 | return platform_add_devices(rsk_devices, |
71 | ARRAY_SIZE(rsk_devices)); | 81 | ARRAY_SIZE(rsk_devices)); |
72 | } | 82 | } |
diff --git a/arch/sh/boards/mach-sdk7786/setup.c b/arch/sh/boards/mach-sdk7786/setup.c index 27a2314f50ac..c29268bfd34a 100644 --- a/arch/sh/boards/mach-sdk7786/setup.c +++ b/arch/sh/boards/mach-sdk7786/setup.c | |||
@@ -11,6 +11,8 @@ | |||
11 | #include <linux/init.h> | 11 | #include <linux/init.h> |
12 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
13 | #include <linux/io.h> | 13 | #include <linux/io.h> |
14 | #include <linux/regulator/fixed.h> | ||
15 | #include <linux/regulator/machine.h> | ||
14 | #include <linux/smsc911x.h> | 16 | #include <linux/smsc911x.h> |
15 | #include <linux/i2c.h> | 17 | #include <linux/i2c.h> |
16 | #include <linux/irq.h> | 18 | #include <linux/irq.h> |
@@ -38,6 +40,12 @@ static struct platform_device heartbeat_device = { | |||
38 | .resource = &heartbeat_resource, | 40 | .resource = &heartbeat_resource, |
39 | }; | 41 | }; |
40 | 42 | ||
43 | /* Dummy supplies, where voltage doesn't matter */ | ||
44 | static struct regulator_consumer_supply dummy_supplies[] = { | ||
45 | REGULATOR_SUPPLY("vddvario", "smsc911x"), | ||
46 | REGULATOR_SUPPLY("vdd33a", "smsc911x"), | ||
47 | }; | ||
48 | |||
41 | static struct resource smsc911x_resources[] = { | 49 | static struct resource smsc911x_resources[] = { |
42 | [0] = { | 50 | [0] = { |
43 | .name = "smsc911x-memory", | 51 | .name = "smsc911x-memory", |
@@ -236,6 +244,8 @@ static void __init sdk7786_setup(char **cmdline_p) | |||
236 | { | 244 | { |
237 | pr_info("Renesas Technology Europe SDK7786 support:\n"); | 245 | pr_info("Renesas Technology Europe SDK7786 support:\n"); |
238 | 246 | ||
247 | regulator_register_fixed(0, dummy_supplies, ARRAY_SIZE(dummy_supplies)); | ||
248 | |||
239 | sdk7786_fpga_init(); | 249 | sdk7786_fpga_init(); |
240 | sdk7786_nmi_init(); | 250 | sdk7786_nmi_init(); |
241 | 251 | ||
diff --git a/arch/sh/boards/mach-se/7724/setup.c b/arch/sh/boards/mach-se/7724/setup.c index ffbf5bc7366b..35f6efa3ac0e 100644 --- a/arch/sh/boards/mach-se/7724/setup.c +++ b/arch/sh/boards/mach-se/7724/setup.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/mmc/sh_mobile_sdhi.h> | 18 | #include <linux/mmc/sh_mobile_sdhi.h> |
19 | #include <linux/mtd/physmap.h> | 19 | #include <linux/mtd/physmap.h> |
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/regulator/fixed.h> | ||
22 | #include <linux/regulator/machine.h> | ||
21 | #include <linux/smc91x.h> | 23 | #include <linux/smc91x.h> |
22 | #include <linux/gpio.h> | 24 | #include <linux/gpio.h> |
23 | #include <linux/input.h> | 25 | #include <linux/input.h> |
@@ -454,6 +456,15 @@ static struct platform_device sh7724_usb1_gadget_device = { | |||
454 | .resource = sh7724_usb1_gadget_resources, | 456 | .resource = sh7724_usb1_gadget_resources, |
455 | }; | 457 | }; |
456 | 458 | ||
459 | /* Fixed 3.3V regulator to be used by SDHI0, SDHI1 */ | ||
460 | static struct regulator_consumer_supply fixed3v3_power_consumers[] = | ||
461 | { | ||
462 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.0"), | ||
463 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.0"), | ||
464 | REGULATOR_SUPPLY("vmmc", "sh_mobile_sdhi.1"), | ||
465 | REGULATOR_SUPPLY("vqmmc", "sh_mobile_sdhi.1"), | ||
466 | }; | ||
467 | |||
457 | static struct resource sdhi0_cn7_resources[] = { | 468 | static struct resource sdhi0_cn7_resources[] = { |
458 | [0] = { | 469 | [0] = { |
459 | .name = "SDHI0", | 470 | .name = "SDHI0", |
@@ -684,6 +695,10 @@ static int __init devices_setup(void) | |||
684 | &ms7724se_sdram_enter_end, | 695 | &ms7724se_sdram_enter_end, |
685 | &ms7724se_sdram_leave_start, | 696 | &ms7724se_sdram_leave_start, |
686 | &ms7724se_sdram_leave_end); | 697 | &ms7724se_sdram_leave_end); |
698 | |||
699 | regulator_register_always_on(0, "fixed-3.3V", fixed3v3_power_consumers, | ||
700 | ARRAY_SIZE(fixed3v3_power_consumers), 3300000); | ||
701 | |||
687 | /* Reset Release */ | 702 | /* Reset Release */ |
688 | fpga_out = __raw_readw(FPGA_OUT); | 703 | fpga_out = __raw_readw(FPGA_OUT); |
689 | /* bit4: NTSC_PDN, bit5: NTSC_RESET */ | 704 | /* bit4: NTSC_PDN, bit5: NTSC_RESET */ |
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index 4c171f13b0e8..b22565623142 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c | |||
@@ -335,7 +335,7 @@ static int dmae_irq_init(void) | |||
335 | 335 | ||
336 | for (n = 0; n < NR_DMAE; n++) { | 336 | for (n = 0; n < NR_DMAE; n++) { |
337 | int i = request_irq(get_dma_error_irq(n), dma_err, | 337 | int i = request_irq(get_dma_error_irq(n), dma_err, |
338 | IRQF_SHARED, dmae_name[n], NULL); | 338 | IRQF_SHARED, dmae_name[n], (void *)dmae_name[n]); |
339 | if (unlikely(i < 0)) { | 339 | if (unlikely(i < 0)) { |
340 | printk(KERN_ERR "%s request_irq fail\n", dmae_name[n]); | 340 | printk(KERN_ERR "%s request_irq fail\n", dmae_name[n]); |
341 | return i; | 341 | return i; |
diff --git a/arch/sh/include/asm/sections.h b/arch/sh/include/asm/sections.h index 4a5350037c8f..1b6199740e98 100644 --- a/arch/sh/include/asm/sections.h +++ b/arch/sh/include/asm/sections.h | |||
@@ -6,7 +6,6 @@ | |||
6 | extern long __nosave_begin, __nosave_end; | 6 | extern long __nosave_begin, __nosave_end; |
7 | extern long __machvec_start, __machvec_end; | 7 | extern long __machvec_start, __machvec_end; |
8 | extern char __uncached_start, __uncached_end; | 8 | extern char __uncached_start, __uncached_end; |
9 | extern char _ebss[]; | ||
10 | extern char __start_eh_frame[], __stop_eh_frame[]; | 9 | extern char __start_eh_frame[], __stop_eh_frame[]; |
11 | 10 | ||
12 | #endif /* __ASM_SH_SECTIONS_H */ | 11 | #endif /* __ASM_SH_SECTIONS_H */ |
diff --git a/arch/sh/include/cpu-sh2a/cpu/sh7269.h b/arch/sh/include/cpu-sh2a/cpu/sh7269.h index 48d14498e774..2a0ca8780f0d 100644 --- a/arch/sh/include/cpu-sh2a/cpu/sh7269.h +++ b/arch/sh/include/cpu-sh2a/cpu/sh7269.h | |||
@@ -183,18 +183,30 @@ enum { | |||
183 | GPIO_FN_DV_DATA1, GPIO_FN_DV_DATA0, | 183 | GPIO_FN_DV_DATA1, GPIO_FN_DV_DATA0, |
184 | GPIO_FN_LCD_CLK, GPIO_FN_LCD_EXTCLK, | 184 | GPIO_FN_LCD_CLK, GPIO_FN_LCD_EXTCLK, |
185 | GPIO_FN_LCD_VSYNC, GPIO_FN_LCD_HSYNC, GPIO_FN_LCD_DE, | 185 | GPIO_FN_LCD_VSYNC, GPIO_FN_LCD_HSYNC, GPIO_FN_LCD_DE, |
186 | GPIO_FN_LCD_DATA23, GPIO_FN_LCD_DATA22, | 186 | GPIO_FN_LCD_DATA23_PG23, GPIO_FN_LCD_DATA22_PG22, |
187 | GPIO_FN_LCD_DATA21, GPIO_FN_LCD_DATA20, | 187 | GPIO_FN_LCD_DATA21_PG21, GPIO_FN_LCD_DATA20_PG20, |
188 | GPIO_FN_LCD_DATA19, GPIO_FN_LCD_DATA18, | 188 | GPIO_FN_LCD_DATA19_PG19, GPIO_FN_LCD_DATA18_PG18, |
189 | GPIO_FN_LCD_DATA17, GPIO_FN_LCD_DATA16, | 189 | GPIO_FN_LCD_DATA17_PG17, GPIO_FN_LCD_DATA16_PG16, |
190 | GPIO_FN_LCD_DATA15, GPIO_FN_LCD_DATA14, | 190 | GPIO_FN_LCD_DATA15_PG15, GPIO_FN_LCD_DATA14_PG14, |
191 | GPIO_FN_LCD_DATA13, GPIO_FN_LCD_DATA12, | 191 | GPIO_FN_LCD_DATA13_PG13, GPIO_FN_LCD_DATA12_PG12, |
192 | GPIO_FN_LCD_DATA11, GPIO_FN_LCD_DATA10, | 192 | GPIO_FN_LCD_DATA11_PG11, GPIO_FN_LCD_DATA10_PG10, |
193 | GPIO_FN_LCD_DATA9, GPIO_FN_LCD_DATA8, | 193 | GPIO_FN_LCD_DATA9_PG9, GPIO_FN_LCD_DATA8_PG8, |
194 | GPIO_FN_LCD_DATA7, GPIO_FN_LCD_DATA6, | 194 | GPIO_FN_LCD_DATA7_PG7, GPIO_FN_LCD_DATA6_PG6, |
195 | GPIO_FN_LCD_DATA5, GPIO_FN_LCD_DATA4, | 195 | GPIO_FN_LCD_DATA5_PG5, GPIO_FN_LCD_DATA4_PG4, |
196 | GPIO_FN_LCD_DATA3, GPIO_FN_LCD_DATA2, | 196 | GPIO_FN_LCD_DATA3_PG3, GPIO_FN_LCD_DATA2_PG2, |
197 | GPIO_FN_LCD_DATA1, GPIO_FN_LCD_DATA0, | 197 | GPIO_FN_LCD_DATA1_PG1, GPIO_FN_LCD_DATA0_PG0, |
198 | GPIO_FN_LCD_DATA23_PJ23, GPIO_FN_LCD_DATA22_PJ22, | ||
199 | GPIO_FN_LCD_DATA21_PJ21, GPIO_FN_LCD_DATA20_PJ20, | ||
200 | GPIO_FN_LCD_DATA19_PJ19, GPIO_FN_LCD_DATA18_PJ18, | ||
201 | GPIO_FN_LCD_DATA17_PJ17, GPIO_FN_LCD_DATA16_PJ16, | ||
202 | GPIO_FN_LCD_DATA15_PJ15, GPIO_FN_LCD_DATA14_PJ14, | ||
203 | GPIO_FN_LCD_DATA13_PJ13, GPIO_FN_LCD_DATA12_PJ12, | ||
204 | GPIO_FN_LCD_DATA11_PJ11, GPIO_FN_LCD_DATA10_PJ10, | ||
205 | GPIO_FN_LCD_DATA9_PJ9, GPIO_FN_LCD_DATA8_PJ8, | ||
206 | GPIO_FN_LCD_DATA7_PJ7, GPIO_FN_LCD_DATA6_PJ6, | ||
207 | GPIO_FN_LCD_DATA5_PJ5, GPIO_FN_LCD_DATA4_PJ4, | ||
208 | GPIO_FN_LCD_DATA3_PJ3, GPIO_FN_LCD_DATA2_PJ2, | ||
209 | GPIO_FN_LCD_DATA1_PJ1, GPIO_FN_LCD_DATA0_PJ0, | ||
198 | GPIO_FN_LCD_M_DISP, | 210 | GPIO_FN_LCD_M_DISP, |
199 | }; | 211 | }; |
200 | 212 | ||
diff --git a/arch/sh/include/cpu-sh4/cpu/sh7757.h b/arch/sh/include/cpu-sh4/cpu/sh7757.h index 41f9f8b9db73..5340f3bc1863 100644 --- a/arch/sh/include/cpu-sh4/cpu/sh7757.h +++ b/arch/sh/include/cpu-sh4/cpu/sh7757.h | |||
@@ -283,5 +283,7 @@ enum { | |||
283 | SHDMA_SLAVE_RIIC8_RX, | 283 | SHDMA_SLAVE_RIIC8_RX, |
284 | SHDMA_SLAVE_RIIC9_TX, | 284 | SHDMA_SLAVE_RIIC9_TX, |
285 | SHDMA_SLAVE_RIIC9_RX, | 285 | SHDMA_SLAVE_RIIC9_RX, |
286 | SHDMA_SLAVE_RSPI_TX, | ||
287 | SHDMA_SLAVE_RSPI_RX, | ||
286 | }; | 288 | }; |
287 | #endif /* __ASM_SH7757_H__ */ | 289 | #endif /* __ASM_SH7757_H__ */ |
diff --git a/arch/sh/kernel/cpu/sh2a/pinmux-sh7269.c b/arch/sh/kernel/cpu/sh2a/pinmux-sh7269.c index f25127c46eca..039e4587dd9b 100644 --- a/arch/sh/kernel/cpu/sh2a/pinmux-sh7269.c +++ b/arch/sh/kernel/cpu/sh2a/pinmux-sh7269.c | |||
@@ -758,12 +758,22 @@ enum { | |||
758 | DV_DATA3_MARK, DV_DATA2_MARK, DV_DATA1_MARK, DV_DATA0_MARK, | 758 | DV_DATA3_MARK, DV_DATA2_MARK, DV_DATA1_MARK, DV_DATA0_MARK, |
759 | LCD_CLK_MARK, LCD_EXTCLK_MARK, | 759 | LCD_CLK_MARK, LCD_EXTCLK_MARK, |
760 | LCD_VSYNC_MARK, LCD_HSYNC_MARK, LCD_DE_MARK, | 760 | LCD_VSYNC_MARK, LCD_HSYNC_MARK, LCD_DE_MARK, |
761 | LCD_DATA23_MARK, LCD_DATA22_MARK, LCD_DATA21_MARK, LCD_DATA20_MARK, | 761 | LCD_DATA23_PG23_MARK, LCD_DATA22_PG22_MARK, LCD_DATA21_PG21_MARK, |
762 | LCD_DATA19_MARK, LCD_DATA18_MARK, LCD_DATA17_MARK, LCD_DATA16_MARK, | 762 | LCD_DATA20_PG20_MARK, LCD_DATA19_PG19_MARK, LCD_DATA18_PG18_MARK, |
763 | LCD_DATA15_MARK, LCD_DATA14_MARK, LCD_DATA13_MARK, LCD_DATA12_MARK, | 763 | LCD_DATA17_PG17_MARK, LCD_DATA16_PG16_MARK, LCD_DATA15_PG15_MARK, |
764 | LCD_DATA11_MARK, LCD_DATA10_MARK, LCD_DATA9_MARK, LCD_DATA8_MARK, | 764 | LCD_DATA14_PG14_MARK, LCD_DATA13_PG13_MARK, LCD_DATA12_PG12_MARK, |
765 | LCD_DATA7_MARK, LCD_DATA6_MARK, LCD_DATA5_MARK, LCD_DATA4_MARK, | 765 | LCD_DATA11_PG11_MARK, LCD_DATA10_PG10_MARK, LCD_DATA9_PG9_MARK, |
766 | LCD_DATA3_MARK, LCD_DATA2_MARK, LCD_DATA1_MARK, LCD_DATA0_MARK, | 766 | LCD_DATA8_PG8_MARK, LCD_DATA7_PG7_MARK, LCD_DATA6_PG6_MARK, |
767 | LCD_DATA5_PG5_MARK, LCD_DATA4_PG4_MARK, LCD_DATA3_PG3_MARK, | ||
768 | LCD_DATA2_PG2_MARK, LCD_DATA1_PG1_MARK, LCD_DATA0_PG0_MARK, | ||
769 | LCD_DATA23_PJ23_MARK, LCD_DATA22_PJ22_MARK, LCD_DATA21_PJ21_MARK, | ||
770 | LCD_DATA20_PJ20_MARK, LCD_DATA19_PJ19_MARK, LCD_DATA18_PJ18_MARK, | ||
771 | LCD_DATA17_PJ17_MARK, LCD_DATA16_PJ16_MARK, LCD_DATA15_PJ15_MARK, | ||
772 | LCD_DATA14_PJ14_MARK, LCD_DATA13_PJ13_MARK, LCD_DATA12_PJ12_MARK, | ||
773 | LCD_DATA11_PJ11_MARK, LCD_DATA10_PJ10_MARK, LCD_DATA9_PJ9_MARK, | ||
774 | LCD_DATA8_PJ8_MARK, LCD_DATA7_PJ7_MARK, LCD_DATA6_PJ6_MARK, | ||
775 | LCD_DATA5_PJ5_MARK, LCD_DATA4_PJ4_MARK, LCD_DATA3_PJ3_MARK, | ||
776 | LCD_DATA2_PJ2_MARK, LCD_DATA1_PJ1_MARK, LCD_DATA0_PJ0_MARK, | ||
767 | LCD_TCON6_MARK, LCD_TCON5_MARK, LCD_TCON4_MARK, | 777 | LCD_TCON6_MARK, LCD_TCON5_MARK, LCD_TCON4_MARK, |
768 | LCD_TCON3_MARK, LCD_TCON2_MARK, LCD_TCON1_MARK, LCD_TCON0_MARK, | 778 | LCD_TCON3_MARK, LCD_TCON2_MARK, LCD_TCON1_MARK, LCD_TCON0_MARK, |
769 | LCD_M_DISP_MARK, | 779 | LCD_M_DISP_MARK, |
@@ -1036,6 +1046,7 @@ static pinmux_enum_t pinmux_data[] = { | |||
1036 | 1046 | ||
1037 | PINMUX_DATA(PF1_DATA, PF1MD_000), | 1047 | PINMUX_DATA(PF1_DATA, PF1MD_000), |
1038 | PINMUX_DATA(BACK_MARK, PF1MD_001), | 1048 | PINMUX_DATA(BACK_MARK, PF1MD_001), |
1049 | PINMUX_DATA(SSL10_MARK, PF1MD_011), | ||
1039 | PINMUX_DATA(TIOC4B_MARK, PF1MD_100), | 1050 | PINMUX_DATA(TIOC4B_MARK, PF1MD_100), |
1040 | PINMUX_DATA(DACK0_MARK, PF1MD_101), | 1051 | PINMUX_DATA(DACK0_MARK, PF1MD_101), |
1041 | 1052 | ||
@@ -1049,47 +1060,50 @@ static pinmux_enum_t pinmux_data[] = { | |||
1049 | PINMUX_DATA(PG27_DATA, PG27MD_00), | 1060 | PINMUX_DATA(PG27_DATA, PG27MD_00), |
1050 | PINMUX_DATA(LCD_TCON2_MARK, PG27MD_10), | 1061 | PINMUX_DATA(LCD_TCON2_MARK, PG27MD_10), |
1051 | PINMUX_DATA(LCD_EXTCLK_MARK, PG27MD_11), | 1062 | PINMUX_DATA(LCD_EXTCLK_MARK, PG27MD_11), |
1063 | PINMUX_DATA(LCD_DE_MARK, PG27MD_11), | ||
1052 | 1064 | ||
1053 | PINMUX_DATA(PG26_DATA, PG26MD_00), | 1065 | PINMUX_DATA(PG26_DATA, PG26MD_00), |
1054 | PINMUX_DATA(LCD_TCON1_MARK, PG26MD_10), | 1066 | PINMUX_DATA(LCD_TCON1_MARK, PG26MD_10), |
1067 | PINMUX_DATA(LCD_HSYNC_MARK, PG26MD_10), | ||
1055 | 1068 | ||
1056 | PINMUX_DATA(PG25_DATA, PG25MD_00), | 1069 | PINMUX_DATA(PG25_DATA, PG25MD_00), |
1057 | PINMUX_DATA(LCD_TCON0_MARK, PG25MD_10), | 1070 | PINMUX_DATA(LCD_TCON0_MARK, PG25MD_10), |
1071 | PINMUX_DATA(LCD_VSYNC_MARK, PG25MD_10), | ||
1058 | 1072 | ||
1059 | PINMUX_DATA(PG24_DATA, PG24MD_00), | 1073 | PINMUX_DATA(PG24_DATA, PG24MD_00), |
1060 | PINMUX_DATA(LCD_CLK_MARK, PG24MD_10), | 1074 | PINMUX_DATA(LCD_CLK_MARK, PG24MD_10), |
1061 | 1075 | ||
1062 | PINMUX_DATA(PG23_DATA, PG23MD_000), | 1076 | PINMUX_DATA(PG23_DATA, PG23MD_000), |
1063 | PINMUX_DATA(LCD_DATA23_MARK, PG23MD_010), | 1077 | PINMUX_DATA(LCD_DATA23_PG23_MARK, PG23MD_010), |
1064 | PINMUX_DATA(LCD_TCON6_MARK, PG23MD_011), | 1078 | PINMUX_DATA(LCD_TCON6_MARK, PG23MD_011), |
1065 | PINMUX_DATA(TXD5_MARK, PG23MD_100), | 1079 | PINMUX_DATA(TXD5_MARK, PG23MD_100), |
1066 | 1080 | ||
1067 | PINMUX_DATA(PG22_DATA, PG22MD_000), | 1081 | PINMUX_DATA(PG22_DATA, PG22MD_000), |
1068 | PINMUX_DATA(LCD_DATA22_MARK, PG22MD_010), | 1082 | PINMUX_DATA(LCD_DATA22_PG22_MARK, PG22MD_010), |
1069 | PINMUX_DATA(LCD_TCON5_MARK, PG22MD_011), | 1083 | PINMUX_DATA(LCD_TCON5_MARK, PG22MD_011), |
1070 | PINMUX_DATA(RXD5_MARK, PG22MD_100), | 1084 | PINMUX_DATA(RXD5_MARK, PG22MD_100), |
1071 | 1085 | ||
1072 | PINMUX_DATA(PG21_DATA, PG21MD_000), | 1086 | PINMUX_DATA(PG21_DATA, PG21MD_000), |
1073 | PINMUX_DATA(DV_DATA7_MARK, PG21MD_001), | 1087 | PINMUX_DATA(DV_DATA7_MARK, PG21MD_001), |
1074 | PINMUX_DATA(LCD_DATA21_MARK, PG21MD_010), | 1088 | PINMUX_DATA(LCD_DATA21_PG21_MARK, PG21MD_010), |
1075 | PINMUX_DATA(LCD_TCON4_MARK, PG21MD_011), | 1089 | PINMUX_DATA(LCD_TCON4_MARK, PG21MD_011), |
1076 | PINMUX_DATA(TXD4_MARK, PG21MD_100), | 1090 | PINMUX_DATA(TXD4_MARK, PG21MD_100), |
1077 | 1091 | ||
1078 | PINMUX_DATA(PG20_DATA, PG20MD_000), | 1092 | PINMUX_DATA(PG20_DATA, PG20MD_000), |
1079 | PINMUX_DATA(DV_DATA6_MARK, PG20MD_001), | 1093 | PINMUX_DATA(DV_DATA6_MARK, PG20MD_001), |
1080 | PINMUX_DATA(LCD_DATA20_MARK, PG21MD_010), | 1094 | PINMUX_DATA(LCD_DATA20_PG20_MARK, PG21MD_010), |
1081 | PINMUX_DATA(LCD_TCON3_MARK, PG20MD_011), | 1095 | PINMUX_DATA(LCD_TCON3_MARK, PG20MD_011), |
1082 | PINMUX_DATA(RXD4_MARK, PG20MD_100), | 1096 | PINMUX_DATA(RXD4_MARK, PG20MD_100), |
1083 | 1097 | ||
1084 | PINMUX_DATA(PG19_DATA, PG19MD_000), | 1098 | PINMUX_DATA(PG19_DATA, PG19MD_000), |
1085 | PINMUX_DATA(DV_DATA5_MARK, PG19MD_001), | 1099 | PINMUX_DATA(DV_DATA5_MARK, PG19MD_001), |
1086 | PINMUX_DATA(LCD_DATA19_MARK, PG19MD_010), | 1100 | PINMUX_DATA(LCD_DATA19_PG19_MARK, PG19MD_010), |
1087 | PINMUX_DATA(SPDIF_OUT_MARK, PG19MD_011), | 1101 | PINMUX_DATA(SPDIF_OUT_MARK, PG19MD_011), |
1088 | PINMUX_DATA(SCK5_MARK, PG19MD_100), | 1102 | PINMUX_DATA(SCK5_MARK, PG19MD_100), |
1089 | 1103 | ||
1090 | PINMUX_DATA(PG18_DATA, PG18MD_000), | 1104 | PINMUX_DATA(PG18_DATA, PG18MD_000), |
1091 | PINMUX_DATA(DV_DATA4_MARK, PG18MD_001), | 1105 | PINMUX_DATA(DV_DATA4_MARK, PG18MD_001), |
1092 | PINMUX_DATA(LCD_DATA18_MARK, PG18MD_010), | 1106 | PINMUX_DATA(LCD_DATA18_PG18_MARK, PG18MD_010), |
1093 | PINMUX_DATA(SPDIF_IN_MARK, PG18MD_011), | 1107 | PINMUX_DATA(SPDIF_IN_MARK, PG18MD_011), |
1094 | PINMUX_DATA(SCK4_MARK, PG18MD_100), | 1108 | PINMUX_DATA(SCK4_MARK, PG18MD_100), |
1095 | 1109 | ||
@@ -1097,103 +1111,103 @@ static pinmux_enum_t pinmux_data[] = { | |||
1097 | // we're going with 2 bits | 1111 | // we're going with 2 bits |
1098 | PINMUX_DATA(PG17_DATA, PG17MD_00), | 1112 | PINMUX_DATA(PG17_DATA, PG17MD_00), |
1099 | PINMUX_DATA(WE3ICIOWRAHDQMUU_MARK, PG17MD_01), | 1113 | PINMUX_DATA(WE3ICIOWRAHDQMUU_MARK, PG17MD_01), |
1100 | PINMUX_DATA(LCD_DATA17_MARK, PG17MD_10), | 1114 | PINMUX_DATA(LCD_DATA17_PG17_MARK, PG17MD_10), |
1101 | 1115 | ||
1102 | // TODO hardware manual has PG16 3 bits wide in reg picture and 2 bits in description | 1116 | // TODO hardware manual has PG16 3 bits wide in reg picture and 2 bits in description |
1103 | // we're going with 2 bits | 1117 | // we're going with 2 bits |
1104 | PINMUX_DATA(PG16_DATA, PG16MD_00), | 1118 | PINMUX_DATA(PG16_DATA, PG16MD_00), |
1105 | PINMUX_DATA(WE2ICIORDDQMUL_MARK, PG16MD_01), | 1119 | PINMUX_DATA(WE2ICIORDDQMUL_MARK, PG16MD_01), |
1106 | PINMUX_DATA(LCD_DATA16_MARK, PG16MD_10), | 1120 | PINMUX_DATA(LCD_DATA16_PG16_MARK, PG16MD_10), |
1107 | 1121 | ||
1108 | PINMUX_DATA(PG15_DATA, PG15MD_00), | 1122 | PINMUX_DATA(PG15_DATA, PG15MD_00), |
1109 | PINMUX_DATA(D31_MARK, PG15MD_01), | 1123 | PINMUX_DATA(D31_MARK, PG15MD_01), |
1110 | PINMUX_DATA(LCD_DATA15_MARK, PG15MD_10), | 1124 | PINMUX_DATA(LCD_DATA15_PG15_MARK, PG15MD_10), |
1111 | PINMUX_DATA(PINT7_PG_MARK, PG15MD_11), | 1125 | PINMUX_DATA(PINT7_PG_MARK, PG15MD_11), |
1112 | 1126 | ||
1113 | PINMUX_DATA(PG14_DATA, PG14MD_00), | 1127 | PINMUX_DATA(PG14_DATA, PG14MD_00), |
1114 | PINMUX_DATA(D30_MARK, PG14MD_01), | 1128 | PINMUX_DATA(D30_MARK, PG14MD_01), |
1115 | PINMUX_DATA(LCD_DATA14_MARK, PG14MD_10), | 1129 | PINMUX_DATA(LCD_DATA14_PG14_MARK, PG14MD_10), |
1116 | PINMUX_DATA(PINT6_PG_MARK, PG14MD_11), | 1130 | PINMUX_DATA(PINT6_PG_MARK, PG14MD_11), |
1117 | 1131 | ||
1118 | PINMUX_DATA(PG13_DATA, PG13MD_00), | 1132 | PINMUX_DATA(PG13_DATA, PG13MD_00), |
1119 | PINMUX_DATA(D29_MARK, PG13MD_01), | 1133 | PINMUX_DATA(D29_MARK, PG13MD_01), |
1120 | PINMUX_DATA(LCD_DATA13_MARK, PG13MD_10), | 1134 | PINMUX_DATA(LCD_DATA13_PG13_MARK, PG13MD_10), |
1121 | PINMUX_DATA(PINT5_PG_MARK, PG13MD_11), | 1135 | PINMUX_DATA(PINT5_PG_MARK, PG13MD_11), |
1122 | 1136 | ||
1123 | PINMUX_DATA(PG12_DATA, PG12MD_00), | 1137 | PINMUX_DATA(PG12_DATA, PG12MD_00), |
1124 | PINMUX_DATA(D28_MARK, PG12MD_01), | 1138 | PINMUX_DATA(D28_MARK, PG12MD_01), |
1125 | PINMUX_DATA(LCD_DATA12_MARK, PG12MD_10), | 1139 | PINMUX_DATA(LCD_DATA12_PG12_MARK, PG12MD_10), |
1126 | PINMUX_DATA(PINT4_PG_MARK, PG12MD_11), | 1140 | PINMUX_DATA(PINT4_PG_MARK, PG12MD_11), |
1127 | 1141 | ||
1128 | PINMUX_DATA(PG11_DATA, PG11MD_000), | 1142 | PINMUX_DATA(PG11_DATA, PG11MD_000), |
1129 | PINMUX_DATA(D27_MARK, PG11MD_001), | 1143 | PINMUX_DATA(D27_MARK, PG11MD_001), |
1130 | PINMUX_DATA(LCD_DATA11_MARK, PG11MD_010), | 1144 | PINMUX_DATA(LCD_DATA11_PG11_MARK, PG11MD_010), |
1131 | PINMUX_DATA(PINT3_PG_MARK, PG11MD_011), | 1145 | PINMUX_DATA(PINT3_PG_MARK, PG11MD_011), |
1132 | PINMUX_DATA(TIOC3D_MARK, PG11MD_100), | 1146 | PINMUX_DATA(TIOC3D_MARK, PG11MD_100), |
1133 | 1147 | ||
1134 | PINMUX_DATA(PG10_DATA, PG10MD_000), | 1148 | PINMUX_DATA(PG10_DATA, PG10MD_000), |
1135 | PINMUX_DATA(D26_MARK, PG10MD_001), | 1149 | PINMUX_DATA(D26_MARK, PG10MD_001), |
1136 | PINMUX_DATA(LCD_DATA10_MARK, PG10MD_010), | 1150 | PINMUX_DATA(LCD_DATA10_PG10_MARK, PG10MD_010), |
1137 | PINMUX_DATA(PINT2_PG_MARK, PG10MD_011), | 1151 | PINMUX_DATA(PINT2_PG_MARK, PG10MD_011), |
1138 | PINMUX_DATA(TIOC3C_MARK, PG10MD_100), | 1152 | PINMUX_DATA(TIOC3C_MARK, PG10MD_100), |
1139 | 1153 | ||
1140 | PINMUX_DATA(PG9_DATA, PG9MD_000), | 1154 | PINMUX_DATA(PG9_DATA, PG9MD_000), |
1141 | PINMUX_DATA(D25_MARK, PG9MD_001), | 1155 | PINMUX_DATA(D25_MARK, PG9MD_001), |
1142 | PINMUX_DATA(LCD_DATA9_MARK, PG9MD_010), | 1156 | PINMUX_DATA(LCD_DATA9_PG9_MARK, PG9MD_010), |
1143 | PINMUX_DATA(PINT1_PG_MARK, PG9MD_011), | 1157 | PINMUX_DATA(PINT1_PG_MARK, PG9MD_011), |
1144 | PINMUX_DATA(TIOC3B_MARK, PG9MD_100), | 1158 | PINMUX_DATA(TIOC3B_MARK, PG9MD_100), |
1145 | 1159 | ||
1146 | PINMUX_DATA(PG8_DATA, PG8MD_000), | 1160 | PINMUX_DATA(PG8_DATA, PG8MD_000), |
1147 | PINMUX_DATA(D24_MARK, PG8MD_001), | 1161 | PINMUX_DATA(D24_MARK, PG8MD_001), |
1148 | PINMUX_DATA(LCD_DATA8_MARK, PG8MD_010), | 1162 | PINMUX_DATA(LCD_DATA8_PG8_MARK, PG8MD_010), |
1149 | PINMUX_DATA(PINT0_PG_MARK, PG8MD_011), | 1163 | PINMUX_DATA(PINT0_PG_MARK, PG8MD_011), |
1150 | PINMUX_DATA(TIOC3A_MARK, PG8MD_100), | 1164 | PINMUX_DATA(TIOC3A_MARK, PG8MD_100), |
1151 | 1165 | ||
1152 | PINMUX_DATA(PG7_DATA, PG7MD_000), | 1166 | PINMUX_DATA(PG7_DATA, PG7MD_000), |
1153 | PINMUX_DATA(D23_MARK, PG7MD_001), | 1167 | PINMUX_DATA(D23_MARK, PG7MD_001), |
1154 | PINMUX_DATA(LCD_DATA7_MARK, PG7MD_010), | 1168 | PINMUX_DATA(LCD_DATA7_PG7_MARK, PG7MD_010), |
1155 | PINMUX_DATA(IRQ7_PG_MARK, PG7MD_011), | 1169 | PINMUX_DATA(IRQ7_PG_MARK, PG7MD_011), |
1156 | PINMUX_DATA(TIOC2B_MARK, PG7MD_100), | 1170 | PINMUX_DATA(TIOC2B_MARK, PG7MD_100), |
1157 | 1171 | ||
1158 | PINMUX_DATA(PG6_DATA, PG6MD_000), | 1172 | PINMUX_DATA(PG6_DATA, PG6MD_000), |
1159 | PINMUX_DATA(D22_MARK, PG6MD_001), | 1173 | PINMUX_DATA(D22_MARK, PG6MD_001), |
1160 | PINMUX_DATA(LCD_DATA6_MARK, PG6MD_010), | 1174 | PINMUX_DATA(LCD_DATA6_PG6_MARK, PG6MD_010), |
1161 | PINMUX_DATA(IRQ6_PG_MARK, PG6MD_011), | 1175 | PINMUX_DATA(IRQ6_PG_MARK, PG6MD_011), |
1162 | PINMUX_DATA(TIOC2A_MARK, PG6MD_100), | 1176 | PINMUX_DATA(TIOC2A_MARK, PG6MD_100), |
1163 | 1177 | ||
1164 | PINMUX_DATA(PG5_DATA, PG5MD_000), | 1178 | PINMUX_DATA(PG5_DATA, PG5MD_000), |
1165 | PINMUX_DATA(D21_MARK, PG5MD_001), | 1179 | PINMUX_DATA(D21_MARK, PG5MD_001), |
1166 | PINMUX_DATA(LCD_DATA5_MARK, PG5MD_010), | 1180 | PINMUX_DATA(LCD_DATA5_PG5_MARK, PG5MD_010), |
1167 | PINMUX_DATA(IRQ5_PG_MARK, PG5MD_011), | 1181 | PINMUX_DATA(IRQ5_PG_MARK, PG5MD_011), |
1168 | PINMUX_DATA(TIOC1B_MARK, PG5MD_100), | 1182 | PINMUX_DATA(TIOC1B_MARK, PG5MD_100), |
1169 | 1183 | ||
1170 | PINMUX_DATA(PG4_DATA, PG4MD_000), | 1184 | PINMUX_DATA(PG4_DATA, PG4MD_000), |
1171 | PINMUX_DATA(D20_MARK, PG4MD_001), | 1185 | PINMUX_DATA(D20_MARK, PG4MD_001), |
1172 | PINMUX_DATA(LCD_DATA4_MARK, PG4MD_010), | 1186 | PINMUX_DATA(LCD_DATA4_PG4_MARK, PG4MD_010), |
1173 | PINMUX_DATA(IRQ4_PG_MARK, PG4MD_011), | 1187 | PINMUX_DATA(IRQ4_PG_MARK, PG4MD_011), |
1174 | PINMUX_DATA(TIOC1A_MARK, PG4MD_100), | 1188 | PINMUX_DATA(TIOC1A_MARK, PG4MD_100), |
1175 | 1189 | ||
1176 | PINMUX_DATA(PG3_DATA, PG3MD_000), | 1190 | PINMUX_DATA(PG3_DATA, PG3MD_000), |
1177 | PINMUX_DATA(D19_MARK, PG3MD_001), | 1191 | PINMUX_DATA(D19_MARK, PG3MD_001), |
1178 | PINMUX_DATA(LCD_DATA3_MARK, PG3MD_010), | 1192 | PINMUX_DATA(LCD_DATA3_PG3_MARK, PG3MD_010), |
1179 | PINMUX_DATA(IRQ3_PG_MARK, PG3MD_011), | 1193 | PINMUX_DATA(IRQ3_PG_MARK, PG3MD_011), |
1180 | PINMUX_DATA(TIOC0D_MARK, PG3MD_100), | 1194 | PINMUX_DATA(TIOC0D_MARK, PG3MD_100), |
1181 | 1195 | ||
1182 | PINMUX_DATA(PG2_DATA, PG2MD_000), | 1196 | PINMUX_DATA(PG2_DATA, PG2MD_000), |
1183 | PINMUX_DATA(D18_MARK, PG2MD_001), | 1197 | PINMUX_DATA(D18_MARK, PG2MD_001), |
1184 | PINMUX_DATA(LCD_DATA2_MARK, PG2MD_010), | 1198 | PINMUX_DATA(LCD_DATA2_PG2_MARK, PG2MD_010), |
1185 | PINMUX_DATA(IRQ2_PG_MARK, PG2MD_011), | 1199 | PINMUX_DATA(IRQ2_PG_MARK, PG2MD_011), |
1186 | PINMUX_DATA(TIOC0C_MARK, PG2MD_100), | 1200 | PINMUX_DATA(TIOC0C_MARK, PG2MD_100), |
1187 | 1201 | ||
1188 | PINMUX_DATA(PG1_DATA, PG1MD_000), | 1202 | PINMUX_DATA(PG1_DATA, PG1MD_000), |
1189 | PINMUX_DATA(D17_MARK, PG1MD_001), | 1203 | PINMUX_DATA(D17_MARK, PG1MD_001), |
1190 | PINMUX_DATA(LCD_DATA1_MARK, PG1MD_010), | 1204 | PINMUX_DATA(LCD_DATA1_PG1_MARK, PG1MD_010), |
1191 | PINMUX_DATA(IRQ1_PG_MARK, PG1MD_011), | 1205 | PINMUX_DATA(IRQ1_PG_MARK, PG1MD_011), |
1192 | PINMUX_DATA(TIOC0B_MARK, PG1MD_100), | 1206 | PINMUX_DATA(TIOC0B_MARK, PG1MD_100), |
1193 | 1207 | ||
1194 | PINMUX_DATA(PG0_DATA, PG0MD_000), | 1208 | PINMUX_DATA(PG0_DATA, PG0MD_000), |
1195 | PINMUX_DATA(D16_MARK, PG0MD_001), | 1209 | PINMUX_DATA(D16_MARK, PG0MD_001), |
1196 | PINMUX_DATA(LCD_DATA0_MARK, PG0MD_010), | 1210 | PINMUX_DATA(LCD_DATA0_PG0_MARK, PG0MD_010), |
1197 | PINMUX_DATA(IRQ0_PG_MARK, PG0MD_011), | 1211 | PINMUX_DATA(IRQ0_PG_MARK, PG0MD_011), |
1198 | PINMUX_DATA(TIOC0A_MARK, PG0MD_100), | 1212 | PINMUX_DATA(TIOC0A_MARK, PG0MD_100), |
1199 | 1213 | ||
@@ -1275,14 +1289,14 @@ static pinmux_enum_t pinmux_data[] = { | |||
1275 | 1289 | ||
1276 | PINMUX_DATA(PJ23_DATA, PJ23MD_000), | 1290 | PINMUX_DATA(PJ23_DATA, PJ23MD_000), |
1277 | PINMUX_DATA(DV_DATA23_MARK, PJ23MD_001), | 1291 | PINMUX_DATA(DV_DATA23_MARK, PJ23MD_001), |
1278 | PINMUX_DATA(LCD_DATA23_MARK, PJ23MD_010), | 1292 | PINMUX_DATA(LCD_DATA23_PJ23_MARK, PJ23MD_010), |
1279 | PINMUX_DATA(LCD_TCON6_MARK, PJ23MD_011), | 1293 | PINMUX_DATA(LCD_TCON6_MARK, PJ23MD_011), |
1280 | PINMUX_DATA(IRQ3_PJ_MARK, PJ23MD_100), | 1294 | PINMUX_DATA(IRQ3_PJ_MARK, PJ23MD_100), |
1281 | PINMUX_DATA(CTX1_MARK, PJ23MD_101), | 1295 | PINMUX_DATA(CTX1_MARK, PJ23MD_101), |
1282 | 1296 | ||
1283 | PINMUX_DATA(PJ22_DATA, PJ22MD_000), | 1297 | PINMUX_DATA(PJ22_DATA, PJ22MD_000), |
1284 | PINMUX_DATA(DV_DATA22_MARK, PJ22MD_001), | 1298 | PINMUX_DATA(DV_DATA22_MARK, PJ22MD_001), |
1285 | PINMUX_DATA(LCD_DATA22_MARK, PJ22MD_010), | 1299 | PINMUX_DATA(LCD_DATA22_PJ22_MARK, PJ22MD_010), |
1286 | PINMUX_DATA(LCD_TCON5_MARK, PJ22MD_011), | 1300 | PINMUX_DATA(LCD_TCON5_MARK, PJ22MD_011), |
1287 | PINMUX_DATA(IRQ2_PJ_MARK, PJ22MD_100), | 1301 | PINMUX_DATA(IRQ2_PJ_MARK, PJ22MD_100), |
1288 | PINMUX_DATA(CRX1_MARK, PJ22MD_101), | 1302 | PINMUX_DATA(CRX1_MARK, PJ22MD_101), |
@@ -1290,14 +1304,14 @@ static pinmux_enum_t pinmux_data[] = { | |||
1290 | 1304 | ||
1291 | PINMUX_DATA(PJ21_DATA, PJ21MD_000), | 1305 | PINMUX_DATA(PJ21_DATA, PJ21MD_000), |
1292 | PINMUX_DATA(DV_DATA21_MARK, PJ21MD_001), | 1306 | PINMUX_DATA(DV_DATA21_MARK, PJ21MD_001), |
1293 | PINMUX_DATA(LCD_DATA21_MARK, PJ21MD_010), | 1307 | PINMUX_DATA(LCD_DATA21_PJ21_MARK, PJ21MD_010), |
1294 | PINMUX_DATA(LCD_TCON4_MARK, PJ21MD_011), | 1308 | PINMUX_DATA(LCD_TCON4_MARK, PJ21MD_011), |
1295 | PINMUX_DATA(IRQ1_PJ_MARK, PJ21MD_100), | 1309 | PINMUX_DATA(IRQ1_PJ_MARK, PJ21MD_100), |
1296 | PINMUX_DATA(CTX2_MARK, PJ21MD_101), | 1310 | PINMUX_DATA(CTX2_MARK, PJ21MD_101), |
1297 | 1311 | ||
1298 | PINMUX_DATA(PJ20_DATA, PJ20MD_000), | 1312 | PINMUX_DATA(PJ20_DATA, PJ20MD_000), |
1299 | PINMUX_DATA(DV_DATA20_MARK, PJ20MD_001), | 1313 | PINMUX_DATA(DV_DATA20_MARK, PJ20MD_001), |
1300 | PINMUX_DATA(LCD_DATA20_MARK, PJ20MD_010), | 1314 | PINMUX_DATA(LCD_DATA20_PJ20_MARK, PJ20MD_010), |
1301 | PINMUX_DATA(LCD_TCON3_MARK, PJ20MD_011), | 1315 | PINMUX_DATA(LCD_TCON3_MARK, PJ20MD_011), |
1302 | PINMUX_DATA(IRQ0_PJ_MARK, PJ20MD_100), | 1316 | PINMUX_DATA(IRQ0_PJ_MARK, PJ20MD_100), |
1303 | PINMUX_DATA(CRX2_MARK, PJ20MD_101), | 1317 | PINMUX_DATA(CRX2_MARK, PJ20MD_101), |
@@ -1305,7 +1319,7 @@ static pinmux_enum_t pinmux_data[] = { | |||
1305 | 1319 | ||
1306 | PINMUX_DATA(PJ19_DATA, PJ19MD_000), | 1320 | PINMUX_DATA(PJ19_DATA, PJ19MD_000), |
1307 | PINMUX_DATA(DV_DATA19_MARK, PJ19MD_001), | 1321 | PINMUX_DATA(DV_DATA19_MARK, PJ19MD_001), |
1308 | PINMUX_DATA(LCD_DATA19_MARK, PJ19MD_010), | 1322 | PINMUX_DATA(LCD_DATA19_PJ19_MARK, PJ19MD_010), |
1309 | PINMUX_DATA(MISO0_PJ19_MARK, PJ19MD_011), | 1323 | PINMUX_DATA(MISO0_PJ19_MARK, PJ19MD_011), |
1310 | PINMUX_DATA(TIOC0D_MARK, PJ19MD_100), | 1324 | PINMUX_DATA(TIOC0D_MARK, PJ19MD_100), |
1311 | PINMUX_DATA(SIOFRXD_MARK, PJ19MD_101), | 1325 | PINMUX_DATA(SIOFRXD_MARK, PJ19MD_101), |
@@ -1313,126 +1327,126 @@ static pinmux_enum_t pinmux_data[] = { | |||
1313 | 1327 | ||
1314 | PINMUX_DATA(PJ18_DATA, PJ18MD_000), | 1328 | PINMUX_DATA(PJ18_DATA, PJ18MD_000), |
1315 | PINMUX_DATA(DV_DATA18_MARK, PJ18MD_001), | 1329 | PINMUX_DATA(DV_DATA18_MARK, PJ18MD_001), |
1316 | PINMUX_DATA(LCD_DATA18_MARK, PJ18MD_010), | 1330 | PINMUX_DATA(LCD_DATA18_PJ18_MARK, PJ18MD_010), |
1317 | PINMUX_DATA(MOSI0_PJ18_MARK, PJ18MD_011), | 1331 | PINMUX_DATA(MOSI0_PJ18_MARK, PJ18MD_011), |
1318 | PINMUX_DATA(TIOC0C_MARK, PJ18MD_100), | 1332 | PINMUX_DATA(TIOC0C_MARK, PJ18MD_100), |
1319 | PINMUX_DATA(SIOFTXD_MARK, PJ18MD_101), | 1333 | PINMUX_DATA(SIOFTXD_MARK, PJ18MD_101), |
1320 | 1334 | ||
1321 | PINMUX_DATA(PJ17_DATA, PJ17MD_000), | 1335 | PINMUX_DATA(PJ17_DATA, PJ17MD_000), |
1322 | PINMUX_DATA(DV_DATA17_MARK, PJ17MD_001), | 1336 | PINMUX_DATA(DV_DATA17_MARK, PJ17MD_001), |
1323 | PINMUX_DATA(LCD_DATA17_MARK, PJ17MD_010), | 1337 | PINMUX_DATA(LCD_DATA17_PJ17_MARK, PJ17MD_010), |
1324 | PINMUX_DATA(SSL00_PJ17_MARK, PJ17MD_011), | 1338 | PINMUX_DATA(SSL00_PJ17_MARK, PJ17MD_011), |
1325 | PINMUX_DATA(TIOC0B_MARK, PJ17MD_100), | 1339 | PINMUX_DATA(TIOC0B_MARK, PJ17MD_100), |
1326 | PINMUX_DATA(SIOFSYNC_MARK, PJ17MD_101), | 1340 | PINMUX_DATA(SIOFSYNC_MARK, PJ17MD_101), |
1327 | 1341 | ||
1328 | PINMUX_DATA(PJ16_DATA, PJ16MD_000), | 1342 | PINMUX_DATA(PJ16_DATA, PJ16MD_000), |
1329 | PINMUX_DATA(DV_DATA16_MARK, PJ16MD_001), | 1343 | PINMUX_DATA(DV_DATA16_MARK, PJ16MD_001), |
1330 | PINMUX_DATA(LCD_DATA16_MARK, PJ16MD_010), | 1344 | PINMUX_DATA(LCD_DATA16_PJ16_MARK, PJ16MD_010), |
1331 | PINMUX_DATA(RSPCK0_PJ16_MARK, PJ16MD_011), | 1345 | PINMUX_DATA(RSPCK0_PJ16_MARK, PJ16MD_011), |
1332 | PINMUX_DATA(TIOC0A_MARK, PJ16MD_100), | 1346 | PINMUX_DATA(TIOC0A_MARK, PJ16MD_100), |
1333 | PINMUX_DATA(SIOFSCK_MARK, PJ16MD_101), | 1347 | PINMUX_DATA(SIOFSCK_MARK, PJ16MD_101), |
1334 | 1348 | ||
1335 | PINMUX_DATA(PJ15_DATA, PJ15MD_000), | 1349 | PINMUX_DATA(PJ15_DATA, PJ15MD_000), |
1336 | PINMUX_DATA(DV_DATA15_MARK, PJ15MD_001), | 1350 | PINMUX_DATA(DV_DATA15_MARK, PJ15MD_001), |
1337 | PINMUX_DATA(LCD_DATA15_MARK, PJ15MD_010), | 1351 | PINMUX_DATA(LCD_DATA15_PJ15_MARK, PJ15MD_010), |
1338 | PINMUX_DATA(PINT7_PJ_MARK, PJ15MD_011), | 1352 | PINMUX_DATA(PINT7_PJ_MARK, PJ15MD_011), |
1339 | PINMUX_DATA(PWM2H_MARK, PJ15MD_100), | 1353 | PINMUX_DATA(PWM2H_MARK, PJ15MD_100), |
1340 | PINMUX_DATA(TXD7_MARK, PJ15MD_101), | 1354 | PINMUX_DATA(TXD7_MARK, PJ15MD_101), |
1341 | 1355 | ||
1342 | PINMUX_DATA(PJ14_DATA, PJ14MD_000), | 1356 | PINMUX_DATA(PJ14_DATA, PJ14MD_000), |
1343 | PINMUX_DATA(DV_DATA14_MARK, PJ14MD_001), | 1357 | PINMUX_DATA(DV_DATA14_MARK, PJ14MD_001), |
1344 | PINMUX_DATA(LCD_DATA14_MARK, PJ14MD_010), | 1358 | PINMUX_DATA(LCD_DATA14_PJ14_MARK, PJ14MD_010), |
1345 | PINMUX_DATA(PINT6_PJ_MARK, PJ14MD_011), | 1359 | PINMUX_DATA(PINT6_PJ_MARK, PJ14MD_011), |
1346 | PINMUX_DATA(PWM2G_MARK, PJ14MD_100), | 1360 | PINMUX_DATA(PWM2G_MARK, PJ14MD_100), |
1347 | PINMUX_DATA(TXD6_MARK, PJ14MD_101), | 1361 | PINMUX_DATA(TXD6_MARK, PJ14MD_101), |
1348 | 1362 | ||
1349 | PINMUX_DATA(PJ13_DATA, PJ13MD_000), | 1363 | PINMUX_DATA(PJ13_DATA, PJ13MD_000), |
1350 | PINMUX_DATA(DV_DATA13_MARK, PJ13MD_001), | 1364 | PINMUX_DATA(DV_DATA13_MARK, PJ13MD_001), |
1351 | PINMUX_DATA(LCD_DATA13_MARK, PJ13MD_010), | 1365 | PINMUX_DATA(LCD_DATA13_PJ13_MARK, PJ13MD_010), |
1352 | PINMUX_DATA(PINT5_PJ_MARK, PJ13MD_011), | 1366 | PINMUX_DATA(PINT5_PJ_MARK, PJ13MD_011), |
1353 | PINMUX_DATA(PWM2F_MARK, PJ13MD_100), | 1367 | PINMUX_DATA(PWM2F_MARK, PJ13MD_100), |
1354 | PINMUX_DATA(TXD5_MARK, PJ13MD_101), | 1368 | PINMUX_DATA(TXD5_MARK, PJ13MD_101), |
1355 | 1369 | ||
1356 | PINMUX_DATA(PJ12_DATA, PJ12MD_000), | 1370 | PINMUX_DATA(PJ12_DATA, PJ12MD_000), |
1357 | PINMUX_DATA(DV_DATA12_MARK, PJ12MD_001), | 1371 | PINMUX_DATA(DV_DATA12_MARK, PJ12MD_001), |
1358 | PINMUX_DATA(LCD_DATA12_MARK, PJ12MD_010), | 1372 | PINMUX_DATA(LCD_DATA12_PJ12_MARK, PJ12MD_010), |
1359 | PINMUX_DATA(PINT4_PJ_MARK, PJ12MD_011), | 1373 | PINMUX_DATA(PINT4_PJ_MARK, PJ12MD_011), |
1360 | PINMUX_DATA(PWM2E_MARK, PJ12MD_100), | 1374 | PINMUX_DATA(PWM2E_MARK, PJ12MD_100), |
1361 | PINMUX_DATA(SCK7_MARK, PJ12MD_101), | 1375 | PINMUX_DATA(SCK7_MARK, PJ12MD_101), |
1362 | 1376 | ||
1363 | PINMUX_DATA(PJ11_DATA, PJ11MD_000), | 1377 | PINMUX_DATA(PJ11_DATA, PJ11MD_000), |
1364 | PINMUX_DATA(DV_DATA11_MARK, PJ11MD_001), | 1378 | PINMUX_DATA(DV_DATA11_MARK, PJ11MD_001), |
1365 | PINMUX_DATA(LCD_DATA11_MARK, PJ11MD_010), | 1379 | PINMUX_DATA(LCD_DATA11_PJ11_MARK, PJ11MD_010), |
1366 | PINMUX_DATA(PINT3_PJ_MARK, PJ11MD_011), | 1380 | PINMUX_DATA(PINT3_PJ_MARK, PJ11MD_011), |
1367 | PINMUX_DATA(PWM2D_MARK, PJ11MD_100), | 1381 | PINMUX_DATA(PWM2D_MARK, PJ11MD_100), |
1368 | PINMUX_DATA(SCK6_MARK, PJ11MD_101), | 1382 | PINMUX_DATA(SCK6_MARK, PJ11MD_101), |
1369 | 1383 | ||
1370 | PINMUX_DATA(PJ10_DATA, PJ10MD_000), | 1384 | PINMUX_DATA(PJ10_DATA, PJ10MD_000), |
1371 | PINMUX_DATA(DV_DATA10_MARK, PJ10MD_001), | 1385 | PINMUX_DATA(DV_DATA10_MARK, PJ10MD_001), |
1372 | PINMUX_DATA(LCD_DATA10_MARK, PJ10MD_010), | 1386 | PINMUX_DATA(LCD_DATA10_PJ10_MARK, PJ10MD_010), |
1373 | PINMUX_DATA(PINT2_PJ_MARK, PJ10MD_011), | 1387 | PINMUX_DATA(PINT2_PJ_MARK, PJ10MD_011), |
1374 | PINMUX_DATA(PWM2C_MARK, PJ10MD_100), | 1388 | PINMUX_DATA(PWM2C_MARK, PJ10MD_100), |
1375 | PINMUX_DATA(SCK5_MARK, PJ10MD_101), | 1389 | PINMUX_DATA(SCK5_MARK, PJ10MD_101), |
1376 | 1390 | ||
1377 | PINMUX_DATA(PJ9_DATA, PJ9MD_000), | 1391 | PINMUX_DATA(PJ9_DATA, PJ9MD_000), |
1378 | PINMUX_DATA(DV_DATA9_MARK, PJ9MD_001), | 1392 | PINMUX_DATA(DV_DATA9_MARK, PJ9MD_001), |
1379 | PINMUX_DATA(LCD_DATA9_MARK, PJ9MD_010), | 1393 | PINMUX_DATA(LCD_DATA9_PJ9_MARK, PJ9MD_010), |
1380 | PINMUX_DATA(PINT1_PJ_MARK, PJ9MD_011), | 1394 | PINMUX_DATA(PINT1_PJ_MARK, PJ9MD_011), |
1381 | PINMUX_DATA(PWM2B_MARK, PJ9MD_100), | 1395 | PINMUX_DATA(PWM2B_MARK, PJ9MD_100), |
1382 | PINMUX_DATA(RTS5_MARK, PJ9MD_101), | 1396 | PINMUX_DATA(RTS5_MARK, PJ9MD_101), |
1383 | 1397 | ||
1384 | PINMUX_DATA(PJ8_DATA, PJ8MD_000), | 1398 | PINMUX_DATA(PJ8_DATA, PJ8MD_000), |
1385 | PINMUX_DATA(DV_DATA8_MARK, PJ8MD_001), | 1399 | PINMUX_DATA(DV_DATA8_MARK, PJ8MD_001), |
1386 | PINMUX_DATA(LCD_DATA8_MARK, PJ8MD_010), | 1400 | PINMUX_DATA(LCD_DATA8_PJ8_MARK, PJ8MD_010), |
1387 | PINMUX_DATA(PINT0_PJ_MARK, PJ8MD_011), | 1401 | PINMUX_DATA(PINT0_PJ_MARK, PJ8MD_011), |
1388 | PINMUX_DATA(PWM2A_MARK, PJ8MD_100), | 1402 | PINMUX_DATA(PWM2A_MARK, PJ8MD_100), |
1389 | PINMUX_DATA(CTS5_MARK, PJ8MD_101), | 1403 | PINMUX_DATA(CTS5_MARK, PJ8MD_101), |
1390 | 1404 | ||
1391 | PINMUX_DATA(PJ7_DATA, PJ7MD_000), | 1405 | PINMUX_DATA(PJ7_DATA, PJ7MD_000), |
1392 | PINMUX_DATA(DV_DATA7_MARK, PJ7MD_001), | 1406 | PINMUX_DATA(DV_DATA7_MARK, PJ7MD_001), |
1393 | PINMUX_DATA(LCD_DATA7_MARK, PJ7MD_010), | 1407 | PINMUX_DATA(LCD_DATA7_PJ7_MARK, PJ7MD_010), |
1394 | PINMUX_DATA(SD_D2_MARK, PJ7MD_011), | 1408 | PINMUX_DATA(SD_D2_MARK, PJ7MD_011), |
1395 | PINMUX_DATA(PWM1H_MARK, PJ7MD_100), | 1409 | PINMUX_DATA(PWM1H_MARK, PJ7MD_100), |
1396 | 1410 | ||
1397 | PINMUX_DATA(PJ6_DATA, PJ6MD_000), | 1411 | PINMUX_DATA(PJ6_DATA, PJ6MD_000), |
1398 | PINMUX_DATA(DV_DATA6_MARK, PJ6MD_001), | 1412 | PINMUX_DATA(DV_DATA6_MARK, PJ6MD_001), |
1399 | PINMUX_DATA(LCD_DATA6_MARK, PJ6MD_010), | 1413 | PINMUX_DATA(LCD_DATA6_PJ6_MARK, PJ6MD_010), |
1400 | PINMUX_DATA(SD_D3_MARK, PJ6MD_011), | 1414 | PINMUX_DATA(SD_D3_MARK, PJ6MD_011), |
1401 | PINMUX_DATA(PWM1G_MARK, PJ6MD_100), | 1415 | PINMUX_DATA(PWM1G_MARK, PJ6MD_100), |
1402 | 1416 | ||
1403 | PINMUX_DATA(PJ5_DATA, PJ5MD_000), | 1417 | PINMUX_DATA(PJ5_DATA, PJ5MD_000), |
1404 | PINMUX_DATA(DV_DATA5_MARK, PJ5MD_001), | 1418 | PINMUX_DATA(DV_DATA5_MARK, PJ5MD_001), |
1405 | PINMUX_DATA(LCD_DATA5_MARK, PJ5MD_010), | 1419 | PINMUX_DATA(LCD_DATA5_PJ5_MARK, PJ5MD_010), |
1406 | PINMUX_DATA(SD_CMD_MARK, PJ5MD_011), | 1420 | PINMUX_DATA(SD_CMD_MARK, PJ5MD_011), |
1407 | PINMUX_DATA(PWM1F_MARK, PJ5MD_100), | 1421 | PINMUX_DATA(PWM1F_MARK, PJ5MD_100), |
1408 | 1422 | ||
1409 | PINMUX_DATA(PJ4_DATA, PJ4MD_000), | 1423 | PINMUX_DATA(PJ4_DATA, PJ4MD_000), |
1410 | PINMUX_DATA(DV_DATA4_MARK, PJ4MD_001), | 1424 | PINMUX_DATA(DV_DATA4_MARK, PJ4MD_001), |
1411 | PINMUX_DATA(LCD_DATA4_MARK, PJ4MD_010), | 1425 | PINMUX_DATA(LCD_DATA4_PJ4_MARK, PJ4MD_010), |
1412 | PINMUX_DATA(SD_CLK_MARK, PJ4MD_011), | 1426 | PINMUX_DATA(SD_CLK_MARK, PJ4MD_011), |
1413 | PINMUX_DATA(PWM1E_MARK, PJ4MD_100), | 1427 | PINMUX_DATA(PWM1E_MARK, PJ4MD_100), |
1414 | 1428 | ||
1415 | PINMUX_DATA(PJ3_DATA, PJ3MD_000), | 1429 | PINMUX_DATA(PJ3_DATA, PJ3MD_000), |
1416 | PINMUX_DATA(DV_DATA3_MARK, PJ3MD_001), | 1430 | PINMUX_DATA(DV_DATA3_MARK, PJ3MD_001), |
1417 | PINMUX_DATA(LCD_DATA3_MARK, PJ3MD_010), | 1431 | PINMUX_DATA(LCD_DATA3_PJ3_MARK, PJ3MD_010), |
1418 | PINMUX_DATA(SD_D0_MARK, PJ3MD_011), | 1432 | PINMUX_DATA(SD_D0_MARK, PJ3MD_011), |
1419 | PINMUX_DATA(PWM1D_MARK, PJ3MD_100), | 1433 | PINMUX_DATA(PWM1D_MARK, PJ3MD_100), |
1420 | 1434 | ||
1421 | PINMUX_DATA(PJ2_DATA, PJ2MD_000), | 1435 | PINMUX_DATA(PJ2_DATA, PJ2MD_000), |
1422 | PINMUX_DATA(DV_DATA2_MARK, PJ2MD_001), | 1436 | PINMUX_DATA(DV_DATA2_MARK, PJ2MD_001), |
1423 | PINMUX_DATA(LCD_DATA2_MARK, PJ2MD_010), | 1437 | PINMUX_DATA(LCD_DATA2_PJ2_MARK, PJ2MD_010), |
1424 | PINMUX_DATA(SD_D1_MARK, PJ2MD_011), | 1438 | PINMUX_DATA(SD_D1_MARK, PJ2MD_011), |
1425 | PINMUX_DATA(PWM1C_MARK, PJ2MD_100), | 1439 | PINMUX_DATA(PWM1C_MARK, PJ2MD_100), |
1426 | 1440 | ||
1427 | PINMUX_DATA(PJ1_DATA, PJ1MD_000), | 1441 | PINMUX_DATA(PJ1_DATA, PJ1MD_000), |
1428 | PINMUX_DATA(DV_DATA1_MARK, PJ1MD_001), | 1442 | PINMUX_DATA(DV_DATA1_MARK, PJ1MD_001), |
1429 | PINMUX_DATA(LCD_DATA1_MARK, PJ1MD_010), | 1443 | PINMUX_DATA(LCD_DATA1_PJ1_MARK, PJ1MD_010), |
1430 | PINMUX_DATA(SD_WP_MARK, PJ1MD_011), | 1444 | PINMUX_DATA(SD_WP_MARK, PJ1MD_011), |
1431 | PINMUX_DATA(PWM1B_MARK, PJ1MD_100), | 1445 | PINMUX_DATA(PWM1B_MARK, PJ1MD_100), |
1432 | 1446 | ||
1433 | PINMUX_DATA(PJ0_DATA, PJ0MD_000), | 1447 | PINMUX_DATA(PJ0_DATA, PJ0MD_000), |
1434 | PINMUX_DATA(DV_DATA0_MARK, PJ0MD_001), | 1448 | PINMUX_DATA(DV_DATA0_MARK, PJ0MD_001), |
1435 | PINMUX_DATA(LCD_DATA0_MARK, PJ0MD_010), | 1449 | PINMUX_DATA(LCD_DATA0_PJ0_MARK, PJ0MD_010), |
1436 | PINMUX_DATA(SD_CD_MARK, PJ0MD_011), | 1450 | PINMUX_DATA(SD_CD_MARK, PJ0MD_011), |
1437 | PINMUX_DATA(PWM1A_MARK, PJ0MD_100), | 1451 | PINMUX_DATA(PWM1A_MARK, PJ0MD_100), |
1438 | }; | 1452 | }; |
@@ -1877,30 +1891,55 @@ static struct pinmux_gpio pinmux_gpios[] = { | |||
1877 | PINMUX_GPIO(GPIO_FN_LCD_HSYNC, LCD_HSYNC_MARK), | 1891 | PINMUX_GPIO(GPIO_FN_LCD_HSYNC, LCD_HSYNC_MARK), |
1878 | PINMUX_GPIO(GPIO_FN_LCD_DE, LCD_DE_MARK), | 1892 | PINMUX_GPIO(GPIO_FN_LCD_DE, LCD_DE_MARK), |
1879 | 1893 | ||
1880 | PINMUX_GPIO(GPIO_FN_LCD_DATA23, LCD_DATA23_MARK), | 1894 | PINMUX_GPIO(GPIO_FN_LCD_DATA23_PG23, LCD_DATA23_PG23_MARK), |
1881 | PINMUX_GPIO(GPIO_FN_LCD_DATA22, LCD_DATA22_MARK), | 1895 | PINMUX_GPIO(GPIO_FN_LCD_DATA22_PG22, LCD_DATA22_PG22_MARK), |
1882 | PINMUX_GPIO(GPIO_FN_LCD_DATA21, LCD_DATA21_MARK), | 1896 | PINMUX_GPIO(GPIO_FN_LCD_DATA21_PG21, LCD_DATA21_PG21_MARK), |
1883 | PINMUX_GPIO(GPIO_FN_LCD_DATA20, LCD_DATA20_MARK), | 1897 | PINMUX_GPIO(GPIO_FN_LCD_DATA20_PG20, LCD_DATA20_PG20_MARK), |
1884 | PINMUX_GPIO(GPIO_FN_LCD_DATA19, LCD_DATA19_MARK), | 1898 | PINMUX_GPIO(GPIO_FN_LCD_DATA19_PG19, LCD_DATA19_PG19_MARK), |
1885 | PINMUX_GPIO(GPIO_FN_LCD_DATA18, LCD_DATA18_MARK), | 1899 | PINMUX_GPIO(GPIO_FN_LCD_DATA18_PG18, LCD_DATA18_PG18_MARK), |
1886 | PINMUX_GPIO(GPIO_FN_LCD_DATA17, LCD_DATA17_MARK), | 1900 | PINMUX_GPIO(GPIO_FN_LCD_DATA17_PG17, LCD_DATA17_PG17_MARK), |
1887 | PINMUX_GPIO(GPIO_FN_LCD_DATA16, LCD_DATA16_MARK), | 1901 | PINMUX_GPIO(GPIO_FN_LCD_DATA16_PG16, LCD_DATA16_PG16_MARK), |
1888 | PINMUX_GPIO(GPIO_FN_LCD_DATA15, LCD_DATA15_MARK), | 1902 | PINMUX_GPIO(GPIO_FN_LCD_DATA15_PG15, LCD_DATA15_PG15_MARK), |
1889 | PINMUX_GPIO(GPIO_FN_LCD_DATA14, LCD_DATA14_MARK), | 1903 | PINMUX_GPIO(GPIO_FN_LCD_DATA14_PG14, LCD_DATA14_PG14_MARK), |
1890 | PINMUX_GPIO(GPIO_FN_LCD_DATA13, LCD_DATA13_MARK), | 1904 | PINMUX_GPIO(GPIO_FN_LCD_DATA13_PG13, LCD_DATA13_PG13_MARK), |
1891 | PINMUX_GPIO(GPIO_FN_LCD_DATA12, LCD_DATA12_MARK), | 1905 | PINMUX_GPIO(GPIO_FN_LCD_DATA12_PG12, LCD_DATA12_PG12_MARK), |
1892 | PINMUX_GPIO(GPIO_FN_LCD_DATA11, LCD_DATA11_MARK), | 1906 | PINMUX_GPIO(GPIO_FN_LCD_DATA11_PG11, LCD_DATA11_PG11_MARK), |
1893 | PINMUX_GPIO(GPIO_FN_LCD_DATA10, LCD_DATA10_MARK), | 1907 | PINMUX_GPIO(GPIO_FN_LCD_DATA10_PG10, LCD_DATA10_PG10_MARK), |
1894 | PINMUX_GPIO(GPIO_FN_LCD_DATA9, LCD_DATA9_MARK), | 1908 | PINMUX_GPIO(GPIO_FN_LCD_DATA9_PG9, LCD_DATA9_PG9_MARK), |
1895 | PINMUX_GPIO(GPIO_FN_LCD_DATA8, LCD_DATA8_MARK), | 1909 | PINMUX_GPIO(GPIO_FN_LCD_DATA8_PG8, LCD_DATA8_PG8_MARK), |
1896 | PINMUX_GPIO(GPIO_FN_LCD_DATA7, LCD_DATA7_MARK), | 1910 | PINMUX_GPIO(GPIO_FN_LCD_DATA7_PG7, LCD_DATA7_PG7_MARK), |
1897 | PINMUX_GPIO(GPIO_FN_LCD_DATA6, LCD_DATA6_MARK), | 1911 | PINMUX_GPIO(GPIO_FN_LCD_DATA6_PG6, LCD_DATA6_PG6_MARK), |
1898 | PINMUX_GPIO(GPIO_FN_LCD_DATA5, LCD_DATA5_MARK), | 1912 | PINMUX_GPIO(GPIO_FN_LCD_DATA5_PG5, LCD_DATA5_PG5_MARK), |
1899 | PINMUX_GPIO(GPIO_FN_LCD_DATA4, LCD_DATA4_MARK), | 1913 | PINMUX_GPIO(GPIO_FN_LCD_DATA4_PG4, LCD_DATA4_PG4_MARK), |
1900 | PINMUX_GPIO(GPIO_FN_LCD_DATA3, LCD_DATA3_MARK), | 1914 | PINMUX_GPIO(GPIO_FN_LCD_DATA3_PG3, LCD_DATA3_PG3_MARK), |
1901 | PINMUX_GPIO(GPIO_FN_LCD_DATA2, LCD_DATA2_MARK), | 1915 | PINMUX_GPIO(GPIO_FN_LCD_DATA2_PG2, LCD_DATA2_PG2_MARK), |
1902 | PINMUX_GPIO(GPIO_FN_LCD_DATA1, LCD_DATA1_MARK), | 1916 | PINMUX_GPIO(GPIO_FN_LCD_DATA1_PG1, LCD_DATA1_PG1_MARK), |
1903 | PINMUX_GPIO(GPIO_FN_LCD_DATA0, LCD_DATA0_MARK), | 1917 | PINMUX_GPIO(GPIO_FN_LCD_DATA0_PG0, LCD_DATA0_PG0_MARK), |
1918 | |||
1919 | PINMUX_GPIO(GPIO_FN_LCD_DATA23_PJ23, LCD_DATA23_PJ23_MARK), | ||
1920 | PINMUX_GPIO(GPIO_FN_LCD_DATA22_PJ22, LCD_DATA22_PJ22_MARK), | ||
1921 | PINMUX_GPIO(GPIO_FN_LCD_DATA21_PJ21, LCD_DATA21_PJ21_MARK), | ||
1922 | PINMUX_GPIO(GPIO_FN_LCD_DATA20_PJ20, LCD_DATA20_PJ20_MARK), | ||
1923 | PINMUX_GPIO(GPIO_FN_LCD_DATA19_PJ19, LCD_DATA19_PJ19_MARK), | ||
1924 | PINMUX_GPIO(GPIO_FN_LCD_DATA18_PJ18, LCD_DATA18_PJ18_MARK), | ||
1925 | PINMUX_GPIO(GPIO_FN_LCD_DATA17_PJ17, LCD_DATA17_PJ17_MARK), | ||
1926 | PINMUX_GPIO(GPIO_FN_LCD_DATA16_PJ16, LCD_DATA16_PJ16_MARK), | ||
1927 | PINMUX_GPIO(GPIO_FN_LCD_DATA15_PJ15, LCD_DATA15_PJ15_MARK), | ||
1928 | PINMUX_GPIO(GPIO_FN_LCD_DATA14_PJ14, LCD_DATA14_PJ14_MARK), | ||
1929 | PINMUX_GPIO(GPIO_FN_LCD_DATA13_PJ13, LCD_DATA13_PJ13_MARK), | ||
1930 | PINMUX_GPIO(GPIO_FN_LCD_DATA12_PJ12, LCD_DATA12_PJ12_MARK), | ||
1931 | PINMUX_GPIO(GPIO_FN_LCD_DATA11_PJ11, LCD_DATA11_PJ11_MARK), | ||
1932 | PINMUX_GPIO(GPIO_FN_LCD_DATA10_PJ10, LCD_DATA10_PJ10_MARK), | ||
1933 | PINMUX_GPIO(GPIO_FN_LCD_DATA9_PJ9, LCD_DATA9_PJ9_MARK), | ||
1934 | PINMUX_GPIO(GPIO_FN_LCD_DATA8_PJ8, LCD_DATA8_PJ8_MARK), | ||
1935 | PINMUX_GPIO(GPIO_FN_LCD_DATA7_PJ7, LCD_DATA7_PJ7_MARK), | ||
1936 | PINMUX_GPIO(GPIO_FN_LCD_DATA6_PJ6, LCD_DATA6_PJ6_MARK), | ||
1937 | PINMUX_GPIO(GPIO_FN_LCD_DATA5_PJ5, LCD_DATA5_PJ5_MARK), | ||
1938 | PINMUX_GPIO(GPIO_FN_LCD_DATA4_PJ4, LCD_DATA4_PJ4_MARK), | ||
1939 | PINMUX_GPIO(GPIO_FN_LCD_DATA3_PJ3, LCD_DATA3_PJ3_MARK), | ||
1940 | PINMUX_GPIO(GPIO_FN_LCD_DATA2_PJ2, LCD_DATA2_PJ2_MARK), | ||
1941 | PINMUX_GPIO(GPIO_FN_LCD_DATA1_PJ1, LCD_DATA1_PJ1_MARK), | ||
1942 | PINMUX_GPIO(GPIO_FN_LCD_DATA0_PJ0, LCD_DATA0_PJ0_MARK), | ||
1904 | 1943 | ||
1905 | PINMUX_GPIO(GPIO_FN_LCD_M_DISP, LCD_M_DISP_MARK), | 1944 | PINMUX_GPIO(GPIO_FN_LCD_M_DISP, LCD_M_DISP_MARK), |
1906 | }; | 1945 | }; |
diff --git a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c index c87e78f73234..5f30f805d2f2 100644 --- a/arch/sh/kernel/cpu/sh4a/clock-sh7724.c +++ b/arch/sh/kernel/cpu/sh4a/clock-sh7724.c | |||
@@ -334,8 +334,8 @@ static struct clk_lookup lookups[] = { | |||
334 | CLKDEV_CON_ID("tpu0", &mstp_clks[HWBLK_TPU]), | 334 | CLKDEV_CON_ID("tpu0", &mstp_clks[HWBLK_TPU]), |
335 | CLKDEV_CON_ID("irda0", &mstp_clks[HWBLK_IRDA]), | 335 | CLKDEV_CON_ID("irda0", &mstp_clks[HWBLK_IRDA]), |
336 | CLKDEV_CON_ID("tsif0", &mstp_clks[HWBLK_TSIF]), | 336 | CLKDEV_CON_ID("tsif0", &mstp_clks[HWBLK_TSIF]), |
337 | CLKDEV_CON_ID("usb1", &mstp_clks[HWBLK_USB1]), | 337 | CLKDEV_DEV_ID("renesas_usbhs.1", &mstp_clks[HWBLK_USB1]), |
338 | CLKDEV_CON_ID("usb0", &mstp_clks[HWBLK_USB0]), | 338 | CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[HWBLK_USB0]), |
339 | CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]), | 339 | CLKDEV_CON_ID("2dg0", &mstp_clks[HWBLK_2DG]), |
340 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[HWBLK_SDHI0]), | 340 | CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[HWBLK_SDHI0]), |
341 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[HWBLK_SDHI1]), | 341 | CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[HWBLK_SDHI1]), |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c index 65786c7f5ded..6a868b091c2d 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7722.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7722.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/platform_device.h> | 12 | #include <linux/platform_device.h> |
13 | #include <linux/serial.h> | 13 | #include <linux/serial.h> |
14 | #include <linux/serial_sci.h> | 14 | #include <linux/serial_sci.h> |
15 | #include <linux/sh_dma.h> | ||
15 | #include <linux/sh_timer.h> | 16 | #include <linux/sh_timer.h> |
16 | #include <linux/sh_intc.h> | 17 | #include <linux/sh_intc.h> |
17 | #include <linux/uio_driver.h> | 18 | #include <linux/uio_driver.h> |
diff --git a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c index a7708425afa9..4a2f357f4df8 100644 --- a/arch/sh/kernel/cpu/sh4a/setup-sh7757.c +++ b/arch/sh/kernel/cpu/sh4a/setup-sh7757.c | |||
@@ -216,6 +216,20 @@ static const struct sh_dmae_slave_config sh7757_dmae1_slaves[] = { | |||
216 | TS_INDEX2VAL(XMIT_SZ_8BIT), | 216 | TS_INDEX2VAL(XMIT_SZ_8BIT), |
217 | .mid_rid = 0x42, | 217 | .mid_rid = 0x42, |
218 | }, | 218 | }, |
219 | { | ||
220 | .slave_id = SHDMA_SLAVE_RSPI_TX, | ||
221 | .addr = 0xfe480004, | ||
222 | .chcr = SM_INC | 0x800 | 0x40000000 | | ||
223 | TS_INDEX2VAL(XMIT_SZ_16BIT), | ||
224 | .mid_rid = 0xc1, | ||
225 | }, | ||
226 | { | ||
227 | .slave_id = SHDMA_SLAVE_RSPI_RX, | ||
228 | .addr = 0xfe480004, | ||
229 | .chcr = DM_INC | 0x800 | 0x40000000 | | ||
230 | TS_INDEX2VAL(XMIT_SZ_16BIT), | ||
231 | .mid_rid = 0xc2, | ||
232 | }, | ||
219 | }; | 233 | }; |
220 | 234 | ||
221 | static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { | 235 | static const struct sh_dmae_slave_config sh7757_dmae2_slaves[] = { |
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index 7b57bf1dc855..ebe7a7d97215 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c | |||
@@ -273,7 +273,7 @@ void __init setup_arch(char **cmdline_p) | |||
273 | data_resource.start = virt_to_phys(_etext); | 273 | data_resource.start = virt_to_phys(_etext); |
274 | data_resource.end = virt_to_phys(_edata)-1; | 274 | data_resource.end = virt_to_phys(_edata)-1; |
275 | bss_resource.start = virt_to_phys(__bss_start); | 275 | bss_resource.start = virt_to_phys(__bss_start); |
276 | bss_resource.end = virt_to_phys(_ebss)-1; | 276 | bss_resource.end = virt_to_phys(__bss_stop)-1; |
277 | 277 | ||
278 | #ifdef CONFIG_CMDLINE_OVERWRITE | 278 | #ifdef CONFIG_CMDLINE_OVERWRITE |
279 | strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line)); | 279 | strlcpy(command_line, CONFIG_CMDLINE, sizeof(command_line)); |
diff --git a/arch/sh/kernel/sh_ksyms_32.c b/arch/sh/kernel/sh_ksyms_32.c index 3896f26efa4a..2a0a596ebf67 100644 --- a/arch/sh/kernel/sh_ksyms_32.c +++ b/arch/sh/kernel/sh_ksyms_32.c | |||
@@ -19,7 +19,6 @@ EXPORT_SYMBOL(csum_partial); | |||
19 | EXPORT_SYMBOL(csum_partial_copy_generic); | 19 | EXPORT_SYMBOL(csum_partial_copy_generic); |
20 | EXPORT_SYMBOL(copy_page); | 20 | EXPORT_SYMBOL(copy_page); |
21 | EXPORT_SYMBOL(__clear_user); | 21 | EXPORT_SYMBOL(__clear_user); |
22 | EXPORT_SYMBOL(_ebss); | ||
23 | EXPORT_SYMBOL(empty_zero_page); | 22 | EXPORT_SYMBOL(empty_zero_page); |
24 | 23 | ||
25 | #define DECLARE_EXPORT(name) \ | 24 | #define DECLARE_EXPORT(name) \ |
diff --git a/arch/sh/kernel/vmlinux.lds.S b/arch/sh/kernel/vmlinux.lds.S index c98905f71e28..db88cbf9eafd 100644 --- a/arch/sh/kernel/vmlinux.lds.S +++ b/arch/sh/kernel/vmlinux.lds.S | |||
@@ -78,7 +78,6 @@ SECTIONS | |||
78 | . = ALIGN(PAGE_SIZE); | 78 | . = ALIGN(PAGE_SIZE); |
79 | __init_end = .; | 79 | __init_end = .; |
80 | BSS_SECTION(0, PAGE_SIZE, 4) | 80 | BSS_SECTION(0, PAGE_SIZE, 4) |
81 | _ebss = .; /* uClinux MTD sucks */ | ||
82 | _end = . ; | 81 | _end = . ; |
83 | 82 | ||
84 | STABS_DEBUG | 83 | STABS_DEBUG |
diff --git a/arch/sh/lib/mcount.S b/arch/sh/lib/mcount.S index 84a57761f17e..60164e65d665 100644 --- a/arch/sh/lib/mcount.S +++ b/arch/sh/lib/mcount.S | |||
@@ -39,7 +39,7 @@ | |||
39 | * | 39 | * |
40 | * Make sure the stack pointer contains a valid address. Valid | 40 | * Make sure the stack pointer contains a valid address. Valid |
41 | * addresses for kernel stacks are anywhere after the bss | 41 | * addresses for kernel stacks are anywhere after the bss |
42 | * (after _ebss) and anywhere in init_thread_union (init_stack). | 42 | * (after __bss_stop) and anywhere in init_thread_union (init_stack). |
43 | */ | 43 | */ |
44 | #define STACK_CHECK() \ | 44 | #define STACK_CHECK() \ |
45 | mov #(THREAD_SIZE >> 10), r0; \ | 45 | mov #(THREAD_SIZE >> 10), r0; \ |
@@ -60,7 +60,7 @@ | |||
60 | cmp/hi r2, r1; \ | 60 | cmp/hi r2, r1; \ |
61 | bf stack_panic; \ | 61 | bf stack_panic; \ |
62 | \ | 62 | \ |
63 | /* If sp > _ebss then we're OK. */ \ | 63 | /* If sp > __bss_stop then we're OK. */ \ |
64 | mov.l .L_ebss, r1; \ | 64 | mov.l .L_ebss, r1; \ |
65 | cmp/hi r1, r15; \ | 65 | cmp/hi r1, r15; \ |
66 | bt 1f; \ | 66 | bt 1f; \ |
@@ -70,7 +70,7 @@ | |||
70 | cmp/hs r1, r15; \ | 70 | cmp/hs r1, r15; \ |
71 | bf stack_panic; \ | 71 | bf stack_panic; \ |
72 | \ | 72 | \ |
73 | /* If sp > init_stack && sp < _ebss, not OK. */ \ | 73 | /* If sp > init_stack && sp < __bss_stop, not OK. */ \ |
74 | add r0, r1; \ | 74 | add r0, r1; \ |
75 | cmp/hs r1, r15; \ | 75 | cmp/hs r1, r15; \ |
76 | bt stack_panic; \ | 76 | bt stack_panic; \ |
@@ -292,8 +292,6 @@ stack_panic: | |||
292 | nop | 292 | nop |
293 | 293 | ||
294 | .align 2 | 294 | .align 2 |
295 | .L_ebss: | ||
296 | .long _ebss | ||
297 | .L_init_thread_union: | 295 | .L_init_thread_union: |
298 | .long init_thread_union | 296 | .long init_thread_union |
299 | .Lpanic: | 297 | .Lpanic: |
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index 1fc25d85e515..3bdc1ad9a341 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c | |||
@@ -58,11 +58,15 @@ static void show_pte(struct mm_struct *mm, unsigned long addr) | |||
58 | { | 58 | { |
59 | pgd_t *pgd; | 59 | pgd_t *pgd; |
60 | 60 | ||
61 | if (mm) | 61 | if (mm) { |
62 | pgd = mm->pgd; | 62 | pgd = mm->pgd; |
63 | else | 63 | } else { |
64 | pgd = get_TTB(); | 64 | pgd = get_TTB(); |
65 | 65 | ||
66 | if (unlikely(!pgd)) | ||
67 | pgd = swapper_pg_dir; | ||
68 | } | ||
69 | |||
66 | printk(KERN_ALERT "pgd = %p\n", pgd); | 70 | printk(KERN_ALERT "pgd = %p\n", pgd); |
67 | pgd += pgd_index(addr); | 71 | pgd += pgd_index(addr); |
68 | printk(KERN_ALERT "[%08lx] *pgd=%0*Lx", addr, | 72 | printk(KERN_ALERT "[%08lx] *pgd=%0*Lx", addr, |
diff --git a/arch/sparc/kernel/sys_sparc_64.c b/arch/sparc/kernel/sys_sparc_64.c index 0dc1f5786081..11c6c9603e71 100644 --- a/arch/sparc/kernel/sys_sparc_64.c +++ b/arch/sparc/kernel/sys_sparc_64.c | |||
@@ -502,12 +502,12 @@ SYSCALL_DEFINE1(sparc64_personality, unsigned long, personality) | |||
502 | { | 502 | { |
503 | int ret; | 503 | int ret; |
504 | 504 | ||
505 | if (current->personality == PER_LINUX32 && | 505 | if (personality(current->personality) == PER_LINUX32 && |
506 | personality == PER_LINUX) | 506 | personality(personality) == PER_LINUX) |
507 | personality = PER_LINUX32; | 507 | personality |= PER_LINUX32; |
508 | ret = sys_personality(personality); | 508 | ret = sys_personality(personality); |
509 | if (ret == PER_LINUX32) | 509 | if (personality(ret) == PER_LINUX32) |
510 | ret = PER_LINUX; | 510 | ret &= ~PER_LINUX32; |
511 | 511 | ||
512 | return ret; | 512 | return ret; |
513 | } | 513 | } |
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 6026fdd1b2ed..d58edf5fefdb 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
@@ -2020,6 +2020,9 @@ EXPORT_SYMBOL(_PAGE_CACHE); | |||
2020 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | 2020 | #ifdef CONFIG_SPARSEMEM_VMEMMAP |
2021 | unsigned long vmemmap_table[VMEMMAP_SIZE]; | 2021 | unsigned long vmemmap_table[VMEMMAP_SIZE]; |
2022 | 2022 | ||
2023 | static long __meminitdata addr_start, addr_end; | ||
2024 | static int __meminitdata node_start; | ||
2025 | |||
2023 | int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) | 2026 | int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) |
2024 | { | 2027 | { |
2025 | unsigned long vstart = (unsigned long) start; | 2028 | unsigned long vstart = (unsigned long) start; |
@@ -2050,15 +2053,30 @@ int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node) | |||
2050 | 2053 | ||
2051 | *vmem_pp = pte_base | __pa(block); | 2054 | *vmem_pp = pte_base | __pa(block); |
2052 | 2055 | ||
2053 | printk(KERN_INFO "[%p-%p] page_structs=%lu " | 2056 | /* check to see if we have contiguous blocks */ |
2054 | "node=%d entry=%lu/%lu\n", start, block, nr, | 2057 | if (addr_end != addr || node_start != node) { |
2055 | node, | 2058 | if (addr_start) |
2056 | addr >> VMEMMAP_CHUNK_SHIFT, | 2059 | printk(KERN_DEBUG " [%lx-%lx] on node %d\n", |
2057 | VMEMMAP_SIZE); | 2060 | addr_start, addr_end-1, node_start); |
2061 | addr_start = addr; | ||
2062 | node_start = node; | ||
2063 | } | ||
2064 | addr_end = addr + VMEMMAP_CHUNK; | ||
2058 | } | 2065 | } |
2059 | } | 2066 | } |
2060 | return 0; | 2067 | return 0; |
2061 | } | 2068 | } |
2069 | |||
2070 | void __meminit vmemmap_populate_print_last(void) | ||
2071 | { | ||
2072 | if (addr_start) { | ||
2073 | printk(KERN_DEBUG " [%lx-%lx] on node %d\n", | ||
2074 | addr_start, addr_end-1, node_start); | ||
2075 | addr_start = 0; | ||
2076 | addr_end = 0; | ||
2077 | node_start = 0; | ||
2078 | } | ||
2079 | } | ||
2062 | #endif /* CONFIG_SPARSEMEM_VMEMMAP */ | 2080 | #endif /* CONFIG_SPARSEMEM_VMEMMAP */ |
2063 | 2081 | ||
2064 | static void prot_init_common(unsigned long page_none, | 2082 | static void prot_init_common(unsigned long page_none, |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index ba2657c49217..8ec3a1aa4abd 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -1527,7 +1527,7 @@ config SECCOMP | |||
1527 | If unsure, say Y. Only embedded should say N here. | 1527 | If unsure, say Y. Only embedded should say N here. |
1528 | 1528 | ||
1529 | config CC_STACKPROTECTOR | 1529 | config CC_STACKPROTECTOR |
1530 | bool "Enable -fstack-protector buffer overflow detection (EXPERIMENTAL)" | 1530 | bool "Enable -fstack-protector buffer overflow detection" |
1531 | ---help--- | 1531 | ---help--- |
1532 | This option turns on the -fstack-protector GCC feature. This | 1532 | This option turns on the -fstack-protector GCC feature. This |
1533 | feature puts, at the beginning of functions, a canary value on | 1533 | feature puts, at the beginning of functions, a canary value on |
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index b0c5276861ec..682e9c210baa 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile | |||
@@ -27,6 +27,10 @@ ifeq ($(CONFIG_X86_32),y) | |||
27 | 27 | ||
28 | KBUILD_CFLAGS += -msoft-float -mregparm=3 -freg-struct-return | 28 | KBUILD_CFLAGS += -msoft-float -mregparm=3 -freg-struct-return |
29 | 29 | ||
30 | # Never want PIC in a 32-bit kernel, prevent breakage with GCC built | ||
31 | # with nonstandard options | ||
32 | KBUILD_CFLAGS += -fno-pic | ||
33 | |||
30 | # prevent gcc from keeping the stack 16 byte aligned | 34 | # prevent gcc from keeping the stack 16 byte aligned |
31 | KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) | 35 | KBUILD_CFLAGS += $(call cc-option,-mpreferred-stack-boundary=2) |
32 | 36 | ||
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index 5a747dd884db..f7535bedc33f 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile | |||
@@ -57,7 +57,7 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) -g -Os -D_SETUP -D__KERNEL__ \ | |||
57 | -Wall -Wstrict-prototypes \ | 57 | -Wall -Wstrict-prototypes \ |
58 | -march=i386 -mregparm=3 \ | 58 | -march=i386 -mregparm=3 \ |
59 | -include $(srctree)/$(src)/code16gcc.h \ | 59 | -include $(srctree)/$(src)/code16gcc.h \ |
60 | -fno-strict-aliasing -fomit-frame-pointer \ | 60 | -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ |
61 | $(call cc-option, -ffreestanding) \ | 61 | $(call cc-option, -ffreestanding) \ |
62 | $(call cc-option, -fno-toplevel-reorder,\ | 62 | $(call cc-option, -fno-toplevel-reorder,\ |
63 | $(call cc-option, -fno-unit-at-a-time)) \ | 63 | $(call cc-option, -fno-unit-at-a-time)) \ |
diff --git a/arch/x86/include/asm/mce.h b/arch/x86/include/asm/mce.h index 441520e4174f..a3ac52b29cbf 100644 --- a/arch/x86/include/asm/mce.h +++ b/arch/x86/include/asm/mce.h | |||
@@ -33,6 +33,14 @@ | |||
33 | #define MCI_STATUS_PCC (1ULL<<57) /* processor context corrupt */ | 33 | #define MCI_STATUS_PCC (1ULL<<57) /* processor context corrupt */ |
34 | #define MCI_STATUS_S (1ULL<<56) /* Signaled machine check */ | 34 | #define MCI_STATUS_S (1ULL<<56) /* Signaled machine check */ |
35 | #define MCI_STATUS_AR (1ULL<<55) /* Action required */ | 35 | #define MCI_STATUS_AR (1ULL<<55) /* Action required */ |
36 | #define MCACOD 0xffff /* MCA Error Code */ | ||
37 | |||
38 | /* Architecturally defined codes from SDM Vol. 3B Chapter 15 */ | ||
39 | #define MCACOD_SCRUB 0x00C0 /* 0xC0-0xCF Memory Scrubbing */ | ||
40 | #define MCACOD_SCRUBMSK 0xfff0 | ||
41 | #define MCACOD_L3WB 0x017A /* L3 Explicit Writeback */ | ||
42 | #define MCACOD_DATA 0x0134 /* Data Load */ | ||
43 | #define MCACOD_INSTR 0x0150 /* Instruction Fetch */ | ||
36 | 44 | ||
37 | /* MCi_MISC register defines */ | 45 | /* MCi_MISC register defines */ |
38 | #define MCI_MISC_ADDR_LSB(m) ((m) & 0x3f) | 46 | #define MCI_MISC_ADDR_LSB(m) ((m) & 0x3f) |
diff --git a/arch/x86/include/asm/olpc.h b/arch/x86/include/asm/olpc.h index 87bdbca72f94..72f9adf6eca4 100644 --- a/arch/x86/include/asm/olpc.h +++ b/arch/x86/include/asm/olpc.h | |||
@@ -100,25 +100,6 @@ extern void olpc_xo1_pm_wakeup_clear(u16 value); | |||
100 | 100 | ||
101 | extern int pci_olpc_init(void); | 101 | extern int pci_olpc_init(void); |
102 | 102 | ||
103 | /* EC related functions */ | ||
104 | |||
105 | extern int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen, | ||
106 | unsigned char *outbuf, size_t outlen); | ||
107 | |||
108 | /* EC commands */ | ||
109 | |||
110 | #define EC_FIRMWARE_REV 0x08 | ||
111 | #define EC_WRITE_SCI_MASK 0x1b | ||
112 | #define EC_WAKE_UP_WLAN 0x24 | ||
113 | #define EC_WLAN_LEAVE_RESET 0x25 | ||
114 | #define EC_READ_EB_MODE 0x2a | ||
115 | #define EC_SET_SCI_INHIBIT 0x32 | ||
116 | #define EC_SET_SCI_INHIBIT_RELEASE 0x34 | ||
117 | #define EC_WLAN_ENTER_RESET 0x35 | ||
118 | #define EC_WRITE_EXT_SCI_MASK 0x38 | ||
119 | #define EC_SCI_QUERY 0x84 | ||
120 | #define EC_EXT_SCI_QUERY 0x85 | ||
121 | |||
122 | /* SCI source values */ | 103 | /* SCI source values */ |
123 | 104 | ||
124 | #define EC_SCI_SRC_EMPTY 0x00 | 105 | #define EC_SCI_SRC_EMPTY 0x00 |
diff --git a/arch/x86/include/asm/perf_event.h b/arch/x86/include/asm/perf_event.h index dab39350e51e..cb4e43bce98a 100644 --- a/arch/x86/include/asm/perf_event.h +++ b/arch/x86/include/asm/perf_event.h | |||
@@ -196,11 +196,16 @@ static inline u32 get_ibs_caps(void) { return 0; } | |||
196 | extern void perf_events_lapic_init(void); | 196 | extern void perf_events_lapic_init(void); |
197 | 197 | ||
198 | /* | 198 | /* |
199 | * Abuse bit 3 of the cpu eflags register to indicate proper PEBS IP fixups. | 199 | * Abuse bits {3,5} of the cpu eflags register. These flags are otherwise |
200 | * This flag is otherwise unused and ABI specified to be 0, so nobody should | 200 | * unused and ABI specified to be 0, so nobody should care what we do with |
201 | * care what we do with it. | 201 | * them. |
202 | * | ||
203 | * EXACT - the IP points to the exact instruction that triggered the | ||
204 | * event (HW bugs exempt). | ||
205 | * VM - original X86_VM_MASK; see set_linear_ip(). | ||
202 | */ | 206 | */ |
203 | #define PERF_EFLAGS_EXACT (1UL << 3) | 207 | #define PERF_EFLAGS_EXACT (1UL << 3) |
208 | #define PERF_EFLAGS_VM (1UL << 5) | ||
204 | 209 | ||
205 | struct pt_regs; | 210 | struct pt_regs; |
206 | extern unsigned long perf_instruction_pointer(struct pt_regs *regs); | 211 | extern unsigned long perf_instruction_pointer(struct pt_regs *regs); |
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 95bf99de9058..1b8e5a03d942 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
@@ -25,10 +25,6 @@ unsigned long acpi_realmode_flags; | |||
25 | static char temp_stack[4096]; | 25 | static char temp_stack[4096]; |
26 | #endif | 26 | #endif |
27 | 27 | ||
28 | asmlinkage void acpi_enter_s3(void) | ||
29 | { | ||
30 | acpi_enter_sleep_state(3, wake_sleep_flags); | ||
31 | } | ||
32 | /** | 28 | /** |
33 | * acpi_suspend_lowlevel - save kernel state | 29 | * acpi_suspend_lowlevel - save kernel state |
34 | * | 30 | * |
diff --git a/arch/x86/kernel/acpi/sleep.h b/arch/x86/kernel/acpi/sleep.h index 5653a5791ec9..67f59f8c6956 100644 --- a/arch/x86/kernel/acpi/sleep.h +++ b/arch/x86/kernel/acpi/sleep.h | |||
@@ -2,7 +2,6 @@ | |||
2 | * Variables and functions used by the code in sleep.c | 2 | * Variables and functions used by the code in sleep.c |
3 | */ | 3 | */ |
4 | 4 | ||
5 | #include <linux/linkage.h> | ||
6 | #include <asm/realmode.h> | 5 | #include <asm/realmode.h> |
7 | 6 | ||
8 | extern unsigned long saved_video_mode; | 7 | extern unsigned long saved_video_mode; |
@@ -11,7 +10,6 @@ extern long saved_magic; | |||
11 | extern int wakeup_pmode_return; | 10 | extern int wakeup_pmode_return; |
12 | 11 | ||
13 | extern u8 wake_sleep_flags; | 12 | extern u8 wake_sleep_flags; |
14 | extern asmlinkage void acpi_enter_s3(void); | ||
15 | 13 | ||
16 | extern unsigned long acpi_copy_wakeup_routine(unsigned long); | 14 | extern unsigned long acpi_copy_wakeup_routine(unsigned long); |
17 | extern void wakeup_long64(void); | 15 | extern void wakeup_long64(void); |
diff --git a/arch/x86/kernel/acpi/wakeup_32.S b/arch/x86/kernel/acpi/wakeup_32.S index 72610839f03b..13ab720573e3 100644 --- a/arch/x86/kernel/acpi/wakeup_32.S +++ b/arch/x86/kernel/acpi/wakeup_32.S | |||
@@ -74,7 +74,9 @@ restore_registers: | |||
74 | ENTRY(do_suspend_lowlevel) | 74 | ENTRY(do_suspend_lowlevel) |
75 | call save_processor_state | 75 | call save_processor_state |
76 | call save_registers | 76 | call save_registers |
77 | call acpi_enter_s3 | 77 | pushl $3 |
78 | call acpi_enter_sleep_state | ||
79 | addl $4, %esp | ||
78 | 80 | ||
79 | # In case of S3 failure, we'll emerge here. Jump | 81 | # In case of S3 failure, we'll emerge here. Jump |
80 | # to ret_point to recover | 82 | # to ret_point to recover |
diff --git a/arch/x86/kernel/acpi/wakeup_64.S b/arch/x86/kernel/acpi/wakeup_64.S index 014d1d28c397..8ea5164cbd04 100644 --- a/arch/x86/kernel/acpi/wakeup_64.S +++ b/arch/x86/kernel/acpi/wakeup_64.S | |||
@@ -71,7 +71,9 @@ ENTRY(do_suspend_lowlevel) | |||
71 | movq %rsi, saved_rsi | 71 | movq %rsi, saved_rsi |
72 | 72 | ||
73 | addq $8, %rsp | 73 | addq $8, %rsp |
74 | call acpi_enter_s3 | 74 | movl $3, %edi |
75 | xorl %eax, %eax | ||
76 | call acpi_enter_sleep_state | ||
75 | /* in case something went wrong, restore the machine status and go on */ | 77 | /* in case something went wrong, restore the machine status and go on */ |
76 | jmp resume_point | 78 | jmp resume_point |
77 | 79 | ||
diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c index 931280ff8299..afb7ff79a29f 100644 --- a/arch/x86/kernel/alternative.c +++ b/arch/x86/kernel/alternative.c | |||
@@ -224,7 +224,7 @@ void __init arch_init_ideal_nops(void) | |||
224 | ideal_nops = intel_nops; | 224 | ideal_nops = intel_nops; |
225 | #endif | 225 | #endif |
226 | } | 226 | } |
227 | 227 | break; | |
228 | default: | 228 | default: |
229 | #ifdef CONFIG_X86_64 | 229 | #ifdef CONFIG_X86_64 |
230 | ideal_nops = k8_nops; | 230 | ideal_nops = k8_nops; |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index 406eee784684..c265593ec2cd 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -1204,7 +1204,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) | |||
1204 | BUG_ON(!cfg->vector); | 1204 | BUG_ON(!cfg->vector); |
1205 | 1205 | ||
1206 | vector = cfg->vector; | 1206 | vector = cfg->vector; |
1207 | for_each_cpu(cpu, cfg->domain) | 1207 | for_each_cpu_and(cpu, cfg->domain, cpu_online_mask) |
1208 | per_cpu(vector_irq, cpu)[vector] = -1; | 1208 | per_cpu(vector_irq, cpu)[vector] = -1; |
1209 | 1209 | ||
1210 | cfg->vector = 0; | 1210 | cfg->vector = 0; |
@@ -1212,7 +1212,7 @@ static void __clear_irq_vector(int irq, struct irq_cfg *cfg) | |||
1212 | 1212 | ||
1213 | if (likely(!cfg->move_in_progress)) | 1213 | if (likely(!cfg->move_in_progress)) |
1214 | return; | 1214 | return; |
1215 | for_each_cpu(cpu, cfg->old_domain) { | 1215 | for_each_cpu_and(cpu, cfg->old_domain, cpu_online_mask) { |
1216 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; | 1216 | for (vector = FIRST_EXTERNAL_VECTOR; vector < NR_VECTORS; |
1217 | vector++) { | 1217 | vector++) { |
1218 | if (per_cpu(vector_irq, cpu)[vector] != irq) | 1218 | if (per_cpu(vector_irq, cpu)[vector] != irq) |
@@ -1356,6 +1356,16 @@ static void setup_ioapic_irq(unsigned int irq, struct irq_cfg *cfg, | |||
1356 | if (!IO_APIC_IRQ(irq)) | 1356 | if (!IO_APIC_IRQ(irq)) |
1357 | return; | 1357 | return; |
1358 | 1358 | ||
1359 | /* | ||
1360 | * For legacy irqs, cfg->domain starts with cpu 0. Now that IO-APIC | ||
1361 | * can handle this irq and the apic driver is finialized at this point, | ||
1362 | * update the cfg->domain. | ||
1363 | */ | ||
1364 | if (irq < legacy_pic->nr_legacy_irqs && | ||
1365 | cpumask_equal(cfg->domain, cpumask_of(0))) | ||
1366 | apic->vector_allocation_domain(0, cfg->domain, | ||
1367 | apic->target_cpus()); | ||
1368 | |||
1359 | if (assign_irq_vector(irq, cfg, apic->target_cpus())) | 1369 | if (assign_irq_vector(irq, cfg, apic->target_cpus())) |
1360 | return; | 1370 | return; |
1361 | 1371 | ||
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 46d8786d655e..a5fbc3c5fccc 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c | |||
@@ -144,6 +144,8 @@ static int __init x86_xsave_setup(char *s) | |||
144 | { | 144 | { |
145 | setup_clear_cpu_cap(X86_FEATURE_XSAVE); | 145 | setup_clear_cpu_cap(X86_FEATURE_XSAVE); |
146 | setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); | 146 | setup_clear_cpu_cap(X86_FEATURE_XSAVEOPT); |
147 | setup_clear_cpu_cap(X86_FEATURE_AVX); | ||
148 | setup_clear_cpu_cap(X86_FEATURE_AVX2); | ||
147 | return 1; | 149 | return 1; |
148 | } | 150 | } |
149 | __setup("noxsave", x86_xsave_setup); | 151 | __setup("noxsave", x86_xsave_setup); |
diff --git a/arch/x86/kernel/cpu/mcheck/mce-severity.c b/arch/x86/kernel/cpu/mcheck/mce-severity.c index 413c2ced887c..13017626f9a8 100644 --- a/arch/x86/kernel/cpu/mcheck/mce-severity.c +++ b/arch/x86/kernel/cpu/mcheck/mce-severity.c | |||
@@ -55,13 +55,6 @@ static struct severity { | |||
55 | #define MCI_UC_S (MCI_STATUS_UC|MCI_STATUS_S) | 55 | #define MCI_UC_S (MCI_STATUS_UC|MCI_STATUS_S) |
56 | #define MCI_UC_SAR (MCI_STATUS_UC|MCI_STATUS_S|MCI_STATUS_AR) | 56 | #define MCI_UC_SAR (MCI_STATUS_UC|MCI_STATUS_S|MCI_STATUS_AR) |
57 | #define MCI_ADDR (MCI_STATUS_ADDRV|MCI_STATUS_MISCV) | 57 | #define MCI_ADDR (MCI_STATUS_ADDRV|MCI_STATUS_MISCV) |
58 | #define MCACOD 0xffff | ||
59 | /* Architecturally defined codes from SDM Vol. 3B Chapter 15 */ | ||
60 | #define MCACOD_SCRUB 0x00C0 /* 0xC0-0xCF Memory Scrubbing */ | ||
61 | #define MCACOD_SCRUBMSK 0xfff0 | ||
62 | #define MCACOD_L3WB 0x017A /* L3 Explicit Writeback */ | ||
63 | #define MCACOD_DATA 0x0134 /* Data Load */ | ||
64 | #define MCACOD_INSTR 0x0150 /* Instruction Fetch */ | ||
65 | 58 | ||
66 | MCESEV( | 59 | MCESEV( |
67 | NO, "Invalid", | 60 | NO, "Invalid", |
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c index 5e095f873e3e..292d0258311c 100644 --- a/arch/x86/kernel/cpu/mcheck/mce.c +++ b/arch/x86/kernel/cpu/mcheck/mce.c | |||
@@ -103,6 +103,8 @@ DEFINE_PER_CPU(mce_banks_t, mce_poll_banks) = { | |||
103 | 103 | ||
104 | static DEFINE_PER_CPU(struct work_struct, mce_work); | 104 | static DEFINE_PER_CPU(struct work_struct, mce_work); |
105 | 105 | ||
106 | static void (*quirk_no_way_out)(int bank, struct mce *m, struct pt_regs *regs); | ||
107 | |||
106 | /* | 108 | /* |
107 | * CPU/chipset specific EDAC code can register a notifier call here to print | 109 | * CPU/chipset specific EDAC code can register a notifier call here to print |
108 | * MCE errors in a human-readable form. | 110 | * MCE errors in a human-readable form. |
@@ -650,14 +652,18 @@ EXPORT_SYMBOL_GPL(machine_check_poll); | |||
650 | * Do a quick check if any of the events requires a panic. | 652 | * Do a quick check if any of the events requires a panic. |
651 | * This decides if we keep the events around or clear them. | 653 | * This decides if we keep the events around or clear them. |
652 | */ | 654 | */ |
653 | static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp) | 655 | static int mce_no_way_out(struct mce *m, char **msg, unsigned long *validp, |
656 | struct pt_regs *regs) | ||
654 | { | 657 | { |
655 | int i, ret = 0; | 658 | int i, ret = 0; |
656 | 659 | ||
657 | for (i = 0; i < banks; i++) { | 660 | for (i = 0; i < banks; i++) { |
658 | m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i)); | 661 | m->status = mce_rdmsrl(MSR_IA32_MCx_STATUS(i)); |
659 | if (m->status & MCI_STATUS_VAL) | 662 | if (m->status & MCI_STATUS_VAL) { |
660 | __set_bit(i, validp); | 663 | __set_bit(i, validp); |
664 | if (quirk_no_way_out) | ||
665 | quirk_no_way_out(i, m, regs); | ||
666 | } | ||
661 | if (mce_severity(m, tolerant, msg) >= MCE_PANIC_SEVERITY) | 667 | if (mce_severity(m, tolerant, msg) >= MCE_PANIC_SEVERITY) |
662 | ret = 1; | 668 | ret = 1; |
663 | } | 669 | } |
@@ -1040,7 +1046,7 @@ void do_machine_check(struct pt_regs *regs, long error_code) | |||
1040 | *final = m; | 1046 | *final = m; |
1041 | 1047 | ||
1042 | memset(valid_banks, 0, sizeof(valid_banks)); | 1048 | memset(valid_banks, 0, sizeof(valid_banks)); |
1043 | no_way_out = mce_no_way_out(&m, &msg, valid_banks); | 1049 | no_way_out = mce_no_way_out(&m, &msg, valid_banks, regs); |
1044 | 1050 | ||
1045 | barrier(); | 1051 | barrier(); |
1046 | 1052 | ||
@@ -1418,6 +1424,34 @@ static void __mcheck_cpu_init_generic(void) | |||
1418 | } | 1424 | } |
1419 | } | 1425 | } |
1420 | 1426 | ||
1427 | /* | ||
1428 | * During IFU recovery Sandy Bridge -EP4S processors set the RIPV and | ||
1429 | * EIPV bits in MCG_STATUS to zero on the affected logical processor (SDM | ||
1430 | * Vol 3B Table 15-20). But this confuses both the code that determines | ||
1431 | * whether the machine check occurred in kernel or user mode, and also | ||
1432 | * the severity assessment code. Pretend that EIPV was set, and take the | ||
1433 | * ip/cs values from the pt_regs that mce_gather_info() ignored earlier. | ||
1434 | */ | ||
1435 | static void quirk_sandybridge_ifu(int bank, struct mce *m, struct pt_regs *regs) | ||
1436 | { | ||
1437 | if (bank != 0) | ||
1438 | return; | ||
1439 | if ((m->mcgstatus & (MCG_STATUS_EIPV|MCG_STATUS_RIPV)) != 0) | ||
1440 | return; | ||
1441 | if ((m->status & (MCI_STATUS_OVER|MCI_STATUS_UC| | ||
1442 | MCI_STATUS_EN|MCI_STATUS_MISCV|MCI_STATUS_ADDRV| | ||
1443 | MCI_STATUS_PCC|MCI_STATUS_S|MCI_STATUS_AR| | ||
1444 | MCACOD)) != | ||
1445 | (MCI_STATUS_UC|MCI_STATUS_EN| | ||
1446 | MCI_STATUS_MISCV|MCI_STATUS_ADDRV|MCI_STATUS_S| | ||
1447 | MCI_STATUS_AR|MCACOD_INSTR)) | ||
1448 | return; | ||
1449 | |||
1450 | m->mcgstatus |= MCG_STATUS_EIPV; | ||
1451 | m->ip = regs->ip; | ||
1452 | m->cs = regs->cs; | ||
1453 | } | ||
1454 | |||
1421 | /* Add per CPU specific workarounds here */ | 1455 | /* Add per CPU specific workarounds here */ |
1422 | static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) | 1456 | static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) |
1423 | { | 1457 | { |
@@ -1515,6 +1549,9 @@ static int __cpuinit __mcheck_cpu_apply_quirks(struct cpuinfo_x86 *c) | |||
1515 | */ | 1549 | */ |
1516 | if (c->x86 == 6 && c->x86_model <= 13 && mce_bootlog < 0) | 1550 | if (c->x86 == 6 && c->x86_model <= 13 && mce_bootlog < 0) |
1517 | mce_bootlog = 0; | 1551 | mce_bootlog = 0; |
1552 | |||
1553 | if (c->x86 == 6 && c->x86_model == 45) | ||
1554 | quirk_no_way_out = quirk_sandybridge_ifu; | ||
1518 | } | 1555 | } |
1519 | if (monarch_timeout < 0) | 1556 | if (monarch_timeout < 0) |
1520 | monarch_timeout = 0; | 1557 | monarch_timeout = 0; |
diff --git a/arch/x86/kernel/cpu/perf_event.c b/arch/x86/kernel/cpu/perf_event.c index 29557aa06dda..915b876edd1e 100644 --- a/arch/x86/kernel/cpu/perf_event.c +++ b/arch/x86/kernel/cpu/perf_event.c | |||
@@ -32,6 +32,8 @@ | |||
32 | #include <asm/smp.h> | 32 | #include <asm/smp.h> |
33 | #include <asm/alternative.h> | 33 | #include <asm/alternative.h> |
34 | #include <asm/timer.h> | 34 | #include <asm/timer.h> |
35 | #include <asm/desc.h> | ||
36 | #include <asm/ldt.h> | ||
35 | 37 | ||
36 | #include "perf_event.h" | 38 | #include "perf_event.h" |
37 | 39 | ||
@@ -1738,6 +1740,29 @@ valid_user_frame(const void __user *fp, unsigned long size) | |||
1738 | return (__range_not_ok(fp, size, TASK_SIZE) == 0); | 1740 | return (__range_not_ok(fp, size, TASK_SIZE) == 0); |
1739 | } | 1741 | } |
1740 | 1742 | ||
1743 | static unsigned long get_segment_base(unsigned int segment) | ||
1744 | { | ||
1745 | struct desc_struct *desc; | ||
1746 | int idx = segment >> 3; | ||
1747 | |||
1748 | if ((segment & SEGMENT_TI_MASK) == SEGMENT_LDT) { | ||
1749 | if (idx > LDT_ENTRIES) | ||
1750 | return 0; | ||
1751 | |||
1752 | if (idx > current->active_mm->context.size) | ||
1753 | return 0; | ||
1754 | |||
1755 | desc = current->active_mm->context.ldt; | ||
1756 | } else { | ||
1757 | if (idx > GDT_ENTRIES) | ||
1758 | return 0; | ||
1759 | |||
1760 | desc = __this_cpu_ptr(&gdt_page.gdt[0]); | ||
1761 | } | ||
1762 | |||
1763 | return get_desc_base(desc + idx); | ||
1764 | } | ||
1765 | |||
1741 | #ifdef CONFIG_COMPAT | 1766 | #ifdef CONFIG_COMPAT |
1742 | 1767 | ||
1743 | #include <asm/compat.h> | 1768 | #include <asm/compat.h> |
@@ -1746,13 +1771,17 @@ static inline int | |||
1746 | perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) | 1771 | perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) |
1747 | { | 1772 | { |
1748 | /* 32-bit process in 64-bit kernel. */ | 1773 | /* 32-bit process in 64-bit kernel. */ |
1774 | unsigned long ss_base, cs_base; | ||
1749 | struct stack_frame_ia32 frame; | 1775 | struct stack_frame_ia32 frame; |
1750 | const void __user *fp; | 1776 | const void __user *fp; |
1751 | 1777 | ||
1752 | if (!test_thread_flag(TIF_IA32)) | 1778 | if (!test_thread_flag(TIF_IA32)) |
1753 | return 0; | 1779 | return 0; |
1754 | 1780 | ||
1755 | fp = compat_ptr(regs->bp); | 1781 | cs_base = get_segment_base(regs->cs); |
1782 | ss_base = get_segment_base(regs->ss); | ||
1783 | |||
1784 | fp = compat_ptr(ss_base + regs->bp); | ||
1756 | while (entry->nr < PERF_MAX_STACK_DEPTH) { | 1785 | while (entry->nr < PERF_MAX_STACK_DEPTH) { |
1757 | unsigned long bytes; | 1786 | unsigned long bytes; |
1758 | frame.next_frame = 0; | 1787 | frame.next_frame = 0; |
@@ -1765,8 +1794,8 @@ perf_callchain_user32(struct pt_regs *regs, struct perf_callchain_entry *entry) | |||
1765 | if (!valid_user_frame(fp, sizeof(frame))) | 1794 | if (!valid_user_frame(fp, sizeof(frame))) |
1766 | break; | 1795 | break; |
1767 | 1796 | ||
1768 | perf_callchain_store(entry, frame.return_address); | 1797 | perf_callchain_store(entry, cs_base + frame.return_address); |
1769 | fp = compat_ptr(frame.next_frame); | 1798 | fp = compat_ptr(ss_base + frame.next_frame); |
1770 | } | 1799 | } |
1771 | return 1; | 1800 | return 1; |
1772 | } | 1801 | } |
@@ -1789,6 +1818,12 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) | |||
1789 | return; | 1818 | return; |
1790 | } | 1819 | } |
1791 | 1820 | ||
1821 | /* | ||
1822 | * We don't know what to do with VM86 stacks.. ignore them for now. | ||
1823 | */ | ||
1824 | if (regs->flags & (X86_VM_MASK | PERF_EFLAGS_VM)) | ||
1825 | return; | ||
1826 | |||
1792 | fp = (void __user *)regs->bp; | 1827 | fp = (void __user *)regs->bp; |
1793 | 1828 | ||
1794 | perf_callchain_store(entry, regs->ip); | 1829 | perf_callchain_store(entry, regs->ip); |
@@ -1816,16 +1851,50 @@ perf_callchain_user(struct perf_callchain_entry *entry, struct pt_regs *regs) | |||
1816 | } | 1851 | } |
1817 | } | 1852 | } |
1818 | 1853 | ||
1819 | unsigned long perf_instruction_pointer(struct pt_regs *regs) | 1854 | /* |
1855 | * Deal with code segment offsets for the various execution modes: | ||
1856 | * | ||
1857 | * VM86 - the good olde 16 bit days, where the linear address is | ||
1858 | * 20 bits and we use regs->ip + 0x10 * regs->cs. | ||
1859 | * | ||
1860 | * IA32 - Where we need to look at GDT/LDT segment descriptor tables | ||
1861 | * to figure out what the 32bit base address is. | ||
1862 | * | ||
1863 | * X32 - has TIF_X32 set, but is running in x86_64 | ||
1864 | * | ||
1865 | * X86_64 - CS,DS,SS,ES are all zero based. | ||
1866 | */ | ||
1867 | static unsigned long code_segment_base(struct pt_regs *regs) | ||
1820 | { | 1868 | { |
1821 | unsigned long ip; | 1869 | /* |
1870 | * If we are in VM86 mode, add the segment offset to convert to a | ||
1871 | * linear address. | ||
1872 | */ | ||
1873 | if (regs->flags & X86_VM_MASK) | ||
1874 | return 0x10 * regs->cs; | ||
1875 | |||
1876 | /* | ||
1877 | * For IA32 we look at the GDT/LDT segment base to convert the | ||
1878 | * effective IP to a linear address. | ||
1879 | */ | ||
1880 | #ifdef CONFIG_X86_32 | ||
1881 | if (user_mode(regs) && regs->cs != __USER_CS) | ||
1882 | return get_segment_base(regs->cs); | ||
1883 | #else | ||
1884 | if (test_thread_flag(TIF_IA32)) { | ||
1885 | if (user_mode(regs) && regs->cs != __USER32_CS) | ||
1886 | return get_segment_base(regs->cs); | ||
1887 | } | ||
1888 | #endif | ||
1889 | return 0; | ||
1890 | } | ||
1822 | 1891 | ||
1892 | unsigned long perf_instruction_pointer(struct pt_regs *regs) | ||
1893 | { | ||
1823 | if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) | 1894 | if (perf_guest_cbs && perf_guest_cbs->is_in_guest()) |
1824 | ip = perf_guest_cbs->get_guest_ip(); | 1895 | return perf_guest_cbs->get_guest_ip(); |
1825 | else | ||
1826 | ip = instruction_pointer(regs); | ||
1827 | 1896 | ||
1828 | return ip; | 1897 | return regs->ip + code_segment_base(regs); |
1829 | } | 1898 | } |
1830 | 1899 | ||
1831 | unsigned long perf_misc_flags(struct pt_regs *regs) | 1900 | unsigned long perf_misc_flags(struct pt_regs *regs) |
@@ -1838,7 +1907,7 @@ unsigned long perf_misc_flags(struct pt_regs *regs) | |||
1838 | else | 1907 | else |
1839 | misc |= PERF_RECORD_MISC_GUEST_KERNEL; | 1908 | misc |= PERF_RECORD_MISC_GUEST_KERNEL; |
1840 | } else { | 1909 | } else { |
1841 | if (!kernel_ip(regs->ip)) | 1910 | if (user_mode(regs)) |
1842 | misc |= PERF_RECORD_MISC_USER; | 1911 | misc |= PERF_RECORD_MISC_USER; |
1843 | else | 1912 | else |
1844 | misc |= PERF_RECORD_MISC_KERNEL; | 1913 | misc |= PERF_RECORD_MISC_KERNEL; |
diff --git a/arch/x86/kernel/cpu/perf_event.h b/arch/x86/kernel/cpu/perf_event.h index 821d53b696d1..6605a81ba339 100644 --- a/arch/x86/kernel/cpu/perf_event.h +++ b/arch/x86/kernel/cpu/perf_event.h | |||
@@ -516,6 +516,26 @@ static inline bool kernel_ip(unsigned long ip) | |||
516 | #endif | 516 | #endif |
517 | } | 517 | } |
518 | 518 | ||
519 | /* | ||
520 | * Not all PMUs provide the right context information to place the reported IP | ||
521 | * into full context. Specifically segment registers are typically not | ||
522 | * supplied. | ||
523 | * | ||
524 | * Assuming the address is a linear address (it is for IBS), we fake the CS and | ||
525 | * vm86 mode using the known zero-based code segment and 'fix up' the registers | ||
526 | * to reflect this. | ||
527 | * | ||
528 | * Intel PEBS/LBR appear to typically provide the effective address, nothing | ||
529 | * much we can do about that but pray and treat it like a linear address. | ||
530 | */ | ||
531 | static inline void set_linear_ip(struct pt_regs *regs, unsigned long ip) | ||
532 | { | ||
533 | regs->cs = kernel_ip(ip) ? __KERNEL_CS : __USER_CS; | ||
534 | if (regs->flags & X86_VM_MASK) | ||
535 | regs->flags ^= (PERF_EFLAGS_VM | X86_VM_MASK); | ||
536 | regs->ip = ip; | ||
537 | } | ||
538 | |||
519 | #ifdef CONFIG_CPU_SUP_AMD | 539 | #ifdef CONFIG_CPU_SUP_AMD |
520 | 540 | ||
521 | int amd_pmu_init(void); | 541 | int amd_pmu_init(void); |
diff --git a/arch/x86/kernel/cpu/perf_event_amd_ibs.c b/arch/x86/kernel/cpu/perf_event_amd_ibs.c index da9bcdcd9856..7bfb5bec8630 100644 --- a/arch/x86/kernel/cpu/perf_event_amd_ibs.c +++ b/arch/x86/kernel/cpu/perf_event_amd_ibs.c | |||
@@ -13,6 +13,8 @@ | |||
13 | 13 | ||
14 | #include <asm/apic.h> | 14 | #include <asm/apic.h> |
15 | 15 | ||
16 | #include "perf_event.h" | ||
17 | |||
16 | static u32 ibs_caps; | 18 | static u32 ibs_caps; |
17 | 19 | ||
18 | #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) | 20 | #if defined(CONFIG_PERF_EVENTS) && defined(CONFIG_CPU_SUP_AMD) |
@@ -536,7 +538,7 @@ static int perf_ibs_handle_irq(struct perf_ibs *perf_ibs, struct pt_regs *iregs) | |||
536 | if (check_rip && (ibs_data.regs[2] & IBS_RIP_INVALID)) { | 538 | if (check_rip && (ibs_data.regs[2] & IBS_RIP_INVALID)) { |
537 | regs.flags &= ~PERF_EFLAGS_EXACT; | 539 | regs.flags &= ~PERF_EFLAGS_EXACT; |
538 | } else { | 540 | } else { |
539 | instruction_pointer_set(®s, ibs_data.regs[1]); | 541 | set_linear_ip(®s, ibs_data.regs[1]); |
540 | regs.flags |= PERF_EFLAGS_EXACT; | 542 | regs.flags |= PERF_EFLAGS_EXACT; |
541 | } | 543 | } |
542 | 544 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_intel.c b/arch/x86/kernel/cpu/perf_event_intel.c index 382366977d4c..7f2739e03e79 100644 --- a/arch/x86/kernel/cpu/perf_event_intel.c +++ b/arch/x86/kernel/cpu/perf_event_intel.c | |||
@@ -1522,8 +1522,16 @@ static struct perf_guest_switch_msr *intel_guest_get_msrs(int *nr) | |||
1522 | arr[0].msr = MSR_CORE_PERF_GLOBAL_CTRL; | 1522 | arr[0].msr = MSR_CORE_PERF_GLOBAL_CTRL; |
1523 | arr[0].host = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask; | 1523 | arr[0].host = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_guest_mask; |
1524 | arr[0].guest = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_host_mask; | 1524 | arr[0].guest = x86_pmu.intel_ctrl & ~cpuc->intel_ctrl_host_mask; |
1525 | /* | ||
1526 | * If PMU counter has PEBS enabled it is not enough to disable counter | ||
1527 | * on a guest entry since PEBS memory write can overshoot guest entry | ||
1528 | * and corrupt guest memory. Disabling PEBS solves the problem. | ||
1529 | */ | ||
1530 | arr[1].msr = MSR_IA32_PEBS_ENABLE; | ||
1531 | arr[1].host = cpuc->pebs_enabled; | ||
1532 | arr[1].guest = 0; | ||
1525 | 1533 | ||
1526 | *nr = 1; | 1534 | *nr = 2; |
1527 | return arr; | 1535 | return arr; |
1528 | } | 1536 | } |
1529 | 1537 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_intel_ds.c b/arch/x86/kernel/cpu/perf_event_intel_ds.c index 629ae0b7ad90..e38d97bf4259 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_ds.c +++ b/arch/x86/kernel/cpu/perf_event_intel_ds.c | |||
@@ -499,7 +499,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) | |||
499 | * We sampled a branch insn, rewind using the LBR stack | 499 | * We sampled a branch insn, rewind using the LBR stack |
500 | */ | 500 | */ |
501 | if (ip == to) { | 501 | if (ip == to) { |
502 | regs->ip = from; | 502 | set_linear_ip(regs, from); |
503 | return 1; | 503 | return 1; |
504 | } | 504 | } |
505 | 505 | ||
@@ -529,7 +529,7 @@ static int intel_pmu_pebs_fixup_ip(struct pt_regs *regs) | |||
529 | } while (to < ip); | 529 | } while (to < ip); |
530 | 530 | ||
531 | if (to == ip) { | 531 | if (to == ip) { |
532 | regs->ip = old_to; | 532 | set_linear_ip(regs, old_to); |
533 | return 1; | 533 | return 1; |
534 | } | 534 | } |
535 | 535 | ||
@@ -569,7 +569,8 @@ static void __intel_pmu_pebs_event(struct perf_event *event, | |||
569 | * A possible PERF_SAMPLE_REGS will have to transfer all regs. | 569 | * A possible PERF_SAMPLE_REGS will have to transfer all regs. |
570 | */ | 570 | */ |
571 | regs = *iregs; | 571 | regs = *iregs; |
572 | regs.ip = pebs->ip; | 572 | regs.flags = pebs->flags; |
573 | set_linear_ip(®s, pebs->ip); | ||
573 | regs.bp = pebs->bp; | 574 | regs.bp = pebs->bp; |
574 | regs.sp = pebs->sp; | 575 | regs.sp = pebs->sp; |
575 | 576 | ||
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.c b/arch/x86/kernel/cpu/perf_event_intel_uncore.c index 7563fda9f033..0a5571080e74 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.c +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.c | |||
@@ -796,7 +796,6 @@ static struct intel_uncore_type *nhm_msr_uncores[] = { | |||
796 | 796 | ||
797 | DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5"); | 797 | DEFINE_UNCORE_FORMAT_ATTR(event5, event, "config:1-5"); |
798 | DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7"); | 798 | DEFINE_UNCORE_FORMAT_ATTR(counter, counter, "config:6-7"); |
799 | DEFINE_UNCORE_FORMAT_ATTR(mm_cfg, mm_cfg, "config:63"); | ||
800 | DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63"); | 799 | DEFINE_UNCORE_FORMAT_ATTR(match, match, "config1:0-63"); |
801 | DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63"); | 800 | DEFINE_UNCORE_FORMAT_ATTR(mask, mask, "config2:0-63"); |
802 | 801 | ||
@@ -902,16 +901,21 @@ static struct attribute_group nhmex_uncore_cbox_format_group = { | |||
902 | .attrs = nhmex_uncore_cbox_formats_attr, | 901 | .attrs = nhmex_uncore_cbox_formats_attr, |
903 | }; | 902 | }; |
904 | 903 | ||
904 | /* msr offset for each instance of cbox */ | ||
905 | static unsigned nhmex_cbox_msr_offsets[] = { | ||
906 | 0x0, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x240, 0x2c0, | ||
907 | }; | ||
908 | |||
905 | static struct intel_uncore_type nhmex_uncore_cbox = { | 909 | static struct intel_uncore_type nhmex_uncore_cbox = { |
906 | .name = "cbox", | 910 | .name = "cbox", |
907 | .num_counters = 6, | 911 | .num_counters = 6, |
908 | .num_boxes = 8, | 912 | .num_boxes = 10, |
909 | .perf_ctr_bits = 48, | 913 | .perf_ctr_bits = 48, |
910 | .event_ctl = NHMEX_C0_MSR_PMON_EV_SEL0, | 914 | .event_ctl = NHMEX_C0_MSR_PMON_EV_SEL0, |
911 | .perf_ctr = NHMEX_C0_MSR_PMON_CTR0, | 915 | .perf_ctr = NHMEX_C0_MSR_PMON_CTR0, |
912 | .event_mask = NHMEX_PMON_RAW_EVENT_MASK, | 916 | .event_mask = NHMEX_PMON_RAW_EVENT_MASK, |
913 | .box_ctl = NHMEX_C0_MSR_PMON_GLOBAL_CTL, | 917 | .box_ctl = NHMEX_C0_MSR_PMON_GLOBAL_CTL, |
914 | .msr_offset = NHMEX_C_MSR_OFFSET, | 918 | .msr_offsets = nhmex_cbox_msr_offsets, |
915 | .pair_ctr_ctl = 1, | 919 | .pair_ctr_ctl = 1, |
916 | .ops = &nhmex_uncore_ops, | 920 | .ops = &nhmex_uncore_ops, |
917 | .format_group = &nhmex_uncore_cbox_format_group | 921 | .format_group = &nhmex_uncore_cbox_format_group |
@@ -1032,24 +1036,22 @@ static struct intel_uncore_type nhmex_uncore_bbox = { | |||
1032 | 1036 | ||
1033 | static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) | 1037 | static int nhmex_sbox_hw_config(struct intel_uncore_box *box, struct perf_event *event) |
1034 | { | 1038 | { |
1035 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | 1039 | struct hw_perf_event *hwc = &event->hw; |
1036 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | 1040 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
1041 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | ||
1037 | 1042 | ||
1038 | if (event->attr.config & NHMEX_S_PMON_MM_CFG_EN) { | 1043 | /* only TO_R_PROG_EV event uses the match/mask register */ |
1039 | reg1->config = event->attr.config1; | 1044 | if ((hwc->config & NHMEX_PMON_CTL_EV_SEL_MASK) != |
1040 | reg2->config = event->attr.config2; | 1045 | NHMEX_S_EVENT_TO_R_PROG_EV) |
1041 | } else { | 1046 | return 0; |
1042 | reg1->config = ~0ULL; | ||
1043 | reg2->config = ~0ULL; | ||
1044 | } | ||
1045 | 1047 | ||
1046 | if (box->pmu->pmu_idx == 0) | 1048 | if (box->pmu->pmu_idx == 0) |
1047 | reg1->reg = NHMEX_S0_MSR_MM_CFG; | 1049 | reg1->reg = NHMEX_S0_MSR_MM_CFG; |
1048 | else | 1050 | else |
1049 | reg1->reg = NHMEX_S1_MSR_MM_CFG; | 1051 | reg1->reg = NHMEX_S1_MSR_MM_CFG; |
1050 | |||
1051 | reg1->idx = 0; | 1052 | reg1->idx = 0; |
1052 | 1053 | reg1->config = event->attr.config1; | |
1054 | reg2->config = event->attr.config2; | ||
1053 | return 0; | 1055 | return 0; |
1054 | } | 1056 | } |
1055 | 1057 | ||
@@ -1059,8 +1061,8 @@ static void nhmex_sbox_msr_enable_event(struct intel_uncore_box *box, struct per | |||
1059 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | 1061 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
1060 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | 1062 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; |
1061 | 1063 | ||
1062 | wrmsrl(reg1->reg, 0); | 1064 | if (reg1->idx != EXTRA_REG_NONE) { |
1063 | if (reg1->config != ~0ULL || reg2->config != ~0ULL) { | 1065 | wrmsrl(reg1->reg, 0); |
1064 | wrmsrl(reg1->reg + 1, reg1->config); | 1066 | wrmsrl(reg1->reg + 1, reg1->config); |
1065 | wrmsrl(reg1->reg + 2, reg2->config); | 1067 | wrmsrl(reg1->reg + 2, reg2->config); |
1066 | wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN); | 1068 | wrmsrl(reg1->reg, NHMEX_S_PMON_MM_CFG_EN); |
@@ -1074,7 +1076,6 @@ static struct attribute *nhmex_uncore_sbox_formats_attr[] = { | |||
1074 | &format_attr_edge.attr, | 1076 | &format_attr_edge.attr, |
1075 | &format_attr_inv.attr, | 1077 | &format_attr_inv.attr, |
1076 | &format_attr_thresh8.attr, | 1078 | &format_attr_thresh8.attr, |
1077 | &format_attr_mm_cfg.attr, | ||
1078 | &format_attr_match.attr, | 1079 | &format_attr_match.attr, |
1079 | &format_attr_mask.attr, | 1080 | &format_attr_mask.attr, |
1080 | NULL, | 1081 | NULL, |
@@ -1142,6 +1143,9 @@ static struct extra_reg nhmex_uncore_mbox_extra_regs[] = { | |||
1142 | EVENT_EXTRA_END | 1143 | EVENT_EXTRA_END |
1143 | }; | 1144 | }; |
1144 | 1145 | ||
1146 | /* Nehalem-EX or Westmere-EX ? */ | ||
1147 | bool uncore_nhmex; | ||
1148 | |||
1145 | static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config) | 1149 | static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 config) |
1146 | { | 1150 | { |
1147 | struct intel_uncore_extra_reg *er; | 1151 | struct intel_uncore_extra_reg *er; |
@@ -1171,18 +1175,29 @@ static bool nhmex_mbox_get_shared_reg(struct intel_uncore_box *box, int idx, u64 | |||
1171 | return false; | 1175 | return false; |
1172 | 1176 | ||
1173 | /* mask of the shared fields */ | 1177 | /* mask of the shared fields */ |
1174 | mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK; | 1178 | if (uncore_nhmex) |
1179 | mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK; | ||
1180 | else | ||
1181 | mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK; | ||
1175 | er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; | 1182 | er = &box->shared_regs[EXTRA_REG_NHMEX_M_ZDP_CTL_FVC]; |
1176 | 1183 | ||
1177 | raw_spin_lock_irqsave(&er->lock, flags); | 1184 | raw_spin_lock_irqsave(&er->lock, flags); |
1178 | /* add mask of the non-shared field if it's in use */ | 1185 | /* add mask of the non-shared field if it's in use */ |
1179 | if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) | 1186 | if (__BITS_VALUE(atomic_read(&er->ref), idx, 8)) { |
1180 | mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | 1187 | if (uncore_nhmex) |
1188 | mask |= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
1189 | else | ||
1190 | mask |= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
1191 | } | ||
1181 | 1192 | ||
1182 | if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) { | 1193 | if (!atomic_read(&er->ref) || !((er->config ^ config) & mask)) { |
1183 | atomic_add(1 << (idx * 8), &er->ref); | 1194 | atomic_add(1 << (idx * 8), &er->ref); |
1184 | mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK | | 1195 | if (uncore_nhmex) |
1185 | NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | 1196 | mask = NHMEX_M_PMON_ZDP_CTL_FVC_MASK | |
1197 | NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
1198 | else | ||
1199 | mask = WSMEX_M_PMON_ZDP_CTL_FVC_MASK | | ||
1200 | WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
1186 | er->config &= ~mask; | 1201 | er->config &= ~mask; |
1187 | er->config |= (config & mask); | 1202 | er->config |= (config & mask); |
1188 | ret = true; | 1203 | ret = true; |
@@ -1216,7 +1231,10 @@ u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify) | |||
1216 | 1231 | ||
1217 | /* get the non-shared control bits and shift them */ | 1232 | /* get the non-shared control bits and shift them */ |
1218 | idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; | 1233 | idx = orig_idx - EXTRA_REG_NHMEX_M_ZDP_CTL_FVC; |
1219 | config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | 1234 | if (uncore_nhmex) |
1235 | config &= NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
1236 | else | ||
1237 | config &= WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(idx); | ||
1220 | if (new_idx > orig_idx) { | 1238 | if (new_idx > orig_idx) { |
1221 | idx = new_idx - orig_idx; | 1239 | idx = new_idx - orig_idx; |
1222 | config <<= 3 * idx; | 1240 | config <<= 3 * idx; |
@@ -1226,6 +1244,10 @@ u64 nhmex_mbox_alter_er(struct perf_event *event, int new_idx, bool modify) | |||
1226 | } | 1244 | } |
1227 | 1245 | ||
1228 | /* add the shared control bits back */ | 1246 | /* add the shared control bits back */ |
1247 | if (uncore_nhmex) | ||
1248 | config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; | ||
1249 | else | ||
1250 | config |= WSMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; | ||
1229 | config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; | 1251 | config |= NHMEX_M_PMON_ZDP_CTL_FVC_MASK & reg1->config; |
1230 | if (modify) { | 1252 | if (modify) { |
1231 | /* adjust the main event selector */ | 1253 | /* adjust the main event selector */ |
@@ -1264,7 +1286,8 @@ again: | |||
1264 | } | 1286 | } |
1265 | 1287 | ||
1266 | /* for the match/mask registers */ | 1288 | /* for the match/mask registers */ |
1267 | if ((uncore_box_is_fake(box) || !reg2->alloc) && | 1289 | if (reg2->idx != EXTRA_REG_NONE && |
1290 | (uncore_box_is_fake(box) || !reg2->alloc) && | ||
1268 | !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config)) | 1291 | !nhmex_mbox_get_shared_reg(box, reg2->idx, reg2->config)) |
1269 | goto fail; | 1292 | goto fail; |
1270 | 1293 | ||
@@ -1278,7 +1301,8 @@ again: | |||
1278 | if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) | 1301 | if (idx[0] != 0xff && idx[0] != __BITS_VALUE(reg1->idx, 0, 8)) |
1279 | nhmex_mbox_alter_er(event, idx[0], true); | 1302 | nhmex_mbox_alter_er(event, idx[0], true); |
1280 | reg1->alloc |= alloc; | 1303 | reg1->alloc |= alloc; |
1281 | reg2->alloc = 1; | 1304 | if (reg2->idx != EXTRA_REG_NONE) |
1305 | reg2->alloc = 1; | ||
1282 | } | 1306 | } |
1283 | return NULL; | 1307 | return NULL; |
1284 | fail: | 1308 | fail: |
@@ -1342,9 +1366,6 @@ static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event | |||
1342 | struct extra_reg *er; | 1366 | struct extra_reg *er; |
1343 | unsigned msr; | 1367 | unsigned msr; |
1344 | int reg_idx = 0; | 1368 | int reg_idx = 0; |
1345 | |||
1346 | if (WARN_ON_ONCE(reg1->idx != -1)) | ||
1347 | return -EINVAL; | ||
1348 | /* | 1369 | /* |
1349 | * The mbox events may require 2 extra MSRs at the most. But only | 1370 | * The mbox events may require 2 extra MSRs at the most. But only |
1350 | * the lower 32 bits in these MSRs are significant, so we can use | 1371 | * the lower 32 bits in these MSRs are significant, so we can use |
@@ -1355,11 +1376,6 @@ static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event | |||
1355 | continue; | 1376 | continue; |
1356 | if (event->attr.config1 & ~er->valid_mask) | 1377 | if (event->attr.config1 & ~er->valid_mask) |
1357 | return -EINVAL; | 1378 | return -EINVAL; |
1358 | if (er->idx == __BITS_VALUE(reg1->idx, 0, 8) || | ||
1359 | er->idx == __BITS_VALUE(reg1->idx, 1, 8)) | ||
1360 | continue; | ||
1361 | if (WARN_ON_ONCE(reg_idx >= 2)) | ||
1362 | return -EINVAL; | ||
1363 | 1379 | ||
1364 | msr = er->msr + type->msr_offset * box->pmu->pmu_idx; | 1380 | msr = er->msr + type->msr_offset * box->pmu->pmu_idx; |
1365 | if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff)) | 1381 | if (WARN_ON_ONCE(msr >= 0xffff || er->idx >= 0xff)) |
@@ -1368,6 +1384,8 @@ static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event | |||
1368 | /* always use the 32~63 bits to pass the PLD config */ | 1384 | /* always use the 32~63 bits to pass the PLD config */ |
1369 | if (er->idx == EXTRA_REG_NHMEX_M_PLD) | 1385 | if (er->idx == EXTRA_REG_NHMEX_M_PLD) |
1370 | reg_idx = 1; | 1386 | reg_idx = 1; |
1387 | else if (WARN_ON_ONCE(reg_idx > 0)) | ||
1388 | return -EINVAL; | ||
1371 | 1389 | ||
1372 | reg1->idx &= ~(0xff << (reg_idx * 8)); | 1390 | reg1->idx &= ~(0xff << (reg_idx * 8)); |
1373 | reg1->reg &= ~(0xffff << (reg_idx * 16)); | 1391 | reg1->reg &= ~(0xffff << (reg_idx * 16)); |
@@ -1376,17 +1394,21 @@ static int nhmex_mbox_hw_config(struct intel_uncore_box *box, struct perf_event | |||
1376 | reg1->config = event->attr.config1; | 1394 | reg1->config = event->attr.config1; |
1377 | reg_idx++; | 1395 | reg_idx++; |
1378 | } | 1396 | } |
1379 | /* use config2 to pass the filter config */ | 1397 | /* |
1380 | reg2->idx = EXTRA_REG_NHMEX_M_FILTER; | 1398 | * The mbox only provides ability to perform address matching |
1381 | if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN) | 1399 | * for the PLD events. |
1382 | reg2->config = event->attr.config2; | 1400 | */ |
1383 | else | 1401 | if (reg_idx == 2) { |
1384 | reg2->config = ~0ULL; | 1402 | reg2->idx = EXTRA_REG_NHMEX_M_FILTER; |
1385 | if (box->pmu->pmu_idx == 0) | 1403 | if (event->attr.config2 & NHMEX_M_PMON_MM_CFG_EN) |
1386 | reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG; | 1404 | reg2->config = event->attr.config2; |
1387 | else | 1405 | else |
1388 | reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG; | 1406 | reg2->config = ~0ULL; |
1389 | 1407 | if (box->pmu->pmu_idx == 0) | |
1408 | reg2->reg = NHMEX_M0_MSR_PMU_MM_CFG; | ||
1409 | else | ||
1410 | reg2->reg = NHMEX_M1_MSR_PMU_MM_CFG; | ||
1411 | } | ||
1390 | return 0; | 1412 | return 0; |
1391 | } | 1413 | } |
1392 | 1414 | ||
@@ -1422,34 +1444,36 @@ static void nhmex_mbox_msr_enable_event(struct intel_uncore_box *box, struct per | |||
1422 | wrmsrl(__BITS_VALUE(reg1->reg, 1, 16), | 1444 | wrmsrl(__BITS_VALUE(reg1->reg, 1, 16), |
1423 | nhmex_mbox_shared_reg_config(box, idx)); | 1445 | nhmex_mbox_shared_reg_config(box, idx)); |
1424 | 1446 | ||
1425 | wrmsrl(reg2->reg, 0); | 1447 | if (reg2->idx != EXTRA_REG_NONE) { |
1426 | if (reg2->config != ~0ULL) { | 1448 | wrmsrl(reg2->reg, 0); |
1427 | wrmsrl(reg2->reg + 1, | 1449 | if (reg2->config != ~0ULL) { |
1428 | reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK); | 1450 | wrmsrl(reg2->reg + 1, |
1429 | wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK & | 1451 | reg2->config & NHMEX_M_PMON_ADDR_MATCH_MASK); |
1430 | (reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT)); | 1452 | wrmsrl(reg2->reg + 2, NHMEX_M_PMON_ADDR_MASK_MASK & |
1431 | wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN); | 1453 | (reg2->config >> NHMEX_M_PMON_ADDR_MASK_SHIFT)); |
1454 | wrmsrl(reg2->reg, NHMEX_M_PMON_MM_CFG_EN); | ||
1455 | } | ||
1432 | } | 1456 | } |
1433 | 1457 | ||
1434 | wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0); | 1458 | wrmsrl(hwc->config_base, hwc->config | NHMEX_PMON_CTL_EN_BIT0); |
1435 | } | 1459 | } |
1436 | 1460 | ||
1437 | DEFINE_UNCORE_FORMAT_ATTR(count_mode, count_mode, "config:2-3"); | 1461 | DEFINE_UNCORE_FORMAT_ATTR(count_mode, count_mode, "config:2-3"); |
1438 | DEFINE_UNCORE_FORMAT_ATTR(storage_mode, storage_mode, "config:4-5"); | 1462 | DEFINE_UNCORE_FORMAT_ATTR(storage_mode, storage_mode, "config:4-5"); |
1439 | DEFINE_UNCORE_FORMAT_ATTR(wrap_mode, wrap_mode, "config:6"); | 1463 | DEFINE_UNCORE_FORMAT_ATTR(wrap_mode, wrap_mode, "config:6"); |
1440 | DEFINE_UNCORE_FORMAT_ATTR(flag_mode, flag_mode, "config:7"); | 1464 | DEFINE_UNCORE_FORMAT_ATTR(flag_mode, flag_mode, "config:7"); |
1441 | DEFINE_UNCORE_FORMAT_ATTR(inc_sel, inc_sel, "config:9-13"); | 1465 | DEFINE_UNCORE_FORMAT_ATTR(inc_sel, inc_sel, "config:9-13"); |
1442 | DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel, set_flag_sel, "config:19-21"); | 1466 | DEFINE_UNCORE_FORMAT_ATTR(set_flag_sel, set_flag_sel, "config:19-21"); |
1443 | DEFINE_UNCORE_FORMAT_ATTR(filter_cfg, filter_cfg, "config2:63"); | 1467 | DEFINE_UNCORE_FORMAT_ATTR(filter_cfg_en, filter_cfg_en, "config2:63"); |
1444 | DEFINE_UNCORE_FORMAT_ATTR(filter_match, filter_match, "config2:0-33"); | 1468 | DEFINE_UNCORE_FORMAT_ATTR(filter_match, filter_match, "config2:0-33"); |
1445 | DEFINE_UNCORE_FORMAT_ATTR(filter_mask, filter_mask, "config2:34-61"); | 1469 | DEFINE_UNCORE_FORMAT_ATTR(filter_mask, filter_mask, "config2:34-61"); |
1446 | DEFINE_UNCORE_FORMAT_ATTR(dsp, dsp, "config1:0-31"); | 1470 | DEFINE_UNCORE_FORMAT_ATTR(dsp, dsp, "config1:0-31"); |
1447 | DEFINE_UNCORE_FORMAT_ATTR(thr, thr, "config1:0-31"); | 1471 | DEFINE_UNCORE_FORMAT_ATTR(thr, thr, "config1:0-31"); |
1448 | DEFINE_UNCORE_FORMAT_ATTR(fvc, fvc, "config1:0-31"); | 1472 | DEFINE_UNCORE_FORMAT_ATTR(fvc, fvc, "config1:0-31"); |
1449 | DEFINE_UNCORE_FORMAT_ATTR(pgt, pgt, "config1:0-31"); | 1473 | DEFINE_UNCORE_FORMAT_ATTR(pgt, pgt, "config1:0-31"); |
1450 | DEFINE_UNCORE_FORMAT_ATTR(map, map, "config1:0-31"); | 1474 | DEFINE_UNCORE_FORMAT_ATTR(map, map, "config1:0-31"); |
1451 | DEFINE_UNCORE_FORMAT_ATTR(iss, iss, "config1:0-31"); | 1475 | DEFINE_UNCORE_FORMAT_ATTR(iss, iss, "config1:0-31"); |
1452 | DEFINE_UNCORE_FORMAT_ATTR(pld, pld, "config1:32-63"); | 1476 | DEFINE_UNCORE_FORMAT_ATTR(pld, pld, "config1:32-63"); |
1453 | 1477 | ||
1454 | static struct attribute *nhmex_uncore_mbox_formats_attr[] = { | 1478 | static struct attribute *nhmex_uncore_mbox_formats_attr[] = { |
1455 | &format_attr_count_mode.attr, | 1479 | &format_attr_count_mode.attr, |
@@ -1458,7 +1482,7 @@ static struct attribute *nhmex_uncore_mbox_formats_attr[] = { | |||
1458 | &format_attr_flag_mode.attr, | 1482 | &format_attr_flag_mode.attr, |
1459 | &format_attr_inc_sel.attr, | 1483 | &format_attr_inc_sel.attr, |
1460 | &format_attr_set_flag_sel.attr, | 1484 | &format_attr_set_flag_sel.attr, |
1461 | &format_attr_filter_cfg.attr, | 1485 | &format_attr_filter_cfg_en.attr, |
1462 | &format_attr_filter_match.attr, | 1486 | &format_attr_filter_match.attr, |
1463 | &format_attr_filter_mask.attr, | 1487 | &format_attr_filter_mask.attr, |
1464 | &format_attr_dsp.attr, | 1488 | &format_attr_dsp.attr, |
@@ -1482,6 +1506,12 @@ static struct uncore_event_desc nhmex_uncore_mbox_events[] = { | |||
1482 | { /* end: all zeroes */ }, | 1506 | { /* end: all zeroes */ }, |
1483 | }; | 1507 | }; |
1484 | 1508 | ||
1509 | static struct uncore_event_desc wsmex_uncore_mbox_events[] = { | ||
1510 | INTEL_UNCORE_EVENT_DESC(bbox_cmds_read, "inc_sel=0xd,fvc=0x5000"), | ||
1511 | INTEL_UNCORE_EVENT_DESC(bbox_cmds_write, "inc_sel=0xd,fvc=0x5040"), | ||
1512 | { /* end: all zeroes */ }, | ||
1513 | }; | ||
1514 | |||
1485 | static struct intel_uncore_ops nhmex_uncore_mbox_ops = { | 1515 | static struct intel_uncore_ops nhmex_uncore_mbox_ops = { |
1486 | NHMEX_UNCORE_OPS_COMMON_INIT(), | 1516 | NHMEX_UNCORE_OPS_COMMON_INIT(), |
1487 | .enable_event = nhmex_mbox_msr_enable_event, | 1517 | .enable_event = nhmex_mbox_msr_enable_event, |
@@ -1513,7 +1543,7 @@ void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) | |||
1513 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | 1543 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
1514 | int port; | 1544 | int port; |
1515 | 1545 | ||
1516 | /* adjust the main event selector */ | 1546 | /* adjust the main event selector and extra register index */ |
1517 | if (reg1->idx % 2) { | 1547 | if (reg1->idx % 2) { |
1518 | reg1->idx--; | 1548 | reg1->idx--; |
1519 | hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; | 1549 | hwc->config -= 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; |
@@ -1522,29 +1552,17 @@ void nhmex_rbox_alter_er(struct intel_uncore_box *box, struct perf_event *event) | |||
1522 | hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; | 1552 | hwc->config += 1 << NHMEX_R_PMON_CTL_EV_SEL_SHIFT; |
1523 | } | 1553 | } |
1524 | 1554 | ||
1525 | /* adjust address or config of extra register */ | 1555 | /* adjust extra register config */ |
1526 | port = reg1->idx / 6 + box->pmu->pmu_idx * 4; | 1556 | port = reg1->idx / 6 + box->pmu->pmu_idx * 4; |
1527 | switch (reg1->idx % 6) { | 1557 | switch (reg1->idx % 6) { |
1528 | case 0: | ||
1529 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG0(port); | ||
1530 | break; | ||
1531 | case 1: | ||
1532 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG1(port); | ||
1533 | break; | ||
1534 | case 2: | 1558 | case 2: |
1535 | /* the 8~15 bits to the 0~7 bits */ | 1559 | /* shift the 8~15 bits to the 0~7 bits */ |
1536 | reg1->config >>= 8; | 1560 | reg1->config >>= 8; |
1537 | break; | 1561 | break; |
1538 | case 3: | 1562 | case 3: |
1539 | /* the 0~7 bits to the 8~15 bits */ | 1563 | /* shift the 0~7 bits to the 8~15 bits */ |
1540 | reg1->config <<= 8; | 1564 | reg1->config <<= 8; |
1541 | break; | 1565 | break; |
1542 | case 4: | ||
1543 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port); | ||
1544 | break; | ||
1545 | case 5: | ||
1546 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port); | ||
1547 | break; | ||
1548 | }; | 1566 | }; |
1549 | } | 1567 | } |
1550 | 1568 | ||
@@ -1671,7 +1689,7 @@ static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event | |||
1671 | struct hw_perf_event *hwc = &event->hw; | 1689 | struct hw_perf_event *hwc = &event->hw; |
1672 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; | 1690 | struct hw_perf_event_extra *reg1 = &event->hw.extra_reg; |
1673 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; | 1691 | struct hw_perf_event_extra *reg2 = &event->hw.branch_reg; |
1674 | int port, idx; | 1692 | int idx; |
1675 | 1693 | ||
1676 | idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >> | 1694 | idx = (event->hw.config & NHMEX_R_PMON_CTL_EV_SEL_MASK) >> |
1677 | NHMEX_R_PMON_CTL_EV_SEL_SHIFT; | 1695 | NHMEX_R_PMON_CTL_EV_SEL_SHIFT; |
@@ -1681,27 +1699,11 @@ static int nhmex_rbox_hw_config(struct intel_uncore_box *box, struct perf_event | |||
1681 | reg1->idx = idx; | 1699 | reg1->idx = idx; |
1682 | reg1->config = event->attr.config1; | 1700 | reg1->config = event->attr.config1; |
1683 | 1701 | ||
1684 | port = idx / 6 + box->pmu->pmu_idx * 4; | 1702 | switch (idx % 6) { |
1685 | idx %= 6; | ||
1686 | switch (idx) { | ||
1687 | case 0: | ||
1688 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG0(port); | ||
1689 | break; | ||
1690 | case 1: | ||
1691 | reg1->reg = NHMEX_R_MSR_PORTN_IPERF_CFG1(port); | ||
1692 | break; | ||
1693 | case 2: | ||
1694 | case 3: | ||
1695 | reg1->reg = NHMEX_R_MSR_PORTN_QLX_CFG(port); | ||
1696 | break; | ||
1697 | case 4: | 1703 | case 4: |
1698 | case 5: | 1704 | case 5: |
1699 | if (idx == 4) | ||
1700 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port); | ||
1701 | else | ||
1702 | reg1->reg = NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port); | ||
1703 | reg2->config = event->attr.config2; | ||
1704 | hwc->config |= event->attr.config & (~0ULL << 32); | 1705 | hwc->config |= event->attr.config & (~0ULL << 32); |
1706 | reg2->config = event->attr.config2; | ||
1705 | break; | 1707 | break; |
1706 | }; | 1708 | }; |
1707 | return 0; | 1709 | return 0; |
@@ -1727,28 +1729,34 @@ static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct per | |||
1727 | struct hw_perf_event *hwc = &event->hw; | 1729 | struct hw_perf_event *hwc = &event->hw; |
1728 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; | 1730 | struct hw_perf_event_extra *reg1 = &hwc->extra_reg; |
1729 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; | 1731 | struct hw_perf_event_extra *reg2 = &hwc->branch_reg; |
1730 | int idx, er_idx; | 1732 | int idx, port; |
1731 | 1733 | ||
1732 | idx = reg1->idx % 6; | 1734 | idx = reg1->idx; |
1733 | er_idx = idx; | 1735 | port = idx / 6 + box->pmu->pmu_idx * 4; |
1734 | if (er_idx > 2) | ||
1735 | er_idx--; | ||
1736 | er_idx += (reg1->idx / 6) * 5; | ||
1737 | 1736 | ||
1738 | switch (idx) { | 1737 | switch (idx % 6) { |
1739 | case 0: | 1738 | case 0: |
1739 | wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG0(port), reg1->config); | ||
1740 | break; | ||
1740 | case 1: | 1741 | case 1: |
1741 | wrmsrl(reg1->reg, reg1->config); | 1742 | wrmsrl(NHMEX_R_MSR_PORTN_IPERF_CFG1(port), reg1->config); |
1742 | break; | 1743 | break; |
1743 | case 2: | 1744 | case 2: |
1744 | case 3: | 1745 | case 3: |
1745 | wrmsrl(reg1->reg, nhmex_rbox_shared_reg_config(box, er_idx)); | 1746 | wrmsrl(NHMEX_R_MSR_PORTN_QLX_CFG(port), |
1747 | nhmex_rbox_shared_reg_config(box, 2 + (idx / 6) * 5)); | ||
1746 | break; | 1748 | break; |
1747 | case 4: | 1749 | case 4: |
1750 | wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MM_CFG(port), | ||
1751 | hwc->config >> 32); | ||
1752 | wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MATCH(port), reg1->config); | ||
1753 | wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET1_MASK(port), reg2->config); | ||
1754 | break; | ||
1748 | case 5: | 1755 | case 5: |
1749 | wrmsrl(reg1->reg, reg1->config); | 1756 | wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MM_CFG(port), |
1750 | wrmsrl(reg1->reg + 1, hwc->config >> 32); | 1757 | hwc->config >> 32); |
1751 | wrmsrl(reg1->reg + 2, reg2->config); | 1758 | wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MATCH(port), reg1->config); |
1759 | wrmsrl(NHMEX_R_MSR_PORTN_XBR_SET2_MASK(port), reg2->config); | ||
1752 | break; | 1760 | break; |
1753 | }; | 1761 | }; |
1754 | 1762 | ||
@@ -1756,8 +1764,8 @@ static void nhmex_rbox_msr_enable_event(struct intel_uncore_box *box, struct per | |||
1756 | (hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK)); | 1764 | (hwc->config & NHMEX_R_PMON_CTL_EV_SEL_MASK)); |
1757 | } | 1765 | } |
1758 | 1766 | ||
1759 | DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config:32-63"); | 1767 | DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config:32-63"); |
1760 | DEFINE_UNCORE_FORMAT_ATTR(xbr_mm_cfg, xbr_mm_cfg, "config1:0-63"); | 1768 | DEFINE_UNCORE_FORMAT_ATTR(xbr_match, xbr_match, "config1:0-63"); |
1761 | DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63"); | 1769 | DEFINE_UNCORE_FORMAT_ATTR(xbr_mask, xbr_mask, "config2:0-63"); |
1762 | DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15"); | 1770 | DEFINE_UNCORE_FORMAT_ATTR(qlx_cfg, qlx_cfg, "config1:0-15"); |
1763 | DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31"); | 1771 | DEFINE_UNCORE_FORMAT_ATTR(iperf_cfg, iperf_cfg, "config1:0-31"); |
@@ -2303,6 +2311,7 @@ int uncore_pmu_event_init(struct perf_event *event) | |||
2303 | event->hw.idx = -1; | 2311 | event->hw.idx = -1; |
2304 | event->hw.last_tag = ~0ULL; | 2312 | event->hw.last_tag = ~0ULL; |
2305 | event->hw.extra_reg.idx = EXTRA_REG_NONE; | 2313 | event->hw.extra_reg.idx = EXTRA_REG_NONE; |
2314 | event->hw.branch_reg.idx = EXTRA_REG_NONE; | ||
2306 | 2315 | ||
2307 | if (event->attr.config == UNCORE_FIXED_EVENT) { | 2316 | if (event->attr.config == UNCORE_FIXED_EVENT) { |
2308 | /* no fixed counter */ | 2317 | /* no fixed counter */ |
@@ -2373,7 +2382,7 @@ static void __init uncore_type_exit(struct intel_uncore_type *type) | |||
2373 | type->attr_groups[1] = NULL; | 2382 | type->attr_groups[1] = NULL; |
2374 | } | 2383 | } |
2375 | 2384 | ||
2376 | static void uncore_types_exit(struct intel_uncore_type **types) | 2385 | static void __init uncore_types_exit(struct intel_uncore_type **types) |
2377 | { | 2386 | { |
2378 | int i; | 2387 | int i; |
2379 | for (i = 0; types[i]; i++) | 2388 | for (i = 0; types[i]; i++) |
@@ -2814,7 +2823,13 @@ static int __init uncore_cpu_init(void) | |||
2814 | snbep_uncore_cbox.num_boxes = max_cores; | 2823 | snbep_uncore_cbox.num_boxes = max_cores; |
2815 | msr_uncores = snbep_msr_uncores; | 2824 | msr_uncores = snbep_msr_uncores; |
2816 | break; | 2825 | break; |
2817 | case 46: | 2826 | case 46: /* Nehalem-EX */ |
2827 | uncore_nhmex = true; | ||
2828 | case 47: /* Westmere-EX aka. Xeon E7 */ | ||
2829 | if (!uncore_nhmex) | ||
2830 | nhmex_uncore_mbox.event_descs = wsmex_uncore_mbox_events; | ||
2831 | if (nhmex_uncore_cbox.num_boxes > max_cores) | ||
2832 | nhmex_uncore_cbox.num_boxes = max_cores; | ||
2818 | msr_uncores = nhmex_msr_uncores; | 2833 | msr_uncores = nhmex_msr_uncores; |
2819 | break; | 2834 | break; |
2820 | default: | 2835 | default: |
diff --git a/arch/x86/kernel/cpu/perf_event_intel_uncore.h b/arch/x86/kernel/cpu/perf_event_intel_uncore.h index f3851892e077..5b81c1856aac 100644 --- a/arch/x86/kernel/cpu/perf_event_intel_uncore.h +++ b/arch/x86/kernel/cpu/perf_event_intel_uncore.h | |||
@@ -5,7 +5,7 @@ | |||
5 | #include "perf_event.h" | 5 | #include "perf_event.h" |
6 | 6 | ||
7 | #define UNCORE_PMU_NAME_LEN 32 | 7 | #define UNCORE_PMU_NAME_LEN 32 |
8 | #define UNCORE_PMU_HRTIMER_INTERVAL (60 * NSEC_PER_SEC) | 8 | #define UNCORE_PMU_HRTIMER_INTERVAL (60LL * NSEC_PER_SEC) |
9 | 9 | ||
10 | #define UNCORE_FIXED_EVENT 0xff | 10 | #define UNCORE_FIXED_EVENT 0xff |
11 | #define UNCORE_PMC_IDX_MAX_GENERIC 8 | 11 | #define UNCORE_PMC_IDX_MAX_GENERIC 8 |
@@ -230,6 +230,7 @@ | |||
230 | #define NHMEX_S1_MSR_MASK 0xe5a | 230 | #define NHMEX_S1_MSR_MASK 0xe5a |
231 | 231 | ||
232 | #define NHMEX_S_PMON_MM_CFG_EN (0x1ULL << 63) | 232 | #define NHMEX_S_PMON_MM_CFG_EN (0x1ULL << 63) |
233 | #define NHMEX_S_EVENT_TO_R_PROG_EV 0 | ||
233 | 234 | ||
234 | /* NHM-EX Mbox */ | 235 | /* NHM-EX Mbox */ |
235 | #define NHMEX_M0_MSR_GLOBAL_CTL 0xca0 | 236 | #define NHMEX_M0_MSR_GLOBAL_CTL 0xca0 |
@@ -275,18 +276,12 @@ | |||
275 | NHMEX_M_PMON_CTL_INC_SEL_MASK | \ | 276 | NHMEX_M_PMON_CTL_INC_SEL_MASK | \ |
276 | NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK) | 277 | NHMEX_M_PMON_CTL_SET_FLAG_SEL_MASK) |
277 | 278 | ||
278 | 279 | #define NHMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 11) - 1) | (1 << 23)) | |
279 | #define NHMEX_M_PMON_ZDP_CTL_FVC_FVID_MASK 0x1f | ||
280 | #define NHMEX_M_PMON_ZDP_CTL_FVC_BCMD_MASK (0x7 << 5) | ||
281 | #define NHMEX_M_PMON_ZDP_CTL_FVC_RSP_MASK (0x7 << 8) | ||
282 | #define NHMEX_M_PMON_ZDP_CTL_FVC_PBOX_INIT_ERR (1 << 23) | ||
283 | #define NHMEX_M_PMON_ZDP_CTL_FVC_MASK \ | ||
284 | (NHMEX_M_PMON_ZDP_CTL_FVC_FVID_MASK | \ | ||
285 | NHMEX_M_PMON_ZDP_CTL_FVC_BCMD_MASK | \ | ||
286 | NHMEX_M_PMON_ZDP_CTL_FVC_RSP_MASK | \ | ||
287 | NHMEX_M_PMON_ZDP_CTL_FVC_PBOX_INIT_ERR) | ||
288 | #define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (11 + 3 * (n))) | 280 | #define NHMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (11 + 3 * (n))) |
289 | 281 | ||
282 | #define WSMEX_M_PMON_ZDP_CTL_FVC_MASK (((1 << 12) - 1) | (1 << 24)) | ||
283 | #define WSMEX_M_PMON_ZDP_CTL_FVC_EVENT_MASK(n) (0x7 << (12 + 3 * (n))) | ||
284 | |||
290 | /* | 285 | /* |
291 | * use the 9~13 bits to select event If the 7th bit is not set, | 286 | * use the 9~13 bits to select event If the 7th bit is not set, |
292 | * otherwise use the 19~21 bits to select event. | 287 | * otherwise use the 19~21 bits to select event. |
@@ -368,6 +363,7 @@ struct intel_uncore_type { | |||
368 | unsigned num_shared_regs:8; | 363 | unsigned num_shared_regs:8; |
369 | unsigned single_fixed:1; | 364 | unsigned single_fixed:1; |
370 | unsigned pair_ctr_ctl:1; | 365 | unsigned pair_ctr_ctl:1; |
366 | unsigned *msr_offsets; | ||
371 | struct event_constraint unconstrainted; | 367 | struct event_constraint unconstrainted; |
372 | struct event_constraint *constraints; | 368 | struct event_constraint *constraints; |
373 | struct intel_uncore_pmu *pmus; | 369 | struct intel_uncore_pmu *pmus; |
@@ -485,29 +481,31 @@ unsigned uncore_pci_perf_ctr(struct intel_uncore_box *box, int idx) | |||
485 | return idx * 8 + box->pmu->type->perf_ctr; | 481 | return idx * 8 + box->pmu->type->perf_ctr; |
486 | } | 482 | } |
487 | 483 | ||
488 | static inline | 484 | static inline unsigned uncore_msr_box_offset(struct intel_uncore_box *box) |
489 | unsigned uncore_msr_box_ctl(struct intel_uncore_box *box) | 485 | { |
486 | struct intel_uncore_pmu *pmu = box->pmu; | ||
487 | return pmu->type->msr_offsets ? | ||
488 | pmu->type->msr_offsets[pmu->pmu_idx] : | ||
489 | pmu->type->msr_offset * pmu->pmu_idx; | ||
490 | } | ||
491 | |||
492 | static inline unsigned uncore_msr_box_ctl(struct intel_uncore_box *box) | ||
490 | { | 493 | { |
491 | if (!box->pmu->type->box_ctl) | 494 | if (!box->pmu->type->box_ctl) |
492 | return 0; | 495 | return 0; |
493 | return box->pmu->type->box_ctl + | 496 | return box->pmu->type->box_ctl + uncore_msr_box_offset(box); |
494 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | ||
495 | } | 497 | } |
496 | 498 | ||
497 | static inline | 499 | static inline unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box) |
498 | unsigned uncore_msr_fixed_ctl(struct intel_uncore_box *box) | ||
499 | { | 500 | { |
500 | if (!box->pmu->type->fixed_ctl) | 501 | if (!box->pmu->type->fixed_ctl) |
501 | return 0; | 502 | return 0; |
502 | return box->pmu->type->fixed_ctl + | 503 | return box->pmu->type->fixed_ctl + uncore_msr_box_offset(box); |
503 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | ||
504 | } | 504 | } |
505 | 505 | ||
506 | static inline | 506 | static inline unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box) |
507 | unsigned uncore_msr_fixed_ctr(struct intel_uncore_box *box) | ||
508 | { | 507 | { |
509 | return box->pmu->type->fixed_ctr + | 508 | return box->pmu->type->fixed_ctr + uncore_msr_box_offset(box); |
510 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | ||
511 | } | 509 | } |
512 | 510 | ||
513 | static inline | 511 | static inline |
@@ -515,7 +513,7 @@ unsigned uncore_msr_event_ctl(struct intel_uncore_box *box, int idx) | |||
515 | { | 513 | { |
516 | return box->pmu->type->event_ctl + | 514 | return box->pmu->type->event_ctl + |
517 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + | 515 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + |
518 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | 516 | uncore_msr_box_offset(box); |
519 | } | 517 | } |
520 | 518 | ||
521 | static inline | 519 | static inline |
@@ -523,7 +521,7 @@ unsigned uncore_msr_perf_ctr(struct intel_uncore_box *box, int idx) | |||
523 | { | 521 | { |
524 | return box->pmu->type->perf_ctr + | 522 | return box->pmu->type->perf_ctr + |
525 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + | 523 | (box->pmu->type->pair_ctr_ctl ? 2 * idx : idx) + |
526 | box->pmu->type->msr_offset * box->pmu->pmu_idx; | 524 | uncore_msr_box_offset(box); |
527 | } | 525 | } |
528 | 526 | ||
529 | static inline | 527 | static inline |
diff --git a/arch/x86/kernel/irq.c b/arch/x86/kernel/irq.c index 1f5f1d5d2a02..7ad683d78645 100644 --- a/arch/x86/kernel/irq.c +++ b/arch/x86/kernel/irq.c | |||
@@ -328,6 +328,7 @@ void fixup_irqs(void) | |||
328 | chip->irq_retrigger(data); | 328 | chip->irq_retrigger(data); |
329 | raw_spin_unlock(&desc->lock); | 329 | raw_spin_unlock(&desc->lock); |
330 | } | 330 | } |
331 | __this_cpu_write(vector_irq[vector], -1); | ||
331 | } | 332 | } |
332 | } | 333 | } |
333 | #endif | 334 | #endif |
diff --git a/arch/x86/kernel/kdebugfs.c b/arch/x86/kernel/kdebugfs.c index 1d5d31ea686b..dc1404bf8e4b 100644 --- a/arch/x86/kernel/kdebugfs.c +++ b/arch/x86/kernel/kdebugfs.c | |||
@@ -107,7 +107,7 @@ static int __init create_setup_data_nodes(struct dentry *parent) | |||
107 | { | 107 | { |
108 | struct setup_data_node *node; | 108 | struct setup_data_node *node; |
109 | struct setup_data *data; | 109 | struct setup_data *data; |
110 | int error = -ENOMEM; | 110 | int error; |
111 | struct dentry *d; | 111 | struct dentry *d; |
112 | struct page *pg; | 112 | struct page *pg; |
113 | u64 pa_data; | 113 | u64 pa_data; |
@@ -121,8 +121,10 @@ static int __init create_setup_data_nodes(struct dentry *parent) | |||
121 | 121 | ||
122 | while (pa_data) { | 122 | while (pa_data) { |
123 | node = kmalloc(sizeof(*node), GFP_KERNEL); | 123 | node = kmalloc(sizeof(*node), GFP_KERNEL); |
124 | if (!node) | 124 | if (!node) { |
125 | error = -ENOMEM; | ||
125 | goto err_dir; | 126 | goto err_dir; |
127 | } | ||
126 | 128 | ||
127 | pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT); | 129 | pg = pfn_to_page((pa_data+sizeof(*data)-1) >> PAGE_SHIFT); |
128 | if (PageHighMem(pg)) { | 130 | if (PageHighMem(pg)) { |
diff --git a/arch/x86/kvm/i8259.c b/arch/x86/kvm/i8259.c index 1df8fb9e1d5d..e498b18f010c 100644 --- a/arch/x86/kvm/i8259.c +++ b/arch/x86/kvm/i8259.c | |||
@@ -316,6 +316,11 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val) | |||
316 | addr &= 1; | 316 | addr &= 1; |
317 | if (addr == 0) { | 317 | if (addr == 0) { |
318 | if (val & 0x10) { | 318 | if (val & 0x10) { |
319 | u8 edge_irr = s->irr & ~s->elcr; | ||
320 | int i; | ||
321 | bool found; | ||
322 | struct kvm_vcpu *vcpu; | ||
323 | |||
319 | s->init4 = val & 1; | 324 | s->init4 = val & 1; |
320 | s->last_irr = 0; | 325 | s->last_irr = 0; |
321 | s->irr &= s->elcr; | 326 | s->irr &= s->elcr; |
@@ -333,6 +338,18 @@ static void pic_ioport_write(void *opaque, u32 addr, u32 val) | |||
333 | if (val & 0x08) | 338 | if (val & 0x08) |
334 | pr_pic_unimpl( | 339 | pr_pic_unimpl( |
335 | "level sensitive irq not supported"); | 340 | "level sensitive irq not supported"); |
341 | |||
342 | kvm_for_each_vcpu(i, vcpu, s->pics_state->kvm) | ||
343 | if (kvm_apic_accept_pic_intr(vcpu)) { | ||
344 | found = true; | ||
345 | break; | ||
346 | } | ||
347 | |||
348 | |||
349 | if (found) | ||
350 | for (irq = 0; irq < PIC_NUM_PINS/2; irq++) | ||
351 | if (edge_irr & (1 << irq)) | ||
352 | pic_clear_isr(s, irq); | ||
336 | } else if (val & 0x08) { | 353 | } else if (val & 0x08) { |
337 | if (val & 0x04) | 354 | if (val & 0x04) |
338 | s->poll = 1; | 355 | s->poll = 1; |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index c39b60707e02..c00f03de1b79 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -1488,13 +1488,6 @@ static void __vmx_load_host_state(struct vcpu_vmx *vmx) | |||
1488 | loadsegment(ds, vmx->host_state.ds_sel); | 1488 | loadsegment(ds, vmx->host_state.ds_sel); |
1489 | loadsegment(es, vmx->host_state.es_sel); | 1489 | loadsegment(es, vmx->host_state.es_sel); |
1490 | } | 1490 | } |
1491 | #else | ||
1492 | /* | ||
1493 | * The sysexit path does not restore ds/es, so we must set them to | ||
1494 | * a reasonable value ourselves. | ||
1495 | */ | ||
1496 | loadsegment(ds, __USER_DS); | ||
1497 | loadsegment(es, __USER_DS); | ||
1498 | #endif | 1491 | #endif |
1499 | reload_tss(); | 1492 | reload_tss(); |
1500 | #ifdef CONFIG_X86_64 | 1493 | #ifdef CONFIG_X86_64 |
@@ -6370,6 +6363,19 @@ static void __noclone vmx_vcpu_run(struct kvm_vcpu *vcpu) | |||
6370 | #endif | 6363 | #endif |
6371 | ); | 6364 | ); |
6372 | 6365 | ||
6366 | #ifndef CONFIG_X86_64 | ||
6367 | /* | ||
6368 | * The sysexit path does not restore ds/es, so we must set them to | ||
6369 | * a reasonable value ourselves. | ||
6370 | * | ||
6371 | * We can't defer this to vmx_load_host_state() since that function | ||
6372 | * may be executed in interrupt context, which saves and restore segments | ||
6373 | * around it, nullifying its effect. | ||
6374 | */ | ||
6375 | loadsegment(ds, __USER_DS); | ||
6376 | loadsegment(es, __USER_DS); | ||
6377 | #endif | ||
6378 | |||
6373 | vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP) | 6379 | vcpu->arch.regs_avail = ~((1 << VCPU_REGS_RIP) | (1 << VCPU_REGS_RSP) |
6374 | | (1 << VCPU_EXREG_RFLAGS) | 6380 | | (1 << VCPU_EXREG_RFLAGS) |
6375 | | (1 << VCPU_EXREG_CPL) | 6381 | | (1 << VCPU_EXREG_CPL) |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 59b59508ff07..42bce48f6928 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -925,6 +925,10 @@ static void kvm_write_wall_clock(struct kvm *kvm, gpa_t wall_clock) | |||
925 | */ | 925 | */ |
926 | getboottime(&boot); | 926 | getboottime(&boot); |
927 | 927 | ||
928 | if (kvm->arch.kvmclock_offset) { | ||
929 | struct timespec ts = ns_to_timespec(kvm->arch.kvmclock_offset); | ||
930 | boot = timespec_sub(boot, ts); | ||
931 | } | ||
928 | wc.sec = boot.tv_sec; | 932 | wc.sec = boot.tv_sec; |
929 | wc.nsec = boot.tv_nsec; | 933 | wc.nsec = boot.tv_nsec; |
930 | wc.version = version; | 934 | wc.version = version; |
diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c index f6679a7fb8ca..b91e48512425 100644 --- a/arch/x86/mm/hugetlbpage.c +++ b/arch/x86/mm/hugetlbpage.c | |||
@@ -56,9 +56,16 @@ static int vma_shareable(struct vm_area_struct *vma, unsigned long addr) | |||
56 | } | 56 | } |
57 | 57 | ||
58 | /* | 58 | /* |
59 | * search for a shareable pmd page for hugetlb. | 59 | * Search for a shareable pmd page for hugetlb. In any case calls pmd_alloc() |
60 | * and returns the corresponding pte. While this is not necessary for the | ||
61 | * !shared pmd case because we can allocate the pmd later as well, it makes the | ||
62 | * code much cleaner. pmd allocation is essential for the shared case because | ||
63 | * pud has to be populated inside the same i_mmap_mutex section - otherwise | ||
64 | * racing tasks could either miss the sharing (see huge_pte_offset) or select a | ||
65 | * bad pmd for sharing. | ||
60 | */ | 66 | */ |
61 | static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) | 67 | static pte_t * |
68 | huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) | ||
62 | { | 69 | { |
63 | struct vm_area_struct *vma = find_vma(mm, addr); | 70 | struct vm_area_struct *vma = find_vma(mm, addr); |
64 | struct address_space *mapping = vma->vm_file->f_mapping; | 71 | struct address_space *mapping = vma->vm_file->f_mapping; |
@@ -68,9 +75,10 @@ static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) | |||
68 | struct vm_area_struct *svma; | 75 | struct vm_area_struct *svma; |
69 | unsigned long saddr; | 76 | unsigned long saddr; |
70 | pte_t *spte = NULL; | 77 | pte_t *spte = NULL; |
78 | pte_t *pte; | ||
71 | 79 | ||
72 | if (!vma_shareable(vma, addr)) | 80 | if (!vma_shareable(vma, addr)) |
73 | return; | 81 | return (pte_t *)pmd_alloc(mm, pud, addr); |
74 | 82 | ||
75 | mutex_lock(&mapping->i_mmap_mutex); | 83 | mutex_lock(&mapping->i_mmap_mutex); |
76 | vma_prio_tree_foreach(svma, &iter, &mapping->i_mmap, idx, idx) { | 84 | vma_prio_tree_foreach(svma, &iter, &mapping->i_mmap, idx, idx) { |
@@ -97,7 +105,9 @@ static void huge_pmd_share(struct mm_struct *mm, unsigned long addr, pud_t *pud) | |||
97 | put_page(virt_to_page(spte)); | 105 | put_page(virt_to_page(spte)); |
98 | spin_unlock(&mm->page_table_lock); | 106 | spin_unlock(&mm->page_table_lock); |
99 | out: | 107 | out: |
108 | pte = (pte_t *)pmd_alloc(mm, pud, addr); | ||
100 | mutex_unlock(&mapping->i_mmap_mutex); | 109 | mutex_unlock(&mapping->i_mmap_mutex); |
110 | return pte; | ||
101 | } | 111 | } |
102 | 112 | ||
103 | /* | 113 | /* |
@@ -142,8 +152,9 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, | |||
142 | } else { | 152 | } else { |
143 | BUG_ON(sz != PMD_SIZE); | 153 | BUG_ON(sz != PMD_SIZE); |
144 | if (pud_none(*pud)) | 154 | if (pud_none(*pud)) |
145 | huge_pmd_share(mm, addr, pud); | 155 | pte = huge_pmd_share(mm, addr, pud); |
146 | pte = (pte_t *) pmd_alloc(mm, pud, addr); | 156 | else |
157 | pte = (pte_t *)pmd_alloc(mm, pud, addr); | ||
147 | } | 158 | } |
148 | } | 159 | } |
149 | BUG_ON(pte && !pte_none(*pte) && !pte_huge(*pte)); | 160 | BUG_ON(pte && !pte_none(*pte) && !pte_huge(*pte)); |
diff --git a/arch/x86/mm/pageattr.c b/arch/x86/mm/pageattr.c index 931930a96160..a718e0d23503 100644 --- a/arch/x86/mm/pageattr.c +++ b/arch/x86/mm/pageattr.c | |||
@@ -919,13 +919,11 @@ static int change_page_attr_set_clr(unsigned long *addr, int numpages, | |||
919 | 919 | ||
920 | /* | 920 | /* |
921 | * On success we use clflush, when the CPU supports it to | 921 | * On success we use clflush, when the CPU supports it to |
922 | * avoid the wbindv. If the CPU does not support it, in the | 922 | * avoid the wbindv. If the CPU does not support it and in the |
923 | * error case, and during early boot (for EFI) we fall back | 923 | * error case we fall back to cpa_flush_all (which uses |
924 | * to cpa_flush_all (which uses wbinvd): | 924 | * wbindv): |
925 | */ | 925 | */ |
926 | if (early_boot_irqs_disabled) | 926 | if (!ret && cpu_has_clflush) { |
927 | __cpa_flush_all((void *)(long)cache); | ||
928 | else if (!ret && cpu_has_clflush) { | ||
929 | if (cpa.flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) { | 927 | if (cpa.flags & (CPA_PAGES_ARRAY | CPA_ARRAY)) { |
930 | cpa_flush_array(addr, numpages, cache, | 928 | cpa_flush_array(addr, numpages, cache, |
931 | cpa.flags, pages); | 929 | cpa.flags, pages); |
diff --git a/arch/x86/mm/srat.c b/arch/x86/mm/srat.c index 4599c3e8bcb6..4ddf497ca65b 100644 --- a/arch/x86/mm/srat.c +++ b/arch/x86/mm/srat.c | |||
@@ -142,23 +142,23 @@ static inline int save_add_info(void) {return 0;} | |||
142 | #endif | 142 | #endif |
143 | 143 | ||
144 | /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ | 144 | /* Callback for parsing of the Proximity Domain <-> Memory Area mappings */ |
145 | void __init | 145 | int __init |
146 | acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | 146 | acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) |
147 | { | 147 | { |
148 | u64 start, end; | 148 | u64 start, end; |
149 | int node, pxm; | 149 | int node, pxm; |
150 | 150 | ||
151 | if (srat_disabled()) | 151 | if (srat_disabled()) |
152 | return; | 152 | return -1; |
153 | if (ma->header.length != sizeof(struct acpi_srat_mem_affinity)) { | 153 | if (ma->header.length != sizeof(struct acpi_srat_mem_affinity)) { |
154 | bad_srat(); | 154 | bad_srat(); |
155 | return; | 155 | return -1; |
156 | } | 156 | } |
157 | if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0) | 157 | if ((ma->flags & ACPI_SRAT_MEM_ENABLED) == 0) |
158 | return; | 158 | return -1; |
159 | 159 | ||
160 | if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && !save_add_info()) | 160 | if ((ma->flags & ACPI_SRAT_MEM_HOT_PLUGGABLE) && !save_add_info()) |
161 | return; | 161 | return -1; |
162 | start = ma->base_address; | 162 | start = ma->base_address; |
163 | end = start + ma->length; | 163 | end = start + ma->length; |
164 | pxm = ma->proximity_domain; | 164 | pxm = ma->proximity_domain; |
@@ -168,12 +168,12 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | |||
168 | if (node < 0) { | 168 | if (node < 0) { |
169 | printk(KERN_ERR "SRAT: Too many proximity domains.\n"); | 169 | printk(KERN_ERR "SRAT: Too many proximity domains.\n"); |
170 | bad_srat(); | 170 | bad_srat(); |
171 | return; | 171 | return -1; |
172 | } | 172 | } |
173 | 173 | ||
174 | if (numa_add_memblk(node, start, end) < 0) { | 174 | if (numa_add_memblk(node, start, end) < 0) { |
175 | bad_srat(); | 175 | bad_srat(); |
176 | return; | 176 | return -1; |
177 | } | 177 | } |
178 | 178 | ||
179 | node_set(node, numa_nodes_parsed); | 179 | node_set(node, numa_nodes_parsed); |
@@ -181,6 +181,7 @@ acpi_numa_memory_affinity_init(struct acpi_srat_mem_affinity *ma) | |||
181 | printk(KERN_INFO "SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]\n", | 181 | printk(KERN_INFO "SRAT: Node %u PXM %u [mem %#010Lx-%#010Lx]\n", |
182 | node, pxm, | 182 | node, pxm, |
183 | (unsigned long long) start, (unsigned long long) end - 1); | 183 | (unsigned long long) start, (unsigned long long) end - 1); |
184 | return 0; | ||
184 | } | 185 | } |
185 | 186 | ||
186 | void __init acpi_numa_arch_fixup(void) {} | 187 | void __init acpi_numa_arch_fixup(void) {} |
diff --git a/arch/x86/platform/efi/efi.c b/arch/x86/platform/efi/efi.c index 2dc29f51e75a..92660edaa1e7 100644 --- a/arch/x86/platform/efi/efi.c +++ b/arch/x86/platform/efi/efi.c | |||
@@ -234,7 +234,22 @@ static efi_status_t __init phys_efi_set_virtual_address_map( | |||
234 | return status; | 234 | return status; |
235 | } | 235 | } |
236 | 236 | ||
237 | static int efi_set_rtc_mmss(unsigned long nowtime) | 237 | static efi_status_t __init phys_efi_get_time(efi_time_t *tm, |
238 | efi_time_cap_t *tc) | ||
239 | { | ||
240 | unsigned long flags; | ||
241 | efi_status_t status; | ||
242 | |||
243 | spin_lock_irqsave(&rtc_lock, flags); | ||
244 | efi_call_phys_prelog(); | ||
245 | status = efi_call_phys2(efi_phys.get_time, virt_to_phys(tm), | ||
246 | virt_to_phys(tc)); | ||
247 | efi_call_phys_epilog(); | ||
248 | spin_unlock_irqrestore(&rtc_lock, flags); | ||
249 | return status; | ||
250 | } | ||
251 | |||
252 | int efi_set_rtc_mmss(unsigned long nowtime) | ||
238 | { | 253 | { |
239 | int real_seconds, real_minutes; | 254 | int real_seconds, real_minutes; |
240 | efi_status_t status; | 255 | efi_status_t status; |
@@ -263,7 +278,7 @@ static int efi_set_rtc_mmss(unsigned long nowtime) | |||
263 | return 0; | 278 | return 0; |
264 | } | 279 | } |
265 | 280 | ||
266 | static unsigned long efi_get_time(void) | 281 | unsigned long efi_get_time(void) |
267 | { | 282 | { |
268 | efi_status_t status; | 283 | efi_status_t status; |
269 | efi_time_t eft; | 284 | efi_time_t eft; |
@@ -606,13 +621,18 @@ static int __init efi_runtime_init(void) | |||
606 | } | 621 | } |
607 | /* | 622 | /* |
608 | * We will only need *early* access to the following | 623 | * We will only need *early* access to the following |
609 | * EFI runtime service before set_virtual_address_map | 624 | * two EFI runtime services before set_virtual_address_map |
610 | * is invoked. | 625 | * is invoked. |
611 | */ | 626 | */ |
627 | efi_phys.get_time = (efi_get_time_t *)runtime->get_time; | ||
612 | efi_phys.set_virtual_address_map = | 628 | efi_phys.set_virtual_address_map = |
613 | (efi_set_virtual_address_map_t *) | 629 | (efi_set_virtual_address_map_t *) |
614 | runtime->set_virtual_address_map; | 630 | runtime->set_virtual_address_map; |
615 | 631 | /* | |
632 | * Make efi_get_time can be called before entering | ||
633 | * virtual mode. | ||
634 | */ | ||
635 | efi.get_time = phys_efi_get_time; | ||
616 | early_iounmap(runtime, sizeof(efi_runtime_services_t)); | 636 | early_iounmap(runtime, sizeof(efi_runtime_services_t)); |
617 | 637 | ||
618 | return 0; | 638 | return 0; |
@@ -700,10 +720,12 @@ void __init efi_init(void) | |||
700 | efi_enabled = 0; | 720 | efi_enabled = 0; |
701 | return; | 721 | return; |
702 | } | 722 | } |
723 | #ifdef CONFIG_X86_32 | ||
703 | if (efi_native) { | 724 | if (efi_native) { |
704 | x86_platform.get_wallclock = efi_get_time; | 725 | x86_platform.get_wallclock = efi_get_time; |
705 | x86_platform.set_wallclock = efi_set_rtc_mmss; | 726 | x86_platform.set_wallclock = efi_set_rtc_mmss; |
706 | } | 727 | } |
728 | #endif | ||
707 | 729 | ||
708 | #if EFI_DEBUG | 730 | #if EFI_DEBUG |
709 | print_efi_memmap(); | 731 | print_efi_memmap(); |
diff --git a/arch/x86/platform/olpc/olpc-xo1-pm.c b/arch/x86/platform/olpc/olpc-xo1-pm.c index 0ce8616c88ae..d75582d1aa55 100644 --- a/arch/x86/platform/olpc/olpc-xo1-pm.c +++ b/arch/x86/platform/olpc/olpc-xo1-pm.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/pm.h> | 18 | #include <linux/pm.h> |
19 | #include <linux/mfd/core.h> | 19 | #include <linux/mfd/core.h> |
20 | #include <linux/suspend.h> | 20 | #include <linux/suspend.h> |
21 | #include <linux/olpc-ec.h> | ||
21 | 22 | ||
22 | #include <asm/io.h> | 23 | #include <asm/io.h> |
23 | #include <asm/olpc.h> | 24 | #include <asm/olpc.h> |
@@ -51,16 +52,11 @@ EXPORT_SYMBOL_GPL(olpc_xo1_pm_wakeup_clear); | |||
51 | static int xo1_power_state_enter(suspend_state_t pm_state) | 52 | static int xo1_power_state_enter(suspend_state_t pm_state) |
52 | { | 53 | { |
53 | unsigned long saved_sci_mask; | 54 | unsigned long saved_sci_mask; |
54 | int r; | ||
55 | 55 | ||
56 | /* Only STR is supported */ | 56 | /* Only STR is supported */ |
57 | if (pm_state != PM_SUSPEND_MEM) | 57 | if (pm_state != PM_SUSPEND_MEM) |
58 | return -EINVAL; | 58 | return -EINVAL; |
59 | 59 | ||
60 | r = olpc_ec_cmd(EC_SET_SCI_INHIBIT, NULL, 0, NULL, 0); | ||
61 | if (r) | ||
62 | return r; | ||
63 | |||
64 | /* | 60 | /* |
65 | * Save SCI mask (this gets lost since PM1_EN is used as a mask for | 61 | * Save SCI mask (this gets lost since PM1_EN is used as a mask for |
66 | * wakeup events, which is not necessarily the same event set) | 62 | * wakeup events, which is not necessarily the same event set) |
@@ -76,16 +72,6 @@ static int xo1_power_state_enter(suspend_state_t pm_state) | |||
76 | /* Restore SCI mask (using dword access to CS5536_PM1_EN) */ | 72 | /* Restore SCI mask (using dword access to CS5536_PM1_EN) */ |
77 | outl(saved_sci_mask, acpi_base + CS5536_PM1_STS); | 73 | outl(saved_sci_mask, acpi_base + CS5536_PM1_STS); |
78 | 74 | ||
79 | /* Tell the EC to stop inhibiting SCIs */ | ||
80 | olpc_ec_cmd(EC_SET_SCI_INHIBIT_RELEASE, NULL, 0, NULL, 0); | ||
81 | |||
82 | /* | ||
83 | * Tell the wireless module to restart USB communication. | ||
84 | * Must be done twice. | ||
85 | */ | ||
86 | olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0); | ||
87 | olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0); | ||
88 | |||
89 | return 0; | 75 | return 0; |
90 | } | 76 | } |
91 | 77 | ||
diff --git a/arch/x86/platform/olpc/olpc-xo1-sci.c b/arch/x86/platform/olpc/olpc-xo1-sci.c index 04b8c73659c5..63d4aa40956e 100644 --- a/arch/x86/platform/olpc/olpc-xo1-sci.c +++ b/arch/x86/platform/olpc/olpc-xo1-sci.c | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/power_supply.h> | 23 | #include <linux/power_supply.h> |
24 | #include <linux/suspend.h> | 24 | #include <linux/suspend.h> |
25 | #include <linux/workqueue.h> | 25 | #include <linux/workqueue.h> |
26 | #include <linux/olpc-ec.h> | ||
26 | 27 | ||
27 | #include <asm/io.h> | 28 | #include <asm/io.h> |
28 | #include <asm/msr.h> | 29 | #include <asm/msr.h> |
diff --git a/arch/x86/platform/olpc/olpc-xo15-sci.c b/arch/x86/platform/olpc/olpc-xo15-sci.c index 599be499fdf7..2fdca25905ae 100644 --- a/arch/x86/platform/olpc/olpc-xo15-sci.c +++ b/arch/x86/platform/olpc/olpc-xo15-sci.c | |||
@@ -13,6 +13,7 @@ | |||
13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
14 | #include <linux/workqueue.h> | 14 | #include <linux/workqueue.h> |
15 | #include <linux/power_supply.h> | 15 | #include <linux/power_supply.h> |
16 | #include <linux/olpc-ec.h> | ||
16 | 17 | ||
17 | #include <acpi/acpi_bus.h> | 18 | #include <acpi/acpi_bus.h> |
18 | #include <acpi/acpi_drivers.h> | 19 | #include <acpi/acpi_drivers.h> |
diff --git a/arch/x86/platform/olpc/olpc.c b/arch/x86/platform/olpc/olpc.c index a4bee53c2e54..27376081ddec 100644 --- a/arch/x86/platform/olpc/olpc.c +++ b/arch/x86/platform/olpc/olpc.c | |||
@@ -14,14 +14,13 @@ | |||
14 | #include <linux/init.h> | 14 | #include <linux/init.h> |
15 | #include <linux/module.h> | 15 | #include <linux/module.h> |
16 | #include <linux/delay.h> | 16 | #include <linux/delay.h> |
17 | #include <linux/spinlock.h> | ||
18 | #include <linux/io.h> | 17 | #include <linux/io.h> |
19 | #include <linux/string.h> | 18 | #include <linux/string.h> |
20 | #include <linux/platform_device.h> | 19 | #include <linux/platform_device.h> |
21 | #include <linux/of.h> | 20 | #include <linux/of.h> |
22 | #include <linux/syscore_ops.h> | 21 | #include <linux/syscore_ops.h> |
23 | #include <linux/debugfs.h> | ||
24 | #include <linux/mutex.h> | 22 | #include <linux/mutex.h> |
23 | #include <linux/olpc-ec.h> | ||
25 | 24 | ||
26 | #include <asm/geode.h> | 25 | #include <asm/geode.h> |
27 | #include <asm/setup.h> | 26 | #include <asm/setup.h> |
@@ -31,17 +30,6 @@ | |||
31 | struct olpc_platform_t olpc_platform_info; | 30 | struct olpc_platform_t olpc_platform_info; |
32 | EXPORT_SYMBOL_GPL(olpc_platform_info); | 31 | EXPORT_SYMBOL_GPL(olpc_platform_info); |
33 | 32 | ||
34 | static DEFINE_SPINLOCK(ec_lock); | ||
35 | |||
36 | /* debugfs interface to EC commands */ | ||
37 | #define EC_MAX_CMD_ARGS (5 + 1) /* cmd byte + 5 args */ | ||
38 | #define EC_MAX_CMD_REPLY (8) | ||
39 | |||
40 | static struct dentry *ec_debugfs_dir; | ||
41 | static DEFINE_MUTEX(ec_debugfs_cmd_lock); | ||
42 | static unsigned char ec_debugfs_resp[EC_MAX_CMD_REPLY]; | ||
43 | static unsigned int ec_debugfs_resp_bytes; | ||
44 | |||
45 | /* EC event mask to be applied during suspend (defining wakeup sources). */ | 33 | /* EC event mask to be applied during suspend (defining wakeup sources). */ |
46 | static u16 ec_wakeup_mask; | 34 | static u16 ec_wakeup_mask; |
47 | 35 | ||
@@ -125,16 +113,13 @@ static int __wait_on_obf(unsigned int line, unsigned int port, int desired) | |||
125 | * <http://wiki.laptop.org/go/Ec_specification>. Unfortunately, while | 113 | * <http://wiki.laptop.org/go/Ec_specification>. Unfortunately, while |
126 | * OpenFirmware's source is available, the EC's is not. | 114 | * OpenFirmware's source is available, the EC's is not. |
127 | */ | 115 | */ |
128 | int olpc_ec_cmd(unsigned char cmd, unsigned char *inbuf, size_t inlen, | 116 | static int olpc_xo1_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *outbuf, |
129 | unsigned char *outbuf, size_t outlen) | 117 | size_t outlen, void *arg) |
130 | { | 118 | { |
131 | unsigned long flags; | ||
132 | int ret = -EIO; | 119 | int ret = -EIO; |
133 | int i; | 120 | int i; |
134 | int restarts = 0; | 121 | int restarts = 0; |
135 | 122 | ||
136 | spin_lock_irqsave(&ec_lock, flags); | ||
137 | |||
138 | /* Clear OBF */ | 123 | /* Clear OBF */ |
139 | for (i = 0; i < 10 && (obf_status(0x6c) == 1); i++) | 124 | for (i = 0; i < 10 && (obf_status(0x6c) == 1); i++) |
140 | inb(0x68); | 125 | inb(0x68); |
@@ -198,10 +183,8 @@ restart: | |||
198 | 183 | ||
199 | ret = 0; | 184 | ret = 0; |
200 | err: | 185 | err: |
201 | spin_unlock_irqrestore(&ec_lock, flags); | ||
202 | return ret; | 186 | return ret; |
203 | } | 187 | } |
204 | EXPORT_SYMBOL_GPL(olpc_ec_cmd); | ||
205 | 188 | ||
206 | void olpc_ec_wakeup_set(u16 value) | 189 | void olpc_ec_wakeup_set(u16 value) |
207 | { | 190 | { |
@@ -280,96 +263,6 @@ int olpc_ec_sci_query(u16 *sci_value) | |||
280 | } | 263 | } |
281 | EXPORT_SYMBOL_GPL(olpc_ec_sci_query); | 264 | EXPORT_SYMBOL_GPL(olpc_ec_sci_query); |
282 | 265 | ||
283 | static ssize_t ec_debugfs_cmd_write(struct file *file, const char __user *buf, | ||
284 | size_t size, loff_t *ppos) | ||
285 | { | ||
286 | int i, m; | ||
287 | unsigned char ec_cmd[EC_MAX_CMD_ARGS]; | ||
288 | unsigned int ec_cmd_int[EC_MAX_CMD_ARGS]; | ||
289 | char cmdbuf[64]; | ||
290 | int ec_cmd_bytes; | ||
291 | |||
292 | mutex_lock(&ec_debugfs_cmd_lock); | ||
293 | |||
294 | size = simple_write_to_buffer(cmdbuf, sizeof(cmdbuf), ppos, buf, size); | ||
295 | |||
296 | m = sscanf(cmdbuf, "%x:%u %x %x %x %x %x", &ec_cmd_int[0], | ||
297 | &ec_debugfs_resp_bytes, | ||
298 | &ec_cmd_int[1], &ec_cmd_int[2], &ec_cmd_int[3], | ||
299 | &ec_cmd_int[4], &ec_cmd_int[5]); | ||
300 | if (m < 2 || ec_debugfs_resp_bytes > EC_MAX_CMD_REPLY) { | ||
301 | /* reset to prevent overflow on read */ | ||
302 | ec_debugfs_resp_bytes = 0; | ||
303 | |||
304 | printk(KERN_DEBUG "olpc-ec: bad ec cmd: " | ||
305 | "cmd:response-count [arg1 [arg2 ...]]\n"); | ||
306 | size = -EINVAL; | ||
307 | goto out; | ||
308 | } | ||
309 | |||
310 | /* convert scanf'd ints to char */ | ||
311 | ec_cmd_bytes = m - 2; | ||
312 | for (i = 0; i <= ec_cmd_bytes; i++) | ||
313 | ec_cmd[i] = ec_cmd_int[i]; | ||
314 | |||
315 | printk(KERN_DEBUG "olpc-ec: debugfs cmd 0x%02x with %d args " | ||
316 | "%02x %02x %02x %02x %02x, want %d returns\n", | ||
317 | ec_cmd[0], ec_cmd_bytes, ec_cmd[1], ec_cmd[2], ec_cmd[3], | ||
318 | ec_cmd[4], ec_cmd[5], ec_debugfs_resp_bytes); | ||
319 | |||
320 | olpc_ec_cmd(ec_cmd[0], (ec_cmd_bytes == 0) ? NULL : &ec_cmd[1], | ||
321 | ec_cmd_bytes, ec_debugfs_resp, ec_debugfs_resp_bytes); | ||
322 | |||
323 | printk(KERN_DEBUG "olpc-ec: response " | ||
324 | "%02x %02x %02x %02x %02x %02x %02x %02x (%d bytes expected)\n", | ||
325 | ec_debugfs_resp[0], ec_debugfs_resp[1], ec_debugfs_resp[2], | ||
326 | ec_debugfs_resp[3], ec_debugfs_resp[4], ec_debugfs_resp[5], | ||
327 | ec_debugfs_resp[6], ec_debugfs_resp[7], ec_debugfs_resp_bytes); | ||
328 | |||
329 | out: | ||
330 | mutex_unlock(&ec_debugfs_cmd_lock); | ||
331 | return size; | ||
332 | } | ||
333 | |||
334 | static ssize_t ec_debugfs_cmd_read(struct file *file, char __user *buf, | ||
335 | size_t size, loff_t *ppos) | ||
336 | { | ||
337 | unsigned int i, r; | ||
338 | char *rp; | ||
339 | char respbuf[64]; | ||
340 | |||
341 | mutex_lock(&ec_debugfs_cmd_lock); | ||
342 | rp = respbuf; | ||
343 | rp += sprintf(rp, "%02x", ec_debugfs_resp[0]); | ||
344 | for (i = 1; i < ec_debugfs_resp_bytes; i++) | ||
345 | rp += sprintf(rp, ", %02x", ec_debugfs_resp[i]); | ||
346 | mutex_unlock(&ec_debugfs_cmd_lock); | ||
347 | rp += sprintf(rp, "\n"); | ||
348 | |||
349 | r = rp - respbuf; | ||
350 | return simple_read_from_buffer(buf, size, ppos, respbuf, r); | ||
351 | } | ||
352 | |||
353 | static const struct file_operations ec_debugfs_genops = { | ||
354 | .write = ec_debugfs_cmd_write, | ||
355 | .read = ec_debugfs_cmd_read, | ||
356 | }; | ||
357 | |||
358 | static void setup_debugfs(void) | ||
359 | { | ||
360 | ec_debugfs_dir = debugfs_create_dir("olpc-ec", 0); | ||
361 | if (ec_debugfs_dir == ERR_PTR(-ENODEV)) | ||
362 | return; | ||
363 | |||
364 | debugfs_create_file("cmd", 0600, ec_debugfs_dir, NULL, | ||
365 | &ec_debugfs_genops); | ||
366 | } | ||
367 | |||
368 | static int olpc_ec_suspend(void) | ||
369 | { | ||
370 | return olpc_ec_mask_write(ec_wakeup_mask); | ||
371 | } | ||
372 | |||
373 | static bool __init check_ofw_architecture(struct device_node *root) | 266 | static bool __init check_ofw_architecture(struct device_node *root) |
374 | { | 267 | { |
375 | const char *olpc_arch; | 268 | const char *olpc_arch; |
@@ -424,8 +317,59 @@ static int __init add_xo1_platform_devices(void) | |||
424 | return 0; | 317 | return 0; |
425 | } | 318 | } |
426 | 319 | ||
427 | static struct syscore_ops olpc_syscore_ops = { | 320 | static int olpc_xo1_ec_probe(struct platform_device *pdev) |
428 | .suspend = olpc_ec_suspend, | 321 | { |
322 | /* get the EC revision */ | ||
323 | olpc_ec_cmd(EC_FIRMWARE_REV, NULL, 0, | ||
324 | (unsigned char *) &olpc_platform_info.ecver, 1); | ||
325 | |||
326 | /* EC version 0x5f adds support for wide SCI mask */ | ||
327 | if (olpc_platform_info.ecver >= 0x5f) | ||
328 | olpc_platform_info.flags |= OLPC_F_EC_WIDE_SCI; | ||
329 | |||
330 | pr_info("OLPC board revision %s%X (EC=%x)\n", | ||
331 | ((olpc_platform_info.boardrev & 0xf) < 8) ? "pre" : "", | ||
332 | olpc_platform_info.boardrev >> 4, | ||
333 | olpc_platform_info.ecver); | ||
334 | |||
335 | return 0; | ||
336 | } | ||
337 | static int olpc_xo1_ec_suspend(struct platform_device *pdev) | ||
338 | { | ||
339 | olpc_ec_mask_write(ec_wakeup_mask); | ||
340 | |||
341 | /* | ||
342 | * Squelch SCIs while suspended. This is a fix for | ||
343 | * <http://dev.laptop.org/ticket/1835>. | ||
344 | */ | ||
345 | return olpc_ec_cmd(EC_SET_SCI_INHIBIT, NULL, 0, NULL, 0); | ||
346 | } | ||
347 | |||
348 | static int olpc_xo1_ec_resume(struct platform_device *pdev) | ||
349 | { | ||
350 | /* Tell the EC to stop inhibiting SCIs */ | ||
351 | olpc_ec_cmd(EC_SET_SCI_INHIBIT_RELEASE, NULL, 0, NULL, 0); | ||
352 | |||
353 | /* | ||
354 | * Tell the wireless module to restart USB communication. | ||
355 | * Must be done twice. | ||
356 | */ | ||
357 | olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0); | ||
358 | olpc_ec_cmd(EC_WAKE_UP_WLAN, NULL, 0, NULL, 0); | ||
359 | |||
360 | return 0; | ||
361 | } | ||
362 | |||
363 | static struct olpc_ec_driver ec_xo1_driver = { | ||
364 | .probe = olpc_xo1_ec_probe, | ||
365 | .suspend = olpc_xo1_ec_suspend, | ||
366 | .resume = olpc_xo1_ec_resume, | ||
367 | .ec_cmd = olpc_xo1_ec_cmd, | ||
368 | }; | ||
369 | |||
370 | static struct olpc_ec_driver ec_xo1_5_driver = { | ||
371 | .probe = olpc_xo1_ec_probe, | ||
372 | .ec_cmd = olpc_xo1_ec_cmd, | ||
429 | }; | 373 | }; |
430 | 374 | ||
431 | static int __init olpc_init(void) | 375 | static int __init olpc_init(void) |
@@ -435,16 +379,17 @@ static int __init olpc_init(void) | |||
435 | if (!olpc_ofw_present() || !platform_detect()) | 379 | if (!olpc_ofw_present() || !platform_detect()) |
436 | return 0; | 380 | return 0; |
437 | 381 | ||
438 | spin_lock_init(&ec_lock); | 382 | /* register the XO-1 and 1.5-specific EC handler */ |
383 | if (olpc_platform_info.boardrev < olpc_board_pre(0xd0)) /* XO-1 */ | ||
384 | olpc_ec_driver_register(&ec_xo1_driver, NULL); | ||
385 | else | ||
386 | olpc_ec_driver_register(&ec_xo1_5_driver, NULL); | ||
387 | platform_device_register_simple("olpc-ec", -1, NULL, 0); | ||
439 | 388 | ||
440 | /* assume B1 and above models always have a DCON */ | 389 | /* assume B1 and above models always have a DCON */ |
441 | if (olpc_board_at_least(olpc_board(0xb1))) | 390 | if (olpc_board_at_least(olpc_board(0xb1))) |
442 | olpc_platform_info.flags |= OLPC_F_DCON; | 391 | olpc_platform_info.flags |= OLPC_F_DCON; |
443 | 392 | ||
444 | /* get the EC revision */ | ||
445 | olpc_ec_cmd(EC_FIRMWARE_REV, NULL, 0, | ||
446 | (unsigned char *) &olpc_platform_info.ecver, 1); | ||
447 | |||
448 | #ifdef CONFIG_PCI_OLPC | 393 | #ifdef CONFIG_PCI_OLPC |
449 | /* If the VSA exists let it emulate PCI, if not emulate in kernel. | 394 | /* If the VSA exists let it emulate PCI, if not emulate in kernel. |
450 | * XO-1 only. */ | 395 | * XO-1 only. */ |
@@ -452,14 +397,6 @@ static int __init olpc_init(void) | |||
452 | !cs5535_has_vsa2()) | 397 | !cs5535_has_vsa2()) |
453 | x86_init.pci.arch_init = pci_olpc_init; | 398 | x86_init.pci.arch_init = pci_olpc_init; |
454 | #endif | 399 | #endif |
455 | /* EC version 0x5f adds support for wide SCI mask */ | ||
456 | if (olpc_platform_info.ecver >= 0x5f) | ||
457 | olpc_platform_info.flags |= OLPC_F_EC_WIDE_SCI; | ||
458 | |||
459 | printk(KERN_INFO "OLPC board revision %s%X (EC=%x)\n", | ||
460 | ((olpc_platform_info.boardrev & 0xf) < 8) ? "pre" : "", | ||
461 | olpc_platform_info.boardrev >> 4, | ||
462 | olpc_platform_info.ecver); | ||
463 | 400 | ||
464 | if (olpc_platform_info.boardrev < olpc_board_pre(0xd0)) { /* XO-1 */ | 401 | if (olpc_platform_info.boardrev < olpc_board_pre(0xd0)) { /* XO-1 */ |
465 | r = add_xo1_platform_devices(); | 402 | r = add_xo1_platform_devices(); |
@@ -467,9 +404,6 @@ static int __init olpc_init(void) | |||
467 | return r; | 404 | return r; |
468 | } | 405 | } |
469 | 406 | ||
470 | register_syscore_ops(&olpc_syscore_ops); | ||
471 | setup_debugfs(); | ||
472 | |||
473 | return 0; | 407 | return 0; |
474 | } | 408 | } |
475 | 409 | ||
diff --git a/arch/x86/realmode/rm/Makefile b/arch/x86/realmode/rm/Makefile index b2d534cab25f..88692871823f 100644 --- a/arch/x86/realmode/rm/Makefile +++ b/arch/x86/realmode/rm/Makefile | |||
@@ -72,7 +72,7 @@ KBUILD_CFLAGS := $(LINUXINCLUDE) -m32 -g -Os -D_SETUP -D__KERNEL__ -D_WAKEUP \ | |||
72 | -Wall -Wstrict-prototypes \ | 72 | -Wall -Wstrict-prototypes \ |
73 | -march=i386 -mregparm=3 \ | 73 | -march=i386 -mregparm=3 \ |
74 | -include $(srctree)/$(src)/../../boot/code16gcc.h \ | 74 | -include $(srctree)/$(src)/../../boot/code16gcc.h \ |
75 | -fno-strict-aliasing -fomit-frame-pointer \ | 75 | -fno-strict-aliasing -fomit-frame-pointer -fno-pic \ |
76 | $(call cc-option, -ffreestanding) \ | 76 | $(call cc-option, -ffreestanding) \ |
77 | $(call cc-option, -fno-toplevel-reorder,\ | 77 | $(call cc-option, -fno-toplevel-reorder,\ |
78 | $(call cc-option, -fno-unit-at-a-time)) \ | 78 | $(call cc-option, -fno-unit-at-a-time)) \ |
diff --git a/arch/x86/syscalls/syscall_64.tbl b/arch/x86/syscalls/syscall_64.tbl index 51171aeff0dc..a582bfed95bb 100644 --- a/arch/x86/syscalls/syscall_64.tbl +++ b/arch/x86/syscalls/syscall_64.tbl | |||
@@ -60,8 +60,8 @@ | |||
60 | 51 common getsockname sys_getsockname | 60 | 51 common getsockname sys_getsockname |
61 | 52 common getpeername sys_getpeername | 61 | 52 common getpeername sys_getpeername |
62 | 53 common socketpair sys_socketpair | 62 | 53 common socketpair sys_socketpair |
63 | 54 common setsockopt sys_setsockopt | 63 | 54 64 setsockopt sys_setsockopt |
64 | 55 common getsockopt sys_getsockopt | 64 | 55 64 getsockopt sys_getsockopt |
65 | 56 common clone stub_clone | 65 | 56 common clone stub_clone |
66 | 57 common fork stub_fork | 66 | 57 common fork stub_fork |
67 | 58 common vfork stub_vfork | 67 | 58 common vfork stub_vfork |
@@ -318,7 +318,7 @@ | |||
318 | 309 common getcpu sys_getcpu | 318 | 309 common getcpu sys_getcpu |
319 | 310 64 process_vm_readv sys_process_vm_readv | 319 | 310 64 process_vm_readv sys_process_vm_readv |
320 | 311 64 process_vm_writev sys_process_vm_writev | 320 | 311 64 process_vm_writev sys_process_vm_writev |
321 | 312 64 kcmp sys_kcmp | 321 | 312 common kcmp sys_kcmp |
322 | 322 | ||
323 | # | 323 | # |
324 | # x32-specific system call numbers start at 512 to avoid cache impact | 324 | # x32-specific system call numbers start at 512 to avoid cache impact |
@@ -353,3 +353,5 @@ | |||
353 | 538 x32 sendmmsg compat_sys_sendmmsg | 353 | 538 x32 sendmmsg compat_sys_sendmmsg |
354 | 539 x32 process_vm_readv compat_sys_process_vm_readv | 354 | 539 x32 process_vm_readv compat_sys_process_vm_readv |
355 | 540 x32 process_vm_writev compat_sys_process_vm_writev | 355 | 540 x32 process_vm_writev compat_sys_process_vm_writev |
356 | 541 x32 setsockopt compat_sys_setsockopt | ||
357 | 542 x32 getsockopt compat_sys_getsockopt | ||
diff --git a/arch/x86/xen/p2m.c b/arch/x86/xen/p2m.c index 64effdc6da94..b2e91d40a4cb 100644 --- a/arch/x86/xen/p2m.c +++ b/arch/x86/xen/p2m.c | |||
@@ -194,6 +194,11 @@ RESERVE_BRK(p2m_mid_mfn, PAGE_SIZE * (MAX_DOMAIN_PAGES / (P2M_PER_PAGE * P2M_MID | |||
194 | * boundary violation will require three middle nodes. */ | 194 | * boundary violation will require three middle nodes. */ |
195 | RESERVE_BRK(p2m_mid_identity, PAGE_SIZE * 2 * 3); | 195 | RESERVE_BRK(p2m_mid_identity, PAGE_SIZE * 2 * 3); |
196 | 196 | ||
197 | /* When we populate back during bootup, the amount of pages can vary. The | ||
198 | * max we have is seen is 395979, but that does not mean it can't be more. | ||
199 | * But some machines can have 3GB I/O holes even. So lets reserve enough | ||
200 | * for 4GB of I/O and E820 holes. */ | ||
201 | RESERVE_BRK(p2m_populated, PMD_SIZE * 4); | ||
197 | static inline unsigned p2m_top_index(unsigned long pfn) | 202 | static inline unsigned p2m_top_index(unsigned long pfn) |
198 | { | 203 | { |
199 | BUG_ON(pfn >= MAX_P2M_PFN); | 204 | BUG_ON(pfn >= MAX_P2M_PFN); |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index ac7034129f3f..d5fdd36190cc 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -69,7 +69,9 @@ static const struct acpi_device_id ac_device_ids[] = { | |||
69 | }; | 69 | }; |
70 | MODULE_DEVICE_TABLE(acpi, ac_device_ids); | 70 | MODULE_DEVICE_TABLE(acpi, ac_device_ids); |
71 | 71 | ||
72 | #ifdef CONFIG_PM_SLEEP | ||
72 | static int acpi_ac_resume(struct device *dev); | 73 | static int acpi_ac_resume(struct device *dev); |
74 | #endif | ||
73 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); | 75 | static SIMPLE_DEV_PM_OPS(acpi_ac_pm, NULL, acpi_ac_resume); |
74 | 76 | ||
75 | static struct acpi_driver acpi_ac_driver = { | 77 | static struct acpi_driver acpi_ac_driver = { |
@@ -313,6 +315,7 @@ static int acpi_ac_add(struct acpi_device *device) | |||
313 | return result; | 315 | return result; |
314 | } | 316 | } |
315 | 317 | ||
318 | #ifdef CONFIG_PM_SLEEP | ||
316 | static int acpi_ac_resume(struct device *dev) | 319 | static int acpi_ac_resume(struct device *dev) |
317 | { | 320 | { |
318 | struct acpi_ac *ac; | 321 | struct acpi_ac *ac; |
@@ -332,6 +335,7 @@ static int acpi_ac_resume(struct device *dev) | |||
332 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); | 335 | kobject_uevent(&ac->charger.dev->kobj, KOBJ_CHANGE); |
333 | return 0; | 336 | return 0; |
334 | } | 337 | } |
338 | #endif | ||
335 | 339 | ||
336 | static int acpi_ac_remove(struct acpi_device *device, int type) | 340 | static int acpi_ac_remove(struct acpi_device *device, int type) |
337 | { | 341 | { |
diff --git a/drivers/acpi/acpica/achware.h b/drivers/acpi/acpica/achware.h index 5ccb99ae3a6f..5de4ec72766d 100644 --- a/drivers/acpi/acpica/achware.h +++ b/drivers/acpi/acpica/achware.h | |||
@@ -83,22 +83,22 @@ acpi_status acpi_hw_clear_acpi_status(void); | |||
83 | /* | 83 | /* |
84 | * hwsleep - sleep/wake support (Legacy sleep registers) | 84 | * hwsleep - sleep/wake support (Legacy sleep registers) |
85 | */ | 85 | */ |
86 | acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags); | 86 | acpi_status acpi_hw_legacy_sleep(u8 sleep_state); |
87 | 87 | ||
88 | acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags); | 88 | acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state); |
89 | 89 | ||
90 | acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags); | 90 | acpi_status acpi_hw_legacy_wake(u8 sleep_state); |
91 | 91 | ||
92 | /* | 92 | /* |
93 | * hwesleep - sleep/wake support (Extended FADT-V5 sleep registers) | 93 | * hwesleep - sleep/wake support (Extended FADT-V5 sleep registers) |
94 | */ | 94 | */ |
95 | void acpi_hw_execute_sleep_method(char *method_name, u32 integer_argument); | 95 | void acpi_hw_execute_sleep_method(char *method_name, u32 integer_argument); |
96 | 96 | ||
97 | acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags); | 97 | acpi_status acpi_hw_extended_sleep(u8 sleep_state); |
98 | 98 | ||
99 | acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags); | 99 | acpi_status acpi_hw_extended_wake_prep(u8 sleep_state); |
100 | 100 | ||
101 | acpi_status acpi_hw_extended_wake(u8 sleep_state, u8 flags); | 101 | acpi_status acpi_hw_extended_wake(u8 sleep_state); |
102 | 102 | ||
103 | /* | 103 | /* |
104 | * hwvalid - Port I/O with validation | 104 | * hwvalid - Port I/O with validation |
diff --git a/drivers/acpi/acpica/hwesleep.c b/drivers/acpi/acpica/hwesleep.c index 48518dac5342..94996f9ae3ad 100644 --- a/drivers/acpi/acpica/hwesleep.c +++ b/drivers/acpi/acpica/hwesleep.c | |||
@@ -90,7 +90,6 @@ void acpi_hw_execute_sleep_method(char *method_pathname, u32 integer_argument) | |||
90 | * FUNCTION: acpi_hw_extended_sleep | 90 | * FUNCTION: acpi_hw_extended_sleep |
91 | * | 91 | * |
92 | * PARAMETERS: sleep_state - Which sleep state to enter | 92 | * PARAMETERS: sleep_state - Which sleep state to enter |
93 | * flags - ACPI_EXECUTE_GTS to run optional method | ||
94 | * | 93 | * |
95 | * RETURN: Status | 94 | * RETURN: Status |
96 | * | 95 | * |
@@ -100,7 +99,7 @@ void acpi_hw_execute_sleep_method(char *method_pathname, u32 integer_argument) | |||
100 | * | 99 | * |
101 | ******************************************************************************/ | 100 | ******************************************************************************/ |
102 | 101 | ||
103 | acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags) | 102 | acpi_status acpi_hw_extended_sleep(u8 sleep_state) |
104 | { | 103 | { |
105 | acpi_status status; | 104 | acpi_status status; |
106 | u8 sleep_type_value; | 105 | u8 sleep_type_value; |
@@ -125,12 +124,6 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags) | |||
125 | 124 | ||
126 | acpi_gbl_system_awake_and_running = FALSE; | 125 | acpi_gbl_system_awake_and_running = FALSE; |
127 | 126 | ||
128 | /* Optionally execute _GTS (Going To Sleep) */ | ||
129 | |||
130 | if (flags & ACPI_EXECUTE_GTS) { | ||
131 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__GTS, sleep_state); | ||
132 | } | ||
133 | |||
134 | /* Flush caches, as per ACPI specification */ | 127 | /* Flush caches, as per ACPI specification */ |
135 | 128 | ||
136 | ACPI_FLUSH_CPU_CACHE(); | 129 | ACPI_FLUSH_CPU_CACHE(); |
@@ -172,7 +165,6 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags) | |||
172 | * FUNCTION: acpi_hw_extended_wake_prep | 165 | * FUNCTION: acpi_hw_extended_wake_prep |
173 | * | 166 | * |
174 | * PARAMETERS: sleep_state - Which sleep state we just exited | 167 | * PARAMETERS: sleep_state - Which sleep state we just exited |
175 | * flags - ACPI_EXECUTE_BFS to run optional method | ||
176 | * | 168 | * |
177 | * RETURN: Status | 169 | * RETURN: Status |
178 | * | 170 | * |
@@ -181,7 +173,7 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state, u8 flags) | |||
181 | * | 173 | * |
182 | ******************************************************************************/ | 174 | ******************************************************************************/ |
183 | 175 | ||
184 | acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags) | 176 | acpi_status acpi_hw_extended_wake_prep(u8 sleep_state) |
185 | { | 177 | { |
186 | acpi_status status; | 178 | acpi_status status; |
187 | u8 sleep_type_value; | 179 | u8 sleep_type_value; |
@@ -200,11 +192,6 @@ acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags) | |||
200 | &acpi_gbl_FADT.sleep_control); | 192 | &acpi_gbl_FADT.sleep_control); |
201 | } | 193 | } |
202 | 194 | ||
203 | /* Optionally execute _BFS (Back From Sleep) */ | ||
204 | |||
205 | if (flags & ACPI_EXECUTE_BFS) { | ||
206 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__BFS, sleep_state); | ||
207 | } | ||
208 | return_ACPI_STATUS(AE_OK); | 195 | return_ACPI_STATUS(AE_OK); |
209 | } | 196 | } |
210 | 197 | ||
@@ -222,7 +209,7 @@ acpi_status acpi_hw_extended_wake_prep(u8 sleep_state, u8 flags) | |||
222 | * | 209 | * |
223 | ******************************************************************************/ | 210 | ******************************************************************************/ |
224 | 211 | ||
225 | acpi_status acpi_hw_extended_wake(u8 sleep_state, u8 flags) | 212 | acpi_status acpi_hw_extended_wake(u8 sleep_state) |
226 | { | 213 | { |
227 | ACPI_FUNCTION_TRACE(hw_extended_wake); | 214 | ACPI_FUNCTION_TRACE(hw_extended_wake); |
228 | 215 | ||
diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index 9960fe9ef533..3fddde056a5e 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c | |||
@@ -56,7 +56,6 @@ ACPI_MODULE_NAME("hwsleep") | |||
56 | * FUNCTION: acpi_hw_legacy_sleep | 56 | * FUNCTION: acpi_hw_legacy_sleep |
57 | * | 57 | * |
58 | * PARAMETERS: sleep_state - Which sleep state to enter | 58 | * PARAMETERS: sleep_state - Which sleep state to enter |
59 | * flags - ACPI_EXECUTE_GTS to run optional method | ||
60 | * | 59 | * |
61 | * RETURN: Status | 60 | * RETURN: Status |
62 | * | 61 | * |
@@ -64,7 +63,7 @@ ACPI_MODULE_NAME("hwsleep") | |||
64 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | 63 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED |
65 | * | 64 | * |
66 | ******************************************************************************/ | 65 | ******************************************************************************/ |
67 | acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) | 66 | acpi_status acpi_hw_legacy_sleep(u8 sleep_state) |
68 | { | 67 | { |
69 | struct acpi_bit_register_info *sleep_type_reg_info; | 68 | struct acpi_bit_register_info *sleep_type_reg_info; |
70 | struct acpi_bit_register_info *sleep_enable_reg_info; | 69 | struct acpi_bit_register_info *sleep_enable_reg_info; |
@@ -110,12 +109,6 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) | |||
110 | return_ACPI_STATUS(status); | 109 | return_ACPI_STATUS(status); |
111 | } | 110 | } |
112 | 111 | ||
113 | /* Optionally execute _GTS (Going To Sleep) */ | ||
114 | |||
115 | if (flags & ACPI_EXECUTE_GTS) { | ||
116 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__GTS, sleep_state); | ||
117 | } | ||
118 | |||
119 | /* Get current value of PM1A control */ | 112 | /* Get current value of PM1A control */ |
120 | 113 | ||
121 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, | 114 | status = acpi_hw_register_read(ACPI_REGISTER_PM1_CONTROL, |
@@ -214,7 +207,6 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) | |||
214 | * FUNCTION: acpi_hw_legacy_wake_prep | 207 | * FUNCTION: acpi_hw_legacy_wake_prep |
215 | * | 208 | * |
216 | * PARAMETERS: sleep_state - Which sleep state we just exited | 209 | * PARAMETERS: sleep_state - Which sleep state we just exited |
217 | * flags - ACPI_EXECUTE_BFS to run optional method | ||
218 | * | 210 | * |
219 | * RETURN: Status | 211 | * RETURN: Status |
220 | * | 212 | * |
@@ -224,7 +216,7 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state, u8 flags) | |||
224 | * | 216 | * |
225 | ******************************************************************************/ | 217 | ******************************************************************************/ |
226 | 218 | ||
227 | acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags) | 219 | acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state) |
228 | { | 220 | { |
229 | acpi_status status; | 221 | acpi_status status; |
230 | struct acpi_bit_register_info *sleep_type_reg_info; | 222 | struct acpi_bit_register_info *sleep_type_reg_info; |
@@ -275,11 +267,6 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags) | |||
275 | } | 267 | } |
276 | } | 268 | } |
277 | 269 | ||
278 | /* Optionally execute _BFS (Back From Sleep) */ | ||
279 | |||
280 | if (flags & ACPI_EXECUTE_BFS) { | ||
281 | acpi_hw_execute_sleep_method(METHOD_PATHNAME__BFS, sleep_state); | ||
282 | } | ||
283 | return_ACPI_STATUS(status); | 270 | return_ACPI_STATUS(status); |
284 | } | 271 | } |
285 | 272 | ||
@@ -288,7 +275,6 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags) | |||
288 | * FUNCTION: acpi_hw_legacy_wake | 275 | * FUNCTION: acpi_hw_legacy_wake |
289 | * | 276 | * |
290 | * PARAMETERS: sleep_state - Which sleep state we just exited | 277 | * PARAMETERS: sleep_state - Which sleep state we just exited |
291 | * flags - Reserved, set to zero | ||
292 | * | 278 | * |
293 | * RETURN: Status | 279 | * RETURN: Status |
294 | * | 280 | * |
@@ -297,7 +283,7 @@ acpi_status acpi_hw_legacy_wake_prep(u8 sleep_state, u8 flags) | |||
297 | * | 283 | * |
298 | ******************************************************************************/ | 284 | ******************************************************************************/ |
299 | 285 | ||
300 | acpi_status acpi_hw_legacy_wake(u8 sleep_state, u8 flags) | 286 | acpi_status acpi_hw_legacy_wake(u8 sleep_state) |
301 | { | 287 | { |
302 | acpi_status status; | 288 | acpi_status status; |
303 | 289 | ||
diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c index f8684bfe7907..1f165a750ae2 100644 --- a/drivers/acpi/acpica/hwxfsleep.c +++ b/drivers/acpi/acpica/hwxfsleep.c | |||
@@ -50,7 +50,7 @@ ACPI_MODULE_NAME("hwxfsleep") | |||
50 | 50 | ||
51 | /* Local prototypes */ | 51 | /* Local prototypes */ |
52 | static acpi_status | 52 | static acpi_status |
53 | acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id); | 53 | acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id); |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * Dispatch table used to efficiently branch to the various sleep | 56 | * Dispatch table used to efficiently branch to the various sleep |
@@ -235,7 +235,7 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_s4bios) | |||
235 | * | 235 | * |
236 | ******************************************************************************/ | 236 | ******************************************************************************/ |
237 | static acpi_status | 237 | static acpi_status |
238 | acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id) | 238 | acpi_hw_sleep_dispatch(u8 sleep_state, u32 function_id) |
239 | { | 239 | { |
240 | acpi_status status; | 240 | acpi_status status; |
241 | struct acpi_sleep_functions *sleep_functions = | 241 | struct acpi_sleep_functions *sleep_functions = |
@@ -248,11 +248,11 @@ acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id) | |||
248 | * use the extended sleep registers | 248 | * use the extended sleep registers |
249 | */ | 249 | */ |
250 | if (acpi_gbl_reduced_hardware || acpi_gbl_FADT.sleep_control.address) { | 250 | if (acpi_gbl_reduced_hardware || acpi_gbl_FADT.sleep_control.address) { |
251 | status = sleep_functions->extended_function(sleep_state, flags); | 251 | status = sleep_functions->extended_function(sleep_state); |
252 | } else { | 252 | } else { |
253 | /* Legacy sleep */ | 253 | /* Legacy sleep */ |
254 | 254 | ||
255 | status = sleep_functions->legacy_function(sleep_state, flags); | 255 | status = sleep_functions->legacy_function(sleep_state); |
256 | } | 256 | } |
257 | 257 | ||
258 | return (status); | 258 | return (status); |
@@ -262,7 +262,7 @@ acpi_hw_sleep_dispatch(u8 sleep_state, u8 flags, u32 function_id) | |||
262 | * For the case where reduced-hardware-only code is being generated, | 262 | * For the case where reduced-hardware-only code is being generated, |
263 | * we know that only the extended sleep registers are available | 263 | * we know that only the extended sleep registers are available |
264 | */ | 264 | */ |
265 | status = sleep_functions->extended_function(sleep_state, flags); | 265 | status = sleep_functions->extended_function(sleep_state); |
266 | return (status); | 266 | return (status); |
267 | 267 | ||
268 | #endif /* !ACPI_REDUCED_HARDWARE */ | 268 | #endif /* !ACPI_REDUCED_HARDWARE */ |
@@ -349,7 +349,6 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) | |||
349 | * FUNCTION: acpi_enter_sleep_state | 349 | * FUNCTION: acpi_enter_sleep_state |
350 | * | 350 | * |
351 | * PARAMETERS: sleep_state - Which sleep state to enter | 351 | * PARAMETERS: sleep_state - Which sleep state to enter |
352 | * flags - ACPI_EXECUTE_GTS to run optional method | ||
353 | * | 352 | * |
354 | * RETURN: Status | 353 | * RETURN: Status |
355 | * | 354 | * |
@@ -357,7 +356,7 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state_prep) | |||
357 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED | 356 | * THIS FUNCTION MUST BE CALLED WITH INTERRUPTS DISABLED |
358 | * | 357 | * |
359 | ******************************************************************************/ | 358 | ******************************************************************************/ |
360 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state, u8 flags) | 359 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) |
361 | { | 360 | { |
362 | acpi_status status; | 361 | acpi_status status; |
363 | 362 | ||
@@ -371,7 +370,7 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state, u8 flags) | |||
371 | } | 370 | } |
372 | 371 | ||
373 | status = | 372 | status = |
374 | acpi_hw_sleep_dispatch(sleep_state, flags, ACPI_SLEEP_FUNCTION_ID); | 373 | acpi_hw_sleep_dispatch(sleep_state, ACPI_SLEEP_FUNCTION_ID); |
375 | return_ACPI_STATUS(status); | 374 | return_ACPI_STATUS(status); |
376 | } | 375 | } |
377 | 376 | ||
@@ -391,14 +390,14 @@ ACPI_EXPORT_SYMBOL(acpi_enter_sleep_state) | |||
391 | * Called with interrupts DISABLED. | 390 | * Called with interrupts DISABLED. |
392 | * | 391 | * |
393 | ******************************************************************************/ | 392 | ******************************************************************************/ |
394 | acpi_status acpi_leave_sleep_state_prep(u8 sleep_state, u8 flags) | 393 | acpi_status acpi_leave_sleep_state_prep(u8 sleep_state) |
395 | { | 394 | { |
396 | acpi_status status; | 395 | acpi_status status; |
397 | 396 | ||
398 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep); | 397 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state_prep); |
399 | 398 | ||
400 | status = | 399 | status = |
401 | acpi_hw_sleep_dispatch(sleep_state, flags, | 400 | acpi_hw_sleep_dispatch(sleep_state, |
402 | ACPI_WAKE_PREP_FUNCTION_ID); | 401 | ACPI_WAKE_PREP_FUNCTION_ID); |
403 | return_ACPI_STATUS(status); | 402 | return_ACPI_STATUS(status); |
404 | } | 403 | } |
@@ -423,8 +422,7 @@ acpi_status acpi_leave_sleep_state(u8 sleep_state) | |||
423 | 422 | ||
424 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); | 423 | ACPI_FUNCTION_TRACE(acpi_leave_sleep_state); |
425 | 424 | ||
426 | 425 | status = acpi_hw_sleep_dispatch(sleep_state, ACPI_WAKE_FUNCTION_ID); | |
427 | status = acpi_hw_sleep_dispatch(sleep_state, 0, ACPI_WAKE_FUNCTION_ID); | ||
428 | return_ACPI_STATUS(status); | 426 | return_ACPI_STATUS(status); |
429 | } | 427 | } |
430 | 428 | ||
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index ff2c876ec412..45e3e1759fb8 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -1052,6 +1052,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type) | |||
1052 | return 0; | 1052 | return 0; |
1053 | } | 1053 | } |
1054 | 1054 | ||
1055 | #ifdef CONFIG_PM_SLEEP | ||
1055 | /* this is needed to learn about changes made in suspended state */ | 1056 | /* this is needed to learn about changes made in suspended state */ |
1056 | static int acpi_battery_resume(struct device *dev) | 1057 | static int acpi_battery_resume(struct device *dev) |
1057 | { | 1058 | { |
@@ -1068,6 +1069,7 @@ static int acpi_battery_resume(struct device *dev) | |||
1068 | acpi_battery_update(battery); | 1069 | acpi_battery_update(battery); |
1069 | return 0; | 1070 | return 0; |
1070 | } | 1071 | } |
1072 | #endif | ||
1071 | 1073 | ||
1072 | static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume); | 1074 | static SIMPLE_DEV_PM_OPS(acpi_battery_pm, NULL, acpi_battery_resume); |
1073 | 1075 | ||
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 79d4c22f7a6d..314a3b84bbc7 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -78,7 +78,9 @@ static int acpi_button_add(struct acpi_device *device); | |||
78 | static int acpi_button_remove(struct acpi_device *device, int type); | 78 | static int acpi_button_remove(struct acpi_device *device, int type); |
79 | static void acpi_button_notify(struct acpi_device *device, u32 event); | 79 | static void acpi_button_notify(struct acpi_device *device, u32 event); |
80 | 80 | ||
81 | #ifdef CONFIG_PM_SLEEP | ||
81 | static int acpi_button_resume(struct device *dev); | 82 | static int acpi_button_resume(struct device *dev); |
83 | #endif | ||
82 | static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); | 84 | static SIMPLE_DEV_PM_OPS(acpi_button_pm, NULL, acpi_button_resume); |
83 | 85 | ||
84 | static struct acpi_driver acpi_button_driver = { | 86 | static struct acpi_driver acpi_button_driver = { |
@@ -310,6 +312,7 @@ static void acpi_button_notify(struct acpi_device *device, u32 event) | |||
310 | } | 312 | } |
311 | } | 313 | } |
312 | 314 | ||
315 | #ifdef CONFIG_PM_SLEEP | ||
313 | static int acpi_button_resume(struct device *dev) | 316 | static int acpi_button_resume(struct device *dev) |
314 | { | 317 | { |
315 | struct acpi_device *device = to_acpi_device(dev); | 318 | struct acpi_device *device = to_acpi_device(dev); |
@@ -319,6 +322,7 @@ static int acpi_button_resume(struct device *dev) | |||
319 | return acpi_lid_send_state(device); | 322 | return acpi_lid_send_state(device); |
320 | return 0; | 323 | return 0; |
321 | } | 324 | } |
325 | #endif | ||
322 | 326 | ||
323 | static int acpi_button_add(struct acpi_device *device) | 327 | static int acpi_button_add(struct acpi_device *device) |
324 | { | 328 | { |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 669d9ee80d16..bc36a476f1ab 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -53,8 +53,10 @@ static const struct acpi_device_id fan_device_ids[] = { | |||
53 | }; | 53 | }; |
54 | MODULE_DEVICE_TABLE(acpi, fan_device_ids); | 54 | MODULE_DEVICE_TABLE(acpi, fan_device_ids); |
55 | 55 | ||
56 | #ifdef CONFIG_PM_SLEEP | ||
56 | static int acpi_fan_suspend(struct device *dev); | 57 | static int acpi_fan_suspend(struct device *dev); |
57 | static int acpi_fan_resume(struct device *dev); | 58 | static int acpi_fan_resume(struct device *dev); |
59 | #endif | ||
58 | static SIMPLE_DEV_PM_OPS(acpi_fan_pm, acpi_fan_suspend, acpi_fan_resume); | 60 | static SIMPLE_DEV_PM_OPS(acpi_fan_pm, acpi_fan_suspend, acpi_fan_resume); |
59 | 61 | ||
60 | static struct acpi_driver acpi_fan_driver = { | 62 | static struct acpi_driver acpi_fan_driver = { |
@@ -184,6 +186,7 @@ static int acpi_fan_remove(struct acpi_device *device, int type) | |||
184 | return 0; | 186 | return 0; |
185 | } | 187 | } |
186 | 188 | ||
189 | #ifdef CONFIG_PM_SLEEP | ||
187 | static int acpi_fan_suspend(struct device *dev) | 190 | static int acpi_fan_suspend(struct device *dev) |
188 | { | 191 | { |
189 | if (!dev) | 192 | if (!dev) |
@@ -207,6 +210,7 @@ static int acpi_fan_resume(struct device *dev) | |||
207 | 210 | ||
208 | return result; | 211 | return result; |
209 | } | 212 | } |
213 | #endif | ||
210 | 214 | ||
211 | static int __init acpi_fan_init(void) | 215 | static int __init acpi_fan_init(void) |
212 | { | 216 | { |
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c index e56f3be7b07d..cb31298ca684 100644 --- a/drivers/acpi/numa.c +++ b/drivers/acpi/numa.c | |||
@@ -237,6 +237,8 @@ acpi_parse_processor_affinity(struct acpi_subtable_header *header, | |||
237 | return 0; | 237 | return 0; |
238 | } | 238 | } |
239 | 239 | ||
240 | static int __initdata parsed_numa_memblks; | ||
241 | |||
240 | static int __init | 242 | static int __init |
241 | acpi_parse_memory_affinity(struct acpi_subtable_header * header, | 243 | acpi_parse_memory_affinity(struct acpi_subtable_header * header, |
242 | const unsigned long end) | 244 | const unsigned long end) |
@@ -250,8 +252,8 @@ acpi_parse_memory_affinity(struct acpi_subtable_header * header, | |||
250 | acpi_table_print_srat_entry(header); | 252 | acpi_table_print_srat_entry(header); |
251 | 253 | ||
252 | /* let architecture-dependent part to do it */ | 254 | /* let architecture-dependent part to do it */ |
253 | acpi_numa_memory_affinity_init(memory_affinity); | 255 | if (!acpi_numa_memory_affinity_init(memory_affinity)) |
254 | 256 | parsed_numa_memblks++; | |
255 | return 0; | 257 | return 0; |
256 | } | 258 | } |
257 | 259 | ||
@@ -304,8 +306,10 @@ int __init acpi_numa_init(void) | |||
304 | 306 | ||
305 | acpi_numa_arch_fixup(); | 307 | acpi_numa_arch_fixup(); |
306 | 308 | ||
307 | if (cnt <= 0) | 309 | if (cnt < 0) |
308 | return cnt ?: -ENOENT; | 310 | return cnt; |
311 | else if (!parsed_numa_memblks) | ||
312 | return -ENOENT; | ||
309 | return 0; | 313 | return 0; |
310 | } | 314 | } |
311 | 315 | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index ec54014c321c..72a2c98bc429 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -573,8 +573,15 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
573 | OSC_CLOCK_PWR_CAPABILITY_SUPPORT; | 573 | OSC_CLOCK_PWR_CAPABILITY_SUPPORT; |
574 | if (pci_msi_enabled()) | 574 | if (pci_msi_enabled()) |
575 | flags |= OSC_MSI_SUPPORT; | 575 | flags |= OSC_MSI_SUPPORT; |
576 | if (flags != base_flags) | 576 | if (flags != base_flags) { |
577 | acpi_pci_osc_support(root, flags); | 577 | status = acpi_pci_osc_support(root, flags); |
578 | if (ACPI_FAILURE(status)) { | ||
579 | dev_info(root->bus->bridge, "ACPI _OSC support " | ||
580 | "notification failed, disabling PCIe ASPM\n"); | ||
581 | pcie_no_aspm(); | ||
582 | flags = base_flags; | ||
583 | } | ||
584 | } | ||
578 | 585 | ||
579 | if (!pcie_ports_disabled | 586 | if (!pcie_ports_disabled |
580 | && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { | 587 | && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 215ecd097408..fc1803414629 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -67,7 +67,9 @@ static const struct acpi_device_id power_device_ids[] = { | |||
67 | }; | 67 | }; |
68 | MODULE_DEVICE_TABLE(acpi, power_device_ids); | 68 | MODULE_DEVICE_TABLE(acpi, power_device_ids); |
69 | 69 | ||
70 | #ifdef CONFIG_PM_SLEEP | ||
70 | static int acpi_power_resume(struct device *dev); | 71 | static int acpi_power_resume(struct device *dev); |
72 | #endif | ||
71 | static SIMPLE_DEV_PM_OPS(acpi_power_pm, NULL, acpi_power_resume); | 73 | static SIMPLE_DEV_PM_OPS(acpi_power_pm, NULL, acpi_power_resume); |
72 | 74 | ||
73 | static struct acpi_driver acpi_power_driver = { | 75 | static struct acpi_driver acpi_power_driver = { |
@@ -775,6 +777,7 @@ static int acpi_power_remove(struct acpi_device *device, int type) | |||
775 | return 0; | 777 | return 0; |
776 | } | 778 | } |
777 | 779 | ||
780 | #ifdef CONFIG_PM_SLEEP | ||
778 | static int acpi_power_resume(struct device *dev) | 781 | static int acpi_power_resume(struct device *dev) |
779 | { | 782 | { |
780 | int result = 0, state; | 783 | int result = 0, state; |
@@ -803,6 +806,7 @@ static int acpi_power_resume(struct device *dev) | |||
803 | 806 | ||
804 | return result; | 807 | return result; |
805 | } | 808 | } |
809 | #endif | ||
806 | 810 | ||
807 | int __init acpi_power_init(void) | 811 | int __init acpi_power_init(void) |
808 | { | 812 | { |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index ff8e04f2fab4..bfc31cb0dd3e 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -437,7 +437,7 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, | |||
437 | /* Normal CPU soft online event */ | 437 | /* Normal CPU soft online event */ |
438 | } else { | 438 | } else { |
439 | acpi_processor_ppc_has_changed(pr, 0); | 439 | acpi_processor_ppc_has_changed(pr, 0); |
440 | acpi_processor_cst_has_changed(pr); | 440 | acpi_processor_hotplug(pr); |
441 | acpi_processor_reevaluate_tstate(pr, action); | 441 | acpi_processor_reevaluate_tstate(pr, action); |
442 | acpi_processor_tstate_has_changed(pr); | 442 | acpi_processor_tstate_has_changed(pr); |
443 | } | 443 | } |
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index c0b9aa5faf4c..ff0740e0a9c2 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -988,6 +988,7 @@ static void acpi_sbs_rmdirs(void) | |||
988 | #endif | 988 | #endif |
989 | } | 989 | } |
990 | 990 | ||
991 | #ifdef CONFIG_PM_SLEEP | ||
991 | static int acpi_sbs_resume(struct device *dev) | 992 | static int acpi_sbs_resume(struct device *dev) |
992 | { | 993 | { |
993 | struct acpi_sbs *sbs; | 994 | struct acpi_sbs *sbs; |
@@ -997,6 +998,7 @@ static int acpi_sbs_resume(struct device *dev) | |||
997 | acpi_sbs_callback(sbs); | 998 | acpi_sbs_callback(sbs); |
998 | return 0; | 999 | return 0; |
999 | } | 1000 | } |
1001 | #endif | ||
1000 | 1002 | ||
1001 | static SIMPLE_DEV_PM_OPS(acpi_sbs_pm, NULL, acpi_sbs_resume); | 1003 | static SIMPLE_DEV_PM_OPS(acpi_sbs_pm, NULL, acpi_sbs_resume); |
1002 | 1004 | ||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 7a7a9c929247..fdcdbb652915 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -28,36 +28,7 @@ | |||
28 | #include "internal.h" | 28 | #include "internal.h" |
29 | #include "sleep.h" | 29 | #include "sleep.h" |
30 | 30 | ||
31 | u8 wake_sleep_flags = ACPI_NO_OPTIONAL_METHODS; | ||
32 | static unsigned int gts, bfs; | ||
33 | static int set_param_wake_flag(const char *val, struct kernel_param *kp) | ||
34 | { | ||
35 | int ret = param_set_int(val, kp); | ||
36 | |||
37 | if (ret) | ||
38 | return ret; | ||
39 | |||
40 | if (kp->arg == (const char *)>s) { | ||
41 | if (gts) | ||
42 | wake_sleep_flags |= ACPI_EXECUTE_GTS; | ||
43 | else | ||
44 | wake_sleep_flags &= ~ACPI_EXECUTE_GTS; | ||
45 | } | ||
46 | if (kp->arg == (const char *)&bfs) { | ||
47 | if (bfs) | ||
48 | wake_sleep_flags |= ACPI_EXECUTE_BFS; | ||
49 | else | ||
50 | wake_sleep_flags &= ~ACPI_EXECUTE_BFS; | ||
51 | } | ||
52 | return ret; | ||
53 | } | ||
54 | module_param_call(gts, set_param_wake_flag, param_get_int, >s, 0644); | ||
55 | module_param_call(bfs, set_param_wake_flag, param_get_int, &bfs, 0644); | ||
56 | MODULE_PARM_DESC(gts, "Enable evaluation of _GTS on suspend."); | ||
57 | MODULE_PARM_DESC(bfs, "Enable evaluation of _BFS on resume".); | ||
58 | |||
59 | static u8 sleep_states[ACPI_S_STATE_COUNT]; | 31 | static u8 sleep_states[ACPI_S_STATE_COUNT]; |
60 | static bool pwr_btn_event_pending; | ||
61 | 32 | ||
62 | static void acpi_sleep_tts_switch(u32 acpi_state) | 33 | static void acpi_sleep_tts_switch(u32 acpi_state) |
63 | { | 34 | { |
@@ -110,6 +81,7 @@ static int acpi_sleep_prepare(u32 acpi_state) | |||
110 | 81 | ||
111 | #ifdef CONFIG_ACPI_SLEEP | 82 | #ifdef CONFIG_ACPI_SLEEP |
112 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; | 83 | static u32 acpi_target_sleep_state = ACPI_STATE_S0; |
84 | static bool pwr_btn_event_pending; | ||
113 | 85 | ||
114 | /* | 86 | /* |
115 | * The ACPI specification wants us to save NVS memory regions during hibernation | 87 | * The ACPI specification wants us to save NVS memory regions during hibernation |
@@ -305,7 +277,7 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
305 | switch (acpi_state) { | 277 | switch (acpi_state) { |
306 | case ACPI_STATE_S1: | 278 | case ACPI_STATE_S1: |
307 | barrier(); | 279 | barrier(); |
308 | status = acpi_enter_sleep_state(acpi_state, wake_sleep_flags); | 280 | status = acpi_enter_sleep_state(acpi_state); |
309 | break; | 281 | break; |
310 | 282 | ||
311 | case ACPI_STATE_S3: | 283 | case ACPI_STATE_S3: |
@@ -319,8 +291,8 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
319 | /* This violates the spec but is required for bug compatibility. */ | 291 | /* This violates the spec but is required for bug compatibility. */ |
320 | acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); | 292 | acpi_write_bit_register(ACPI_BITREG_SCI_ENABLE, 1); |
321 | 293 | ||
322 | /* Reprogram control registers and execute _BFS */ | 294 | /* Reprogram control registers */ |
323 | acpi_leave_sleep_state_prep(acpi_state, wake_sleep_flags); | 295 | acpi_leave_sleep_state_prep(acpi_state); |
324 | 296 | ||
325 | /* ACPI 3.0 specs (P62) says that it's the responsibility | 297 | /* ACPI 3.0 specs (P62) says that it's the responsibility |
326 | * of the OSPM to clear the status bit [ implying that the | 298 | * of the OSPM to clear the status bit [ implying that the |
@@ -603,9 +575,9 @@ static int acpi_hibernation_enter(void) | |||
603 | ACPI_FLUSH_CPU_CACHE(); | 575 | ACPI_FLUSH_CPU_CACHE(); |
604 | 576 | ||
605 | /* This shouldn't return. If it returns, we have a problem */ | 577 | /* This shouldn't return. If it returns, we have a problem */ |
606 | status = acpi_enter_sleep_state(ACPI_STATE_S4, wake_sleep_flags); | 578 | status = acpi_enter_sleep_state(ACPI_STATE_S4); |
607 | /* Reprogram control registers and execute _BFS */ | 579 | /* Reprogram control registers */ |
608 | acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags); | 580 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); |
609 | 581 | ||
610 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | 582 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
611 | } | 583 | } |
@@ -617,8 +589,8 @@ static void acpi_hibernation_leave(void) | |||
617 | * enable it here. | 589 | * enable it here. |
618 | */ | 590 | */ |
619 | acpi_enable(); | 591 | acpi_enable(); |
620 | /* Reprogram control registers and execute _BFS */ | 592 | /* Reprogram control registers */ |
621 | acpi_leave_sleep_state_prep(ACPI_STATE_S4, wake_sleep_flags); | 593 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); |
622 | /* Check the hardware signature */ | 594 | /* Check the hardware signature */ |
623 | if (facs && s4_hardware_signature != facs->hardware_signature) { | 595 | if (facs && s4_hardware_signature != facs->hardware_signature) { |
624 | printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " | 596 | printk(KERN_EMERG "ACPI: Hardware changed while hibernated, " |
@@ -892,33 +864,7 @@ static void acpi_power_off(void) | |||
892 | /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ | 864 | /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ |
893 | printk(KERN_DEBUG "%s called\n", __func__); | 865 | printk(KERN_DEBUG "%s called\n", __func__); |
894 | local_irq_disable(); | 866 | local_irq_disable(); |
895 | acpi_enter_sleep_state(ACPI_STATE_S5, wake_sleep_flags); | 867 | acpi_enter_sleep_state(ACPI_STATE_S5); |
896 | } | ||
897 | |||
898 | /* | ||
899 | * ACPI 2.0 created the optional _GTS and _BFS, | ||
900 | * but industry adoption has been neither rapid nor broad. | ||
901 | * | ||
902 | * Linux gets into trouble when it executes poorly validated | ||
903 | * paths through the BIOS, so disable _GTS and _BFS by default, | ||
904 | * but do speak up and offer the option to enable them. | ||
905 | */ | ||
906 | static void __init acpi_gts_bfs_check(void) | ||
907 | { | ||
908 | acpi_handle dummy; | ||
909 | |||
910 | if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__GTS, &dummy))) | ||
911 | { | ||
912 | printk(KERN_NOTICE PREFIX "BIOS offers _GTS\n"); | ||
913 | printk(KERN_NOTICE PREFIX "If \"acpi.gts=1\" improves suspend, " | ||
914 | "please notify linux-acpi@vger.kernel.org\n"); | ||
915 | } | ||
916 | if (ACPI_SUCCESS(acpi_get_handle(ACPI_ROOT_OBJECT, METHOD_PATHNAME__BFS, &dummy))) | ||
917 | { | ||
918 | printk(KERN_NOTICE PREFIX "BIOS offers _BFS\n"); | ||
919 | printk(KERN_NOTICE PREFIX "If \"acpi.bfs=1\" improves resume, " | ||
920 | "please notify linux-acpi@vger.kernel.org\n"); | ||
921 | } | ||
922 | } | 868 | } |
923 | 869 | ||
924 | int __init acpi_sleep_init(void) | 870 | int __init acpi_sleep_init(void) |
@@ -979,6 +925,5 @@ int __init acpi_sleep_init(void) | |||
979 | * object can also be evaluated when the system enters S5. | 925 | * object can also be evaluated when the system enters S5. |
980 | */ | 926 | */ |
981 | register_reboot_notifier(&tts_notifier); | 927 | register_reboot_notifier(&tts_notifier); |
982 | acpi_gts_bfs_check(); | ||
983 | return 0; | 928 | return 0; |
984 | } | 929 | } |
diff --git a/drivers/acpi/sysfs.c b/drivers/acpi/sysfs.c index 240a24400976..7c3f98ba4afe 100644 --- a/drivers/acpi/sysfs.c +++ b/drivers/acpi/sysfs.c | |||
@@ -173,7 +173,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) | |||
173 | { | 173 | { |
174 | int result = 0; | 174 | int result = 0; |
175 | 175 | ||
176 | if (!strncmp(val, "enable", strlen("enable"))) { | 176 | if (!strncmp(val, "enable", sizeof("enable") - 1)) { |
177 | result = acpi_debug_trace(trace_method_name, trace_debug_level, | 177 | result = acpi_debug_trace(trace_method_name, trace_debug_level, |
178 | trace_debug_layer, 0); | 178 | trace_debug_layer, 0); |
179 | if (result) | 179 | if (result) |
@@ -181,7 +181,7 @@ static int param_set_trace_state(const char *val, struct kernel_param *kp) | |||
181 | goto exit; | 181 | goto exit; |
182 | } | 182 | } |
183 | 183 | ||
184 | if (!strncmp(val, "disable", strlen("disable"))) { | 184 | if (!strncmp(val, "disable", sizeof("disable") - 1)) { |
185 | int name = 0; | 185 | int name = 0; |
186 | result = acpi_debug_trace((char *)&name, trace_debug_level, | 186 | result = acpi_debug_trace((char *)&name, trace_debug_level, |
187 | trace_debug_layer, 0); | 187 | trace_debug_layer, 0); |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 9fe90e9fecb5..edda74a43406 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -106,7 +106,9 @@ static const struct acpi_device_id thermal_device_ids[] = { | |||
106 | }; | 106 | }; |
107 | MODULE_DEVICE_TABLE(acpi, thermal_device_ids); | 107 | MODULE_DEVICE_TABLE(acpi, thermal_device_ids); |
108 | 108 | ||
109 | #ifdef CONFIG_PM_SLEEP | ||
109 | static int acpi_thermal_resume(struct device *dev); | 110 | static int acpi_thermal_resume(struct device *dev); |
111 | #endif | ||
110 | static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume); | 112 | static SIMPLE_DEV_PM_OPS(acpi_thermal_pm, NULL, acpi_thermal_resume); |
111 | 113 | ||
112 | static struct acpi_driver acpi_thermal_driver = { | 114 | static struct acpi_driver acpi_thermal_driver = { |
@@ -1041,6 +1043,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) | |||
1041 | return 0; | 1043 | return 0; |
1042 | } | 1044 | } |
1043 | 1045 | ||
1046 | #ifdef CONFIG_PM_SLEEP | ||
1044 | static int acpi_thermal_resume(struct device *dev) | 1047 | static int acpi_thermal_resume(struct device *dev) |
1045 | { | 1048 | { |
1046 | struct acpi_thermal *tz; | 1049 | struct acpi_thermal *tz; |
@@ -1075,6 +1078,7 @@ static int acpi_thermal_resume(struct device *dev) | |||
1075 | 1078 | ||
1076 | return AE_OK; | 1079 | return AE_OK; |
1077 | } | 1080 | } |
1081 | #endif | ||
1078 | 1082 | ||
1079 | static int thermal_act(const struct dmi_system_id *d) { | 1083 | static int thermal_act(const struct dmi_system_id *d) { |
1080 | 1084 | ||
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 24712adf69df..311be18d3f03 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
@@ -65,6 +65,8 @@ | |||
65 | #include <linux/mbus.h> | 65 | #include <linux/mbus.h> |
66 | #include <linux/bitops.h> | 66 | #include <linux/bitops.h> |
67 | #include <linux/gfp.h> | 67 | #include <linux/gfp.h> |
68 | #include <linux/of.h> | ||
69 | #include <linux/of_irq.h> | ||
68 | #include <scsi/scsi_host.h> | 70 | #include <scsi/scsi_host.h> |
69 | #include <scsi/scsi_cmnd.h> | 71 | #include <scsi/scsi_cmnd.h> |
70 | #include <scsi/scsi_device.h> | 72 | #include <scsi/scsi_device.h> |
@@ -4026,7 +4028,7 @@ static int mv_platform_probe(struct platform_device *pdev) | |||
4026 | struct ata_host *host; | 4028 | struct ata_host *host; |
4027 | struct mv_host_priv *hpriv; | 4029 | struct mv_host_priv *hpriv; |
4028 | struct resource *res; | 4030 | struct resource *res; |
4029 | int n_ports = 0; | 4031 | int n_ports = 0, irq = 0; |
4030 | int rc; | 4032 | int rc; |
4031 | #if defined(CONFIG_HAVE_CLK) | 4033 | #if defined(CONFIG_HAVE_CLK) |
4032 | int port; | 4034 | int port; |
@@ -4050,8 +4052,14 @@ static int mv_platform_probe(struct platform_device *pdev) | |||
4050 | return -EINVAL; | 4052 | return -EINVAL; |
4051 | 4053 | ||
4052 | /* allocate host */ | 4054 | /* allocate host */ |
4053 | mv_platform_data = pdev->dev.platform_data; | 4055 | if (pdev->dev.of_node) { |
4054 | n_ports = mv_platform_data->n_ports; | 4056 | of_property_read_u32(pdev->dev.of_node, "nr-ports", &n_ports); |
4057 | irq = irq_of_parse_and_map(pdev->dev.of_node, 0); | ||
4058 | } else { | ||
4059 | mv_platform_data = pdev->dev.platform_data; | ||
4060 | n_ports = mv_platform_data->n_ports; | ||
4061 | irq = platform_get_irq(pdev, 0); | ||
4062 | } | ||
4055 | 4063 | ||
4056 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); | 4064 | host = ata_host_alloc_pinfo(&pdev->dev, ppi, n_ports); |
4057 | hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); | 4065 | hpriv = devm_kzalloc(&pdev->dev, sizeof(*hpriv), GFP_KERNEL); |
@@ -4109,8 +4117,7 @@ static int mv_platform_probe(struct platform_device *pdev) | |||
4109 | dev_info(&pdev->dev, "slots %u ports %d\n", | 4117 | dev_info(&pdev->dev, "slots %u ports %d\n", |
4110 | (unsigned)MV_MAX_Q_DEPTH, host->n_ports); | 4118 | (unsigned)MV_MAX_Q_DEPTH, host->n_ports); |
4111 | 4119 | ||
4112 | rc = ata_host_activate(host, platform_get_irq(pdev, 0), mv_interrupt, | 4120 | rc = ata_host_activate(host, irq, mv_interrupt, IRQF_SHARED, &mv6_sht); |
4113 | IRQF_SHARED, &mv6_sht); | ||
4114 | if (!rc) | 4121 | if (!rc) |
4115 | return 0; | 4122 | return 0; |
4116 | 4123 | ||
@@ -4205,15 +4212,24 @@ static int mv_platform_resume(struct platform_device *pdev) | |||
4205 | #define mv_platform_resume NULL | 4212 | #define mv_platform_resume NULL |
4206 | #endif | 4213 | #endif |
4207 | 4214 | ||
4215 | #ifdef CONFIG_OF | ||
4216 | static struct of_device_id mv_sata_dt_ids[] __devinitdata = { | ||
4217 | { .compatible = "marvell,orion-sata", }, | ||
4218 | {}, | ||
4219 | }; | ||
4220 | MODULE_DEVICE_TABLE(of, mv_sata_dt_ids); | ||
4221 | #endif | ||
4222 | |||
4208 | static struct platform_driver mv_platform_driver = { | 4223 | static struct platform_driver mv_platform_driver = { |
4209 | .probe = mv_platform_probe, | 4224 | .probe = mv_platform_probe, |
4210 | .remove = __devexit_p(mv_platform_remove), | 4225 | .remove = __devexit_p(mv_platform_remove), |
4211 | .suspend = mv_platform_suspend, | 4226 | .suspend = mv_platform_suspend, |
4212 | .resume = mv_platform_resume, | 4227 | .resume = mv_platform_resume, |
4213 | .driver = { | 4228 | .driver = { |
4214 | .name = DRV_NAME, | 4229 | .name = DRV_NAME, |
4215 | .owner = THIS_MODULE, | 4230 | .owner = THIS_MODULE, |
4216 | }, | 4231 | .of_match_table = of_match_ptr(mv_sata_dt_ids), |
4232 | }, | ||
4217 | }; | 4233 | }; |
4218 | 4234 | ||
4219 | 4235 | ||
diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index d4386019af5d..96cce6d53195 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c | |||
@@ -2362,7 +2362,7 @@ static int __devinit ia_init(struct atm_dev *dev) | |||
2362 | { | 2362 | { |
2363 | printk(DEV_LABEL " (itf %d): can't set up page mapping\n", | 2363 | printk(DEV_LABEL " (itf %d): can't set up page mapping\n", |
2364 | dev->number); | 2364 | dev->number); |
2365 | return error; | 2365 | return -ENOMEM; |
2366 | } | 2366 | } |
2367 | IF_INIT(printk(DEV_LABEL " (itf %d): rev.%d,base=%p,irq=%d\n", | 2367 | IF_INIT(printk(DEV_LABEL " (itf %d): rev.%d,base=%p,irq=%d\n", |
2368 | dev->number, iadev->pci->revision, base, iadev->irq);) | 2368 | dev->number, iadev->pci->revision, base, iadev->irq);) |
diff --git a/drivers/base/core.c b/drivers/base/core.c index f338037a4f3d..5e6e00bc1652 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -1865,6 +1865,7 @@ int __dev_printk(const char *level, const struct device *dev, | |||
1865 | struct va_format *vaf) | 1865 | struct va_format *vaf) |
1866 | { | 1866 | { |
1867 | char dict[128]; | 1867 | char dict[128]; |
1868 | const char *level_extra = ""; | ||
1868 | size_t dictlen = 0; | 1869 | size_t dictlen = 0; |
1869 | const char *subsys; | 1870 | const char *subsys; |
1870 | 1871 | ||
@@ -1911,10 +1912,14 @@ int __dev_printk(const char *level, const struct device *dev, | |||
1911 | "DEVICE=+%s:%s", subsys, dev_name(dev)); | 1912 | "DEVICE=+%s:%s", subsys, dev_name(dev)); |
1912 | } | 1913 | } |
1913 | skip: | 1914 | skip: |
1915 | if (level[2]) | ||
1916 | level_extra = &level[2]; /* skip past KERN_SOH "L" */ | ||
1917 | |||
1914 | return printk_emit(0, level[1] - '0', | 1918 | return printk_emit(0, level[1] - '0', |
1915 | dictlen ? dict : NULL, dictlen, | 1919 | dictlen ? dict : NULL, dictlen, |
1916 | "%s %s: %pV", | 1920 | "%s %s: %s%pV", |
1917 | dev_driver_string(dev), dev_name(dev), vaf); | 1921 | dev_driver_string(dev), dev_name(dev), |
1922 | level_extra, vaf); | ||
1918 | } | 1923 | } |
1919 | EXPORT_SYMBOL(__dev_printk); | 1924 | EXPORT_SYMBOL(__dev_printk); |
1920 | 1925 | ||
diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index 869d7ff2227f..eb78e9640c4a 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c | |||
@@ -169,8 +169,7 @@ void pm_clk_init(struct device *dev) | |||
169 | */ | 169 | */ |
170 | int pm_clk_create(struct device *dev) | 170 | int pm_clk_create(struct device *dev) |
171 | { | 171 | { |
172 | int ret = dev_pm_get_subsys_data(dev); | 172 | return dev_pm_get_subsys_data(dev); |
173 | return ret < 0 ? ret : 0; | ||
174 | } | 173 | } |
175 | 174 | ||
176 | /** | 175 | /** |
diff --git a/drivers/base/power/common.c b/drivers/base/power/common.c index a14085cc613f..39c32529b833 100644 --- a/drivers/base/power/common.c +++ b/drivers/base/power/common.c | |||
@@ -24,7 +24,6 @@ | |||
24 | int dev_pm_get_subsys_data(struct device *dev) | 24 | int dev_pm_get_subsys_data(struct device *dev) |
25 | { | 25 | { |
26 | struct pm_subsys_data *psd; | 26 | struct pm_subsys_data *psd; |
27 | int ret = 0; | ||
28 | 27 | ||
29 | psd = kzalloc(sizeof(*psd), GFP_KERNEL); | 28 | psd = kzalloc(sizeof(*psd), GFP_KERNEL); |
30 | if (!psd) | 29 | if (!psd) |
@@ -40,7 +39,6 @@ int dev_pm_get_subsys_data(struct device *dev) | |||
40 | dev->power.subsys_data = psd; | 39 | dev->power.subsys_data = psd; |
41 | pm_clk_init(dev); | 40 | pm_clk_init(dev); |
42 | psd = NULL; | 41 | psd = NULL; |
43 | ret = 1; | ||
44 | } | 42 | } |
45 | 43 | ||
46 | spin_unlock_irq(&dev->power.lock); | 44 | spin_unlock_irq(&dev->power.lock); |
@@ -48,7 +46,7 @@ int dev_pm_get_subsys_data(struct device *dev) | |||
48 | /* kfree() verifies that its argument is nonzero. */ | 46 | /* kfree() verifies that its argument is nonzero. */ |
49 | kfree(psd); | 47 | kfree(psd); |
50 | 48 | ||
51 | return ret; | 49 | return 0; |
52 | } | 50 | } |
53 | EXPORT_SYMBOL_GPL(dev_pm_get_subsys_data); | 51 | EXPORT_SYMBOL_GPL(dev_pm_get_subsys_data); |
54 | 52 | ||
diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 59894873a3b3..7d9c1cb1c39a 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c | |||
@@ -147,6 +147,8 @@ static int rpm_check_suspend_allowed(struct device *dev) | |||
147 | || (dev->power.request_pending | 147 | || (dev->power.request_pending |
148 | && dev->power.request == RPM_REQ_RESUME)) | 148 | && dev->power.request == RPM_REQ_RESUME)) |
149 | retval = -EAGAIN; | 149 | retval = -EAGAIN; |
150 | else if (__dev_pm_qos_read_value(dev) < 0) | ||
151 | retval = -EPERM; | ||
150 | else if (dev->power.runtime_status == RPM_SUSPENDED) | 152 | else if (dev->power.runtime_status == RPM_SUSPENDED) |
151 | retval = 1; | 153 | retval = 1; |
152 | 154 | ||
@@ -388,7 +390,6 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
388 | goto repeat; | 390 | goto repeat; |
389 | } | 391 | } |
390 | 392 | ||
391 | dev->power.deferred_resume = false; | ||
392 | if (dev->power.no_callbacks) | 393 | if (dev->power.no_callbacks) |
393 | goto no_callback; /* Assume success. */ | 394 | goto no_callback; /* Assume success. */ |
394 | 395 | ||
@@ -403,12 +404,6 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
403 | goto out; | 404 | goto out; |
404 | } | 405 | } |
405 | 406 | ||
406 | if (__dev_pm_qos_read_value(dev) < 0) { | ||
407 | /* Negative PM QoS constraint means "never suspend". */ | ||
408 | retval = -EPERM; | ||
409 | goto out; | ||
410 | } | ||
411 | |||
412 | __update_runtime_status(dev, RPM_SUSPENDING); | 407 | __update_runtime_status(dev, RPM_SUSPENDING); |
413 | 408 | ||
414 | if (dev->pm_domain) | 409 | if (dev->pm_domain) |
@@ -440,6 +435,7 @@ static int rpm_suspend(struct device *dev, int rpmflags) | |||
440 | wake_up_all(&dev->power.wait_queue); | 435 | wake_up_all(&dev->power.wait_queue); |
441 | 436 | ||
442 | if (dev->power.deferred_resume) { | 437 | if (dev->power.deferred_resume) { |
438 | dev->power.deferred_resume = false; | ||
443 | rpm_resume(dev, 0); | 439 | rpm_resume(dev, 0); |
444 | retval = -EAGAIN; | 440 | retval = -EAGAIN; |
445 | goto out; | 441 | goto out; |
@@ -584,6 +580,7 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
584 | || dev->parent->power.runtime_status == RPM_ACTIVE) { | 580 | || dev->parent->power.runtime_status == RPM_ACTIVE) { |
585 | atomic_inc(&dev->parent->power.child_count); | 581 | atomic_inc(&dev->parent->power.child_count); |
586 | spin_unlock(&dev->parent->power.lock); | 582 | spin_unlock(&dev->parent->power.lock); |
583 | retval = 1; | ||
587 | goto no_callback; /* Assume success. */ | 584 | goto no_callback; /* Assume success. */ |
588 | } | 585 | } |
589 | spin_unlock(&dev->parent->power.lock); | 586 | spin_unlock(&dev->parent->power.lock); |
@@ -664,7 +661,7 @@ static int rpm_resume(struct device *dev, int rpmflags) | |||
664 | } | 661 | } |
665 | wake_up_all(&dev->power.wait_queue); | 662 | wake_up_all(&dev->power.wait_queue); |
666 | 663 | ||
667 | if (!retval) | 664 | if (retval >= 0) |
668 | rpm_idle(dev, RPM_ASYNC); | 665 | rpm_idle(dev, RPM_ASYNC); |
669 | 666 | ||
670 | out: | 667 | out: |
diff --git a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c index acda773b3720..38aa6dda6b81 100644 --- a/drivers/block/cciss_scsi.c +++ b/drivers/block/cciss_scsi.c | |||
@@ -763,16 +763,7 @@ static void complete_scsi_command(CommandList_struct *c, int timeout, | |||
763 | { | 763 | { |
764 | case CMD_TARGET_STATUS: | 764 | case CMD_TARGET_STATUS: |
765 | /* Pass it up to the upper layers... */ | 765 | /* Pass it up to the upper layers... */ |
766 | if( ei->ScsiStatus) | 766 | if (!ei->ScsiStatus) { |
767 | { | ||
768 | #if 0 | ||
769 | printk(KERN_WARNING "cciss: cmd %p " | ||
770 | "has SCSI Status = %x\n", | ||
771 | c, ei->ScsiStatus); | ||
772 | #endif | ||
773 | cmd->result |= (ei->ScsiStatus << 1); | ||
774 | } | ||
775 | else { /* scsi status is zero??? How??? */ | ||
776 | 767 | ||
777 | /* Ordinarily, this case should never happen, but there is a bug | 768 | /* Ordinarily, this case should never happen, but there is a bug |
778 | in some released firmware revisions that allows it to happen | 769 | in some released firmware revisions that allows it to happen |
diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 2e0e7fc1dbba..dbe6135a2abe 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c | |||
@@ -3537,9 +3537,9 @@ static void drbd_cleanup(void) | |||
3537 | } | 3537 | } |
3538 | 3538 | ||
3539 | /** | 3539 | /** |
3540 | * drbd_congested() - Callback for pdflush | 3540 | * drbd_congested() - Callback for the flusher thread |
3541 | * @congested_data: User data | 3541 | * @congested_data: User data |
3542 | * @bdi_bits: Bits pdflush is currently interested in | 3542 | * @bdi_bits: Bits the BDI flusher thread is currently interested in |
3543 | * | 3543 | * |
3544 | * Returns 1<<BDI_async_congested and/or 1<<BDI_sync_congested if we are congested. | 3544 | * Returns 1<<BDI_async_congested and/or 1<<BDI_sync_congested if we are congested. |
3545 | */ | 3545 | */ |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index 10308cd8a7ed..11f36e502136 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -79,6 +79,7 @@ static struct usb_device_id ath3k_table[] = { | |||
79 | { USB_DEVICE(0x13d3, 0x3362) }, | 79 | { USB_DEVICE(0x13d3, 0x3362) }, |
80 | { USB_DEVICE(0x0CF3, 0xE004) }, | 80 | { USB_DEVICE(0x0CF3, 0xE004) }, |
81 | { USB_DEVICE(0x0930, 0x0219) }, | 81 | { USB_DEVICE(0x0930, 0x0219) }, |
82 | { USB_DEVICE(0x0489, 0xe057) }, | ||
82 | 83 | ||
83 | /* Atheros AR5BBU12 with sflash firmware */ | 84 | /* Atheros AR5BBU12 with sflash firmware */ |
84 | { USB_DEVICE(0x0489, 0xE02C) }, | 85 | { USB_DEVICE(0x0489, 0xE02C) }, |
@@ -104,6 +105,7 @@ static struct usb_device_id ath3k_blist_tbl[] = { | |||
104 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, | 105 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, |
105 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, | 106 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, |
106 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, | 107 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, |
108 | { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, | ||
107 | 109 | ||
108 | /* Atheros AR5BBU22 with sflash firmware */ | 110 | /* Atheros AR5BBU22 with sflash firmware */ |
109 | { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, | 111 | { USB_DEVICE(0x0489, 0xE03C), .driver_info = BTUSB_ATH3012 }, |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index f637c2550016..fa2a7d5a6b43 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -98,6 +98,7 @@ static struct usb_device_id btusb_table[] = { | |||
98 | { USB_DEVICE(0x0a5c, 0x21e6) }, | 98 | { USB_DEVICE(0x0a5c, 0x21e6) }, |
99 | { USB_DEVICE(0x0a5c, 0x21e8) }, | 99 | { USB_DEVICE(0x0a5c, 0x21e8) }, |
100 | { USB_DEVICE(0x0a5c, 0x21f3) }, | 100 | { USB_DEVICE(0x0a5c, 0x21f3) }, |
101 | { USB_DEVICE(0x0a5c, 0x21f4) }, | ||
101 | { USB_DEVICE(0x413c, 0x8197) }, | 102 | { USB_DEVICE(0x413c, 0x8197) }, |
102 | 103 | ||
103 | /* Foxconn - Hon Hai */ | 104 | /* Foxconn - Hon Hai */ |
@@ -133,6 +134,7 @@ static struct usb_device_id blacklist_table[] = { | |||
133 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, | 134 | { USB_DEVICE(0x13d3, 0x3362), .driver_info = BTUSB_ATH3012 }, |
134 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, | 135 | { USB_DEVICE(0x0cf3, 0xe004), .driver_info = BTUSB_ATH3012 }, |
135 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, | 136 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, |
137 | { USB_DEVICE(0x0489, 0xe057), .driver_info = BTUSB_ATH3012 }, | ||
136 | 138 | ||
137 | /* Atheros AR5BBU12 with sflash firmware */ | 139 | /* Atheros AR5BBU12 with sflash firmware */ |
138 | { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, | 140 | { USB_DEVICE(0x0489, 0xe02c), .driver_info = BTUSB_IGNORE }, |
diff --git a/drivers/char/agp/intel-agp.h b/drivers/char/agp/intel-agp.h index 57226424690c..6f007b6c240d 100644 --- a/drivers/char/agp/intel-agp.h +++ b/drivers/char/agp/intel-agp.h | |||
@@ -239,16 +239,45 @@ | |||
239 | #define PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT2_IG 0x016A | 239 | #define PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_GT2_IG 0x016A |
240 | #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_HB 0x0F00 /* VLV1 */ | 240 | #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_HB 0x0F00 /* VLV1 */ |
241 | #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_IG 0x0F30 | 241 | #define PCI_DEVICE_ID_INTEL_VALLEYVIEW_IG 0x0F30 |
242 | #define PCI_DEVICE_ID_INTEL_HASWELL_HB 0x0400 /* Desktop */ | 242 | #define PCI_DEVICE_ID_INTEL_HASWELL_HB 0x0400 /* Desktop */ |
243 | #define PCI_DEVICE_ID_INTEL_HASWELL_D_GT1_IG 0x0402 | 243 | #define PCI_DEVICE_ID_INTEL_HASWELL_D_GT1_IG 0x0402 |
244 | #define PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_IG 0x0412 | 244 | #define PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_IG 0x0412 |
245 | #define PCI_DEVICE_ID_INTEL_HASWELL_M_HB 0x0404 /* Mobile */ | 245 | #define PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_PLUS_IG 0x0422 |
246 | #define PCI_DEVICE_ID_INTEL_HASWELL_M_HB 0x0404 /* Mobile */ | ||
246 | #define PCI_DEVICE_ID_INTEL_HASWELL_M_GT1_IG 0x0406 | 247 | #define PCI_DEVICE_ID_INTEL_HASWELL_M_GT1_IG 0x0406 |
247 | #define PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_IG 0x0416 | 248 | #define PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_IG 0x0416 |
248 | #define PCI_DEVICE_ID_INTEL_HASWELL_S_HB 0x0408 /* Server */ | 249 | #define PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_PLUS_IG 0x0426 |
250 | #define PCI_DEVICE_ID_INTEL_HASWELL_S_HB 0x0408 /* Server */ | ||
249 | #define PCI_DEVICE_ID_INTEL_HASWELL_S_GT1_IG 0x040a | 251 | #define PCI_DEVICE_ID_INTEL_HASWELL_S_GT1_IG 0x040a |
250 | #define PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_IG 0x041a | 252 | #define PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_IG 0x041a |
251 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV 0x0c16 /* SDV */ | 253 | #define PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_PLUS_IG 0x042a |
252 | #define PCI_DEVICE_ID_INTEL_HASWELL_E_HB 0x0c04 | 254 | #define PCI_DEVICE_ID_INTEL_HASWELL_E_HB 0x0c04 |
255 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT1_IG 0x0C02 | ||
256 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_IG 0x0C12 | ||
257 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_PLUS_IG 0x0C22 | ||
258 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT1_IG 0x0C06 | ||
259 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_IG 0x0C16 | ||
260 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_PLUS_IG 0x0C26 | ||
261 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT1_IG 0x0C0A | ||
262 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_IG 0x0C1A | ||
263 | #define PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_PLUS_IG 0x0C2A | ||
264 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT1_IG 0x0A02 | ||
265 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_IG 0x0A12 | ||
266 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_PLUS_IG 0x0A22 | ||
267 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT1_IG 0x0A06 | ||
268 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_IG 0x0A16 | ||
269 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_PLUS_IG 0x0A26 | ||
270 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT1_IG 0x0A0A | ||
271 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_IG 0x0A1A | ||
272 | #define PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_PLUS_IG 0x0A2A | ||
273 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT1_IG 0x0D12 | ||
274 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_IG 0x0D22 | ||
275 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_PLUS_IG 0x0D32 | ||
276 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT1_IG 0x0D16 | ||
277 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_IG 0x0D26 | ||
278 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_PLUS_IG 0x0D36 | ||
279 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT1_IG 0x0D1A | ||
280 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_IG 0x0D2A | ||
281 | #define PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_PLUS_IG 0x0D3A | ||
253 | 282 | ||
254 | #endif | 283 | #endif |
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 9ed92ef5829b..08fc5cbb13cd 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -1502,15 +1502,73 @@ static const struct intel_gtt_driver_description { | |||
1502 | "Haswell", &sandybridge_gtt_driver }, | 1502 | "Haswell", &sandybridge_gtt_driver }, |
1503 | { PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_IG, | 1503 | { PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_IG, |
1504 | "Haswell", &sandybridge_gtt_driver }, | 1504 | "Haswell", &sandybridge_gtt_driver }, |
1505 | { PCI_DEVICE_ID_INTEL_HASWELL_D_GT2_PLUS_IG, | ||
1506 | "Haswell", &sandybridge_gtt_driver }, | ||
1505 | { PCI_DEVICE_ID_INTEL_HASWELL_M_GT1_IG, | 1507 | { PCI_DEVICE_ID_INTEL_HASWELL_M_GT1_IG, |
1506 | "Haswell", &sandybridge_gtt_driver }, | 1508 | "Haswell", &sandybridge_gtt_driver }, |
1507 | { PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_IG, | 1509 | { PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_IG, |
1508 | "Haswell", &sandybridge_gtt_driver }, | 1510 | "Haswell", &sandybridge_gtt_driver }, |
1511 | { PCI_DEVICE_ID_INTEL_HASWELL_M_GT2_PLUS_IG, | ||
1512 | "Haswell", &sandybridge_gtt_driver }, | ||
1509 | { PCI_DEVICE_ID_INTEL_HASWELL_S_GT1_IG, | 1513 | { PCI_DEVICE_ID_INTEL_HASWELL_S_GT1_IG, |
1510 | "Haswell", &sandybridge_gtt_driver }, | 1514 | "Haswell", &sandybridge_gtt_driver }, |
1511 | { PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_IG, | 1515 | { PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_IG, |
1512 | "Haswell", &sandybridge_gtt_driver }, | 1516 | "Haswell", &sandybridge_gtt_driver }, |
1513 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV, | 1517 | { PCI_DEVICE_ID_INTEL_HASWELL_S_GT2_PLUS_IG, |
1518 | "Haswell", &sandybridge_gtt_driver }, | ||
1519 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT1_IG, | ||
1520 | "Haswell", &sandybridge_gtt_driver }, | ||
1521 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_IG, | ||
1522 | "Haswell", &sandybridge_gtt_driver }, | ||
1523 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_D_GT2_PLUS_IG, | ||
1524 | "Haswell", &sandybridge_gtt_driver }, | ||
1525 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT1_IG, | ||
1526 | "Haswell", &sandybridge_gtt_driver }, | ||
1527 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_IG, | ||
1528 | "Haswell", &sandybridge_gtt_driver }, | ||
1529 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_M_GT2_PLUS_IG, | ||
1530 | "Haswell", &sandybridge_gtt_driver }, | ||
1531 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT1_IG, | ||
1532 | "Haswell", &sandybridge_gtt_driver }, | ||
1533 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_IG, | ||
1534 | "Haswell", &sandybridge_gtt_driver }, | ||
1535 | { PCI_DEVICE_ID_INTEL_HASWELL_SDV_S_GT2_PLUS_IG, | ||
1536 | "Haswell", &sandybridge_gtt_driver }, | ||
1537 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT1_IG, | ||
1538 | "Haswell", &sandybridge_gtt_driver }, | ||
1539 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_IG, | ||
1540 | "Haswell", &sandybridge_gtt_driver }, | ||
1541 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_D_GT2_PLUS_IG, | ||
1542 | "Haswell", &sandybridge_gtt_driver }, | ||
1543 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT1_IG, | ||
1544 | "Haswell", &sandybridge_gtt_driver }, | ||
1545 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_IG, | ||
1546 | "Haswell", &sandybridge_gtt_driver }, | ||
1547 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_M_GT2_PLUS_IG, | ||
1548 | "Haswell", &sandybridge_gtt_driver }, | ||
1549 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT1_IG, | ||
1550 | "Haswell", &sandybridge_gtt_driver }, | ||
1551 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_IG, | ||
1552 | "Haswell", &sandybridge_gtt_driver }, | ||
1553 | { PCI_DEVICE_ID_INTEL_HASWELL_ULT_S_GT2_PLUS_IG, | ||
1554 | "Haswell", &sandybridge_gtt_driver }, | ||
1555 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT1_IG, | ||
1556 | "Haswell", &sandybridge_gtt_driver }, | ||
1557 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_IG, | ||
1558 | "Haswell", &sandybridge_gtt_driver }, | ||
1559 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_D_GT2_PLUS_IG, | ||
1560 | "Haswell", &sandybridge_gtt_driver }, | ||
1561 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT1_IG, | ||
1562 | "Haswell", &sandybridge_gtt_driver }, | ||
1563 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_IG, | ||
1564 | "Haswell", &sandybridge_gtt_driver }, | ||
1565 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_M_GT2_PLUS_IG, | ||
1566 | "Haswell", &sandybridge_gtt_driver }, | ||
1567 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT1_IG, | ||
1568 | "Haswell", &sandybridge_gtt_driver }, | ||
1569 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_IG, | ||
1570 | "Haswell", &sandybridge_gtt_driver }, | ||
1571 | { PCI_DEVICE_ID_INTEL_HASWELL_CRW_S_GT2_PLUS_IG, | ||
1514 | "Haswell", &sandybridge_gtt_driver }, | 1572 | "Haswell", &sandybridge_gtt_driver }, |
1515 | { 0, NULL, NULL } | 1573 | { 0, NULL, NULL } |
1516 | }; | 1574 | }; |
diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c index d706bd0e9e80..4fbdceb6f773 100644 --- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c | |||
@@ -160,7 +160,7 @@ static int __exit omap_rng_remove(struct platform_device *pdev) | |||
160 | return 0; | 160 | return 0; |
161 | } | 161 | } |
162 | 162 | ||
163 | #ifdef CONFIG_PM | 163 | #ifdef CONFIG_PM_SLEEP |
164 | 164 | ||
165 | static int omap_rng_suspend(struct device *dev) | 165 | static int omap_rng_suspend(struct device *dev) |
166 | { | 166 | { |
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 89682fa8801e..c4be3519a587 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c | |||
@@ -807,6 +807,7 @@ module_param_string(hid, tpm_pnp_tbl[TIS_HID_USR_IDX].id, | |||
807 | MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); | 807 | MODULE_PARM_DESC(hid, "Set additional specific HID for this driver to probe"); |
808 | #endif | 808 | #endif |
809 | 809 | ||
810 | #ifdef CONFIG_PM_SLEEP | ||
810 | static int tpm_tis_resume(struct device *dev) | 811 | static int tpm_tis_resume(struct device *dev) |
811 | { | 812 | { |
812 | struct tpm_chip *chip = dev_get_drvdata(dev); | 813 | struct tpm_chip *chip = dev_get_drvdata(dev); |
@@ -816,6 +817,7 @@ static int tpm_tis_resume(struct device *dev) | |||
816 | 817 | ||
817 | return tpm_pm_resume(dev); | 818 | return tpm_pm_resume(dev); |
818 | } | 819 | } |
820 | #endif | ||
819 | 821 | ||
820 | static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); | 822 | static SIMPLE_DEV_PM_OPS(tpm_tis_pm, tpm_pm_suspend, tpm_tis_resume); |
821 | 823 | ||
diff --git a/drivers/clocksource/cs5535-clockevt.c b/drivers/clocksource/cs5535-clockevt.c index 540795cd0760..d9279385304d 100644 --- a/drivers/clocksource/cs5535-clockevt.c +++ b/drivers/clocksource/cs5535-clockevt.c | |||
@@ -53,7 +53,7 @@ static struct cs5535_mfgpt_timer *cs5535_event_clock; | |||
53 | #define MFGPT_PERIODIC (MFGPT_HZ / HZ) | 53 | #define MFGPT_PERIODIC (MFGPT_HZ / HZ) |
54 | 54 | ||
55 | /* | 55 | /* |
56 | * The MFPGT timers on the CS5536 provide us with suitable timers to use | 56 | * The MFGPT timers on the CS5536 provide us with suitable timers to use |
57 | * as clock event sources - not as good as a HPET or APIC, but certainly | 57 | * as clock event sources - not as good as a HPET or APIC, but certainly |
58 | * better than the PIT. This isn't a general purpose MFGPT driver, but | 58 | * better than the PIT. This isn't a general purpose MFGPT driver, but |
59 | * a simplified one designed specifically to act as a clock event source. | 59 | * a simplified one designed specifically to act as a clock event source. |
@@ -144,7 +144,7 @@ static int __init cs5535_mfgpt_init(void) | |||
144 | 144 | ||
145 | timer = cs5535_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING); | 145 | timer = cs5535_mfgpt_alloc_timer(MFGPT_TIMER_ANY, MFGPT_DOMAIN_WORKING); |
146 | if (!timer) { | 146 | if (!timer) { |
147 | printk(KERN_ERR DRV_NAME ": Could not allocate MFPGT timer\n"); | 147 | printk(KERN_ERR DRV_NAME ": Could not allocate MFGPT timer\n"); |
148 | return -ENODEV; | 148 | return -ENODEV; |
149 | } | 149 | } |
150 | cs5535_event_clock = timer; | 150 | cs5535_event_clock = timer; |
diff --git a/drivers/cpufreq/pcc-cpufreq.c b/drivers/cpufreq/pcc-cpufreq.c index cdc02ac8f41a..503996a94a6a 100644 --- a/drivers/cpufreq/pcc-cpufreq.c +++ b/drivers/cpufreq/pcc-cpufreq.c | |||
@@ -454,6 +454,7 @@ static int __init pcc_cpufreq_probe(void) | |||
454 | mem_resource->address_length); | 454 | mem_resource->address_length); |
455 | if (pcch_virt_addr == NULL) { | 455 | if (pcch_virt_addr == NULL) { |
456 | pr_debug("probe: could not map shared mem region\n"); | 456 | pr_debug("probe: could not map shared mem region\n"); |
457 | ret = -ENOMEM; | ||
457 | goto out_free; | 458 | goto out_free; |
458 | } | 459 | } |
459 | pcch_hdr = pcch_virt_addr; | 460 | pcch_hdr = pcch_virt_addr; |
diff --git a/drivers/cpuidle/coupled.c b/drivers/cpuidle/coupled.c index 2c9bf2692232..3265844839bf 100644 --- a/drivers/cpuidle/coupled.c +++ b/drivers/cpuidle/coupled.c | |||
@@ -678,10 +678,22 @@ static int cpuidle_coupled_cpu_notify(struct notifier_block *nb, | |||
678 | int cpu = (unsigned long)hcpu; | 678 | int cpu = (unsigned long)hcpu; |
679 | struct cpuidle_device *dev; | 679 | struct cpuidle_device *dev; |
680 | 680 | ||
681 | switch (action & ~CPU_TASKS_FROZEN) { | ||
682 | case CPU_UP_PREPARE: | ||
683 | case CPU_DOWN_PREPARE: | ||
684 | case CPU_ONLINE: | ||
685 | case CPU_DEAD: | ||
686 | case CPU_UP_CANCELED: | ||
687 | case CPU_DOWN_FAILED: | ||
688 | break; | ||
689 | default: | ||
690 | return NOTIFY_OK; | ||
691 | } | ||
692 | |||
681 | mutex_lock(&cpuidle_lock); | 693 | mutex_lock(&cpuidle_lock); |
682 | 694 | ||
683 | dev = per_cpu(cpuidle_devices, cpu); | 695 | dev = per_cpu(cpuidle_devices, cpu); |
684 | if (!dev->coupled) | 696 | if (!dev || !dev->coupled) |
685 | goto out; | 697 | goto out; |
686 | 698 | ||
687 | switch (action & ~CPU_TASKS_FROZEN) { | 699 | switch (action & ~CPU_TASKS_FROZEN) { |
diff --git a/drivers/dma/imx-dma.c b/drivers/dma/imx-dma.c index fcfeb3cd8d31..5084975d793c 100644 --- a/drivers/dma/imx-dma.c +++ b/drivers/dma/imx-dma.c | |||
@@ -172,7 +172,8 @@ struct imxdma_engine { | |||
172 | struct device_dma_parameters dma_parms; | 172 | struct device_dma_parameters dma_parms; |
173 | struct dma_device dma_device; | 173 | struct dma_device dma_device; |
174 | void __iomem *base; | 174 | void __iomem *base; |
175 | struct clk *dma_clk; | 175 | struct clk *dma_ahb; |
176 | struct clk *dma_ipg; | ||
176 | spinlock_t lock; | 177 | spinlock_t lock; |
177 | struct imx_dma_2d_config slots_2d[IMX_DMA_2D_SLOTS]; | 178 | struct imx_dma_2d_config slots_2d[IMX_DMA_2D_SLOTS]; |
178 | struct imxdma_channel channel[IMX_DMA_CHANNELS]; | 179 | struct imxdma_channel channel[IMX_DMA_CHANNELS]; |
@@ -976,10 +977,20 @@ static int __init imxdma_probe(struct platform_device *pdev) | |||
976 | return 0; | 977 | return 0; |
977 | } | 978 | } |
978 | 979 | ||
979 | imxdma->dma_clk = clk_get(NULL, "dma"); | 980 | imxdma->dma_ipg = devm_clk_get(&pdev->dev, "ipg"); |
980 | if (IS_ERR(imxdma->dma_clk)) | 981 | if (IS_ERR(imxdma->dma_ipg)) { |
981 | return PTR_ERR(imxdma->dma_clk); | 982 | ret = PTR_ERR(imxdma->dma_ipg); |
982 | clk_enable(imxdma->dma_clk); | 983 | goto err_clk; |
984 | } | ||
985 | |||
986 | imxdma->dma_ahb = devm_clk_get(&pdev->dev, "ahb"); | ||
987 | if (IS_ERR(imxdma->dma_ahb)) { | ||
988 | ret = PTR_ERR(imxdma->dma_ahb); | ||
989 | goto err_clk; | ||
990 | } | ||
991 | |||
992 | clk_prepare_enable(imxdma->dma_ipg); | ||
993 | clk_prepare_enable(imxdma->dma_ahb); | ||
983 | 994 | ||
984 | /* reset DMA module */ | 995 | /* reset DMA module */ |
985 | imx_dmav1_writel(imxdma, DCR_DRST, DMA_DCR); | 996 | imx_dmav1_writel(imxdma, DCR_DRST, DMA_DCR); |
@@ -988,16 +999,14 @@ static int __init imxdma_probe(struct platform_device *pdev) | |||
988 | ret = request_irq(MX1_DMA_INT, dma_irq_handler, 0, "DMA", imxdma); | 999 | ret = request_irq(MX1_DMA_INT, dma_irq_handler, 0, "DMA", imxdma); |
989 | if (ret) { | 1000 | if (ret) { |
990 | dev_warn(imxdma->dev, "Can't register IRQ for DMA\n"); | 1001 | dev_warn(imxdma->dev, "Can't register IRQ for DMA\n"); |
991 | kfree(imxdma); | 1002 | goto err_enable; |
992 | return ret; | ||
993 | } | 1003 | } |
994 | 1004 | ||
995 | ret = request_irq(MX1_DMA_ERR, imxdma_err_handler, 0, "DMA", imxdma); | 1005 | ret = request_irq(MX1_DMA_ERR, imxdma_err_handler, 0, "DMA", imxdma); |
996 | if (ret) { | 1006 | if (ret) { |
997 | dev_warn(imxdma->dev, "Can't register ERRIRQ for DMA\n"); | 1007 | dev_warn(imxdma->dev, "Can't register ERRIRQ for DMA\n"); |
998 | free_irq(MX1_DMA_INT, NULL); | 1008 | free_irq(MX1_DMA_INT, NULL); |
999 | kfree(imxdma); | 1009 | goto err_enable; |
1000 | return ret; | ||
1001 | } | 1010 | } |
1002 | } | 1011 | } |
1003 | 1012 | ||
@@ -1094,7 +1103,10 @@ err_init: | |||
1094 | free_irq(MX1_DMA_INT, NULL); | 1103 | free_irq(MX1_DMA_INT, NULL); |
1095 | free_irq(MX1_DMA_ERR, NULL); | 1104 | free_irq(MX1_DMA_ERR, NULL); |
1096 | } | 1105 | } |
1097 | 1106 | err_enable: | |
1107 | clk_disable_unprepare(imxdma->dma_ipg); | ||
1108 | clk_disable_unprepare(imxdma->dma_ahb); | ||
1109 | err_clk: | ||
1098 | kfree(imxdma); | 1110 | kfree(imxdma); |
1099 | return ret; | 1111 | return ret; |
1100 | } | 1112 | } |
@@ -1114,7 +1126,9 @@ static int __exit imxdma_remove(struct platform_device *pdev) | |||
1114 | free_irq(MX1_DMA_ERR, NULL); | 1126 | free_irq(MX1_DMA_ERR, NULL); |
1115 | } | 1127 | } |
1116 | 1128 | ||
1117 | kfree(imxdma); | 1129 | clk_disable_unprepare(imxdma->dma_ipg); |
1130 | clk_disable_unprepare(imxdma->dma_ahb); | ||
1131 | kfree(imxdma); | ||
1118 | 1132 | ||
1119 | return 0; | 1133 | return 0; |
1120 | } | 1134 | } |
diff --git a/drivers/dma/sh/shdma-base.c b/drivers/dma/sh/shdma-base.c index 27f5c781fd73..f4cd946d259d 100644 --- a/drivers/dma/sh/shdma-base.c +++ b/drivers/dma/sh/shdma-base.c | |||
@@ -483,6 +483,7 @@ static struct shdma_desc *shdma_add_desc(struct shdma_chan *schan, | |||
483 | new->mark = DESC_PREPARED; | 483 | new->mark = DESC_PREPARED; |
484 | new->async_tx.flags = flags; | 484 | new->async_tx.flags = flags; |
485 | new->direction = direction; | 485 | new->direction = direction; |
486 | new->partial = 0; | ||
486 | 487 | ||
487 | *len -= copy_size; | 488 | *len -= copy_size; |
488 | if (direction == DMA_MEM_TO_MEM || direction == DMA_MEM_TO_DEV) | 489 | if (direction == DMA_MEM_TO_MEM || direction == DMA_MEM_TO_DEV) |
@@ -644,6 +645,14 @@ static int shdma_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd, | |||
644 | case DMA_TERMINATE_ALL: | 645 | case DMA_TERMINATE_ALL: |
645 | spin_lock_irqsave(&schan->chan_lock, flags); | 646 | spin_lock_irqsave(&schan->chan_lock, flags); |
646 | ops->halt_channel(schan); | 647 | ops->halt_channel(schan); |
648 | |||
649 | if (ops->get_partial && !list_empty(&schan->ld_queue)) { | ||
650 | /* Record partial transfer */ | ||
651 | struct shdma_desc *desc = list_first_entry(&schan->ld_queue, | ||
652 | struct shdma_desc, node); | ||
653 | desc->partial = ops->get_partial(schan, desc); | ||
654 | } | ||
655 | |||
647 | spin_unlock_irqrestore(&schan->chan_lock, flags); | 656 | spin_unlock_irqrestore(&schan->chan_lock, flags); |
648 | 657 | ||
649 | shdma_chan_ld_cleanup(schan, true); | 658 | shdma_chan_ld_cleanup(schan, true); |
diff --git a/drivers/dma/sh/shdma.c b/drivers/dma/sh/shdma.c index 027c9be97654..f41bcc5267fd 100644 --- a/drivers/dma/sh/shdma.c +++ b/drivers/dma/sh/shdma.c | |||
@@ -381,6 +381,17 @@ static bool sh_dmae_chan_irq(struct shdma_chan *schan, int irq) | |||
381 | return true; | 381 | return true; |
382 | } | 382 | } |
383 | 383 | ||
384 | static size_t sh_dmae_get_partial(struct shdma_chan *schan, | ||
385 | struct shdma_desc *sdesc) | ||
386 | { | ||
387 | struct sh_dmae_chan *sh_chan = container_of(schan, struct sh_dmae_chan, | ||
388 | shdma_chan); | ||
389 | struct sh_dmae_desc *sh_desc = container_of(sdesc, | ||
390 | struct sh_dmae_desc, shdma_desc); | ||
391 | return (sh_desc->hw.tcr - sh_dmae_readl(sh_chan, TCR)) << | ||
392 | sh_chan->xmit_shift; | ||
393 | } | ||
394 | |||
384 | /* Called from error IRQ or NMI */ | 395 | /* Called from error IRQ or NMI */ |
385 | static bool sh_dmae_reset(struct sh_dmae_device *shdev) | 396 | static bool sh_dmae_reset(struct sh_dmae_device *shdev) |
386 | { | 397 | { |
@@ -632,6 +643,7 @@ static const struct shdma_ops sh_dmae_shdma_ops = { | |||
632 | .start_xfer = sh_dmae_start_xfer, | 643 | .start_xfer = sh_dmae_start_xfer, |
633 | .embedded_desc = sh_dmae_embedded_desc, | 644 | .embedded_desc = sh_dmae_embedded_desc, |
634 | .chan_irq = sh_dmae_chan_irq, | 645 | .chan_irq = sh_dmae_chan_irq, |
646 | .get_partial = sh_dmae_get_partial, | ||
635 | }; | 647 | }; |
636 | 648 | ||
637 | static int __devinit sh_dmae_probe(struct platform_device *pdev) | 649 | static int __devinit sh_dmae_probe(struct platform_device *pdev) |
diff --git a/drivers/dma/tegra20-apb-dma.c b/drivers/dma/tegra20-apb-dma.c index d52dbc6c54ab..24acd711e032 100644 --- a/drivers/dma/tegra20-apb-dma.c +++ b/drivers/dma/tegra20-apb-dma.c | |||
@@ -1119,15 +1119,21 @@ struct dma_async_tx_descriptor *tegra_dma_prep_dma_cyclic( | |||
1119 | static int tegra_dma_alloc_chan_resources(struct dma_chan *dc) | 1119 | static int tegra_dma_alloc_chan_resources(struct dma_chan *dc) |
1120 | { | 1120 | { |
1121 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); | 1121 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); |
1122 | struct tegra_dma *tdma = tdc->tdma; | ||
1123 | int ret; | ||
1122 | 1124 | ||
1123 | dma_cookie_init(&tdc->dma_chan); | 1125 | dma_cookie_init(&tdc->dma_chan); |
1124 | tdc->config_init = false; | 1126 | tdc->config_init = false; |
1125 | return 0; | 1127 | ret = clk_prepare_enable(tdma->dma_clk); |
1128 | if (ret < 0) | ||
1129 | dev_err(tdc2dev(tdc), "clk_prepare_enable failed: %d\n", ret); | ||
1130 | return ret; | ||
1126 | } | 1131 | } |
1127 | 1132 | ||
1128 | static void tegra_dma_free_chan_resources(struct dma_chan *dc) | 1133 | static void tegra_dma_free_chan_resources(struct dma_chan *dc) |
1129 | { | 1134 | { |
1130 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); | 1135 | struct tegra_dma_channel *tdc = to_tegra_dma_chan(dc); |
1136 | struct tegra_dma *tdma = tdc->tdma; | ||
1131 | 1137 | ||
1132 | struct tegra_dma_desc *dma_desc; | 1138 | struct tegra_dma_desc *dma_desc; |
1133 | struct tegra_dma_sg_req *sg_req; | 1139 | struct tegra_dma_sg_req *sg_req; |
@@ -1163,6 +1169,7 @@ static void tegra_dma_free_chan_resources(struct dma_chan *dc) | |||
1163 | list_del(&sg_req->node); | 1169 | list_del(&sg_req->node); |
1164 | kfree(sg_req); | 1170 | kfree(sg_req); |
1165 | } | 1171 | } |
1172 | clk_disable_unprepare(tdma->dma_clk); | ||
1166 | } | 1173 | } |
1167 | 1174 | ||
1168 | /* Tegra20 specific DMA controller information */ | 1175 | /* Tegra20 specific DMA controller information */ |
@@ -1255,6 +1262,13 @@ static int __devinit tegra_dma_probe(struct platform_device *pdev) | |||
1255 | } | 1262 | } |
1256 | } | 1263 | } |
1257 | 1264 | ||
1265 | /* Enable clock before accessing registers */ | ||
1266 | ret = clk_prepare_enable(tdma->dma_clk); | ||
1267 | if (ret < 0) { | ||
1268 | dev_err(&pdev->dev, "clk_prepare_enable failed: %d\n", ret); | ||
1269 | goto err_pm_disable; | ||
1270 | } | ||
1271 | |||
1258 | /* Reset DMA controller */ | 1272 | /* Reset DMA controller */ |
1259 | tegra_periph_reset_assert(tdma->dma_clk); | 1273 | tegra_periph_reset_assert(tdma->dma_clk); |
1260 | udelay(2); | 1274 | udelay(2); |
@@ -1265,6 +1279,8 @@ static int __devinit tegra_dma_probe(struct platform_device *pdev) | |||
1265 | tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0); | 1279 | tdma_write(tdma, TEGRA_APBDMA_CONTROL, 0); |
1266 | tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul); | 1280 | tdma_write(tdma, TEGRA_APBDMA_IRQ_MASK_SET, 0xFFFFFFFFul); |
1267 | 1281 | ||
1282 | clk_disable_unprepare(tdma->dma_clk); | ||
1283 | |||
1268 | INIT_LIST_HEAD(&tdma->dma_dev.channels); | 1284 | INIT_LIST_HEAD(&tdma->dma_dev.channels); |
1269 | for (i = 0; i < cdata->nr_channels; i++) { | 1285 | for (i = 0; i < cdata->nr_channels; i++) { |
1270 | struct tegra_dma_channel *tdc = &tdma->channels[i]; | 1286 | struct tegra_dma_channel *tdc = &tdma->channels[i]; |
diff --git a/drivers/extcon/extcon_gpio.c b/drivers/extcon/extcon_gpio.c index fe3db45fa83c..3cc152e690b0 100644 --- a/drivers/extcon/extcon_gpio.c +++ b/drivers/extcon/extcon_gpio.c | |||
@@ -107,7 +107,8 @@ static int __devinit gpio_extcon_probe(struct platform_device *pdev) | |||
107 | if (ret < 0) | 107 | if (ret < 0) |
108 | return ret; | 108 | return ret; |
109 | 109 | ||
110 | ret = gpio_request_one(extcon_data->gpio, GPIOF_DIR_IN, pdev->name); | 110 | ret = devm_gpio_request_one(&pdev->dev, extcon_data->gpio, GPIOF_DIR_IN, |
111 | pdev->name); | ||
111 | if (ret < 0) | 112 | if (ret < 0) |
112 | goto err; | 113 | goto err; |
113 | 114 | ||
diff --git a/drivers/gpio/gpio-em.c b/drivers/gpio/gpio-em.c index 150d9768811d..ae37181798b3 100644 --- a/drivers/gpio/gpio-em.c +++ b/drivers/gpio/gpio-em.c | |||
@@ -266,7 +266,7 @@ static int __devinit em_gio_irq_domain_init(struct em_gio_priv *p) | |||
266 | return 0; | 266 | return 0; |
267 | } | 267 | } |
268 | 268 | ||
269 | static void __devexit em_gio_irq_domain_cleanup(struct em_gio_priv *p) | 269 | static void em_gio_irq_domain_cleanup(struct em_gio_priv *p) |
270 | { | 270 | { |
271 | struct gpio_em_config *pdata = p->pdev->dev.platform_data; | 271 | struct gpio_em_config *pdata = p->pdev->dev.platform_data; |
272 | 272 | ||
diff --git a/drivers/gpio/gpio-langwell.c b/drivers/gpio/gpio-langwell.c index a1c8754f52cf..202a99207b7d 100644 --- a/drivers/gpio/gpio-langwell.c +++ b/drivers/gpio/gpio-langwell.c | |||
@@ -339,7 +339,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, | |||
339 | resource_size_t start, len; | 339 | resource_size_t start, len; |
340 | struct lnw_gpio *lnw; | 340 | struct lnw_gpio *lnw; |
341 | u32 gpio_base; | 341 | u32 gpio_base; |
342 | int retval = 0; | 342 | int retval; |
343 | int ngpio = id->driver_data; | 343 | int ngpio = id->driver_data; |
344 | 344 | ||
345 | retval = pci_enable_device(pdev); | 345 | retval = pci_enable_device(pdev); |
@@ -357,6 +357,7 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, | |||
357 | base = ioremap_nocache(start, len); | 357 | base = ioremap_nocache(start, len); |
358 | if (!base) { | 358 | if (!base) { |
359 | dev_err(&pdev->dev, "error mapping bar1\n"); | 359 | dev_err(&pdev->dev, "error mapping bar1\n"); |
360 | retval = -EFAULT; | ||
360 | goto err3; | 361 | goto err3; |
361 | } | 362 | } |
362 | gpio_base = *((u32 *)base + 1); | 363 | gpio_base = *((u32 *)base + 1); |
@@ -381,8 +382,10 @@ static int __devinit lnw_gpio_probe(struct pci_dev *pdev, | |||
381 | 382 | ||
382 | lnw->domain = irq_domain_add_linear(pdev->dev.of_node, ngpio, | 383 | lnw->domain = irq_domain_add_linear(pdev->dev.of_node, ngpio, |
383 | &lnw_gpio_irq_ops, lnw); | 384 | &lnw_gpio_irq_ops, lnw); |
384 | if (!lnw->domain) | 385 | if (!lnw->domain) { |
386 | retval = -ENOMEM; | ||
385 | goto err3; | 387 | goto err3; |
388 | } | ||
386 | 389 | ||
387 | lnw->reg_base = base; | 390 | lnw->reg_base = base; |
388 | lnw->chip.label = dev_name(&pdev->dev); | 391 | lnw->chip.label = dev_name(&pdev->dev); |
diff --git a/drivers/gpio/gpio-msic.c b/drivers/gpio/gpio-msic.c index 71a838f44501..b38986285868 100644 --- a/drivers/gpio/gpio-msic.c +++ b/drivers/gpio/gpio-msic.c | |||
@@ -99,7 +99,7 @@ static int msic_gpio_to_oreg(unsigned offset) | |||
99 | if (offset < 20) | 99 | if (offset < 20) |
100 | return INTEL_MSIC_GPIO0HV0CTLO - offset + 16; | 100 | return INTEL_MSIC_GPIO0HV0CTLO - offset + 16; |
101 | 101 | ||
102 | return INTEL_MSIC_GPIO1HV0CTLO + offset + 20; | 102 | return INTEL_MSIC_GPIO1HV0CTLO - offset + 20; |
103 | } | 103 | } |
104 | 104 | ||
105 | static int msic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) | 105 | static int msic_gpio_direction_input(struct gpio_chip *chip, unsigned offset) |
diff --git a/drivers/gpio/gpio-mxc.c b/drivers/gpio/gpio-mxc.c index 4db460b6ecf7..80f44bb64a87 100644 --- a/drivers/gpio/gpio-mxc.c +++ b/drivers/gpio/gpio-mxc.c | |||
@@ -465,9 +465,8 @@ static int __devinit mxc_gpio_probe(struct platform_device *pdev) | |||
465 | goto out_iounmap; | 465 | goto out_iounmap; |
466 | 466 | ||
467 | port->bgc.gc.to_irq = mxc_gpio_to_irq; | 467 | port->bgc.gc.to_irq = mxc_gpio_to_irq; |
468 | port->bgc.gc.base = pdev->id * 32; | 468 | port->bgc.gc.base = (pdev->id < 0) ? of_alias_get_id(np, "gpio") * 32 : |
469 | port->bgc.dir = port->bgc.read_reg(port->bgc.reg_dir); | 469 | pdev->id * 32; |
470 | port->bgc.data = port->bgc.read_reg(port->bgc.reg_set); | ||
471 | 470 | ||
472 | err = gpiochip_add(&port->bgc.gc); | 471 | err = gpiochip_add(&port->bgc.gc); |
473 | if (err) | 472 | if (err) |
diff --git a/drivers/gpio/gpio-pxa.c b/drivers/gpio/gpio-pxa.c index 58a6a63a6ece..9cac88a65f78 100644 --- a/drivers/gpio/gpio-pxa.c +++ b/drivers/gpio/gpio-pxa.c | |||
@@ -62,6 +62,7 @@ int pxa_last_gpio; | |||
62 | 62 | ||
63 | #ifdef CONFIG_OF | 63 | #ifdef CONFIG_OF |
64 | static struct irq_domain *domain; | 64 | static struct irq_domain *domain; |
65 | static struct device_node *pxa_gpio_of_node; | ||
65 | #endif | 66 | #endif |
66 | 67 | ||
67 | struct pxa_gpio_chip { | 68 | struct pxa_gpio_chip { |
@@ -277,6 +278,24 @@ static void pxa_gpio_set(struct gpio_chip *chip, unsigned offset, int value) | |||
277 | (value ? GPSR_OFFSET : GPCR_OFFSET)); | 278 | (value ? GPSR_OFFSET : GPCR_OFFSET)); |
278 | } | 279 | } |
279 | 280 | ||
281 | #ifdef CONFIG_OF_GPIO | ||
282 | static int pxa_gpio_of_xlate(struct gpio_chip *gc, | ||
283 | const struct of_phandle_args *gpiospec, | ||
284 | u32 *flags) | ||
285 | { | ||
286 | if (gpiospec->args[0] > pxa_last_gpio) | ||
287 | return -EINVAL; | ||
288 | |||
289 | if (gc != &pxa_gpio_chips[gpiospec->args[0] / 32].chip) | ||
290 | return -EINVAL; | ||
291 | |||
292 | if (flags) | ||
293 | *flags = gpiospec->args[1]; | ||
294 | |||
295 | return gpiospec->args[0] % 32; | ||
296 | } | ||
297 | #endif | ||
298 | |||
280 | static int __devinit pxa_init_gpio_chip(int gpio_end, | 299 | static int __devinit pxa_init_gpio_chip(int gpio_end, |
281 | int (*set_wake)(unsigned int, unsigned int)) | 300 | int (*set_wake)(unsigned int, unsigned int)) |
282 | { | 301 | { |
@@ -304,6 +323,11 @@ static int __devinit pxa_init_gpio_chip(int gpio_end, | |||
304 | c->get = pxa_gpio_get; | 323 | c->get = pxa_gpio_get; |
305 | c->set = pxa_gpio_set; | 324 | c->set = pxa_gpio_set; |
306 | c->to_irq = pxa_gpio_to_irq; | 325 | c->to_irq = pxa_gpio_to_irq; |
326 | #ifdef CONFIG_OF_GPIO | ||
327 | c->of_node = pxa_gpio_of_node; | ||
328 | c->of_xlate = pxa_gpio_of_xlate; | ||
329 | c->of_gpio_n_cells = 2; | ||
330 | #endif | ||
307 | 331 | ||
308 | /* number of GPIOs on last bank may be less than 32 */ | 332 | /* number of GPIOs on last bank may be less than 32 */ |
309 | c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; | 333 | c->ngpio = (gpio + 31 > gpio_end) ? (gpio_end - gpio + 1) : 32; |
@@ -488,6 +512,7 @@ static int pxa_gpio_nums(void) | |||
488 | return count; | 512 | return count; |
489 | } | 513 | } |
490 | 514 | ||
515 | #ifdef CONFIG_OF | ||
491 | static struct of_device_id pxa_gpio_dt_ids[] = { | 516 | static struct of_device_id pxa_gpio_dt_ids[] = { |
492 | { .compatible = "mrvl,pxa-gpio" }, | 517 | { .compatible = "mrvl,pxa-gpio" }, |
493 | { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO }, | 518 | { .compatible = "mrvl,mmp-gpio", .data = (void *)MMP_GPIO }, |
@@ -505,9 +530,9 @@ static int pxa_irq_domain_map(struct irq_domain *d, unsigned int irq, | |||
505 | 530 | ||
506 | const struct irq_domain_ops pxa_irq_domain_ops = { | 531 | const struct irq_domain_ops pxa_irq_domain_ops = { |
507 | .map = pxa_irq_domain_map, | 532 | .map = pxa_irq_domain_map, |
533 | .xlate = irq_domain_xlate_twocell, | ||
508 | }; | 534 | }; |
509 | 535 | ||
510 | #ifdef CONFIG_OF | ||
511 | static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) | 536 | static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) |
512 | { | 537 | { |
513 | int ret, nr_banks, nr_gpios, irq_base; | 538 | int ret, nr_banks, nr_gpios, irq_base; |
@@ -545,6 +570,7 @@ static int __devinit pxa_gpio_probe_dt(struct platform_device *pdev) | |||
545 | } | 570 | } |
546 | domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0, | 571 | domain = irq_domain_add_legacy(np, nr_gpios, irq_base, 0, |
547 | &pxa_irq_domain_ops, NULL); | 572 | &pxa_irq_domain_ops, NULL); |
573 | pxa_gpio_of_node = np; | ||
548 | return 0; | 574 | return 0; |
549 | err: | 575 | err: |
550 | iounmap(gpio_reg_base); | 576 | iounmap(gpio_reg_base); |
@@ -653,7 +679,7 @@ static struct platform_driver pxa_gpio_driver = { | |||
653 | .probe = pxa_gpio_probe, | 679 | .probe = pxa_gpio_probe, |
654 | .driver = { | 680 | .driver = { |
655 | .name = "pxa-gpio", | 681 | .name = "pxa-gpio", |
656 | .of_match_table = pxa_gpio_dt_ids, | 682 | .of_match_table = of_match_ptr(pxa_gpio_dt_ids), |
657 | }, | 683 | }, |
658 | }; | 684 | }; |
659 | 685 | ||
diff --git a/drivers/gpio/gpio-samsung.c b/drivers/gpio/gpio-samsung.c index 92f7b2bb79d4..ba126cc04073 100644 --- a/drivers/gpio/gpio-samsung.c +++ b/drivers/gpio/gpio-samsung.c | |||
@@ -2454,12 +2454,6 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = { | |||
2454 | }, | 2454 | }, |
2455 | }, { | 2455 | }, { |
2456 | .chip = { | 2456 | .chip = { |
2457 | .base = EXYNOS5_GPC4(0), | ||
2458 | .ngpio = EXYNOS5_GPIO_C4_NR, | ||
2459 | .label = "GPC4", | ||
2460 | }, | ||
2461 | }, { | ||
2462 | .chip = { | ||
2463 | .base = EXYNOS5_GPD0(0), | 2457 | .base = EXYNOS5_GPD0(0), |
2464 | .ngpio = EXYNOS5_GPIO_D0_NR, | 2458 | .ngpio = EXYNOS5_GPIO_D0_NR, |
2465 | .label = "GPD0", | 2459 | .label = "GPD0", |
@@ -2513,6 +2507,12 @@ static struct samsung_gpio_chip exynos5_gpios_1[] = { | |||
2513 | .label = "GPY6", | 2507 | .label = "GPY6", |
2514 | }, | 2508 | }, |
2515 | }, { | 2509 | }, { |
2510 | .chip = { | ||
2511 | .base = EXYNOS5_GPC4(0), | ||
2512 | .ngpio = EXYNOS5_GPIO_C4_NR, | ||
2513 | .label = "GPC4", | ||
2514 | }, | ||
2515 | }, { | ||
2516 | .config = &samsung_gpio_cfgs[9], | 2516 | .config = &samsung_gpio_cfgs[9], |
2517 | .irq_base = IRQ_EINT(0), | 2517 | .irq_base = IRQ_EINT(0), |
2518 | .chip = { | 2518 | .chip = { |
@@ -2836,7 +2836,7 @@ static __init void exynos5_gpiolib_init(void) | |||
2836 | } | 2836 | } |
2837 | 2837 | ||
2838 | /* need to set base address for gpc4 */ | 2838 | /* need to set base address for gpc4 */ |
2839 | exynos5_gpios_1[11].base = gpio_base1 + 0x2E0; | 2839 | exynos5_gpios_1[20].base = gpio_base1 + 0x2E0; |
2840 | 2840 | ||
2841 | /* need to set base address for gpx */ | 2841 | /* need to set base address for gpx */ |
2842 | chip = &exynos5_gpios_1[21]; | 2842 | chip = &exynos5_gpios_1[21]; |
diff --git a/drivers/gpio/gpio-sch.c b/drivers/gpio/gpio-sch.c index 424dce8e3f30..8707d4572a06 100644 --- a/drivers/gpio/gpio-sch.c +++ b/drivers/gpio/gpio-sch.c | |||
@@ -241,7 +241,8 @@ static int __devinit sch_gpio_probe(struct platform_device *pdev) | |||
241 | break; | 241 | break; |
242 | 242 | ||
243 | default: | 243 | default: |
244 | return -ENODEV; | 244 | err = -ENODEV; |
245 | goto err_sch_gpio_core; | ||
245 | } | 246 | } |
246 | 247 | ||
247 | sch_gpio_core.dev = &pdev->dev; | 248 | sch_gpio_core.dev = &pdev->dev; |
diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index 23120c00a881..90e28081712d 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig | |||
@@ -22,6 +22,7 @@ menuconfig DRM | |||
22 | config DRM_USB | 22 | config DRM_USB |
23 | tristate | 23 | tristate |
24 | depends on DRM | 24 | depends on DRM |
25 | depends on USB_ARCH_HAS_HCD | ||
25 | select USB | 26 | select USB |
26 | 27 | ||
27 | config DRM_KMS_HELPER | 28 | config DRM_KMS_HELPER |
diff --git a/drivers/gpu/drm/drm_edid_load.c b/drivers/gpu/drm/drm_edid_load.c index 66d4a28ad5a2..0303935d10e2 100644 --- a/drivers/gpu/drm/drm_edid_load.c +++ b/drivers/gpu/drm/drm_edid_load.c | |||
@@ -119,7 +119,7 @@ static int edid_load(struct drm_connector *connector, char *name, | |||
119 | { | 119 | { |
120 | const struct firmware *fw; | 120 | const struct firmware *fw; |
121 | struct platform_device *pdev; | 121 | struct platform_device *pdev; |
122 | u8 *fwdata = NULL, *edid; | 122 | u8 *fwdata = NULL, *edid, *new_edid; |
123 | int fwsize, expected; | 123 | int fwsize, expected; |
124 | int builtin = 0, err = 0; | 124 | int builtin = 0, err = 0; |
125 | int i, valid_extensions = 0; | 125 | int i, valid_extensions = 0; |
@@ -195,12 +195,14 @@ static int edid_load(struct drm_connector *connector, char *name, | |||
195 | "\"%s\" for connector \"%s\"\n", valid_extensions, | 195 | "\"%s\" for connector \"%s\"\n", valid_extensions, |
196 | edid[0x7e], name, connector_name); | 196 | edid[0x7e], name, connector_name); |
197 | edid[0x7e] = valid_extensions; | 197 | edid[0x7e] = valid_extensions; |
198 | edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, | 198 | new_edid = krealloc(edid, (valid_extensions + 1) * EDID_LENGTH, |
199 | GFP_KERNEL); | 199 | GFP_KERNEL); |
200 | if (edid == NULL) { | 200 | if (new_edid == NULL) { |
201 | err = -ENOMEM; | 201 | err = -ENOMEM; |
202 | kfree(edid); | ||
202 | goto relfw_out; | 203 | goto relfw_out; |
203 | } | 204 | } |
205 | edid = new_edid; | ||
204 | } | 206 | } |
205 | 207 | ||
206 | connector->display_info.raw_edid = edid; | 208 | connector->display_info.raw_edid = edid; |
diff --git a/drivers/gpu/drm/i915/i915_drv.c b/drivers/gpu/drm/i915/i915_drv.c index ed22612bc847..a24ffbe97c01 100644 --- a/drivers/gpu/drm/i915/i915_drv.c +++ b/drivers/gpu/drm/i915/i915_drv.c | |||
@@ -346,11 +346,40 @@ static const struct pci_device_id pciidlist[] = { /* aka */ | |||
346 | INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ | 346 | INTEL_VGA_DEVICE(0x016a, &intel_ivybridge_d_info), /* GT2 server */ |
347 | INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */ | 347 | INTEL_VGA_DEVICE(0x0402, &intel_haswell_d_info), /* GT1 desktop */ |
348 | INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */ | 348 | INTEL_VGA_DEVICE(0x0412, &intel_haswell_d_info), /* GT2 desktop */ |
349 | INTEL_VGA_DEVICE(0x0422, &intel_haswell_d_info), /* GT2 desktop */ | ||
349 | INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */ | 350 | INTEL_VGA_DEVICE(0x040a, &intel_haswell_d_info), /* GT1 server */ |
350 | INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */ | 351 | INTEL_VGA_DEVICE(0x041a, &intel_haswell_d_info), /* GT2 server */ |
352 | INTEL_VGA_DEVICE(0x042a, &intel_haswell_d_info), /* GT2 server */ | ||
351 | INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */ | 353 | INTEL_VGA_DEVICE(0x0406, &intel_haswell_m_info), /* GT1 mobile */ |
352 | INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */ | 354 | INTEL_VGA_DEVICE(0x0416, &intel_haswell_m_info), /* GT2 mobile */ |
353 | INTEL_VGA_DEVICE(0x0c16, &intel_haswell_d_info), /* SDV */ | 355 | INTEL_VGA_DEVICE(0x0426, &intel_haswell_m_info), /* GT2 mobile */ |
356 | INTEL_VGA_DEVICE(0x0C02, &intel_haswell_d_info), /* SDV GT1 desktop */ | ||
357 | INTEL_VGA_DEVICE(0x0C12, &intel_haswell_d_info), /* SDV GT2 desktop */ | ||
358 | INTEL_VGA_DEVICE(0x0C22, &intel_haswell_d_info), /* SDV GT2 desktop */ | ||
359 | INTEL_VGA_DEVICE(0x0C0A, &intel_haswell_d_info), /* SDV GT1 server */ | ||
360 | INTEL_VGA_DEVICE(0x0C1A, &intel_haswell_d_info), /* SDV GT2 server */ | ||
361 | INTEL_VGA_DEVICE(0x0C2A, &intel_haswell_d_info), /* SDV GT2 server */ | ||
362 | INTEL_VGA_DEVICE(0x0C06, &intel_haswell_m_info), /* SDV GT1 mobile */ | ||
363 | INTEL_VGA_DEVICE(0x0C16, &intel_haswell_m_info), /* SDV GT2 mobile */ | ||
364 | INTEL_VGA_DEVICE(0x0C26, &intel_haswell_m_info), /* SDV GT2 mobile */ | ||
365 | INTEL_VGA_DEVICE(0x0A02, &intel_haswell_d_info), /* ULT GT1 desktop */ | ||
366 | INTEL_VGA_DEVICE(0x0A12, &intel_haswell_d_info), /* ULT GT2 desktop */ | ||
367 | INTEL_VGA_DEVICE(0x0A22, &intel_haswell_d_info), /* ULT GT2 desktop */ | ||
368 | INTEL_VGA_DEVICE(0x0A0A, &intel_haswell_d_info), /* ULT GT1 server */ | ||
369 | INTEL_VGA_DEVICE(0x0A1A, &intel_haswell_d_info), /* ULT GT2 server */ | ||
370 | INTEL_VGA_DEVICE(0x0A2A, &intel_haswell_d_info), /* ULT GT2 server */ | ||
371 | INTEL_VGA_DEVICE(0x0A06, &intel_haswell_m_info), /* ULT GT1 mobile */ | ||
372 | INTEL_VGA_DEVICE(0x0A16, &intel_haswell_m_info), /* ULT GT2 mobile */ | ||
373 | INTEL_VGA_DEVICE(0x0A26, &intel_haswell_m_info), /* ULT GT2 mobile */ | ||
374 | INTEL_VGA_DEVICE(0x0D12, &intel_haswell_d_info), /* CRW GT1 desktop */ | ||
375 | INTEL_VGA_DEVICE(0x0D22, &intel_haswell_d_info), /* CRW GT2 desktop */ | ||
376 | INTEL_VGA_DEVICE(0x0D32, &intel_haswell_d_info), /* CRW GT2 desktop */ | ||
377 | INTEL_VGA_DEVICE(0x0D1A, &intel_haswell_d_info), /* CRW GT1 server */ | ||
378 | INTEL_VGA_DEVICE(0x0D2A, &intel_haswell_d_info), /* CRW GT2 server */ | ||
379 | INTEL_VGA_DEVICE(0x0D3A, &intel_haswell_d_info), /* CRW GT2 server */ | ||
380 | INTEL_VGA_DEVICE(0x0D16, &intel_haswell_m_info), /* CRW GT1 mobile */ | ||
381 | INTEL_VGA_DEVICE(0x0D26, &intel_haswell_m_info), /* CRW GT2 mobile */ | ||
382 | INTEL_VGA_DEVICE(0x0D36, &intel_haswell_m_info), /* CRW GT2 mobile */ | ||
354 | INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), | 383 | INTEL_VGA_DEVICE(0x0f30, &intel_valleyview_m_info), |
355 | INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), | 384 | INTEL_VGA_DEVICE(0x0157, &intel_valleyview_m_info), |
356 | INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), | 385 | INTEL_VGA_DEVICE(0x0155, &intel_valleyview_d_info), |
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c index da8b01fb1bf8..a9d58d72bb4d 100644 --- a/drivers/gpu/drm/i915/i915_gem_context.c +++ b/drivers/gpu/drm/i915/i915_gem_context.c | |||
@@ -451,7 +451,6 @@ int i915_switch_context(struct intel_ring_buffer *ring, | |||
451 | struct drm_i915_file_private *file_priv = NULL; | 451 | struct drm_i915_file_private *file_priv = NULL; |
452 | struct i915_hw_context *to; | 452 | struct i915_hw_context *to; |
453 | struct drm_i915_gem_object *from_obj = ring->last_context_obj; | 453 | struct drm_i915_gem_object *from_obj = ring->last_context_obj; |
454 | int ret; | ||
455 | 454 | ||
456 | if (dev_priv->hw_contexts_disabled) | 455 | if (dev_priv->hw_contexts_disabled) |
457 | return 0; | 456 | return 0; |
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c index 5af631e788c8..ff2819ea0813 100644 --- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c +++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c | |||
@@ -291,6 +291,16 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
291 | target_i915_obj = to_intel_bo(target_obj); | 291 | target_i915_obj = to_intel_bo(target_obj); |
292 | target_offset = target_i915_obj->gtt_offset; | 292 | target_offset = target_i915_obj->gtt_offset; |
293 | 293 | ||
294 | /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and | ||
295 | * pipe_control writes because the gpu doesn't properly redirect them | ||
296 | * through the ppgtt for non_secure batchbuffers. */ | ||
297 | if (unlikely(IS_GEN6(dev) && | ||
298 | reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION && | ||
299 | !target_i915_obj->has_global_gtt_mapping)) { | ||
300 | i915_gem_gtt_bind_object(target_i915_obj, | ||
301 | target_i915_obj->cache_level); | ||
302 | } | ||
303 | |||
294 | /* The target buffer should have appeared before us in the | 304 | /* The target buffer should have appeared before us in the |
295 | * exec_object list, so it should have a GTT space bound by now. | 305 | * exec_object list, so it should have a GTT space bound by now. |
296 | */ | 306 | */ |
@@ -399,16 +409,6 @@ i915_gem_execbuffer_relocate_entry(struct drm_i915_gem_object *obj, | |||
399 | io_mapping_unmap_atomic(reloc_page); | 409 | io_mapping_unmap_atomic(reloc_page); |
400 | } | 410 | } |
401 | 411 | ||
402 | /* Sandybridge PPGTT errata: We need a global gtt mapping for MI and | ||
403 | * pipe_control writes because the gpu doesn't properly redirect them | ||
404 | * through the ppgtt for non_secure batchbuffers. */ | ||
405 | if (unlikely(IS_GEN6(dev) && | ||
406 | reloc->write_domain == I915_GEM_DOMAIN_INSTRUCTION && | ||
407 | !target_i915_obj->has_global_gtt_mapping)) { | ||
408 | i915_gem_gtt_bind_object(target_i915_obj, | ||
409 | target_i915_obj->cache_level); | ||
410 | } | ||
411 | |||
412 | /* and update the user's relocation entry */ | 412 | /* and update the user's relocation entry */ |
413 | reloc->presumed_offset = target_offset; | 413 | reloc->presumed_offset = target_offset; |
414 | 414 | ||
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 9fd25a435536..ee9b68f6bc36 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -361,7 +361,8 @@ int i915_gem_gtt_prepare_object(struct drm_i915_gem_object *obj) | |||
361 | struct drm_device *dev = obj->base.dev; | 361 | struct drm_device *dev = obj->base.dev; |
362 | struct drm_i915_private *dev_priv = dev->dev_private; | 362 | struct drm_i915_private *dev_priv = dev->dev_private; |
363 | 363 | ||
364 | if (dev_priv->mm.gtt->needs_dmar) | 364 | /* don't map imported dma buf objects */ |
365 | if (dev_priv->mm.gtt->needs_dmar && !obj->sg_table) | ||
365 | return intel_gtt_map_memory(obj->pages, | 366 | return intel_gtt_map_memory(obj->pages, |
366 | obj->base.size >> PAGE_SHIFT, | 367 | obj->base.size >> PAGE_SHIFT, |
367 | &obj->sg_list, | 368 | &obj->sg_list, |
diff --git a/drivers/gpu/drm/i915/i915_sysfs.c b/drivers/gpu/drm/i915/i915_sysfs.c index 2f5388af8df9..7631807a2788 100644 --- a/drivers/gpu/drm/i915/i915_sysfs.c +++ b/drivers/gpu/drm/i915/i915_sysfs.c | |||
@@ -32,6 +32,7 @@ | |||
32 | #include "intel_drv.h" | 32 | #include "intel_drv.h" |
33 | #include "i915_drv.h" | 33 | #include "i915_drv.h" |
34 | 34 | ||
35 | #ifdef CONFIG_PM | ||
35 | static u32 calc_residency(struct drm_device *dev, const u32 reg) | 36 | static u32 calc_residency(struct drm_device *dev, const u32 reg) |
36 | { | 37 | { |
37 | struct drm_i915_private *dev_priv = dev->dev_private; | 38 | struct drm_i915_private *dev_priv = dev->dev_private; |
@@ -224,3 +225,14 @@ void i915_teardown_sysfs(struct drm_device *dev) | |||
224 | device_remove_bin_file(&dev->primary->kdev, &dpf_attrs); | 225 | device_remove_bin_file(&dev->primary->kdev, &dpf_attrs); |
225 | sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group); | 226 | sysfs_unmerge_group(&dev->primary->kdev.kobj, &rc6_attr_group); |
226 | } | 227 | } |
228 | #else | ||
229 | void i915_setup_sysfs(struct drm_device *dev) | ||
230 | { | ||
231 | return; | ||
232 | } | ||
233 | |||
234 | void i915_teardown_sysfs(struct drm_device *dev) | ||
235 | { | ||
236 | return; | ||
237 | } | ||
238 | #endif /* CONFIG_PM */ | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index f6159765f1eb..a69a3d0d3acf 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -869,6 +869,7 @@ intel_vlv_find_best_pll(const intel_limit_t *limit, struct drm_crtc *crtc, | |||
869 | unsigned long bestppm, ppm, absppm; | 869 | unsigned long bestppm, ppm, absppm; |
870 | int dotclk, flag; | 870 | int dotclk, flag; |
871 | 871 | ||
872 | flag = 0; | ||
872 | dotclk = target * 1000; | 873 | dotclk = target * 1000; |
873 | bestppm = 1000000; | 874 | bestppm = 1000000; |
874 | ppm = absppm = 0; | 875 | ppm = absppm = 0; |
@@ -3753,17 +3754,6 @@ static bool intel_choose_pipe_bpp_dither(struct drm_crtc *crtc, | |||
3753 | continue; | 3754 | continue; |
3754 | } | 3755 | } |
3755 | 3756 | ||
3756 | if (intel_encoder->type == INTEL_OUTPUT_EDP) { | ||
3757 | /* Use VBT settings if we have an eDP panel */ | ||
3758 | unsigned int edp_bpc = dev_priv->edp.bpp / 3; | ||
3759 | |||
3760 | if (edp_bpc < display_bpc) { | ||
3761 | DRM_DEBUG_KMS("clamping display bpc (was %d) to eDP (%d)\n", display_bpc, edp_bpc); | ||
3762 | display_bpc = edp_bpc; | ||
3763 | } | ||
3764 | continue; | ||
3765 | } | ||
3766 | |||
3767 | /* Not one of the known troublemakers, check the EDID */ | 3757 | /* Not one of the known troublemakers, check the EDID */ |
3768 | list_for_each_entry(connector, &dev->mode_config.connector_list, | 3758 | list_for_each_entry(connector, &dev->mode_config.connector_list, |
3769 | head) { | 3759 | head) { |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index 0a56b9ab0f58..a6c426afaa7a 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -1174,10 +1174,14 @@ static void ironlake_edp_panel_off(struct intel_dp *intel_dp) | |||
1174 | WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); | 1174 | WARN(!intel_dp->want_panel_vdd, "Need VDD to turn off panel\n"); |
1175 | 1175 | ||
1176 | pp = ironlake_get_pp_control(dev_priv); | 1176 | pp = ironlake_get_pp_control(dev_priv); |
1177 | pp &= ~(POWER_TARGET_ON | PANEL_POWER_RESET | EDP_BLC_ENABLE); | 1177 | /* We need to switch off panel power _and_ force vdd, for otherwise some |
1178 | * panels get very unhappy and cease to work. */ | ||
1179 | pp &= ~(POWER_TARGET_ON | EDP_FORCE_VDD | PANEL_POWER_RESET | EDP_BLC_ENABLE); | ||
1178 | I915_WRITE(PCH_PP_CONTROL, pp); | 1180 | I915_WRITE(PCH_PP_CONTROL, pp); |
1179 | POSTING_READ(PCH_PP_CONTROL); | 1181 | POSTING_READ(PCH_PP_CONTROL); |
1180 | 1182 | ||
1183 | intel_dp->want_panel_vdd = false; | ||
1184 | |||
1181 | ironlake_wait_panel_off(intel_dp); | 1185 | ironlake_wait_panel_off(intel_dp); |
1182 | } | 1186 | } |
1183 | 1187 | ||
@@ -1287,11 +1291,9 @@ static void intel_dp_prepare(struct drm_encoder *encoder) | |||
1287 | * ensure that we have vdd while we switch off the panel. */ | 1291 | * ensure that we have vdd while we switch off the panel. */ |
1288 | ironlake_edp_panel_vdd_on(intel_dp); | 1292 | ironlake_edp_panel_vdd_on(intel_dp); |
1289 | ironlake_edp_backlight_off(intel_dp); | 1293 | ironlake_edp_backlight_off(intel_dp); |
1290 | ironlake_edp_panel_off(intel_dp); | ||
1291 | |||
1292 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); | 1294 | intel_dp_sink_dpms(intel_dp, DRM_MODE_DPMS_ON); |
1295 | ironlake_edp_panel_off(intel_dp); | ||
1293 | intel_dp_link_down(intel_dp); | 1296 | intel_dp_link_down(intel_dp); |
1294 | ironlake_edp_panel_vdd_off(intel_dp, false); | ||
1295 | } | 1297 | } |
1296 | 1298 | ||
1297 | static void intel_dp_commit(struct drm_encoder *encoder) | 1299 | static void intel_dp_commit(struct drm_encoder *encoder) |
@@ -1326,11 +1328,9 @@ intel_dp_dpms(struct drm_encoder *encoder, int mode) | |||
1326 | /* Switching the panel off requires vdd. */ | 1328 | /* Switching the panel off requires vdd. */ |
1327 | ironlake_edp_panel_vdd_on(intel_dp); | 1329 | ironlake_edp_panel_vdd_on(intel_dp); |
1328 | ironlake_edp_backlight_off(intel_dp); | 1330 | ironlake_edp_backlight_off(intel_dp); |
1329 | ironlake_edp_panel_off(intel_dp); | ||
1330 | |||
1331 | intel_dp_sink_dpms(intel_dp, mode); | 1331 | intel_dp_sink_dpms(intel_dp, mode); |
1332 | ironlake_edp_panel_off(intel_dp); | ||
1332 | intel_dp_link_down(intel_dp); | 1333 | intel_dp_link_down(intel_dp); |
1333 | ironlake_edp_panel_vdd_off(intel_dp, false); | ||
1334 | 1334 | ||
1335 | if (is_cpu_edp(intel_dp)) | 1335 | if (is_cpu_edp(intel_dp)) |
1336 | ironlake_edp_pll_off(encoder); | 1336 | ironlake_edp_pll_off(encoder); |
diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h index 84353559441c..132ab511b90c 100644 --- a/drivers/gpu/drm/i915/intel_drv.h +++ b/drivers/gpu/drm/i915/intel_drv.h | |||
@@ -46,15 +46,16 @@ | |||
46 | }) | 46 | }) |
47 | 47 | ||
48 | #define wait_for_atomic_us(COND, US) ({ \ | 48 | #define wait_for_atomic_us(COND, US) ({ \ |
49 | int i, ret__ = -ETIMEDOUT; \ | 49 | unsigned long timeout__ = jiffies + usecs_to_jiffies(US); \ |
50 | for (i = 0; i < (US); i++) { \ | 50 | int ret__ = 0; \ |
51 | if ((COND)) { \ | 51 | while (!(COND)) { \ |
52 | ret__ = 0; \ | 52 | if (time_after(jiffies, timeout__)) { \ |
53 | break; \ | 53 | ret__ = -ETIMEDOUT; \ |
54 | } \ | 54 | break; \ |
55 | udelay(1); \ | 55 | } \ |
56 | } \ | 56 | cpu_relax(); \ |
57 | ret__; \ | 57 | } \ |
58 | ret__; \ | ||
58 | }) | 59 | }) |
59 | 60 | ||
60 | #define wait_for(COND, MS) _wait_for(COND, MS, 1) | 61 | #define wait_for(COND, MS) _wait_for(COND, MS, 1) |
@@ -380,7 +381,6 @@ extern void intel_pch_panel_fitting(struct drm_device *dev, | |||
380 | const struct drm_display_mode *mode, | 381 | const struct drm_display_mode *mode, |
381 | struct drm_display_mode *adjusted_mode); | 382 | struct drm_display_mode *adjusted_mode); |
382 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); | 383 | extern u32 intel_panel_get_max_backlight(struct drm_device *dev); |
383 | extern u32 intel_panel_get_backlight(struct drm_device *dev); | ||
384 | extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); | 384 | extern void intel_panel_set_backlight(struct drm_device *dev, u32 level); |
385 | extern int intel_panel_setup_backlight(struct drm_device *dev); | 385 | extern int intel_panel_setup_backlight(struct drm_device *dev); |
386 | extern void intel_panel_enable_backlight(struct drm_device *dev, | 386 | extern void intel_panel_enable_backlight(struct drm_device *dev, |
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index 1991a4408cf9..b9755f6378d8 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -486,9 +486,6 @@ int intel_setup_gmbus(struct drm_device *dev) | |||
486 | bus->dev_priv = dev_priv; | 486 | bus->dev_priv = dev_priv; |
487 | 487 | ||
488 | bus->adapter.algo = &gmbus_algorithm; | 488 | bus->adapter.algo = &gmbus_algorithm; |
489 | ret = i2c_add_adapter(&bus->adapter); | ||
490 | if (ret) | ||
491 | goto err; | ||
492 | 489 | ||
493 | /* By default use a conservative clock rate */ | 490 | /* By default use a conservative clock rate */ |
494 | bus->reg0 = port | GMBUS_RATE_100KHZ; | 491 | bus->reg0 = port | GMBUS_RATE_100KHZ; |
@@ -498,6 +495,10 @@ int intel_setup_gmbus(struct drm_device *dev) | |||
498 | bus->force_bit = true; | 495 | bus->force_bit = true; |
499 | 496 | ||
500 | intel_gpio_setup(bus, port); | 497 | intel_gpio_setup(bus, port); |
498 | |||
499 | ret = i2c_add_adapter(&bus->adapter); | ||
500 | if (ret) | ||
501 | goto err; | ||
501 | } | 502 | } |
502 | 503 | ||
503 | intel_i2c_reset(dev_priv->dev); | 504 | intel_i2c_reset(dev_priv->dev); |
@@ -540,9 +541,6 @@ void intel_teardown_gmbus(struct drm_device *dev) | |||
540 | struct drm_i915_private *dev_priv = dev->dev_private; | 541 | struct drm_i915_private *dev_priv = dev->dev_private; |
541 | int i; | 542 | int i; |
542 | 543 | ||
543 | if (dev_priv->gmbus == NULL) | ||
544 | return; | ||
545 | |||
546 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { | 544 | for (i = 0; i < GMBUS_NUM_PORTS; i++) { |
547 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; | 545 | struct intel_gmbus *bus = &dev_priv->gmbus[i]; |
548 | i2c_del_adapter(&bus->adapter); | 546 | i2c_del_adapter(&bus->adapter); |
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c index 10c7d39034e1..3df4f5fa892a 100644 --- a/drivers/gpu/drm/i915/intel_panel.c +++ b/drivers/gpu/drm/i915/intel_panel.c | |||
@@ -213,7 +213,7 @@ static u32 intel_panel_compute_brightness(struct drm_device *dev, u32 val) | |||
213 | return val; | 213 | return val; |
214 | } | 214 | } |
215 | 215 | ||
216 | u32 intel_panel_get_backlight(struct drm_device *dev) | 216 | static u32 intel_panel_get_backlight(struct drm_device *dev) |
217 | { | 217 | { |
218 | struct drm_i915_private *dev_priv = dev->dev_private; | 218 | struct drm_i915_private *dev_priv = dev->dev_private; |
219 | u32 val; | 219 | u32 val; |
@@ -311,9 +311,6 @@ void intel_panel_enable_backlight(struct drm_device *dev, | |||
311 | if (dev_priv->backlight_level == 0) | 311 | if (dev_priv->backlight_level == 0) |
312 | dev_priv->backlight_level = intel_panel_get_max_backlight(dev); | 312 | dev_priv->backlight_level = intel_panel_get_max_backlight(dev); |
313 | 313 | ||
314 | dev_priv->backlight_enabled = true; | ||
315 | intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); | ||
316 | |||
317 | if (INTEL_INFO(dev)->gen >= 4) { | 314 | if (INTEL_INFO(dev)->gen >= 4) { |
318 | uint32_t reg, tmp; | 315 | uint32_t reg, tmp; |
319 | 316 | ||
@@ -326,7 +323,7 @@ void intel_panel_enable_backlight(struct drm_device *dev, | |||
326 | * we don't track the backlight dpms state, hence check whether | 323 | * we don't track the backlight dpms state, hence check whether |
327 | * we have to do anything first. */ | 324 | * we have to do anything first. */ |
328 | if (tmp & BLM_PWM_ENABLE) | 325 | if (tmp & BLM_PWM_ENABLE) |
329 | return; | 326 | goto set_level; |
330 | 327 | ||
331 | if (dev_priv->num_pipe == 3) | 328 | if (dev_priv->num_pipe == 3) |
332 | tmp &= ~BLM_PIPE_SELECT_IVB; | 329 | tmp &= ~BLM_PIPE_SELECT_IVB; |
@@ -347,6 +344,14 @@ void intel_panel_enable_backlight(struct drm_device *dev, | |||
347 | I915_WRITE(BLC_PWM_PCH_CTL1, tmp); | 344 | I915_WRITE(BLC_PWM_PCH_CTL1, tmp); |
348 | } | 345 | } |
349 | } | 346 | } |
347 | |||
348 | set_level: | ||
349 | /* Call below after setting BLC_PWM_CPU_CTL2 and BLC_PWM_PCH_CTL1. | ||
350 | * BLC_PWM_CPU_CTL may be cleared to zero automatically when these | ||
351 | * registers are set. | ||
352 | */ | ||
353 | dev_priv->backlight_enabled = true; | ||
354 | intel_panel_actually_set_backlight(dev, dev_priv->backlight_level); | ||
350 | } | 355 | } |
351 | 356 | ||
352 | static void intel_panel_init_backlight(struct drm_device *dev) | 357 | static void intel_panel_init_backlight(struct drm_device *dev) |
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c index 94aabcaa3a67..58c07cdafb7e 100644 --- a/drivers/gpu/drm/i915/intel_pm.c +++ b/drivers/gpu/drm/i915/intel_pm.c | |||
@@ -3963,6 +3963,7 @@ static void __gen6_gt_force_wake_get(struct drm_i915_private *dev_priv) | |||
3963 | DRM_ERROR("Force wake wait timed out\n"); | 3963 | DRM_ERROR("Force wake wait timed out\n"); |
3964 | 3964 | ||
3965 | I915_WRITE_NOTRACE(FORCEWAKE, 1); | 3965 | I915_WRITE_NOTRACE(FORCEWAKE, 1); |
3966 | POSTING_READ(FORCEWAKE); | ||
3966 | 3967 | ||
3967 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) | 3968 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) |
3968 | DRM_ERROR("Force wake wait timed out\n"); | 3969 | DRM_ERROR("Force wake wait timed out\n"); |
@@ -3983,6 +3984,7 @@ static void __gen6_gt_force_wake_mt_get(struct drm_i915_private *dev_priv) | |||
3983 | DRM_ERROR("Force wake wait timed out\n"); | 3984 | DRM_ERROR("Force wake wait timed out\n"); |
3984 | 3985 | ||
3985 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); | 3986 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_ENABLE(1)); |
3987 | POSTING_READ(FORCEWAKE_MT); | ||
3986 | 3988 | ||
3987 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) | 3989 | if (wait_for_atomic_us((I915_READ_NOTRACE(forcewake_ack) & 1), 500)) |
3988 | DRM_ERROR("Force wake wait timed out\n"); | 3990 | DRM_ERROR("Force wake wait timed out\n"); |
@@ -4018,14 +4020,14 @@ void gen6_gt_check_fifodbg(struct drm_i915_private *dev_priv) | |||
4018 | static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) | 4020 | static void __gen6_gt_force_wake_put(struct drm_i915_private *dev_priv) |
4019 | { | 4021 | { |
4020 | I915_WRITE_NOTRACE(FORCEWAKE, 0); | 4022 | I915_WRITE_NOTRACE(FORCEWAKE, 0); |
4021 | /* The below doubles as a POSTING_READ */ | 4023 | POSTING_READ(FORCEWAKE); |
4022 | gen6_gt_check_fifodbg(dev_priv); | 4024 | gen6_gt_check_fifodbg(dev_priv); |
4023 | } | 4025 | } |
4024 | 4026 | ||
4025 | static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) | 4027 | static void __gen6_gt_force_wake_mt_put(struct drm_i915_private *dev_priv) |
4026 | { | 4028 | { |
4027 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); | 4029 | I915_WRITE_NOTRACE(FORCEWAKE_MT, _MASKED_BIT_DISABLE(1)); |
4028 | /* The below doubles as a POSTING_READ */ | 4030 | POSTING_READ(FORCEWAKE_MT); |
4029 | gen6_gt_check_fifodbg(dev_priv); | 4031 | gen6_gt_check_fifodbg(dev_priv); |
4030 | } | 4032 | } |
4031 | 4033 | ||
diff --git a/drivers/gpu/drm/i915/intel_ringbuffer.c b/drivers/gpu/drm/i915/intel_ringbuffer.c index bf0195a96d53..e2a73b38abe9 100644 --- a/drivers/gpu/drm/i915/intel_ringbuffer.c +++ b/drivers/gpu/drm/i915/intel_ringbuffer.c | |||
@@ -227,31 +227,36 @@ gen6_render_ring_flush(struct intel_ring_buffer *ring, | |||
227 | * number of bits based on the write domains has little performance | 227 | * number of bits based on the write domains has little performance |
228 | * impact. | 228 | * impact. |
229 | */ | 229 | */ |
230 | flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; | 230 | if (flush_domains) { |
231 | flags |= PIPE_CONTROL_TLB_INVALIDATE; | 231 | flags |= PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH; |
232 | flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; | 232 | flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; |
233 | flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; | 233 | /* |
234 | flags |= PIPE_CONTROL_DEPTH_CACHE_FLUSH; | 234 | * Ensure that any following seqno writes only happen |
235 | flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; | 235 | * when the render cache is indeed flushed. |
236 | flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; | 236 | */ |
237 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; | ||
238 | /* | ||
239 | * Ensure that any following seqno writes only happen when the render | ||
240 | * cache is indeed flushed (but only if the caller actually wants that). | ||
241 | */ | ||
242 | if (flush_domains) | ||
243 | flags |= PIPE_CONTROL_CS_STALL; | 237 | flags |= PIPE_CONTROL_CS_STALL; |
238 | } | ||
239 | if (invalidate_domains) { | ||
240 | flags |= PIPE_CONTROL_TLB_INVALIDATE; | ||
241 | flags |= PIPE_CONTROL_INSTRUCTION_CACHE_INVALIDATE; | ||
242 | flags |= PIPE_CONTROL_TEXTURE_CACHE_INVALIDATE; | ||
243 | flags |= PIPE_CONTROL_VF_CACHE_INVALIDATE; | ||
244 | flags |= PIPE_CONTROL_CONST_CACHE_INVALIDATE; | ||
245 | flags |= PIPE_CONTROL_STATE_CACHE_INVALIDATE; | ||
246 | /* | ||
247 | * TLB invalidate requires a post-sync write. | ||
248 | */ | ||
249 | flags |= PIPE_CONTROL_QW_WRITE; | ||
250 | } | ||
244 | 251 | ||
245 | ret = intel_ring_begin(ring, 6); | 252 | ret = intel_ring_begin(ring, 4); |
246 | if (ret) | 253 | if (ret) |
247 | return ret; | 254 | return ret; |
248 | 255 | ||
249 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(5)); | 256 | intel_ring_emit(ring, GFX_OP_PIPE_CONTROL(4)); |
250 | intel_ring_emit(ring, flags); | 257 | intel_ring_emit(ring, flags); |
251 | intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); | 258 | intel_ring_emit(ring, scratch_addr | PIPE_CONTROL_GLOBAL_GTT); |
252 | intel_ring_emit(ring, 0); /* lower dword */ | 259 | intel_ring_emit(ring, 0); |
253 | intel_ring_emit(ring, 0); /* uppwer dword */ | ||
254 | intel_ring_emit(ring, MI_NOOP); | ||
255 | intel_ring_advance(ring); | 260 | intel_ring_advance(ring); |
256 | 261 | ||
257 | return 0; | 262 | return 0; |
@@ -289,8 +294,6 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
289 | I915_WRITE_HEAD(ring, 0); | 294 | I915_WRITE_HEAD(ring, 0); |
290 | ring->write_tail(ring, 0); | 295 | ring->write_tail(ring, 0); |
291 | 296 | ||
292 | /* Initialize the ring. */ | ||
293 | I915_WRITE_START(ring, obj->gtt_offset); | ||
294 | head = I915_READ_HEAD(ring) & HEAD_ADDR; | 297 | head = I915_READ_HEAD(ring) & HEAD_ADDR; |
295 | 298 | ||
296 | /* G45 ring initialization fails to reset head to zero */ | 299 | /* G45 ring initialization fails to reset head to zero */ |
@@ -316,6 +319,11 @@ static int init_ring_common(struct intel_ring_buffer *ring) | |||
316 | } | 319 | } |
317 | } | 320 | } |
318 | 321 | ||
322 | /* Initialize the ring. This must happen _after_ we've cleared the ring | ||
323 | * registers with the above sequence (the readback of the HEAD registers | ||
324 | * also enforces ordering), otherwise the hw might lose the new ring | ||
325 | * register values. */ | ||
326 | I915_WRITE_START(ring, obj->gtt_offset); | ||
319 | I915_WRITE_CTL(ring, | 327 | I915_WRITE_CTL(ring, |
320 | ((ring->size - PAGE_SIZE) & RING_NR_PAGES) | 328 | ((ring->size - PAGE_SIZE) & RING_NR_PAGES) |
321 | | RING_VALID); | 329 | | RING_VALID); |
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 26a6a4d0d078..d172e9873131 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -444,13 +444,16 @@ static bool intel_sdvo_write_cmd(struct intel_sdvo *intel_sdvo, u8 cmd, | |||
444 | struct i2c_msg *msgs; | 444 | struct i2c_msg *msgs; |
445 | int i, ret = true; | 445 | int i, ret = true; |
446 | 446 | ||
447 | /* Would be simpler to allocate both in one go ? */ | ||
447 | buf = (u8 *)kzalloc(args_len * 2 + 2, GFP_KERNEL); | 448 | buf = (u8 *)kzalloc(args_len * 2 + 2, GFP_KERNEL); |
448 | if (!buf) | 449 | if (!buf) |
449 | return false; | 450 | return false; |
450 | 451 | ||
451 | msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL); | 452 | msgs = kcalloc(args_len + 3, sizeof(*msgs), GFP_KERNEL); |
452 | if (!msgs) | 453 | if (!msgs) { |
454 | kfree(buf); | ||
453 | return false; | 455 | return false; |
456 | } | ||
454 | 457 | ||
455 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); | 458 | intel_sdvo_debug_write(intel_sdvo, cmd, args, args_len); |
456 | 459 | ||
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c index a4d7c500c97b..b69642d5d850 100644 --- a/drivers/gpu/drm/mgag200/mgag200_mode.c +++ b/drivers/gpu/drm/mgag200/mgag200_mode.c | |||
@@ -468,10 +468,11 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) | |||
468 | { | 468 | { |
469 | unsigned int vcomax, vcomin, pllreffreq; | 469 | unsigned int vcomax, vcomin, pllreffreq; |
470 | unsigned int delta, tmpdelta; | 470 | unsigned int delta, tmpdelta; |
471 | unsigned int testr, testn, testm, testo; | 471 | int testr, testn, testm, testo; |
472 | unsigned int p, m, n; | 472 | unsigned int p, m, n; |
473 | unsigned int computed; | 473 | unsigned int computed, vco; |
474 | int tmp; | 474 | int tmp; |
475 | const unsigned int m_div_val[] = { 1, 2, 4, 8 }; | ||
475 | 476 | ||
476 | m = n = p = 0; | 477 | m = n = p = 0; |
477 | vcomax = 1488000; | 478 | vcomax = 1488000; |
@@ -490,12 +491,13 @@ static int mga_g200er_set_plls(struct mga_device *mdev, long clock) | |||
490 | if (delta == 0) | 491 | if (delta == 0) |
491 | break; | 492 | break; |
492 | for (testo = 5; testo < 33; testo++) { | 493 | for (testo = 5; testo < 33; testo++) { |
493 | computed = pllreffreq * (testn + 1) / | 494 | vco = pllreffreq * (testn + 1) / |
494 | (testr + 1); | 495 | (testr + 1); |
495 | if (computed < vcomin) | 496 | if (vco < vcomin) |
496 | continue; | 497 | continue; |
497 | if (computed > vcomax) | 498 | if (vco > vcomax) |
498 | continue; | 499 | continue; |
500 | computed = vco / (m_div_val[testm] * (testo + 1)); | ||
499 | if (computed > clock) | 501 | if (computed > clock) |
500 | tmpdelta = computed - clock; | 502 | tmpdelta = computed - clock; |
501 | else | 503 | else |
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index fc841e87b343..26ebffebe710 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c | |||
@@ -211,11 +211,6 @@ static int nouveau_dsm_power_state(enum vga_switcheroo_client_id id, | |||
211 | return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); | 211 | return nouveau_dsm_set_discrete_state(nouveau_dsm_priv.dhandle, state); |
212 | } | 212 | } |
213 | 213 | ||
214 | static int nouveau_dsm_init(void) | ||
215 | { | ||
216 | return 0; | ||
217 | } | ||
218 | |||
219 | static int nouveau_dsm_get_client_id(struct pci_dev *pdev) | 214 | static int nouveau_dsm_get_client_id(struct pci_dev *pdev) |
220 | { | 215 | { |
221 | /* easy option one - intel vendor ID means Integrated */ | 216 | /* easy option one - intel vendor ID means Integrated */ |
@@ -232,7 +227,6 @@ static int nouveau_dsm_get_client_id(struct pci_dev *pdev) | |||
232 | static struct vga_switcheroo_handler nouveau_dsm_handler = { | 227 | static struct vga_switcheroo_handler nouveau_dsm_handler = { |
233 | .switchto = nouveau_dsm_switchto, | 228 | .switchto = nouveau_dsm_switchto, |
234 | .power_state = nouveau_dsm_power_state, | 229 | .power_state = nouveau_dsm_power_state, |
235 | .init = nouveau_dsm_init, | ||
236 | .get_client_id = nouveau_dsm_get_client_id, | 230 | .get_client_id = nouveau_dsm_get_client_id, |
237 | }; | 231 | }; |
238 | 232 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index 77e564667b5c..240cf962c999 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c | |||
@@ -229,7 +229,7 @@ nouveau_i2c_init(struct drm_device *dev) | |||
229 | } | 229 | } |
230 | break; | 230 | break; |
231 | case 6: /* NV50- DP AUX */ | 231 | case 6: /* NV50- DP AUX */ |
232 | port->drive = entry[0]; | 232 | port->drive = entry[0] & 0x0f; |
233 | port->sense = port->drive; | 233 | port->sense = port->drive; |
234 | port->adapter.algo = &nouveau_dp_i2c_algo; | 234 | port->adapter.algo = &nouveau_dp_i2c_algo; |
235 | break; | 235 | break; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index 1cdfd6e757ce..1866dbb49979 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -731,7 +731,6 @@ nouveau_card_init(struct drm_device *dev) | |||
731 | case 0xa3: | 731 | case 0xa3: |
732 | case 0xa5: | 732 | case 0xa5: |
733 | case 0xa8: | 733 | case 0xa8: |
734 | case 0xaf: | ||
735 | nva3_copy_create(dev); | 734 | nva3_copy_create(dev); |
736 | break; | 735 | break; |
737 | } | 736 | } |
diff --git a/drivers/gpu/drm/nouveau/nv84_fifo.c b/drivers/gpu/drm/nouveau/nv84_fifo.c index cc82d799fc3b..c564c5e4c30a 100644 --- a/drivers/gpu/drm/nouveau/nv84_fifo.c +++ b/drivers/gpu/drm/nouveau/nv84_fifo.c | |||
@@ -117,17 +117,22 @@ nv84_fifo_context_del(struct nouveau_channel *chan, int engine) | |||
117 | struct drm_device *dev = chan->dev; | 117 | struct drm_device *dev = chan->dev; |
118 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 118 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
119 | unsigned long flags; | 119 | unsigned long flags; |
120 | u32 save; | ||
120 | 121 | ||
121 | /* remove channel from playlist, will context switch if active */ | 122 | /* remove channel from playlist, will context switch if active */ |
122 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | 123 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); |
123 | nv_mask(dev, 0x002600 + (chan->id * 4), 0x80000000, 0x00000000); | 124 | nv_mask(dev, 0x002600 + (chan->id * 4), 0x80000000, 0x00000000); |
124 | nv50_fifo_playlist_update(dev); | 125 | nv50_fifo_playlist_update(dev); |
125 | 126 | ||
127 | save = nv_mask(dev, 0x002520, 0x0000003f, 0x15); | ||
128 | |||
126 | /* tell any engines on this channel to unload their contexts */ | 129 | /* tell any engines on this channel to unload their contexts */ |
127 | nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12); | 130 | nv_wr32(dev, 0x0032fc, chan->ramin->vinst >> 12); |
128 | if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff)) | 131 | if (!nv_wait_ne(dev, 0x0032fc, 0xffffffff, 0xffffffff)) |
129 | NV_INFO(dev, "PFIFO: channel %d unload timeout\n", chan->id); | 132 | NV_INFO(dev, "PFIFO: channel %d unload timeout\n", chan->id); |
130 | 133 | ||
134 | nv_wr32(dev, 0x002520, save); | ||
135 | |||
131 | nv_wr32(dev, 0x002600 + (chan->id * 4), 0x00000000); | 136 | nv_wr32(dev, 0x002600 + (chan->id * 4), 0x00000000); |
132 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | 137 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); |
133 | 138 | ||
@@ -184,10 +189,13 @@ nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend) | |||
184 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 189 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
185 | struct nv84_fifo_priv *priv = nv_engine(dev, engine); | 190 | struct nv84_fifo_priv *priv = nv_engine(dev, engine); |
186 | int i; | 191 | int i; |
192 | u32 save; | ||
187 | 193 | ||
188 | /* set playlist length to zero, fifo will unload context */ | 194 | /* set playlist length to zero, fifo will unload context */ |
189 | nv_wr32(dev, 0x0032ec, 0); | 195 | nv_wr32(dev, 0x0032ec, 0); |
190 | 196 | ||
197 | save = nv_mask(dev, 0x002520, 0x0000003f, 0x15); | ||
198 | |||
191 | /* tell all connected engines to unload their contexts */ | 199 | /* tell all connected engines to unload their contexts */ |
192 | for (i = 0; i < priv->base.channels; i++) { | 200 | for (i = 0; i < priv->base.channels; i++) { |
193 | struct nouveau_channel *chan = dev_priv->channels.ptr[i]; | 201 | struct nouveau_channel *chan = dev_priv->channels.ptr[i]; |
@@ -199,6 +207,7 @@ nv84_fifo_fini(struct drm_device *dev, int engine, bool suspend) | |||
199 | } | 207 | } |
200 | } | 208 | } |
201 | 209 | ||
210 | nv_wr32(dev, 0x002520, save); | ||
202 | nv_wr32(dev, 0x002140, 0); | 211 | nv_wr32(dev, 0x002140, 0); |
203 | return 0; | 212 | return 0; |
204 | } | 213 | } |
diff --git a/drivers/gpu/drm/nouveau/nvc0_pm.c b/drivers/gpu/drm/nouveau/nvc0_pm.c index 7c95c44e2887..4e712b10ebdb 100644 --- a/drivers/gpu/drm/nouveau/nvc0_pm.c +++ b/drivers/gpu/drm/nouveau/nvc0_pm.c | |||
@@ -557,7 +557,7 @@ prog_mem(struct drm_device *dev, struct nvc0_pm_state *info) | |||
557 | nouveau_mem_exec(&exec, info->perflvl); | 557 | nouveau_mem_exec(&exec, info->perflvl); |
558 | 558 | ||
559 | if (dev_priv->chipset < 0xd0) | 559 | if (dev_priv->chipset < 0xd0) |
560 | nv_wr32(dev, 0x611200, 0x00003300); | 560 | nv_wr32(dev, 0x611200, 0x00003330); |
561 | else | 561 | else |
562 | nv_wr32(dev, 0x62c000, 0x03030300); | 562 | nv_wr32(dev, 0x62c000, 0x03030300); |
563 | } | 563 | } |
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index d0d60e1e7f95..dac525b2994e 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c | |||
@@ -790,7 +790,7 @@ nvd0_crtc_cursor_move(struct drm_crtc *crtc, int x, int y) | |||
790 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 790 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
791 | int ch = EVO_CURS(nv_crtc->index); | 791 | int ch = EVO_CURS(nv_crtc->index); |
792 | 792 | ||
793 | evo_piow(crtc->dev, ch, 0x0084, (y << 16) | x); | 793 | evo_piow(crtc->dev, ch, 0x0084, (y << 16) | (x & 0xffff)); |
794 | evo_piow(crtc->dev, ch, 0x0080, 0x00000000); | 794 | evo_piow(crtc->dev, ch, 0x0080, 0x00000000); |
795 | return 0; | 795 | return 0; |
796 | } | 796 | } |
diff --git a/drivers/gpu/drm/nouveau/nve0_fifo.c b/drivers/gpu/drm/nouveau/nve0_fifo.c index 1855ecbd843b..e98d144e6eb9 100644 --- a/drivers/gpu/drm/nouveau/nve0_fifo.c +++ b/drivers/gpu/drm/nouveau/nve0_fifo.c | |||
@@ -294,6 +294,25 @@ nve0_fifo_isr_vm_fault(struct drm_device *dev, int unit) | |||
294 | printk(" on channel 0x%010llx\n", (u64)inst << 12); | 294 | printk(" on channel 0x%010llx\n", (u64)inst << 12); |
295 | } | 295 | } |
296 | 296 | ||
297 | static int | ||
298 | nve0_fifo_page_flip(struct drm_device *dev, u32 chid) | ||
299 | { | ||
300 | struct nve0_fifo_priv *priv = nv_engine(dev, NVOBJ_ENGINE_FIFO); | ||
301 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
302 | struct nouveau_channel *chan = NULL; | ||
303 | unsigned long flags; | ||
304 | int ret = -EINVAL; | ||
305 | |||
306 | spin_lock_irqsave(&dev_priv->channels.lock, flags); | ||
307 | if (likely(chid >= 0 && chid < priv->base.channels)) { | ||
308 | chan = dev_priv->channels.ptr[chid]; | ||
309 | if (likely(chan)) | ||
310 | ret = nouveau_finish_page_flip(chan, NULL); | ||
311 | } | ||
312 | spin_unlock_irqrestore(&dev_priv->channels.lock, flags); | ||
313 | return ret; | ||
314 | } | ||
315 | |||
297 | static void | 316 | static void |
298 | nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) | 317 | nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) |
299 | { | 318 | { |
@@ -303,11 +322,21 @@ nve0_fifo_isr_subfifo_intr(struct drm_device *dev, int unit) | |||
303 | u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f; | 322 | u32 chid = nv_rd32(dev, 0x040120 + (unit * 0x2000)) & 0x7f; |
304 | u32 subc = (addr & 0x00070000); | 323 | u32 subc = (addr & 0x00070000); |
305 | u32 mthd = (addr & 0x00003ffc); | 324 | u32 mthd = (addr & 0x00003ffc); |
325 | u32 show = stat; | ||
326 | |||
327 | if (stat & 0x00200000) { | ||
328 | if (mthd == 0x0054) { | ||
329 | if (!nve0_fifo_page_flip(dev, chid)) | ||
330 | show &= ~0x00200000; | ||
331 | } | ||
332 | } | ||
306 | 333 | ||
307 | NV_INFO(dev, "PSUBFIFO %d:", unit); | 334 | if (show) { |
308 | nouveau_bitfield_print(nve0_fifo_subfifo_intr, stat); | 335 | NV_INFO(dev, "PFIFO%d:", unit); |
309 | NV_INFO(dev, "PSUBFIFO %d: ch %d subc %d mthd 0x%04x data 0x%08x\n", | 336 | nouveau_bitfield_print(nve0_fifo_subfifo_intr, show); |
310 | unit, chid, subc, mthd, data); | 337 | NV_INFO(dev, "PFIFO%d: ch %d subc %d mthd 0x%04x data 0x%08x\n", |
338 | unit, chid, subc, mthd, data); | ||
339 | } | ||
311 | 340 | ||
312 | nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008); | 341 | nv_wr32(dev, 0x0400c0 + (unit * 0x2000), 0x80600008); |
313 | nv_wr32(dev, 0x040108 + (unit * 0x2000), stat); | 342 | nv_wr32(dev, 0x040108 + (unit * 0x2000), stat); |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 9e6f76fec527..c6fcb5b86a45 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -259,7 +259,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
259 | /* adjust pm to dpms changes BEFORE enabling crtcs */ | 259 | /* adjust pm to dpms changes BEFORE enabling crtcs */ |
260 | radeon_pm_compute_clocks(rdev); | 260 | radeon_pm_compute_clocks(rdev); |
261 | /* disable crtc pair power gating before programming */ | 261 | /* disable crtc pair power gating before programming */ |
262 | if (ASIC_IS_DCE6(rdev)) | 262 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) |
263 | atombios_powergate_crtc(crtc, ATOM_DISABLE); | 263 | atombios_powergate_crtc(crtc, ATOM_DISABLE); |
264 | atombios_enable_crtc(crtc, ATOM_ENABLE); | 264 | atombios_enable_crtc(crtc, ATOM_ENABLE); |
265 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) | 265 | if (ASIC_IS_DCE3(rdev) && !ASIC_IS_DCE6(rdev)) |
@@ -279,7 +279,7 @@ void atombios_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
279 | atombios_enable_crtc(crtc, ATOM_DISABLE); | 279 | atombios_enable_crtc(crtc, ATOM_DISABLE); |
280 | radeon_crtc->enabled = false; | 280 | radeon_crtc->enabled = false; |
281 | /* power gating is per-pair */ | 281 | /* power gating is per-pair */ |
282 | if (ASIC_IS_DCE6(rdev)) { | 282 | if (ASIC_IS_DCE6(rdev) && !radeon_crtc->in_mode_set) { |
283 | struct drm_crtc *other_crtc; | 283 | struct drm_crtc *other_crtc; |
284 | struct radeon_crtc *other_radeon_crtc; | 284 | struct radeon_crtc *other_radeon_crtc; |
285 | list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) { | 285 | list_for_each_entry(other_crtc, &rdev->ddev->mode_config.crtc_list, head) { |
@@ -1531,12 +1531,12 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1531 | * crtc virtual pixel clock. | 1531 | * crtc virtual pixel clock. |
1532 | */ | 1532 | */ |
1533 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { | 1533 | if (ENCODER_MODE_IS_DP(atombios_get_encoder_mode(test_encoder))) { |
1534 | if (ASIC_IS_DCE5(rdev)) | 1534 | if (rdev->clock.dp_extclk) |
1535 | return ATOM_DCPLL; | 1535 | return ATOM_PPLL_INVALID; |
1536 | else if (ASIC_IS_DCE6(rdev)) | 1536 | else if (ASIC_IS_DCE6(rdev)) |
1537 | return ATOM_PPLL0; | 1537 | return ATOM_PPLL0; |
1538 | else if (rdev->clock.dp_extclk) | 1538 | else if (ASIC_IS_DCE5(rdev)) |
1539 | return ATOM_PPLL_INVALID; | 1539 | return ATOM_DCPLL; |
1540 | } | 1540 | } |
1541 | } | 1541 | } |
1542 | } | 1542 | } |
@@ -1635,18 +1635,28 @@ static bool atombios_crtc_mode_fixup(struct drm_crtc *crtc, | |||
1635 | static void atombios_crtc_prepare(struct drm_crtc *crtc) | 1635 | static void atombios_crtc_prepare(struct drm_crtc *crtc) |
1636 | { | 1636 | { |
1637 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | 1637 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); |
1638 | struct drm_device *dev = crtc->dev; | ||
1639 | struct radeon_device *rdev = dev->dev_private; | ||
1638 | 1640 | ||
1641 | radeon_crtc->in_mode_set = true; | ||
1639 | /* pick pll */ | 1642 | /* pick pll */ |
1640 | radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); | 1643 | radeon_crtc->pll_id = radeon_atom_pick_pll(crtc); |
1641 | 1644 | ||
1645 | /* disable crtc pair power gating before programming */ | ||
1646 | if (ASIC_IS_DCE6(rdev)) | ||
1647 | atombios_powergate_crtc(crtc, ATOM_DISABLE); | ||
1648 | |||
1642 | atombios_lock_crtc(crtc, ATOM_ENABLE); | 1649 | atombios_lock_crtc(crtc, ATOM_ENABLE); |
1643 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); | 1650 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_OFF); |
1644 | } | 1651 | } |
1645 | 1652 | ||
1646 | static void atombios_crtc_commit(struct drm_crtc *crtc) | 1653 | static void atombios_crtc_commit(struct drm_crtc *crtc) |
1647 | { | 1654 | { |
1655 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
1656 | |||
1648 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); | 1657 | atombios_crtc_dpms(crtc, DRM_MODE_DPMS_ON); |
1649 | atombios_lock_crtc(crtc, ATOM_DISABLE); | 1658 | atombios_lock_crtc(crtc, ATOM_DISABLE); |
1659 | radeon_crtc->in_mode_set = false; | ||
1650 | } | 1660 | } |
1651 | 1661 | ||
1652 | static void atombios_crtc_disable(struct drm_crtc *crtc) | 1662 | static void atombios_crtc_disable(struct drm_crtc *crtc) |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index e585a3b947eb..e93b80a6d4e9 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -1229,24 +1229,8 @@ void evergreen_agp_enable(struct radeon_device *rdev) | |||
1229 | 1229 | ||
1230 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) | 1230 | void evergreen_mc_stop(struct radeon_device *rdev, struct evergreen_mc_save *save) |
1231 | { | 1231 | { |
1232 | save->vga_control[0] = RREG32(D1VGA_CONTROL); | ||
1233 | save->vga_control[1] = RREG32(D2VGA_CONTROL); | ||
1234 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); | 1232 | save->vga_render_control = RREG32(VGA_RENDER_CONTROL); |
1235 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); | 1233 | save->vga_hdp_control = RREG32(VGA_HDP_CONTROL); |
1236 | save->crtc_control[0] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET); | ||
1237 | save->crtc_control[1] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET); | ||
1238 | if (rdev->num_crtc >= 4) { | ||
1239 | save->vga_control[2] = RREG32(EVERGREEN_D3VGA_CONTROL); | ||
1240 | save->vga_control[3] = RREG32(EVERGREEN_D4VGA_CONTROL); | ||
1241 | save->crtc_control[2] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET); | ||
1242 | save->crtc_control[3] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET); | ||
1243 | } | ||
1244 | if (rdev->num_crtc >= 6) { | ||
1245 | save->vga_control[4] = RREG32(EVERGREEN_D5VGA_CONTROL); | ||
1246 | save->vga_control[5] = RREG32(EVERGREEN_D6VGA_CONTROL); | ||
1247 | save->crtc_control[4] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET); | ||
1248 | save->crtc_control[5] = RREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
1249 | } | ||
1250 | 1234 | ||
1251 | /* Stop all video */ | 1235 | /* Stop all video */ |
1252 | WREG32(VGA_RENDER_CONTROL, 0); | 1236 | WREG32(VGA_RENDER_CONTROL, 0); |
@@ -1357,47 +1341,6 @@ void evergreen_mc_resume(struct radeon_device *rdev, struct evergreen_mc_save *s | |||
1357 | /* Unlock host access */ | 1341 | /* Unlock host access */ |
1358 | WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); | 1342 | WREG32(VGA_HDP_CONTROL, save->vga_hdp_control); |
1359 | mdelay(1); | 1343 | mdelay(1); |
1360 | /* Restore video state */ | ||
1361 | WREG32(D1VGA_CONTROL, save->vga_control[0]); | ||
1362 | WREG32(D2VGA_CONTROL, save->vga_control[1]); | ||
1363 | if (rdev->num_crtc >= 4) { | ||
1364 | WREG32(EVERGREEN_D3VGA_CONTROL, save->vga_control[2]); | ||
1365 | WREG32(EVERGREEN_D4VGA_CONTROL, save->vga_control[3]); | ||
1366 | } | ||
1367 | if (rdev->num_crtc >= 6) { | ||
1368 | WREG32(EVERGREEN_D5VGA_CONTROL, save->vga_control[4]); | ||
1369 | WREG32(EVERGREEN_D6VGA_CONTROL, save->vga_control[5]); | ||
1370 | } | ||
1371 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 1); | ||
1372 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 1); | ||
1373 | if (rdev->num_crtc >= 4) { | ||
1374 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 1); | ||
1375 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 1); | ||
1376 | } | ||
1377 | if (rdev->num_crtc >= 6) { | ||
1378 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 1); | ||
1379 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 1); | ||
1380 | } | ||
1381 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, save->crtc_control[0]); | ||
1382 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, save->crtc_control[1]); | ||
1383 | if (rdev->num_crtc >= 4) { | ||
1384 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, save->crtc_control[2]); | ||
1385 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, save->crtc_control[3]); | ||
1386 | } | ||
1387 | if (rdev->num_crtc >= 6) { | ||
1388 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, save->crtc_control[4]); | ||
1389 | WREG32(EVERGREEN_CRTC_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, save->crtc_control[5]); | ||
1390 | } | ||
1391 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | ||
1392 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | ||
1393 | if (rdev->num_crtc >= 4) { | ||
1394 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | ||
1395 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | ||
1396 | } | ||
1397 | if (rdev->num_crtc >= 6) { | ||
1398 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | ||
1399 | WREG32(EVERGREEN_CRTC_UPDATE_LOCK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
1400 | } | ||
1401 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); | 1344 | WREG32(VGA_RENDER_CONTROL, save->vga_render_control); |
1402 | } | 1345 | } |
1403 | 1346 | ||
@@ -1986,10 +1929,18 @@ static void evergreen_gpu_init(struct radeon_device *rdev) | |||
1986 | if (rdev->flags & RADEON_IS_IGP) | 1929 | if (rdev->flags & RADEON_IS_IGP) |
1987 | rdev->config.evergreen.tile_config |= 1 << 4; | 1930 | rdev->config.evergreen.tile_config |= 1 << 4; |
1988 | else { | 1931 | else { |
1989 | if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) | 1932 | switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { |
1990 | rdev->config.evergreen.tile_config |= 1 << 4; | 1933 | case 0: /* four banks */ |
1991 | else | ||
1992 | rdev->config.evergreen.tile_config |= 0 << 4; | 1934 | rdev->config.evergreen.tile_config |= 0 << 4; |
1935 | break; | ||
1936 | case 1: /* eight banks */ | ||
1937 | rdev->config.evergreen.tile_config |= 1 << 4; | ||
1938 | break; | ||
1939 | case 2: /* sixteen banks */ | ||
1940 | default: | ||
1941 | rdev->config.evergreen.tile_config |= 2 << 4; | ||
1942 | break; | ||
1943 | } | ||
1993 | } | 1944 | } |
1994 | rdev->config.evergreen.tile_config |= 0 << 8; | 1945 | rdev->config.evergreen.tile_config |= 0 << 8; |
1995 | rdev->config.evergreen.tile_config |= | 1946 | rdev->config.evergreen.tile_config |= |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index c16554122ccd..e44a62a07fe3 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -788,6 +788,13 @@ static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p, | |||
788 | case V_030000_SQ_TEX_DIM_1D_ARRAY: | 788 | case V_030000_SQ_TEX_DIM_1D_ARRAY: |
789 | case V_030000_SQ_TEX_DIM_2D_ARRAY: | 789 | case V_030000_SQ_TEX_DIM_2D_ARRAY: |
790 | depth = 1; | 790 | depth = 1; |
791 | break; | ||
792 | case V_030000_SQ_TEX_DIM_2D_MSAA: | ||
793 | case V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA: | ||
794 | surf.nsamples = 1 << llevel; | ||
795 | llevel = 0; | ||
796 | depth = 1; | ||
797 | break; | ||
791 | case V_030000_SQ_TEX_DIM_3D: | 798 | case V_030000_SQ_TEX_DIM_3D: |
792 | break; | 799 | break; |
793 | default: | 800 | default: |
@@ -961,13 +968,15 @@ static int evergreen_cs_track_check(struct radeon_cs_parser *p) | |||
961 | 968 | ||
962 | if (track->db_dirty) { | 969 | if (track->db_dirty) { |
963 | /* Check stencil buffer */ | 970 | /* Check stencil buffer */ |
964 | if (G_028800_STENCIL_ENABLE(track->db_depth_control)) { | 971 | if (G_028044_FORMAT(track->db_s_info) != V_028044_STENCIL_INVALID && |
972 | G_028800_STENCIL_ENABLE(track->db_depth_control)) { | ||
965 | r = evergreen_cs_track_validate_stencil(p); | 973 | r = evergreen_cs_track_validate_stencil(p); |
966 | if (r) | 974 | if (r) |
967 | return r; | 975 | return r; |
968 | } | 976 | } |
969 | /* Check depth buffer */ | 977 | /* Check depth buffer */ |
970 | if (G_028800_Z_ENABLE(track->db_depth_control)) { | 978 | if (G_028040_FORMAT(track->db_z_info) != V_028040_Z_INVALID && |
979 | G_028800_Z_ENABLE(track->db_depth_control)) { | ||
971 | r = evergreen_cs_track_validate_depth(p); | 980 | r = evergreen_cs_track_validate_depth(p); |
972 | if (r) | 981 | if (r) |
973 | return r; | 982 | return r; |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index d3bd098e4e19..79347855d9bf 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -1277,6 +1277,8 @@ | |||
1277 | #define S_028044_FORMAT(x) (((x) & 0x1) << 0) | 1277 | #define S_028044_FORMAT(x) (((x) & 0x1) << 0) |
1278 | #define G_028044_FORMAT(x) (((x) >> 0) & 0x1) | 1278 | #define G_028044_FORMAT(x) (((x) >> 0) & 0x1) |
1279 | #define C_028044_FORMAT 0xFFFFFFFE | 1279 | #define C_028044_FORMAT 0xFFFFFFFE |
1280 | #define V_028044_STENCIL_INVALID 0 | ||
1281 | #define V_028044_STENCIL_8 1 | ||
1280 | #define G_028044_TILE_SPLIT(x) (((x) >> 8) & 0x7) | 1282 | #define G_028044_TILE_SPLIT(x) (((x) >> 8) & 0x7) |
1281 | #define DB_Z_READ_BASE 0x28048 | 1283 | #define DB_Z_READ_BASE 0x28048 |
1282 | #define DB_STENCIL_READ_BASE 0x2804c | 1284 | #define DB_STENCIL_READ_BASE 0x2804c |
diff --git a/drivers/gpu/drm/radeon/ni.c b/drivers/gpu/drm/radeon/ni.c index 9945d86d9001..853800e8582f 100644 --- a/drivers/gpu/drm/radeon/ni.c +++ b/drivers/gpu/drm/radeon/ni.c | |||
@@ -574,10 +574,18 @@ static void cayman_gpu_init(struct radeon_device *rdev) | |||
574 | if (rdev->flags & RADEON_IS_IGP) | 574 | if (rdev->flags & RADEON_IS_IGP) |
575 | rdev->config.cayman.tile_config |= 1 << 4; | 575 | rdev->config.cayman.tile_config |= 1 << 4; |
576 | else { | 576 | else { |
577 | if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) | 577 | switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { |
578 | rdev->config.cayman.tile_config |= 1 << 4; | 578 | case 0: /* four banks */ |
579 | else | ||
580 | rdev->config.cayman.tile_config |= 0 << 4; | 579 | rdev->config.cayman.tile_config |= 0 << 4; |
580 | break; | ||
581 | case 1: /* eight banks */ | ||
582 | rdev->config.cayman.tile_config |= 1 << 4; | ||
583 | break; | ||
584 | case 2: /* sixteen banks */ | ||
585 | default: | ||
586 | rdev->config.cayman.tile_config |= 2 << 4; | ||
587 | break; | ||
588 | } | ||
581 | } | 589 | } |
582 | rdev->config.cayman.tile_config |= | 590 | rdev->config.cayman.tile_config |= |
583 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; | 591 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 637280f541a3..d79c639ae739 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -3789,3 +3789,23 @@ static void r600_pcie_gen2_enable(struct radeon_device *rdev) | |||
3789 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); | 3789 | WREG32_PCIE_P(PCIE_LC_LINK_WIDTH_CNTL, link_width_cntl); |
3790 | } | 3790 | } |
3791 | } | 3791 | } |
3792 | |||
3793 | /** | ||
3794 | * r600_get_gpu_clock - return GPU clock counter snapshot | ||
3795 | * | ||
3796 | * @rdev: radeon_device pointer | ||
3797 | * | ||
3798 | * Fetches a GPU clock counter snapshot (R6xx-cayman). | ||
3799 | * Returns the 64 bit clock counter snapshot. | ||
3800 | */ | ||
3801 | uint64_t r600_get_gpu_clock(struct radeon_device *rdev) | ||
3802 | { | ||
3803 | uint64_t clock; | ||
3804 | |||
3805 | mutex_lock(&rdev->gpu_clock_mutex); | ||
3806 | WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); | ||
3807 | clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | | ||
3808 | ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); | ||
3809 | mutex_unlock(&rdev->gpu_clock_mutex); | ||
3810 | return clock; | ||
3811 | } | ||
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index ca87f7afaf23..3dab49cb1d4a 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -764,8 +764,10 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
764 | } | 764 | } |
765 | 765 | ||
766 | /* Check depth buffer */ | 766 | /* Check depth buffer */ |
767 | if (track->db_dirty && (G_028800_STENCIL_ENABLE(track->db_depth_control) || | 767 | if (track->db_dirty && |
768 | G_028800_Z_ENABLE(track->db_depth_control))) { | 768 | G_028010_FORMAT(track->db_depth_info) != V_028010_DEPTH_INVALID && |
769 | (G_028800_STENCIL_ENABLE(track->db_depth_control) || | ||
770 | G_028800_Z_ENABLE(track->db_depth_control))) { | ||
769 | r = r600_cs_track_validate_db(p); | 771 | r = r600_cs_track_validate_db(p); |
770 | if (r) | 772 | if (r) |
771 | return r; | 773 | return r; |
@@ -1557,13 +1559,14 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1557 | u32 tiling_flags) | 1559 | u32 tiling_flags) |
1558 | { | 1560 | { |
1559 | struct r600_cs_track *track = p->track; | 1561 | struct r600_cs_track *track = p->track; |
1560 | u32 nfaces, llevel, blevel, w0, h0, d0; | 1562 | u32 dim, nfaces, llevel, blevel, w0, h0, d0; |
1561 | u32 word0, word1, l0_size, mipmap_size, word2, word3; | 1563 | u32 word0, word1, l0_size, mipmap_size, word2, word3, word4, word5; |
1562 | u32 height_align, pitch, pitch_align, depth_align; | 1564 | u32 height_align, pitch, pitch_align, depth_align; |
1563 | u32 array, barray, larray; | 1565 | u32 barray, larray; |
1564 | u64 base_align; | 1566 | u64 base_align; |
1565 | struct array_mode_checker array_check; | 1567 | struct array_mode_checker array_check; |
1566 | u32 format; | 1568 | u32 format; |
1569 | bool is_array; | ||
1567 | 1570 | ||
1568 | /* on legacy kernel we don't perform advanced check */ | 1571 | /* on legacy kernel we don't perform advanced check */ |
1569 | if (p->rdev == NULL) | 1572 | if (p->rdev == NULL) |
@@ -1581,12 +1584,28 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1581 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); | 1584 | word0 |= S_038000_TILE_MODE(V_038000_ARRAY_1D_TILED_THIN1); |
1582 | } | 1585 | } |
1583 | word1 = radeon_get_ib_value(p, idx + 1); | 1586 | word1 = radeon_get_ib_value(p, idx + 1); |
1587 | word2 = radeon_get_ib_value(p, idx + 2) << 8; | ||
1588 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
1589 | word4 = radeon_get_ib_value(p, idx + 4); | ||
1590 | word5 = radeon_get_ib_value(p, idx + 5); | ||
1591 | dim = G_038000_DIM(word0); | ||
1584 | w0 = G_038000_TEX_WIDTH(word0) + 1; | 1592 | w0 = G_038000_TEX_WIDTH(word0) + 1; |
1593 | pitch = (G_038000_PITCH(word0) + 1) * 8; | ||
1585 | h0 = G_038004_TEX_HEIGHT(word1) + 1; | 1594 | h0 = G_038004_TEX_HEIGHT(word1) + 1; |
1586 | d0 = G_038004_TEX_DEPTH(word1); | 1595 | d0 = G_038004_TEX_DEPTH(word1); |
1596 | format = G_038004_DATA_FORMAT(word1); | ||
1597 | blevel = G_038010_BASE_LEVEL(word4); | ||
1598 | llevel = G_038014_LAST_LEVEL(word5); | ||
1599 | /* pitch in texels */ | ||
1600 | array_check.array_mode = G_038000_TILE_MODE(word0); | ||
1601 | array_check.group_size = track->group_size; | ||
1602 | array_check.nbanks = track->nbanks; | ||
1603 | array_check.npipes = track->npipes; | ||
1604 | array_check.nsamples = 1; | ||
1605 | array_check.blocksize = r600_fmt_get_blocksize(format); | ||
1587 | nfaces = 1; | 1606 | nfaces = 1; |
1588 | array = 0; | 1607 | is_array = false; |
1589 | switch (G_038000_DIM(word0)) { | 1608 | switch (dim) { |
1590 | case V_038000_SQ_TEX_DIM_1D: | 1609 | case V_038000_SQ_TEX_DIM_1D: |
1591 | case V_038000_SQ_TEX_DIM_2D: | 1610 | case V_038000_SQ_TEX_DIM_2D: |
1592 | case V_038000_SQ_TEX_DIM_3D: | 1611 | case V_038000_SQ_TEX_DIM_3D: |
@@ -1599,29 +1618,25 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1599 | break; | 1618 | break; |
1600 | case V_038000_SQ_TEX_DIM_1D_ARRAY: | 1619 | case V_038000_SQ_TEX_DIM_1D_ARRAY: |
1601 | case V_038000_SQ_TEX_DIM_2D_ARRAY: | 1620 | case V_038000_SQ_TEX_DIM_2D_ARRAY: |
1602 | array = 1; | 1621 | is_array = true; |
1603 | break; | 1622 | break; |
1604 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
1605 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: | 1623 | case V_038000_SQ_TEX_DIM_2D_ARRAY_MSAA: |
1624 | is_array = true; | ||
1625 | /* fall through */ | ||
1626 | case V_038000_SQ_TEX_DIM_2D_MSAA: | ||
1627 | array_check.nsamples = 1 << llevel; | ||
1628 | llevel = 0; | ||
1629 | break; | ||
1606 | default: | 1630 | default: |
1607 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); | 1631 | dev_warn(p->dev, "this kernel doesn't support %d texture dim\n", G_038000_DIM(word0)); |
1608 | return -EINVAL; | 1632 | return -EINVAL; |
1609 | } | 1633 | } |
1610 | format = G_038004_DATA_FORMAT(word1); | ||
1611 | if (!r600_fmt_is_valid_texture(format, p->family)) { | 1634 | if (!r600_fmt_is_valid_texture(format, p->family)) { |
1612 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", | 1635 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", |
1613 | __func__, __LINE__, format); | 1636 | __func__, __LINE__, format); |
1614 | return -EINVAL; | 1637 | return -EINVAL; |
1615 | } | 1638 | } |
1616 | 1639 | ||
1617 | /* pitch in texels */ | ||
1618 | pitch = (G_038000_PITCH(word0) + 1) * 8; | ||
1619 | array_check.array_mode = G_038000_TILE_MODE(word0); | ||
1620 | array_check.group_size = track->group_size; | ||
1621 | array_check.nbanks = track->nbanks; | ||
1622 | array_check.npipes = track->npipes; | ||
1623 | array_check.nsamples = 1; | ||
1624 | array_check.blocksize = r600_fmt_get_blocksize(format); | ||
1625 | if (r600_get_array_mode_alignment(&array_check, | 1640 | if (r600_get_array_mode_alignment(&array_check, |
1626 | &pitch_align, &height_align, &depth_align, &base_align)) { | 1641 | &pitch_align, &height_align, &depth_align, &base_align)) { |
1627 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", | 1642 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", |
@@ -1647,20 +1662,13 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1647 | return -EINVAL; | 1662 | return -EINVAL; |
1648 | } | 1663 | } |
1649 | 1664 | ||
1650 | word2 = radeon_get_ib_value(p, idx + 2) << 8; | ||
1651 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
1652 | |||
1653 | word0 = radeon_get_ib_value(p, idx + 4); | ||
1654 | word1 = radeon_get_ib_value(p, idx + 5); | ||
1655 | blevel = G_038010_BASE_LEVEL(word0); | ||
1656 | llevel = G_038014_LAST_LEVEL(word1); | ||
1657 | if (blevel > llevel) { | 1665 | if (blevel > llevel) { |
1658 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", | 1666 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", |
1659 | blevel, llevel); | 1667 | blevel, llevel); |
1660 | } | 1668 | } |
1661 | if (array == 1) { | 1669 | if (is_array) { |
1662 | barray = G_038014_BASE_ARRAY(word1); | 1670 | barray = G_038014_BASE_ARRAY(word5); |
1663 | larray = G_038014_LAST_ARRAY(word1); | 1671 | larray = G_038014_LAST_ARRAY(word5); |
1664 | 1672 | ||
1665 | nfaces = larray - barray + 1; | 1673 | nfaces = larray - barray + 1; |
1666 | } | 1674 | } |
@@ -1677,7 +1685,6 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1677 | return -EINVAL; | 1685 | return -EINVAL; |
1678 | } | 1686 | } |
1679 | /* using get ib will give us the offset into the mipmap bo */ | 1687 | /* using get ib will give us the offset into the mipmap bo */ |
1680 | word3 = radeon_get_ib_value(p, idx + 3) << 8; | ||
1681 | if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { | 1688 | if ((mipmap_size + word3) > radeon_bo_size(mipmap)) { |
1682 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", | 1689 | /*dev_warn(p->dev, "mipmap bo too small (%d %d %d %d %d %d -> %d have %ld)\n", |
1683 | w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ | 1690 | w0, h0, format, blevel, nlevels, word3, mipmap_size, radeon_bo_size(texture));*/ |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 4b116ae75fc2..fd328f4c3ea8 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -602,6 +602,9 @@ | |||
602 | #define RLC_HB_WPTR 0x3f1c | 602 | #define RLC_HB_WPTR 0x3f1c |
603 | #define RLC_HB_WPTR_LSB_ADDR 0x3f14 | 603 | #define RLC_HB_WPTR_LSB_ADDR 0x3f14 |
604 | #define RLC_HB_WPTR_MSB_ADDR 0x3f18 | 604 | #define RLC_HB_WPTR_MSB_ADDR 0x3f18 |
605 | #define RLC_GPU_CLOCK_COUNT_LSB 0x3f38 | ||
606 | #define RLC_GPU_CLOCK_COUNT_MSB 0x3f3c | ||
607 | #define RLC_CAPTURE_GPU_CLOCK_COUNT 0x3f40 | ||
605 | #define RLC_MC_CNTL 0x3f44 | 608 | #define RLC_MC_CNTL 0x3f44 |
606 | #define RLC_UCODE_CNTL 0x3f48 | 609 | #define RLC_UCODE_CNTL 0x3f48 |
607 | #define RLC_UCODE_ADDR 0x3f2c | 610 | #define RLC_UCODE_ADDR 0x3f2c |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 5431af292408..99304194a65c 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -300,6 +300,7 @@ struct radeon_bo_va { | |||
300 | uint64_t soffset; | 300 | uint64_t soffset; |
301 | uint64_t eoffset; | 301 | uint64_t eoffset; |
302 | uint32_t flags; | 302 | uint32_t flags; |
303 | struct radeon_fence *fence; | ||
303 | bool valid; | 304 | bool valid; |
304 | }; | 305 | }; |
305 | 306 | ||
@@ -1533,6 +1534,7 @@ struct radeon_device { | |||
1533 | unsigned debugfs_count; | 1534 | unsigned debugfs_count; |
1534 | /* virtual memory */ | 1535 | /* virtual memory */ |
1535 | struct radeon_vm_manager vm_manager; | 1536 | struct radeon_vm_manager vm_manager; |
1537 | struct mutex gpu_clock_mutex; | ||
1536 | }; | 1538 | }; |
1537 | 1539 | ||
1538 | int radeon_device_init(struct radeon_device *rdev, | 1540 | int radeon_device_init(struct radeon_device *rdev, |
@@ -1733,11 +1735,11 @@ void radeon_ring_write(struct radeon_ring *ring, uint32_t v); | |||
1733 | #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev)) | 1735 | #define radeon_pm_finish(rdev) (rdev)->asic->pm.finish((rdev)) |
1734 | #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev)) | 1736 | #define radeon_pm_init_profile(rdev) (rdev)->asic->pm.init_profile((rdev)) |
1735 | #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev)) | 1737 | #define radeon_pm_get_dynpm_state(rdev) (rdev)->asic->pm.get_dynpm_state((rdev)) |
1736 | #define radeon_pre_page_flip(rdev, crtc) rdev->asic->pflip.pre_page_flip((rdev), (crtc)) | 1738 | #define radeon_pre_page_flip(rdev, crtc) (rdev)->asic->pflip.pre_page_flip((rdev), (crtc)) |
1737 | #define radeon_page_flip(rdev, crtc, base) rdev->asic->pflip.page_flip((rdev), (crtc), (base)) | 1739 | #define radeon_page_flip(rdev, crtc, base) (rdev)->asic->pflip.page_flip((rdev), (crtc), (base)) |
1738 | #define radeon_post_page_flip(rdev, crtc) rdev->asic->pflip.post_page_flip((rdev), (crtc)) | 1740 | #define radeon_post_page_flip(rdev, crtc) (rdev)->asic->pflip.post_page_flip((rdev), (crtc)) |
1739 | #define radeon_wait_for_vblank(rdev, crtc) rdev->asic->display.wait_for_vblank((rdev), (crtc)) | 1741 | #define radeon_wait_for_vblank(rdev, crtc) (rdev)->asic->display.wait_for_vblank((rdev), (crtc)) |
1740 | #define radeon_mc_wait_for_idle(rdev) rdev->asic->mc_wait_for_idle((rdev)) | 1742 | #define radeon_mc_wait_for_idle(rdev) (rdev)->asic->mc_wait_for_idle((rdev)) |
1741 | 1743 | ||
1742 | /* Common functions */ | 1744 | /* Common functions */ |
1743 | /* AGP */ | 1745 | /* AGP */ |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.h b/drivers/gpu/drm/radeon/radeon_asic.h index f4af24310438..18c38d14c8cd 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.h +++ b/drivers/gpu/drm/radeon/radeon_asic.h | |||
@@ -255,13 +255,10 @@ extern int rs690_mc_wait_for_idle(struct radeon_device *rdev); | |||
255 | * rv515 | 255 | * rv515 |
256 | */ | 256 | */ |
257 | struct rv515_mc_save { | 257 | struct rv515_mc_save { |
258 | u32 d1vga_control; | ||
259 | u32 d2vga_control; | ||
260 | u32 vga_render_control; | 258 | u32 vga_render_control; |
261 | u32 vga_hdp_control; | 259 | u32 vga_hdp_control; |
262 | u32 d1crtc_control; | ||
263 | u32 d2crtc_control; | ||
264 | }; | 260 | }; |
261 | |||
265 | int rv515_init(struct radeon_device *rdev); | 262 | int rv515_init(struct radeon_device *rdev); |
266 | void rv515_fini(struct radeon_device *rdev); | 263 | void rv515_fini(struct radeon_device *rdev); |
267 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); | 264 | uint32_t rv515_mc_rreg(struct radeon_device *rdev, uint32_t reg); |
@@ -371,6 +368,7 @@ void r600_kms_blit_copy(struct radeon_device *rdev, | |||
371 | unsigned num_gpu_pages, | 368 | unsigned num_gpu_pages, |
372 | struct radeon_sa_bo *vb); | 369 | struct radeon_sa_bo *vb); |
373 | int r600_mc_wait_for_idle(struct radeon_device *rdev); | 370 | int r600_mc_wait_for_idle(struct radeon_device *rdev); |
371 | uint64_t r600_get_gpu_clock(struct radeon_device *rdev); | ||
374 | 372 | ||
375 | /* | 373 | /* |
376 | * rv770,rv730,rv710,rv740 | 374 | * rv770,rv730,rv710,rv740 |
@@ -389,11 +387,10 @@ void r700_cp_fini(struct radeon_device *rdev); | |||
389 | * evergreen | 387 | * evergreen |
390 | */ | 388 | */ |
391 | struct evergreen_mc_save { | 389 | struct evergreen_mc_save { |
392 | u32 vga_control[6]; | ||
393 | u32 vga_render_control; | 390 | u32 vga_render_control; |
394 | u32 vga_hdp_control; | 391 | u32 vga_hdp_control; |
395 | u32 crtc_control[6]; | ||
396 | }; | 392 | }; |
393 | |||
397 | void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev); | 394 | void evergreen_pcie_gart_tlb_flush(struct radeon_device *rdev); |
398 | int evergreen_init(struct radeon_device *rdev); | 395 | int evergreen_init(struct radeon_device *rdev); |
399 | void evergreen_fini(struct radeon_device *rdev); | 396 | void evergreen_fini(struct radeon_device *rdev); |
@@ -472,5 +469,6 @@ int si_vm_bind(struct radeon_device *rdev, struct radeon_vm *vm, int id); | |||
472 | void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); | 469 | void si_vm_unbind(struct radeon_device *rdev, struct radeon_vm *vm); |
473 | void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); | 470 | void si_vm_tlb_flush(struct radeon_device *rdev, struct radeon_vm *vm); |
474 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); | 471 | int si_ib_parse(struct radeon_device *rdev, struct radeon_ib *ib); |
472 | uint64_t si_get_gpu_clock(struct radeon_device *rdev); | ||
475 | 473 | ||
476 | #endif | 474 | #endif |
diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index b1e3820df363..f9c21f9d16bc 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c | |||
@@ -1263,6 +1263,8 @@ bool radeon_atom_get_clock_info(struct drm_device *dev) | |||
1263 | union igp_info { | 1263 | union igp_info { |
1264 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; | 1264 | struct _ATOM_INTEGRATED_SYSTEM_INFO info; |
1265 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; | 1265 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V2 info_2; |
1266 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 info_6; | ||
1267 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V1_7 info_7; | ||
1266 | }; | 1268 | }; |
1267 | 1269 | ||
1268 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) | 1270 | bool radeon_atombios_sideport_present(struct radeon_device *rdev) |
@@ -1390,27 +1392,50 @@ static void radeon_atombios_get_igp_ss_overrides(struct radeon_device *rdev, | |||
1390 | struct radeon_mode_info *mode_info = &rdev->mode_info; | 1392 | struct radeon_mode_info *mode_info = &rdev->mode_info; |
1391 | int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); | 1393 | int index = GetIndexIntoMasterTable(DATA, IntegratedSystemInfo); |
1392 | u16 data_offset, size; | 1394 | u16 data_offset, size; |
1393 | struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *igp_info; | 1395 | union igp_info *igp_info; |
1394 | u8 frev, crev; | 1396 | u8 frev, crev; |
1395 | u16 percentage = 0, rate = 0; | 1397 | u16 percentage = 0, rate = 0; |
1396 | 1398 | ||
1397 | /* get any igp specific overrides */ | 1399 | /* get any igp specific overrides */ |
1398 | if (atom_parse_data_header(mode_info->atom_context, index, &size, | 1400 | if (atom_parse_data_header(mode_info->atom_context, index, &size, |
1399 | &frev, &crev, &data_offset)) { | 1401 | &frev, &crev, &data_offset)) { |
1400 | igp_info = (struct _ATOM_INTEGRATED_SYSTEM_INFO_V6 *) | 1402 | igp_info = (union igp_info *) |
1401 | (mode_info->atom_context->bios + data_offset); | 1403 | (mode_info->atom_context->bios + data_offset); |
1402 | switch (id) { | 1404 | switch (crev) { |
1403 | case ASIC_INTERNAL_SS_ON_TMDS: | 1405 | case 6: |
1404 | percentage = le16_to_cpu(igp_info->usDVISSPercentage); | 1406 | switch (id) { |
1405 | rate = le16_to_cpu(igp_info->usDVISSpreadRateIn10Hz); | 1407 | case ASIC_INTERNAL_SS_ON_TMDS: |
1408 | percentage = le16_to_cpu(igp_info->info_6.usDVISSPercentage); | ||
1409 | rate = le16_to_cpu(igp_info->info_6.usDVISSpreadRateIn10Hz); | ||
1410 | break; | ||
1411 | case ASIC_INTERNAL_SS_ON_HDMI: | ||
1412 | percentage = le16_to_cpu(igp_info->info_6.usHDMISSPercentage); | ||
1413 | rate = le16_to_cpu(igp_info->info_6.usHDMISSpreadRateIn10Hz); | ||
1414 | break; | ||
1415 | case ASIC_INTERNAL_SS_ON_LVDS: | ||
1416 | percentage = le16_to_cpu(igp_info->info_6.usLvdsSSPercentage); | ||
1417 | rate = le16_to_cpu(igp_info->info_6.usLvdsSSpreadRateIn10Hz); | ||
1418 | break; | ||
1419 | } | ||
1406 | break; | 1420 | break; |
1407 | case ASIC_INTERNAL_SS_ON_HDMI: | 1421 | case 7: |
1408 | percentage = le16_to_cpu(igp_info->usHDMISSPercentage); | 1422 | switch (id) { |
1409 | rate = le16_to_cpu(igp_info->usHDMISSpreadRateIn10Hz); | 1423 | case ASIC_INTERNAL_SS_ON_TMDS: |
1424 | percentage = le16_to_cpu(igp_info->info_7.usDVISSPercentage); | ||
1425 | rate = le16_to_cpu(igp_info->info_7.usDVISSpreadRateIn10Hz); | ||
1426 | break; | ||
1427 | case ASIC_INTERNAL_SS_ON_HDMI: | ||
1428 | percentage = le16_to_cpu(igp_info->info_7.usHDMISSPercentage); | ||
1429 | rate = le16_to_cpu(igp_info->info_7.usHDMISSpreadRateIn10Hz); | ||
1430 | break; | ||
1431 | case ASIC_INTERNAL_SS_ON_LVDS: | ||
1432 | percentage = le16_to_cpu(igp_info->info_7.usLvdsSSPercentage); | ||
1433 | rate = le16_to_cpu(igp_info->info_7.usLvdsSSpreadRateIn10Hz); | ||
1434 | break; | ||
1435 | } | ||
1410 | break; | 1436 | break; |
1411 | case ASIC_INTERNAL_SS_ON_LVDS: | 1437 | default: |
1412 | percentage = le16_to_cpu(igp_info->usLvdsSSPercentage); | 1438 | DRM_ERROR("Unsupported IGP table: %d %d\n", frev, crev); |
1413 | rate = le16_to_cpu(igp_info->usLvdsSSpreadRateIn10Hz); | ||
1414 | break; | 1439 | break; |
1415 | } | 1440 | } |
1416 | if (percentage) | 1441 | if (percentage) |
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c index 576f4f6919f2..f75247d42ffd 100644 --- a/drivers/gpu/drm/radeon/radeon_combios.c +++ b/drivers/gpu/drm/radeon/radeon_combios.c | |||
@@ -719,6 +719,34 @@ static struct radeon_i2c_bus_rec combios_setup_i2c_bus(struct radeon_device *rde | |||
719 | return i2c; | 719 | return i2c; |
720 | } | 720 | } |
721 | 721 | ||
722 | static struct radeon_i2c_bus_rec radeon_combios_get_i2c_info_from_table(struct radeon_device *rdev) | ||
723 | { | ||
724 | struct drm_device *dev = rdev->ddev; | ||
725 | struct radeon_i2c_bus_rec i2c; | ||
726 | u16 offset; | ||
727 | u8 id, blocks, clk, data; | ||
728 | int i; | ||
729 | |||
730 | i2c.valid = false; | ||
731 | |||
732 | offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); | ||
733 | if (offset) { | ||
734 | blocks = RBIOS8(offset + 2); | ||
735 | for (i = 0; i < blocks; i++) { | ||
736 | id = RBIOS8(offset + 3 + (i * 5) + 0); | ||
737 | if (id == 136) { | ||
738 | clk = RBIOS8(offset + 3 + (i * 5) + 3); | ||
739 | data = RBIOS8(offset + 3 + (i * 5) + 4); | ||
740 | /* gpiopad */ | ||
741 | i2c = combios_setup_i2c_bus(rdev, DDC_MONID, | ||
742 | (1 << clk), (1 << data)); | ||
743 | break; | ||
744 | } | ||
745 | } | ||
746 | } | ||
747 | return i2c; | ||
748 | } | ||
749 | |||
722 | void radeon_combios_i2c_init(struct radeon_device *rdev) | 750 | void radeon_combios_i2c_init(struct radeon_device *rdev) |
723 | { | 751 | { |
724 | struct drm_device *dev = rdev->ddev; | 752 | struct drm_device *dev = rdev->ddev; |
@@ -755,30 +783,14 @@ void radeon_combios_i2c_init(struct radeon_device *rdev) | |||
755 | } else if (rdev->family == CHIP_RS300 || | 783 | } else if (rdev->family == CHIP_RS300 || |
756 | rdev->family == CHIP_RS400 || | 784 | rdev->family == CHIP_RS400 || |
757 | rdev->family == CHIP_RS480) { | 785 | rdev->family == CHIP_RS480) { |
758 | u16 offset; | ||
759 | u8 id, blocks, clk, data; | ||
760 | int i; | ||
761 | |||
762 | /* 0x68 */ | 786 | /* 0x68 */ |
763 | i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); | 787 | i2c = combios_setup_i2c_bus(rdev, DDC_CRT2, 0, 0); |
764 | rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); | 788 | rdev->i2c_bus[3] = radeon_i2c_create(dev, &i2c, "MONID"); |
765 | 789 | ||
766 | offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE); | 790 | /* gpiopad */ |
767 | if (offset) { | 791 | i2c = radeon_combios_get_i2c_info_from_table(rdev); |
768 | blocks = RBIOS8(offset + 2); | 792 | if (i2c.valid) |
769 | for (i = 0; i < blocks; i++) { | 793 | rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); |
770 | id = RBIOS8(offset + 3 + (i * 5) + 0); | ||
771 | if (id == 136) { | ||
772 | clk = RBIOS8(offset + 3 + (i * 5) + 3); | ||
773 | data = RBIOS8(offset + 3 + (i * 5) + 4); | ||
774 | /* gpiopad */ | ||
775 | i2c = combios_setup_i2c_bus(rdev, DDC_MONID, | ||
776 | (1 << clk), (1 << data)); | ||
777 | rdev->i2c_bus[4] = radeon_i2c_create(dev, &i2c, "GPIOPAD_MASK"); | ||
778 | break; | ||
779 | } | ||
780 | } | ||
781 | } | ||
782 | } else if ((rdev->family == CHIP_R200) || | 794 | } else if ((rdev->family == CHIP_R200) || |
783 | (rdev->family >= CHIP_R300)) { | 795 | (rdev->family >= CHIP_R300)) { |
784 | /* 0x68 */ | 796 | /* 0x68 */ |
@@ -2321,7 +2333,10 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev) | |||
2321 | connector = (tmp >> 12) & 0xf; | 2333 | connector = (tmp >> 12) & 0xf; |
2322 | 2334 | ||
2323 | ddc_type = (tmp >> 8) & 0xf; | 2335 | ddc_type = (tmp >> 8) & 0xf; |
2324 | ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0); | 2336 | if (ddc_type == 5) |
2337 | ddc_i2c = radeon_combios_get_i2c_info_from_table(rdev); | ||
2338 | else | ||
2339 | ddc_i2c = combios_setup_i2c_bus(rdev, ddc_type, 0, 0); | ||
2325 | 2340 | ||
2326 | switch (connector) { | 2341 | switch (connector) { |
2327 | case CONNECTOR_PROPRIETARY_LEGACY: | 2342 | case CONNECTOR_PROPRIETARY_LEGACY: |
diff --git a/drivers/gpu/drm/radeon/radeon_cs.c b/drivers/gpu/drm/radeon/radeon_cs.c index 8a4c49ef0cc4..b4a0db24f4dd 100644 --- a/drivers/gpu/drm/radeon/radeon_cs.c +++ b/drivers/gpu/drm/radeon/radeon_cs.c | |||
@@ -278,6 +278,30 @@ int radeon_cs_parser_init(struct radeon_cs_parser *p, void *data) | |||
278 | return 0; | 278 | return 0; |
279 | } | 279 | } |
280 | 280 | ||
281 | static void radeon_bo_vm_fence_va(struct radeon_cs_parser *parser, | ||
282 | struct radeon_fence *fence) | ||
283 | { | ||
284 | struct radeon_fpriv *fpriv = parser->filp->driver_priv; | ||
285 | struct radeon_vm *vm = &fpriv->vm; | ||
286 | struct radeon_bo_list *lobj; | ||
287 | |||
288 | if (parser->chunk_ib_idx == -1) { | ||
289 | return; | ||
290 | } | ||
291 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) { | ||
292 | return; | ||
293 | } | ||
294 | |||
295 | list_for_each_entry(lobj, &parser->validated, tv.head) { | ||
296 | struct radeon_bo_va *bo_va; | ||
297 | struct radeon_bo *rbo = lobj->bo; | ||
298 | |||
299 | bo_va = radeon_bo_va(rbo, vm); | ||
300 | radeon_fence_unref(&bo_va->fence); | ||
301 | bo_va->fence = radeon_fence_ref(fence); | ||
302 | } | ||
303 | } | ||
304 | |||
281 | /** | 305 | /** |
282 | * cs_parser_fini() - clean parser states | 306 | * cs_parser_fini() - clean parser states |
283 | * @parser: parser structure holding parsing context. | 307 | * @parser: parser structure holding parsing context. |
@@ -290,11 +314,14 @@ static void radeon_cs_parser_fini(struct radeon_cs_parser *parser, int error) | |||
290 | { | 314 | { |
291 | unsigned i; | 315 | unsigned i; |
292 | 316 | ||
293 | if (!error) | 317 | if (!error) { |
318 | /* fence all bo va before ttm_eu_fence_buffer_objects so bo are still reserved */ | ||
319 | radeon_bo_vm_fence_va(parser, parser->ib.fence); | ||
294 | ttm_eu_fence_buffer_objects(&parser->validated, | 320 | ttm_eu_fence_buffer_objects(&parser->validated, |
295 | parser->ib.fence); | 321 | parser->ib.fence); |
296 | else | 322 | } else { |
297 | ttm_eu_backoff_reservation(&parser->validated); | 323 | ttm_eu_backoff_reservation(&parser->validated); |
324 | } | ||
298 | 325 | ||
299 | if (parser->relocs != NULL) { | 326 | if (parser->relocs != NULL) { |
300 | for (i = 0; i < parser->nrelocs; i++) { | 327 | for (i = 0; i < parser->nrelocs; i++) { |
@@ -388,7 +415,6 @@ static int radeon_cs_ib_vm_chunk(struct radeon_device *rdev, | |||
388 | 415 | ||
389 | if (parser->chunk_ib_idx == -1) | 416 | if (parser->chunk_ib_idx == -1) |
390 | return 0; | 417 | return 0; |
391 | |||
392 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) | 418 | if ((parser->cs_flags & RADEON_CS_USE_VM) == 0) |
393 | return 0; | 419 | return 0; |
394 | 420 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_cursor.c b/drivers/gpu/drm/radeon/radeon_cursor.c index 711e95ad39bf..8794744cdf1a 100644 --- a/drivers/gpu/drm/radeon/radeon_cursor.c +++ b/drivers/gpu/drm/radeon/radeon_cursor.c | |||
@@ -67,7 +67,8 @@ static void radeon_hide_cursor(struct drm_crtc *crtc) | |||
67 | 67 | ||
68 | if (ASIC_IS_DCE4(rdev)) { | 68 | if (ASIC_IS_DCE4(rdev)) { |
69 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); | 69 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); |
70 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); | 70 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | |
71 | EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); | ||
71 | } else if (ASIC_IS_AVIVO(rdev)) { | 72 | } else if (ASIC_IS_AVIVO(rdev)) { |
72 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); | 73 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); |
73 | WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); | 74 | WREG32(RADEON_MM_DATA, (AVIVO_D1CURSOR_MODE_24BPP << AVIVO_D1CURSOR_MODE_SHIFT)); |
@@ -94,7 +95,8 @@ static void radeon_show_cursor(struct drm_crtc *crtc) | |||
94 | if (ASIC_IS_DCE4(rdev)) { | 95 | if (ASIC_IS_DCE4(rdev)) { |
95 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); | 96 | WREG32(RADEON_MM_INDEX, EVERGREEN_CUR_CONTROL + radeon_crtc->crtc_offset); |
96 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | | 97 | WREG32(RADEON_MM_DATA, EVERGREEN_CURSOR_EN | |
97 | EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT)); | 98 | EVERGREEN_CURSOR_MODE(EVERGREEN_CURSOR_24_8_PRE_MULT) | |
99 | EVERGREEN_CURSOR_URGENT_CONTROL(EVERGREEN_CURSOR_URGENT_1_2)); | ||
98 | } else if (ASIC_IS_AVIVO(rdev)) { | 100 | } else if (ASIC_IS_AVIVO(rdev)) { |
99 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); | 101 | WREG32(RADEON_MM_INDEX, AVIVO_D1CUR_CONTROL + radeon_crtc->crtc_offset); |
100 | WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | | 102 | WREG32(RADEON_MM_DATA, AVIVO_D1CURSOR_EN | |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 742af8244e89..d2e243867ac6 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -1009,6 +1009,7 @@ int radeon_device_init(struct radeon_device *rdev, | |||
1009 | atomic_set(&rdev->ih.lock, 0); | 1009 | atomic_set(&rdev->ih.lock, 0); |
1010 | mutex_init(&rdev->gem.mutex); | 1010 | mutex_init(&rdev->gem.mutex); |
1011 | mutex_init(&rdev->pm.mutex); | 1011 | mutex_init(&rdev->pm.mutex); |
1012 | mutex_init(&rdev->gpu_clock_mutex); | ||
1012 | init_rwsem(&rdev->pm.mclk_lock); | 1013 | init_rwsem(&rdev->pm.mclk_lock); |
1013 | init_rwsem(&rdev->exclusive_lock); | 1014 | init_rwsem(&rdev->exclusive_lock); |
1014 | init_waitqueue_head(&rdev->irq.vblank_queue); | 1015 | init_waitqueue_head(&rdev->irq.vblank_queue); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index dcea6f01ae4e..d7269f48d37c 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -59,9 +59,12 @@ | |||
59 | * 2.15.0 - add max_pipes query | 59 | * 2.15.0 - add max_pipes query |
60 | * 2.16.0 - fix evergreen 2D tiled surface calculation | 60 | * 2.16.0 - fix evergreen 2D tiled surface calculation |
61 | * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx | 61 | * 2.17.0 - add STRMOUT_BASE_UPDATE for r7xx |
62 | * 2.18.0 - r600-eg: allow "invalid" DB formats | ||
63 | * 2.19.0 - r600-eg: MSAA textures | ||
64 | * 2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query | ||
62 | */ | 65 | */ |
63 | #define KMS_DRIVER_MAJOR 2 | 66 | #define KMS_DRIVER_MAJOR 2 |
64 | #define KMS_DRIVER_MINOR 17 | 67 | #define KMS_DRIVER_MINOR 20 |
65 | #define KMS_DRIVER_PATCHLEVEL 0 | 68 | #define KMS_DRIVER_PATCHLEVEL 0 |
66 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 69 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
67 | int radeon_driver_unload_kms(struct drm_device *dev); | 70 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_gart.c b/drivers/gpu/drm/radeon/radeon_gart.c index b3720054614d..bb3b7fe05ccd 100644 --- a/drivers/gpu/drm/radeon/radeon_gart.c +++ b/drivers/gpu/drm/radeon/radeon_gart.c | |||
@@ -814,7 +814,7 @@ int radeon_vm_bo_update_pte(struct radeon_device *rdev, | |||
814 | return -EINVAL; | 814 | return -EINVAL; |
815 | } | 815 | } |
816 | 816 | ||
817 | if (bo_va->valid) | 817 | if (bo_va->valid && mem) |
818 | return 0; | 818 | return 0; |
819 | 819 | ||
820 | ngpu_pages = radeon_bo_ngpu_pages(bo); | 820 | ngpu_pages = radeon_bo_ngpu_pages(bo); |
@@ -859,11 +859,27 @@ int radeon_vm_bo_rmv(struct radeon_device *rdev, | |||
859 | struct radeon_bo *bo) | 859 | struct radeon_bo *bo) |
860 | { | 860 | { |
861 | struct radeon_bo_va *bo_va; | 861 | struct radeon_bo_va *bo_va; |
862 | int r; | ||
862 | 863 | ||
863 | bo_va = radeon_bo_va(bo, vm); | 864 | bo_va = radeon_bo_va(bo, vm); |
864 | if (bo_va == NULL) | 865 | if (bo_va == NULL) |
865 | return 0; | 866 | return 0; |
866 | 867 | ||
868 | /* wait for va use to end */ | ||
869 | while (bo_va->fence) { | ||
870 | r = radeon_fence_wait(bo_va->fence, false); | ||
871 | if (r) { | ||
872 | DRM_ERROR("error while waiting for fence: %d\n", r); | ||
873 | } | ||
874 | if (r == -EDEADLK) { | ||
875 | r = radeon_gpu_reset(rdev); | ||
876 | if (!r) | ||
877 | continue; | ||
878 | } | ||
879 | break; | ||
880 | } | ||
881 | radeon_fence_unref(&bo_va->fence); | ||
882 | |||
867 | mutex_lock(&rdev->vm_manager.lock); | 883 | mutex_lock(&rdev->vm_manager.lock); |
868 | mutex_lock(&vm->mutex); | 884 | mutex_lock(&vm->mutex); |
869 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); | 885 | radeon_vm_bo_update_pte(rdev, vm, bo, NULL); |
@@ -934,7 +950,7 @@ int radeon_vm_init(struct radeon_device *rdev, struct radeon_vm *vm) | |||
934 | } | 950 | } |
935 | 951 | ||
936 | /** | 952 | /** |
937 | * radeon_vm_init - tear down a vm instance | 953 | * radeon_vm_fini - tear down a vm instance |
938 | * | 954 | * |
939 | * @rdev: radeon_device pointer | 955 | * @rdev: radeon_device pointer |
940 | * @vm: requested vm | 956 | * @vm: requested vm |
@@ -952,12 +968,15 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
952 | radeon_vm_unbind_locked(rdev, vm); | 968 | radeon_vm_unbind_locked(rdev, vm); |
953 | mutex_unlock(&rdev->vm_manager.lock); | 969 | mutex_unlock(&rdev->vm_manager.lock); |
954 | 970 | ||
955 | /* remove all bo */ | 971 | /* remove all bo at this point non are busy any more because unbind |
972 | * waited for the last vm fence to signal | ||
973 | */ | ||
956 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); | 974 | r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); |
957 | if (!r) { | 975 | if (!r) { |
958 | bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm); | 976 | bo_va = radeon_bo_va(rdev->ring_tmp_bo.bo, vm); |
959 | list_del_init(&bo_va->bo_list); | 977 | list_del_init(&bo_va->bo_list); |
960 | list_del_init(&bo_va->vm_list); | 978 | list_del_init(&bo_va->vm_list); |
979 | radeon_fence_unref(&bo_va->fence); | ||
961 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); | 980 | radeon_bo_unreserve(rdev->ring_tmp_bo.bo); |
962 | kfree(bo_va); | 981 | kfree(bo_va); |
963 | } | 982 | } |
@@ -969,6 +988,7 @@ void radeon_vm_fini(struct radeon_device *rdev, struct radeon_vm *vm) | |||
969 | r = radeon_bo_reserve(bo_va->bo, false); | 988 | r = radeon_bo_reserve(bo_va->bo, false); |
970 | if (!r) { | 989 | if (!r) { |
971 | list_del_init(&bo_va->bo_list); | 990 | list_del_init(&bo_va->bo_list); |
991 | radeon_fence_unref(&bo_va->fence); | ||
972 | radeon_bo_unreserve(bo_va->bo); | 992 | radeon_bo_unreserve(bo_va->bo); |
973 | kfree(bo_va); | 993 | kfree(bo_va); |
974 | } | 994 | } |
diff --git a/drivers/gpu/drm/radeon/radeon_gem.c b/drivers/gpu/drm/radeon/radeon_gem.c index 84d045245739..1b57b0058ad6 100644 --- a/drivers/gpu/drm/radeon/radeon_gem.c +++ b/drivers/gpu/drm/radeon/radeon_gem.c | |||
@@ -134,25 +134,16 @@ void radeon_gem_object_close(struct drm_gem_object *obj, | |||
134 | struct radeon_device *rdev = rbo->rdev; | 134 | struct radeon_device *rdev = rbo->rdev; |
135 | struct radeon_fpriv *fpriv = file_priv->driver_priv; | 135 | struct radeon_fpriv *fpriv = file_priv->driver_priv; |
136 | struct radeon_vm *vm = &fpriv->vm; | 136 | struct radeon_vm *vm = &fpriv->vm; |
137 | struct radeon_bo_va *bo_va, *tmp; | ||
138 | 137 | ||
139 | if (rdev->family < CHIP_CAYMAN) { | 138 | if (rdev->family < CHIP_CAYMAN) { |
140 | return; | 139 | return; |
141 | } | 140 | } |
142 | 141 | ||
143 | if (radeon_bo_reserve(rbo, false)) { | 142 | if (radeon_bo_reserve(rbo, false)) { |
143 | dev_err(rdev->dev, "leaking bo va because we fail to reserve bo\n"); | ||
144 | return; | 144 | return; |
145 | } | 145 | } |
146 | list_for_each_entry_safe(bo_va, tmp, &rbo->va, bo_list) { | 146 | radeon_vm_bo_rmv(rdev, vm, rbo); |
147 | if (bo_va->vm == vm) { | ||
148 | /* remove from this vm address space */ | ||
149 | mutex_lock(&vm->mutex); | ||
150 | list_del(&bo_va->vm_list); | ||
151 | mutex_unlock(&vm->mutex); | ||
152 | list_del(&bo_va->bo_list); | ||
153 | kfree(bo_va); | ||
154 | } | ||
155 | } | ||
156 | radeon_bo_unreserve(rbo); | 147 | radeon_bo_unreserve(rbo); |
157 | } | 148 | } |
158 | 149 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index 1d73f16b5d97..414b4acf6947 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -29,6 +29,7 @@ | |||
29 | #include "drm_sarea.h" | 29 | #include "drm_sarea.h" |
30 | #include "radeon.h" | 30 | #include "radeon.h" |
31 | #include "radeon_drm.h" | 31 | #include "radeon_drm.h" |
32 | #include "radeon_asic.h" | ||
32 | 33 | ||
33 | #include <linux/vga_switcheroo.h> | 34 | #include <linux/vga_switcheroo.h> |
34 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
@@ -167,17 +168,39 @@ static void radeon_set_filp_rights(struct drm_device *dev, | |||
167 | int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | 168 | int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) |
168 | { | 169 | { |
169 | struct radeon_device *rdev = dev->dev_private; | 170 | struct radeon_device *rdev = dev->dev_private; |
170 | struct drm_radeon_info *info; | 171 | struct drm_radeon_info *info = data; |
171 | struct radeon_mode_info *minfo = &rdev->mode_info; | 172 | struct radeon_mode_info *minfo = &rdev->mode_info; |
172 | uint32_t *value_ptr; | 173 | uint32_t value, *value_ptr; |
173 | uint32_t value; | 174 | uint64_t value64, *value_ptr64; |
174 | struct drm_crtc *crtc; | 175 | struct drm_crtc *crtc; |
175 | int i, found; | 176 | int i, found; |
176 | 177 | ||
177 | info = data; | 178 | /* TIMESTAMP is a 64-bit value, needs special handling. */ |
179 | if (info->request == RADEON_INFO_TIMESTAMP) { | ||
180 | if (rdev->family >= CHIP_R600) { | ||
181 | value_ptr64 = (uint64_t*)((unsigned long)info->value); | ||
182 | if (rdev->family >= CHIP_TAHITI) { | ||
183 | value64 = si_get_gpu_clock(rdev); | ||
184 | } else { | ||
185 | value64 = r600_get_gpu_clock(rdev); | ||
186 | } | ||
187 | |||
188 | if (DRM_COPY_TO_USER(value_ptr64, &value64, sizeof(value64))) { | ||
189 | DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); | ||
190 | return -EFAULT; | ||
191 | } | ||
192 | return 0; | ||
193 | } else { | ||
194 | DRM_DEBUG_KMS("timestamp is r6xx+ only!\n"); | ||
195 | return -EINVAL; | ||
196 | } | ||
197 | } | ||
198 | |||
178 | value_ptr = (uint32_t *)((unsigned long)info->value); | 199 | value_ptr = (uint32_t *)((unsigned long)info->value); |
179 | if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) | 200 | if (DRM_COPY_FROM_USER(&value, value_ptr, sizeof(value))) { |
201 | DRM_ERROR("copy_from_user %s:%u\n", __func__, __LINE__); | ||
180 | return -EFAULT; | 202 | return -EFAULT; |
203 | } | ||
181 | 204 | ||
182 | switch (info->request) { | 205 | switch (info->request) { |
183 | case RADEON_INFO_DEVICE_ID: | 206 | case RADEON_INFO_DEVICE_ID: |
@@ -337,7 +360,7 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp) | |||
337 | return -EINVAL; | 360 | return -EINVAL; |
338 | } | 361 | } |
339 | if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { | 362 | if (DRM_COPY_TO_USER(value_ptr, &value, sizeof(uint32_t))) { |
340 | DRM_ERROR("copy_to_user\n"); | 363 | DRM_ERROR("copy_to_user %s:%u\n", __func__, __LINE__); |
341 | return -EFAULT; | 364 | return -EFAULT; |
342 | } | 365 | } |
343 | return 0; | 366 | return 0; |
diff --git a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c index d5fd615897ec..94b4a1c12893 100644 --- a/drivers/gpu/drm/radeon/radeon_legacy_crtc.c +++ b/drivers/gpu/drm/radeon/radeon_legacy_crtc.c | |||
@@ -1025,9 +1025,11 @@ static int radeon_crtc_mode_set(struct drm_crtc *crtc, | |||
1025 | 1025 | ||
1026 | static void radeon_crtc_prepare(struct drm_crtc *crtc) | 1026 | static void radeon_crtc_prepare(struct drm_crtc *crtc) |
1027 | { | 1027 | { |
1028 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
1028 | struct drm_device *dev = crtc->dev; | 1029 | struct drm_device *dev = crtc->dev; |
1029 | struct drm_crtc *crtci; | 1030 | struct drm_crtc *crtci; |
1030 | 1031 | ||
1032 | radeon_crtc->in_mode_set = true; | ||
1031 | /* | 1033 | /* |
1032 | * The hardware wedges sometimes if you reconfigure one CRTC | 1034 | * The hardware wedges sometimes if you reconfigure one CRTC |
1033 | * whilst another is running (see fdo bug #24611). | 1035 | * whilst another is running (see fdo bug #24611). |
@@ -1038,6 +1040,7 @@ static void radeon_crtc_prepare(struct drm_crtc *crtc) | |||
1038 | 1040 | ||
1039 | static void radeon_crtc_commit(struct drm_crtc *crtc) | 1041 | static void radeon_crtc_commit(struct drm_crtc *crtc) |
1040 | { | 1042 | { |
1043 | struct radeon_crtc *radeon_crtc = to_radeon_crtc(crtc); | ||
1041 | struct drm_device *dev = crtc->dev; | 1044 | struct drm_device *dev = crtc->dev; |
1042 | struct drm_crtc *crtci; | 1045 | struct drm_crtc *crtci; |
1043 | 1046 | ||
@@ -1048,6 +1051,7 @@ static void radeon_crtc_commit(struct drm_crtc *crtc) | |||
1048 | if (crtci->enabled) | 1051 | if (crtci->enabled) |
1049 | radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); | 1052 | radeon_crtc_dpms(crtci, DRM_MODE_DPMS_ON); |
1050 | } | 1053 | } |
1054 | radeon_crtc->in_mode_set = false; | ||
1051 | } | 1055 | } |
1052 | 1056 | ||
1053 | static const struct drm_crtc_helper_funcs legacy_helper_funcs = { | 1057 | static const struct drm_crtc_helper_funcs legacy_helper_funcs = { |
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h index f380d59c5763..d56978949f34 100644 --- a/drivers/gpu/drm/radeon/radeon_mode.h +++ b/drivers/gpu/drm/radeon/radeon_mode.h | |||
@@ -275,6 +275,7 @@ struct radeon_crtc { | |||
275 | u16 lut_r[256], lut_g[256], lut_b[256]; | 275 | u16 lut_r[256], lut_g[256], lut_b[256]; |
276 | bool enabled; | 276 | bool enabled; |
277 | bool can_tile; | 277 | bool can_tile; |
278 | bool in_mode_set; | ||
278 | uint32_t crtc_offset; | 279 | uint32_t crtc_offset; |
279 | struct drm_gem_object *cursor_bo; | 280 | struct drm_gem_object *cursor_bo; |
280 | uint64_t cursor_addr; | 281 | uint64_t cursor_addr; |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index 1f1a4c803c1d..1cb014b571ab 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -52,11 +52,7 @@ void radeon_bo_clear_va(struct radeon_bo *bo) | |||
52 | 52 | ||
53 | list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) { | 53 | list_for_each_entry_safe(bo_va, tmp, &bo->va, bo_list) { |
54 | /* remove from all vm address space */ | 54 | /* remove from all vm address space */ |
55 | mutex_lock(&bo_va->vm->mutex); | 55 | radeon_vm_bo_rmv(bo->rdev, bo_va->vm, bo); |
56 | list_del(&bo_va->vm_list); | ||
57 | mutex_unlock(&bo_va->vm->mutex); | ||
58 | list_del(&bo_va->bo_list); | ||
59 | kfree(bo_va); | ||
60 | } | 56 | } |
61 | } | 57 | } |
62 | 58 | ||
diff --git a/drivers/gpu/drm/radeon/rv515.c b/drivers/gpu/drm/radeon/rv515.c index a12fbcc8ccb6..aa8ef491ef3c 100644 --- a/drivers/gpu/drm/radeon/rv515.c +++ b/drivers/gpu/drm/radeon/rv515.c | |||
@@ -281,12 +281,8 @@ int rv515_debugfs_ga_info_init(struct radeon_device *rdev) | |||
281 | 281 | ||
282 | void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) | 282 | void rv515_mc_stop(struct radeon_device *rdev, struct rv515_mc_save *save) |
283 | { | 283 | { |
284 | save->d1vga_control = RREG32(R_000330_D1VGA_CONTROL); | ||
285 | save->d2vga_control = RREG32(R_000338_D2VGA_CONTROL); | ||
286 | save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); | 284 | save->vga_render_control = RREG32(R_000300_VGA_RENDER_CONTROL); |
287 | save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); | 285 | save->vga_hdp_control = RREG32(R_000328_VGA_HDP_CONTROL); |
288 | save->d1crtc_control = RREG32(R_006080_D1CRTC_CONTROL); | ||
289 | save->d2crtc_control = RREG32(R_006880_D2CRTC_CONTROL); | ||
290 | 286 | ||
291 | /* Stop all video */ | 287 | /* Stop all video */ |
292 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | 288 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); |
@@ -311,15 +307,6 @@ void rv515_mc_resume(struct radeon_device *rdev, struct rv515_mc_save *save) | |||
311 | /* Unlock host access */ | 307 | /* Unlock host access */ |
312 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); | 308 | WREG32(R_000328_VGA_HDP_CONTROL, save->vga_hdp_control); |
313 | mdelay(1); | 309 | mdelay(1); |
314 | /* Restore video state */ | ||
315 | WREG32(R_000330_D1VGA_CONTROL, save->d1vga_control); | ||
316 | WREG32(R_000338_D2VGA_CONTROL, save->d2vga_control); | ||
317 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 1); | ||
318 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 1); | ||
319 | WREG32(R_006080_D1CRTC_CONTROL, save->d1crtc_control); | ||
320 | WREG32(R_006880_D2CRTC_CONTROL, save->d2crtc_control); | ||
321 | WREG32(R_0060E8_D1CRTC_UPDATE_LOCK, 0); | ||
322 | WREG32(R_0068E8_D2CRTC_UPDATE_LOCK, 0); | ||
323 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); | 310 | WREG32(R_000300_VGA_RENDER_CONTROL, save->vga_render_control); |
324 | } | 311 | } |
325 | 312 | ||
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index c053f8193771..0139e227e3c7 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -1639,11 +1639,19 @@ static void si_gpu_init(struct radeon_device *rdev) | |||
1639 | /* XXX what about 12? */ | 1639 | /* XXX what about 12? */ |
1640 | rdev->config.si.tile_config |= (3 << 0); | 1640 | rdev->config.si.tile_config |= (3 << 0); |
1641 | break; | 1641 | break; |
1642 | } | 1642 | } |
1643 | if ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) | 1643 | switch ((mc_arb_ramcfg & NOOFBANK_MASK) >> NOOFBANK_SHIFT) { |
1644 | rdev->config.si.tile_config |= 1 << 4; | 1644 | case 0: /* four banks */ |
1645 | else | ||
1646 | rdev->config.si.tile_config |= 0 << 4; | 1645 | rdev->config.si.tile_config |= 0 << 4; |
1646 | break; | ||
1647 | case 1: /* eight banks */ | ||
1648 | rdev->config.si.tile_config |= 1 << 4; | ||
1649 | break; | ||
1650 | case 2: /* sixteen banks */ | ||
1651 | default: | ||
1652 | rdev->config.si.tile_config |= 2 << 4; | ||
1653 | break; | ||
1654 | } | ||
1647 | rdev->config.si.tile_config |= | 1655 | rdev->config.si.tile_config |= |
1648 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; | 1656 | ((gb_addr_config & PIPE_INTERLEAVE_SIZE_MASK) >> PIPE_INTERLEAVE_SIZE_SHIFT) << 8; |
1649 | rdev->config.si.tile_config |= | 1657 | rdev->config.si.tile_config |= |
@@ -3960,3 +3968,22 @@ void si_fini(struct radeon_device *rdev) | |||
3960 | rdev->bios = NULL; | 3968 | rdev->bios = NULL; |
3961 | } | 3969 | } |
3962 | 3970 | ||
3971 | /** | ||
3972 | * si_get_gpu_clock - return GPU clock counter snapshot | ||
3973 | * | ||
3974 | * @rdev: radeon_device pointer | ||
3975 | * | ||
3976 | * Fetches a GPU clock counter snapshot (SI). | ||
3977 | * Returns the 64 bit clock counter snapshot. | ||
3978 | */ | ||
3979 | uint64_t si_get_gpu_clock(struct radeon_device *rdev) | ||
3980 | { | ||
3981 | uint64_t clock; | ||
3982 | |||
3983 | mutex_lock(&rdev->gpu_clock_mutex); | ||
3984 | WREG32(RLC_CAPTURE_GPU_CLOCK_COUNT, 1); | ||
3985 | clock = (uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_LSB) | | ||
3986 | ((uint64_t)RREG32(RLC_GPU_CLOCK_COUNT_MSB) << 32ULL); | ||
3987 | mutex_unlock(&rdev->gpu_clock_mutex); | ||
3988 | return clock; | ||
3989 | } | ||
diff --git a/drivers/gpu/drm/radeon/sid.h b/drivers/gpu/drm/radeon/sid.h index 7869089e8761..ef4815c27b1c 100644 --- a/drivers/gpu/drm/radeon/sid.h +++ b/drivers/gpu/drm/radeon/sid.h | |||
@@ -698,6 +698,9 @@ | |||
698 | #define RLC_UCODE_ADDR 0xC32C | 698 | #define RLC_UCODE_ADDR 0xC32C |
699 | #define RLC_UCODE_DATA 0xC330 | 699 | #define RLC_UCODE_DATA 0xC330 |
700 | 700 | ||
701 | #define RLC_GPU_CLOCK_COUNT_LSB 0xC338 | ||
702 | #define RLC_GPU_CLOCK_COUNT_MSB 0xC33C | ||
703 | #define RLC_CAPTURE_GPU_CLOCK_COUNT 0xC340 | ||
701 | #define RLC_MC_CNTL 0xC344 | 704 | #define RLC_MC_CNTL 0xC344 |
702 | #define RLC_UCODE_CNTL 0xC348 | 705 | #define RLC_UCODE_CNTL 0xC348 |
703 | 706 | ||
diff --git a/drivers/gpu/drm/udl/Kconfig b/drivers/gpu/drm/udl/Kconfig index 0b5e096d39a6..56e0bf31d425 100644 --- a/drivers/gpu/drm/udl/Kconfig +++ b/drivers/gpu/drm/udl/Kconfig | |||
@@ -1,6 +1,7 @@ | |||
1 | config DRM_UDL | 1 | config DRM_UDL |
2 | tristate "DisplayLink" | 2 | tristate "DisplayLink" |
3 | depends on DRM && EXPERIMENTAL | 3 | depends on DRM && EXPERIMENTAL |
4 | depends on USB_ARCH_HAS_HCD | ||
4 | select DRM_USB | 5 | select DRM_USB |
5 | select FB_SYS_FILLRECT | 6 | select FB_SYS_FILLRECT |
6 | select FB_SYS_COPYAREA | 7 | select FB_SYS_COPYAREA |
diff --git a/drivers/gpu/drm/udl/udl_gem.c b/drivers/gpu/drm/udl/udl_gem.c index 7bd65bdd15a8..291ecc145585 100644 --- a/drivers/gpu/drm/udl/udl_gem.c +++ b/drivers/gpu/drm/udl/udl_gem.c | |||
@@ -308,7 +308,7 @@ struct drm_gem_object *udl_gem_prime_import(struct drm_device *dev, | |||
308 | /* need to attach */ | 308 | /* need to attach */ |
309 | attach = dma_buf_attach(dma_buf, dev->dev); | 309 | attach = dma_buf_attach(dma_buf, dev->dev); |
310 | if (IS_ERR(attach)) | 310 | if (IS_ERR(attach)) |
311 | return ERR_PTR(PTR_ERR(attach)); | 311 | return ERR_CAST(attach); |
312 | 312 | ||
313 | sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); | 313 | sg = dma_buf_map_attachment(attach, DMA_BIDIRECTIONAL); |
314 | if (IS_ERR(sg)) { | 314 | if (IS_ERR(sg)) { |
diff --git a/drivers/gpu/vga/vga_switcheroo.c b/drivers/gpu/vga/vga_switcheroo.c index 5b3c7d135dc9..e25cf31faab2 100644 --- a/drivers/gpu/vga/vga_switcheroo.c +++ b/drivers/gpu/vga/vga_switcheroo.c | |||
@@ -70,27 +70,12 @@ static struct vgasr_priv vgasr_priv = { | |||
70 | .clients = LIST_HEAD_INIT(vgasr_priv.clients), | 70 | .clients = LIST_HEAD_INIT(vgasr_priv.clients), |
71 | }; | 71 | }; |
72 | 72 | ||
73 | int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) | 73 | static bool vga_switcheroo_ready(void) |
74 | { | ||
75 | mutex_lock(&vgasr_mutex); | ||
76 | if (vgasr_priv.handler) { | ||
77 | mutex_unlock(&vgasr_mutex); | ||
78 | return -EINVAL; | ||
79 | } | ||
80 | |||
81 | vgasr_priv.handler = handler; | ||
82 | mutex_unlock(&vgasr_mutex); | ||
83 | return 0; | ||
84 | } | ||
85 | EXPORT_SYMBOL(vga_switcheroo_register_handler); | ||
86 | |||
87 | void vga_switcheroo_unregister_handler(void) | ||
88 | { | 74 | { |
89 | mutex_lock(&vgasr_mutex); | 75 | /* we're ready if we get two clients + handler */ |
90 | vgasr_priv.handler = NULL; | 76 | return !vgasr_priv.active && |
91 | mutex_unlock(&vgasr_mutex); | 77 | vgasr_priv.registered_clients == 2 && vgasr_priv.handler; |
92 | } | 78 | } |
93 | EXPORT_SYMBOL(vga_switcheroo_unregister_handler); | ||
94 | 79 | ||
95 | static void vga_switcheroo_enable(void) | 80 | static void vga_switcheroo_enable(void) |
96 | { | 81 | { |
@@ -98,7 +83,8 @@ static void vga_switcheroo_enable(void) | |||
98 | struct vga_switcheroo_client *client; | 83 | struct vga_switcheroo_client *client; |
99 | 84 | ||
100 | /* call the handler to init */ | 85 | /* call the handler to init */ |
101 | vgasr_priv.handler->init(); | 86 | if (vgasr_priv.handler->init) |
87 | vgasr_priv.handler->init(); | ||
102 | 88 | ||
103 | list_for_each_entry(client, &vgasr_priv.clients, list) { | 89 | list_for_each_entry(client, &vgasr_priv.clients, list) { |
104 | if (client->id != -1) | 90 | if (client->id != -1) |
@@ -113,6 +99,37 @@ static void vga_switcheroo_enable(void) | |||
113 | vgasr_priv.active = true; | 99 | vgasr_priv.active = true; |
114 | } | 100 | } |
115 | 101 | ||
102 | int vga_switcheroo_register_handler(struct vga_switcheroo_handler *handler) | ||
103 | { | ||
104 | mutex_lock(&vgasr_mutex); | ||
105 | if (vgasr_priv.handler) { | ||
106 | mutex_unlock(&vgasr_mutex); | ||
107 | return -EINVAL; | ||
108 | } | ||
109 | |||
110 | vgasr_priv.handler = handler; | ||
111 | if (vga_switcheroo_ready()) { | ||
112 | printk(KERN_INFO "vga_switcheroo: enabled\n"); | ||
113 | vga_switcheroo_enable(); | ||
114 | } | ||
115 | mutex_unlock(&vgasr_mutex); | ||
116 | return 0; | ||
117 | } | ||
118 | EXPORT_SYMBOL(vga_switcheroo_register_handler); | ||
119 | |||
120 | void vga_switcheroo_unregister_handler(void) | ||
121 | { | ||
122 | mutex_lock(&vgasr_mutex); | ||
123 | vgasr_priv.handler = NULL; | ||
124 | if (vgasr_priv.active) { | ||
125 | pr_info("vga_switcheroo: disabled\n"); | ||
126 | vga_switcheroo_debugfs_fini(&vgasr_priv); | ||
127 | vgasr_priv.active = false; | ||
128 | } | ||
129 | mutex_unlock(&vgasr_mutex); | ||
130 | } | ||
131 | EXPORT_SYMBOL(vga_switcheroo_unregister_handler); | ||
132 | |||
116 | static int register_client(struct pci_dev *pdev, | 133 | static int register_client(struct pci_dev *pdev, |
117 | const struct vga_switcheroo_client_ops *ops, | 134 | const struct vga_switcheroo_client_ops *ops, |
118 | int id, bool active) | 135 | int id, bool active) |
@@ -134,9 +151,7 @@ static int register_client(struct pci_dev *pdev, | |||
134 | if (client_is_vga(client)) | 151 | if (client_is_vga(client)) |
135 | vgasr_priv.registered_clients++; | 152 | vgasr_priv.registered_clients++; |
136 | 153 | ||
137 | /* if we get two clients + handler */ | 154 | if (vga_switcheroo_ready()) { |
138 | if (!vgasr_priv.active && | ||
139 | vgasr_priv.registered_clients == 2 && vgasr_priv.handler) { | ||
140 | printk(KERN_INFO "vga_switcheroo: enabled\n"); | 155 | printk(KERN_INFO "vga_switcheroo: enabled\n"); |
141 | vga_switcheroo_enable(); | 156 | vga_switcheroo_enable(); |
142 | } | 157 | } |
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c index faa16f80db9c..0fa356fe82cc 100644 --- a/drivers/hwmon/coretemp.c +++ b/drivers/hwmon/coretemp.c | |||
@@ -196,7 +196,7 @@ struct tjmax { | |||
196 | int tjmax; | 196 | int tjmax; |
197 | }; | 197 | }; |
198 | 198 | ||
199 | static struct tjmax __cpuinitconst tjmax_table[] = { | 199 | static const struct tjmax __cpuinitconst tjmax_table[] = { |
200 | { "CPU D410", 100000 }, | 200 | { "CPU D410", 100000 }, |
201 | { "CPU D425", 100000 }, | 201 | { "CPU D425", 100000 }, |
202 | { "CPU D510", 100000 }, | 202 | { "CPU D510", 100000 }, |
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index ab4825205a9d..5b1a6a666441 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
@@ -1206,7 +1206,7 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr, | |||
1206 | int err = -ENODEV; | 1206 | int err = -ENODEV; |
1207 | u16 val; | 1207 | u16 val; |
1208 | 1208 | ||
1209 | static const __initdata char *names[] = { | 1209 | static __initconst char *const names[] = { |
1210 | "W83627HF", | 1210 | "W83627HF", |
1211 | "W83627THF", | 1211 | "W83627THF", |
1212 | "W83697HF", | 1212 | "W83697HF", |
diff --git a/drivers/idle/intel_idle.c b/drivers/idle/intel_idle.c index f559088869f6..e8726177d103 100644 --- a/drivers/idle/intel_idle.c +++ b/drivers/idle/intel_idle.c | |||
@@ -606,8 +606,9 @@ static int __init intel_idle_init(void) | |||
606 | intel_idle_cpuidle_driver_init(); | 606 | intel_idle_cpuidle_driver_init(); |
607 | retval = cpuidle_register_driver(&intel_idle_driver); | 607 | retval = cpuidle_register_driver(&intel_idle_driver); |
608 | if (retval) { | 608 | if (retval) { |
609 | struct cpuidle_driver *drv = cpuidle_get_driver(); | ||
609 | printk(KERN_DEBUG PREFIX "intel_idle yielding to %s", | 610 | printk(KERN_DEBUG PREFIX "intel_idle yielding to %s", |
610 | cpuidle_get_driver()->name); | 611 | drv ? drv->name : "none"); |
611 | return retval; | 612 | return retval; |
612 | } | 613 | } |
613 | 614 | ||
diff --git a/drivers/iio/frequency/adf4350.c b/drivers/iio/frequency/adf4350.c index 59fbb3ae40e7..e35bb8f6fe75 100644 --- a/drivers/iio/frequency/adf4350.c +++ b/drivers/iio/frequency/adf4350.c | |||
@@ -129,7 +129,7 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) | |||
129 | { | 129 | { |
130 | struct adf4350_platform_data *pdata = st->pdata; | 130 | struct adf4350_platform_data *pdata = st->pdata; |
131 | u64 tmp; | 131 | u64 tmp; |
132 | u32 div_gcd, prescaler; | 132 | u32 div_gcd, prescaler, chspc; |
133 | u16 mdiv, r_cnt = 0; | 133 | u16 mdiv, r_cnt = 0; |
134 | u8 band_sel_div; | 134 | u8 band_sel_div; |
135 | 135 | ||
@@ -158,14 +158,20 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) | |||
158 | if (pdata->ref_div_factor) | 158 | if (pdata->ref_div_factor) |
159 | r_cnt = pdata->ref_div_factor - 1; | 159 | r_cnt = pdata->ref_div_factor - 1; |
160 | 160 | ||
161 | do { | 161 | chspc = st->chspc; |
162 | r_cnt = adf4350_tune_r_cnt(st, r_cnt); | ||
163 | 162 | ||
164 | st->r1_mod = st->fpfd / st->chspc; | 163 | do { |
165 | while (st->r1_mod > ADF4350_MAX_MODULUS) { | 164 | do { |
166 | r_cnt = adf4350_tune_r_cnt(st, r_cnt); | 165 | do { |
167 | st->r1_mod = st->fpfd / st->chspc; | 166 | r_cnt = adf4350_tune_r_cnt(st, r_cnt); |
168 | } | 167 | st->r1_mod = st->fpfd / chspc; |
168 | if (r_cnt > ADF4350_MAX_R_CNT) { | ||
169 | /* try higher spacing values */ | ||
170 | chspc++; | ||
171 | r_cnt = 0; | ||
172 | } | ||
173 | } while ((st->r1_mod > ADF4350_MAX_MODULUS) && r_cnt); | ||
174 | } while (r_cnt == 0); | ||
169 | 175 | ||
170 | tmp = freq * (u64)st->r1_mod + (st->fpfd > 1); | 176 | tmp = freq * (u64)st->r1_mod + (st->fpfd > 1); |
171 | do_div(tmp, st->fpfd); /* Div round closest (n + d/2)/d */ | 177 | do_div(tmp, st->fpfd); /* Div round closest (n + d/2)/d */ |
@@ -194,7 +200,7 @@ static int adf4350_set_freq(struct adf4350_state *st, unsigned long long freq) | |||
194 | st->regs[ADF4350_REG0] = ADF4350_REG0_INT(st->r0_int) | | 200 | st->regs[ADF4350_REG0] = ADF4350_REG0_INT(st->r0_int) | |
195 | ADF4350_REG0_FRACT(st->r0_fract); | 201 | ADF4350_REG0_FRACT(st->r0_fract); |
196 | 202 | ||
197 | st->regs[ADF4350_REG1] = ADF4350_REG1_PHASE(0) | | 203 | st->regs[ADF4350_REG1] = ADF4350_REG1_PHASE(1) | |
198 | ADF4350_REG1_MOD(st->r1_mod) | | 204 | ADF4350_REG1_MOD(st->r1_mod) | |
199 | prescaler; | 205 | prescaler; |
200 | 206 | ||
diff --git a/drivers/iio/light/adjd_s311.c b/drivers/iio/light/adjd_s311.c index 1cbb449b319a..9a99f43094f0 100644 --- a/drivers/iio/light/adjd_s311.c +++ b/drivers/iio/light/adjd_s311.c | |||
@@ -271,9 +271,10 @@ static int adjd_s311_update_scan_mode(struct iio_dev *indio_dev, | |||
271 | const unsigned long *scan_mask) | 271 | const unsigned long *scan_mask) |
272 | { | 272 | { |
273 | struct adjd_s311_data *data = iio_priv(indio_dev); | 273 | struct adjd_s311_data *data = iio_priv(indio_dev); |
274 | data->buffer = krealloc(data->buffer, indio_dev->scan_bytes, | 274 | |
275 | GFP_KERNEL); | 275 | kfree(data->buffer); |
276 | if (!data->buffer) | 276 | data->buffer = kmalloc(indio_dev->scan_bytes, GFP_KERNEL); |
277 | if (data->buffer == NULL) | ||
277 | return -ENOMEM; | 278 | return -ENOMEM; |
278 | 279 | ||
279 | return 0; | 280 | return 0; |
diff --git a/drivers/iio/light/lm3533-als.c b/drivers/iio/light/lm3533-als.c index c3e7bac13123..e45712a921ce 100644 --- a/drivers/iio/light/lm3533-als.c +++ b/drivers/iio/light/lm3533-als.c | |||
@@ -404,7 +404,7 @@ out: | |||
404 | return ret; | 404 | return ret; |
405 | } | 405 | } |
406 | 406 | ||
407 | static int show_thresh_either_en(struct device *dev, | 407 | static ssize_t show_thresh_either_en(struct device *dev, |
408 | struct device_attribute *attr, | 408 | struct device_attribute *attr, |
409 | char *buf) | 409 | char *buf) |
410 | { | 410 | { |
@@ -424,7 +424,7 @@ static int show_thresh_either_en(struct device *dev, | |||
424 | return scnprintf(buf, PAGE_SIZE, "%u\n", enable); | 424 | return scnprintf(buf, PAGE_SIZE, "%u\n", enable); |
425 | } | 425 | } |
426 | 426 | ||
427 | static int store_thresh_either_en(struct device *dev, | 427 | static ssize_t store_thresh_either_en(struct device *dev, |
428 | struct device_attribute *attr, | 428 | struct device_attribute *attr, |
429 | const char *buf, size_t len) | 429 | const char *buf, size_t len) |
430 | { | 430 | { |
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index 6bf850422895..055ed59838dc 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c | |||
@@ -267,6 +267,7 @@ static int ucma_event_handler(struct rdma_cm_id *cm_id, | |||
267 | if (!uevent) | 267 | if (!uevent) |
268 | return event->event == RDMA_CM_EVENT_CONNECT_REQUEST; | 268 | return event->event == RDMA_CM_EVENT_CONNECT_REQUEST; |
269 | 269 | ||
270 | mutex_lock(&ctx->file->mut); | ||
270 | uevent->cm_id = cm_id; | 271 | uevent->cm_id = cm_id; |
271 | ucma_set_event_context(ctx, event, uevent); | 272 | ucma_set_event_context(ctx, event, uevent); |
272 | uevent->resp.event = event->event; | 273 | uevent->resp.event = event->event; |
@@ -277,7 +278,6 @@ static int ucma_event_handler(struct rdma_cm_id *cm_id, | |||
277 | ucma_copy_conn_event(&uevent->resp.param.conn, | 278 | ucma_copy_conn_event(&uevent->resp.param.conn, |
278 | &event->param.conn); | 279 | &event->param.conn); |
279 | 280 | ||
280 | mutex_lock(&ctx->file->mut); | ||
281 | if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST) { | 281 | if (event->event == RDMA_CM_EVENT_CONNECT_REQUEST) { |
282 | if (!ctx->backlog) { | 282 | if (!ctx->backlog) { |
283 | ret = -ENOMEM; | 283 | ret = -ENOMEM; |
diff --git a/drivers/infiniband/hw/amso1100/c2_rnic.c b/drivers/infiniband/hw/amso1100/c2_rnic.c index 8c81992fa6db..e4a73158fc7f 100644 --- a/drivers/infiniband/hw/amso1100/c2_rnic.c +++ b/drivers/infiniband/hw/amso1100/c2_rnic.c | |||
@@ -439,7 +439,7 @@ static int c2_rnic_close(struct c2_dev *c2dev) | |||
439 | 439 | ||
440 | /* | 440 | /* |
441 | * Called by c2_probe to initialize the RNIC. This principally | 441 | * Called by c2_probe to initialize the RNIC. This principally |
442 | * involves initalizing the various limits and resouce pools that | 442 | * involves initializing the various limits and resource pools that |
443 | * comprise the RNIC instance. | 443 | * comprise the RNIC instance. |
444 | */ | 444 | */ |
445 | int __devinit c2_rnic_init(struct c2_dev *c2dev) | 445 | int __devinit c2_rnic_init(struct c2_dev *c2dev) |
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c index 77b6b182778a..aaf88ef9409c 100644 --- a/drivers/infiniband/hw/cxgb3/iwch_cm.c +++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c | |||
@@ -1680,7 +1680,7 @@ static int close_con_rpl(struct t3cdev *tdev, struct sk_buff *skb, void *ctx) | |||
1680 | * T3A does 3 things when a TERM is received: | 1680 | * T3A does 3 things when a TERM is received: |
1681 | * 1) send up a CPL_RDMA_TERMINATE message with the TERM packet | 1681 | * 1) send up a CPL_RDMA_TERMINATE message with the TERM packet |
1682 | * 2) generate an async event on the QP with the TERMINATE opcode | 1682 | * 2) generate an async event on the QP with the TERMINATE opcode |
1683 | * 3) post a TERMINATE opcde cqe into the associated CQ. | 1683 | * 3) post a TERMINATE opcode cqe into the associated CQ. |
1684 | * | 1684 | * |
1685 | * For (1), we save the message in the qp for later consumer consumption. | 1685 | * For (1), we save the message in the qp for later consumer consumption. |
1686 | * For (2), we move the QP into TERMINATE, post a QP event and disconnect. | 1686 | * For (2), we move the QP into TERMINATE, post a QP event and disconnect. |
diff --git a/drivers/infiniband/hw/mlx4/mad.c b/drivers/infiniband/hw/mlx4/mad.c index c27141fef1ab..9c2ae7efd00f 100644 --- a/drivers/infiniband/hw/mlx4/mad.c +++ b/drivers/infiniband/hw/mlx4/mad.c | |||
@@ -125,6 +125,7 @@ static void update_sm_ah(struct mlx4_ib_dev *dev, u8 port_num, u16 lid, u8 sl) | |||
125 | { | 125 | { |
126 | struct ib_ah *new_ah; | 126 | struct ib_ah *new_ah; |
127 | struct ib_ah_attr ah_attr; | 127 | struct ib_ah_attr ah_attr; |
128 | unsigned long flags; | ||
128 | 129 | ||
129 | if (!dev->send_agent[port_num - 1][0]) | 130 | if (!dev->send_agent[port_num - 1][0]) |
130 | return; | 131 | return; |
@@ -139,11 +140,11 @@ static void update_sm_ah(struct mlx4_ib_dev *dev, u8 port_num, u16 lid, u8 sl) | |||
139 | if (IS_ERR(new_ah)) | 140 | if (IS_ERR(new_ah)) |
140 | return; | 141 | return; |
141 | 142 | ||
142 | spin_lock(&dev->sm_lock); | 143 | spin_lock_irqsave(&dev->sm_lock, flags); |
143 | if (dev->sm_ah[port_num - 1]) | 144 | if (dev->sm_ah[port_num - 1]) |
144 | ib_destroy_ah(dev->sm_ah[port_num - 1]); | 145 | ib_destroy_ah(dev->sm_ah[port_num - 1]); |
145 | dev->sm_ah[port_num - 1] = new_ah; | 146 | dev->sm_ah[port_num - 1] = new_ah; |
146 | spin_unlock(&dev->sm_lock); | 147 | spin_unlock_irqrestore(&dev->sm_lock, flags); |
147 | } | 148 | } |
148 | 149 | ||
149 | /* | 150 | /* |
@@ -197,13 +198,15 @@ static void smp_snoop(struct ib_device *ibdev, u8 port_num, struct ib_mad *mad, | |||
197 | static void node_desc_override(struct ib_device *dev, | 198 | static void node_desc_override(struct ib_device *dev, |
198 | struct ib_mad *mad) | 199 | struct ib_mad *mad) |
199 | { | 200 | { |
201 | unsigned long flags; | ||
202 | |||
200 | if ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED || | 203 | if ((mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_LID_ROUTED || |
201 | mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) && | 204 | mad->mad_hdr.mgmt_class == IB_MGMT_CLASS_SUBN_DIRECTED_ROUTE) && |
202 | mad->mad_hdr.method == IB_MGMT_METHOD_GET_RESP && | 205 | mad->mad_hdr.method == IB_MGMT_METHOD_GET_RESP && |
203 | mad->mad_hdr.attr_id == IB_SMP_ATTR_NODE_DESC) { | 206 | mad->mad_hdr.attr_id == IB_SMP_ATTR_NODE_DESC) { |
204 | spin_lock(&to_mdev(dev)->sm_lock); | 207 | spin_lock_irqsave(&to_mdev(dev)->sm_lock, flags); |
205 | memcpy(((struct ib_smp *) mad)->data, dev->node_desc, 64); | 208 | memcpy(((struct ib_smp *) mad)->data, dev->node_desc, 64); |
206 | spin_unlock(&to_mdev(dev)->sm_lock); | 209 | spin_unlock_irqrestore(&to_mdev(dev)->sm_lock, flags); |
207 | } | 210 | } |
208 | } | 211 | } |
209 | 212 | ||
@@ -213,6 +216,7 @@ static void forward_trap(struct mlx4_ib_dev *dev, u8 port_num, struct ib_mad *ma | |||
213 | struct ib_mad_send_buf *send_buf; | 216 | struct ib_mad_send_buf *send_buf; |
214 | struct ib_mad_agent *agent = dev->send_agent[port_num - 1][qpn]; | 217 | struct ib_mad_agent *agent = dev->send_agent[port_num - 1][qpn]; |
215 | int ret; | 218 | int ret; |
219 | unsigned long flags; | ||
216 | 220 | ||
217 | if (agent) { | 221 | if (agent) { |
218 | send_buf = ib_create_send_mad(agent, qpn, 0, 0, IB_MGMT_MAD_HDR, | 222 | send_buf = ib_create_send_mad(agent, qpn, 0, 0, IB_MGMT_MAD_HDR, |
@@ -225,13 +229,13 @@ static void forward_trap(struct mlx4_ib_dev *dev, u8 port_num, struct ib_mad *ma | |||
225 | * wrong following the IB spec strictly, but we know | 229 | * wrong following the IB spec strictly, but we know |
226 | * it's OK for our devices). | 230 | * it's OK for our devices). |
227 | */ | 231 | */ |
228 | spin_lock(&dev->sm_lock); | 232 | spin_lock_irqsave(&dev->sm_lock, flags); |
229 | memcpy(send_buf->mad, mad, sizeof *mad); | 233 | memcpy(send_buf->mad, mad, sizeof *mad); |
230 | if ((send_buf->ah = dev->sm_ah[port_num - 1])) | 234 | if ((send_buf->ah = dev->sm_ah[port_num - 1])) |
231 | ret = ib_post_send_mad(send_buf, NULL); | 235 | ret = ib_post_send_mad(send_buf, NULL); |
232 | else | 236 | else |
233 | ret = -EINVAL; | 237 | ret = -EINVAL; |
234 | spin_unlock(&dev->sm_lock); | 238 | spin_unlock_irqrestore(&dev->sm_lock, flags); |
235 | 239 | ||
236 | if (ret) | 240 | if (ret) |
237 | ib_free_send_mad(send_buf); | 241 | ib_free_send_mad(send_buf); |
diff --git a/drivers/infiniband/hw/mlx4/main.c b/drivers/infiniband/hw/mlx4/main.c index fe2088cfa6ee..cc05579ebce7 100644 --- a/drivers/infiniband/hw/mlx4/main.c +++ b/drivers/infiniband/hw/mlx4/main.c | |||
@@ -423,6 +423,7 @@ static int mlx4_ib_modify_device(struct ib_device *ibdev, int mask, | |||
423 | struct ib_device_modify *props) | 423 | struct ib_device_modify *props) |
424 | { | 424 | { |
425 | struct mlx4_cmd_mailbox *mailbox; | 425 | struct mlx4_cmd_mailbox *mailbox; |
426 | unsigned long flags; | ||
426 | 427 | ||
427 | if (mask & ~IB_DEVICE_MODIFY_NODE_DESC) | 428 | if (mask & ~IB_DEVICE_MODIFY_NODE_DESC) |
428 | return -EOPNOTSUPP; | 429 | return -EOPNOTSUPP; |
@@ -430,9 +431,9 @@ static int mlx4_ib_modify_device(struct ib_device *ibdev, int mask, | |||
430 | if (!(mask & IB_DEVICE_MODIFY_NODE_DESC)) | 431 | if (!(mask & IB_DEVICE_MODIFY_NODE_DESC)) |
431 | return 0; | 432 | return 0; |
432 | 433 | ||
433 | spin_lock(&to_mdev(ibdev)->sm_lock); | 434 | spin_lock_irqsave(&to_mdev(ibdev)->sm_lock, flags); |
434 | memcpy(ibdev->node_desc, props->node_desc, 64); | 435 | memcpy(ibdev->node_desc, props->node_desc, 64); |
435 | spin_unlock(&to_mdev(ibdev)->sm_lock); | 436 | spin_unlock_irqrestore(&to_mdev(ibdev)->sm_lock, flags); |
436 | 437 | ||
437 | /* | 438 | /* |
438 | * If possible, pass node desc to FW, so it can generate | 439 | * If possible, pass node desc to FW, so it can generate |
diff --git a/drivers/infiniband/hw/mlx4/qp.c b/drivers/infiniband/hw/mlx4/qp.c index a6d8ea060ea8..f585eddef4b7 100644 --- a/drivers/infiniband/hw/mlx4/qp.c +++ b/drivers/infiniband/hw/mlx4/qp.c | |||
@@ -1407,6 +1407,7 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr, | |||
1407 | struct mlx4_wqe_mlx_seg *mlx = wqe; | 1407 | struct mlx4_wqe_mlx_seg *mlx = wqe; |
1408 | struct mlx4_wqe_inline_seg *inl = wqe + sizeof *mlx; | 1408 | struct mlx4_wqe_inline_seg *inl = wqe + sizeof *mlx; |
1409 | struct mlx4_ib_ah *ah = to_mah(wr->wr.ud.ah); | 1409 | struct mlx4_ib_ah *ah = to_mah(wr->wr.ud.ah); |
1410 | struct net_device *ndev; | ||
1410 | union ib_gid sgid; | 1411 | union ib_gid sgid; |
1411 | u16 pkey; | 1412 | u16 pkey; |
1412 | int send_size; | 1413 | int send_size; |
@@ -1483,7 +1484,10 @@ static int build_mlx_header(struct mlx4_ib_sqp *sqp, struct ib_send_wr *wr, | |||
1483 | 1484 | ||
1484 | memcpy(sqp->ud_header.eth.dmac_h, ah->av.eth.mac, 6); | 1485 | memcpy(sqp->ud_header.eth.dmac_h, ah->av.eth.mac, 6); |
1485 | /* FIXME: cache smac value? */ | 1486 | /* FIXME: cache smac value? */ |
1486 | smac = to_mdev(sqp->qp.ibqp.device)->iboe.netdevs[sqp->qp.port - 1]->dev_addr; | 1487 | ndev = to_mdev(sqp->qp.ibqp.device)->iboe.netdevs[sqp->qp.port - 1]; |
1488 | if (!ndev) | ||
1489 | return -ENODEV; | ||
1490 | smac = ndev->dev_addr; | ||
1487 | memcpy(sqp->ud_header.eth.smac_h, smac, 6); | 1491 | memcpy(sqp->ud_header.eth.smac_h, smac, 6); |
1488 | if (!memcmp(sqp->ud_header.eth.smac_h, sqp->ud_header.eth.dmac_h, 6)) | 1492 | if (!memcmp(sqp->ud_header.eth.smac_h, sqp->ud_header.eth.dmac_h, 6)) |
1489 | mlx->flags |= cpu_to_be32(MLX4_WQE_CTRL_FORCE_LOOPBACK); | 1493 | mlx->flags |= cpu_to_be32(MLX4_WQE_CTRL_FORCE_LOOPBACK); |
diff --git a/drivers/infiniband/hw/ocrdma/ocrdma_main.c b/drivers/infiniband/hw/ocrdma/ocrdma_main.c index 5a044526e4f4..c4e0131f1b57 100644 --- a/drivers/infiniband/hw/ocrdma/ocrdma_main.c +++ b/drivers/infiniband/hw/ocrdma/ocrdma_main.c | |||
@@ -161,7 +161,7 @@ static void ocrdma_add_default_sgid(struct ocrdma_dev *dev) | |||
161 | ocrdma_get_guid(dev, &sgid->raw[8]); | 161 | ocrdma_get_guid(dev, &sgid->raw[8]); |
162 | } | 162 | } |
163 | 163 | ||
164 | #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE) | 164 | #if IS_ENABLED(CONFIG_VLAN_8021Q) |
165 | static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) | 165 | static void ocrdma_add_vlan_sgids(struct ocrdma_dev *dev) |
166 | { | 166 | { |
167 | struct net_device *netdev, *tmp; | 167 | struct net_device *netdev, *tmp; |
@@ -202,14 +202,13 @@ static int ocrdma_build_sgid_tbl(struct ocrdma_dev *dev) | |||
202 | return 0; | 202 | return 0; |
203 | } | 203 | } |
204 | 204 | ||
205 | #if IS_ENABLED(CONFIG_IPV6) || IS_ENABLED(CONFIG_VLAN_8021Q) | 205 | #if IS_ENABLED(CONFIG_IPV6) |
206 | 206 | ||
207 | static int ocrdma_inet6addr_event(struct notifier_block *notifier, | 207 | static int ocrdma_inet6addr_event(struct notifier_block *notifier, |
208 | unsigned long event, void *ptr) | 208 | unsigned long event, void *ptr) |
209 | { | 209 | { |
210 | struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; | 210 | struct inet6_ifaddr *ifa = (struct inet6_ifaddr *)ptr; |
211 | struct net_device *event_netdev = ifa->idev->dev; | 211 | struct net_device *netdev = ifa->idev->dev; |
212 | struct net_device *netdev = NULL; | ||
213 | struct ib_event gid_event; | 212 | struct ib_event gid_event; |
214 | struct ocrdma_dev *dev; | 213 | struct ocrdma_dev *dev; |
215 | bool found = false; | 214 | bool found = false; |
@@ -217,11 +216,12 @@ static int ocrdma_inet6addr_event(struct notifier_block *notifier, | |||
217 | bool is_vlan = false; | 216 | bool is_vlan = false; |
218 | u16 vid = 0; | 217 | u16 vid = 0; |
219 | 218 | ||
220 | netdev = vlan_dev_real_dev(event_netdev); | 219 | is_vlan = netdev->priv_flags & IFF_802_1Q_VLAN; |
221 | if (netdev != event_netdev) { | 220 | if (is_vlan) { |
222 | is_vlan = true; | 221 | vid = vlan_dev_vlan_id(netdev); |
223 | vid = vlan_dev_vlan_id(event_netdev); | 222 | netdev = vlan_dev_real_dev(netdev); |
224 | } | 223 | } |
224 | |||
225 | rcu_read_lock(); | 225 | rcu_read_lock(); |
226 | list_for_each_entry_rcu(dev, &ocrdma_dev_list, entry) { | 226 | list_for_each_entry_rcu(dev, &ocrdma_dev_list, entry) { |
227 | if (dev->nic_info.netdev == netdev) { | 227 | if (dev->nic_info.netdev == netdev) { |
diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 0d7280af99bc..3f6b21e9dc11 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c | |||
@@ -6346,8 +6346,10 @@ static int qib_init_7322_variables(struct qib_devdata *dd) | |||
6346 | dd->piobcnt4k * dd->align4k; | 6346 | dd->piobcnt4k * dd->align4k; |
6347 | dd->piovl15base = ioremap_nocache(vl15off, | 6347 | dd->piovl15base = ioremap_nocache(vl15off, |
6348 | NUM_VL15_BUFS * dd->align4k); | 6348 | NUM_VL15_BUFS * dd->align4k); |
6349 | if (!dd->piovl15base) | 6349 | if (!dd->piovl15base) { |
6350 | ret = -ENOMEM; | ||
6350 | goto bail; | 6351 | goto bail; |
6352 | } | ||
6351 | } | 6353 | } |
6352 | qib_7322_set_baseaddrs(dd); /* set chip access pointers now */ | 6354 | qib_7322_set_baseaddrs(dd); /* set chip access pointers now */ |
6353 | 6355 | ||
diff --git a/drivers/infiniband/hw/qib/qib_sd7220.c b/drivers/infiniband/hw/qib/qib_sd7220.c index a322d5171a2c..50a8a0d4fe67 100644 --- a/drivers/infiniband/hw/qib/qib_sd7220.c +++ b/drivers/infiniband/hw/qib/qib_sd7220.c | |||
@@ -372,7 +372,7 @@ static void qib_sd_trimdone_monitor(struct qib_devdata *dd, | |||
372 | /* Read CTRL reg for each channel to check TRIMDONE */ | 372 | /* Read CTRL reg for each channel to check TRIMDONE */ |
373 | if (baduns & (1 << chn)) { | 373 | if (baduns & (1 << chn)) { |
374 | qib_dev_err(dd, | 374 | qib_dev_err(dd, |
375 | "Reseting TRIMDONE on chn %d (%s)\n", | 375 | "Resetting TRIMDONE on chn %d (%s)\n", |
376 | chn, where); | 376 | chn, where); |
377 | ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, | 377 | ret = qib_sd7220_reg_mod(dd, IB_7220_SERDES, |
378 | IB_CTRL2(chn), 0x10, 0x10); | 378 | IB_CTRL2(chn), 0x10, 0x10); |
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c index 95ecf4eadf5f..24683fda8e21 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c | |||
@@ -1271,12 +1271,15 @@ struct ipoib_cm_tx *ipoib_cm_create_tx(struct net_device *dev, struct ipoib_path | |||
1271 | void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx) | 1271 | void ipoib_cm_destroy_tx(struct ipoib_cm_tx *tx) |
1272 | { | 1272 | { |
1273 | struct ipoib_dev_priv *priv = netdev_priv(tx->dev); | 1273 | struct ipoib_dev_priv *priv = netdev_priv(tx->dev); |
1274 | unsigned long flags; | ||
1274 | if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) { | 1275 | if (test_and_clear_bit(IPOIB_FLAG_INITIALIZED, &tx->flags)) { |
1276 | spin_lock_irqsave(&priv->lock, flags); | ||
1275 | list_move(&tx->list, &priv->cm.reap_list); | 1277 | list_move(&tx->list, &priv->cm.reap_list); |
1276 | queue_work(ipoib_workqueue, &priv->cm.reap_task); | 1278 | queue_work(ipoib_workqueue, &priv->cm.reap_task); |
1277 | ipoib_dbg(priv, "Reap connection for gid %pI6\n", | 1279 | ipoib_dbg(priv, "Reap connection for gid %pI6\n", |
1278 | tx->neigh->daddr + 4); | 1280 | tx->neigh->daddr + 4); |
1279 | tx->neigh = NULL; | 1281 | tx->neigh = NULL; |
1282 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1280 | } | 1283 | } |
1281 | } | 1284 | } |
1282 | 1285 | ||
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_main.c b/drivers/infiniband/ulp/ipoib/ipoib_main.c index 97920b77a5d0..3e2085a3ee47 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_main.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_main.c | |||
@@ -1052,7 +1052,7 @@ void ipoib_neigh_free(struct ipoib_neigh *neigh) | |||
1052 | for (n = rcu_dereference_protected(*np, | 1052 | for (n = rcu_dereference_protected(*np, |
1053 | lockdep_is_held(&ntbl->rwlock)); | 1053 | lockdep_is_held(&ntbl->rwlock)); |
1054 | n != NULL; | 1054 | n != NULL; |
1055 | n = rcu_dereference_protected(neigh->hnext, | 1055 | n = rcu_dereference_protected(*np, |
1056 | lockdep_is_held(&ntbl->rwlock))) { | 1056 | lockdep_is_held(&ntbl->rwlock))) { |
1057 | if (n == neigh) { | 1057 | if (n == neigh) { |
1058 | /* found */ | 1058 | /* found */ |
diff --git a/drivers/infiniband/ulp/srp/ib_srp.c b/drivers/infiniband/ulp/srp/ib_srp.c index bcbf22ee0aa7..1b5b0c730054 100644 --- a/drivers/infiniband/ulp/srp/ib_srp.c +++ b/drivers/infiniband/ulp/srp/ib_srp.c | |||
@@ -586,24 +586,62 @@ static void srp_unmap_data(struct scsi_cmnd *scmnd, | |||
586 | scmnd->sc_data_direction); | 586 | scmnd->sc_data_direction); |
587 | } | 587 | } |
588 | 588 | ||
589 | static void srp_remove_req(struct srp_target_port *target, | 589 | /** |
590 | struct srp_request *req, s32 req_lim_delta) | 590 | * srp_claim_req - Take ownership of the scmnd associated with a request. |
591 | * @target: SRP target port. | ||
592 | * @req: SRP request. | ||
593 | * @scmnd: If NULL, take ownership of @req->scmnd. If not NULL, only take | ||
594 | * ownership of @req->scmnd if it equals @scmnd. | ||
595 | * | ||
596 | * Return value: | ||
597 | * Either NULL or a pointer to the SCSI command the caller became owner of. | ||
598 | */ | ||
599 | static struct scsi_cmnd *srp_claim_req(struct srp_target_port *target, | ||
600 | struct srp_request *req, | ||
601 | struct scsi_cmnd *scmnd) | ||
602 | { | ||
603 | unsigned long flags; | ||
604 | |||
605 | spin_lock_irqsave(&target->lock, flags); | ||
606 | if (!scmnd) { | ||
607 | scmnd = req->scmnd; | ||
608 | req->scmnd = NULL; | ||
609 | } else if (req->scmnd == scmnd) { | ||
610 | req->scmnd = NULL; | ||
611 | } else { | ||
612 | scmnd = NULL; | ||
613 | } | ||
614 | spin_unlock_irqrestore(&target->lock, flags); | ||
615 | |||
616 | return scmnd; | ||
617 | } | ||
618 | |||
619 | /** | ||
620 | * srp_free_req() - Unmap data and add request to the free request list. | ||
621 | */ | ||
622 | static void srp_free_req(struct srp_target_port *target, | ||
623 | struct srp_request *req, struct scsi_cmnd *scmnd, | ||
624 | s32 req_lim_delta) | ||
591 | { | 625 | { |
592 | unsigned long flags; | 626 | unsigned long flags; |
593 | 627 | ||
594 | srp_unmap_data(req->scmnd, target, req); | 628 | srp_unmap_data(scmnd, target, req); |
629 | |||
595 | spin_lock_irqsave(&target->lock, flags); | 630 | spin_lock_irqsave(&target->lock, flags); |
596 | target->req_lim += req_lim_delta; | 631 | target->req_lim += req_lim_delta; |
597 | req->scmnd = NULL; | ||
598 | list_add_tail(&req->list, &target->free_reqs); | 632 | list_add_tail(&req->list, &target->free_reqs); |
599 | spin_unlock_irqrestore(&target->lock, flags); | 633 | spin_unlock_irqrestore(&target->lock, flags); |
600 | } | 634 | } |
601 | 635 | ||
602 | static void srp_reset_req(struct srp_target_port *target, struct srp_request *req) | 636 | static void srp_reset_req(struct srp_target_port *target, struct srp_request *req) |
603 | { | 637 | { |
604 | req->scmnd->result = DID_RESET << 16; | 638 | struct scsi_cmnd *scmnd = srp_claim_req(target, req, NULL); |
605 | req->scmnd->scsi_done(req->scmnd); | 639 | |
606 | srp_remove_req(target, req, 0); | 640 | if (scmnd) { |
641 | scmnd->result = DID_RESET << 16; | ||
642 | scmnd->scsi_done(scmnd); | ||
643 | srp_free_req(target, req, scmnd, 0); | ||
644 | } | ||
607 | } | 645 | } |
608 | 646 | ||
609 | static int srp_reconnect_target(struct srp_target_port *target) | 647 | static int srp_reconnect_target(struct srp_target_port *target) |
@@ -1073,11 +1111,18 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | |||
1073 | complete(&target->tsk_mgmt_done); | 1111 | complete(&target->tsk_mgmt_done); |
1074 | } else { | 1112 | } else { |
1075 | req = &target->req_ring[rsp->tag]; | 1113 | req = &target->req_ring[rsp->tag]; |
1076 | scmnd = req->scmnd; | 1114 | scmnd = srp_claim_req(target, req, NULL); |
1077 | if (!scmnd) | 1115 | if (!scmnd) { |
1078 | shost_printk(KERN_ERR, target->scsi_host, | 1116 | shost_printk(KERN_ERR, target->scsi_host, |
1079 | "Null scmnd for RSP w/tag %016llx\n", | 1117 | "Null scmnd for RSP w/tag %016llx\n", |
1080 | (unsigned long long) rsp->tag); | 1118 | (unsigned long long) rsp->tag); |
1119 | |||
1120 | spin_lock_irqsave(&target->lock, flags); | ||
1121 | target->req_lim += be32_to_cpu(rsp->req_lim_delta); | ||
1122 | spin_unlock_irqrestore(&target->lock, flags); | ||
1123 | |||
1124 | return; | ||
1125 | } | ||
1081 | scmnd->result = rsp->status; | 1126 | scmnd->result = rsp->status; |
1082 | 1127 | ||
1083 | if (rsp->flags & SRP_RSP_FLAG_SNSVALID) { | 1128 | if (rsp->flags & SRP_RSP_FLAG_SNSVALID) { |
@@ -1092,7 +1137,9 @@ static void srp_process_rsp(struct srp_target_port *target, struct srp_rsp *rsp) | |||
1092 | else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER)) | 1137 | else if (rsp->flags & (SRP_RSP_FLAG_DIOVER | SRP_RSP_FLAG_DIUNDER)) |
1093 | scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt)); | 1138 | scsi_set_resid(scmnd, be32_to_cpu(rsp->data_in_res_cnt)); |
1094 | 1139 | ||
1095 | srp_remove_req(target, req, be32_to_cpu(rsp->req_lim_delta)); | 1140 | srp_free_req(target, req, scmnd, |
1141 | be32_to_cpu(rsp->req_lim_delta)); | ||
1142 | |||
1096 | scmnd->host_scribble = NULL; | 1143 | scmnd->host_scribble = NULL; |
1097 | scmnd->scsi_done(scmnd); | 1144 | scmnd->scsi_done(scmnd); |
1098 | } | 1145 | } |
@@ -1631,25 +1678,17 @@ static int srp_abort(struct scsi_cmnd *scmnd) | |||
1631 | { | 1678 | { |
1632 | struct srp_target_port *target = host_to_target(scmnd->device->host); | 1679 | struct srp_target_port *target = host_to_target(scmnd->device->host); |
1633 | struct srp_request *req = (struct srp_request *) scmnd->host_scribble; | 1680 | struct srp_request *req = (struct srp_request *) scmnd->host_scribble; |
1634 | int ret = SUCCESS; | ||
1635 | 1681 | ||
1636 | shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); | 1682 | shost_printk(KERN_ERR, target->scsi_host, "SRP abort called\n"); |
1637 | 1683 | ||
1638 | if (!req || target->qp_in_error) | 1684 | if (!req || target->qp_in_error || !srp_claim_req(target, req, scmnd)) |
1639 | return FAILED; | 1685 | return FAILED; |
1640 | if (srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, | 1686 | srp_send_tsk_mgmt(target, req->index, scmnd->device->lun, |
1641 | SRP_TSK_ABORT_TASK)) | 1687 | SRP_TSK_ABORT_TASK); |
1642 | return FAILED; | 1688 | srp_free_req(target, req, scmnd, 0); |
1643 | 1689 | scmnd->result = DID_ABORT << 16; | |
1644 | if (req->scmnd) { | ||
1645 | if (!target->tsk_mgmt_status) { | ||
1646 | srp_remove_req(target, req, 0); | ||
1647 | scmnd->result = DID_ABORT << 16; | ||
1648 | } else | ||
1649 | ret = FAILED; | ||
1650 | } | ||
1651 | 1690 | ||
1652 | return ret; | 1691 | return SUCCESS; |
1653 | } | 1692 | } |
1654 | 1693 | ||
1655 | static int srp_reset_device(struct scsi_cmnd *scmnd) | 1694 | static int srp_reset_device(struct scsi_cmnd *scmnd) |
diff --git a/drivers/infiniband/ulp/srpt/ib_srpt.c b/drivers/infiniband/ulp/srpt/ib_srpt.c index 7a0ce8d42887..9e1449f8c6a2 100644 --- a/drivers/infiniband/ulp/srpt/ib_srpt.c +++ b/drivers/infiniband/ulp/srpt/ib_srpt.c | |||
@@ -1469,7 +1469,7 @@ static void srpt_handle_send_comp(struct srpt_rdma_ch *ch, | |||
1469 | * | 1469 | * |
1470 | * XXX: what is now target_execute_cmd used to be asynchronous, and unmapping | 1470 | * XXX: what is now target_execute_cmd used to be asynchronous, and unmapping |
1471 | * the data that has been transferred via IB RDMA had to be postponed until the | 1471 | * the data that has been transferred via IB RDMA had to be postponed until the |
1472 | * check_stop_free() callback. None of this is nessecary anymore and needs to | 1472 | * check_stop_free() callback. None of this is necessary anymore and needs to |
1473 | * be cleaned up. | 1473 | * be cleaned up. |
1474 | */ | 1474 | */ |
1475 | static void srpt_handle_rdma_comp(struct srpt_rdma_ch *ch, | 1475 | static void srpt_handle_rdma_comp(struct srpt_rdma_ch *ch, |
diff --git a/drivers/input/touchscreen/eeti_ts.c b/drivers/input/touchscreen/eeti_ts.c index 503c7096ed36..908407efc672 100644 --- a/drivers/input/touchscreen/eeti_ts.c +++ b/drivers/input/touchscreen/eeti_ts.c | |||
@@ -48,7 +48,7 @@ struct eeti_ts_priv { | |||
48 | struct input_dev *input; | 48 | struct input_dev *input; |
49 | struct work_struct work; | 49 | struct work_struct work; |
50 | struct mutex mutex; | 50 | struct mutex mutex; |
51 | int irq, irq_active_high; | 51 | int irq_gpio, irq, irq_active_high; |
52 | }; | 52 | }; |
53 | 53 | ||
54 | #define EETI_TS_BITDEPTH (11) | 54 | #define EETI_TS_BITDEPTH (11) |
@@ -62,7 +62,7 @@ struct eeti_ts_priv { | |||
62 | 62 | ||
63 | static inline int eeti_ts_irq_active(struct eeti_ts_priv *priv) | 63 | static inline int eeti_ts_irq_active(struct eeti_ts_priv *priv) |
64 | { | 64 | { |
65 | return gpio_get_value(irq_to_gpio(priv->irq)) == priv->irq_active_high; | 65 | return gpio_get_value(priv->irq_gpio) == priv->irq_active_high; |
66 | } | 66 | } |
67 | 67 | ||
68 | static void eeti_ts_read(struct work_struct *work) | 68 | static void eeti_ts_read(struct work_struct *work) |
@@ -157,7 +157,7 @@ static void eeti_ts_close(struct input_dev *dev) | |||
157 | static int __devinit eeti_ts_probe(struct i2c_client *client, | 157 | static int __devinit eeti_ts_probe(struct i2c_client *client, |
158 | const struct i2c_device_id *idp) | 158 | const struct i2c_device_id *idp) |
159 | { | 159 | { |
160 | struct eeti_ts_platform_data *pdata; | 160 | struct eeti_ts_platform_data *pdata = client->dev.platform_data; |
161 | struct eeti_ts_priv *priv; | 161 | struct eeti_ts_priv *priv; |
162 | struct input_dev *input; | 162 | struct input_dev *input; |
163 | unsigned int irq_flags; | 163 | unsigned int irq_flags; |
@@ -199,9 +199,12 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, | |||
199 | 199 | ||
200 | priv->client = client; | 200 | priv->client = client; |
201 | priv->input = input; | 201 | priv->input = input; |
202 | priv->irq = client->irq; | 202 | priv->irq_gpio = pdata->irq_gpio; |
203 | priv->irq = gpio_to_irq(pdata->irq_gpio); | ||
203 | 204 | ||
204 | pdata = client->dev.platform_data; | 205 | err = gpio_request_one(pdata->irq_gpio, GPIOF_IN, client->name); |
206 | if (err < 0) | ||
207 | goto err1; | ||
205 | 208 | ||
206 | if (pdata) | 209 | if (pdata) |
207 | priv->irq_active_high = pdata->irq_active_high; | 210 | priv->irq_active_high = pdata->irq_active_high; |
@@ -215,13 +218,13 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, | |||
215 | 218 | ||
216 | err = input_register_device(input); | 219 | err = input_register_device(input); |
217 | if (err) | 220 | if (err) |
218 | goto err1; | 221 | goto err2; |
219 | 222 | ||
220 | err = request_irq(priv->irq, eeti_ts_isr, irq_flags, | 223 | err = request_irq(priv->irq, eeti_ts_isr, irq_flags, |
221 | client->name, priv); | 224 | client->name, priv); |
222 | if (err) { | 225 | if (err) { |
223 | dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); | 226 | dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); |
224 | goto err2; | 227 | goto err3; |
225 | } | 228 | } |
226 | 229 | ||
227 | /* | 230 | /* |
@@ -233,9 +236,11 @@ static int __devinit eeti_ts_probe(struct i2c_client *client, | |||
233 | device_init_wakeup(&client->dev, 0); | 236 | device_init_wakeup(&client->dev, 0); |
234 | return 0; | 237 | return 0; |
235 | 238 | ||
236 | err2: | 239 | err3: |
237 | input_unregister_device(input); | 240 | input_unregister_device(input); |
238 | input = NULL; /* so we dont try to free it below */ | 241 | input = NULL; /* so we dont try to free it below */ |
242 | err2: | ||
243 | gpio_free(pdata->irq_gpio); | ||
239 | err1: | 244 | err1: |
240 | input_free_device(input); | 245 | input_free_device(input); |
241 | kfree(priv); | 246 | kfree(priv); |
diff --git a/drivers/iommu/amd_iommu.c b/drivers/iommu/amd_iommu.c index 6d1cbdfc9b2a..b64502dfa9f4 100644 --- a/drivers/iommu/amd_iommu.c +++ b/drivers/iommu/amd_iommu.c | |||
@@ -296,8 +296,13 @@ static int iommu_init_device(struct device *dev) | |||
296 | } else | 296 | } else |
297 | dma_pdev = pci_dev_get(pdev); | 297 | dma_pdev = pci_dev_get(pdev); |
298 | 298 | ||
299 | /* Account for quirked devices */ | ||
299 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); | 300 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); |
300 | 301 | ||
302 | /* | ||
303 | * If it's a multifunction device that does not support our | ||
304 | * required ACS flags, add to the same group as function 0. | ||
305 | */ | ||
301 | if (dma_pdev->multifunction && | 306 | if (dma_pdev->multifunction && |
302 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) | 307 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) |
303 | swap_pci_ref(&dma_pdev, | 308 | swap_pci_ref(&dma_pdev, |
@@ -305,14 +310,28 @@ static int iommu_init_device(struct device *dev) | |||
305 | PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), | 310 | PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), |
306 | 0))); | 311 | 0))); |
307 | 312 | ||
313 | /* | ||
314 | * Devices on the root bus go through the iommu. If that's not us, | ||
315 | * find the next upstream device and test ACS up to the root bus. | ||
316 | * Finding the next device may require skipping virtual buses. | ||
317 | */ | ||
308 | while (!pci_is_root_bus(dma_pdev->bus)) { | 318 | while (!pci_is_root_bus(dma_pdev->bus)) { |
309 | if (pci_acs_path_enabled(dma_pdev->bus->self, | 319 | struct pci_bus *bus = dma_pdev->bus; |
310 | NULL, REQ_ACS_FLAGS)) | 320 | |
321 | while (!bus->self) { | ||
322 | if (!pci_is_root_bus(bus)) | ||
323 | bus = bus->parent; | ||
324 | else | ||
325 | goto root_bus; | ||
326 | } | ||
327 | |||
328 | if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS)) | ||
311 | break; | 329 | break; |
312 | 330 | ||
313 | swap_pci_ref(&dma_pdev, pci_dev_get(dma_pdev->bus->self)); | 331 | swap_pci_ref(&dma_pdev, pci_dev_get(bus->self)); |
314 | } | 332 | } |
315 | 333 | ||
334 | root_bus: | ||
316 | group = iommu_group_get(&dma_pdev->dev); | 335 | group = iommu_group_get(&dma_pdev->dev); |
317 | pci_dev_put(dma_pdev); | 336 | pci_dev_put(dma_pdev); |
318 | if (!group) { | 337 | if (!group) { |
diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 500e7f15f5c2..18a89b760aaa 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c | |||
@@ -1111,7 +1111,7 @@ static void print_iommu_info(void) | |||
1111 | 1111 | ||
1112 | if (iommu->cap & (1 << IOMMU_CAP_EFR)) { | 1112 | if (iommu->cap & (1 << IOMMU_CAP_EFR)) { |
1113 | pr_info("AMD-Vi: Extended features: "); | 1113 | pr_info("AMD-Vi: Extended features: "); |
1114 | for (i = 0; ARRAY_SIZE(feat_str); ++i) { | 1114 | for (i = 0; i < ARRAY_SIZE(feat_str); ++i) { |
1115 | if (iommu_feature(iommu, (1ULL << i))) | 1115 | if (iommu_feature(iommu, (1ULL << i))) |
1116 | pr_cont(" %s", feat_str[i]); | 1116 | pr_cont(" %s", feat_str[i]); |
1117 | } | 1117 | } |
@@ -1131,9 +1131,6 @@ static int __init amd_iommu_init_pci(void) | |||
1131 | break; | 1131 | break; |
1132 | } | 1132 | } |
1133 | 1133 | ||
1134 | /* Make sure ACS will be enabled */ | ||
1135 | pci_request_acs(); | ||
1136 | |||
1137 | ret = amd_iommu_init_devices(); | 1134 | ret = amd_iommu_init_devices(); |
1138 | 1135 | ||
1139 | print_iommu_info(); | 1136 | print_iommu_info(); |
@@ -1652,6 +1649,9 @@ static bool detect_ivrs(void) | |||
1652 | 1649 | ||
1653 | early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size); | 1650 | early_acpi_os_unmap_memory((char __iomem *)ivrs_base, ivrs_size); |
1654 | 1651 | ||
1652 | /* Make sure ACS will be enabled during PCI probe */ | ||
1653 | pci_request_acs(); | ||
1654 | |||
1655 | return true; | 1655 | return true; |
1656 | } | 1656 | } |
1657 | 1657 | ||
diff --git a/drivers/iommu/exynos-iommu.c b/drivers/iommu/exynos-iommu.c index 45350ff5e93c..80bad32aa463 100644 --- a/drivers/iommu/exynos-iommu.c +++ b/drivers/iommu/exynos-iommu.c | |||
@@ -732,9 +732,9 @@ static int exynos_iommu_domain_init(struct iommu_domain *domain) | |||
732 | spin_lock_init(&priv->pgtablelock); | 732 | spin_lock_init(&priv->pgtablelock); |
733 | INIT_LIST_HEAD(&priv->clients); | 733 | INIT_LIST_HEAD(&priv->clients); |
734 | 734 | ||
735 | dom->geometry.aperture_start = 0; | 735 | domain->geometry.aperture_start = 0; |
736 | dom->geometry.aperture_end = ~0UL; | 736 | domain->geometry.aperture_end = ~0UL; |
737 | dom->geometry.force_aperture = true; | 737 | domain->geometry.force_aperture = true; |
738 | 738 | ||
739 | domain->priv = priv; | 739 | domain->priv = priv; |
740 | return 0; | 740 | return 0; |
diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index 7469b5346643..2297ec193eb4 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c | |||
@@ -2008,6 +2008,7 @@ static struct dmar_domain *get_domain_for_dev(struct pci_dev *pdev, int gaw) | |||
2008 | if (!drhd) { | 2008 | if (!drhd) { |
2009 | printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n", | 2009 | printk(KERN_ERR "IOMMU: can't find DMAR for device %s\n", |
2010 | pci_name(pdev)); | 2010 | pci_name(pdev)); |
2011 | free_domain_mem(domain); | ||
2011 | return NULL; | 2012 | return NULL; |
2012 | } | 2013 | } |
2013 | iommu = drhd->iommu; | 2014 | iommu = drhd->iommu; |
@@ -4124,8 +4125,13 @@ static int intel_iommu_add_device(struct device *dev) | |||
4124 | } else | 4125 | } else |
4125 | dma_pdev = pci_dev_get(pdev); | 4126 | dma_pdev = pci_dev_get(pdev); |
4126 | 4127 | ||
4128 | /* Account for quirked devices */ | ||
4127 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); | 4129 | swap_pci_ref(&dma_pdev, pci_get_dma_source(dma_pdev)); |
4128 | 4130 | ||
4131 | /* | ||
4132 | * If it's a multifunction device that does not support our | ||
4133 | * required ACS flags, add to the same group as function 0. | ||
4134 | */ | ||
4129 | if (dma_pdev->multifunction && | 4135 | if (dma_pdev->multifunction && |
4130 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) | 4136 | !pci_acs_enabled(dma_pdev, REQ_ACS_FLAGS)) |
4131 | swap_pci_ref(&dma_pdev, | 4137 | swap_pci_ref(&dma_pdev, |
@@ -4133,14 +4139,28 @@ static int intel_iommu_add_device(struct device *dev) | |||
4133 | PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), | 4139 | PCI_DEVFN(PCI_SLOT(dma_pdev->devfn), |
4134 | 0))); | 4140 | 0))); |
4135 | 4141 | ||
4142 | /* | ||
4143 | * Devices on the root bus go through the iommu. If that's not us, | ||
4144 | * find the next upstream device and test ACS up to the root bus. | ||
4145 | * Finding the next device may require skipping virtual buses. | ||
4146 | */ | ||
4136 | while (!pci_is_root_bus(dma_pdev->bus)) { | 4147 | while (!pci_is_root_bus(dma_pdev->bus)) { |
4137 | if (pci_acs_path_enabled(dma_pdev->bus->self, | 4148 | struct pci_bus *bus = dma_pdev->bus; |
4138 | NULL, REQ_ACS_FLAGS)) | 4149 | |
4150 | while (!bus->self) { | ||
4151 | if (!pci_is_root_bus(bus)) | ||
4152 | bus = bus->parent; | ||
4153 | else | ||
4154 | goto root_bus; | ||
4155 | } | ||
4156 | |||
4157 | if (pci_acs_path_enabled(bus->self, NULL, REQ_ACS_FLAGS)) | ||
4139 | break; | 4158 | break; |
4140 | 4159 | ||
4141 | swap_pci_ref(&dma_pdev, pci_dev_get(dma_pdev->bus->self)); | 4160 | swap_pci_ref(&dma_pdev, pci_dev_get(bus->self)); |
4142 | } | 4161 | } |
4143 | 4162 | ||
4163 | root_bus: | ||
4144 | group = iommu_group_get(&dma_pdev->dev); | 4164 | group = iommu_group_get(&dma_pdev->dev); |
4145 | pci_dev_put(dma_pdev); | 4165 | pci_dev_put(dma_pdev); |
4146 | if (!group) { | 4166 | if (!group) { |
diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c index e0b18f3ae9a8..af8904de1d44 100644 --- a/drivers/iommu/intel_irq_remapping.c +++ b/drivers/iommu/intel_irq_remapping.c | |||
@@ -736,6 +736,7 @@ int __init parse_ioapics_under_ir(void) | |||
736 | { | 736 | { |
737 | struct dmar_drhd_unit *drhd; | 737 | struct dmar_drhd_unit *drhd; |
738 | int ir_supported = 0; | 738 | int ir_supported = 0; |
739 | int ioapic_idx; | ||
739 | 740 | ||
740 | for_each_drhd_unit(drhd) { | 741 | for_each_drhd_unit(drhd) { |
741 | struct intel_iommu *iommu = drhd->iommu; | 742 | struct intel_iommu *iommu = drhd->iommu; |
@@ -748,13 +749,20 @@ int __init parse_ioapics_under_ir(void) | |||
748 | } | 749 | } |
749 | } | 750 | } |
750 | 751 | ||
751 | if (ir_supported && ir_ioapic_num != nr_ioapics) { | 752 | if (!ir_supported) |
752 | printk(KERN_WARNING | 753 | return 0; |
753 | "Not all IO-APIC's listed under remapping hardware\n"); | 754 | |
754 | return -1; | 755 | for (ioapic_idx = 0; ioapic_idx < nr_ioapics; ioapic_idx++) { |
756 | int ioapic_id = mpc_ioapic_id(ioapic_idx); | ||
757 | if (!map_ioapic_to_ir(ioapic_id)) { | ||
758 | pr_err(FW_BUG "ioapic %d has no mapping iommu, " | ||
759 | "interrupt remapping will be disabled\n", | ||
760 | ioapic_id); | ||
761 | return -1; | ||
762 | } | ||
755 | } | 763 | } |
756 | 764 | ||
757 | return ir_supported; | 765 | return 1; |
758 | } | 766 | } |
759 | 767 | ||
760 | int __init ir_dev_scope_init(void) | 768 | int __init ir_dev_scope_init(void) |
diff --git a/drivers/iommu/tegra-smmu.c b/drivers/iommu/tegra-smmu.c index 4ba325ab6262..2a4bb36bc688 100644 --- a/drivers/iommu/tegra-smmu.c +++ b/drivers/iommu/tegra-smmu.c | |||
@@ -799,14 +799,14 @@ static void smmu_iommu_detach_dev(struct iommu_domain *domain, | |||
799 | goto out; | 799 | goto out; |
800 | } | 800 | } |
801 | } | 801 | } |
802 | dev_err(smmu->dev, "Couldn't find %s\n", dev_name(c->dev)); | 802 | dev_err(smmu->dev, "Couldn't find %s\n", dev_name(dev)); |
803 | out: | 803 | out: |
804 | spin_unlock(&as->client_lock); | 804 | spin_unlock(&as->client_lock); |
805 | } | 805 | } |
806 | 806 | ||
807 | static int smmu_iommu_domain_init(struct iommu_domain *domain) | 807 | static int smmu_iommu_domain_init(struct iommu_domain *domain) |
808 | { | 808 | { |
809 | int i, err = -ENODEV; | 809 | int i, err = -EAGAIN; |
810 | unsigned long flags; | 810 | unsigned long flags; |
811 | struct smmu_as *as; | 811 | struct smmu_as *as; |
812 | struct smmu_device *smmu = smmu_handle; | 812 | struct smmu_device *smmu = smmu_handle; |
@@ -814,11 +814,14 @@ static int smmu_iommu_domain_init(struct iommu_domain *domain) | |||
814 | /* Look for a free AS with lock held */ | 814 | /* Look for a free AS with lock held */ |
815 | for (i = 0; i < smmu->num_as; i++) { | 815 | for (i = 0; i < smmu->num_as; i++) { |
816 | as = &smmu->as[i]; | 816 | as = &smmu->as[i]; |
817 | if (!as->pdir_page) { | 817 | |
818 | err = alloc_pdir(as); | 818 | if (as->pdir_page) |
819 | if (!err) | 819 | continue; |
820 | goto found; | 820 | |
821 | } | 821 | err = alloc_pdir(as); |
822 | if (!err) | ||
823 | goto found; | ||
824 | |||
822 | if (err != -EAGAIN) | 825 | if (err != -EAGAIN) |
823 | break; | 826 | break; |
824 | } | 827 | } |
diff --git a/drivers/isdn/mISDN/layer2.c b/drivers/isdn/mISDN/layer2.c index 0dc8abca1407..949cabb88f1c 100644 --- a/drivers/isdn/mISDN/layer2.c +++ b/drivers/isdn/mISDN/layer2.c | |||
@@ -2222,7 +2222,7 @@ create_l2(struct mISDNchannel *ch, u_int protocol, u_long options, int tei, | |||
2222 | InitWin(l2); | 2222 | InitWin(l2); |
2223 | l2->l2m.fsm = &l2fsm; | 2223 | l2->l2m.fsm = &l2fsm; |
2224 | if (test_bit(FLG_LAPB, &l2->flag) || | 2224 | if (test_bit(FLG_LAPB, &l2->flag) || |
2225 | test_bit(FLG_PTP, &l2->flag) || | 2225 | test_bit(FLG_FIXED_TEI, &l2->flag) || |
2226 | test_bit(FLG_LAPD_NET, &l2->flag)) | 2226 | test_bit(FLG_LAPD_NET, &l2->flag)) |
2227 | l2->l2m.state = ST_L2_4; | 2227 | l2->l2m.state = ST_L2_4; |
2228 | else | 2228 | else |
diff --git a/drivers/leds/led-triggers.c b/drivers/leds/led-triggers.c index 6157cbbf4113..363975b3c925 100644 --- a/drivers/leds/led-triggers.c +++ b/drivers/leds/led-triggers.c | |||
@@ -224,7 +224,7 @@ void led_trigger_event(struct led_trigger *trig, | |||
224 | struct led_classdev *led_cdev; | 224 | struct led_classdev *led_cdev; |
225 | 225 | ||
226 | led_cdev = list_entry(entry, struct led_classdev, trig_list); | 226 | led_cdev = list_entry(entry, struct led_classdev, trig_list); |
227 | led_set_brightness(led_cdev, brightness); | 227 | __led_set_brightness(led_cdev, brightness); |
228 | } | 228 | } |
229 | read_unlock(&trig->leddev_list_lock); | 229 | read_unlock(&trig->leddev_list_lock); |
230 | } | 230 | } |
diff --git a/drivers/leds/leds-lp8788.c b/drivers/leds/leds-lp8788.c index 53bd136f1ef0..0ade6ebfc914 100644 --- a/drivers/leds/leds-lp8788.c +++ b/drivers/leds/leds-lp8788.c | |||
@@ -63,7 +63,7 @@ static int lp8788_led_init_device(struct lp8788_led *led, | |||
63 | /* scale configuration */ | 63 | /* scale configuration */ |
64 | addr = LP8788_ISINK_CTRL; | 64 | addr = LP8788_ISINK_CTRL; |
65 | mask = 1 << (cfg->num + LP8788_ISINK_SCALE_OFFSET); | 65 | mask = 1 << (cfg->num + LP8788_ISINK_SCALE_OFFSET); |
66 | val = cfg->scale << cfg->num; | 66 | val = cfg->scale << (cfg->num + LP8788_ISINK_SCALE_OFFSET); |
67 | ret = lp8788_update_bits(led->lp, addr, mask, val); | 67 | ret = lp8788_update_bits(led->lp, addr, mask, val); |
68 | if (ret) | 68 | if (ret) |
69 | return ret; | 69 | return ret; |
diff --git a/drivers/leds/leds-renesas-tpu.c b/drivers/leds/leds-renesas-tpu.c index 9ee12c28059a..771ea067e680 100644 --- a/drivers/leds/leds-renesas-tpu.c +++ b/drivers/leds/leds-renesas-tpu.c | |||
@@ -247,7 +247,7 @@ static int __devinit r_tpu_probe(struct platform_device *pdev) | |||
247 | 247 | ||
248 | if (!cfg) { | 248 | if (!cfg) { |
249 | dev_err(&pdev->dev, "missing platform data\n"); | 249 | dev_err(&pdev->dev, "missing platform data\n"); |
250 | goto err0; | 250 | return -ENODEV; |
251 | } | 251 | } |
252 | 252 | ||
253 | p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); | 253 | p = devm_kzalloc(&pdev->dev, sizeof(*p), GFP_KERNEL); |
diff --git a/drivers/md/Kconfig b/drivers/md/Kconfig index 1eee45b69b71..d949b781f6f8 100644 --- a/drivers/md/Kconfig +++ b/drivers/md/Kconfig | |||
@@ -268,13 +268,14 @@ config DM_MIRROR | |||
268 | needed for live data migration tools such as 'pvmove'. | 268 | needed for live data migration tools such as 'pvmove'. |
269 | 269 | ||
270 | config DM_RAID | 270 | config DM_RAID |
271 | tristate "RAID 1/4/5/6 target" | 271 | tristate "RAID 1/4/5/6/10 target" |
272 | depends on BLK_DEV_DM | 272 | depends on BLK_DEV_DM |
273 | select MD_RAID1 | 273 | select MD_RAID1 |
274 | select MD_RAID10 | ||
274 | select MD_RAID456 | 275 | select MD_RAID456 |
275 | select BLK_DEV_MD | 276 | select BLK_DEV_MD |
276 | ---help--- | 277 | ---help--- |
277 | A dm target that supports RAID1, RAID4, RAID5 and RAID6 mappings | 278 | A dm target that supports RAID1, RAID10, RAID4, RAID5 and RAID6 mappings |
278 | 279 | ||
279 | A RAID-5 set of N drives with a capacity of C MB per drive provides | 280 | A RAID-5 set of N drives with a capacity of C MB per drive provides |
280 | the capacity of C * (N - 1) MB, and protects against a failure | 281 | the capacity of C * (N - 1) MB, and protects against a failure |
diff --git a/drivers/md/bitmap.c b/drivers/md/bitmap.c index 15dbe03117e4..94e7f6ba2e11 100644 --- a/drivers/md/bitmap.c +++ b/drivers/md/bitmap.c | |||
@@ -1305,7 +1305,7 @@ int bitmap_startwrite(struct bitmap *bitmap, sector_t offset, unsigned long sect | |||
1305 | prepare_to_wait(&bitmap->overflow_wait, &__wait, | 1305 | prepare_to_wait(&bitmap->overflow_wait, &__wait, |
1306 | TASK_UNINTERRUPTIBLE); | 1306 | TASK_UNINTERRUPTIBLE); |
1307 | spin_unlock_irq(&bitmap->counts.lock); | 1307 | spin_unlock_irq(&bitmap->counts.lock); |
1308 | io_schedule(); | 1308 | schedule(); |
1309 | finish_wait(&bitmap->overflow_wait, &__wait); | 1309 | finish_wait(&bitmap->overflow_wait, &__wait); |
1310 | continue; | 1310 | continue; |
1311 | } | 1311 | } |
diff --git a/drivers/md/md.c b/drivers/md/md.c index fcd098794d37..3f6203a4c7ea 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -1108,8 +1108,11 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor | |||
1108 | ret = 0; | 1108 | ret = 0; |
1109 | } | 1109 | } |
1110 | rdev->sectors = rdev->sb_start; | 1110 | rdev->sectors = rdev->sb_start; |
1111 | /* Limit to 4TB as metadata cannot record more than that */ | 1111 | /* Limit to 4TB as metadata cannot record more than that. |
1112 | if (rdev->sectors >= (2ULL << 32)) | 1112 | * (not needed for Linear and RAID0 as metadata doesn't |
1113 | * record this size) | ||
1114 | */ | ||
1115 | if (rdev->sectors >= (2ULL << 32) && sb->level >= 1) | ||
1113 | rdev->sectors = (2ULL << 32) - 2; | 1116 | rdev->sectors = (2ULL << 32) - 2; |
1114 | 1117 | ||
1115 | if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) | 1118 | if (rdev->sectors < ((sector_t)sb->size) * 2 && sb->level >= 1) |
@@ -1400,7 +1403,7 @@ super_90_rdev_size_change(struct md_rdev *rdev, sector_t num_sectors) | |||
1400 | /* Limit to 4TB as metadata cannot record more than that. | 1403 | /* Limit to 4TB as metadata cannot record more than that. |
1401 | * 4TB == 2^32 KB, or 2*2^32 sectors. | 1404 | * 4TB == 2^32 KB, or 2*2^32 sectors. |
1402 | */ | 1405 | */ |
1403 | if (num_sectors >= (2ULL << 32)) | 1406 | if (num_sectors >= (2ULL << 32) && rdev->mddev->level >= 1) |
1404 | num_sectors = (2ULL << 32) - 2; | 1407 | num_sectors = (2ULL << 32) - 2; |
1405 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, | 1408 | md_super_write(rdev->mddev, rdev, rdev->sb_start, rdev->sb_size, |
1406 | rdev->sb_page); | 1409 | rdev->sb_page); |
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 9f7f8bee8442..611b5f797618 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -944,6 +944,44 @@ do_sync_io: | |||
944 | pr_debug("%dB behind alloc failed, doing sync I/O\n", bio->bi_size); | 944 | pr_debug("%dB behind alloc failed, doing sync I/O\n", bio->bi_size); |
945 | } | 945 | } |
946 | 946 | ||
947 | struct raid1_plug_cb { | ||
948 | struct blk_plug_cb cb; | ||
949 | struct bio_list pending; | ||
950 | int pending_cnt; | ||
951 | }; | ||
952 | |||
953 | static void raid1_unplug(struct blk_plug_cb *cb, bool from_schedule) | ||
954 | { | ||
955 | struct raid1_plug_cb *plug = container_of(cb, struct raid1_plug_cb, | ||
956 | cb); | ||
957 | struct mddev *mddev = plug->cb.data; | ||
958 | struct r1conf *conf = mddev->private; | ||
959 | struct bio *bio; | ||
960 | |||
961 | if (from_schedule) { | ||
962 | spin_lock_irq(&conf->device_lock); | ||
963 | bio_list_merge(&conf->pending_bio_list, &plug->pending); | ||
964 | conf->pending_count += plug->pending_cnt; | ||
965 | spin_unlock_irq(&conf->device_lock); | ||
966 | md_wakeup_thread(mddev->thread); | ||
967 | kfree(plug); | ||
968 | return; | ||
969 | } | ||
970 | |||
971 | /* we aren't scheduling, so we can do the write-out directly. */ | ||
972 | bio = bio_list_get(&plug->pending); | ||
973 | bitmap_unplug(mddev->bitmap); | ||
974 | wake_up(&conf->wait_barrier); | ||
975 | |||
976 | while (bio) { /* submit pending writes */ | ||
977 | struct bio *next = bio->bi_next; | ||
978 | bio->bi_next = NULL; | ||
979 | generic_make_request(bio); | ||
980 | bio = next; | ||
981 | } | ||
982 | kfree(plug); | ||
983 | } | ||
984 | |||
947 | static void make_request(struct mddev *mddev, struct bio * bio) | 985 | static void make_request(struct mddev *mddev, struct bio * bio) |
948 | { | 986 | { |
949 | struct r1conf *conf = mddev->private; | 987 | struct r1conf *conf = mddev->private; |
@@ -957,6 +995,8 @@ static void make_request(struct mddev *mddev, struct bio * bio) | |||
957 | const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); | 995 | const unsigned long do_sync = (bio->bi_rw & REQ_SYNC); |
958 | const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); | 996 | const unsigned long do_flush_fua = (bio->bi_rw & (REQ_FLUSH | REQ_FUA)); |
959 | struct md_rdev *blocked_rdev; | 997 | struct md_rdev *blocked_rdev; |
998 | struct blk_plug_cb *cb; | ||
999 | struct raid1_plug_cb *plug = NULL; | ||
960 | int first_clone; | 1000 | int first_clone; |
961 | int sectors_handled; | 1001 | int sectors_handled; |
962 | int max_sectors; | 1002 | int max_sectors; |
@@ -1259,11 +1299,22 @@ read_again: | |||
1259 | mbio->bi_private = r1_bio; | 1299 | mbio->bi_private = r1_bio; |
1260 | 1300 | ||
1261 | atomic_inc(&r1_bio->remaining); | 1301 | atomic_inc(&r1_bio->remaining); |
1302 | |||
1303 | cb = blk_check_plugged(raid1_unplug, mddev, sizeof(*plug)); | ||
1304 | if (cb) | ||
1305 | plug = container_of(cb, struct raid1_plug_cb, cb); | ||
1306 | else | ||
1307 | plug = NULL; | ||
1262 | spin_lock_irqsave(&conf->device_lock, flags); | 1308 | spin_lock_irqsave(&conf->device_lock, flags); |
1263 | bio_list_add(&conf->pending_bio_list, mbio); | 1309 | if (plug) { |
1264 | conf->pending_count++; | 1310 | bio_list_add(&plug->pending, mbio); |
1311 | plug->pending_cnt++; | ||
1312 | } else { | ||
1313 | bio_list_add(&conf->pending_bio_list, mbio); | ||
1314 | conf->pending_count++; | ||
1315 | } | ||
1265 | spin_unlock_irqrestore(&conf->device_lock, flags); | 1316 | spin_unlock_irqrestore(&conf->device_lock, flags); |
1266 | if (!mddev_check_plugged(mddev)) | 1317 | if (!plug) |
1267 | md_wakeup_thread(mddev->thread); | 1318 | md_wakeup_thread(mddev->thread); |
1268 | } | 1319 | } |
1269 | /* Mustn't call r1_bio_write_done before this next test, | 1320 | /* Mustn't call r1_bio_write_done before this next test, |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index de5ed6fd8806..1c2eb38f3c51 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -659,7 +659,11 @@ static int raid10_mergeable_bvec(struct request_queue *q, | |||
659 | max = biovec->bv_len; | 659 | max = biovec->bv_len; |
660 | 660 | ||
661 | if (mddev->merge_check_needed) { | 661 | if (mddev->merge_check_needed) { |
662 | struct r10bio r10_bio; | 662 | struct { |
663 | struct r10bio r10_bio; | ||
664 | struct r10dev devs[conf->copies]; | ||
665 | } on_stack; | ||
666 | struct r10bio *r10_bio = &on_stack.r10_bio; | ||
663 | int s; | 667 | int s; |
664 | if (conf->reshape_progress != MaxSector) { | 668 | if (conf->reshape_progress != MaxSector) { |
665 | /* Cannot give any guidance during reshape */ | 669 | /* Cannot give any guidance during reshape */ |
@@ -667,18 +671,18 @@ static int raid10_mergeable_bvec(struct request_queue *q, | |||
667 | return biovec->bv_len; | 671 | return biovec->bv_len; |
668 | return 0; | 672 | return 0; |
669 | } | 673 | } |
670 | r10_bio.sector = sector; | 674 | r10_bio->sector = sector; |
671 | raid10_find_phys(conf, &r10_bio); | 675 | raid10_find_phys(conf, r10_bio); |
672 | rcu_read_lock(); | 676 | rcu_read_lock(); |
673 | for (s = 0; s < conf->copies; s++) { | 677 | for (s = 0; s < conf->copies; s++) { |
674 | int disk = r10_bio.devs[s].devnum; | 678 | int disk = r10_bio->devs[s].devnum; |
675 | struct md_rdev *rdev = rcu_dereference( | 679 | struct md_rdev *rdev = rcu_dereference( |
676 | conf->mirrors[disk].rdev); | 680 | conf->mirrors[disk].rdev); |
677 | if (rdev && !test_bit(Faulty, &rdev->flags)) { | 681 | if (rdev && !test_bit(Faulty, &rdev->flags)) { |
678 | struct request_queue *q = | 682 | struct request_queue *q = |
679 | bdev_get_queue(rdev->bdev); | 683 | bdev_get_queue(rdev->bdev); |
680 | if (q->merge_bvec_fn) { | 684 | if (q->merge_bvec_fn) { |
681 | bvm->bi_sector = r10_bio.devs[s].addr | 685 | bvm->bi_sector = r10_bio->devs[s].addr |
682 | + rdev->data_offset; | 686 | + rdev->data_offset; |
683 | bvm->bi_bdev = rdev->bdev; | 687 | bvm->bi_bdev = rdev->bdev; |
684 | max = min(max, q->merge_bvec_fn( | 688 | max = min(max, q->merge_bvec_fn( |
@@ -690,7 +694,7 @@ static int raid10_mergeable_bvec(struct request_queue *q, | |||
690 | struct request_queue *q = | 694 | struct request_queue *q = |
691 | bdev_get_queue(rdev->bdev); | 695 | bdev_get_queue(rdev->bdev); |
692 | if (q->merge_bvec_fn) { | 696 | if (q->merge_bvec_fn) { |
693 | bvm->bi_sector = r10_bio.devs[s].addr | 697 | bvm->bi_sector = r10_bio->devs[s].addr |
694 | + rdev->data_offset; | 698 | + rdev->data_offset; |
695 | bvm->bi_bdev = rdev->bdev; | 699 | bvm->bi_bdev = rdev->bdev; |
696 | max = min(max, q->merge_bvec_fn( | 700 | max = min(max, q->merge_bvec_fn( |
@@ -4414,14 +4418,18 @@ static int handle_reshape_read_error(struct mddev *mddev, | |||
4414 | { | 4418 | { |
4415 | /* Use sync reads to get the blocks from somewhere else */ | 4419 | /* Use sync reads to get the blocks from somewhere else */ |
4416 | int sectors = r10_bio->sectors; | 4420 | int sectors = r10_bio->sectors; |
4417 | struct r10bio r10b; | ||
4418 | struct r10conf *conf = mddev->private; | 4421 | struct r10conf *conf = mddev->private; |
4422 | struct { | ||
4423 | struct r10bio r10_bio; | ||
4424 | struct r10dev devs[conf->copies]; | ||
4425 | } on_stack; | ||
4426 | struct r10bio *r10b = &on_stack.r10_bio; | ||
4419 | int slot = 0; | 4427 | int slot = 0; |
4420 | int idx = 0; | 4428 | int idx = 0; |
4421 | struct bio_vec *bvec = r10_bio->master_bio->bi_io_vec; | 4429 | struct bio_vec *bvec = r10_bio->master_bio->bi_io_vec; |
4422 | 4430 | ||
4423 | r10b.sector = r10_bio->sector; | 4431 | r10b->sector = r10_bio->sector; |
4424 | __raid10_find_phys(&conf->prev, &r10b); | 4432 | __raid10_find_phys(&conf->prev, r10b); |
4425 | 4433 | ||
4426 | while (sectors) { | 4434 | while (sectors) { |
4427 | int s = sectors; | 4435 | int s = sectors; |
@@ -4432,7 +4440,7 @@ static int handle_reshape_read_error(struct mddev *mddev, | |||
4432 | s = PAGE_SIZE >> 9; | 4440 | s = PAGE_SIZE >> 9; |
4433 | 4441 | ||
4434 | while (!success) { | 4442 | while (!success) { |
4435 | int d = r10b.devs[slot].devnum; | 4443 | int d = r10b->devs[slot].devnum; |
4436 | struct md_rdev *rdev = conf->mirrors[d].rdev; | 4444 | struct md_rdev *rdev = conf->mirrors[d].rdev; |
4437 | sector_t addr; | 4445 | sector_t addr; |
4438 | if (rdev == NULL || | 4446 | if (rdev == NULL || |
@@ -4440,7 +4448,7 @@ static int handle_reshape_read_error(struct mddev *mddev, | |||
4440 | !test_bit(In_sync, &rdev->flags)) | 4448 | !test_bit(In_sync, &rdev->flags)) |
4441 | goto failed; | 4449 | goto failed; |
4442 | 4450 | ||
4443 | addr = r10b.devs[slot].addr + idx * PAGE_SIZE; | 4451 | addr = r10b->devs[slot].addr + idx * PAGE_SIZE; |
4444 | success = sync_page_io(rdev, | 4452 | success = sync_page_io(rdev, |
4445 | addr, | 4453 | addr, |
4446 | s << 9, | 4454 | s << 9, |
diff --git a/drivers/md/raid10.h b/drivers/md/raid10.h index 007c2c68dd83..1054cf602345 100644 --- a/drivers/md/raid10.h +++ b/drivers/md/raid10.h | |||
@@ -110,7 +110,7 @@ struct r10bio { | |||
110 | * We choose the number when they are allocated. | 110 | * We choose the number when they are allocated. |
111 | * We sometimes need an extra bio to write to the replacement. | 111 | * We sometimes need an extra bio to write to the replacement. |
112 | */ | 112 | */ |
113 | struct { | 113 | struct r10dev { |
114 | struct bio *bio; | 114 | struct bio *bio; |
115 | union { | 115 | union { |
116 | struct bio *repl_bio; /* used for resync and | 116 | struct bio *repl_bio; /* used for resync and |
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c index 87a2d0bdedd1..adda94df5eb2 100644 --- a/drivers/md/raid5.c +++ b/drivers/md/raid5.c | |||
@@ -484,7 +484,8 @@ get_active_stripe(struct r5conf *conf, sector_t sector, | |||
484 | } else { | 484 | } else { |
485 | if (atomic_read(&sh->count)) { | 485 | if (atomic_read(&sh->count)) { |
486 | BUG_ON(!list_empty(&sh->lru) | 486 | BUG_ON(!list_empty(&sh->lru) |
487 | && !test_bit(STRIPE_EXPANDING, &sh->state)); | 487 | && !test_bit(STRIPE_EXPANDING, &sh->state) |
488 | && !test_bit(STRIPE_ON_UNPLUG_LIST, &sh->state)); | ||
488 | } else { | 489 | } else { |
489 | if (!test_bit(STRIPE_HANDLE, &sh->state)) | 490 | if (!test_bit(STRIPE_HANDLE, &sh->state)) |
490 | atomic_inc(&conf->active_stripes); | 491 | atomic_inc(&conf->active_stripes); |
@@ -4010,6 +4011,62 @@ static struct stripe_head *__get_priority_stripe(struct r5conf *conf) | |||
4010 | return sh; | 4011 | return sh; |
4011 | } | 4012 | } |
4012 | 4013 | ||
4014 | struct raid5_plug_cb { | ||
4015 | struct blk_plug_cb cb; | ||
4016 | struct list_head list; | ||
4017 | }; | ||
4018 | |||
4019 | static void raid5_unplug(struct blk_plug_cb *blk_cb, bool from_schedule) | ||
4020 | { | ||
4021 | struct raid5_plug_cb *cb = container_of( | ||
4022 | blk_cb, struct raid5_plug_cb, cb); | ||
4023 | struct stripe_head *sh; | ||
4024 | struct mddev *mddev = cb->cb.data; | ||
4025 | struct r5conf *conf = mddev->private; | ||
4026 | |||
4027 | if (cb->list.next && !list_empty(&cb->list)) { | ||
4028 | spin_lock_irq(&conf->device_lock); | ||
4029 | while (!list_empty(&cb->list)) { | ||
4030 | sh = list_first_entry(&cb->list, struct stripe_head, lru); | ||
4031 | list_del_init(&sh->lru); | ||
4032 | /* | ||
4033 | * avoid race release_stripe_plug() sees | ||
4034 | * STRIPE_ON_UNPLUG_LIST clear but the stripe | ||
4035 | * is still in our list | ||
4036 | */ | ||
4037 | smp_mb__before_clear_bit(); | ||
4038 | clear_bit(STRIPE_ON_UNPLUG_LIST, &sh->state); | ||
4039 | __release_stripe(conf, sh); | ||
4040 | } | ||
4041 | spin_unlock_irq(&conf->device_lock); | ||
4042 | } | ||
4043 | kfree(cb); | ||
4044 | } | ||
4045 | |||
4046 | static void release_stripe_plug(struct mddev *mddev, | ||
4047 | struct stripe_head *sh) | ||
4048 | { | ||
4049 | struct blk_plug_cb *blk_cb = blk_check_plugged( | ||
4050 | raid5_unplug, mddev, | ||
4051 | sizeof(struct raid5_plug_cb)); | ||
4052 | struct raid5_plug_cb *cb; | ||
4053 | |||
4054 | if (!blk_cb) { | ||
4055 | release_stripe(sh); | ||
4056 | return; | ||
4057 | } | ||
4058 | |||
4059 | cb = container_of(blk_cb, struct raid5_plug_cb, cb); | ||
4060 | |||
4061 | if (cb->list.next == NULL) | ||
4062 | INIT_LIST_HEAD(&cb->list); | ||
4063 | |||
4064 | if (!test_and_set_bit(STRIPE_ON_UNPLUG_LIST, &sh->state)) | ||
4065 | list_add_tail(&sh->lru, &cb->list); | ||
4066 | else | ||
4067 | release_stripe(sh); | ||
4068 | } | ||
4069 | |||
4013 | static void make_request(struct mddev *mddev, struct bio * bi) | 4070 | static void make_request(struct mddev *mddev, struct bio * bi) |
4014 | { | 4071 | { |
4015 | struct r5conf *conf = mddev->private; | 4072 | struct r5conf *conf = mddev->private; |
@@ -4138,8 +4195,7 @@ static void make_request(struct mddev *mddev, struct bio * bi) | |||
4138 | if ((bi->bi_rw & REQ_NOIDLE) && | 4195 | if ((bi->bi_rw & REQ_NOIDLE) && |
4139 | !test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) | 4196 | !test_and_set_bit(STRIPE_PREREAD_ACTIVE, &sh->state)) |
4140 | atomic_inc(&conf->preread_active_stripes); | 4197 | atomic_inc(&conf->preread_active_stripes); |
4141 | mddev_check_plugged(mddev); | 4198 | release_stripe_plug(mddev, sh); |
4142 | release_stripe(sh); | ||
4143 | } else { | 4199 | } else { |
4144 | /* cannot get stripe for read-ahead, just give-up */ | 4200 | /* cannot get stripe for read-ahead, just give-up */ |
4145 | clear_bit(BIO_UPTODATE, &bi->bi_flags); | 4201 | clear_bit(BIO_UPTODATE, &bi->bi_flags); |
@@ -4537,6 +4593,30 @@ static int retry_aligned_read(struct r5conf *conf, struct bio *raid_bio) | |||
4537 | return handled; | 4593 | return handled; |
4538 | } | 4594 | } |
4539 | 4595 | ||
4596 | #define MAX_STRIPE_BATCH 8 | ||
4597 | static int handle_active_stripes(struct r5conf *conf) | ||
4598 | { | ||
4599 | struct stripe_head *batch[MAX_STRIPE_BATCH], *sh; | ||
4600 | int i, batch_size = 0; | ||
4601 | |||
4602 | while (batch_size < MAX_STRIPE_BATCH && | ||
4603 | (sh = __get_priority_stripe(conf)) != NULL) | ||
4604 | batch[batch_size++] = sh; | ||
4605 | |||
4606 | if (batch_size == 0) | ||
4607 | return batch_size; | ||
4608 | spin_unlock_irq(&conf->device_lock); | ||
4609 | |||
4610 | for (i = 0; i < batch_size; i++) | ||
4611 | handle_stripe(batch[i]); | ||
4612 | |||
4613 | cond_resched(); | ||
4614 | |||
4615 | spin_lock_irq(&conf->device_lock); | ||
4616 | for (i = 0; i < batch_size; i++) | ||
4617 | __release_stripe(conf, batch[i]); | ||
4618 | return batch_size; | ||
4619 | } | ||
4540 | 4620 | ||
4541 | /* | 4621 | /* |
4542 | * This is our raid5 kernel thread. | 4622 | * This is our raid5 kernel thread. |
@@ -4547,7 +4627,6 @@ static int retry_aligned_read(struct r5conf *conf, struct bio *raid_bio) | |||
4547 | */ | 4627 | */ |
4548 | static void raid5d(struct mddev *mddev) | 4628 | static void raid5d(struct mddev *mddev) |
4549 | { | 4629 | { |
4550 | struct stripe_head *sh; | ||
4551 | struct r5conf *conf = mddev->private; | 4630 | struct r5conf *conf = mddev->private; |
4552 | int handled; | 4631 | int handled; |
4553 | struct blk_plug plug; | 4632 | struct blk_plug plug; |
@@ -4561,6 +4640,7 @@ static void raid5d(struct mddev *mddev) | |||
4561 | spin_lock_irq(&conf->device_lock); | 4640 | spin_lock_irq(&conf->device_lock); |
4562 | while (1) { | 4641 | while (1) { |
4563 | struct bio *bio; | 4642 | struct bio *bio; |
4643 | int batch_size; | ||
4564 | 4644 | ||
4565 | if ( | 4645 | if ( |
4566 | !list_empty(&conf->bitmap_list)) { | 4646 | !list_empty(&conf->bitmap_list)) { |
@@ -4584,21 +4664,16 @@ static void raid5d(struct mddev *mddev) | |||
4584 | handled++; | 4664 | handled++; |
4585 | } | 4665 | } |
4586 | 4666 | ||
4587 | sh = __get_priority_stripe(conf); | 4667 | batch_size = handle_active_stripes(conf); |
4588 | 4668 | if (!batch_size) | |
4589 | if (!sh) | ||
4590 | break; | 4669 | break; |
4591 | spin_unlock_irq(&conf->device_lock); | 4670 | handled += batch_size; |
4592 | |||
4593 | handled++; | ||
4594 | handle_stripe(sh); | ||
4595 | release_stripe(sh); | ||
4596 | cond_resched(); | ||
4597 | 4671 | ||
4598 | if (mddev->flags & ~(1<<MD_CHANGE_PENDING)) | 4672 | if (mddev->flags & ~(1<<MD_CHANGE_PENDING)) { |
4673 | spin_unlock_irq(&conf->device_lock); | ||
4599 | md_check_recovery(mddev); | 4674 | md_check_recovery(mddev); |
4600 | 4675 | spin_lock_irq(&conf->device_lock); | |
4601 | spin_lock_irq(&conf->device_lock); | 4676 | } |
4602 | } | 4677 | } |
4603 | pr_debug("%d stripes handled\n", handled); | 4678 | pr_debug("%d stripes handled\n", handled); |
4604 | 4679 | ||
diff --git a/drivers/md/raid5.h b/drivers/md/raid5.h index 61dbb615c30b..a9fc24901eda 100644 --- a/drivers/md/raid5.h +++ b/drivers/md/raid5.h | |||
@@ -321,6 +321,7 @@ enum { | |||
321 | STRIPE_BIOFILL_RUN, | 321 | STRIPE_BIOFILL_RUN, |
322 | STRIPE_COMPUTE_RUN, | 322 | STRIPE_COMPUTE_RUN, |
323 | STRIPE_OPS_REQ_PENDING, | 323 | STRIPE_OPS_REQ_PENDING, |
324 | STRIPE_ON_UNPLUG_LIST, | ||
324 | }; | 325 | }; |
325 | 326 | ||
326 | /* | 327 | /* |
diff --git a/drivers/media/dvb/siano/smsusb.c b/drivers/media/dvb/siano/smsusb.c index 664e460f247b..aac622200e99 100644 --- a/drivers/media/dvb/siano/smsusb.c +++ b/drivers/media/dvb/siano/smsusb.c | |||
@@ -481,7 +481,7 @@ static int smsusb_resume(struct usb_interface *intf) | |||
481 | return 0; | 481 | return 0; |
482 | } | 482 | } |
483 | 483 | ||
484 | static const struct usb_device_id smsusb_id_table[] __devinitconst = { | 484 | static const struct usb_device_id smsusb_id_table[] = { |
485 | { USB_DEVICE(0x187f, 0x0010), | 485 | { USB_DEVICE(0x187f, 0x0010), |
486 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, | 486 | .driver_info = SMS1XXX_BOARD_SIANO_STELLAR }, |
487 | { USB_DEVICE(0x187f, 0x0100), | 487 | { USB_DEVICE(0x187f, 0x0100), |
diff --git a/drivers/media/radio/radio-shark.c b/drivers/media/radio/radio-shark.c index d0b6bb507634..72ded29728bb 100644 --- a/drivers/media/radio/radio-shark.c +++ b/drivers/media/radio/radio-shark.c | |||
@@ -35,6 +35,11 @@ | |||
35 | #include <media/v4l2-device.h> | 35 | #include <media/v4l2-device.h> |
36 | #include <sound/tea575x-tuner.h> | 36 | #include <sound/tea575x-tuner.h> |
37 | 37 | ||
38 | #if defined(CONFIG_LEDS_CLASS) || \ | ||
39 | (defined(CONFIG_LEDS_CLASS_MODULE) && defined(CONFIG_RADIO_SHARK_MODULE)) | ||
40 | #define SHARK_USE_LEDS 1 | ||
41 | #endif | ||
42 | |||
38 | /* | 43 | /* |
39 | * Version Information | 44 | * Version Information |
40 | */ | 45 | */ |
@@ -56,44 +61,18 @@ MODULE_LICENSE("GPL"); | |||
56 | 61 | ||
57 | enum { BLUE_LED, BLUE_PULSE_LED, RED_LED, NO_LEDS }; | 62 | enum { BLUE_LED, BLUE_PULSE_LED, RED_LED, NO_LEDS }; |
58 | 63 | ||
59 | static void shark_led_set_blue(struct led_classdev *led_cdev, | ||
60 | enum led_brightness value); | ||
61 | static void shark_led_set_blue_pulse(struct led_classdev *led_cdev, | ||
62 | enum led_brightness value); | ||
63 | static void shark_led_set_red(struct led_classdev *led_cdev, | ||
64 | enum led_brightness value); | ||
65 | |||
66 | static const struct led_classdev shark_led_templates[NO_LEDS] = { | ||
67 | [BLUE_LED] = { | ||
68 | .name = "%s:blue:", | ||
69 | .brightness = LED_OFF, | ||
70 | .max_brightness = 127, | ||
71 | .brightness_set = shark_led_set_blue, | ||
72 | }, | ||
73 | [BLUE_PULSE_LED] = { | ||
74 | .name = "%s:blue-pulse:", | ||
75 | .brightness = LED_OFF, | ||
76 | .max_brightness = 255, | ||
77 | .brightness_set = shark_led_set_blue_pulse, | ||
78 | }, | ||
79 | [RED_LED] = { | ||
80 | .name = "%s:red:", | ||
81 | .brightness = LED_OFF, | ||
82 | .max_brightness = 1, | ||
83 | .brightness_set = shark_led_set_red, | ||
84 | }, | ||
85 | }; | ||
86 | |||
87 | struct shark_device { | 64 | struct shark_device { |
88 | struct usb_device *usbdev; | 65 | struct usb_device *usbdev; |
89 | struct v4l2_device v4l2_dev; | 66 | struct v4l2_device v4l2_dev; |
90 | struct snd_tea575x tea; | 67 | struct snd_tea575x tea; |
91 | 68 | ||
69 | #ifdef SHARK_USE_LEDS | ||
92 | struct work_struct led_work; | 70 | struct work_struct led_work; |
93 | struct led_classdev leds[NO_LEDS]; | 71 | struct led_classdev leds[NO_LEDS]; |
94 | char led_names[NO_LEDS][32]; | 72 | char led_names[NO_LEDS][32]; |
95 | atomic_t brightness[NO_LEDS]; | 73 | atomic_t brightness[NO_LEDS]; |
96 | unsigned long brightness_new; | 74 | unsigned long brightness_new; |
75 | #endif | ||
97 | 76 | ||
98 | u8 *transfer_buffer; | 77 | u8 *transfer_buffer; |
99 | u32 last_val; | 78 | u32 last_val; |
@@ -175,20 +154,13 @@ static struct snd_tea575x_ops shark_tea_ops = { | |||
175 | .read_val = shark_read_val, | 154 | .read_val = shark_read_val, |
176 | }; | 155 | }; |
177 | 156 | ||
157 | #ifdef SHARK_USE_LEDS | ||
178 | static void shark_led_work(struct work_struct *work) | 158 | static void shark_led_work(struct work_struct *work) |
179 | { | 159 | { |
180 | struct shark_device *shark = | 160 | struct shark_device *shark = |
181 | container_of(work, struct shark_device, led_work); | 161 | container_of(work, struct shark_device, led_work); |
182 | int i, res, brightness, actual_len; | 162 | int i, res, brightness, actual_len; |
183 | 163 | ||
184 | /* | ||
185 | * We use the v4l2_dev lock and registered bit to ensure the device | ||
186 | * does not get unplugged and unreffed while we're running. | ||
187 | */ | ||
188 | mutex_lock(&shark->tea.mutex); | ||
189 | if (!video_is_registered(&shark->tea.vd)) | ||
190 | goto leave; | ||
191 | |||
192 | for (i = 0; i < 3; i++) { | 164 | for (i = 0; i < 3; i++) { |
193 | if (!test_and_clear_bit(i, &shark->brightness_new)) | 165 | if (!test_and_clear_bit(i, &shark->brightness_new)) |
194 | continue; | 166 | continue; |
@@ -208,8 +180,6 @@ static void shark_led_work(struct work_struct *work) | |||
208 | v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", | 180 | v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", |
209 | shark->led_names[i], res); | 181 | shark->led_names[i], res); |
210 | } | 182 | } |
211 | leave: | ||
212 | mutex_unlock(&shark->tea.mutex); | ||
213 | } | 183 | } |
214 | 184 | ||
215 | static void shark_led_set_blue(struct led_classdev *led_cdev, | 185 | static void shark_led_set_blue(struct led_classdev *led_cdev, |
@@ -245,19 +215,78 @@ static void shark_led_set_red(struct led_classdev *led_cdev, | |||
245 | schedule_work(&shark->led_work); | 215 | schedule_work(&shark->led_work); |
246 | } | 216 | } |
247 | 217 | ||
218 | static const struct led_classdev shark_led_templates[NO_LEDS] = { | ||
219 | [BLUE_LED] = { | ||
220 | .name = "%s:blue:", | ||
221 | .brightness = LED_OFF, | ||
222 | .max_brightness = 127, | ||
223 | .brightness_set = shark_led_set_blue, | ||
224 | }, | ||
225 | [BLUE_PULSE_LED] = { | ||
226 | .name = "%s:blue-pulse:", | ||
227 | .brightness = LED_OFF, | ||
228 | .max_brightness = 255, | ||
229 | .brightness_set = shark_led_set_blue_pulse, | ||
230 | }, | ||
231 | [RED_LED] = { | ||
232 | .name = "%s:red:", | ||
233 | .brightness = LED_OFF, | ||
234 | .max_brightness = 1, | ||
235 | .brightness_set = shark_led_set_red, | ||
236 | }, | ||
237 | }; | ||
238 | |||
239 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
240 | { | ||
241 | int i, retval; | ||
242 | |||
243 | INIT_WORK(&shark->led_work, shark_led_work); | ||
244 | for (i = 0; i < NO_LEDS; i++) { | ||
245 | shark->leds[i] = shark_led_templates[i]; | ||
246 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
247 | shark->leds[i].name, shark->v4l2_dev.name); | ||
248 | shark->leds[i].name = shark->led_names[i]; | ||
249 | retval = led_classdev_register(dev, &shark->leds[i]); | ||
250 | if (retval) { | ||
251 | v4l2_err(&shark->v4l2_dev, | ||
252 | "couldn't register led: %s\n", | ||
253 | shark->led_names[i]); | ||
254 | return retval; | ||
255 | } | ||
256 | } | ||
257 | return 0; | ||
258 | } | ||
259 | |||
260 | static void shark_unregister_leds(struct shark_device *shark) | ||
261 | { | ||
262 | int i; | ||
263 | |||
264 | for (i = 0; i < NO_LEDS; i++) | ||
265 | led_classdev_unregister(&shark->leds[i]); | ||
266 | |||
267 | cancel_work_sync(&shark->led_work); | ||
268 | } | ||
269 | #else | ||
270 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
271 | { | ||
272 | v4l2_warn(&shark->v4l2_dev, | ||
273 | "CONFIG_LED_CLASS not enabled, LED support disabled\n"); | ||
274 | return 0; | ||
275 | } | ||
276 | static inline void shark_unregister_leds(struct shark_device *shark) { } | ||
277 | #endif | ||
278 | |||
248 | static void usb_shark_disconnect(struct usb_interface *intf) | 279 | static void usb_shark_disconnect(struct usb_interface *intf) |
249 | { | 280 | { |
250 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); | 281 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); |
251 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); | 282 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); |
252 | int i; | ||
253 | 283 | ||
254 | mutex_lock(&shark->tea.mutex); | 284 | mutex_lock(&shark->tea.mutex); |
255 | v4l2_device_disconnect(&shark->v4l2_dev); | 285 | v4l2_device_disconnect(&shark->v4l2_dev); |
256 | snd_tea575x_exit(&shark->tea); | 286 | snd_tea575x_exit(&shark->tea); |
257 | mutex_unlock(&shark->tea.mutex); | 287 | mutex_unlock(&shark->tea.mutex); |
258 | 288 | ||
259 | for (i = 0; i < NO_LEDS; i++) | 289 | shark_unregister_leds(shark); |
260 | led_classdev_unregister(&shark->leds[i]); | ||
261 | 290 | ||
262 | v4l2_device_put(&shark->v4l2_dev); | 291 | v4l2_device_put(&shark->v4l2_dev); |
263 | } | 292 | } |
@@ -266,7 +295,6 @@ static void usb_shark_release(struct v4l2_device *v4l2_dev) | |||
266 | { | 295 | { |
267 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); | 296 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); |
268 | 297 | ||
269 | cancel_work_sync(&shark->led_work); | ||
270 | v4l2_device_unregister(&shark->v4l2_dev); | 298 | v4l2_device_unregister(&shark->v4l2_dev); |
271 | kfree(shark->transfer_buffer); | 299 | kfree(shark->transfer_buffer); |
272 | kfree(shark); | 300 | kfree(shark); |
@@ -276,7 +304,7 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
276 | const struct usb_device_id *id) | 304 | const struct usb_device_id *id) |
277 | { | 305 | { |
278 | struct shark_device *shark; | 306 | struct shark_device *shark; |
279 | int i, retval = -ENOMEM; | 307 | int retval = -ENOMEM; |
280 | 308 | ||
281 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); | 309 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); |
282 | if (!shark) | 310 | if (!shark) |
@@ -286,17 +314,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
286 | if (!shark->transfer_buffer) | 314 | if (!shark->transfer_buffer) |
287 | goto err_alloc_buffer; | 315 | goto err_alloc_buffer; |
288 | 316 | ||
289 | /* | 317 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); |
290 | * Work around a bug in usbhid/hid-core.c, where it leaves a dangling | 318 | |
291 | * pointer in intfdata causing v4l2-device.c to not set it. Which | 319 | retval = shark_register_leds(shark, &intf->dev); |
292 | * results in usb_shark_disconnect() referencing the dangling pointer | 320 | if (retval) |
293 | * | 321 | goto err_reg_leds; |
294 | * REMOVE (as soon as the above bug is fixed, patch submitted) | ||
295 | */ | ||
296 | usb_set_intfdata(intf, NULL); | ||
297 | 322 | ||
298 | shark->v4l2_dev.release = usb_shark_release; | 323 | shark->v4l2_dev.release = usb_shark_release; |
299 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); | ||
300 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); | 324 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); |
301 | if (retval) { | 325 | if (retval) { |
302 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); | 326 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); |
@@ -320,32 +344,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
320 | goto err_init_tea; | 344 | goto err_init_tea; |
321 | } | 345 | } |
322 | 346 | ||
323 | INIT_WORK(&shark->led_work, shark_led_work); | ||
324 | for (i = 0; i < NO_LEDS; i++) { | ||
325 | shark->leds[i] = shark_led_templates[i]; | ||
326 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
327 | shark->leds[i].name, shark->v4l2_dev.name); | ||
328 | shark->leds[i].name = shark->led_names[i]; | ||
329 | /* | ||
330 | * We don't fail the probe if we fail to register the leds, | ||
331 | * because once we've called snd_tea575x_init, the /dev/radio0 | ||
332 | * node may be opened from userspace holding a reference to us! | ||
333 | * | ||
334 | * Note we cannot register the leds first instead as | ||
335 | * shark_led_work depends on the v4l2 mutex and registered bit. | ||
336 | */ | ||
337 | retval = led_classdev_register(&intf->dev, &shark->leds[i]); | ||
338 | if (retval) | ||
339 | v4l2_err(&shark->v4l2_dev, | ||
340 | "couldn't register led: %s\n", | ||
341 | shark->led_names[i]); | ||
342 | } | ||
343 | |||
344 | return 0; | 347 | return 0; |
345 | 348 | ||
346 | err_init_tea: | 349 | err_init_tea: |
347 | v4l2_device_unregister(&shark->v4l2_dev); | 350 | v4l2_device_unregister(&shark->v4l2_dev); |
348 | err_reg_dev: | 351 | err_reg_dev: |
352 | shark_unregister_leds(shark); | ||
353 | err_reg_leds: | ||
349 | kfree(shark->transfer_buffer); | 354 | kfree(shark->transfer_buffer); |
350 | err_alloc_buffer: | 355 | err_alloc_buffer: |
351 | kfree(shark); | 356 | kfree(shark); |
diff --git a/drivers/media/radio/radio-shark2.c b/drivers/media/radio/radio-shark2.c index b9575de3e7e8..7b4efdfaae28 100644 --- a/drivers/media/radio/radio-shark2.c +++ b/drivers/media/radio/radio-shark2.c | |||
@@ -35,6 +35,11 @@ | |||
35 | #include <media/v4l2-device.h> | 35 | #include <media/v4l2-device.h> |
36 | #include "radio-tea5777.h" | 36 | #include "radio-tea5777.h" |
37 | 37 | ||
38 | #if defined(CONFIG_LEDS_CLASS) || \ | ||
39 | (defined(CONFIG_LEDS_CLASS_MODULE) && defined(CONFIG_RADIO_SHARK2_MODULE)) | ||
40 | #define SHARK_USE_LEDS 1 | ||
41 | #endif | ||
42 | |||
38 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); | 43 | MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); |
39 | MODULE_DESCRIPTION("Griffin radioSHARK2, USB radio receiver driver"); | 44 | MODULE_DESCRIPTION("Griffin radioSHARK2, USB radio receiver driver"); |
40 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
@@ -43,7 +48,6 @@ static int debug; | |||
43 | module_param(debug, int, 0); | 48 | module_param(debug, int, 0); |
44 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); | 49 | MODULE_PARM_DESC(debug, "Debug level (0-1)"); |
45 | 50 | ||
46 | |||
47 | #define SHARK_IN_EP 0x83 | 51 | #define SHARK_IN_EP 0x83 |
48 | #define SHARK_OUT_EP 0x05 | 52 | #define SHARK_OUT_EP 0x05 |
49 | 53 | ||
@@ -54,36 +58,18 @@ MODULE_PARM_DESC(debug, "Debug level (0-1)"); | |||
54 | 58 | ||
55 | enum { BLUE_LED, RED_LED, NO_LEDS }; | 59 | enum { BLUE_LED, RED_LED, NO_LEDS }; |
56 | 60 | ||
57 | static void shark_led_set_blue(struct led_classdev *led_cdev, | ||
58 | enum led_brightness value); | ||
59 | static void shark_led_set_red(struct led_classdev *led_cdev, | ||
60 | enum led_brightness value); | ||
61 | |||
62 | static const struct led_classdev shark_led_templates[NO_LEDS] = { | ||
63 | [BLUE_LED] = { | ||
64 | .name = "%s:blue:", | ||
65 | .brightness = LED_OFF, | ||
66 | .max_brightness = 127, | ||
67 | .brightness_set = shark_led_set_blue, | ||
68 | }, | ||
69 | [RED_LED] = { | ||
70 | .name = "%s:red:", | ||
71 | .brightness = LED_OFF, | ||
72 | .max_brightness = 1, | ||
73 | .brightness_set = shark_led_set_red, | ||
74 | }, | ||
75 | }; | ||
76 | |||
77 | struct shark_device { | 61 | struct shark_device { |
78 | struct usb_device *usbdev; | 62 | struct usb_device *usbdev; |
79 | struct v4l2_device v4l2_dev; | 63 | struct v4l2_device v4l2_dev; |
80 | struct radio_tea5777 tea; | 64 | struct radio_tea5777 tea; |
81 | 65 | ||
66 | #ifdef SHARK_USE_LEDS | ||
82 | struct work_struct led_work; | 67 | struct work_struct led_work; |
83 | struct led_classdev leds[NO_LEDS]; | 68 | struct led_classdev leds[NO_LEDS]; |
84 | char led_names[NO_LEDS][32]; | 69 | char led_names[NO_LEDS][32]; |
85 | atomic_t brightness[NO_LEDS]; | 70 | atomic_t brightness[NO_LEDS]; |
86 | unsigned long brightness_new; | 71 | unsigned long brightness_new; |
72 | #endif | ||
87 | 73 | ||
88 | u8 *transfer_buffer; | 74 | u8 *transfer_buffer; |
89 | }; | 75 | }; |
@@ -161,18 +147,12 @@ static struct radio_tea5777_ops shark_tea_ops = { | |||
161 | .read_reg = shark_read_reg, | 147 | .read_reg = shark_read_reg, |
162 | }; | 148 | }; |
163 | 149 | ||
150 | #ifdef SHARK_USE_LEDS | ||
164 | static void shark_led_work(struct work_struct *work) | 151 | static void shark_led_work(struct work_struct *work) |
165 | { | 152 | { |
166 | struct shark_device *shark = | 153 | struct shark_device *shark = |
167 | container_of(work, struct shark_device, led_work); | 154 | container_of(work, struct shark_device, led_work); |
168 | int i, res, brightness, actual_len; | 155 | int i, res, brightness, actual_len; |
169 | /* | ||
170 | * We use the v4l2_dev lock and registered bit to ensure the device | ||
171 | * does not get unplugged and unreffed while we're running. | ||
172 | */ | ||
173 | mutex_lock(&shark->tea.mutex); | ||
174 | if (!video_is_registered(&shark->tea.vd)) | ||
175 | goto leave; | ||
176 | 156 | ||
177 | for (i = 0; i < 2; i++) { | 157 | for (i = 0; i < 2; i++) { |
178 | if (!test_and_clear_bit(i, &shark->brightness_new)) | 158 | if (!test_and_clear_bit(i, &shark->brightness_new)) |
@@ -191,8 +171,6 @@ static void shark_led_work(struct work_struct *work) | |||
191 | v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", | 171 | v4l2_err(&shark->v4l2_dev, "set LED %s error: %d\n", |
192 | shark->led_names[i], res); | 172 | shark->led_names[i], res); |
193 | } | 173 | } |
194 | leave: | ||
195 | mutex_unlock(&shark->tea.mutex); | ||
196 | } | 174 | } |
197 | 175 | ||
198 | static void shark_led_set_blue(struct led_classdev *led_cdev, | 176 | static void shark_led_set_blue(struct led_classdev *led_cdev, |
@@ -217,19 +195,72 @@ static void shark_led_set_red(struct led_classdev *led_cdev, | |||
217 | schedule_work(&shark->led_work); | 195 | schedule_work(&shark->led_work); |
218 | } | 196 | } |
219 | 197 | ||
198 | static const struct led_classdev shark_led_templates[NO_LEDS] = { | ||
199 | [BLUE_LED] = { | ||
200 | .name = "%s:blue:", | ||
201 | .brightness = LED_OFF, | ||
202 | .max_brightness = 127, | ||
203 | .brightness_set = shark_led_set_blue, | ||
204 | }, | ||
205 | [RED_LED] = { | ||
206 | .name = "%s:red:", | ||
207 | .brightness = LED_OFF, | ||
208 | .max_brightness = 1, | ||
209 | .brightness_set = shark_led_set_red, | ||
210 | }, | ||
211 | }; | ||
212 | |||
213 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
214 | { | ||
215 | int i, retval; | ||
216 | |||
217 | INIT_WORK(&shark->led_work, shark_led_work); | ||
218 | for (i = 0; i < NO_LEDS; i++) { | ||
219 | shark->leds[i] = shark_led_templates[i]; | ||
220 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
221 | shark->leds[i].name, shark->v4l2_dev.name); | ||
222 | shark->leds[i].name = shark->led_names[i]; | ||
223 | retval = led_classdev_register(dev, &shark->leds[i]); | ||
224 | if (retval) { | ||
225 | v4l2_err(&shark->v4l2_dev, | ||
226 | "couldn't register led: %s\n", | ||
227 | shark->led_names[i]); | ||
228 | return retval; | ||
229 | } | ||
230 | } | ||
231 | return 0; | ||
232 | } | ||
233 | |||
234 | static void shark_unregister_leds(struct shark_device *shark) | ||
235 | { | ||
236 | int i; | ||
237 | |||
238 | for (i = 0; i < NO_LEDS; i++) | ||
239 | led_classdev_unregister(&shark->leds[i]); | ||
240 | |||
241 | cancel_work_sync(&shark->led_work); | ||
242 | } | ||
243 | #else | ||
244 | static int shark_register_leds(struct shark_device *shark, struct device *dev) | ||
245 | { | ||
246 | v4l2_warn(&shark->v4l2_dev, | ||
247 | "CONFIG_LED_CLASS not enabled, LED support disabled\n"); | ||
248 | return 0; | ||
249 | } | ||
250 | static inline void shark_unregister_leds(struct shark_device *shark) { } | ||
251 | #endif | ||
252 | |||
220 | static void usb_shark_disconnect(struct usb_interface *intf) | 253 | static void usb_shark_disconnect(struct usb_interface *intf) |
221 | { | 254 | { |
222 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); | 255 | struct v4l2_device *v4l2_dev = usb_get_intfdata(intf); |
223 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); | 256 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); |
224 | int i; | ||
225 | 257 | ||
226 | mutex_lock(&shark->tea.mutex); | 258 | mutex_lock(&shark->tea.mutex); |
227 | v4l2_device_disconnect(&shark->v4l2_dev); | 259 | v4l2_device_disconnect(&shark->v4l2_dev); |
228 | radio_tea5777_exit(&shark->tea); | 260 | radio_tea5777_exit(&shark->tea); |
229 | mutex_unlock(&shark->tea.mutex); | 261 | mutex_unlock(&shark->tea.mutex); |
230 | 262 | ||
231 | for (i = 0; i < NO_LEDS; i++) | 263 | shark_unregister_leds(shark); |
232 | led_classdev_unregister(&shark->leds[i]); | ||
233 | 264 | ||
234 | v4l2_device_put(&shark->v4l2_dev); | 265 | v4l2_device_put(&shark->v4l2_dev); |
235 | } | 266 | } |
@@ -238,7 +269,6 @@ static void usb_shark_release(struct v4l2_device *v4l2_dev) | |||
238 | { | 269 | { |
239 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); | 270 | struct shark_device *shark = v4l2_dev_to_shark(v4l2_dev); |
240 | 271 | ||
241 | cancel_work_sync(&shark->led_work); | ||
242 | v4l2_device_unregister(&shark->v4l2_dev); | 272 | v4l2_device_unregister(&shark->v4l2_dev); |
243 | kfree(shark->transfer_buffer); | 273 | kfree(shark->transfer_buffer); |
244 | kfree(shark); | 274 | kfree(shark); |
@@ -248,7 +278,7 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
248 | const struct usb_device_id *id) | 278 | const struct usb_device_id *id) |
249 | { | 279 | { |
250 | struct shark_device *shark; | 280 | struct shark_device *shark; |
251 | int i, retval = -ENOMEM; | 281 | int retval = -ENOMEM; |
252 | 282 | ||
253 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); | 283 | shark = kzalloc(sizeof(struct shark_device), GFP_KERNEL); |
254 | if (!shark) | 284 | if (!shark) |
@@ -258,17 +288,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
258 | if (!shark->transfer_buffer) | 288 | if (!shark->transfer_buffer) |
259 | goto err_alloc_buffer; | 289 | goto err_alloc_buffer; |
260 | 290 | ||
261 | /* | 291 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); |
262 | * Work around a bug in usbhid/hid-core.c, where it leaves a dangling | 292 | |
263 | * pointer in intfdata causing v4l2-device.c to not set it. Which | 293 | retval = shark_register_leds(shark, &intf->dev); |
264 | * results in usb_shark_disconnect() referencing the dangling pointer | 294 | if (retval) |
265 | * | 295 | goto err_reg_leds; |
266 | * REMOVE (as soon as the above bug is fixed, patch submitted) | ||
267 | */ | ||
268 | usb_set_intfdata(intf, NULL); | ||
269 | 296 | ||
270 | shark->v4l2_dev.release = usb_shark_release; | 297 | shark->v4l2_dev.release = usb_shark_release; |
271 | v4l2_device_set_name(&shark->v4l2_dev, DRV_NAME, &shark_instance); | ||
272 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); | 298 | retval = v4l2_device_register(&intf->dev, &shark->v4l2_dev); |
273 | if (retval) { | 299 | if (retval) { |
274 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); | 300 | v4l2_err(&shark->v4l2_dev, "couldn't register v4l2_device\n"); |
@@ -292,32 +318,13 @@ static int usb_shark_probe(struct usb_interface *intf, | |||
292 | goto err_init_tea; | 318 | goto err_init_tea; |
293 | } | 319 | } |
294 | 320 | ||
295 | INIT_WORK(&shark->led_work, shark_led_work); | ||
296 | for (i = 0; i < NO_LEDS; i++) { | ||
297 | shark->leds[i] = shark_led_templates[i]; | ||
298 | snprintf(shark->led_names[i], sizeof(shark->led_names[0]), | ||
299 | shark->leds[i].name, shark->v4l2_dev.name); | ||
300 | shark->leds[i].name = shark->led_names[i]; | ||
301 | /* | ||
302 | * We don't fail the probe if we fail to register the leds, | ||
303 | * because once we've called radio_tea5777_init, the /dev/radio0 | ||
304 | * node may be opened from userspace holding a reference to us! | ||
305 | * | ||
306 | * Note we cannot register the leds first instead as | ||
307 | * shark_led_work depends on the v4l2 mutex and registered bit. | ||
308 | */ | ||
309 | retval = led_classdev_register(&intf->dev, &shark->leds[i]); | ||
310 | if (retval) | ||
311 | v4l2_err(&shark->v4l2_dev, | ||
312 | "couldn't register led: %s\n", | ||
313 | shark->led_names[i]); | ||
314 | } | ||
315 | |||
316 | return 0; | 321 | return 0; |
317 | 322 | ||
318 | err_init_tea: | 323 | err_init_tea: |
319 | v4l2_device_unregister(&shark->v4l2_dev); | 324 | v4l2_device_unregister(&shark->v4l2_dev); |
320 | err_reg_dev: | 325 | err_reg_dev: |
326 | shark_unregister_leds(shark); | ||
327 | err_reg_leds: | ||
321 | kfree(shark->transfer_buffer); | 328 | kfree(shark->transfer_buffer); |
322 | err_alloc_buffer: | 329 | err_alloc_buffer: |
323 | kfree(shark); | 330 | kfree(shark); |
diff --git a/drivers/media/radio/si470x/radio-si470x-common.c b/drivers/media/radio/si470x/radio-si470x-common.c index 9e38132afec6..9bb65e170d99 100644 --- a/drivers/media/radio/si470x/radio-si470x-common.c +++ b/drivers/media/radio/si470x/radio-si470x-common.c | |||
@@ -151,6 +151,7 @@ static const struct v4l2_frequency_band bands[] = { | |||
151 | .index = 0, | 151 | .index = 0, |
152 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | | 152 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | |
153 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | | 153 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | |
154 | V4L2_TUNER_CAP_FREQ_BANDS | | ||
154 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | | 155 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | |
155 | V4L2_TUNER_CAP_HWSEEK_WRAP, | 156 | V4L2_TUNER_CAP_HWSEEK_WRAP, |
156 | .rangelow = 87500 * 16, | 157 | .rangelow = 87500 * 16, |
@@ -162,6 +163,7 @@ static const struct v4l2_frequency_band bands[] = { | |||
162 | .index = 1, | 163 | .index = 1, |
163 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | | 164 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | |
164 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | | 165 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | |
166 | V4L2_TUNER_CAP_FREQ_BANDS | | ||
165 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | | 167 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | |
166 | V4L2_TUNER_CAP_HWSEEK_WRAP, | 168 | V4L2_TUNER_CAP_HWSEEK_WRAP, |
167 | .rangelow = 76000 * 16, | 169 | .rangelow = 76000 * 16, |
@@ -173,6 +175,7 @@ static const struct v4l2_frequency_band bands[] = { | |||
173 | .index = 2, | 175 | .index = 2, |
174 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | | 176 | .capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO | |
175 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | | 177 | V4L2_TUNER_CAP_RDS | V4L2_TUNER_CAP_RDS_BLOCK_IO | |
178 | V4L2_TUNER_CAP_FREQ_BANDS | | ||
176 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | | 179 | V4L2_TUNER_CAP_HWSEEK_BOUNDED | |
177 | V4L2_TUNER_CAP_HWSEEK_WRAP, | 180 | V4L2_TUNER_CAP_HWSEEK_WRAP, |
178 | .rangelow = 76000 * 16, | 181 | .rangelow = 76000 * 16, |
diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c index 643a6ff7c5d0..f867f04cccc9 100644 --- a/drivers/media/radio/si470x/radio-si470x-i2c.c +++ b/drivers/media/radio/si470x/radio-si470x-i2c.c | |||
@@ -225,8 +225,9 @@ int si470x_vidioc_querycap(struct file *file, void *priv, | |||
225 | { | 225 | { |
226 | strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver)); | 226 | strlcpy(capability->driver, DRIVER_NAME, sizeof(capability->driver)); |
227 | strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); | 227 | strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); |
228 | capability->capabilities = V4L2_CAP_HW_FREQ_SEEK | | 228 | capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE | |
229 | V4L2_CAP_TUNER | V4L2_CAP_RADIO; | 229 | V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE; |
230 | capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS; | ||
230 | 231 | ||
231 | return 0; | 232 | return 0; |
232 | } | 233 | } |
diff --git a/drivers/media/radio/si470x/radio-si470x-usb.c b/drivers/media/radio/si470x/radio-si470x-usb.c index 146be4263ea1..be076f7181e7 100644 --- a/drivers/media/radio/si470x/radio-si470x-usb.c +++ b/drivers/media/radio/si470x/radio-si470x-usb.c | |||
@@ -531,7 +531,7 @@ int si470x_vidioc_querycap(struct file *file, void *priv, | |||
531 | strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); | 531 | strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); |
532 | usb_make_path(radio->usbdev, capability->bus_info, | 532 | usb_make_path(radio->usbdev, capability->bus_info, |
533 | sizeof(capability->bus_info)); | 533 | sizeof(capability->bus_info)); |
534 | capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | | 534 | capability->device_caps = V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_READWRITE | |
535 | V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE; | 535 | V4L2_CAP_TUNER | V4L2_CAP_RADIO | V4L2_CAP_RDS_CAPTURE; |
536 | capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS; | 536 | capability->capabilities = capability->device_caps | V4L2_CAP_DEVICE_CAPS; |
537 | return 0; | 537 | return 0; |
diff --git a/drivers/media/rc/Kconfig b/drivers/media/rc/Kconfig index 5180390be7ab..8be57634ba60 100644 --- a/drivers/media/rc/Kconfig +++ b/drivers/media/rc/Kconfig | |||
@@ -261,6 +261,7 @@ config IR_WINBOND_CIR | |||
261 | 261 | ||
262 | config IR_IGUANA | 262 | config IR_IGUANA |
263 | tristate "IguanaWorks USB IR Transceiver" | 263 | tristate "IguanaWorks USB IR Transceiver" |
264 | depends on USB_ARCH_HAS_HCD | ||
264 | depends on RC_CORE | 265 | depends on RC_CORE |
265 | select USB | 266 | select USB |
266 | ---help--- | 267 | ---help--- |
diff --git a/drivers/media/video/gspca/jl2005bcd.c b/drivers/media/video/gspca/jl2005bcd.c index cf9d9fca5b84..234777116e5f 100644 --- a/drivers/media/video/gspca/jl2005bcd.c +++ b/drivers/media/video/gspca/jl2005bcd.c | |||
@@ -512,7 +512,7 @@ static const struct sd_desc sd_desc = { | |||
512 | }; | 512 | }; |
513 | 513 | ||
514 | /* -- module initialisation -- */ | 514 | /* -- module initialisation -- */ |
515 | static const __devinitdata struct usb_device_id device_table[] = { | 515 | static const struct usb_device_id device_table[] = { |
516 | {USB_DEVICE(0x0979, 0x0227)}, | 516 | {USB_DEVICE(0x0979, 0x0227)}, |
517 | {} | 517 | {} |
518 | }; | 518 | }; |
diff --git a/drivers/media/video/gspca/spca506.c b/drivers/media/video/gspca/spca506.c index 969bb5a4cd93..bab01c86c315 100644 --- a/drivers/media/video/gspca/spca506.c +++ b/drivers/media/video/gspca/spca506.c | |||
@@ -579,7 +579,7 @@ static const struct sd_desc sd_desc = { | |||
579 | }; | 579 | }; |
580 | 580 | ||
581 | /* -- module initialisation -- */ | 581 | /* -- module initialisation -- */ |
582 | static const struct usb_device_id device_table[] __devinitconst = { | 582 | static const struct usb_device_id device_table[] = { |
583 | {USB_DEVICE(0x06e1, 0xa190)}, | 583 | {USB_DEVICE(0x06e1, 0xa190)}, |
584 | /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 | 584 | /*fixme: may be IntelPCCameraPro BRIDGE_SPCA505 |
585 | {USB_DEVICE(0x0733, 0x0430)}, */ | 585 | {USB_DEVICE(0x0733, 0x0430)}, */ |
diff --git a/drivers/media/video/mem2mem_testdev.c b/drivers/media/video/mem2mem_testdev.c index 7efe9ad7acc7..0b91a5cd38eb 100644 --- a/drivers/media/video/mem2mem_testdev.c +++ b/drivers/media/video/mem2mem_testdev.c | |||
@@ -431,7 +431,7 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
431 | strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1); | 431 | strncpy(cap->driver, MEM2MEM_NAME, sizeof(cap->driver) - 1); |
432 | strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1); | 432 | strncpy(cap->card, MEM2MEM_NAME, sizeof(cap->card) - 1); |
433 | strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->bus_info)); | 433 | strlcpy(cap->bus_info, MEM2MEM_NAME, sizeof(cap->bus_info)); |
434 | cap->capabilities = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; | 434 | cap->device_caps = V4L2_CAP_VIDEO_M2M | V4L2_CAP_STREAMING; |
435 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; | 435 | cap->capabilities = cap->device_caps | V4L2_CAP_DEVICE_CAPS; |
436 | return 0; | 436 | return 0; |
437 | } | 437 | } |
diff --git a/drivers/media/video/mx1_camera.c b/drivers/media/video/mx1_camera.c index d2e6f82ecfac..560a65aa7038 100644 --- a/drivers/media/video/mx1_camera.c +++ b/drivers/media/video/mx1_camera.c | |||
@@ -403,7 +403,7 @@ static void mx1_camera_activate(struct mx1_camera_dev *pcdev) | |||
403 | 403 | ||
404 | dev_dbg(pcdev->icd->parent, "Activate device\n"); | 404 | dev_dbg(pcdev->icd->parent, "Activate device\n"); |
405 | 405 | ||
406 | clk_enable(pcdev->clk); | 406 | clk_prepare_enable(pcdev->clk); |
407 | 407 | ||
408 | /* enable CSI before doing anything else */ | 408 | /* enable CSI before doing anything else */ |
409 | __raw_writel(csicr1, pcdev->base + CSICR1); | 409 | __raw_writel(csicr1, pcdev->base + CSICR1); |
@@ -422,7 +422,7 @@ static void mx1_camera_deactivate(struct mx1_camera_dev *pcdev) | |||
422 | /* Disable all CSI interface */ | 422 | /* Disable all CSI interface */ |
423 | __raw_writel(0x00, pcdev->base + CSICR1); | 423 | __raw_writel(0x00, pcdev->base + CSICR1); |
424 | 424 | ||
425 | clk_disable(pcdev->clk); | 425 | clk_disable_unprepare(pcdev->clk); |
426 | } | 426 | } |
427 | 427 | ||
428 | /* | 428 | /* |
diff --git a/drivers/media/video/mx2_camera.c b/drivers/media/video/mx2_camera.c index 637bde8aca28..ac175406e582 100644 --- a/drivers/media/video/mx2_camera.c +++ b/drivers/media/video/mx2_camera.c | |||
@@ -272,7 +272,7 @@ struct mx2_camera_dev { | |||
272 | struct device *dev; | 272 | struct device *dev; |
273 | struct soc_camera_host soc_host; | 273 | struct soc_camera_host soc_host; |
274 | struct soc_camera_device *icd; | 274 | struct soc_camera_device *icd; |
275 | struct clk *clk_csi, *clk_emma; | 275 | struct clk *clk_csi, *clk_emma_ahb, *clk_emma_ipg; |
276 | 276 | ||
277 | unsigned int irq_csi, irq_emma; | 277 | unsigned int irq_csi, irq_emma; |
278 | void __iomem *base_csi, *base_emma; | 278 | void __iomem *base_csi, *base_emma; |
@@ -407,7 +407,7 @@ static void mx2_camera_deactivate(struct mx2_camera_dev *pcdev) | |||
407 | { | 407 | { |
408 | unsigned long flags; | 408 | unsigned long flags; |
409 | 409 | ||
410 | clk_disable(pcdev->clk_csi); | 410 | clk_disable_unprepare(pcdev->clk_csi); |
411 | writel(0, pcdev->base_csi + CSICR1); | 411 | writel(0, pcdev->base_csi + CSICR1); |
412 | if (cpu_is_mx27()) { | 412 | if (cpu_is_mx27()) { |
413 | writel(0, pcdev->base_emma + PRP_CNTL); | 413 | writel(0, pcdev->base_emma + PRP_CNTL); |
@@ -435,7 +435,7 @@ static int mx2_camera_add_device(struct soc_camera_device *icd) | |||
435 | if (pcdev->icd) | 435 | if (pcdev->icd) |
436 | return -EBUSY; | 436 | return -EBUSY; |
437 | 437 | ||
438 | ret = clk_enable(pcdev->clk_csi); | 438 | ret = clk_prepare_enable(pcdev->clk_csi); |
439 | if (ret < 0) | 439 | if (ret < 0) |
440 | return ret; | 440 | return ret; |
441 | 441 | ||
@@ -1633,23 +1633,34 @@ static int __devinit mx27_camera_emma_init(struct mx2_camera_dev *pcdev) | |||
1633 | goto exit_iounmap; | 1633 | goto exit_iounmap; |
1634 | } | 1634 | } |
1635 | 1635 | ||
1636 | pcdev->clk_emma = clk_get(NULL, "emma"); | 1636 | pcdev->clk_emma_ipg = clk_get(pcdev->dev, "emma-ipg"); |
1637 | if (IS_ERR(pcdev->clk_emma)) { | 1637 | if (IS_ERR(pcdev->clk_emma_ipg)) { |
1638 | err = PTR_ERR(pcdev->clk_emma); | 1638 | err = PTR_ERR(pcdev->clk_emma_ipg); |
1639 | goto exit_free_irq; | 1639 | goto exit_free_irq; |
1640 | } | 1640 | } |
1641 | 1641 | ||
1642 | clk_enable(pcdev->clk_emma); | 1642 | clk_prepare_enable(pcdev->clk_emma_ipg); |
1643 | |||
1644 | pcdev->clk_emma_ahb = clk_get(pcdev->dev, "emma-ahb"); | ||
1645 | if (IS_ERR(pcdev->clk_emma_ahb)) { | ||
1646 | err = PTR_ERR(pcdev->clk_emma_ahb); | ||
1647 | goto exit_clk_emma_ipg_put; | ||
1648 | } | ||
1649 | |||
1650 | clk_prepare_enable(pcdev->clk_emma_ahb); | ||
1643 | 1651 | ||
1644 | err = mx27_camera_emma_prp_reset(pcdev); | 1652 | err = mx27_camera_emma_prp_reset(pcdev); |
1645 | if (err) | 1653 | if (err) |
1646 | goto exit_clk_emma_put; | 1654 | goto exit_clk_emma_ahb_put; |
1647 | 1655 | ||
1648 | return err; | 1656 | return err; |
1649 | 1657 | ||
1650 | exit_clk_emma_put: | 1658 | exit_clk_emma_ahb_put: |
1651 | clk_disable(pcdev->clk_emma); | 1659 | clk_disable_unprepare(pcdev->clk_emma_ahb); |
1652 | clk_put(pcdev->clk_emma); | 1660 | clk_put(pcdev->clk_emma_ahb); |
1661 | exit_clk_emma_ipg_put: | ||
1662 | clk_disable_unprepare(pcdev->clk_emma_ipg); | ||
1663 | clk_put(pcdev->clk_emma_ipg); | ||
1653 | exit_free_irq: | 1664 | exit_free_irq: |
1654 | free_irq(pcdev->irq_emma, pcdev); | 1665 | free_irq(pcdev->irq_emma, pcdev); |
1655 | exit_iounmap: | 1666 | exit_iounmap: |
@@ -1685,7 +1696,7 @@ static int __devinit mx2_camera_probe(struct platform_device *pdev) | |||
1685 | goto exit; | 1696 | goto exit; |
1686 | } | 1697 | } |
1687 | 1698 | ||
1688 | pcdev->clk_csi = clk_get(&pdev->dev, NULL); | 1699 | pcdev->clk_csi = clk_get(&pdev->dev, "ahb"); |
1689 | if (IS_ERR(pcdev->clk_csi)) { | 1700 | if (IS_ERR(pcdev->clk_csi)) { |
1690 | dev_err(&pdev->dev, "Could not get csi clock\n"); | 1701 | dev_err(&pdev->dev, "Could not get csi clock\n"); |
1691 | err = PTR_ERR(pcdev->clk_csi); | 1702 | err = PTR_ERR(pcdev->clk_csi); |
@@ -1785,8 +1796,10 @@ exit_free_emma: | |||
1785 | eallocctx: | 1796 | eallocctx: |
1786 | if (cpu_is_mx27()) { | 1797 | if (cpu_is_mx27()) { |
1787 | free_irq(pcdev->irq_emma, pcdev); | 1798 | free_irq(pcdev->irq_emma, pcdev); |
1788 | clk_disable(pcdev->clk_emma); | 1799 | clk_disable_unprepare(pcdev->clk_emma_ipg); |
1789 | clk_put(pcdev->clk_emma); | 1800 | clk_put(pcdev->clk_emma_ipg); |
1801 | clk_disable_unprepare(pcdev->clk_emma_ahb); | ||
1802 | clk_put(pcdev->clk_emma_ahb); | ||
1790 | iounmap(pcdev->base_emma); | 1803 | iounmap(pcdev->base_emma); |
1791 | release_mem_region(pcdev->res_emma->start, resource_size(pcdev->res_emma)); | 1804 | release_mem_region(pcdev->res_emma->start, resource_size(pcdev->res_emma)); |
1792 | } | 1805 | } |
@@ -1825,8 +1838,10 @@ static int __devexit mx2_camera_remove(struct platform_device *pdev) | |||
1825 | iounmap(pcdev->base_csi); | 1838 | iounmap(pcdev->base_csi); |
1826 | 1839 | ||
1827 | if (cpu_is_mx27()) { | 1840 | if (cpu_is_mx27()) { |
1828 | clk_disable(pcdev->clk_emma); | 1841 | clk_disable_unprepare(pcdev->clk_emma_ipg); |
1829 | clk_put(pcdev->clk_emma); | 1842 | clk_put(pcdev->clk_emma_ipg); |
1843 | clk_disable_unprepare(pcdev->clk_emma_ahb); | ||
1844 | clk_put(pcdev->clk_emma_ahb); | ||
1830 | iounmap(pcdev->base_emma); | 1845 | iounmap(pcdev->base_emma); |
1831 | res = pcdev->res_emma; | 1846 | res = pcdev->res_emma; |
1832 | release_mem_region(res->start, resource_size(res)); | 1847 | release_mem_region(res->start, resource_size(res)); |
diff --git a/drivers/media/video/mx3_camera.c b/drivers/media/video/mx3_camera.c index f13643d31353..af2297dd49c8 100644 --- a/drivers/media/video/mx3_camera.c +++ b/drivers/media/video/mx3_camera.c | |||
@@ -61,15 +61,9 @@ | |||
61 | 61 | ||
62 | #define MAX_VIDEO_MEM 16 | 62 | #define MAX_VIDEO_MEM 16 |
63 | 63 | ||
64 | enum csi_buffer_state { | ||
65 | CSI_BUF_NEEDS_INIT, | ||
66 | CSI_BUF_PREPARED, | ||
67 | }; | ||
68 | |||
69 | struct mx3_camera_buffer { | 64 | struct mx3_camera_buffer { |
70 | /* common v4l buffer stuff -- must be first */ | 65 | /* common v4l buffer stuff -- must be first */ |
71 | struct vb2_buffer vb; | 66 | struct vb2_buffer vb; |
72 | enum csi_buffer_state state; | ||
73 | struct list_head queue; | 67 | struct list_head queue; |
74 | 68 | ||
75 | /* One descriptot per scatterlist (per frame) */ | 69 | /* One descriptot per scatterlist (per frame) */ |
@@ -285,7 +279,7 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb) | |||
285 | goto error; | 279 | goto error; |
286 | } | 280 | } |
287 | 281 | ||
288 | if (buf->state == CSI_BUF_NEEDS_INIT) { | 282 | if (!buf->txd) { |
289 | sg_dma_address(sg) = vb2_dma_contig_plane_dma_addr(vb, 0); | 283 | sg_dma_address(sg) = vb2_dma_contig_plane_dma_addr(vb, 0); |
290 | sg_dma_len(sg) = new_size; | 284 | sg_dma_len(sg) = new_size; |
291 | 285 | ||
@@ -298,7 +292,6 @@ static void mx3_videobuf_queue(struct vb2_buffer *vb) | |||
298 | txd->callback_param = txd; | 292 | txd->callback_param = txd; |
299 | txd->callback = mx3_cam_dma_done; | 293 | txd->callback = mx3_cam_dma_done; |
300 | 294 | ||
301 | buf->state = CSI_BUF_PREPARED; | ||
302 | buf->txd = txd; | 295 | buf->txd = txd; |
303 | } else { | 296 | } else { |
304 | txd = buf->txd; | 297 | txd = buf->txd; |
@@ -385,7 +378,6 @@ static void mx3_videobuf_release(struct vb2_buffer *vb) | |||
385 | 378 | ||
386 | /* Doesn't hurt also if the list is empty */ | 379 | /* Doesn't hurt also if the list is empty */ |
387 | list_del_init(&buf->queue); | 380 | list_del_init(&buf->queue); |
388 | buf->state = CSI_BUF_NEEDS_INIT; | ||
389 | 381 | ||
390 | if (txd) { | 382 | if (txd) { |
391 | buf->txd = NULL; | 383 | buf->txd = NULL; |
@@ -405,13 +397,13 @@ static int mx3_videobuf_init(struct vb2_buffer *vb) | |||
405 | struct mx3_camera_dev *mx3_cam = ici->priv; | 397 | struct mx3_camera_dev *mx3_cam = ici->priv; |
406 | struct mx3_camera_buffer *buf = to_mx3_vb(vb); | 398 | struct mx3_camera_buffer *buf = to_mx3_vb(vb); |
407 | 399 | ||
408 | /* This is for locking debugging only */ | 400 | if (!buf->txd) { |
409 | INIT_LIST_HEAD(&buf->queue); | 401 | /* This is for locking debugging only */ |
410 | sg_init_table(&buf->sg, 1); | 402 | INIT_LIST_HEAD(&buf->queue); |
403 | sg_init_table(&buf->sg, 1); | ||
411 | 404 | ||
412 | buf->state = CSI_BUF_NEEDS_INIT; | 405 | mx3_cam->buf_total += vb2_plane_size(vb, 0); |
413 | 406 | } | |
414 | mx3_cam->buf_total += vb2_plane_size(vb, 0); | ||
415 | 407 | ||
416 | return 0; | 408 | return 0; |
417 | } | 409 | } |
diff --git a/drivers/media/video/soc_camera.c b/drivers/media/video/soc_camera.c index b03ffecb7438..1bde255e45df 100644 --- a/drivers/media/video/soc_camera.c +++ b/drivers/media/video/soc_camera.c | |||
@@ -171,7 +171,8 @@ static int soc_camera_try_fmt(struct soc_camera_device *icd, | |||
171 | dev_dbg(icd->pdev, "TRY_FMT(%c%c%c%c, %ux%u)\n", | 171 | dev_dbg(icd->pdev, "TRY_FMT(%c%c%c%c, %ux%u)\n", |
172 | pixfmtstr(pix->pixelformat), pix->width, pix->height); | 172 | pixfmtstr(pix->pixelformat), pix->width, pix->height); |
173 | 173 | ||
174 | if (!(ici->capabilities & SOCAM_HOST_CAP_STRIDE)) { | 174 | if (pix->pixelformat != V4L2_PIX_FMT_JPEG && |
175 | !(ici->capabilities & SOCAM_HOST_CAP_STRIDE)) { | ||
175 | pix->bytesperline = 0; | 176 | pix->bytesperline = 0; |
176 | pix->sizeimage = 0; | 177 | pix->sizeimage = 0; |
177 | } | 178 | } |
diff --git a/drivers/media/video/soc_mediabus.c b/drivers/media/video/soc_mediabus.c index 89dce097a827..a397812635d6 100644 --- a/drivers/media/video/soc_mediabus.c +++ b/drivers/media/video/soc_mediabus.c | |||
@@ -378,6 +378,9 @@ EXPORT_SYMBOL(soc_mbus_samples_per_pixel); | |||
378 | 378 | ||
379 | s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) | 379 | s32 soc_mbus_bytes_per_line(u32 width, const struct soc_mbus_pixelfmt *mf) |
380 | { | 380 | { |
381 | if (mf->fourcc == V4L2_PIX_FMT_JPEG) | ||
382 | return 0; | ||
383 | |||
381 | if (mf->layout != SOC_MBUS_LAYOUT_PACKED) | 384 | if (mf->layout != SOC_MBUS_LAYOUT_PACKED) |
382 | return width * mf->bits_per_sample / 8; | 385 | return width * mf->bits_per_sample / 8; |
383 | 386 | ||
@@ -400,6 +403,9 @@ EXPORT_SYMBOL(soc_mbus_bytes_per_line); | |||
400 | s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf, | 403 | s32 soc_mbus_image_size(const struct soc_mbus_pixelfmt *mf, |
401 | u32 bytes_per_line, u32 height) | 404 | u32 bytes_per_line, u32 height) |
402 | { | 405 | { |
406 | if (mf->fourcc == V4L2_PIX_FMT_JPEG) | ||
407 | return 0; | ||
408 | |||
403 | if (mf->layout == SOC_MBUS_LAYOUT_PACKED) | 409 | if (mf->layout == SOC_MBUS_LAYOUT_PACKED) |
404 | return bytes_per_line * height; | 410 | return bytes_per_line * height; |
405 | 411 | ||
diff --git a/drivers/media/video/uvc/uvc_queue.c b/drivers/media/video/uvc/uvc_queue.c index 9288fbd5001b..5577381b5bf0 100644 --- a/drivers/media/video/uvc/uvc_queue.c +++ b/drivers/media/video/uvc/uvc_queue.c | |||
@@ -338,6 +338,7 @@ struct uvc_buffer *uvc_queue_next_buffer(struct uvc_video_queue *queue, | |||
338 | if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) { | 338 | if ((queue->flags & UVC_QUEUE_DROP_CORRUPTED) && buf->error) { |
339 | buf->error = 0; | 339 | buf->error = 0; |
340 | buf->state = UVC_BUF_STATE_QUEUED; | 340 | buf->state = UVC_BUF_STATE_QUEUED; |
341 | buf->bytesused = 0; | ||
341 | vb2_set_plane_payload(&buf->buf, 0, 0); | 342 | vb2_set_plane_payload(&buf->buf, 0, 0); |
342 | return buf; | 343 | return buf; |
343 | } | 344 | } |
diff --git a/drivers/media/video/v4l2-ioctl.c b/drivers/media/video/v4l2-ioctl.c index c3b7b5f59b32..6bc47fc82fe2 100644 --- a/drivers/media/video/v4l2-ioctl.c +++ b/drivers/media/video/v4l2-ioctl.c | |||
@@ -402,8 +402,10 @@ static void v4l_print_hw_freq_seek(const void *arg, bool write_only) | |||
402 | { | 402 | { |
403 | const struct v4l2_hw_freq_seek *p = arg; | 403 | const struct v4l2_hw_freq_seek *p = arg; |
404 | 404 | ||
405 | pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u\n", | 405 | pr_cont("tuner=%u, type=%u, seek_upward=%u, wrap_around=%u, spacing=%u, " |
406 | p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing); | 406 | "rangelow=%u, rangehigh=%u\n", |
407 | p->tuner, p->type, p->seek_upward, p->wrap_around, p->spacing, | ||
408 | p->rangelow, p->rangehigh); | ||
407 | } | 409 | } |
408 | 410 | ||
409 | static void v4l_print_requestbuffers(const void *arg, bool write_only) | 411 | static void v4l_print_requestbuffers(const void *arg, bool write_only) |
@@ -1853,6 +1855,8 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops, | |||
1853 | .type = type, | 1855 | .type = type, |
1854 | }; | 1856 | }; |
1855 | 1857 | ||
1858 | if (p->index) | ||
1859 | return -EINVAL; | ||
1856 | err = ops->vidioc_g_tuner(file, fh, &t); | 1860 | err = ops->vidioc_g_tuner(file, fh, &t); |
1857 | if (err) | 1861 | if (err) |
1858 | return err; | 1862 | return err; |
@@ -1870,6 +1874,8 @@ static int v4l_enum_freq_bands(const struct v4l2_ioctl_ops *ops, | |||
1870 | 1874 | ||
1871 | if (type != V4L2_TUNER_RADIO) | 1875 | if (type != V4L2_TUNER_RADIO) |
1872 | return -EINVAL; | 1876 | return -EINVAL; |
1877 | if (p->index) | ||
1878 | return -EINVAL; | ||
1873 | err = ops->vidioc_g_modulator(file, fh, &m); | 1879 | err = ops->vidioc_g_modulator(file, fh, &m); |
1874 | if (err) | 1880 | if (err) |
1875 | return err; | 1881 | return err; |
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index d1facef28a60..b1a146205c08 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -395,7 +395,8 @@ config MFD_TC6387XB | |||
395 | 395 | ||
396 | config MFD_TC6393XB | 396 | config MFD_TC6393XB |
397 | bool "Support Toshiba TC6393XB" | 397 | bool "Support Toshiba TC6393XB" |
398 | depends on GPIOLIB && ARM && HAVE_CLK | 398 | depends on ARM && HAVE_CLK |
399 | select GPIOLIB | ||
399 | select MFD_CORE | 400 | select MFD_CORE |
400 | select MFD_TMIO | 401 | select MFD_TMIO |
401 | help | 402 | help |
diff --git a/drivers/mfd/asic3.c b/drivers/mfd/asic3.c index 383421bf5760..683e18a23329 100644 --- a/drivers/mfd/asic3.c +++ b/drivers/mfd/asic3.c | |||
@@ -925,6 +925,7 @@ static int __init asic3_mfd_probe(struct platform_device *pdev, | |||
925 | goto out; | 925 | goto out; |
926 | } | 926 | } |
927 | 927 | ||
928 | ret = 0; | ||
928 | if (pdata->leds) { | 929 | if (pdata->leds) { |
929 | int i; | 930 | int i; |
930 | 931 | ||
diff --git a/drivers/mfd/ezx-pcap.c b/drivers/mfd/ezx-pcap.c index 43a76c41cfcc..db662e2dcfa5 100644 --- a/drivers/mfd/ezx-pcap.c +++ b/drivers/mfd/ezx-pcap.c | |||
@@ -202,7 +202,7 @@ static void pcap_isr_work(struct work_struct *work) | |||
202 | } | 202 | } |
203 | local_irq_enable(); | 203 | local_irq_enable(); |
204 | ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr); | 204 | ezx_pcap_write(pcap, PCAP_REG_MSR, pcap->msr); |
205 | } while (gpio_get_value(irq_to_gpio(pcap->spi->irq))); | 205 | } while (gpio_get_value(pdata->gpio)); |
206 | } | 206 | } |
207 | 207 | ||
208 | static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) | 208 | static void pcap_irq_handler(unsigned int irq, struct irq_desc *desc) |
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c index c6ffbbe5a6c0..d78c05e693f7 100644 --- a/drivers/misc/mei/interrupt.c +++ b/drivers/misc/mei/interrupt.c | |||
@@ -1253,7 +1253,7 @@ static int mei_irq_thread_write_handler(struct mei_io_list *cmpl_list, | |||
1253 | if (dev->wd_timeout) | 1253 | if (dev->wd_timeout) |
1254 | *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE); | 1254 | *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE); |
1255 | else | 1255 | else |
1256 | *slots -= mei_data2slots(MEI_START_WD_DATA_SIZE); | 1256 | *slots -= mei_data2slots(MEI_WD_PARAMS_SIZE); |
1257 | } | 1257 | } |
1258 | } | 1258 | } |
1259 | if (dev->stop) | 1259 | if (dev->stop) |
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c index 092330208869..7422c7652845 100644 --- a/drivers/misc/mei/main.c +++ b/drivers/misc/mei/main.c | |||
@@ -925,6 +925,27 @@ static struct miscdevice mei_misc_device = { | |||
925 | }; | 925 | }; |
926 | 926 | ||
927 | /** | 927 | /** |
928 | * mei_quirk_probe - probe for devices that doesn't valid ME interface | ||
929 | * @pdev: PCI device structure | ||
930 | * @ent: entry into pci_device_table | ||
931 | * | ||
932 | * returns true if ME Interface is valid, false otherwise | ||
933 | */ | ||
934 | static bool __devinit mei_quirk_probe(struct pci_dev *pdev, | ||
935 | const struct pci_device_id *ent) | ||
936 | { | ||
937 | u32 reg; | ||
938 | if (ent->device == MEI_DEV_ID_PBG_1) { | ||
939 | pci_read_config_dword(pdev, 0x48, ®); | ||
940 | /* make sure that bit 9 is up and bit 10 is down */ | ||
941 | if ((reg & 0x600) == 0x200) { | ||
942 | dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n"); | ||
943 | return false; | ||
944 | } | ||
945 | } | ||
946 | return true; | ||
947 | } | ||
948 | /** | ||
928 | * mei_probe - Device Initialization Routine | 949 | * mei_probe - Device Initialization Routine |
929 | * | 950 | * |
930 | * @pdev: PCI device structure | 951 | * @pdev: PCI device structure |
@@ -939,6 +960,12 @@ static int __devinit mei_probe(struct pci_dev *pdev, | |||
939 | int err; | 960 | int err; |
940 | 961 | ||
941 | mutex_lock(&mei_mutex); | 962 | mutex_lock(&mei_mutex); |
963 | |||
964 | if (!mei_quirk_probe(pdev, ent)) { | ||
965 | err = -ENODEV; | ||
966 | goto end; | ||
967 | } | ||
968 | |||
942 | if (mei_device) { | 969 | if (mei_device) { |
943 | err = -EEXIST; | 970 | err = -EEXIST; |
944 | goto end; | 971 | goto end; |
diff --git a/drivers/misc/sgi-xp/xpc_uv.c b/drivers/misc/sgi-xp/xpc_uv.c index 87b251ab6ec5..b9e2000969f0 100644 --- a/drivers/misc/sgi-xp/xpc_uv.c +++ b/drivers/misc/sgi-xp/xpc_uv.c | |||
@@ -18,6 +18,8 @@ | |||
18 | #include <linux/interrupt.h> | 18 | #include <linux/interrupt.h> |
19 | #include <linux/delay.h> | 19 | #include <linux/delay.h> |
20 | #include <linux/device.h> | 20 | #include <linux/device.h> |
21 | #include <linux/cpu.h> | ||
22 | #include <linux/module.h> | ||
21 | #include <linux/err.h> | 23 | #include <linux/err.h> |
22 | #include <linux/slab.h> | 24 | #include <linux/slab.h> |
23 | #include <asm/uv/uv_hub.h> | 25 | #include <asm/uv/uv_hub.h> |
@@ -59,6 +61,8 @@ static struct xpc_heartbeat_uv *xpc_heartbeat_uv; | |||
59 | XPC_NOTIFY_MSG_SIZE_UV) | 61 | XPC_NOTIFY_MSG_SIZE_UV) |
60 | #define XPC_NOTIFY_IRQ_NAME "xpc_notify" | 62 | #define XPC_NOTIFY_IRQ_NAME "xpc_notify" |
61 | 63 | ||
64 | static int xpc_mq_node = -1; | ||
65 | |||
62 | static struct xpc_gru_mq_uv *xpc_activate_mq_uv; | 66 | static struct xpc_gru_mq_uv *xpc_activate_mq_uv; |
63 | static struct xpc_gru_mq_uv *xpc_notify_mq_uv; | 67 | static struct xpc_gru_mq_uv *xpc_notify_mq_uv; |
64 | 68 | ||
@@ -109,11 +113,8 @@ xpc_get_gru_mq_irq_uv(struct xpc_gru_mq_uv *mq, int cpu, char *irq_name) | |||
109 | #if defined CONFIG_X86_64 | 113 | #if defined CONFIG_X86_64 |
110 | mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset, | 114 | mq->irq = uv_setup_irq(irq_name, cpu, mq->mmr_blade, mq->mmr_offset, |
111 | UV_AFFINITY_CPU); | 115 | UV_AFFINITY_CPU); |
112 | if (mq->irq < 0) { | 116 | if (mq->irq < 0) |
113 | dev_err(xpc_part, "uv_setup_irq() returned error=%d\n", | ||
114 | -mq->irq); | ||
115 | return mq->irq; | 117 | return mq->irq; |
116 | } | ||
117 | 118 | ||
118 | mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset); | 119 | mq->mmr_value = uv_read_global_mmr64(mmr_pnode, mq->mmr_offset); |
119 | 120 | ||
@@ -238,8 +239,9 @@ xpc_create_gru_mq_uv(unsigned int mq_size, int cpu, char *irq_name, | |||
238 | mq->mmr_blade = uv_cpu_to_blade_id(cpu); | 239 | mq->mmr_blade = uv_cpu_to_blade_id(cpu); |
239 | 240 | ||
240 | nid = cpu_to_node(cpu); | 241 | nid = cpu_to_node(cpu); |
241 | page = alloc_pages_exact_node(nid, GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, | 242 | page = alloc_pages_exact_node(nid, |
242 | pg_order); | 243 | GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, |
244 | pg_order); | ||
243 | if (page == NULL) { | 245 | if (page == NULL) { |
244 | dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " | 246 | dev_err(xpc_part, "xpc_create_gru_mq_uv() failed to alloc %d " |
245 | "bytes of memory on nid=%d for GRU mq\n", mq_size, nid); | 247 | "bytes of memory on nid=%d for GRU mq\n", mq_size, nid); |
@@ -1731,9 +1733,50 @@ static struct xpc_arch_operations xpc_arch_ops_uv = { | |||
1731 | .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv, | 1733 | .notify_senders_of_disconnect = xpc_notify_senders_of_disconnect_uv, |
1732 | }; | 1734 | }; |
1733 | 1735 | ||
1736 | static int | ||
1737 | xpc_init_mq_node(int nid) | ||
1738 | { | ||
1739 | int cpu; | ||
1740 | |||
1741 | get_online_cpus(); | ||
1742 | |||
1743 | for_each_cpu(cpu, cpumask_of_node(nid)) { | ||
1744 | xpc_activate_mq_uv = | ||
1745 | xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, nid, | ||
1746 | XPC_ACTIVATE_IRQ_NAME, | ||
1747 | xpc_handle_activate_IRQ_uv); | ||
1748 | if (!IS_ERR(xpc_activate_mq_uv)) | ||
1749 | break; | ||
1750 | } | ||
1751 | if (IS_ERR(xpc_activate_mq_uv)) { | ||
1752 | put_online_cpus(); | ||
1753 | return PTR_ERR(xpc_activate_mq_uv); | ||
1754 | } | ||
1755 | |||
1756 | for_each_cpu(cpu, cpumask_of_node(nid)) { | ||
1757 | xpc_notify_mq_uv = | ||
1758 | xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, nid, | ||
1759 | XPC_NOTIFY_IRQ_NAME, | ||
1760 | xpc_handle_notify_IRQ_uv); | ||
1761 | if (!IS_ERR(xpc_notify_mq_uv)) | ||
1762 | break; | ||
1763 | } | ||
1764 | if (IS_ERR(xpc_notify_mq_uv)) { | ||
1765 | xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); | ||
1766 | put_online_cpus(); | ||
1767 | return PTR_ERR(xpc_notify_mq_uv); | ||
1768 | } | ||
1769 | |||
1770 | put_online_cpus(); | ||
1771 | return 0; | ||
1772 | } | ||
1773 | |||
1734 | int | 1774 | int |
1735 | xpc_init_uv(void) | 1775 | xpc_init_uv(void) |
1736 | { | 1776 | { |
1777 | int nid; | ||
1778 | int ret = 0; | ||
1779 | |||
1737 | xpc_arch_ops = xpc_arch_ops_uv; | 1780 | xpc_arch_ops = xpc_arch_ops_uv; |
1738 | 1781 | ||
1739 | if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) { | 1782 | if (sizeof(struct xpc_notify_mq_msghdr_uv) > XPC_MSG_HDR_MAX_SIZE) { |
@@ -1742,21 +1785,21 @@ xpc_init_uv(void) | |||
1742 | return -E2BIG; | 1785 | return -E2BIG; |
1743 | } | 1786 | } |
1744 | 1787 | ||
1745 | xpc_activate_mq_uv = xpc_create_gru_mq_uv(XPC_ACTIVATE_MQ_SIZE_UV, 0, | 1788 | if (xpc_mq_node < 0) |
1746 | XPC_ACTIVATE_IRQ_NAME, | 1789 | for_each_online_node(nid) { |
1747 | xpc_handle_activate_IRQ_uv); | 1790 | ret = xpc_init_mq_node(nid); |
1748 | if (IS_ERR(xpc_activate_mq_uv)) | ||
1749 | return PTR_ERR(xpc_activate_mq_uv); | ||
1750 | 1791 | ||
1751 | xpc_notify_mq_uv = xpc_create_gru_mq_uv(XPC_NOTIFY_MQ_SIZE_UV, 0, | 1792 | if (!ret) |
1752 | XPC_NOTIFY_IRQ_NAME, | 1793 | break; |
1753 | xpc_handle_notify_IRQ_uv); | 1794 | } |
1754 | if (IS_ERR(xpc_notify_mq_uv)) { | 1795 | else |
1755 | xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); | 1796 | ret = xpc_init_mq_node(xpc_mq_node); |
1756 | return PTR_ERR(xpc_notify_mq_uv); | ||
1757 | } | ||
1758 | 1797 | ||
1759 | return 0; | 1798 | if (ret < 0) |
1799 | dev_err(xpc_part, "xpc_init_mq_node() returned error=%d\n", | ||
1800 | -ret); | ||
1801 | |||
1802 | return ret; | ||
1760 | } | 1803 | } |
1761 | 1804 | ||
1762 | void | 1805 | void |
@@ -1765,3 +1808,6 @@ xpc_exit_uv(void) | |||
1765 | xpc_destroy_gru_mq_uv(xpc_notify_mq_uv); | 1808 | xpc_destroy_gru_mq_uv(xpc_notify_mq_uv); |
1766 | xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); | 1809 | xpc_destroy_gru_mq_uv(xpc_activate_mq_uv); |
1767 | } | 1810 | } |
1811 | |||
1812 | module_param(xpc_mq_node, int, 0); | ||
1813 | MODULE_PARM_DESC(xpc_mq_node, "Node number on which to allocate message queues."); | ||
diff --git a/drivers/misc/ti-st/st_ll.c b/drivers/misc/ti-st/st_ll.c index 1ff460a8e9c7..93b4d67cc4a3 100644 --- a/drivers/misc/ti-st/st_ll.c +++ b/drivers/misc/ti-st/st_ll.c | |||
@@ -87,7 +87,7 @@ static void ll_device_want_to_wakeup(struct st_data_s *st_data) | |||
87 | /* communicate to platform about chip wakeup */ | 87 | /* communicate to platform about chip wakeup */ |
88 | kim_data = st_data->kim_data; | 88 | kim_data = st_data->kim_data; |
89 | pdata = kim_data->kim_pdev->dev.platform_data; | 89 | pdata = kim_data->kim_pdev->dev.platform_data; |
90 | if (pdata->chip_asleep) | 90 | if (pdata->chip_awake) |
91 | pdata->chip_awake(NULL); | 91 | pdata->chip_awake(NULL); |
92 | } | 92 | } |
93 | 93 | ||
diff --git a/drivers/mtd/maps/uclinux.c b/drivers/mtd/maps/uclinux.c index cfff454f628b..c3bb304eca07 100644 --- a/drivers/mtd/maps/uclinux.c +++ b/drivers/mtd/maps/uclinux.c | |||
@@ -19,14 +19,13 @@ | |||
19 | #include <linux/mtd/map.h> | 19 | #include <linux/mtd/map.h> |
20 | #include <linux/mtd/partitions.h> | 20 | #include <linux/mtd/partitions.h> |
21 | #include <asm/io.h> | 21 | #include <asm/io.h> |
22 | #include <asm/sections.h> | ||
22 | 23 | ||
23 | /****************************************************************************/ | 24 | /****************************************************************************/ |
24 | 25 | ||
25 | extern char _ebss; | ||
26 | |||
27 | struct map_info uclinux_ram_map = { | 26 | struct map_info uclinux_ram_map = { |
28 | .name = "RAM", | 27 | .name = "RAM", |
29 | .phys = (unsigned long)&_ebss, | 28 | .phys = (unsigned long)__bss_stop, |
30 | .size = 0, | 29 | .size = 0, |
31 | }; | 30 | }; |
32 | 31 | ||
diff --git a/drivers/mtd/nand/Kconfig b/drivers/mtd/nand/Kconfig index 31bb7e5b504a..8ca417614c57 100644 --- a/drivers/mtd/nand/Kconfig +++ b/drivers/mtd/nand/Kconfig | |||
@@ -480,7 +480,7 @@ config MTD_NAND_NANDSIM | |||
480 | 480 | ||
481 | config MTD_NAND_GPMI_NAND | 481 | config MTD_NAND_GPMI_NAND |
482 | bool "GPMI NAND Flash Controller driver" | 482 | bool "GPMI NAND Flash Controller driver" |
483 | depends on MTD_NAND && (SOC_IMX23 || SOC_IMX28 || SOC_IMX6Q) | 483 | depends on MTD_NAND && MXS_DMA |
484 | help | 484 | help |
485 | Enables NAND Flash support for IMX23 or IMX28. | 485 | Enables NAND Flash support for IMX23 or IMX28. |
486 | The GPMI controller is very powerful, with the help of BCH | 486 | The GPMI controller is very powerful, with the help of BCH |
diff --git a/drivers/mtd/nand/omap2.c b/drivers/mtd/nand/omap2.c index e9309b3659e7..ac4fd756eda3 100644 --- a/drivers/mtd/nand/omap2.c +++ b/drivers/mtd/nand/omap2.c | |||
@@ -1245,7 +1245,6 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
1245 | goto out_release_mem_region; | 1245 | goto out_release_mem_region; |
1246 | } else { | 1246 | } else { |
1247 | struct dma_slave_config cfg; | 1247 | struct dma_slave_config cfg; |
1248 | int rc; | ||
1249 | 1248 | ||
1250 | memset(&cfg, 0, sizeof(cfg)); | 1249 | memset(&cfg, 0, sizeof(cfg)); |
1251 | cfg.src_addr = info->phys_base; | 1250 | cfg.src_addr = info->phys_base; |
@@ -1254,10 +1253,10 @@ static int __devinit omap_nand_probe(struct platform_device *pdev) | |||
1254 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; | 1253 | cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; |
1255 | cfg.src_maxburst = 16; | 1254 | cfg.src_maxburst = 16; |
1256 | cfg.dst_maxburst = 16; | 1255 | cfg.dst_maxburst = 16; |
1257 | rc = dmaengine_slave_config(info->dma, &cfg); | 1256 | err = dmaengine_slave_config(info->dma, &cfg); |
1258 | if (rc) { | 1257 | if (err) { |
1259 | dev_err(&pdev->dev, "DMA engine slave config failed: %d\n", | 1258 | dev_err(&pdev->dev, "DMA engine slave config failed: %d\n", |
1260 | rc); | 1259 | err); |
1261 | goto out_release_mem_region; | 1260 | goto out_release_mem_region; |
1262 | } | 1261 | } |
1263 | info->nand.read_buf = omap_read_buf_dma_pref; | 1262 | info->nand.read_buf = omap_read_buf_dma_pref; |
diff --git a/drivers/net/appletalk/cops.c b/drivers/net/appletalk/cops.c index 545c09ed9079..cff6f023c03a 100644 --- a/drivers/net/appletalk/cops.c +++ b/drivers/net/appletalk/cops.c | |||
@@ -996,9 +996,7 @@ static int __init cops_module_init(void) | |||
996 | printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", | 996 | printk(KERN_WARNING "%s: You shouldn't autoprobe with insmod\n", |
997 | cardname); | 997 | cardname); |
998 | cops_dev = cops_probe(-1); | 998 | cops_dev = cops_probe(-1); |
999 | if (IS_ERR(cops_dev)) | 999 | return PTR_RET(cops_dev); |
1000 | return PTR_ERR(cops_dev); | ||
1001 | return 0; | ||
1002 | } | 1000 | } |
1003 | 1001 | ||
1004 | static void __exit cops_module_exit(void) | 1002 | static void __exit cops_module_exit(void) |
diff --git a/drivers/net/appletalk/ltpc.c b/drivers/net/appletalk/ltpc.c index 0910dce3996d..b5782cdf0bca 100644 --- a/drivers/net/appletalk/ltpc.c +++ b/drivers/net/appletalk/ltpc.c | |||
@@ -1243,9 +1243,7 @@ static int __init ltpc_module_init(void) | |||
1243 | "ltpc: Autoprobing is not recommended for modules\n"); | 1243 | "ltpc: Autoprobing is not recommended for modules\n"); |
1244 | 1244 | ||
1245 | dev_ltpc = ltpc_probe(); | 1245 | dev_ltpc = ltpc_probe(); |
1246 | if (IS_ERR(dev_ltpc)) | 1246 | return PTR_RET(dev_ltpc); |
1247 | return PTR_ERR(dev_ltpc); | ||
1248 | return 0; | ||
1249 | } | 1247 | } |
1250 | module_init(ltpc_module_init); | 1248 | module_init(ltpc_module_init); |
1251 | #endif | 1249 | #endif |
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c index d95fbc34b229..a86174c9fed1 100644 --- a/drivers/net/bonding/bond_main.c +++ b/drivers/net/bonding/bond_main.c | |||
@@ -398,7 +398,7 @@ int bond_dev_queue_xmit(struct bonding *bond, struct sk_buff *skb, | |||
398 | sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping)); | 398 | sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping)); |
399 | skb->queue_mapping = qdisc_skb_cb(skb)->slave_dev_queue_mapping; | 399 | skb->queue_mapping = qdisc_skb_cb(skb)->slave_dev_queue_mapping; |
400 | 400 | ||
401 | if (unlikely(netpoll_tx_running(slave_dev))) | 401 | if (unlikely(netpoll_tx_running(bond->dev))) |
402 | bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb); | 402 | bond_netpoll_send_skb(bond_get_slave_by_dev(bond, slave_dev), skb); |
403 | else | 403 | else |
404 | dev_queue_xmit(skb); | 404 | dev_queue_xmit(skb); |
@@ -1235,12 +1235,12 @@ static inline int slave_enable_netpoll(struct slave *slave) | |||
1235 | struct netpoll *np; | 1235 | struct netpoll *np; |
1236 | int err = 0; | 1236 | int err = 0; |
1237 | 1237 | ||
1238 | np = kzalloc(sizeof(*np), GFP_KERNEL); | 1238 | np = kzalloc(sizeof(*np), GFP_ATOMIC); |
1239 | err = -ENOMEM; | 1239 | err = -ENOMEM; |
1240 | if (!np) | 1240 | if (!np) |
1241 | goto out; | 1241 | goto out; |
1242 | 1242 | ||
1243 | err = __netpoll_setup(np, slave->dev); | 1243 | err = __netpoll_setup(np, slave->dev, GFP_ATOMIC); |
1244 | if (err) { | 1244 | if (err) { |
1245 | kfree(np); | 1245 | kfree(np); |
1246 | goto out; | 1246 | goto out; |
@@ -1257,9 +1257,7 @@ static inline void slave_disable_netpoll(struct slave *slave) | |||
1257 | return; | 1257 | return; |
1258 | 1258 | ||
1259 | slave->np = NULL; | 1259 | slave->np = NULL; |
1260 | synchronize_rcu_bh(); | 1260 | __netpoll_free_rcu(np); |
1261 | __netpoll_cleanup(np); | ||
1262 | kfree(np); | ||
1263 | } | 1261 | } |
1264 | static inline bool slave_dev_support_netpoll(struct net_device *slave_dev) | 1262 | static inline bool slave_dev_support_netpoll(struct net_device *slave_dev) |
1265 | { | 1263 | { |
@@ -1292,7 +1290,7 @@ static void bond_netpoll_cleanup(struct net_device *bond_dev) | |||
1292 | read_unlock(&bond->lock); | 1290 | read_unlock(&bond->lock); |
1293 | } | 1291 | } |
1294 | 1292 | ||
1295 | static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni) | 1293 | static int bond_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, gfp_t gfp) |
1296 | { | 1294 | { |
1297 | struct bonding *bond = netdev_priv(dev); | 1295 | struct bonding *bond = netdev_priv(dev); |
1298 | struct slave *slave; | 1296 | struct slave *slave; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h index 77bcd4cb4ffb..463b9ec57d80 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | |||
@@ -1278,7 +1278,7 @@ struct bnx2x { | |||
1278 | #define BNX2X_FW_RX_ALIGN_START (1UL << BNX2X_RX_ALIGN_SHIFT) | 1278 | #define BNX2X_FW_RX_ALIGN_START (1UL << BNX2X_RX_ALIGN_SHIFT) |
1279 | 1279 | ||
1280 | #define BNX2X_FW_RX_ALIGN_END \ | 1280 | #define BNX2X_FW_RX_ALIGN_END \ |
1281 | max(1UL << BNX2X_RX_ALIGN_SHIFT, \ | 1281 | max_t(u64, 1UL << BNX2X_RX_ALIGN_SHIFT, \ |
1282 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) | 1282 | SKB_DATA_ALIGN(sizeof(struct skb_shared_info))) |
1283 | 1283 | ||
1284 | #define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5) | 1284 | #define BNX2X_PXP_DRAM_ALIGN (BNX2X_RX_ALIGN_SHIFT - 5) |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index dd451c3dd83d..02b5a343b195 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -4041,20 +4041,6 @@ static bool bnx2x_get_load_status(struct bnx2x *bp, int engine) | |||
4041 | return val != 0; | 4041 | return val != 0; |
4042 | } | 4042 | } |
4043 | 4043 | ||
4044 | /* | ||
4045 | * Reset the load status for the current engine. | ||
4046 | */ | ||
4047 | static void bnx2x_clear_load_status(struct bnx2x *bp) | ||
4048 | { | ||
4049 | u32 val; | ||
4050 | u32 mask = (BP_PATH(bp) ? BNX2X_PATH1_LOAD_CNT_MASK : | ||
4051 | BNX2X_PATH0_LOAD_CNT_MASK); | ||
4052 | bnx2x_acquire_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); | ||
4053 | val = REG_RD(bp, BNX2X_RECOVERY_GLOB_REG); | ||
4054 | REG_WR(bp, BNX2X_RECOVERY_GLOB_REG, val & (~mask)); | ||
4055 | bnx2x_release_hw_lock(bp, HW_LOCK_RESOURCE_RECOVERY_REG); | ||
4056 | } | ||
4057 | |||
4058 | static void _print_next_block(int idx, const char *blk) | 4044 | static void _print_next_block(int idx, const char *blk) |
4059 | { | 4045 | { |
4060 | pr_cont("%s%s", idx ? ", " : "", blk); | 4046 | pr_cont("%s%s", idx ? ", " : "", blk); |
@@ -9384,32 +9370,24 @@ static int __devinit bnx2x_prev_mark_path(struct bnx2x *bp) | |||
9384 | return rc; | 9370 | return rc; |
9385 | } | 9371 | } |
9386 | 9372 | ||
9387 | static bool __devinit bnx2x_can_flr(struct bnx2x *bp) | ||
9388 | { | ||
9389 | int pos; | ||
9390 | u32 cap; | ||
9391 | struct pci_dev *dev = bp->pdev; | ||
9392 | |||
9393 | pos = pci_pcie_cap(dev); | ||
9394 | if (!pos) | ||
9395 | return false; | ||
9396 | |||
9397 | pci_read_config_dword(dev, pos + PCI_EXP_DEVCAP, &cap); | ||
9398 | if (!(cap & PCI_EXP_DEVCAP_FLR)) | ||
9399 | return false; | ||
9400 | |||
9401 | return true; | ||
9402 | } | ||
9403 | |||
9404 | static int __devinit bnx2x_do_flr(struct bnx2x *bp) | 9373 | static int __devinit bnx2x_do_flr(struct bnx2x *bp) |
9405 | { | 9374 | { |
9406 | int i, pos; | 9375 | int i, pos; |
9407 | u16 status; | 9376 | u16 status; |
9408 | struct pci_dev *dev = bp->pdev; | 9377 | struct pci_dev *dev = bp->pdev; |
9409 | 9378 | ||
9410 | /* probe the capability first */ | 9379 | |
9411 | if (bnx2x_can_flr(bp)) | 9380 | if (CHIP_IS_E1x(bp)) { |
9412 | return -ENOTTY; | 9381 | BNX2X_DEV_INFO("FLR not supported in E1/E1H\n"); |
9382 | return -EINVAL; | ||
9383 | } | ||
9384 | |||
9385 | /* only bootcode REQ_BC_VER_4_INITIATE_FLR and onwards support flr */ | ||
9386 | if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) { | ||
9387 | BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n", | ||
9388 | bp->common.bc_ver); | ||
9389 | return -EINVAL; | ||
9390 | } | ||
9413 | 9391 | ||
9414 | pos = pci_pcie_cap(dev); | 9392 | pos = pci_pcie_cap(dev); |
9415 | if (!pos) | 9393 | if (!pos) |
@@ -9429,12 +9407,8 @@ static int __devinit bnx2x_do_flr(struct bnx2x *bp) | |||
9429 | "transaction is not cleared; proceeding with reset anyway\n"); | 9407 | "transaction is not cleared; proceeding with reset anyway\n"); |
9430 | 9408 | ||
9431 | clear: | 9409 | clear: |
9432 | if (bp->common.bc_ver < REQ_BC_VER_4_INITIATE_FLR) { | ||
9433 | BNX2X_ERR("FLR not supported by BC_VER: 0x%x\n", | ||
9434 | bp->common.bc_ver); | ||
9435 | return -EINVAL; | ||
9436 | } | ||
9437 | 9410 | ||
9411 | BNX2X_DEV_INFO("Initiating FLR\n"); | ||
9438 | bnx2x_fw_command(bp, DRV_MSG_CODE_INITIATE_FLR, 0); | 9412 | bnx2x_fw_command(bp, DRV_MSG_CODE_INITIATE_FLR, 0); |
9439 | 9413 | ||
9440 | return 0; | 9414 | return 0; |
@@ -9454,8 +9428,21 @@ static int __devinit bnx2x_prev_unload_uncommon(struct bnx2x *bp) | |||
9454 | * the one required, then FLR will be sufficient to clean any residue | 9428 | * the one required, then FLR will be sufficient to clean any residue |
9455 | * left by previous driver | 9429 | * left by previous driver |
9456 | */ | 9430 | */ |
9457 | if (bnx2x_test_firmware_version(bp, false) && bnx2x_can_flr(bp)) | 9431 | rc = bnx2x_test_firmware_version(bp, false); |
9458 | return bnx2x_do_flr(bp); | 9432 | |
9433 | if (!rc) { | ||
9434 | /* fw version is good */ | ||
9435 | BNX2X_DEV_INFO("FW version matches our own. Attempting FLR\n"); | ||
9436 | rc = bnx2x_do_flr(bp); | ||
9437 | } | ||
9438 | |||
9439 | if (!rc) { | ||
9440 | /* FLR was performed */ | ||
9441 | BNX2X_DEV_INFO("FLR successful\n"); | ||
9442 | return 0; | ||
9443 | } | ||
9444 | |||
9445 | BNX2X_DEV_INFO("Could not FLR\n"); | ||
9459 | 9446 | ||
9460 | /* Close the MCP request, return failure*/ | 9447 | /* Close the MCP request, return failure*/ |
9461 | rc = bnx2x_prev_mcp_done(bp); | 9448 | rc = bnx2x_prev_mcp_done(bp); |
@@ -11427,9 +11414,6 @@ static int __devinit bnx2x_init_dev(struct pci_dev *pdev, | |||
11427 | if (!chip_is_e1x) | 11414 | if (!chip_is_e1x) |
11428 | REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1); | 11415 | REG_WR(bp, PGLUE_B_REG_INTERNAL_PFID_ENABLE_TARGET_READ, 1); |
11429 | 11416 | ||
11430 | /* Reset the load counter */ | ||
11431 | bnx2x_clear_load_status(bp); | ||
11432 | |||
11433 | dev->watchdog_timeo = TX_TIMEOUT; | 11417 | dev->watchdog_timeo = TX_TIMEOUT; |
11434 | 11418 | ||
11435 | dev->netdev_ops = &bnx2x_netdev_ops; | 11419 | dev->netdev_ops = &bnx2x_netdev_ops; |
diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c index 0f2d1a710909..151453309401 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c +++ b/drivers/net/ethernet/freescale/fs_enet/mii-bitbang.c | |||
@@ -174,8 +174,10 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) | |||
174 | 174 | ||
175 | new_bus->phy_mask = ~0; | 175 | new_bus->phy_mask = ~0; |
176 | new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); | 176 | new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); |
177 | if (!new_bus->irq) | 177 | if (!new_bus->irq) { |
178 | ret = -ENOMEM; | ||
178 | goto out_unmap_regs; | 179 | goto out_unmap_regs; |
180 | } | ||
179 | 181 | ||
180 | new_bus->parent = &ofdev->dev; | 182 | new_bus->parent = &ofdev->dev; |
181 | dev_set_drvdata(&ofdev->dev, new_bus); | 183 | dev_set_drvdata(&ofdev->dev, new_bus); |
diff --git a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c index 55bb867258e6..cdf702a59485 100644 --- a/drivers/net/ethernet/freescale/fs_enet/mii-fec.c +++ b/drivers/net/ethernet/freescale/fs_enet/mii-fec.c | |||
@@ -137,8 +137,10 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) | |||
137 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start); | 137 | snprintf(new_bus->id, MII_BUS_ID_SIZE, "%x", res.start); |
138 | 138 | ||
139 | fec->fecp = ioremap(res.start, resource_size(&res)); | 139 | fec->fecp = ioremap(res.start, resource_size(&res)); |
140 | if (!fec->fecp) | 140 | if (!fec->fecp) { |
141 | ret = -ENOMEM; | ||
141 | goto out_fec; | 142 | goto out_fec; |
143 | } | ||
142 | 144 | ||
143 | if (get_bus_freq) { | 145 | if (get_bus_freq) { |
144 | clock = get_bus_freq(ofdev->dev.of_node); | 146 | clock = get_bus_freq(ofdev->dev.of_node); |
@@ -172,8 +174,10 @@ static int __devinit fs_enet_mdio_probe(struct platform_device *ofdev) | |||
172 | 174 | ||
173 | new_bus->phy_mask = ~0; | 175 | new_bus->phy_mask = ~0; |
174 | new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); | 176 | new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL); |
175 | if (!new_bus->irq) | 177 | if (!new_bus->irq) { |
178 | ret = -ENOMEM; | ||
176 | goto out_unmap_regs; | 179 | goto out_unmap_regs; |
180 | } | ||
177 | 181 | ||
178 | new_bus->parent = &ofdev->dev; | 182 | new_bus->parent = &ofdev->dev; |
179 | dev_set_drvdata(&ofdev->dev, new_bus); | 183 | dev_set_drvdata(&ofdev->dev, new_bus); |
diff --git a/drivers/net/ethernet/intel/e1000e/82571.c b/drivers/net/ethernet/intel/e1000e/82571.c index 0b3bade957fd..080c89093feb 100644 --- a/drivers/net/ethernet/intel/e1000e/82571.c +++ b/drivers/net/ethernet/intel/e1000e/82571.c | |||
@@ -999,7 +999,7 @@ static s32 e1000_set_d0_lplu_state_82571(struct e1000_hw *hw, bool active) | |||
999 | **/ | 999 | **/ |
1000 | static s32 e1000_reset_hw_82571(struct e1000_hw *hw) | 1000 | static s32 e1000_reset_hw_82571(struct e1000_hw *hw) |
1001 | { | 1001 | { |
1002 | u32 ctrl, ctrl_ext, eecd; | 1002 | u32 ctrl, ctrl_ext, eecd, tctl; |
1003 | s32 ret_val; | 1003 | s32 ret_val; |
1004 | 1004 | ||
1005 | /* | 1005 | /* |
@@ -1014,7 +1014,9 @@ static s32 e1000_reset_hw_82571(struct e1000_hw *hw) | |||
1014 | ew32(IMC, 0xffffffff); | 1014 | ew32(IMC, 0xffffffff); |
1015 | 1015 | ||
1016 | ew32(RCTL, 0); | 1016 | ew32(RCTL, 0); |
1017 | ew32(TCTL, E1000_TCTL_PSP); | 1017 | tctl = er32(TCTL); |
1018 | tctl &= ~E1000_TCTL_EN; | ||
1019 | ew32(TCTL, tctl); | ||
1018 | e1e_flush(); | 1020 | e1e_flush(); |
1019 | 1021 | ||
1020 | usleep_range(10000, 20000); | 1022 | usleep_range(10000, 20000); |
@@ -1601,10 +1603,8 @@ static s32 e1000_check_for_serdes_link_82571(struct e1000_hw *hw) | |||
1601 | * auto-negotiation in the TXCW register and disable | 1603 | * auto-negotiation in the TXCW register and disable |
1602 | * forced link in the Device Control register in an | 1604 | * forced link in the Device Control register in an |
1603 | * attempt to auto-negotiate with our link partner. | 1605 | * attempt to auto-negotiate with our link partner. |
1604 | * If the partner code word is null, stop forcing | ||
1605 | * and restart auto negotiation. | ||
1606 | */ | 1606 | */ |
1607 | if ((rxcw & E1000_RXCW_C) || !(rxcw & E1000_RXCW_CW)) { | 1607 | if (rxcw & E1000_RXCW_C) { |
1608 | /* Enable autoneg, and unforce link up */ | 1608 | /* Enable autoneg, and unforce link up */ |
1609 | ew32(TXCW, mac->txcw); | 1609 | ew32(TXCW, mac->txcw); |
1610 | ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); | 1610 | ew32(CTRL, (ctrl & ~E1000_CTRL_SLU)); |
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index 95b245310f17..46c3b1f9ff89 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -178,6 +178,24 @@ static void e1000_regdump(struct e1000_hw *hw, struct e1000_reg_info *reginfo) | |||
178 | pr_info("%-15s %08x %08x\n", rname, regs[0], regs[1]); | 178 | pr_info("%-15s %08x %08x\n", rname, regs[0], regs[1]); |
179 | } | 179 | } |
180 | 180 | ||
181 | static void e1000e_dump_ps_pages(struct e1000_adapter *adapter, | ||
182 | struct e1000_buffer *bi) | ||
183 | { | ||
184 | int i; | ||
185 | struct e1000_ps_page *ps_page; | ||
186 | |||
187 | for (i = 0; i < adapter->rx_ps_pages; i++) { | ||
188 | ps_page = &bi->ps_pages[i]; | ||
189 | |||
190 | if (ps_page->page) { | ||
191 | pr_info("packet dump for ps_page %d:\n", i); | ||
192 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, | ||
193 | 16, 1, page_address(ps_page->page), | ||
194 | PAGE_SIZE, true); | ||
195 | } | ||
196 | } | ||
197 | } | ||
198 | |||
181 | /* | 199 | /* |
182 | * e1000e_dump - Print registers, Tx-ring and Rx-ring | 200 | * e1000e_dump - Print registers, Tx-ring and Rx-ring |
183 | */ | 201 | */ |
@@ -299,10 +317,10 @@ static void e1000e_dump(struct e1000_adapter *adapter) | |||
299 | (unsigned long long)buffer_info->time_stamp, | 317 | (unsigned long long)buffer_info->time_stamp, |
300 | buffer_info->skb, next_desc); | 318 | buffer_info->skb, next_desc); |
301 | 319 | ||
302 | if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) | 320 | if (netif_msg_pktdata(adapter) && buffer_info->skb) |
303 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, | 321 | print_hex_dump(KERN_INFO, "", DUMP_PREFIX_ADDRESS, |
304 | 16, 1, phys_to_virt(buffer_info->dma), | 322 | 16, 1, buffer_info->skb->data, |
305 | buffer_info->length, true); | 323 | buffer_info->skb->len, true); |
306 | } | 324 | } |
307 | 325 | ||
308 | /* Print Rx Ring Summary */ | 326 | /* Print Rx Ring Summary */ |
@@ -381,10 +399,8 @@ rx_ring_summary: | |||
381 | buffer_info->skb, next_desc); | 399 | buffer_info->skb, next_desc); |
382 | 400 | ||
383 | if (netif_msg_pktdata(adapter)) | 401 | if (netif_msg_pktdata(adapter)) |
384 | print_hex_dump(KERN_INFO, "", | 402 | e1000e_dump_ps_pages(adapter, |
385 | DUMP_PREFIX_ADDRESS, 16, 1, | 403 | buffer_info); |
386 | phys_to_virt(buffer_info->dma), | ||
387 | adapter->rx_ps_bsize0, true); | ||
388 | } | 404 | } |
389 | } | 405 | } |
390 | break; | 406 | break; |
@@ -444,12 +460,12 @@ rx_ring_summary: | |||
444 | (unsigned long long)buffer_info->dma, | 460 | (unsigned long long)buffer_info->dma, |
445 | buffer_info->skb, next_desc); | 461 | buffer_info->skb, next_desc); |
446 | 462 | ||
447 | if (netif_msg_pktdata(adapter)) | 463 | if (netif_msg_pktdata(adapter) && |
464 | buffer_info->skb) | ||
448 | print_hex_dump(KERN_INFO, "", | 465 | print_hex_dump(KERN_INFO, "", |
449 | DUMP_PREFIX_ADDRESS, 16, | 466 | DUMP_PREFIX_ADDRESS, 16, |
450 | 1, | 467 | 1, |
451 | phys_to_virt | 468 | buffer_info->skb->data, |
452 | (buffer_info->dma), | ||
453 | adapter->rx_buffer_len, | 469 | adapter->rx_buffer_len, |
454 | true); | 470 | true); |
455 | } | 471 | } |
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c index 5e84eaac48c1..ba994fb4cec6 100644 --- a/drivers/net/ethernet/intel/igb/e1000_82575.c +++ b/drivers/net/ethernet/intel/igb/e1000_82575.c | |||
@@ -254,6 +254,14 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) | |||
254 | */ | 254 | */ |
255 | size += NVM_WORD_SIZE_BASE_SHIFT; | 255 | size += NVM_WORD_SIZE_BASE_SHIFT; |
256 | 256 | ||
257 | /* | ||
258 | * Check for invalid size | ||
259 | */ | ||
260 | if ((hw->mac.type == e1000_82576) && (size > 15)) { | ||
261 | pr_notice("The NVM size is not valid, defaulting to 32K\n"); | ||
262 | size = 15; | ||
263 | } | ||
264 | |||
257 | nvm->word_size = 1 << size; | 265 | nvm->word_size = 1 << size; |
258 | if (hw->mac.type < e1000_i210) { | 266 | if (hw->mac.type < e1000_i210) { |
259 | nvm->opcode_bits = 8; | 267 | nvm->opcode_bits = 8; |
@@ -281,14 +289,6 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw) | |||
281 | } else | 289 | } else |
282 | nvm->type = e1000_nvm_flash_hw; | 290 | nvm->type = e1000_nvm_flash_hw; |
283 | 291 | ||
284 | /* | ||
285 | * Check for invalid size | ||
286 | */ | ||
287 | if ((hw->mac.type == e1000_82576) && (size > 15)) { | ||
288 | pr_notice("The NVM size is not valid, defaulting to 32K\n"); | ||
289 | size = 15; | ||
290 | } | ||
291 | |||
292 | /* NVM Function Pointers */ | 292 | /* NVM Function Pointers */ |
293 | switch (hw->mac.type) { | 293 | switch (hw->mac.type) { |
294 | case e1000_82580: | 294 | case e1000_82580: |
diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h index 10efcd88dca0..28394bea5253 100644 --- a/drivers/net/ethernet/intel/igb/e1000_regs.h +++ b/drivers/net/ethernet/intel/igb/e1000_regs.h | |||
@@ -156,8 +156,12 @@ | |||
156 | : (0x0E018 + ((_n) * 0x40))) | 156 | : (0x0E018 + ((_n) * 0x40))) |
157 | #define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) \ | 157 | #define E1000_TXDCTL(_n) ((_n) < 4 ? (0x03828 + ((_n) * 0x100)) \ |
158 | : (0x0E028 + ((_n) * 0x40))) | 158 | : (0x0E028 + ((_n) * 0x40))) |
159 | #define E1000_DCA_TXCTRL(_n) (0x03814 + (_n << 8)) | 159 | #define E1000_RXCTL(_n) ((_n) < 4 ? (0x02814 + ((_n) * 0x100)) : \ |
160 | #define E1000_DCA_RXCTRL(_n) (0x02814 + (_n << 8)) | 160 | (0x0C014 + ((_n) * 0x40))) |
161 | #define E1000_DCA_RXCTRL(_n) E1000_RXCTL(_n) | ||
162 | #define E1000_TXCTL(_n) ((_n) < 4 ? (0x03814 + ((_n) * 0x100)) : \ | ||
163 | (0x0E014 + ((_n) * 0x40))) | ||
164 | #define E1000_DCA_TXCTRL(_n) E1000_TXCTL(_n) | ||
161 | #define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) \ | 165 | #define E1000_TDWBAL(_n) ((_n) < 4 ? (0x03838 + ((_n) * 0x100)) \ |
162 | : (0x0E038 + ((_n) * 0x40))) | 166 | : (0x0E038 + ((_n) * 0x40))) |
163 | #define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) \ | 167 | #define E1000_TDWBAH(_n) ((_n) < 4 ? (0x0383C + ((_n) * 0x100)) \ |
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c index a19c84cad0e9..70591117051b 100644 --- a/drivers/net/ethernet/intel/igb/igb_ethtool.c +++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c | |||
@@ -209,8 +209,8 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) | |||
209 | /* When SoL/IDER sessions are active, autoneg/speed/duplex | 209 | /* When SoL/IDER sessions are active, autoneg/speed/duplex |
210 | * cannot be changed */ | 210 | * cannot be changed */ |
211 | if (igb_check_reset_block(hw)) { | 211 | if (igb_check_reset_block(hw)) { |
212 | dev_err(&adapter->pdev->dev, "Cannot change link " | 212 | dev_err(&adapter->pdev->dev, |
213 | "characteristics when SoL/IDER is active.\n"); | 213 | "Cannot change link characteristics when SoL/IDER is active.\n"); |
214 | return -EINVAL; | 214 | return -EINVAL; |
215 | } | 215 | } |
216 | 216 | ||
@@ -1089,8 +1089,8 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data, | |||
1089 | wr32(reg, (_test[pat] & write)); | 1089 | wr32(reg, (_test[pat] & write)); |
1090 | val = rd32(reg) & mask; | 1090 | val = rd32(reg) & mask; |
1091 | if (val != (_test[pat] & write & mask)) { | 1091 | if (val != (_test[pat] & write & mask)) { |
1092 | dev_err(&adapter->pdev->dev, "pattern test reg %04X " | 1092 | dev_err(&adapter->pdev->dev, |
1093 | "failed: got 0x%08X expected 0x%08X\n", | 1093 | "pattern test reg %04X failed: got 0x%08X expected 0x%08X\n", |
1094 | reg, val, (_test[pat] & write & mask)); | 1094 | reg, val, (_test[pat] & write & mask)); |
1095 | *data = reg; | 1095 | *data = reg; |
1096 | return 1; | 1096 | return 1; |
@@ -1108,8 +1108,8 @@ static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data, | |||
1108 | wr32(reg, write & mask); | 1108 | wr32(reg, write & mask); |
1109 | val = rd32(reg); | 1109 | val = rd32(reg); |
1110 | if ((write & mask) != (val & mask)) { | 1110 | if ((write & mask) != (val & mask)) { |
1111 | dev_err(&adapter->pdev->dev, "set/check reg %04X test failed:" | 1111 | dev_err(&adapter->pdev->dev, |
1112 | " got 0x%08X expected 0x%08X\n", reg, | 1112 | "set/check reg %04X test failed: got 0x%08X expected 0x%08X\n", reg, |
1113 | (val & mask), (write & mask)); | 1113 | (val & mask), (write & mask)); |
1114 | *data = reg; | 1114 | *data = reg; |
1115 | return 1; | 1115 | return 1; |
@@ -1171,8 +1171,9 @@ static int igb_reg_test(struct igb_adapter *adapter, u64 *data) | |||
1171 | wr32(E1000_STATUS, toggle); | 1171 | wr32(E1000_STATUS, toggle); |
1172 | after = rd32(E1000_STATUS) & toggle; | 1172 | after = rd32(E1000_STATUS) & toggle; |
1173 | if (value != after) { | 1173 | if (value != after) { |
1174 | dev_err(&adapter->pdev->dev, "failed STATUS register test " | 1174 | dev_err(&adapter->pdev->dev, |
1175 | "got: 0x%08X expected: 0x%08X\n", after, value); | 1175 | "failed STATUS register test got: 0x%08X expected: 0x%08X\n", |
1176 | after, value); | ||
1176 | *data = 1; | 1177 | *data = 1; |
1177 | return 1; | 1178 | return 1; |
1178 | } | 1179 | } |
@@ -1497,6 +1498,9 @@ static int igb_integrated_phy_loopback(struct igb_adapter *adapter) | |||
1497 | break; | 1498 | break; |
1498 | } | 1499 | } |
1499 | 1500 | ||
1501 | /* add small delay to avoid loopback test failure */ | ||
1502 | msleep(50); | ||
1503 | |||
1500 | /* force 1000, set loopback */ | 1504 | /* force 1000, set loopback */ |
1501 | igb_write_phy_reg(hw, PHY_CONTROL, 0x4140); | 1505 | igb_write_phy_reg(hw, PHY_CONTROL, 0x4140); |
1502 | 1506 | ||
@@ -1777,16 +1781,14 @@ static int igb_loopback_test(struct igb_adapter *adapter, u64 *data) | |||
1777 | * sessions are active */ | 1781 | * sessions are active */ |
1778 | if (igb_check_reset_block(&adapter->hw)) { | 1782 | if (igb_check_reset_block(&adapter->hw)) { |
1779 | dev_err(&adapter->pdev->dev, | 1783 | dev_err(&adapter->pdev->dev, |
1780 | "Cannot do PHY loopback test " | 1784 | "Cannot do PHY loopback test when SoL/IDER is active.\n"); |
1781 | "when SoL/IDER is active.\n"); | ||
1782 | *data = 0; | 1785 | *data = 0; |
1783 | goto out; | 1786 | goto out; |
1784 | } | 1787 | } |
1785 | if ((adapter->hw.mac.type == e1000_i210) | 1788 | if ((adapter->hw.mac.type == e1000_i210) |
1786 | || (adapter->hw.mac.type == e1000_i210)) { | 1789 | || (adapter->hw.mac.type == e1000_i211)) { |
1787 | dev_err(&adapter->pdev->dev, | 1790 | dev_err(&adapter->pdev->dev, |
1788 | "Loopback test not supported " | 1791 | "Loopback test not supported on this part at this time.\n"); |
1789 | "on this part at this time.\n"); | ||
1790 | *data = 0; | 1792 | *data = 0; |
1791 | goto out; | 1793 | goto out; |
1792 | } | 1794 | } |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index b7c2d5050572..48cc4fb1a307 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -462,10 +462,10 @@ static void igb_dump(struct igb_adapter *adapter) | |||
462 | (u64)buffer_info->time_stamp, | 462 | (u64)buffer_info->time_stamp, |
463 | buffer_info->skb, next_desc); | 463 | buffer_info->skb, next_desc); |
464 | 464 | ||
465 | if (netif_msg_pktdata(adapter) && buffer_info->dma != 0) | 465 | if (netif_msg_pktdata(adapter) && buffer_info->skb) |
466 | print_hex_dump(KERN_INFO, "", | 466 | print_hex_dump(KERN_INFO, "", |
467 | DUMP_PREFIX_ADDRESS, | 467 | DUMP_PREFIX_ADDRESS, |
468 | 16, 1, phys_to_virt(buffer_info->dma), | 468 | 16, 1, buffer_info->skb->data, |
469 | buffer_info->length, true); | 469 | buffer_info->length, true); |
470 | } | 470 | } |
471 | } | 471 | } |
@@ -547,18 +547,17 @@ rx_ring_summary: | |||
547 | (u64)buffer_info->dma, | 547 | (u64)buffer_info->dma, |
548 | buffer_info->skb, next_desc); | 548 | buffer_info->skb, next_desc); |
549 | 549 | ||
550 | if (netif_msg_pktdata(adapter)) { | 550 | if (netif_msg_pktdata(adapter) && |
551 | buffer_info->dma && buffer_info->skb) { | ||
551 | print_hex_dump(KERN_INFO, "", | 552 | print_hex_dump(KERN_INFO, "", |
552 | DUMP_PREFIX_ADDRESS, | 553 | DUMP_PREFIX_ADDRESS, |
553 | 16, 1, | 554 | 16, 1, buffer_info->skb->data, |
554 | phys_to_virt(buffer_info->dma), | 555 | IGB_RX_HDR_LEN, true); |
555 | IGB_RX_HDR_LEN, true); | ||
556 | print_hex_dump(KERN_INFO, "", | 556 | print_hex_dump(KERN_INFO, "", |
557 | DUMP_PREFIX_ADDRESS, | 557 | DUMP_PREFIX_ADDRESS, |
558 | 16, 1, | 558 | 16, 1, |
559 | phys_to_virt( | 559 | page_address(buffer_info->page) + |
560 | buffer_info->page_dma + | 560 | buffer_info->page_offset, |
561 | buffer_info->page_offset), | ||
562 | PAGE_SIZE/2, true); | 561 | PAGE_SIZE/2, true); |
563 | } | 562 | } |
564 | } | 563 | } |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c index 50fc137501da..18bf08c9d7a4 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c | |||
@@ -804,12 +804,13 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, | |||
804 | link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) { | 804 | link_mode == IXGBE_AUTOC_LMS_KX4_KX_KR_SGMII) { |
805 | /* Set KX4/KX/KR support according to speed requested */ | 805 | /* Set KX4/KX/KR support according to speed requested */ |
806 | autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP); | 806 | autoc &= ~(IXGBE_AUTOC_KX4_KX_SUPP_MASK | IXGBE_AUTOC_KR_SUPP); |
807 | if (speed & IXGBE_LINK_SPEED_10GB_FULL) | 807 | if (speed & IXGBE_LINK_SPEED_10GB_FULL) { |
808 | if (orig_autoc & IXGBE_AUTOC_KX4_SUPP) | 808 | if (orig_autoc & IXGBE_AUTOC_KX4_SUPP) |
809 | autoc |= IXGBE_AUTOC_KX4_SUPP; | 809 | autoc |= IXGBE_AUTOC_KX4_SUPP; |
810 | if ((orig_autoc & IXGBE_AUTOC_KR_SUPP) && | 810 | if ((orig_autoc & IXGBE_AUTOC_KR_SUPP) && |
811 | (hw->phy.smart_speed_active == false)) | 811 | (hw->phy.smart_speed_active == false)) |
812 | autoc |= IXGBE_AUTOC_KR_SUPP; | 812 | autoc |= IXGBE_AUTOC_KR_SUPP; |
813 | } | ||
813 | if (speed & IXGBE_LINK_SPEED_1GB_FULL) | 814 | if (speed & IXGBE_LINK_SPEED_1GB_FULL) |
814 | autoc |= IXGBE_AUTOC_KX_SUPP; | 815 | autoc |= IXGBE_AUTOC_KX_SUPP; |
815 | } else if ((pma_pmd_1g == IXGBE_AUTOC_1G_SFI) && | 816 | } else if ((pma_pmd_1g == IXGBE_AUTOC_1G_SFI) && |
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.c b/drivers/net/ethernet/mellanox/mlx4/icm.c index 88b7b3e75ab1..daf417923661 100644 --- a/drivers/net/ethernet/mellanox/mlx4/icm.c +++ b/drivers/net/ethernet/mellanox/mlx4/icm.c | |||
@@ -358,13 +358,14 @@ void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, | |||
358 | } | 358 | } |
359 | 359 | ||
360 | int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, | 360 | int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, |
361 | u64 virt, int obj_size, int nobj, int reserved, | 361 | u64 virt, int obj_size, u32 nobj, int reserved, |
362 | int use_lowmem, int use_coherent) | 362 | int use_lowmem, int use_coherent) |
363 | { | 363 | { |
364 | int obj_per_chunk; | 364 | int obj_per_chunk; |
365 | int num_icm; | 365 | int num_icm; |
366 | unsigned chunk_size; | 366 | unsigned chunk_size; |
367 | int i; | 367 | int i; |
368 | u64 size; | ||
368 | 369 | ||
369 | obj_per_chunk = MLX4_TABLE_CHUNK_SIZE / obj_size; | 370 | obj_per_chunk = MLX4_TABLE_CHUNK_SIZE / obj_size; |
370 | num_icm = (nobj + obj_per_chunk - 1) / obj_per_chunk; | 371 | num_icm = (nobj + obj_per_chunk - 1) / obj_per_chunk; |
@@ -380,10 +381,12 @@ int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, | |||
380 | table->coherent = use_coherent; | 381 | table->coherent = use_coherent; |
381 | mutex_init(&table->mutex); | 382 | mutex_init(&table->mutex); |
382 | 383 | ||
384 | size = (u64) nobj * obj_size; | ||
383 | for (i = 0; i * MLX4_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) { | 385 | for (i = 0; i * MLX4_TABLE_CHUNK_SIZE < reserved * obj_size; ++i) { |
384 | chunk_size = MLX4_TABLE_CHUNK_SIZE; | 386 | chunk_size = MLX4_TABLE_CHUNK_SIZE; |
385 | if ((i + 1) * MLX4_TABLE_CHUNK_SIZE > nobj * obj_size) | 387 | if ((i + 1) * MLX4_TABLE_CHUNK_SIZE > size) |
386 | chunk_size = PAGE_ALIGN(nobj * obj_size - i * MLX4_TABLE_CHUNK_SIZE); | 388 | chunk_size = PAGE_ALIGN(size - |
389 | i * MLX4_TABLE_CHUNK_SIZE); | ||
387 | 390 | ||
388 | table->icm[i] = mlx4_alloc_icm(dev, chunk_size >> PAGE_SHIFT, | 391 | table->icm[i] = mlx4_alloc_icm(dev, chunk_size >> PAGE_SHIFT, |
389 | (use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) | | 392 | (use_lowmem ? GFP_KERNEL : GFP_HIGHUSER) | |
diff --git a/drivers/net/ethernet/mellanox/mlx4/icm.h b/drivers/net/ethernet/mellanox/mlx4/icm.h index 19e4efc0b342..a67744f53506 100644 --- a/drivers/net/ethernet/mellanox/mlx4/icm.h +++ b/drivers/net/ethernet/mellanox/mlx4/icm.h | |||
@@ -78,7 +78,7 @@ int mlx4_table_get_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, | |||
78 | void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, | 78 | void mlx4_table_put_range(struct mlx4_dev *dev, struct mlx4_icm_table *table, |
79 | int start, int end); | 79 | int start, int end); |
80 | int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, | 80 | int mlx4_init_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table, |
81 | u64 virt, int obj_size, int nobj, int reserved, | 81 | u64 virt, int obj_size, u32 nobj, int reserved, |
82 | int use_lowmem, int use_coherent); | 82 | int use_lowmem, int use_coherent); |
83 | void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table); | 83 | void mlx4_cleanup_icm_table(struct mlx4_dev *dev, struct mlx4_icm_table *table); |
84 | void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle); | 84 | void *mlx4_table_find(struct mlx4_icm_table *table, int obj, dma_addr_t *dma_handle); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mcg.c b/drivers/net/ethernet/mellanox/mlx4/mcg.c index 4ec3835e1bc2..a018ea2a43de 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mcg.c +++ b/drivers/net/ethernet/mellanox/mlx4/mcg.c | |||
@@ -432,8 +432,10 @@ static int add_promisc_qp(struct mlx4_dev *dev, u8 port, | |||
432 | if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) { | 432 | if ((be32_to_cpu(mgm->qp[i]) & MGM_QPN_MASK) == qpn) { |
433 | /* Entry already exists, add to duplicates */ | 433 | /* Entry already exists, add to duplicates */ |
434 | dqp = kmalloc(sizeof *dqp, GFP_KERNEL); | 434 | dqp = kmalloc(sizeof *dqp, GFP_KERNEL); |
435 | if (!dqp) | 435 | if (!dqp) { |
436 | err = -ENOMEM; | ||
436 | goto out_mailbox; | 437 | goto out_mailbox; |
438 | } | ||
437 | dqp->qpn = qpn; | 439 | dqp->qpn = qpn; |
438 | list_add_tail(&dqp->list, &entry->duplicates); | 440 | list_add_tail(&dqp->list, &entry->duplicates); |
439 | found = true; | 441 | found = true; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4.h b/drivers/net/ethernet/mellanox/mlx4/mlx4.h index 59ebc0339638..4d9df8f2a126 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4.h | |||
@@ -249,7 +249,7 @@ struct mlx4_bitmap { | |||
249 | struct mlx4_buddy { | 249 | struct mlx4_buddy { |
250 | unsigned long **bits; | 250 | unsigned long **bits; |
251 | unsigned int *num_free; | 251 | unsigned int *num_free; |
252 | int max_order; | 252 | u32 max_order; |
253 | spinlock_t lock; | 253 | spinlock_t lock; |
254 | }; | 254 | }; |
255 | 255 | ||
@@ -258,7 +258,7 @@ struct mlx4_icm; | |||
258 | struct mlx4_icm_table { | 258 | struct mlx4_icm_table { |
259 | u64 virt; | 259 | u64 virt; |
260 | int num_icm; | 260 | int num_icm; |
261 | int num_obj; | 261 | u32 num_obj; |
262 | int obj_size; | 262 | int obj_size; |
263 | int lowmem; | 263 | int lowmem; |
264 | int coherent; | 264 | int coherent; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/mr.c b/drivers/net/ethernet/mellanox/mlx4/mr.c index af55b7ce5341..c202d3ad2a0e 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mr.c +++ b/drivers/net/ethernet/mellanox/mlx4/mr.c | |||
@@ -37,6 +37,7 @@ | |||
37 | #include <linux/export.h> | 37 | #include <linux/export.h> |
38 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
39 | #include <linux/kernel.h> | 39 | #include <linux/kernel.h> |
40 | #include <linux/vmalloc.h> | ||
40 | 41 | ||
41 | #include <linux/mlx4/cmd.h> | 42 | #include <linux/mlx4/cmd.h> |
42 | 43 | ||
@@ -120,7 +121,7 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order) | |||
120 | buddy->max_order = max_order; | 121 | buddy->max_order = max_order; |
121 | spin_lock_init(&buddy->lock); | 122 | spin_lock_init(&buddy->lock); |
122 | 123 | ||
123 | buddy->bits = kzalloc((buddy->max_order + 1) * sizeof (long *), | 124 | buddy->bits = kcalloc(buddy->max_order + 1, sizeof (long *), |
124 | GFP_KERNEL); | 125 | GFP_KERNEL); |
125 | buddy->num_free = kcalloc((buddy->max_order + 1), sizeof *buddy->num_free, | 126 | buddy->num_free = kcalloc((buddy->max_order + 1), sizeof *buddy->num_free, |
126 | GFP_KERNEL); | 127 | GFP_KERNEL); |
@@ -129,10 +130,12 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order) | |||
129 | 130 | ||
130 | for (i = 0; i <= buddy->max_order; ++i) { | 131 | for (i = 0; i <= buddy->max_order; ++i) { |
131 | s = BITS_TO_LONGS(1 << (buddy->max_order - i)); | 132 | s = BITS_TO_LONGS(1 << (buddy->max_order - i)); |
132 | buddy->bits[i] = kmalloc(s * sizeof (long), GFP_KERNEL); | 133 | buddy->bits[i] = kcalloc(s, sizeof (long), GFP_KERNEL | __GFP_NOWARN); |
133 | if (!buddy->bits[i]) | 134 | if (!buddy->bits[i]) { |
134 | goto err_out_free; | 135 | buddy->bits[i] = vzalloc(s * sizeof(long)); |
135 | bitmap_zero(buddy->bits[i], 1 << (buddy->max_order - i)); | 136 | if (!buddy->bits[i]) |
137 | goto err_out_free; | ||
138 | } | ||
136 | } | 139 | } |
137 | 140 | ||
138 | set_bit(0, buddy->bits[buddy->max_order]); | 141 | set_bit(0, buddy->bits[buddy->max_order]); |
@@ -142,7 +145,10 @@ static int mlx4_buddy_init(struct mlx4_buddy *buddy, int max_order) | |||
142 | 145 | ||
143 | err_out_free: | 146 | err_out_free: |
144 | for (i = 0; i <= buddy->max_order; ++i) | 147 | for (i = 0; i <= buddy->max_order; ++i) |
145 | kfree(buddy->bits[i]); | 148 | if (buddy->bits[i] && is_vmalloc_addr(buddy->bits[i])) |
149 | vfree(buddy->bits[i]); | ||
150 | else | ||
151 | kfree(buddy->bits[i]); | ||
146 | 152 | ||
147 | err_out: | 153 | err_out: |
148 | kfree(buddy->bits); | 154 | kfree(buddy->bits); |
@@ -156,7 +162,10 @@ static void mlx4_buddy_cleanup(struct mlx4_buddy *buddy) | |||
156 | int i; | 162 | int i; |
157 | 163 | ||
158 | for (i = 0; i <= buddy->max_order; ++i) | 164 | for (i = 0; i <= buddy->max_order; ++i) |
159 | kfree(buddy->bits[i]); | 165 | if (is_vmalloc_addr(buddy->bits[i])) |
166 | vfree(buddy->bits[i]); | ||
167 | else | ||
168 | kfree(buddy->bits[i]); | ||
160 | 169 | ||
161 | kfree(buddy->bits); | 170 | kfree(buddy->bits); |
162 | kfree(buddy->num_free); | 171 | kfree(buddy->num_free); |
@@ -668,7 +677,7 @@ int mlx4_init_mr_table(struct mlx4_dev *dev) | |||
668 | return err; | 677 | return err; |
669 | 678 | ||
670 | err = mlx4_buddy_init(&mr_table->mtt_buddy, | 679 | err = mlx4_buddy_init(&mr_table->mtt_buddy, |
671 | ilog2(dev->caps.num_mtts / | 680 | ilog2((u32)dev->caps.num_mtts / |
672 | (1 << log_mtts_per_seg))); | 681 | (1 << log_mtts_per_seg))); |
673 | if (err) | 682 | if (err) |
674 | goto err_buddy; | 683 | goto err_buddy; |
@@ -678,7 +687,7 @@ int mlx4_init_mr_table(struct mlx4_dev *dev) | |||
678 | mlx4_alloc_mtt_range(dev, | 687 | mlx4_alloc_mtt_range(dev, |
679 | fls(dev->caps.reserved_mtts - 1)); | 688 | fls(dev->caps.reserved_mtts - 1)); |
680 | if (priv->reserved_mtts < 0) { | 689 | if (priv->reserved_mtts < 0) { |
681 | mlx4_warn(dev, "MTT table of order %d is too small.\n", | 690 | mlx4_warn(dev, "MTT table of order %u is too small.\n", |
682 | mr_table->mtt_buddy.max_order); | 691 | mr_table->mtt_buddy.max_order); |
683 | err = -ENOMEM; | 692 | err = -ENOMEM; |
684 | goto err_reserve_mtts; | 693 | goto err_reserve_mtts; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/profile.c b/drivers/net/ethernet/mellanox/mlx4/profile.c index 9ee4725363d5..8e0c3cc2a1ec 100644 --- a/drivers/net/ethernet/mellanox/mlx4/profile.c +++ b/drivers/net/ethernet/mellanox/mlx4/profile.c | |||
@@ -76,7 +76,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, | |||
76 | u64 size; | 76 | u64 size; |
77 | u64 start; | 77 | u64 start; |
78 | int type; | 78 | int type; |
79 | int num; | 79 | u32 num; |
80 | int log_num; | 80 | int log_num; |
81 | }; | 81 | }; |
82 | 82 | ||
@@ -105,7 +105,7 @@ u64 mlx4_make_profile(struct mlx4_dev *dev, | |||
105 | si_meminfo(&si); | 105 | si_meminfo(&si); |
106 | request->num_mtt = | 106 | request->num_mtt = |
107 | roundup_pow_of_two(max_t(unsigned, request->num_mtt, | 107 | roundup_pow_of_two(max_t(unsigned, request->num_mtt, |
108 | min(1UL << 31, | 108 | min(1UL << (31 - log_mtts_per_seg), |
109 | si.totalram >> (log_mtts_per_seg - 1)))); | 109 | si.totalram >> (log_mtts_per_seg - 1)))); |
110 | 110 | ||
111 | profile[MLX4_RES_QP].size = dev_cap->qpc_entry_sz; | 111 | profile[MLX4_RES_QP].size = dev_cap->qpc_entry_sz; |
diff --git a/drivers/net/ethernet/nxp/lpc_eth.c b/drivers/net/ethernet/nxp/lpc_eth.c index 4069edab229e..53743f7a2ca9 100644 --- a/drivers/net/ethernet/nxp/lpc_eth.c +++ b/drivers/net/ethernet/nxp/lpc_eth.c | |||
@@ -346,28 +346,15 @@ static phy_interface_t lpc_phy_interface_mode(struct device *dev) | |||
346 | "phy-mode", NULL); | 346 | "phy-mode", NULL); |
347 | if (mode && !strcmp(mode, "mii")) | 347 | if (mode && !strcmp(mode, "mii")) |
348 | return PHY_INTERFACE_MODE_MII; | 348 | return PHY_INTERFACE_MODE_MII; |
349 | return PHY_INTERFACE_MODE_RMII; | ||
350 | } | 349 | } |
351 | |||
352 | /* non-DT */ | ||
353 | #ifdef CONFIG_ARCH_LPC32XX_MII_SUPPORT | ||
354 | return PHY_INTERFACE_MODE_MII; | ||
355 | #else | ||
356 | return PHY_INTERFACE_MODE_RMII; | 350 | return PHY_INTERFACE_MODE_RMII; |
357 | #endif | ||
358 | } | 351 | } |
359 | 352 | ||
360 | static bool use_iram_for_net(struct device *dev) | 353 | static bool use_iram_for_net(struct device *dev) |
361 | { | 354 | { |
362 | if (dev && dev->of_node) | 355 | if (dev && dev->of_node) |
363 | return of_property_read_bool(dev->of_node, "use-iram"); | 356 | return of_property_read_bool(dev->of_node, "use-iram"); |
364 | |||
365 | /* non-DT */ | ||
366 | #ifdef CONFIG_ARCH_LPC32XX_IRAM_FOR_NET | ||
367 | return true; | ||
368 | #else | ||
369 | return false; | 357 | return false; |
370 | #endif | ||
371 | } | 358 | } |
372 | 359 | ||
373 | /* Receive Status information word */ | 360 | /* Receive Status information word */ |
diff --git a/drivers/net/ethernet/renesas/Kconfig b/drivers/net/ethernet/renesas/Kconfig index 46df3a04030c..24c2305d7948 100644 --- a/drivers/net/ethernet/renesas/Kconfig +++ b/drivers/net/ethernet/renesas/Kconfig | |||
@@ -8,7 +8,7 @@ config SH_ETH | |||
8 | (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \ | 8 | (CPU_SUBTYPE_SH7710 || CPU_SUBTYPE_SH7712 || \ |
9 | CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \ | 9 | CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7619 || \ |
10 | CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7734 || \ | 10 | CPU_SUBTYPE_SH7724 || CPU_SUBTYPE_SH7734 || \ |
11 | CPU_SUBTYPE_SH7757 || ARCH_R8A7740) | 11 | CPU_SUBTYPE_SH7757 || ARCH_R8A7740 || ARCH_R8A7779) |
12 | select CRC32 | 12 | select CRC32 |
13 | select NET_CORE | 13 | select NET_CORE |
14 | select MII | 14 | select MII |
@@ -18,4 +18,4 @@ config SH_ETH | |||
18 | Renesas SuperH Ethernet device driver. | 18 | Renesas SuperH Ethernet device driver. |
19 | This driver supporting CPUs are: | 19 | This driver supporting CPUs are: |
20 | - SH7619, SH7710, SH7712, SH7724, SH7734, SH7763, SH7757, | 20 | - SH7619, SH7710, SH7712, SH7724, SH7734, SH7763, SH7757, |
21 | and R8A7740. | 21 | R8A7740 and R8A7779. |
diff --git a/drivers/net/ethernet/renesas/sh_eth.c b/drivers/net/ethernet/renesas/sh_eth.c index af0b867a6cf6..bad8f2eec9b4 100644 --- a/drivers/net/ethernet/renesas/sh_eth.c +++ b/drivers/net/ethernet/renesas/sh_eth.c | |||
@@ -78,7 +78,7 @@ static void sh_eth_select_mii(struct net_device *ndev) | |||
78 | #endif | 78 | #endif |
79 | 79 | ||
80 | /* There is CPU dependent code */ | 80 | /* There is CPU dependent code */ |
81 | #if defined(CONFIG_CPU_SUBTYPE_SH7724) | 81 | #if defined(CONFIG_CPU_SUBTYPE_SH7724) || defined(CONFIG_ARCH_R8A7779) |
82 | #define SH_ETH_RESET_DEFAULT 1 | 82 | #define SH_ETH_RESET_DEFAULT 1 |
83 | static void sh_eth_set_duplex(struct net_device *ndev) | 83 | static void sh_eth_set_duplex(struct net_device *ndev) |
84 | { | 84 | { |
@@ -93,13 +93,18 @@ static void sh_eth_set_duplex(struct net_device *ndev) | |||
93 | static void sh_eth_set_rate(struct net_device *ndev) | 93 | static void sh_eth_set_rate(struct net_device *ndev) |
94 | { | 94 | { |
95 | struct sh_eth_private *mdp = netdev_priv(ndev); | 95 | struct sh_eth_private *mdp = netdev_priv(ndev); |
96 | unsigned int bits = ECMR_RTM; | ||
97 | |||
98 | #if defined(CONFIG_ARCH_R8A7779) | ||
99 | bits |= ECMR_ELB; | ||
100 | #endif | ||
96 | 101 | ||
97 | switch (mdp->speed) { | 102 | switch (mdp->speed) { |
98 | case 10: /* 10BASE */ | 103 | case 10: /* 10BASE */ |
99 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR); | 104 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~bits, ECMR); |
100 | break; | 105 | break; |
101 | case 100:/* 100BASE */ | 106 | case 100:/* 100BASE */ |
102 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR); | 107 | sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | bits, ECMR); |
103 | break; | 108 | break; |
104 | default: | 109 | default: |
105 | break; | 110 | break; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index fd8882f9602a..c136162e6473 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | |||
@@ -2077,7 +2077,7 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, | |||
2077 | goto error_netdev_register; | 2077 | goto error_netdev_register; |
2078 | } | 2078 | } |
2079 | 2079 | ||
2080 | priv->stmmac_clk = clk_get(priv->device, NULL); | 2080 | priv->stmmac_clk = clk_get(priv->device, STMMAC_RESOURCE_NAME); |
2081 | if (IS_ERR(priv->stmmac_clk)) { | 2081 | if (IS_ERR(priv->stmmac_clk)) { |
2082 | pr_warning("%s: warning: cannot get CSR clock\n", __func__); | 2082 | pr_warning("%s: warning: cannot get CSR clock\n", __func__); |
2083 | goto error_clk_get; | 2083 | goto error_clk_get; |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index cd01ee7ecef1..b93245c11995 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | |||
@@ -74,7 +74,7 @@ static int __devinit stmmac_probe_config_dt(struct platform_device *pdev, | |||
74 | * the necessary resources and invokes the main to init | 74 | * the necessary resources and invokes the main to init |
75 | * the net device, register the mdio bus etc. | 75 | * the net device, register the mdio bus etc. |
76 | */ | 76 | */ |
77 | static int stmmac_pltfr_probe(struct platform_device *pdev) | 77 | static int __devinit stmmac_pltfr_probe(struct platform_device *pdev) |
78 | { | 78 | { |
79 | int ret = 0; | 79 | int ret = 0; |
80 | struct resource *res; | 80 | struct resource *res; |
diff --git a/drivers/net/ethernet/ti/davinci_cpdma.c b/drivers/net/ethernet/ti/davinci_cpdma.c index 3b5c4571b55e..d15c888e9df8 100644 --- a/drivers/net/ethernet/ti/davinci_cpdma.c +++ b/drivers/net/ethernet/ti/davinci_cpdma.c | |||
@@ -538,11 +538,12 @@ EXPORT_SYMBOL_GPL(cpdma_chan_create); | |||
538 | 538 | ||
539 | int cpdma_chan_destroy(struct cpdma_chan *chan) | 539 | int cpdma_chan_destroy(struct cpdma_chan *chan) |
540 | { | 540 | { |
541 | struct cpdma_ctlr *ctlr = chan->ctlr; | 541 | struct cpdma_ctlr *ctlr; |
542 | unsigned long flags; | 542 | unsigned long flags; |
543 | 543 | ||
544 | if (!chan) | 544 | if (!chan) |
545 | return -EINVAL; | 545 | return -EINVAL; |
546 | ctlr = chan->ctlr; | ||
546 | 547 | ||
547 | spin_lock_irqsave(&ctlr->lock, flags); | 548 | spin_lock_irqsave(&ctlr->lock, flags); |
548 | if (chan->state != CPDMA_STATE_IDLE) | 549 | if (chan->state != CPDMA_STATE_IDLE) |
diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c index 482648fcf0b6..98934bdf6acf 100644 --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c | |||
@@ -1003,6 +1003,7 @@ static int ixp4xx_nway_reset(struct net_device *dev) | |||
1003 | } | 1003 | } |
1004 | 1004 | ||
1005 | int ixp46x_phc_index = -1; | 1005 | int ixp46x_phc_index = -1; |
1006 | EXPORT_SYMBOL_GPL(ixp46x_phc_index); | ||
1006 | 1007 | ||
1007 | static int ixp4xx_get_ts_info(struct net_device *dev, | 1008 | static int ixp4xx_get_ts_info(struct net_device *dev, |
1008 | struct ethtool_ts_info *info) | 1009 | struct ethtool_ts_info *info) |
diff --git a/drivers/net/irda/bfin_sir.c b/drivers/net/irda/bfin_sir.c index a561ae44a9ac..c6a0299aa9f9 100644 --- a/drivers/net/irda/bfin_sir.c +++ b/drivers/net/irda/bfin_sir.c | |||
@@ -158,7 +158,7 @@ static int bfin_sir_set_speed(struct bfin_sir_port *port, int speed) | |||
158 | /* If not add the 'RPOLC', we can't catch the receive interrupt. | 158 | /* If not add the 'RPOLC', we can't catch the receive interrupt. |
159 | * It's related with the HW layout and the IR transiver. | 159 | * It's related with the HW layout and the IR transiver. |
160 | */ | 160 | */ |
161 | val |= IREN | RPOLC; | 161 | val |= UMOD_IRDA | RPOLC; |
162 | UART_PUT_GCTL(port, val); | 162 | UART_PUT_GCTL(port, val); |
163 | return ret; | 163 | return ret; |
164 | } | 164 | } |
@@ -432,7 +432,7 @@ static void bfin_sir_shutdown(struct bfin_sir_port *port, struct net_device *dev | |||
432 | bfin_sir_stop_rx(port); | 432 | bfin_sir_stop_rx(port); |
433 | 433 | ||
434 | val = UART_GET_GCTL(port); | 434 | val = UART_GET_GCTL(port); |
435 | val &= ~(UCEN | IREN | RPOLC); | 435 | val &= ~(UCEN | UMOD_MASK | RPOLC); |
436 | UART_PUT_GCTL(port, val); | 436 | UART_PUT_GCTL(port, val); |
437 | 437 | ||
438 | #ifdef CONFIG_SIR_BFIN_DMA | 438 | #ifdef CONFIG_SIR_BFIN_DMA |
@@ -518,10 +518,10 @@ static void bfin_sir_send_work(struct work_struct *work) | |||
518 | * reset all the UART. | 518 | * reset all the UART. |
519 | */ | 519 | */ |
520 | val = UART_GET_GCTL(port); | 520 | val = UART_GET_GCTL(port); |
521 | val &= ~(IREN | RPOLC); | 521 | val &= ~(UMOD_MASK | RPOLC); |
522 | UART_PUT_GCTL(port, val); | 522 | UART_PUT_GCTL(port, val); |
523 | SSYNC(); | 523 | SSYNC(); |
524 | val |= IREN | RPOLC; | 524 | val |= UMOD_IRDA | RPOLC; |
525 | UART_PUT_GCTL(port, val); | 525 | UART_PUT_GCTL(port, val); |
526 | SSYNC(); | 526 | SSYNC(); |
527 | /* bfin_sir_set_speed(port, self->speed); */ | 527 | /* bfin_sir_set_speed(port, self->speed); */ |
diff --git a/drivers/net/irda/ks959-sir.c b/drivers/net/irda/ks959-sir.c index 824e2a93fe8a..5f3aeac3f86d 100644 --- a/drivers/net/irda/ks959-sir.c +++ b/drivers/net/irda/ks959-sir.c | |||
@@ -542,6 +542,7 @@ static int ks959_net_open(struct net_device *netdev) | |||
542 | sprintf(hwname, "usb#%d", kingsun->usbdev->devnum); | 542 | sprintf(hwname, "usb#%d", kingsun->usbdev->devnum); |
543 | kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname); | 543 | kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname); |
544 | if (!kingsun->irlap) { | 544 | if (!kingsun->irlap) { |
545 | err = -ENOMEM; | ||
545 | dev_err(&kingsun->usbdev->dev, "irlap_open failed\n"); | 546 | dev_err(&kingsun->usbdev->dev, "irlap_open failed\n"); |
546 | goto free_mem; | 547 | goto free_mem; |
547 | } | 548 | } |
diff --git a/drivers/net/irda/ksdazzle-sir.c b/drivers/net/irda/ksdazzle-sir.c index 5a278ab83c2f..2d4b6a1ab202 100644 --- a/drivers/net/irda/ksdazzle-sir.c +++ b/drivers/net/irda/ksdazzle-sir.c | |||
@@ -436,6 +436,7 @@ static int ksdazzle_net_open(struct net_device *netdev) | |||
436 | sprintf(hwname, "usb#%d", kingsun->usbdev->devnum); | 436 | sprintf(hwname, "usb#%d", kingsun->usbdev->devnum); |
437 | kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname); | 437 | kingsun->irlap = irlap_open(netdev, &kingsun->qos, hwname); |
438 | if (!kingsun->irlap) { | 438 | if (!kingsun->irlap) { |
439 | err = -ENOMEM; | ||
439 | dev_err(&kingsun->usbdev->dev, "irlap_open failed\n"); | 440 | dev_err(&kingsun->usbdev->dev, "irlap_open failed\n"); |
440 | goto free_mem; | 441 | goto free_mem; |
441 | } | 442 | } |
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index 0737bd4d1669..0f0f9ce3a776 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
@@ -94,7 +94,8 @@ static int get_slot(struct macvlan_dev *vlan, struct macvtap_queue *q) | |||
94 | int i; | 94 | int i; |
95 | 95 | ||
96 | for (i = 0; i < MAX_MACVTAP_QUEUES; i++) { | 96 | for (i = 0; i < MAX_MACVTAP_QUEUES; i++) { |
97 | if (rcu_dereference(vlan->taps[i]) == q) | 97 | if (rcu_dereference_protected(vlan->taps[i], |
98 | lockdep_is_held(&macvtap_lock)) == q) | ||
98 | return i; | 99 | return i; |
99 | } | 100 | } |
100 | 101 | ||
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c index f9347ea3d381..b3321129a83c 100644 --- a/drivers/net/netconsole.c +++ b/drivers/net/netconsole.c | |||
@@ -640,15 +640,9 @@ static int netconsole_netdev_event(struct notifier_block *this, | |||
640 | * rtnl_lock already held | 640 | * rtnl_lock already held |
641 | */ | 641 | */ |
642 | if (nt->np.dev) { | 642 | if (nt->np.dev) { |
643 | spin_unlock_irqrestore( | ||
644 | &target_list_lock, | ||
645 | flags); | ||
646 | __netpoll_cleanup(&nt->np); | 643 | __netpoll_cleanup(&nt->np); |
647 | spin_lock_irqsave(&target_list_lock, | ||
648 | flags); | ||
649 | dev_put(nt->np.dev); | 644 | dev_put(nt->np.dev); |
650 | nt->np.dev = NULL; | 645 | nt->np.dev = NULL; |
651 | netconsole_target_put(nt); | ||
652 | } | 646 | } |
653 | nt->enabled = 0; | 647 | nt->enabled = 0; |
654 | stopped = true; | 648 | stopped = true; |
diff --git a/drivers/net/phy/mdio-mux-gpio.c b/drivers/net/phy/mdio-mux-gpio.c index e0cc4ef33dee..eefe49e8713c 100644 --- a/drivers/net/phy/mdio-mux-gpio.c +++ b/drivers/net/phy/mdio-mux-gpio.c | |||
@@ -101,7 +101,6 @@ err: | |||
101 | n--; | 101 | n--; |
102 | gpio_free(s->gpio[n]); | 102 | gpio_free(s->gpio[n]); |
103 | } | 103 | } |
104 | devm_kfree(&pdev->dev, s); | ||
105 | return r; | 104 | return r; |
106 | } | 105 | } |
107 | 106 | ||
diff --git a/drivers/net/phy/mdio-mux.c b/drivers/net/phy/mdio-mux.c index 5c120189ec86..4d4d25efc1e1 100644 --- a/drivers/net/phy/mdio-mux.c +++ b/drivers/net/phy/mdio-mux.c | |||
@@ -132,7 +132,7 @@ int mdio_mux_init(struct device *dev, | |||
132 | pb->mii_bus = parent_bus; | 132 | pb->mii_bus = parent_bus; |
133 | 133 | ||
134 | ret_val = -ENODEV; | 134 | ret_val = -ENODEV; |
135 | for_each_child_of_node(dev->of_node, child_bus_node) { | 135 | for_each_available_child_of_node(dev->of_node, child_bus_node) { |
136 | u32 v; | 136 | u32 v; |
137 | 137 | ||
138 | r = of_property_read_u32(child_bus_node, "reg", &v); | 138 | r = of_property_read_u32(child_bus_node, "reg", &v); |
diff --git a/drivers/net/ppp/pptp.c b/drivers/net/ppp/pptp.c index 1c98321b56cc..162464fe86bf 100644 --- a/drivers/net/ppp/pptp.c +++ b/drivers/net/ppp/pptp.c | |||
@@ -189,7 +189,7 @@ static int pptp_xmit(struct ppp_channel *chan, struct sk_buff *skb) | |||
189 | if (sk_pppox(po)->sk_state & PPPOX_DEAD) | 189 | if (sk_pppox(po)->sk_state & PPPOX_DEAD) |
190 | goto tx_error; | 190 | goto tx_error; |
191 | 191 | ||
192 | rt = ip_route_output_ports(&init_net, &fl4, NULL, | 192 | rt = ip_route_output_ports(sock_net(sk), &fl4, NULL, |
193 | opt->dst_addr.sin_addr.s_addr, | 193 | opt->dst_addr.sin_addr.s_addr, |
194 | opt->src_addr.sin_addr.s_addr, | 194 | opt->src_addr.sin_addr.s_addr, |
195 | 0, 0, IPPROTO_GRE, | 195 | 0, 0, IPPROTO_GRE, |
@@ -468,7 +468,7 @@ static int pptp_connect(struct socket *sock, struct sockaddr *uservaddr, | |||
468 | po->chan.private = sk; | 468 | po->chan.private = sk; |
469 | po->chan.ops = &pptp_chan_ops; | 469 | po->chan.ops = &pptp_chan_ops; |
470 | 470 | ||
471 | rt = ip_route_output_ports(&init_net, &fl4, sk, | 471 | rt = ip_route_output_ports(sock_net(sk), &fl4, sk, |
472 | opt->dst_addr.sin_addr.s_addr, | 472 | opt->dst_addr.sin_addr.s_addr, |
473 | opt->src_addr.sin_addr.s_addr, | 473 | opt->src_addr.sin_addr.s_addr, |
474 | 0, 0, | 474 | 0, 0, |
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index bc36d13c2675..c8a3f108dc94 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
@@ -913,16 +913,17 @@ static void team_port_leave(struct team *team, struct team_port *port) | |||
913 | } | 913 | } |
914 | 914 | ||
915 | #ifdef CONFIG_NET_POLL_CONTROLLER | 915 | #ifdef CONFIG_NET_POLL_CONTROLLER |
916 | static int team_port_enable_netpoll(struct team *team, struct team_port *port) | 916 | static int team_port_enable_netpoll(struct team *team, struct team_port *port, |
917 | gfp_t gfp) | ||
917 | { | 918 | { |
918 | struct netpoll *np; | 919 | struct netpoll *np; |
919 | int err; | 920 | int err; |
920 | 921 | ||
921 | np = kzalloc(sizeof(*np), GFP_KERNEL); | 922 | np = kzalloc(sizeof(*np), gfp); |
922 | if (!np) | 923 | if (!np) |
923 | return -ENOMEM; | 924 | return -ENOMEM; |
924 | 925 | ||
925 | err = __netpoll_setup(np, port->dev); | 926 | err = __netpoll_setup(np, port->dev, gfp); |
926 | if (err) { | 927 | if (err) { |
927 | kfree(np); | 928 | kfree(np); |
928 | return err; | 929 | return err; |
@@ -951,7 +952,8 @@ static struct netpoll_info *team_netpoll_info(struct team *team) | |||
951 | } | 952 | } |
952 | 953 | ||
953 | #else | 954 | #else |
954 | static int team_port_enable_netpoll(struct team *team, struct team_port *port) | 955 | static int team_port_enable_netpoll(struct team *team, struct team_port *port, |
956 | gfp_t gfp) | ||
955 | { | 957 | { |
956 | return 0; | 958 | return 0; |
957 | } | 959 | } |
@@ -1037,7 +1039,7 @@ static int team_port_add(struct team *team, struct net_device *port_dev) | |||
1037 | } | 1039 | } |
1038 | 1040 | ||
1039 | if (team_netpoll_info(team)) { | 1041 | if (team_netpoll_info(team)) { |
1040 | err = team_port_enable_netpoll(team, port); | 1042 | err = team_port_enable_netpoll(team, port, GFP_KERNEL); |
1041 | if (err) { | 1043 | if (err) { |
1042 | netdev_err(dev, "Failed to enable netpoll on device %s\n", | 1044 | netdev_err(dev, "Failed to enable netpoll on device %s\n", |
1043 | portname); | 1045 | portname); |
@@ -1633,7 +1635,7 @@ static void team_netpoll_cleanup(struct net_device *dev) | |||
1633 | } | 1635 | } |
1634 | 1636 | ||
1635 | static int team_netpoll_setup(struct net_device *dev, | 1637 | static int team_netpoll_setup(struct net_device *dev, |
1636 | struct netpoll_info *npifo) | 1638 | struct netpoll_info *npifo, gfp_t gfp) |
1637 | { | 1639 | { |
1638 | struct team *team = netdev_priv(dev); | 1640 | struct team *team = netdev_priv(dev); |
1639 | struct team_port *port; | 1641 | struct team_port *port; |
@@ -1641,7 +1643,7 @@ static int team_netpoll_setup(struct net_device *dev, | |||
1641 | 1643 | ||
1642 | mutex_lock(&team->lock); | 1644 | mutex_lock(&team->lock); |
1643 | list_for_each_entry(port, &team->port_list, list) { | 1645 | list_for_each_entry(port, &team->port_list, list) { |
1644 | err = team_port_enable_netpoll(team, port); | 1646 | err = team_port_enable_netpoll(team, port, gfp); |
1645 | if (err) { | 1647 | if (err) { |
1646 | __team_netpoll_cleanup(team); | 1648 | __team_netpoll_cleanup(team); |
1647 | break; | 1649 | break; |
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 926d4db5cb38..3a16d4fdaa05 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c | |||
@@ -187,7 +187,6 @@ static void __tun_detach(struct tun_struct *tun) | |||
187 | netif_tx_lock_bh(tun->dev); | 187 | netif_tx_lock_bh(tun->dev); |
188 | netif_carrier_off(tun->dev); | 188 | netif_carrier_off(tun->dev); |
189 | tun->tfile = NULL; | 189 | tun->tfile = NULL; |
190 | tun->socket.file = NULL; | ||
191 | netif_tx_unlock_bh(tun->dev); | 190 | netif_tx_unlock_bh(tun->dev); |
192 | 191 | ||
193 | /* Drop read queue */ | 192 | /* Drop read queue */ |
diff --git a/drivers/net/usb/cdc-phonet.c b/drivers/net/usb/cdc-phonet.c index 64610048ce87..7d78669000d7 100644 --- a/drivers/net/usb/cdc-phonet.c +++ b/drivers/net/usb/cdc-phonet.c | |||
@@ -232,6 +232,7 @@ static int usbpn_open(struct net_device *dev) | |||
232 | struct urb *req = usb_alloc_urb(0, GFP_KERNEL); | 232 | struct urb *req = usb_alloc_urb(0, GFP_KERNEL); |
233 | 233 | ||
234 | if (!req || rx_submit(pnd, req, GFP_KERNEL | __GFP_COLD)) { | 234 | if (!req || rx_submit(pnd, req, GFP_KERNEL | __GFP_COLD)) { |
235 | usb_free_urb(req); | ||
235 | usbpn_close(dev); | 236 | usbpn_close(dev); |
236 | return -ENOMEM; | 237 | return -ENOMEM; |
237 | } | 238 | } |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index 2ea126a16d79..328397c66730 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -247,30 +247,12 @@ err: | |||
247 | */ | 247 | */ |
248 | static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) | 248 | static int qmi_wwan_bind_shared(struct usbnet *dev, struct usb_interface *intf) |
249 | { | 249 | { |
250 | int rv; | ||
251 | struct qmi_wwan_state *info = (void *)&dev->data; | 250 | struct qmi_wwan_state *info = (void *)&dev->data; |
252 | 251 | ||
253 | /* ZTE makes devices where the interface descriptors and endpoint | ||
254 | * configurations of two or more interfaces are identical, even | ||
255 | * though the functions are completely different. If set, then | ||
256 | * driver_info->data is a bitmap of acceptable interface numbers | ||
257 | * allowing us to bind to one such interface without binding to | ||
258 | * all of them | ||
259 | */ | ||
260 | if (dev->driver_info->data && | ||
261 | !test_bit(intf->cur_altsetting->desc.bInterfaceNumber, &dev->driver_info->data)) { | ||
262 | dev_info(&intf->dev, "not on our whitelist - ignored"); | ||
263 | rv = -ENODEV; | ||
264 | goto err; | ||
265 | } | ||
266 | |||
267 | /* control and data is shared */ | 252 | /* control and data is shared */ |
268 | info->control = intf; | 253 | info->control = intf; |
269 | info->data = intf; | 254 | info->data = intf; |
270 | rv = qmi_wwan_register_subdriver(dev); | 255 | return qmi_wwan_register_subdriver(dev); |
271 | |||
272 | err: | ||
273 | return rv; | ||
274 | } | 256 | } |
275 | 257 | ||
276 | static void qmi_wwan_unbind(struct usbnet *dev, struct usb_interface *intf) | 258 | static void qmi_wwan_unbind(struct usbnet *dev, struct usb_interface *intf) |
@@ -356,214 +338,64 @@ static const struct driver_info qmi_wwan_shared = { | |||
356 | .manage_power = qmi_wwan_manage_power, | 338 | .manage_power = qmi_wwan_manage_power, |
357 | }; | 339 | }; |
358 | 340 | ||
359 | static const struct driver_info qmi_wwan_force_int0 = { | ||
360 | .description = "Qualcomm WWAN/QMI device", | ||
361 | .flags = FLAG_WWAN, | ||
362 | .bind = qmi_wwan_bind_shared, | ||
363 | .unbind = qmi_wwan_unbind, | ||
364 | .manage_power = qmi_wwan_manage_power, | ||
365 | .data = BIT(0), /* interface whitelist bitmap */ | ||
366 | }; | ||
367 | |||
368 | static const struct driver_info qmi_wwan_force_int1 = { | ||
369 | .description = "Qualcomm WWAN/QMI device", | ||
370 | .flags = FLAG_WWAN, | ||
371 | .bind = qmi_wwan_bind_shared, | ||
372 | .unbind = qmi_wwan_unbind, | ||
373 | .manage_power = qmi_wwan_manage_power, | ||
374 | .data = BIT(1), /* interface whitelist bitmap */ | ||
375 | }; | ||
376 | |||
377 | static const struct driver_info qmi_wwan_force_int2 = { | ||
378 | .description = "Qualcomm WWAN/QMI device", | ||
379 | .flags = FLAG_WWAN, | ||
380 | .bind = qmi_wwan_bind_shared, | ||
381 | .unbind = qmi_wwan_unbind, | ||
382 | .manage_power = qmi_wwan_manage_power, | ||
383 | .data = BIT(2), /* interface whitelist bitmap */ | ||
384 | }; | ||
385 | |||
386 | static const struct driver_info qmi_wwan_force_int3 = { | ||
387 | .description = "Qualcomm WWAN/QMI device", | ||
388 | .flags = FLAG_WWAN, | ||
389 | .bind = qmi_wwan_bind_shared, | ||
390 | .unbind = qmi_wwan_unbind, | ||
391 | .manage_power = qmi_wwan_manage_power, | ||
392 | .data = BIT(3), /* interface whitelist bitmap */ | ||
393 | }; | ||
394 | |||
395 | static const struct driver_info qmi_wwan_force_int4 = { | ||
396 | .description = "Qualcomm WWAN/QMI device", | ||
397 | .flags = FLAG_WWAN, | ||
398 | .bind = qmi_wwan_bind_shared, | ||
399 | .unbind = qmi_wwan_unbind, | ||
400 | .manage_power = qmi_wwan_manage_power, | ||
401 | .data = BIT(4), /* interface whitelist bitmap */ | ||
402 | }; | ||
403 | |||
404 | /* Sierra Wireless provide equally useless interface descriptors | ||
405 | * Devices in QMI mode can be switched between two different | ||
406 | * configurations: | ||
407 | * a) USB interface #8 is QMI/wwan | ||
408 | * b) USB interfaces #8, #19 and #20 are QMI/wwan | ||
409 | * | ||
410 | * Both configurations provide a number of other interfaces (serial++), | ||
411 | * some of which have the same endpoint configuration as we expect, so | ||
412 | * a whitelist or blacklist is necessary. | ||
413 | * | ||
414 | * FIXME: The below whitelist should include BIT(20). It does not | ||
415 | * because I cannot get it to work... | ||
416 | */ | ||
417 | static const struct driver_info qmi_wwan_sierra = { | ||
418 | .description = "Sierra Wireless wwan/QMI device", | ||
419 | .flags = FLAG_WWAN, | ||
420 | .bind = qmi_wwan_bind_shared, | ||
421 | .unbind = qmi_wwan_unbind, | ||
422 | .manage_power = qmi_wwan_manage_power, | ||
423 | .data = BIT(8) | BIT(19), /* interface whitelist bitmap */ | ||
424 | }; | ||
425 | |||
426 | #define HUAWEI_VENDOR_ID 0x12D1 | 341 | #define HUAWEI_VENDOR_ID 0x12D1 |
427 | 342 | ||
343 | /* map QMI/wwan function by a fixed interface number */ | ||
344 | #define QMI_FIXED_INTF(vend, prod, num) \ | ||
345 | USB_DEVICE_INTERFACE_NUMBER(vend, prod, num), \ | ||
346 | .driver_info = (unsigned long)&qmi_wwan_shared | ||
347 | |||
428 | /* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */ | 348 | /* Gobi 1000 QMI/wwan interface number is 3 according to qcserial */ |
429 | #define QMI_GOBI1K_DEVICE(vend, prod) \ | 349 | #define QMI_GOBI1K_DEVICE(vend, prod) \ |
430 | USB_DEVICE(vend, prod), \ | 350 | QMI_FIXED_INTF(vend, prod, 3) |
431 | .driver_info = (unsigned long)&qmi_wwan_force_int3 | ||
432 | 351 | ||
433 | /* Gobi 2000 and Gobi 3000 QMI/wwan interface number is 0 according to qcserial */ | 352 | /* Gobi 2000/3000 QMI/wwan interface number is 0 according to qcserial */ |
434 | #define QMI_GOBI_DEVICE(vend, prod) \ | 353 | #define QMI_GOBI_DEVICE(vend, prod) \ |
435 | USB_DEVICE(vend, prod), \ | 354 | QMI_FIXED_INTF(vend, prod, 0) |
436 | .driver_info = (unsigned long)&qmi_wwan_force_int0 | ||
437 | 355 | ||
438 | static const struct usb_device_id products[] = { | 356 | static const struct usb_device_id products[] = { |
357 | /* 1. CDC ECM like devices match on the control interface */ | ||
439 | { /* Huawei E392, E398 and possibly others sharing both device id and more... */ | 358 | { /* Huawei E392, E398 and possibly others sharing both device id and more... */ |
440 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, | 359 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 9), |
441 | .idVendor = HUAWEI_VENDOR_ID, | ||
442 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | ||
443 | .bInterfaceSubClass = 1, | ||
444 | .bInterfaceProtocol = 9, /* CDC Ethernet *control* interface */ | ||
445 | .driver_info = (unsigned long)&qmi_wwan_info, | 360 | .driver_info = (unsigned long)&qmi_wwan_info, |
446 | }, | 361 | }, |
447 | { /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */ | 362 | { /* Vodafone/Huawei K5005 (12d1:14c8) and similar modems */ |
448 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, | 363 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 57), |
449 | .idVendor = HUAWEI_VENDOR_ID, | ||
450 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | ||
451 | .bInterfaceSubClass = 1, | ||
452 | .bInterfaceProtocol = 57, /* CDC Ethernet *control* interface */ | ||
453 | .driver_info = (unsigned long)&qmi_wwan_info, | 364 | .driver_info = (unsigned long)&qmi_wwan_info, |
454 | }, | 365 | }, |
455 | { /* Huawei E392, E398 and possibly others in "Windows mode" | 366 | |
456 | * using a combined control and data interface without any CDC | 367 | /* 2. Combined interface devices matching on class+protocol */ |
457 | * functional descriptors | 368 | { /* Huawei E392, E398 and possibly others in "Windows mode" */ |
458 | */ | 369 | USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, USB_CLASS_VENDOR_SPEC, 1, 17), |
459 | .match_flags = USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_INT_INFO, | ||
460 | .idVendor = HUAWEI_VENDOR_ID, | ||
461 | .bInterfaceClass = USB_CLASS_VENDOR_SPEC, | ||
462 | .bInterfaceSubClass = 1, | ||
463 | .bInterfaceProtocol = 17, | ||
464 | .driver_info = (unsigned long)&qmi_wwan_shared, | 370 | .driver_info = (unsigned long)&qmi_wwan_shared, |
465 | }, | 371 | }, |
466 | { /* Pantech UML290 */ | 372 | { /* Pantech UML290 */ |
467 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | 373 | USB_DEVICE_AND_INTERFACE_INFO(0x106c, 0x3718, USB_CLASS_VENDOR_SPEC, 0xf0, 0xff), |
468 | .idVendor = 0x106c, | ||
469 | .idProduct = 0x3718, | ||
470 | .bInterfaceClass = 0xff, | ||
471 | .bInterfaceSubClass = 0xf0, | ||
472 | .bInterfaceProtocol = 0xff, | ||
473 | .driver_info = (unsigned long)&qmi_wwan_shared, | 374 | .driver_info = (unsigned long)&qmi_wwan_shared, |
474 | }, | 375 | }, |
475 | { /* ZTE MF820D */ | 376 | { /* Pantech UML290 - newer firmware */ |
476 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | 377 | USB_DEVICE_AND_INTERFACE_INFO(0x106c, 0x3718, USB_CLASS_VENDOR_SPEC, 0xf1, 0xff), |
477 | .idVendor = 0x19d2, | 378 | .driver_info = (unsigned long)&qmi_wwan_shared, |
478 | .idProduct = 0x0167, | ||
479 | .bInterfaceClass = 0xff, | ||
480 | .bInterfaceSubClass = 0xff, | ||
481 | .bInterfaceProtocol = 0xff, | ||
482 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | ||
483 | }, | ||
484 | { /* ZTE MF821D */ | ||
485 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
486 | .idVendor = 0x19d2, | ||
487 | .idProduct = 0x0326, | ||
488 | .bInterfaceClass = 0xff, | ||
489 | .bInterfaceSubClass = 0xff, | ||
490 | .bInterfaceProtocol = 0xff, | ||
491 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | ||
492 | }, | ||
493 | { /* ZTE (Vodafone) K3520-Z */ | ||
494 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
495 | .idVendor = 0x19d2, | ||
496 | .idProduct = 0x0055, | ||
497 | .bInterfaceClass = 0xff, | ||
498 | .bInterfaceSubClass = 0xff, | ||
499 | .bInterfaceProtocol = 0xff, | ||
500 | .driver_info = (unsigned long)&qmi_wwan_force_int1, | ||
501 | }, | ||
502 | { /* ZTE (Vodafone) K3565-Z */ | ||
503 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
504 | .idVendor = 0x19d2, | ||
505 | .idProduct = 0x0063, | ||
506 | .bInterfaceClass = 0xff, | ||
507 | .bInterfaceSubClass = 0xff, | ||
508 | .bInterfaceProtocol = 0xff, | ||
509 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | ||
510 | }, | ||
511 | { /* ZTE (Vodafone) K3570-Z */ | ||
512 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
513 | .idVendor = 0x19d2, | ||
514 | .idProduct = 0x1008, | ||
515 | .bInterfaceClass = 0xff, | ||
516 | .bInterfaceSubClass = 0xff, | ||
517 | .bInterfaceProtocol = 0xff, | ||
518 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | ||
519 | }, | ||
520 | { /* ZTE (Vodafone) K3571-Z */ | ||
521 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
522 | .idVendor = 0x19d2, | ||
523 | .idProduct = 0x1010, | ||
524 | .bInterfaceClass = 0xff, | ||
525 | .bInterfaceSubClass = 0xff, | ||
526 | .bInterfaceProtocol = 0xff, | ||
527 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | ||
528 | }, | ||
529 | { /* ZTE (Vodafone) K3765-Z */ | ||
530 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
531 | .idVendor = 0x19d2, | ||
532 | .idProduct = 0x2002, | ||
533 | .bInterfaceClass = 0xff, | ||
534 | .bInterfaceSubClass = 0xff, | ||
535 | .bInterfaceProtocol = 0xff, | ||
536 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | ||
537 | }, | ||
538 | { /* ZTE (Vodafone) K4505-Z */ | ||
539 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
540 | .idVendor = 0x19d2, | ||
541 | .idProduct = 0x0104, | ||
542 | .bInterfaceClass = 0xff, | ||
543 | .bInterfaceSubClass = 0xff, | ||
544 | .bInterfaceProtocol = 0xff, | ||
545 | .driver_info = (unsigned long)&qmi_wwan_force_int4, | ||
546 | }, | ||
547 | { /* ZTE MF60 */ | ||
548 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
549 | .idVendor = 0x19d2, | ||
550 | .idProduct = 0x1402, | ||
551 | .bInterfaceClass = 0xff, | ||
552 | .bInterfaceSubClass = 0xff, | ||
553 | .bInterfaceProtocol = 0xff, | ||
554 | .driver_info = (unsigned long)&qmi_wwan_force_int2, | ||
555 | }, | ||
556 | { /* Sierra Wireless MC77xx in QMI mode */ | ||
557 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_INT_INFO, | ||
558 | .idVendor = 0x1199, | ||
559 | .idProduct = 0x68a2, | ||
560 | .bInterfaceClass = 0xff, | ||
561 | .bInterfaceSubClass = 0xff, | ||
562 | .bInterfaceProtocol = 0xff, | ||
563 | .driver_info = (unsigned long)&qmi_wwan_sierra, | ||
564 | }, | 379 | }, |
565 | 380 | ||
566 | /* Gobi 1000 devices */ | 381 | /* 3. Combined interface devices matching on interface number */ |
382 | {QMI_FIXED_INTF(0x19d2, 0x0055, 1)}, /* ZTE (Vodafone) K3520-Z */ | ||
383 | {QMI_FIXED_INTF(0x19d2, 0x0063, 4)}, /* ZTE (Vodafone) K3565-Z */ | ||
384 | {QMI_FIXED_INTF(0x19d2, 0x0104, 4)}, /* ZTE (Vodafone) K4505-Z */ | ||
385 | {QMI_FIXED_INTF(0x19d2, 0x0167, 4)}, /* ZTE MF820D */ | ||
386 | {QMI_FIXED_INTF(0x19d2, 0x0326, 4)}, /* ZTE MF821D */ | ||
387 | {QMI_FIXED_INTF(0x19d2, 0x1008, 4)}, /* ZTE (Vodafone) K3570-Z */ | ||
388 | {QMI_FIXED_INTF(0x19d2, 0x1010, 4)}, /* ZTE (Vodafone) K3571-Z */ | ||
389 | {QMI_FIXED_INTF(0x19d2, 0x1018, 3)}, /* ZTE (Vodafone) K5006-Z */ | ||
390 | {QMI_FIXED_INTF(0x19d2, 0x1402, 2)}, /* ZTE MF60 */ | ||
391 | {QMI_FIXED_INTF(0x19d2, 0x2002, 4)}, /* ZTE (Vodafone) K3765-Z */ | ||
392 | {QMI_FIXED_INTF(0x0f3d, 0x68a2, 8)}, /* Sierra Wireless MC7700 */ | ||
393 | {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ | ||
394 | {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ | ||
395 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ | ||
396 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ | ||
397 | |||
398 | /* 4. Gobi 1000 devices */ | ||
567 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 399 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
568 | {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ | 400 | {QMI_GOBI1K_DEVICE(0x03f0, 0x1f1d)}, /* HP un2400 Gobi Modem Device */ |
569 | {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ | 401 | {QMI_GOBI1K_DEVICE(0x03f0, 0x371d)}, /* HP un2430 Mobile Broadband Module */ |
@@ -579,7 +411,7 @@ static const struct usb_device_id products[] = { | |||
579 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ | 411 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9222)}, /* Generic Gobi Modem device */ |
580 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ | 412 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9009)}, /* Generic Gobi Modem device */ |
581 | 413 | ||
582 | /* Gobi 2000 and 3000 devices */ | 414 | /* 5. Gobi 2000 and 3000 devices */ |
583 | {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ | 415 | {QMI_GOBI_DEVICE(0x413c, 0x8186)}, /* Dell Gobi 2000 Modem device (N0218, VU936) */ |
584 | {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ | 416 | {QMI_GOBI_DEVICE(0x05c6, 0x920b)}, /* Generic Gobi 2000 Modem device */ |
585 | {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ | 417 | {QMI_GOBI_DEVICE(0x05c6, 0x9225)}, /* Sony Gobi 2000 Modem device (N0279, VU730) */ |
@@ -589,6 +421,8 @@ static const struct usb_device_id products[] = { | |||
589 | {QMI_GOBI_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ | 421 | {QMI_GOBI_DEVICE(0x05c6, 0x9265)}, /* Asus Gobi 2000 Modem device (VR305) */ |
590 | {QMI_GOBI_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ | 422 | {QMI_GOBI_DEVICE(0x05c6, 0x9235)}, /* Top Global Gobi 2000 Modem device (VR306) */ |
591 | {QMI_GOBI_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ | 423 | {QMI_GOBI_DEVICE(0x05c6, 0x9275)}, /* iRex Technologies Gobi 2000 Modem device (VR307) */ |
424 | {QMI_GOBI_DEVICE(0x1199, 0x68a5)}, /* Sierra Wireless Modem */ | ||
425 | {QMI_GOBI_DEVICE(0x1199, 0x68a9)}, /* Sierra Wireless Modem */ | ||
592 | {QMI_GOBI_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | 426 | {QMI_GOBI_DEVICE(0x1199, 0x9001)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ |
593 | {QMI_GOBI_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | 427 | {QMI_GOBI_DEVICE(0x1199, 0x9002)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ |
594 | {QMI_GOBI_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | 428 | {QMI_GOBI_DEVICE(0x1199, 0x9003)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ |
@@ -600,11 +434,14 @@ static const struct usb_device_id products[] = { | |||
600 | {QMI_GOBI_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | 434 | {QMI_GOBI_DEVICE(0x1199, 0x9009)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ |
601 | {QMI_GOBI_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ | 435 | {QMI_GOBI_DEVICE(0x1199, 0x900a)}, /* Sierra Wireless Gobi 2000 Modem device (VT773) */ |
602 | {QMI_GOBI_DEVICE(0x1199, 0x9011)}, /* Sierra Wireless Gobi 2000 Modem device (MC8305) */ | 436 | {QMI_GOBI_DEVICE(0x1199, 0x9011)}, /* Sierra Wireless Gobi 2000 Modem device (MC8305) */ |
437 | {QMI_FIXED_INTF(0x1199, 0x9011, 5)}, /* alternate interface number!? */ | ||
603 | {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ | 438 | {QMI_GOBI_DEVICE(0x16d8, 0x8002)}, /* CMDTech Gobi 2000 Modem device (VU922) */ |
604 | {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ | 439 | {QMI_GOBI_DEVICE(0x05c6, 0x9205)}, /* Gobi 2000 Modem device */ |
605 | {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ | 440 | {QMI_GOBI_DEVICE(0x1199, 0x9013)}, /* Sierra Wireless Gobi 3000 Modem device (MC8355) */ |
606 | {QMI_GOBI_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ | 441 | {QMI_GOBI_DEVICE(0x1199, 0x9015)}, /* Sierra Wireless Gobi 3000 Modem device */ |
607 | {QMI_GOBI_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ | 442 | {QMI_GOBI_DEVICE(0x1199, 0x9019)}, /* Sierra Wireless Gobi 3000 Modem device */ |
443 | {QMI_GOBI_DEVICE(0x1199, 0x901b)}, /* Sierra Wireless MC7770 */ | ||
444 | |||
608 | { } /* END */ | 445 | { } /* END */ |
609 | }; | 446 | }; |
610 | MODULE_DEVICE_TABLE(usb, products); | 447 | MODULE_DEVICE_TABLE(usb, products); |
diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index d75d1f56becf..7be49ea60b6d 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c | |||
@@ -68,15 +68,8 @@ static atomic_t iface_counter = ATOMIC_INIT(0); | |||
68 | */ | 68 | */ |
69 | #define SIERRA_NET_USBCTL_BUF_LEN 1024 | 69 | #define SIERRA_NET_USBCTL_BUF_LEN 1024 |
70 | 70 | ||
71 | /* list of interface numbers - used for constructing interface lists */ | ||
72 | struct sierra_net_iface_info { | ||
73 | const u32 infolen; /* number of interface numbers on list */ | ||
74 | const u8 *ifaceinfo; /* pointer to the array holding the numbers */ | ||
75 | }; | ||
76 | |||
77 | struct sierra_net_info_data { | 71 | struct sierra_net_info_data { |
78 | u16 rx_urb_size; | 72 | u16 rx_urb_size; |
79 | struct sierra_net_iface_info whitelist; | ||
80 | }; | 73 | }; |
81 | 74 | ||
82 | /* Private data structure */ | 75 | /* Private data structure */ |
@@ -637,21 +630,6 @@ static int sierra_net_change_mtu(struct net_device *net, int new_mtu) | |||
637 | return usbnet_change_mtu(net, new_mtu); | 630 | return usbnet_change_mtu(net, new_mtu); |
638 | } | 631 | } |
639 | 632 | ||
640 | static int is_whitelisted(const u8 ifnum, | ||
641 | const struct sierra_net_iface_info *whitelist) | ||
642 | { | ||
643 | if (whitelist) { | ||
644 | const u8 *list = whitelist->ifaceinfo; | ||
645 | int i; | ||
646 | |||
647 | for (i = 0; i < whitelist->infolen; i++) { | ||
648 | if (list[i] == ifnum) | ||
649 | return 1; | ||
650 | } | ||
651 | } | ||
652 | return 0; | ||
653 | } | ||
654 | |||
655 | static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap) | 633 | static int sierra_net_get_fw_attr(struct usbnet *dev, u16 *datap) |
656 | { | 634 | { |
657 | int result = 0; | 635 | int result = 0; |
@@ -706,11 +684,6 @@ static int sierra_net_bind(struct usbnet *dev, struct usb_interface *intf) | |||
706 | dev_dbg(&dev->udev->dev, "%s", __func__); | 684 | dev_dbg(&dev->udev->dev, "%s", __func__); |
707 | 685 | ||
708 | ifacenum = intf->cur_altsetting->desc.bInterfaceNumber; | 686 | ifacenum = intf->cur_altsetting->desc.bInterfaceNumber; |
709 | /* We only accept certain interfaces */ | ||
710 | if (!is_whitelisted(ifacenum, &data->whitelist)) { | ||
711 | dev_dbg(&dev->udev->dev, "Ignoring interface: %d", ifacenum); | ||
712 | return -ENODEV; | ||
713 | } | ||
714 | numendpoints = intf->cur_altsetting->desc.bNumEndpoints; | 687 | numendpoints = intf->cur_altsetting->desc.bNumEndpoints; |
715 | /* We have three endpoints, bulk in and out, and a status */ | 688 | /* We have three endpoints, bulk in and out, and a status */ |
716 | if (numendpoints != 3) { | 689 | if (numendpoints != 3) { |
@@ -945,13 +918,8 @@ struct sk_buff *sierra_net_tx_fixup(struct usbnet *dev, struct sk_buff *skb, | |||
945 | return NULL; | 918 | return NULL; |
946 | } | 919 | } |
947 | 920 | ||
948 | static const u8 sierra_net_ifnum_list[] = { 7, 10, 11 }; | ||
949 | static const struct sierra_net_info_data sierra_net_info_data_direct_ip = { | 921 | static const struct sierra_net_info_data sierra_net_info_data_direct_ip = { |
950 | .rx_urb_size = 8 * 1024, | 922 | .rx_urb_size = 8 * 1024, |
951 | .whitelist = { | ||
952 | .infolen = ARRAY_SIZE(sierra_net_ifnum_list), | ||
953 | .ifaceinfo = sierra_net_ifnum_list | ||
954 | } | ||
955 | }; | 923 | }; |
956 | 924 | ||
957 | static const struct driver_info sierra_net_info_direct_ip = { | 925 | static const struct driver_info sierra_net_info_direct_ip = { |
@@ -965,15 +933,19 @@ static const struct driver_info sierra_net_info_direct_ip = { | |||
965 | .data = (unsigned long)&sierra_net_info_data_direct_ip, | 933 | .data = (unsigned long)&sierra_net_info_data_direct_ip, |
966 | }; | 934 | }; |
967 | 935 | ||
936 | #define DIRECT_IP_DEVICE(vend, prod) \ | ||
937 | {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 7), \ | ||
938 | .driver_info = (unsigned long)&sierra_net_info_direct_ip}, \ | ||
939 | {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 10), \ | ||
940 | .driver_info = (unsigned long)&sierra_net_info_direct_ip}, \ | ||
941 | {USB_DEVICE_INTERFACE_NUMBER(vend, prod, 11), \ | ||
942 | .driver_info = (unsigned long)&sierra_net_info_direct_ip} | ||
943 | |||
968 | static const struct usb_device_id products[] = { | 944 | static const struct usb_device_id products[] = { |
969 | {USB_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */ | 945 | DIRECT_IP_DEVICE(0x1199, 0x68A3), /* Sierra Wireless USB-to-WWAN modem */ |
970 | .driver_info = (unsigned long) &sierra_net_info_direct_ip}, | 946 | DIRECT_IP_DEVICE(0x0F3D, 0x68A3), /* AT&T Direct IP modem */ |
971 | {USB_DEVICE(0x0F3D, 0x68A3), /* AT&T Direct IP modem */ | 947 | DIRECT_IP_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */ |
972 | .driver_info = (unsigned long) &sierra_net_info_direct_ip}, | 948 | DIRECT_IP_DEVICE(0x0F3D, 0x68AA), /* AT&T Direct IP LTE modem */ |
973 | {USB_DEVICE(0x1199, 0x68AA), /* Sierra Wireless Direct IP LTE modem */ | ||
974 | .driver_info = (unsigned long) &sierra_net_info_direct_ip}, | ||
975 | {USB_DEVICE(0x0F3D, 0x68AA), /* AT&T Direct IP LTE modem */ | ||
976 | .driver_info = (unsigned long) &sierra_net_info_direct_ip}, | ||
977 | 949 | ||
978 | {}, /* last item */ | 950 | {}, /* last item */ |
979 | }; | 951 | }; |
diff --git a/drivers/net/vmxnet3/vmxnet3_drv.c b/drivers/net/vmxnet3/vmxnet3_drv.c index 93e0cfb739b8..ce9d4f2c9776 100644 --- a/drivers/net/vmxnet3/vmxnet3_drv.c +++ b/drivers/net/vmxnet3/vmxnet3_drv.c | |||
@@ -3019,6 +3019,7 @@ vmxnet3_probe_device(struct pci_dev *pdev, | |||
3019 | netdev->watchdog_timeo = 5 * HZ; | 3019 | netdev->watchdog_timeo = 5 * HZ; |
3020 | 3020 | ||
3021 | INIT_WORK(&adapter->work, vmxnet3_reset_work); | 3021 | INIT_WORK(&adapter->work, vmxnet3_reset_work); |
3022 | set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state); | ||
3022 | 3023 | ||
3023 | if (adapter->intr.type == VMXNET3_IT_MSIX) { | 3024 | if (adapter->intr.type == VMXNET3_IT_MSIX) { |
3024 | int i; | 3025 | int i; |
@@ -3043,7 +3044,6 @@ vmxnet3_probe_device(struct pci_dev *pdev, | |||
3043 | goto err_register; | 3044 | goto err_register; |
3044 | } | 3045 | } |
3045 | 3046 | ||
3046 | set_bit(VMXNET3_STATE_BIT_QUIESCED, &adapter->state); | ||
3047 | vmxnet3_check_link(adapter, false); | 3047 | vmxnet3_check_link(adapter, false); |
3048 | atomic_inc(&devices_found); | 3048 | atomic_inc(&devices_found); |
3049 | return 0; | 3049 | return 0; |
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c index 9eb6479306d6..ef36cafd44b7 100644 --- a/drivers/net/wan/dscc4.c +++ b/drivers/net/wan/dscc4.c | |||
@@ -774,14 +774,15 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev, | |||
774 | } | 774 | } |
775 | /* Global interrupt queue */ | 775 | /* Global interrupt queue */ |
776 | writel((u32)(((IRQ_RING_SIZE >> 5) - 1) << 20), ioaddr + IQLENR1); | 776 | writel((u32)(((IRQ_RING_SIZE >> 5) - 1) << 20), ioaddr + IQLENR1); |
777 | |||
778 | rc = -ENOMEM; | ||
779 | |||
777 | priv->iqcfg = (__le32 *) pci_alloc_consistent(pdev, | 780 | priv->iqcfg = (__le32 *) pci_alloc_consistent(pdev, |
778 | IRQ_RING_SIZE*sizeof(__le32), &priv->iqcfg_dma); | 781 | IRQ_RING_SIZE*sizeof(__le32), &priv->iqcfg_dma); |
779 | if (!priv->iqcfg) | 782 | if (!priv->iqcfg) |
780 | goto err_free_irq_5; | 783 | goto err_free_irq_5; |
781 | writel(priv->iqcfg_dma, ioaddr + IQCFG); | 784 | writel(priv->iqcfg_dma, ioaddr + IQCFG); |
782 | 785 | ||
783 | rc = -ENOMEM; | ||
784 | |||
785 | /* | 786 | /* |
786 | * SCC 0-3 private rx/tx irq structures | 787 | * SCC 0-3 private rx/tx irq structures |
787 | * IQRX/TXi needs to be set soon. Learned it the hard way... | 788 | * IQRX/TXi needs to be set soon. Learned it the hard way... |
diff --git a/drivers/net/wimax/i2400m/fw.c b/drivers/net/wimax/i2400m/fw.c index 283237f6f074..def12b38cbf7 100644 --- a/drivers/net/wimax/i2400m/fw.c +++ b/drivers/net/wimax/i2400m/fw.c | |||
@@ -326,8 +326,10 @@ int i2400m_barker_db_init(const char *_options) | |||
326 | unsigned barker; | 326 | unsigned barker; |
327 | 327 | ||
328 | options_orig = kstrdup(_options, GFP_KERNEL); | 328 | options_orig = kstrdup(_options, GFP_KERNEL); |
329 | if (options_orig == NULL) | 329 | if (options_orig == NULL) { |
330 | result = -ENOMEM; | ||
330 | goto error_parse; | 331 | goto error_parse; |
332 | } | ||
331 | options = options_orig; | 333 | options = options_orig; |
332 | 334 | ||
333 | while ((token = strsep(&options, ",")) != NULL) { | 335 | while ((token = strsep(&options, ",")) != NULL) { |
diff --git a/drivers/net/wireless/at76c50x-usb.c b/drivers/net/wireless/at76c50x-usb.c index efc162e0b511..88b8d64c90f1 100644 --- a/drivers/net/wireless/at76c50x-usb.c +++ b/drivers/net/wireless/at76c50x-usb.c | |||
@@ -342,7 +342,7 @@ static int at76_dfu_get_status(struct usb_device *udev, | |||
342 | return ret; | 342 | return ret; |
343 | } | 343 | } |
344 | 344 | ||
345 | static u8 at76_dfu_get_state(struct usb_device *udev, u8 *state) | 345 | static int at76_dfu_get_state(struct usb_device *udev, u8 *state) |
346 | { | 346 | { |
347 | int ret; | 347 | int ret; |
348 | 348 | ||
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 9d48f9a461e1..a0a202de1109 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -2057,9 +2057,7 @@ ath5k_beacon_update_timers(struct ath5k_hw *ah, u64 bc_tsf) | |||
2057 | void | 2057 | void |
2058 | ath5k_beacon_config(struct ath5k_hw *ah) | 2058 | ath5k_beacon_config(struct ath5k_hw *ah) |
2059 | { | 2059 | { |
2060 | unsigned long flags; | 2060 | spin_lock_bh(&ah->block); |
2061 | |||
2062 | spin_lock_irqsave(&ah->block, flags); | ||
2063 | ah->bmisscount = 0; | 2061 | ah->bmisscount = 0; |
2064 | ah->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); | 2062 | ah->imask &= ~(AR5K_INT_BMISS | AR5K_INT_SWBA); |
2065 | 2063 | ||
@@ -2086,7 +2084,7 @@ ath5k_beacon_config(struct ath5k_hw *ah) | |||
2086 | 2084 | ||
2087 | ath5k_hw_set_imr(ah, ah->imask); | 2085 | ath5k_hw_set_imr(ah, ah->imask); |
2088 | mmiowb(); | 2086 | mmiowb(); |
2089 | spin_unlock_irqrestore(&ah->block, flags); | 2087 | spin_unlock_bh(&ah->block); |
2090 | } | 2088 | } |
2091 | 2089 | ||
2092 | static void ath5k_tasklet_beacon(unsigned long data) | 2090 | static void ath5k_tasklet_beacon(unsigned long data) |
diff --git a/drivers/net/wireless/ath/ath5k/mac80211-ops.c b/drivers/net/wireless/ath/ath5k/mac80211-ops.c index 92ee3a0a5192..384e67af73bc 100644 --- a/drivers/net/wireless/ath/ath5k/mac80211-ops.c +++ b/drivers/net/wireless/ath/ath5k/mac80211-ops.c | |||
@@ -254,7 +254,6 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
254 | struct ath5k_vif *avf = (void *)vif->drv_priv; | 254 | struct ath5k_vif *avf = (void *)vif->drv_priv; |
255 | struct ath5k_hw *ah = hw->priv; | 255 | struct ath5k_hw *ah = hw->priv; |
256 | struct ath_common *common = ath5k_hw_common(ah); | 256 | struct ath_common *common = ath5k_hw_common(ah); |
257 | unsigned long flags; | ||
258 | 257 | ||
259 | mutex_lock(&ah->lock); | 258 | mutex_lock(&ah->lock); |
260 | 259 | ||
@@ -300,9 +299,9 @@ ath5k_bss_info_changed(struct ieee80211_hw *hw, struct ieee80211_vif *vif, | |||
300 | } | 299 | } |
301 | 300 | ||
302 | if (changes & BSS_CHANGED_BEACON) { | 301 | if (changes & BSS_CHANGED_BEACON) { |
303 | spin_lock_irqsave(&ah->block, flags); | 302 | spin_lock_bh(&ah->block); |
304 | ath5k_beacon_update(hw, vif); | 303 | ath5k_beacon_update(hw, vif); |
305 | spin_unlock_irqrestore(&ah->block, flags); | 304 | spin_unlock_bh(&ah->block); |
306 | } | 305 | } |
307 | 306 | ||
308 | if (changes & BSS_CHANGED_BEACON_ENABLED) | 307 | if (changes & BSS_CHANGED_BEACON_ENABLED) |
diff --git a/drivers/net/wireless/ath/ath9k/mac.c b/drivers/net/wireless/ath/ath9k/mac.c index 7990cd55599c..b42be910a83d 100644 --- a/drivers/net/wireless/ath/ath9k/mac.c +++ b/drivers/net/wireless/ath/ath9k/mac.c | |||
@@ -773,15 +773,10 @@ bool ath9k_hw_intrpend(struct ath_hw *ah) | |||
773 | } | 773 | } |
774 | EXPORT_SYMBOL(ath9k_hw_intrpend); | 774 | EXPORT_SYMBOL(ath9k_hw_intrpend); |
775 | 775 | ||
776 | void ath9k_hw_disable_interrupts(struct ath_hw *ah) | 776 | void ath9k_hw_kill_interrupts(struct ath_hw *ah) |
777 | { | 777 | { |
778 | struct ath_common *common = ath9k_hw_common(ah); | 778 | struct ath_common *common = ath9k_hw_common(ah); |
779 | 779 | ||
780 | if (!(ah->imask & ATH9K_INT_GLOBAL)) | ||
781 | atomic_set(&ah->intr_ref_cnt, -1); | ||
782 | else | ||
783 | atomic_dec(&ah->intr_ref_cnt); | ||
784 | |||
785 | ath_dbg(common, INTERRUPT, "disable IER\n"); | 780 | ath_dbg(common, INTERRUPT, "disable IER\n"); |
786 | REG_WRITE(ah, AR_IER, AR_IER_DISABLE); | 781 | REG_WRITE(ah, AR_IER, AR_IER_DISABLE); |
787 | (void) REG_READ(ah, AR_IER); | 782 | (void) REG_READ(ah, AR_IER); |
@@ -793,6 +788,17 @@ void ath9k_hw_disable_interrupts(struct ath_hw *ah) | |||
793 | (void) REG_READ(ah, AR_INTR_SYNC_ENABLE); | 788 | (void) REG_READ(ah, AR_INTR_SYNC_ENABLE); |
794 | } | 789 | } |
795 | } | 790 | } |
791 | EXPORT_SYMBOL(ath9k_hw_kill_interrupts); | ||
792 | |||
793 | void ath9k_hw_disable_interrupts(struct ath_hw *ah) | ||
794 | { | ||
795 | if (!(ah->imask & ATH9K_INT_GLOBAL)) | ||
796 | atomic_set(&ah->intr_ref_cnt, -1); | ||
797 | else | ||
798 | atomic_dec(&ah->intr_ref_cnt); | ||
799 | |||
800 | ath9k_hw_kill_interrupts(ah); | ||
801 | } | ||
796 | EXPORT_SYMBOL(ath9k_hw_disable_interrupts); | 802 | EXPORT_SYMBOL(ath9k_hw_disable_interrupts); |
797 | 803 | ||
798 | void ath9k_hw_enable_interrupts(struct ath_hw *ah) | 804 | void ath9k_hw_enable_interrupts(struct ath_hw *ah) |
diff --git a/drivers/net/wireless/ath/ath9k/mac.h b/drivers/net/wireless/ath/ath9k/mac.h index 0eba36dca6f8..4a745e68dd94 100644 --- a/drivers/net/wireless/ath/ath9k/mac.h +++ b/drivers/net/wireless/ath/ath9k/mac.h | |||
@@ -738,6 +738,7 @@ bool ath9k_hw_intrpend(struct ath_hw *ah); | |||
738 | void ath9k_hw_set_interrupts(struct ath_hw *ah); | 738 | void ath9k_hw_set_interrupts(struct ath_hw *ah); |
739 | void ath9k_hw_enable_interrupts(struct ath_hw *ah); | 739 | void ath9k_hw_enable_interrupts(struct ath_hw *ah); |
740 | void ath9k_hw_disable_interrupts(struct ath_hw *ah); | 740 | void ath9k_hw_disable_interrupts(struct ath_hw *ah); |
741 | void ath9k_hw_kill_interrupts(struct ath_hw *ah); | ||
741 | 742 | ||
742 | void ar9002_hw_attach_mac_ops(struct ath_hw *ah); | 743 | void ar9002_hw_attach_mac_ops(struct ath_hw *ah); |
743 | 744 | ||
diff --git a/drivers/net/wireless/ath/ath9k/main.c b/drivers/net/wireless/ath/ath9k/main.c index 6049d8b82855..a22df749b8db 100644 --- a/drivers/net/wireless/ath/ath9k/main.c +++ b/drivers/net/wireless/ath/ath9k/main.c | |||
@@ -462,8 +462,10 @@ irqreturn_t ath_isr(int irq, void *dev) | |||
462 | if (!ath9k_hw_intrpend(ah)) | 462 | if (!ath9k_hw_intrpend(ah)) |
463 | return IRQ_NONE; | 463 | return IRQ_NONE; |
464 | 464 | ||
465 | if(test_bit(SC_OP_HW_RESET, &sc->sc_flags)) | 465 | if (test_bit(SC_OP_HW_RESET, &sc->sc_flags)) { |
466 | ath9k_hw_kill_interrupts(ah); | ||
466 | return IRQ_HANDLED; | 467 | return IRQ_HANDLED; |
468 | } | ||
467 | 469 | ||
468 | /* | 470 | /* |
469 | * Figure out the reason(s) for the interrupt. Note | 471 | * Figure out the reason(s) for the interrupt. Note |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index d455de9162ec..a978984d78a5 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -321,6 +321,7 @@ static int ath_pci_suspend(struct device *device) | |||
321 | * Otherwise the chip never moved to full sleep, | 321 | * Otherwise the chip never moved to full sleep, |
322 | * when no interface is up. | 322 | * when no interface is up. |
323 | */ | 323 | */ |
324 | ath9k_stop_btcoex(sc); | ||
324 | ath9k_hw_disable(sc->sc_ah); | 325 | ath9k_hw_disable(sc->sc_ah); |
325 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); | 326 | ath9k_hw_setpower(sc->sc_ah, ATH9K_PM_FULL_SLEEP); |
326 | 327 | ||
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 12aca02228c2..4480c0cc655f 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -1044,7 +1044,6 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1044 | struct ieee80211_hw *hw = sc->hw; | 1044 | struct ieee80211_hw *hw = sc->hw; |
1045 | struct ieee80211_hdr *hdr; | 1045 | struct ieee80211_hdr *hdr; |
1046 | int retval; | 1046 | int retval; |
1047 | bool decrypt_error = false; | ||
1048 | struct ath_rx_status rs; | 1047 | struct ath_rx_status rs; |
1049 | enum ath9k_rx_qtype qtype; | 1048 | enum ath9k_rx_qtype qtype; |
1050 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); | 1049 | bool edma = !!(ah->caps.hw_caps & ATH9K_HW_CAP_EDMA); |
@@ -1066,6 +1065,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
1066 | tsf_lower = tsf & 0xffffffff; | 1065 | tsf_lower = tsf & 0xffffffff; |
1067 | 1066 | ||
1068 | do { | 1067 | do { |
1068 | bool decrypt_error = false; | ||
1069 | /* If handling rx interrupt and flush is in progress => exit */ | 1069 | /* If handling rx interrupt and flush is in progress => exit */ |
1070 | if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0)) | 1070 | if (test_bit(SC_OP_RXFLUSH, &sc->sc_flags) && (flush == 0)) |
1071 | break; | 1071 | break; |
diff --git a/drivers/net/wireless/iwlwifi/dvm/rs.c b/drivers/net/wireless/iwlwifi/dvm/rs.c index 6fddd2785e6e..a82f46c10f5e 100644 --- a/drivers/net/wireless/iwlwifi/dvm/rs.c +++ b/drivers/net/wireless/iwlwifi/dvm/rs.c | |||
@@ -707,11 +707,14 @@ static int rs_toggle_antenna(u32 valid_ant, u32 *rate_n_flags, | |||
707 | */ | 707 | */ |
708 | static bool rs_use_green(struct ieee80211_sta *sta) | 708 | static bool rs_use_green(struct ieee80211_sta *sta) |
709 | { | 709 | { |
710 | struct iwl_station_priv *sta_priv = (void *)sta->drv_priv; | 710 | /* |
711 | struct iwl_rxon_context *ctx = sta_priv->ctx; | 711 | * There's a bug somewhere in this code that causes the |
712 | 712 | * scaling to get stuck because GF+SGI can't be combined | |
713 | return (sta->ht_cap.cap & IEEE80211_HT_CAP_GRN_FLD) && | 713 | * in SISO rates. Until we find that bug, disable GF, it |
714 | !(ctx->ht.non_gf_sta_present); | 714 | * has only limited benefit and we still interoperate with |
715 | * GF APs since we can always receive GF transmissions. | ||
716 | */ | ||
717 | return false; | ||
715 | } | 718 | } |
716 | 719 | ||
717 | /** | 720 | /** |
diff --git a/drivers/net/wireless/libertas/if_usb.c b/drivers/net/wireless/libertas/if_usb.c index 55a77e41170a..27980778d992 100644 --- a/drivers/net/wireless/libertas/if_usb.c +++ b/drivers/net/wireless/libertas/if_usb.c | |||
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/netdevice.h> | 10 | #include <linux/netdevice.h> |
11 | #include <linux/slab.h> | 11 | #include <linux/slab.h> |
12 | #include <linux/usb.h> | 12 | #include <linux/usb.h> |
13 | #include <linux/olpc-ec.h> | ||
13 | 14 | ||
14 | #ifdef CONFIG_OLPC | 15 | #ifdef CONFIG_OLPC |
15 | #include <asm/olpc.h> | 16 | #include <asm/olpc.h> |
diff --git a/drivers/net/wireless/p54/p54usb.c b/drivers/net/wireless/p54/p54usb.c index 7f207b6e9552..effb044a8a9d 100644 --- a/drivers/net/wireless/p54/p54usb.c +++ b/drivers/net/wireless/p54/p54usb.c | |||
@@ -42,7 +42,7 @@ MODULE_FIRMWARE("isl3887usb"); | |||
42 | * whenever you add a new device. | 42 | * whenever you add a new device. |
43 | */ | 43 | */ |
44 | 44 | ||
45 | static struct usb_device_id p54u_table[] __devinitdata = { | 45 | static struct usb_device_id p54u_table[] = { |
46 | /* Version 1 devices (pci chip + net2280) */ | 46 | /* Version 1 devices (pci chip + net2280) */ |
47 | {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */ | 47 | {USB_DEVICE(0x0411, 0x0050)}, /* Buffalo WLI2-USB2-G54 */ |
48 | {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ | 48 | {USB_DEVICE(0x045e, 0x00c2)}, /* Microsoft MN-710 */ |
diff --git a/drivers/net/wireless/rndis_wlan.c b/drivers/net/wireless/rndis_wlan.c index 241162e8111d..7a4ae9ee1c63 100644 --- a/drivers/net/wireless/rndis_wlan.c +++ b/drivers/net/wireless/rndis_wlan.c | |||
@@ -1803,6 +1803,7 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev, | |||
1803 | struct cfg80211_pmksa *pmksa, | 1803 | struct cfg80211_pmksa *pmksa, |
1804 | int max_pmkids) | 1804 | int max_pmkids) |
1805 | { | 1805 | { |
1806 | struct ndis_80211_pmkid *new_pmkids; | ||
1806 | int i, err, newlen; | 1807 | int i, err, newlen; |
1807 | unsigned int count; | 1808 | unsigned int count; |
1808 | 1809 | ||
@@ -1833,11 +1834,12 @@ static struct ndis_80211_pmkid *update_pmkid(struct usbnet *usbdev, | |||
1833 | /* add new pmkid */ | 1834 | /* add new pmkid */ |
1834 | newlen = sizeof(*pmkids) + (count + 1) * sizeof(pmkids->bssid_info[0]); | 1835 | newlen = sizeof(*pmkids) + (count + 1) * sizeof(pmkids->bssid_info[0]); |
1835 | 1836 | ||
1836 | pmkids = krealloc(pmkids, newlen, GFP_KERNEL); | 1837 | new_pmkids = krealloc(pmkids, newlen, GFP_KERNEL); |
1837 | if (!pmkids) { | 1838 | if (!new_pmkids) { |
1838 | err = -ENOMEM; | 1839 | err = -ENOMEM; |
1839 | goto error; | 1840 | goto error; |
1840 | } | 1841 | } |
1842 | pmkids = new_pmkids; | ||
1841 | 1843 | ||
1842 | pmkids->length = cpu_to_le32(newlen); | 1844 | pmkids->length = cpu_to_le32(newlen); |
1843 | pmkids->bssid_info_count = cpu_to_le32(count + 1); | 1845 | pmkids->bssid_info_count = cpu_to_le32(count + 1); |
diff --git a/drivers/net/wireless/rt2x00/rt61pci.c b/drivers/net/wireless/rt2x00/rt61pci.c index f32259686b45..3f7bc5cadf9a 100644 --- a/drivers/net/wireless/rt2x00/rt61pci.c +++ b/drivers/net/wireless/rt2x00/rt61pci.c | |||
@@ -2243,8 +2243,7 @@ static void rt61pci_txdone(struct rt2x00_dev *rt2x00dev) | |||
2243 | 2243 | ||
2244 | static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev) | 2244 | static void rt61pci_wakeup(struct rt2x00_dev *rt2x00dev) |
2245 | { | 2245 | { |
2246 | struct ieee80211_conf conf = { .flags = 0 }; | 2246 | struct rt2x00lib_conf libconf = { .conf = &rt2x00dev->hw->conf }; |
2247 | struct rt2x00lib_conf libconf = { .conf = &conf }; | ||
2248 | 2247 | ||
2249 | rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); | 2248 | rt61pci_config(rt2x00dev, &libconf, IEEE80211_CONF_CHANGE_PS); |
2250 | } | 2249 | } |
diff --git a/drivers/net/wireless/rtl818x/rtl8187/dev.c b/drivers/net/wireless/rtl818x/rtl8187/dev.c index 71a30b026089..533024095c43 100644 --- a/drivers/net/wireless/rtl818x/rtl8187/dev.c +++ b/drivers/net/wireless/rtl818x/rtl8187/dev.c | |||
@@ -44,7 +44,7 @@ MODULE_AUTHOR("Larry Finger <Larry.Finger@lwfinger.net>"); | |||
44 | MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver"); | 44 | MODULE_DESCRIPTION("RTL8187/RTL8187B USB wireless driver"); |
45 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
46 | 46 | ||
47 | static struct usb_device_id rtl8187_table[] __devinitdata = { | 47 | static struct usb_device_id rtl8187_table[] = { |
48 | /* Asus */ | 48 | /* Asus */ |
49 | {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187}, | 49 | {USB_DEVICE(0x0b05, 0x171d), .driver_info = DEVICE_RTL8187}, |
50 | /* Belkin */ | 50 | /* Belkin */ |
diff --git a/drivers/of/base.c b/drivers/of/base.c index c181b94abc36..d4a1c9a043e1 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -364,6 +364,33 @@ struct device_node *of_get_next_child(const struct device_node *node, | |||
364 | EXPORT_SYMBOL(of_get_next_child); | 364 | EXPORT_SYMBOL(of_get_next_child); |
365 | 365 | ||
366 | /** | 366 | /** |
367 | * of_get_next_available_child - Find the next available child node | ||
368 | * @node: parent node | ||
369 | * @prev: previous child of the parent node, or NULL to get first | ||
370 | * | ||
371 | * This function is like of_get_next_child(), except that it | ||
372 | * automatically skips any disabled nodes (i.e. status = "disabled"). | ||
373 | */ | ||
374 | struct device_node *of_get_next_available_child(const struct device_node *node, | ||
375 | struct device_node *prev) | ||
376 | { | ||
377 | struct device_node *next; | ||
378 | |||
379 | read_lock(&devtree_lock); | ||
380 | next = prev ? prev->sibling : node->child; | ||
381 | for (; next; next = next->sibling) { | ||
382 | if (!of_device_is_available(next)) | ||
383 | continue; | ||
384 | if (of_node_get(next)) | ||
385 | break; | ||
386 | } | ||
387 | of_node_put(prev); | ||
388 | read_unlock(&devtree_lock); | ||
389 | return next; | ||
390 | } | ||
391 | EXPORT_SYMBOL(of_get_next_available_child); | ||
392 | |||
393 | /** | ||
367 | * of_find_node_by_path - Find a node matching a full OF path | 394 | * of_find_node_by_path - Find a node matching a full OF path |
368 | * @path: The full path to match | 395 | * @path: The full path to match |
369 | * | 396 | * |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index fbf7b26c7c8a..c5792d622dc4 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
@@ -266,8 +266,8 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state) | |||
266 | } | 266 | } |
267 | 267 | ||
268 | if (!error) | 268 | if (!error) |
269 | dev_printk(KERN_INFO, &dev->dev, | 269 | dev_info(&dev->dev, "power state changed by ACPI to %s\n", |
270 | "power state changed by ACPI to D%d\n", state); | 270 | pci_power_name(state)); |
271 | 271 | ||
272 | return error; | 272 | return error; |
273 | } | 273 | } |
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c index 185be3703343..5270f1a99328 100644 --- a/drivers/pci/pci-driver.c +++ b/drivers/pci/pci-driver.c | |||
@@ -959,6 +959,13 @@ static int pci_pm_poweroff_noirq(struct device *dev) | |||
959 | if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) | 959 | if (!pci_dev->state_saved && !pci_is_bridge(pci_dev)) |
960 | pci_prepare_to_sleep(pci_dev); | 960 | pci_prepare_to_sleep(pci_dev); |
961 | 961 | ||
962 | /* | ||
963 | * The reason for doing this here is the same as for the analogous code | ||
964 | * in pci_pm_suspend_noirq(). | ||
965 | */ | ||
966 | if (pci_dev->class == PCI_CLASS_SERIAL_USB_EHCI) | ||
967 | pci_write_config_word(pci_dev, PCI_COMMAND, 0); | ||
968 | |||
962 | return 0; | 969 | return 0; |
963 | } | 970 | } |
964 | 971 | ||
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index fb7f3bebdc69..dc5c126e398a 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c | |||
@@ -657,11 +657,7 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev) | |||
657 | if (p != NULL) | 657 | if (p != NULL) |
658 | return ERR_PTR(-EBUSY); | 658 | return ERR_PTR(-EBUSY); |
659 | 659 | ||
660 | p = create_pinctrl(dev); | 660 | return create_pinctrl(dev); |
661 | if (IS_ERR(p)) | ||
662 | return p; | ||
663 | |||
664 | return p; | ||
665 | } | 661 | } |
666 | 662 | ||
667 | /** | 663 | /** |
@@ -738,11 +734,8 @@ static struct pinctrl_state *pinctrl_lookup_state_locked(struct pinctrl *p, | |||
738 | dev_dbg(p->dev, "using pinctrl dummy state (%s)\n", | 734 | dev_dbg(p->dev, "using pinctrl dummy state (%s)\n", |
739 | name); | 735 | name); |
740 | state = create_state(p, name); | 736 | state = create_state(p, name); |
741 | if (IS_ERR(state)) | 737 | } else |
742 | return state; | 738 | state = ERR_PTR(-ENODEV); |
743 | } else { | ||
744 | return ERR_PTR(-ENODEV); | ||
745 | } | ||
746 | } | 739 | } |
747 | 740 | ||
748 | return state; | 741 | return state; |
diff --git a/drivers/pinctrl/pinctrl-imx23.c b/drivers/pinctrl/pinctrl-imx23.c index 75d3eff94296..3674d877ed7c 100644 --- a/drivers/pinctrl/pinctrl-imx23.c +++ b/drivers/pinctrl/pinctrl-imx23.c | |||
@@ -292,7 +292,7 @@ static int __init imx23_pinctrl_init(void) | |||
292 | { | 292 | { |
293 | return platform_driver_register(&imx23_pinctrl_driver); | 293 | return platform_driver_register(&imx23_pinctrl_driver); |
294 | } | 294 | } |
295 | arch_initcall(imx23_pinctrl_init); | 295 | postcore_initcall(imx23_pinctrl_init); |
296 | 296 | ||
297 | static void __exit imx23_pinctrl_exit(void) | 297 | static void __exit imx23_pinctrl_exit(void) |
298 | { | 298 | { |
diff --git a/drivers/pinctrl/pinctrl-imx28.c b/drivers/pinctrl/pinctrl-imx28.c index b973026811a2..0f5b2122b1ba 100644 --- a/drivers/pinctrl/pinctrl-imx28.c +++ b/drivers/pinctrl/pinctrl-imx28.c | |||
@@ -408,7 +408,7 @@ static int __init imx28_pinctrl_init(void) | |||
408 | { | 408 | { |
409 | return platform_driver_register(&imx28_pinctrl_driver); | 409 | return platform_driver_register(&imx28_pinctrl_driver); |
410 | } | 410 | } |
411 | arch_initcall(imx28_pinctrl_init); | 411 | postcore_initcall(imx28_pinctrl_init); |
412 | 412 | ||
413 | static void __exit imx28_pinctrl_exit(void) | 413 | static void __exit imx28_pinctrl_exit(void) |
414 | { | 414 | { |
diff --git a/drivers/pinctrl/pinctrl-imx51.c b/drivers/pinctrl/pinctrl-imx51.c index 689b3c88dd2e..9fd02162a3c2 100644 --- a/drivers/pinctrl/pinctrl-imx51.c +++ b/drivers/pinctrl/pinctrl-imx51.c | |||
@@ -974,7 +974,7 @@ static struct imx_pin_reg imx51_pin_regs[] = { | |||
974 | IMX_PIN_REG(MX51_PAD_EIM_DA13, NO_PAD, 0x050, 0, 0x000, 0), /* MX51_PAD_EIM_DA13__EIM_DA13 */ | 974 | IMX_PIN_REG(MX51_PAD_EIM_DA13, NO_PAD, 0x050, 0, 0x000, 0), /* MX51_PAD_EIM_DA13__EIM_DA13 */ |
975 | IMX_PIN_REG(MX51_PAD_EIM_DA14, NO_PAD, 0x054, 0, 0x000, 0), /* MX51_PAD_EIM_DA14__EIM_DA14 */ | 975 | IMX_PIN_REG(MX51_PAD_EIM_DA14, NO_PAD, 0x054, 0, 0x000, 0), /* MX51_PAD_EIM_DA14__EIM_DA14 */ |
976 | IMX_PIN_REG(MX51_PAD_EIM_DA15, NO_PAD, 0x058, 0, 0x000, 0), /* MX51_PAD_EIM_DA15__EIM_DA15 */ | 976 | IMX_PIN_REG(MX51_PAD_EIM_DA15, NO_PAD, 0x058, 0, 0x000, 0), /* MX51_PAD_EIM_DA15__EIM_DA15 */ |
977 | IMX_PIN_REG(MX51_PAD_SD2_CMD, NO_PAD, 0x3b4, 2, 0x91c, 3), /* MX51_PAD_SD2_CMD__CSPI_MOSI */ | 977 | IMX_PIN_REG(MX51_PAD_SD2_CMD, 0x7bc, 0x3b4, 2, 0x91c, 3), /* MX51_PAD_SD2_CMD__CSPI_MOSI */ |
978 | IMX_PIN_REG(MX51_PAD_SD2_CMD, 0x7bc, 0x3b4, 1, 0x9b0, 2), /* MX51_PAD_SD2_CMD__I2C1_SCL */ | 978 | IMX_PIN_REG(MX51_PAD_SD2_CMD, 0x7bc, 0x3b4, 1, 0x9b0, 2), /* MX51_PAD_SD2_CMD__I2C1_SCL */ |
979 | IMX_PIN_REG(MX51_PAD_SD2_CMD, 0x7bc, 0x3b4, 0, 0x000, 0), /* MX51_PAD_SD2_CMD__SD2_CMD */ | 979 | IMX_PIN_REG(MX51_PAD_SD2_CMD, 0x7bc, 0x3b4, 0, 0x000, 0), /* MX51_PAD_SD2_CMD__SD2_CMD */ |
980 | IMX_PIN_REG(MX51_PAD_SD2_CLK, 0x7c0, 0x3b8, 2, 0x914, 3), /* MX51_PAD_SD2_CLK__CSPI_SCLK */ | 980 | IMX_PIN_REG(MX51_PAD_SD2_CLK, 0x7c0, 0x3b8, 2, 0x914, 3), /* MX51_PAD_SD2_CLK__CSPI_SCLK */ |
diff --git a/drivers/pinctrl/pinctrl-nomadik-db8500.c b/drivers/pinctrl/pinctrl-nomadik-db8500.c index 6f99769c6733..a39fb7a6fc51 100644 --- a/drivers/pinctrl/pinctrl-nomadik-db8500.c +++ b/drivers/pinctrl/pinctrl-nomadik-db8500.c | |||
@@ -505,6 +505,8 @@ static const unsigned kp_b_1_pins[] = { DB8500_PIN_F3, DB8500_PIN_F1, | |||
505 | DB8500_PIN_J3, DB8500_PIN_H2, DB8500_PIN_J2, DB8500_PIN_H1, | 505 | DB8500_PIN_J3, DB8500_PIN_H2, DB8500_PIN_J2, DB8500_PIN_H1, |
506 | DB8500_PIN_F4, DB8500_PIN_E3, DB8500_PIN_E4, DB8500_PIN_D2, | 506 | DB8500_PIN_F4, DB8500_PIN_E3, DB8500_PIN_E4, DB8500_PIN_D2, |
507 | DB8500_PIN_C1, DB8500_PIN_D3, DB8500_PIN_C2, DB8500_PIN_D5 }; | 507 | DB8500_PIN_C1, DB8500_PIN_D3, DB8500_PIN_C2, DB8500_PIN_D5 }; |
508 | static const unsigned kp_b_2_pins[] = { DB8500_PIN_F3, DB8500_PIN_F1, | ||
509 | DB8500_PIN_G3, DB8500_PIN_G2, DB8500_PIN_F4, DB8500_PIN_E3}; | ||
508 | static const unsigned sm_b_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3, | 510 | static const unsigned sm_b_1_pins[] = { DB8500_PIN_C6, DB8500_PIN_B3, |
509 | DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6, | 511 | DB8500_PIN_C4, DB8500_PIN_E6, DB8500_PIN_A3, DB8500_PIN_B6, |
510 | DB8500_PIN_D6, DB8500_PIN_B7, DB8500_PIN_D7, DB8500_PIN_D8, | 512 | DB8500_PIN_D6, DB8500_PIN_B7, DB8500_PIN_D7, DB8500_PIN_D8, |
@@ -662,6 +664,7 @@ static const struct nmk_pingroup nmk_db8500_groups[] = { | |||
662 | DB8500_PIN_GROUP(spi3_b_1, NMK_GPIO_ALT_B), | 664 | DB8500_PIN_GROUP(spi3_b_1, NMK_GPIO_ALT_B), |
663 | DB8500_PIN_GROUP(msp1txrx_b_1, NMK_GPIO_ALT_B), | 665 | DB8500_PIN_GROUP(msp1txrx_b_1, NMK_GPIO_ALT_B), |
664 | DB8500_PIN_GROUP(kp_b_1, NMK_GPIO_ALT_B), | 666 | DB8500_PIN_GROUP(kp_b_1, NMK_GPIO_ALT_B), |
667 | DB8500_PIN_GROUP(kp_b_2, NMK_GPIO_ALT_B), | ||
665 | DB8500_PIN_GROUP(sm_b_1, NMK_GPIO_ALT_B), | 668 | DB8500_PIN_GROUP(sm_b_1, NMK_GPIO_ALT_B), |
666 | DB8500_PIN_GROUP(smcs0_b_1, NMK_GPIO_ALT_B), | 669 | DB8500_PIN_GROUP(smcs0_b_1, NMK_GPIO_ALT_B), |
667 | DB8500_PIN_GROUP(smcs1_b_1, NMK_GPIO_ALT_B), | 670 | DB8500_PIN_GROUP(smcs1_b_1, NMK_GPIO_ALT_B), |
@@ -751,7 +754,7 @@ DB8500_FUNC_GROUPS(msp1, "msp1txrx_a_1", "msp1_a_1", "msp1txrx_b_1"); | |||
751 | DB8500_FUNC_GROUPS(lcdb, "lcdb_a_1"); | 754 | DB8500_FUNC_GROUPS(lcdb, "lcdb_a_1"); |
752 | DB8500_FUNC_GROUPS(lcd, "lcdvsi0_a_1", "lcdvsi1_a_1", "lcd_d0_d7_a_1", | 755 | DB8500_FUNC_GROUPS(lcd, "lcdvsi0_a_1", "lcdvsi1_a_1", "lcd_d0_d7_a_1", |
753 | "lcd_d8_d11_a_1", "lcd_d12_d23_a_1", "lcd_b_1"); | 756 | "lcd_d8_d11_a_1", "lcd_d12_d23_a_1", "lcd_b_1"); |
754 | DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_b_1", "kp_c_1", "kp_oc1_1"); | 757 | DB8500_FUNC_GROUPS(kp, "kp_a_1", "kp_b_1", "kp_b_2", "kp_c_1", "kp_oc1_1"); |
755 | DB8500_FUNC_GROUPS(mc2, "mc2_a_1", "mc2rstn_c_1"); | 758 | DB8500_FUNC_GROUPS(mc2, "mc2_a_1", "mc2rstn_c_1"); |
756 | DB8500_FUNC_GROUPS(ssp1, "ssp1_a_1"); | 759 | DB8500_FUNC_GROUPS(ssp1, "ssp1_a_1"); |
757 | DB8500_FUNC_GROUPS(ssp0, "ssp0_a_1"); | 760 | DB8500_FUNC_GROUPS(ssp0, "ssp0_a_1"); |
@@ -766,7 +769,7 @@ DB8500_FUNC_GROUPS(ipgpio, "ipgpio0_a_1", "ipgpio1_a_1", "ipgpio7_b_1", | |||
766 | DB8500_FUNC_GROUPS(msp2, "msp2sck_a_1", "msp2_a_1"); | 769 | DB8500_FUNC_GROUPS(msp2, "msp2sck_a_1", "msp2_a_1"); |
767 | DB8500_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1"); | 770 | DB8500_FUNC_GROUPS(mc4, "mc4_a_1", "mc4rstn_c_1"); |
768 | DB8500_FUNC_GROUPS(mc1, "mc1_a_1", "mc1dir_a_1"); | 771 | DB8500_FUNC_GROUPS(mc1, "mc1_a_1", "mc1dir_a_1"); |
769 | DB8500_FUNC_GROUPS(hsi, "hsir1_a_1", "hsit1_a_1", "hsit_a_2"); | 772 | DB8500_FUNC_GROUPS(hsi, "hsir_a_1", "hsit_a_1", "hsit_a_2"); |
770 | DB8500_FUNC_GROUPS(clkout, "clkout_a_1", "clkout_a_2", "clkout_c_1"); | 773 | DB8500_FUNC_GROUPS(clkout, "clkout_a_1", "clkout_a_2", "clkout_c_1"); |
771 | DB8500_FUNC_GROUPS(usb, "usb_a_1"); | 774 | DB8500_FUNC_GROUPS(usb, "usb_a_1"); |
772 | DB8500_FUNC_GROUPS(trig, "trig_b_1"); | 775 | DB8500_FUNC_GROUPS(trig, "trig_b_1"); |
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c index 53b0d49a7a1c..3dde6537adb8 100644 --- a/drivers/pinctrl/pinctrl-nomadik.c +++ b/drivers/pinctrl/pinctrl-nomadik.c | |||
@@ -1292,7 +1292,7 @@ static int __devinit nmk_gpio_probe(struct platform_device *dev) | |||
1292 | NOMADIK_GPIO_TO_IRQ(pdata->first_gpio), | 1292 | NOMADIK_GPIO_TO_IRQ(pdata->first_gpio), |
1293 | 0, &nmk_gpio_irq_simple_ops, nmk_chip); | 1293 | 0, &nmk_gpio_irq_simple_ops, nmk_chip); |
1294 | if (!nmk_chip->domain) { | 1294 | if (!nmk_chip->domain) { |
1295 | pr_err("%s: Failed to create irqdomain\n", np->full_name); | 1295 | dev_err(&dev->dev, "failed to create irqdomain\n"); |
1296 | ret = -ENOSYS; | 1296 | ret = -ENOSYS; |
1297 | goto out; | 1297 | goto out; |
1298 | } | 1298 | } |
@@ -1731,7 +1731,6 @@ static int __devinit nmk_pinctrl_probe(struct platform_device *pdev) | |||
1731 | for (i = 0; i < npct->soc->gpio_num_ranges; i++) { | 1731 | for (i = 0; i < npct->soc->gpio_num_ranges; i++) { |
1732 | if (!nmk_gpio_chips[i]) { | 1732 | if (!nmk_gpio_chips[i]) { |
1733 | dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i); | 1733 | dev_warn(&pdev->dev, "GPIO chip %d not registered yet\n", i); |
1734 | devm_kfree(&pdev->dev, npct); | ||
1735 | return -EPROBE_DEFER; | 1734 | return -EPROBE_DEFER; |
1736 | } | 1735 | } |
1737 | npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[i]->chip; | 1736 | npct->soc->gpio_ranges[i].gc = &nmk_gpio_chips[i]->chip; |
diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c index 2aae8a8978e9..7fca6ce5952b 100644 --- a/drivers/pinctrl/pinctrl-sirf.c +++ b/drivers/pinctrl/pinctrl-sirf.c | |||
@@ -1217,7 +1217,6 @@ out_no_rsc_remap: | |||
1217 | iounmap(spmx->gpio_virtbase); | 1217 | iounmap(spmx->gpio_virtbase); |
1218 | out_no_gpio_remap: | 1218 | out_no_gpio_remap: |
1219 | platform_set_drvdata(pdev, NULL); | 1219 | platform_set_drvdata(pdev, NULL); |
1220 | devm_kfree(&pdev->dev, spmx); | ||
1221 | return ret; | 1220 | return ret; |
1222 | } | 1221 | } |
1223 | 1222 | ||
diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index a7ad8c112d91..309f5b9a70ec 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c | |||
@@ -1121,10 +1121,8 @@ static int __devinit u300_pmx_probe(struct platform_device *pdev) | |||
1121 | upmx->dev = &pdev->dev; | 1121 | upmx->dev = &pdev->dev; |
1122 | 1122 | ||
1123 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1123 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1124 | if (!res) { | 1124 | if (!res) |
1125 | ret = -ENOENT; | 1125 | return -ENOENT; |
1126 | goto out_no_resource; | ||
1127 | } | ||
1128 | upmx->phybase = res->start; | 1126 | upmx->phybase = res->start; |
1129 | upmx->physize = resource_size(res); | 1127 | upmx->physize = resource_size(res); |
1130 | 1128 | ||
@@ -1165,8 +1163,6 @@ out_no_remap: | |||
1165 | platform_set_drvdata(pdev, NULL); | 1163 | platform_set_drvdata(pdev, NULL); |
1166 | out_no_memregion: | 1164 | out_no_memregion: |
1167 | release_mem_region(upmx->phybase, upmx->physize); | 1165 | release_mem_region(upmx->phybase, upmx->physize); |
1168 | out_no_resource: | ||
1169 | devm_kfree(&pdev->dev, upmx); | ||
1170 | return ret; | 1166 | return ret; |
1171 | } | 1167 | } |
1172 | 1168 | ||
diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile index 782953ae4c03..b17c16ce54ad 100644 --- a/drivers/platform/Makefile +++ b/drivers/platform/Makefile | |||
@@ -3,3 +3,4 @@ | |||
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_X86) += x86/ | 5 | obj-$(CONFIG_X86) += x86/ |
6 | obj-$(CONFIG_OLPC) += olpc/ | ||
diff --git a/drivers/platform/olpc/Makefile b/drivers/platform/olpc/Makefile new file mode 100644 index 000000000000..dc8b26bc7209 --- /dev/null +++ b/drivers/platform/olpc/Makefile | |||
@@ -0,0 +1,4 @@ | |||
1 | # | ||
2 | # OLPC XO platform-specific drivers | ||
3 | # | ||
4 | obj-$(CONFIG_OLPC) += olpc-ec.o | ||
diff --git a/drivers/platform/olpc/olpc-ec.c b/drivers/platform/olpc/olpc-ec.c new file mode 100644 index 000000000000..0f9f8596b300 --- /dev/null +++ b/drivers/platform/olpc/olpc-ec.c | |||
@@ -0,0 +1,336 @@ | |||
1 | /* | ||
2 | * Generic driver for the OLPC Embedded Controller. | ||
3 | * | ||
4 | * Copyright (C) 2011-2012 One Laptop per Child Foundation. | ||
5 | * | ||
6 | * Licensed under the GPL v2 or later. | ||
7 | */ | ||
8 | #include <linux/completion.h> | ||
9 | #include <linux/debugfs.h> | ||
10 | #include <linux/spinlock.h> | ||
11 | #include <linux/mutex.h> | ||
12 | #include <linux/platform_device.h> | ||
13 | #include <linux/slab.h> | ||
14 | #include <linux/workqueue.h> | ||
15 | #include <linux/module.h> | ||
16 | #include <linux/list.h> | ||
17 | #include <linux/olpc-ec.h> | ||
18 | #include <asm/olpc.h> | ||
19 | |||
20 | struct ec_cmd_desc { | ||
21 | u8 cmd; | ||
22 | u8 *inbuf, *outbuf; | ||
23 | size_t inlen, outlen; | ||
24 | |||
25 | int err; | ||
26 | struct completion finished; | ||
27 | struct list_head node; | ||
28 | |||
29 | void *priv; | ||
30 | }; | ||
31 | |||
32 | struct olpc_ec_priv { | ||
33 | struct olpc_ec_driver *drv; | ||
34 | struct work_struct worker; | ||
35 | struct mutex cmd_lock; | ||
36 | |||
37 | /* Pending EC commands */ | ||
38 | struct list_head cmd_q; | ||
39 | spinlock_t cmd_q_lock; | ||
40 | |||
41 | struct dentry *dbgfs_dir; | ||
42 | |||
43 | /* | ||
44 | * Running an EC command while suspending means we don't always finish | ||
45 | * the command before the machine suspends. This means that the EC | ||
46 | * is expecting the command protocol to finish, but we after a period | ||
47 | * of time (while the OS is asleep) the EC times out and restarts its | ||
48 | * idle loop. Meanwhile, the OS wakes up, thinks it's still in the | ||
49 | * middle of the command protocol, starts throwing random things at | ||
50 | * the EC... and everyone's uphappy. | ||
51 | */ | ||
52 | bool suspended; | ||
53 | }; | ||
54 | |||
55 | static struct olpc_ec_driver *ec_driver; | ||
56 | static struct olpc_ec_priv *ec_priv; | ||
57 | static void *ec_cb_arg; | ||
58 | |||
59 | void olpc_ec_driver_register(struct olpc_ec_driver *drv, void *arg) | ||
60 | { | ||
61 | ec_driver = drv; | ||
62 | ec_cb_arg = arg; | ||
63 | } | ||
64 | EXPORT_SYMBOL_GPL(olpc_ec_driver_register); | ||
65 | |||
66 | static void olpc_ec_worker(struct work_struct *w) | ||
67 | { | ||
68 | struct olpc_ec_priv *ec = container_of(w, struct olpc_ec_priv, worker); | ||
69 | struct ec_cmd_desc *desc = NULL; | ||
70 | unsigned long flags; | ||
71 | |||
72 | /* Grab the first pending command from the queue */ | ||
73 | spin_lock_irqsave(&ec->cmd_q_lock, flags); | ||
74 | if (!list_empty(&ec->cmd_q)) { | ||
75 | desc = list_first_entry(&ec->cmd_q, struct ec_cmd_desc, node); | ||
76 | list_del(&desc->node); | ||
77 | } | ||
78 | spin_unlock_irqrestore(&ec->cmd_q_lock, flags); | ||
79 | |||
80 | /* Do we actually have anything to do? */ | ||
81 | if (!desc) | ||
82 | return; | ||
83 | |||
84 | /* Protect the EC hw with a mutex; only run one cmd at a time */ | ||
85 | mutex_lock(&ec->cmd_lock); | ||
86 | desc->err = ec_driver->ec_cmd(desc->cmd, desc->inbuf, desc->inlen, | ||
87 | desc->outbuf, desc->outlen, ec_cb_arg); | ||
88 | mutex_unlock(&ec->cmd_lock); | ||
89 | |||
90 | /* Finished, wake up olpc_ec_cmd() */ | ||
91 | complete(&desc->finished); | ||
92 | |||
93 | /* Run the worker thread again in case there are more cmds pending */ | ||
94 | schedule_work(&ec->worker); | ||
95 | } | ||
96 | |||
97 | /* | ||
98 | * Throw a cmd descripter onto the list. We now have SMP OLPC machines, so | ||
99 | * locking is pretty critical. | ||
100 | */ | ||
101 | static void queue_ec_descriptor(struct ec_cmd_desc *desc, | ||
102 | struct olpc_ec_priv *ec) | ||
103 | { | ||
104 | unsigned long flags; | ||
105 | |||
106 | INIT_LIST_HEAD(&desc->node); | ||
107 | |||
108 | spin_lock_irqsave(&ec->cmd_q_lock, flags); | ||
109 | list_add_tail(&desc->node, &ec->cmd_q); | ||
110 | spin_unlock_irqrestore(&ec->cmd_q_lock, flags); | ||
111 | |||
112 | schedule_work(&ec->worker); | ||
113 | } | ||
114 | |||
115 | int olpc_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *outbuf, size_t outlen) | ||
116 | { | ||
117 | struct olpc_ec_priv *ec = ec_priv; | ||
118 | struct ec_cmd_desc desc; | ||
119 | |||
120 | /* Ensure a driver and ec hook have been registered */ | ||
121 | if (WARN_ON(!ec_driver || !ec_driver->ec_cmd)) | ||
122 | return -ENODEV; | ||
123 | |||
124 | if (!ec) | ||
125 | return -ENOMEM; | ||
126 | |||
127 | /* Suspending in the middle of a command hoses things really badly */ | ||
128 | if (WARN_ON(ec->suspended)) | ||
129 | return -EBUSY; | ||
130 | |||
131 | might_sleep(); | ||
132 | |||
133 | desc.cmd = cmd; | ||
134 | desc.inbuf = inbuf; | ||
135 | desc.outbuf = outbuf; | ||
136 | desc.inlen = inlen; | ||
137 | desc.outlen = outlen; | ||
138 | desc.err = 0; | ||
139 | init_completion(&desc.finished); | ||
140 | |||
141 | queue_ec_descriptor(&desc, ec); | ||
142 | |||
143 | /* Timeouts must be handled in the platform-specific EC hook */ | ||
144 | wait_for_completion(&desc.finished); | ||
145 | |||
146 | /* The worker thread dequeues the cmd; no need to do anything here */ | ||
147 | return desc.err; | ||
148 | } | ||
149 | EXPORT_SYMBOL_GPL(olpc_ec_cmd); | ||
150 | |||
151 | #ifdef CONFIG_DEBUG_FS | ||
152 | |||
153 | /* | ||
154 | * debugfs support for "generic commands", to allow sending | ||
155 | * arbitrary EC commands from userspace. | ||
156 | */ | ||
157 | |||
158 | #define EC_MAX_CMD_ARGS (5 + 1) /* cmd byte + 5 args */ | ||
159 | #define EC_MAX_CMD_REPLY (8) | ||
160 | |||
161 | static DEFINE_MUTEX(ec_dbgfs_lock); | ||
162 | static unsigned char ec_dbgfs_resp[EC_MAX_CMD_REPLY]; | ||
163 | static unsigned int ec_dbgfs_resp_bytes; | ||
164 | |||
165 | static ssize_t ec_dbgfs_cmd_write(struct file *file, const char __user *buf, | ||
166 | size_t size, loff_t *ppos) | ||
167 | { | ||
168 | int i, m; | ||
169 | unsigned char ec_cmd[EC_MAX_CMD_ARGS]; | ||
170 | unsigned int ec_cmd_int[EC_MAX_CMD_ARGS]; | ||
171 | char cmdbuf[64]; | ||
172 | int ec_cmd_bytes; | ||
173 | |||
174 | mutex_lock(&ec_dbgfs_lock); | ||
175 | |||
176 | size = simple_write_to_buffer(cmdbuf, sizeof(cmdbuf), ppos, buf, size); | ||
177 | |||
178 | m = sscanf(cmdbuf, "%x:%u %x %x %x %x %x", &ec_cmd_int[0], | ||
179 | &ec_dbgfs_resp_bytes, &ec_cmd_int[1], &ec_cmd_int[2], | ||
180 | &ec_cmd_int[3], &ec_cmd_int[4], &ec_cmd_int[5]); | ||
181 | if (m < 2 || ec_dbgfs_resp_bytes > EC_MAX_CMD_REPLY) { | ||
182 | /* reset to prevent overflow on read */ | ||
183 | ec_dbgfs_resp_bytes = 0; | ||
184 | |||
185 | pr_debug("olpc-ec: bad ec cmd: cmd:response-count [arg1 [arg2 ...]]\n"); | ||
186 | size = -EINVAL; | ||
187 | goto out; | ||
188 | } | ||
189 | |||
190 | /* convert scanf'd ints to char */ | ||
191 | ec_cmd_bytes = m - 2; | ||
192 | for (i = 0; i <= ec_cmd_bytes; i++) | ||
193 | ec_cmd[i] = ec_cmd_int[i]; | ||
194 | |||
195 | pr_debug("olpc-ec: debugfs cmd 0x%02x with %d args %02x %02x %02x %02x %02x, want %d returns\n", | ||
196 | ec_cmd[0], ec_cmd_bytes, ec_cmd[1], ec_cmd[2], | ||
197 | ec_cmd[3], ec_cmd[4], ec_cmd[5], ec_dbgfs_resp_bytes); | ||
198 | |||
199 | olpc_ec_cmd(ec_cmd[0], (ec_cmd_bytes == 0) ? NULL : &ec_cmd[1], | ||
200 | ec_cmd_bytes, ec_dbgfs_resp, ec_dbgfs_resp_bytes); | ||
201 | |||
202 | pr_debug("olpc-ec: response %02x %02x %02x %02x %02x %02x %02x %02x (%d bytes expected)\n", | ||
203 | ec_dbgfs_resp[0], ec_dbgfs_resp[1], ec_dbgfs_resp[2], | ||
204 | ec_dbgfs_resp[3], ec_dbgfs_resp[4], ec_dbgfs_resp[5], | ||
205 | ec_dbgfs_resp[6], ec_dbgfs_resp[7], | ||
206 | ec_dbgfs_resp_bytes); | ||
207 | |||
208 | out: | ||
209 | mutex_unlock(&ec_dbgfs_lock); | ||
210 | return size; | ||
211 | } | ||
212 | |||
213 | static ssize_t ec_dbgfs_cmd_read(struct file *file, char __user *buf, | ||
214 | size_t size, loff_t *ppos) | ||
215 | { | ||
216 | unsigned int i, r; | ||
217 | char *rp; | ||
218 | char respbuf[64]; | ||
219 | |||
220 | mutex_lock(&ec_dbgfs_lock); | ||
221 | rp = respbuf; | ||
222 | rp += sprintf(rp, "%02x", ec_dbgfs_resp[0]); | ||
223 | for (i = 1; i < ec_dbgfs_resp_bytes; i++) | ||
224 | rp += sprintf(rp, ", %02x", ec_dbgfs_resp[i]); | ||
225 | mutex_unlock(&ec_dbgfs_lock); | ||
226 | rp += sprintf(rp, "\n"); | ||
227 | |||
228 | r = rp - respbuf; | ||
229 | return simple_read_from_buffer(buf, size, ppos, respbuf, r); | ||
230 | } | ||
231 | |||
232 | static const struct file_operations ec_dbgfs_ops = { | ||
233 | .write = ec_dbgfs_cmd_write, | ||
234 | .read = ec_dbgfs_cmd_read, | ||
235 | }; | ||
236 | |||
237 | static struct dentry *olpc_ec_setup_debugfs(void) | ||
238 | { | ||
239 | struct dentry *dbgfs_dir; | ||
240 | |||
241 | dbgfs_dir = debugfs_create_dir("olpc-ec", NULL); | ||
242 | if (IS_ERR_OR_NULL(dbgfs_dir)) | ||
243 | return NULL; | ||
244 | |||
245 | debugfs_create_file("cmd", 0600, dbgfs_dir, NULL, &ec_dbgfs_ops); | ||
246 | |||
247 | return dbgfs_dir; | ||
248 | } | ||
249 | |||
250 | #else | ||
251 | |||
252 | static struct dentry *olpc_ec_setup_debugfs(void) | ||
253 | { | ||
254 | return NULL; | ||
255 | } | ||
256 | |||
257 | #endif /* CONFIG_DEBUG_FS */ | ||
258 | |||
259 | static int olpc_ec_probe(struct platform_device *pdev) | ||
260 | { | ||
261 | struct olpc_ec_priv *ec; | ||
262 | int err; | ||
263 | |||
264 | if (!ec_driver) | ||
265 | return -ENODEV; | ||
266 | |||
267 | ec = kzalloc(sizeof(*ec), GFP_KERNEL); | ||
268 | if (!ec) | ||
269 | return -ENOMEM; | ||
270 | |||
271 | ec->drv = ec_driver; | ||
272 | INIT_WORK(&ec->worker, olpc_ec_worker); | ||
273 | mutex_init(&ec->cmd_lock); | ||
274 | |||
275 | INIT_LIST_HEAD(&ec->cmd_q); | ||
276 | spin_lock_init(&ec->cmd_q_lock); | ||
277 | |||
278 | ec_priv = ec; | ||
279 | platform_set_drvdata(pdev, ec); | ||
280 | |||
281 | err = ec_driver->probe ? ec_driver->probe(pdev) : 0; | ||
282 | if (err) { | ||
283 | ec_priv = NULL; | ||
284 | kfree(ec); | ||
285 | } else { | ||
286 | ec->dbgfs_dir = olpc_ec_setup_debugfs(); | ||
287 | } | ||
288 | |||
289 | return err; | ||
290 | } | ||
291 | |||
292 | static int olpc_ec_suspend(struct device *dev) | ||
293 | { | ||
294 | struct platform_device *pdev = to_platform_device(dev); | ||
295 | struct olpc_ec_priv *ec = platform_get_drvdata(pdev); | ||
296 | int err = 0; | ||
297 | |||
298 | if (ec_driver->suspend) | ||
299 | err = ec_driver->suspend(pdev); | ||
300 | if (!err) | ||
301 | ec->suspended = true; | ||
302 | |||
303 | return err; | ||
304 | } | ||
305 | |||
306 | static int olpc_ec_resume(struct device *dev) | ||
307 | { | ||
308 | struct platform_device *pdev = to_platform_device(dev); | ||
309 | struct olpc_ec_priv *ec = platform_get_drvdata(pdev); | ||
310 | |||
311 | ec->suspended = false; | ||
312 | return ec_driver->resume ? ec_driver->resume(pdev) : 0; | ||
313 | } | ||
314 | |||
315 | static const struct dev_pm_ops olpc_ec_pm_ops = { | ||
316 | .suspend_late = olpc_ec_suspend, | ||
317 | .resume_early = olpc_ec_resume, | ||
318 | }; | ||
319 | |||
320 | static struct platform_driver olpc_ec_plat_driver = { | ||
321 | .probe = olpc_ec_probe, | ||
322 | .driver = { | ||
323 | .name = "olpc-ec", | ||
324 | .pm = &olpc_ec_pm_ops, | ||
325 | }, | ||
326 | }; | ||
327 | |||
328 | static int __init olpc_ec_init_module(void) | ||
329 | { | ||
330 | return platform_driver_register(&olpc_ec_plat_driver); | ||
331 | } | ||
332 | |||
333 | module_init(olpc_ec_init_module); | ||
334 | |||
335 | MODULE_AUTHOR("Andres Salomon <dilinger@queued.net>"); | ||
336 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/platform/x86/Kconfig b/drivers/platform/x86/Kconfig index 2a262f5c5c0c..c86bae828c28 100644 --- a/drivers/platform/x86/Kconfig +++ b/drivers/platform/x86/Kconfig | |||
@@ -289,6 +289,7 @@ config IDEAPAD_LAPTOP | |||
289 | tristate "Lenovo IdeaPad Laptop Extras" | 289 | tristate "Lenovo IdeaPad Laptop Extras" |
290 | depends on ACPI | 290 | depends on ACPI |
291 | depends on RFKILL && INPUT | 291 | depends on RFKILL && INPUT |
292 | depends on SERIO_I8042 | ||
292 | select INPUT_SPARSEKMAP | 293 | select INPUT_SPARSEKMAP |
293 | help | 294 | help |
294 | This is a driver for the rfkill switches on Lenovo IdeaPad netbooks. | 295 | This is a driver for the rfkill switches on Lenovo IdeaPad netbooks. |
@@ -758,8 +759,11 @@ config SAMSUNG_Q10 | |||
758 | 759 | ||
759 | config APPLE_GMUX | 760 | config APPLE_GMUX |
760 | tristate "Apple Gmux Driver" | 761 | tristate "Apple Gmux Driver" |
762 | depends on ACPI | ||
761 | depends on PNP | 763 | depends on PNP |
762 | select BACKLIGHT_CLASS_DEVICE | 764 | depends on BACKLIGHT_CLASS_DEVICE |
765 | depends on BACKLIGHT_APPLE=n || BACKLIGHT_APPLE | ||
766 | depends on ACPI_VIDEO=n || ACPI_VIDEO | ||
763 | ---help--- | 767 | ---help--- |
764 | This driver provides support for the gmux device found on many | 768 | This driver provides support for the gmux device found on many |
765 | Apple laptops, which controls the display mux for the hybrid | 769 | Apple laptops, which controls the display mux for the hybrid |
diff --git a/drivers/platform/x86/apple-gmux.c b/drivers/platform/x86/apple-gmux.c index 905fa01ac8df..dfb1a92ce949 100644 --- a/drivers/platform/x86/apple-gmux.c +++ b/drivers/platform/x86/apple-gmux.c | |||
@@ -2,6 +2,7 @@ | |||
2 | * Gmux driver for Apple laptops | 2 | * Gmux driver for Apple laptops |
3 | * | 3 | * |
4 | * Copyright (C) Canonical Ltd. <seth.forshee@canonical.com> | 4 | * Copyright (C) Canonical Ltd. <seth.forshee@canonical.com> |
5 | * Copyright (C) 2010-2012 Andreas Heider <andreas@meetr.de> | ||
5 | * | 6 | * |
6 | * This program is free software; you can redistribute it and/or modify | 7 | * This program is free software; you can redistribute it and/or modify |
7 | * it under the terms of the GNU General Public License version 2 as | 8 | * it under the terms of the GNU General Public License version 2 as |
@@ -18,16 +19,30 @@ | |||
18 | #include <linux/pnp.h> | 19 | #include <linux/pnp.h> |
19 | #include <linux/apple_bl.h> | 20 | #include <linux/apple_bl.h> |
20 | #include <linux/slab.h> | 21 | #include <linux/slab.h> |
22 | #include <linux/delay.h> | ||
23 | #include <linux/pci.h> | ||
24 | #include <linux/vga_switcheroo.h> | ||
21 | #include <acpi/video.h> | 25 | #include <acpi/video.h> |
22 | #include <asm/io.h> | 26 | #include <asm/io.h> |
23 | 27 | ||
24 | struct apple_gmux_data { | 28 | struct apple_gmux_data { |
25 | unsigned long iostart; | 29 | unsigned long iostart; |
26 | unsigned long iolen; | 30 | unsigned long iolen; |
31 | bool indexed; | ||
32 | struct mutex index_lock; | ||
27 | 33 | ||
28 | struct backlight_device *bdev; | 34 | struct backlight_device *bdev; |
35 | |||
36 | /* switcheroo data */ | ||
37 | acpi_handle dhandle; | ||
38 | int gpe; | ||
39 | enum vga_switcheroo_client_id resume_client_id; | ||
40 | enum vga_switcheroo_state power_state; | ||
41 | struct completion powerchange_done; | ||
29 | }; | 42 | }; |
30 | 43 | ||
44 | static struct apple_gmux_data *apple_gmux_data; | ||
45 | |||
31 | /* | 46 | /* |
32 | * gmux port offsets. Many of these are not yet used, but may be in the | 47 | * gmux port offsets. Many of these are not yet used, but may be in the |
33 | * future, and it's useful to have them documented here anyhow. | 48 | * future, and it's useful to have them documented here anyhow. |
@@ -45,6 +60,9 @@ struct apple_gmux_data { | |||
45 | #define GMUX_PORT_DISCRETE_POWER 0x50 | 60 | #define GMUX_PORT_DISCRETE_POWER 0x50 |
46 | #define GMUX_PORT_MAX_BRIGHTNESS 0x70 | 61 | #define GMUX_PORT_MAX_BRIGHTNESS 0x70 |
47 | #define GMUX_PORT_BRIGHTNESS 0x74 | 62 | #define GMUX_PORT_BRIGHTNESS 0x74 |
63 | #define GMUX_PORT_VALUE 0xc2 | ||
64 | #define GMUX_PORT_READ 0xd0 | ||
65 | #define GMUX_PORT_WRITE 0xd4 | ||
48 | 66 | ||
49 | #define GMUX_MIN_IO_LEN (GMUX_PORT_BRIGHTNESS + 4) | 67 | #define GMUX_MIN_IO_LEN (GMUX_PORT_BRIGHTNESS + 4) |
50 | 68 | ||
@@ -59,22 +77,172 @@ struct apple_gmux_data { | |||
59 | #define GMUX_BRIGHTNESS_MASK 0x00ffffff | 77 | #define GMUX_BRIGHTNESS_MASK 0x00ffffff |
60 | #define GMUX_MAX_BRIGHTNESS GMUX_BRIGHTNESS_MASK | 78 | #define GMUX_MAX_BRIGHTNESS GMUX_BRIGHTNESS_MASK |
61 | 79 | ||
62 | static inline u8 gmux_read8(struct apple_gmux_data *gmux_data, int port) | 80 | static u8 gmux_pio_read8(struct apple_gmux_data *gmux_data, int port) |
63 | { | 81 | { |
64 | return inb(gmux_data->iostart + port); | 82 | return inb(gmux_data->iostart + port); |
65 | } | 83 | } |
66 | 84 | ||
67 | static inline void gmux_write8(struct apple_gmux_data *gmux_data, int port, | 85 | static void gmux_pio_write8(struct apple_gmux_data *gmux_data, int port, |
68 | u8 val) | 86 | u8 val) |
69 | { | 87 | { |
70 | outb(val, gmux_data->iostart + port); | 88 | outb(val, gmux_data->iostart + port); |
71 | } | 89 | } |
72 | 90 | ||
73 | static inline u32 gmux_read32(struct apple_gmux_data *gmux_data, int port) | 91 | static u32 gmux_pio_read32(struct apple_gmux_data *gmux_data, int port) |
74 | { | 92 | { |
75 | return inl(gmux_data->iostart + port); | 93 | return inl(gmux_data->iostart + port); |
76 | } | 94 | } |
77 | 95 | ||
96 | static void gmux_pio_write32(struct apple_gmux_data *gmux_data, int port, | ||
97 | u32 val) | ||
98 | { | ||
99 | int i; | ||
100 | u8 tmpval; | ||
101 | |||
102 | for (i = 0; i < 4; i++) { | ||
103 | tmpval = (val >> (i * 8)) & 0xff; | ||
104 | outb(tmpval, port + i); | ||
105 | } | ||
106 | } | ||
107 | |||
108 | static int gmux_index_wait_ready(struct apple_gmux_data *gmux_data) | ||
109 | { | ||
110 | int i = 200; | ||
111 | u8 gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); | ||
112 | |||
113 | while (i && (gwr & 0x01)) { | ||
114 | inb(gmux_data->iostart + GMUX_PORT_READ); | ||
115 | gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); | ||
116 | udelay(100); | ||
117 | i--; | ||
118 | } | ||
119 | |||
120 | return !!i; | ||
121 | } | ||
122 | |||
123 | static int gmux_index_wait_complete(struct apple_gmux_data *gmux_data) | ||
124 | { | ||
125 | int i = 200; | ||
126 | u8 gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); | ||
127 | |||
128 | while (i && !(gwr & 0x01)) { | ||
129 | gwr = inb(gmux_data->iostart + GMUX_PORT_WRITE); | ||
130 | udelay(100); | ||
131 | i--; | ||
132 | } | ||
133 | |||
134 | if (gwr & 0x01) | ||
135 | inb(gmux_data->iostart + GMUX_PORT_READ); | ||
136 | |||
137 | return !!i; | ||
138 | } | ||
139 | |||
140 | static u8 gmux_index_read8(struct apple_gmux_data *gmux_data, int port) | ||
141 | { | ||
142 | u8 val; | ||
143 | |||
144 | mutex_lock(&gmux_data->index_lock); | ||
145 | outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); | ||
146 | gmux_index_wait_ready(gmux_data); | ||
147 | val = inb(gmux_data->iostart + GMUX_PORT_VALUE); | ||
148 | mutex_unlock(&gmux_data->index_lock); | ||
149 | |||
150 | return val; | ||
151 | } | ||
152 | |||
153 | static void gmux_index_write8(struct apple_gmux_data *gmux_data, int port, | ||
154 | u8 val) | ||
155 | { | ||
156 | mutex_lock(&gmux_data->index_lock); | ||
157 | outb(val, gmux_data->iostart + GMUX_PORT_VALUE); | ||
158 | gmux_index_wait_ready(gmux_data); | ||
159 | outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE); | ||
160 | gmux_index_wait_complete(gmux_data); | ||
161 | mutex_unlock(&gmux_data->index_lock); | ||
162 | } | ||
163 | |||
164 | static u32 gmux_index_read32(struct apple_gmux_data *gmux_data, int port) | ||
165 | { | ||
166 | u32 val; | ||
167 | |||
168 | mutex_lock(&gmux_data->index_lock); | ||
169 | outb((port & 0xff), gmux_data->iostart + GMUX_PORT_READ); | ||
170 | gmux_index_wait_ready(gmux_data); | ||
171 | val = inl(gmux_data->iostart + GMUX_PORT_VALUE); | ||
172 | mutex_unlock(&gmux_data->index_lock); | ||
173 | |||
174 | return val; | ||
175 | } | ||
176 | |||
177 | static void gmux_index_write32(struct apple_gmux_data *gmux_data, int port, | ||
178 | u32 val) | ||
179 | { | ||
180 | int i; | ||
181 | u8 tmpval; | ||
182 | |||
183 | mutex_lock(&gmux_data->index_lock); | ||
184 | |||
185 | for (i = 0; i < 4; i++) { | ||
186 | tmpval = (val >> (i * 8)) & 0xff; | ||
187 | outb(tmpval, gmux_data->iostart + GMUX_PORT_VALUE + i); | ||
188 | } | ||
189 | |||
190 | gmux_index_wait_ready(gmux_data); | ||
191 | outb(port & 0xff, gmux_data->iostart + GMUX_PORT_WRITE); | ||
192 | gmux_index_wait_complete(gmux_data); | ||
193 | mutex_unlock(&gmux_data->index_lock); | ||
194 | } | ||
195 | |||
196 | static u8 gmux_read8(struct apple_gmux_data *gmux_data, int port) | ||
197 | { | ||
198 | if (gmux_data->indexed) | ||
199 | return gmux_index_read8(gmux_data, port); | ||
200 | else | ||
201 | return gmux_pio_read8(gmux_data, port); | ||
202 | } | ||
203 | |||
204 | static void gmux_write8(struct apple_gmux_data *gmux_data, int port, u8 val) | ||
205 | { | ||
206 | if (gmux_data->indexed) | ||
207 | gmux_index_write8(gmux_data, port, val); | ||
208 | else | ||
209 | gmux_pio_write8(gmux_data, port, val); | ||
210 | } | ||
211 | |||
212 | static u32 gmux_read32(struct apple_gmux_data *gmux_data, int port) | ||
213 | { | ||
214 | if (gmux_data->indexed) | ||
215 | return gmux_index_read32(gmux_data, port); | ||
216 | else | ||
217 | return gmux_pio_read32(gmux_data, port); | ||
218 | } | ||
219 | |||
220 | static void gmux_write32(struct apple_gmux_data *gmux_data, int port, | ||
221 | u32 val) | ||
222 | { | ||
223 | if (gmux_data->indexed) | ||
224 | gmux_index_write32(gmux_data, port, val); | ||
225 | else | ||
226 | gmux_pio_write32(gmux_data, port, val); | ||
227 | } | ||
228 | |||
229 | static bool gmux_is_indexed(struct apple_gmux_data *gmux_data) | ||
230 | { | ||
231 | u16 val; | ||
232 | |||
233 | outb(0xaa, gmux_data->iostart + 0xcc); | ||
234 | outb(0x55, gmux_data->iostart + 0xcd); | ||
235 | outb(0x00, gmux_data->iostart + 0xce); | ||
236 | |||
237 | val = inb(gmux_data->iostart + 0xcc) | | ||
238 | (inb(gmux_data->iostart + 0xcd) << 8); | ||
239 | |||
240 | if (val == 0x55aa) | ||
241 | return true; | ||
242 | |||
243 | return false; | ||
244 | } | ||
245 | |||
78 | static int gmux_get_brightness(struct backlight_device *bd) | 246 | static int gmux_get_brightness(struct backlight_device *bd) |
79 | { | 247 | { |
80 | struct apple_gmux_data *gmux_data = bl_get_data(bd); | 248 | struct apple_gmux_data *gmux_data = bl_get_data(bd); |
@@ -90,16 +258,7 @@ static int gmux_update_status(struct backlight_device *bd) | |||
90 | if (bd->props.state & BL_CORE_SUSPENDED) | 258 | if (bd->props.state & BL_CORE_SUSPENDED) |
91 | return 0; | 259 | return 0; |
92 | 260 | ||
93 | /* | 261 | gmux_write32(gmux_data, GMUX_PORT_BRIGHTNESS, brightness); |
94 | * Older gmux versions require writing out lower bytes first then | ||
95 | * setting the upper byte to 0 to flush the values. Newer versions | ||
96 | * accept a single u32 write, but the old method also works, so we | ||
97 | * just use the old method for all gmux versions. | ||
98 | */ | ||
99 | gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS, brightness); | ||
100 | gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS + 1, brightness >> 8); | ||
101 | gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS + 2, brightness >> 16); | ||
102 | gmux_write8(gmux_data, GMUX_PORT_BRIGHTNESS + 3, 0); | ||
103 | 262 | ||
104 | return 0; | 263 | return 0; |
105 | } | 264 | } |
@@ -110,6 +269,146 @@ static const struct backlight_ops gmux_bl_ops = { | |||
110 | .update_status = gmux_update_status, | 269 | .update_status = gmux_update_status, |
111 | }; | 270 | }; |
112 | 271 | ||
272 | static int gmux_switchto(enum vga_switcheroo_client_id id) | ||
273 | { | ||
274 | if (id == VGA_SWITCHEROO_IGD) { | ||
275 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 1); | ||
276 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 2); | ||
277 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 2); | ||
278 | } else { | ||
279 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DDC, 2); | ||
280 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_DISPLAY, 3); | ||
281 | gmux_write8(apple_gmux_data, GMUX_PORT_SWITCH_EXTERNAL, 3); | ||
282 | } | ||
283 | |||
284 | return 0; | ||
285 | } | ||
286 | |||
287 | static int gmux_set_discrete_state(struct apple_gmux_data *gmux_data, | ||
288 | enum vga_switcheroo_state state) | ||
289 | { | ||
290 | INIT_COMPLETION(gmux_data->powerchange_done); | ||
291 | |||
292 | if (state == VGA_SWITCHEROO_ON) { | ||
293 | gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1); | ||
294 | gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 3); | ||
295 | pr_debug("Discrete card powered up\n"); | ||
296 | } else { | ||
297 | gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 1); | ||
298 | gmux_write8(gmux_data, GMUX_PORT_DISCRETE_POWER, 0); | ||
299 | pr_debug("Discrete card powered down\n"); | ||
300 | } | ||
301 | |||
302 | gmux_data->power_state = state; | ||
303 | |||
304 | if (gmux_data->gpe >= 0 && | ||
305 | !wait_for_completion_interruptible_timeout(&gmux_data->powerchange_done, | ||
306 | msecs_to_jiffies(200))) | ||
307 | pr_warn("Timeout waiting for gmux switch to complete\n"); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static int gmux_set_power_state(enum vga_switcheroo_client_id id, | ||
313 | enum vga_switcheroo_state state) | ||
314 | { | ||
315 | if (id == VGA_SWITCHEROO_IGD) | ||
316 | return 0; | ||
317 | |||
318 | return gmux_set_discrete_state(apple_gmux_data, state); | ||
319 | } | ||
320 | |||
321 | static int gmux_get_client_id(struct pci_dev *pdev) | ||
322 | { | ||
323 | /* | ||
324 | * Early Macbook Pros with switchable graphics use nvidia | ||
325 | * integrated graphics. Hardcode that the 9400M is integrated. | ||
326 | */ | ||
327 | if (pdev->vendor == PCI_VENDOR_ID_INTEL) | ||
328 | return VGA_SWITCHEROO_IGD; | ||
329 | else if (pdev->vendor == PCI_VENDOR_ID_NVIDIA && | ||
330 | pdev->device == 0x0863) | ||
331 | return VGA_SWITCHEROO_IGD; | ||
332 | else | ||
333 | return VGA_SWITCHEROO_DIS; | ||
334 | } | ||
335 | |||
336 | static enum vga_switcheroo_client_id | ||
337 | gmux_active_client(struct apple_gmux_data *gmux_data) | ||
338 | { | ||
339 | if (gmux_read8(gmux_data, GMUX_PORT_SWITCH_DISPLAY) == 2) | ||
340 | return VGA_SWITCHEROO_IGD; | ||
341 | |||
342 | return VGA_SWITCHEROO_DIS; | ||
343 | } | ||
344 | |||
345 | static struct vga_switcheroo_handler gmux_handler = { | ||
346 | .switchto = gmux_switchto, | ||
347 | .power_state = gmux_set_power_state, | ||
348 | .get_client_id = gmux_get_client_id, | ||
349 | }; | ||
350 | |||
351 | static inline void gmux_disable_interrupts(struct apple_gmux_data *gmux_data) | ||
352 | { | ||
353 | gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_ENABLE, | ||
354 | GMUX_INTERRUPT_DISABLE); | ||
355 | } | ||
356 | |||
357 | static inline void gmux_enable_interrupts(struct apple_gmux_data *gmux_data) | ||
358 | { | ||
359 | gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_ENABLE, | ||
360 | GMUX_INTERRUPT_ENABLE); | ||
361 | } | ||
362 | |||
363 | static inline u8 gmux_interrupt_get_status(struct apple_gmux_data *gmux_data) | ||
364 | { | ||
365 | return gmux_read8(gmux_data, GMUX_PORT_INTERRUPT_STATUS); | ||
366 | } | ||
367 | |||
368 | static void gmux_clear_interrupts(struct apple_gmux_data *gmux_data) | ||
369 | { | ||
370 | u8 status; | ||
371 | |||
372 | /* to clear interrupts write back current status */ | ||
373 | status = gmux_interrupt_get_status(gmux_data); | ||
374 | gmux_write8(gmux_data, GMUX_PORT_INTERRUPT_STATUS, status); | ||
375 | } | ||
376 | |||
377 | static void gmux_notify_handler(acpi_handle device, u32 value, void *context) | ||
378 | { | ||
379 | u8 status; | ||
380 | struct pnp_dev *pnp = (struct pnp_dev *)context; | ||
381 | struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); | ||
382 | |||
383 | status = gmux_interrupt_get_status(gmux_data); | ||
384 | gmux_disable_interrupts(gmux_data); | ||
385 | pr_debug("Notify handler called: status %d\n", status); | ||
386 | |||
387 | gmux_clear_interrupts(gmux_data); | ||
388 | gmux_enable_interrupts(gmux_data); | ||
389 | |||
390 | if (status & GMUX_INTERRUPT_STATUS_POWER) | ||
391 | complete(&gmux_data->powerchange_done); | ||
392 | } | ||
393 | |||
394 | static int gmux_suspend(struct pnp_dev *pnp, pm_message_t state) | ||
395 | { | ||
396 | struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); | ||
397 | gmux_data->resume_client_id = gmux_active_client(gmux_data); | ||
398 | gmux_disable_interrupts(gmux_data); | ||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | static int gmux_resume(struct pnp_dev *pnp) | ||
403 | { | ||
404 | struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); | ||
405 | gmux_enable_interrupts(gmux_data); | ||
406 | gmux_switchto(gmux_data->resume_client_id); | ||
407 | if (gmux_data->power_state == VGA_SWITCHEROO_OFF) | ||
408 | gmux_set_discrete_state(gmux_data, gmux_data->power_state); | ||
409 | return 0; | ||
410 | } | ||
411 | |||
113 | static int __devinit gmux_probe(struct pnp_dev *pnp, | 412 | static int __devinit gmux_probe(struct pnp_dev *pnp, |
114 | const struct pnp_device_id *id) | 413 | const struct pnp_device_id *id) |
115 | { | 414 | { |
@@ -119,6 +418,11 @@ static int __devinit gmux_probe(struct pnp_dev *pnp, | |||
119 | struct backlight_device *bdev; | 418 | struct backlight_device *bdev; |
120 | u8 ver_major, ver_minor, ver_release; | 419 | u8 ver_major, ver_minor, ver_release; |
121 | int ret = -ENXIO; | 420 | int ret = -ENXIO; |
421 | acpi_status status; | ||
422 | unsigned long long gpe; | ||
423 | |||
424 | if (apple_gmux_data) | ||
425 | return -EBUSY; | ||
122 | 426 | ||
123 | gmux_data = kzalloc(sizeof(*gmux_data), GFP_KERNEL); | 427 | gmux_data = kzalloc(sizeof(*gmux_data), GFP_KERNEL); |
124 | if (!gmux_data) | 428 | if (!gmux_data) |
@@ -147,22 +451,29 @@ static int __devinit gmux_probe(struct pnp_dev *pnp, | |||
147 | } | 451 | } |
148 | 452 | ||
149 | /* | 453 | /* |
150 | * On some machines the gmux is in ACPI even thought the machine | 454 | * Invalid version information may indicate either that the gmux |
151 | * doesn't really have a gmux. Check for invalid version information | 455 | * device isn't present or that it's a new one that uses indexed |
152 | * to detect this. | 456 | * io |
153 | */ | 457 | */ |
458 | |||
154 | ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR); | 459 | ver_major = gmux_read8(gmux_data, GMUX_PORT_VERSION_MAJOR); |
155 | ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR); | 460 | ver_minor = gmux_read8(gmux_data, GMUX_PORT_VERSION_MINOR); |
156 | ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE); | 461 | ver_release = gmux_read8(gmux_data, GMUX_PORT_VERSION_RELEASE); |
157 | if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) { | 462 | if (ver_major == 0xff && ver_minor == 0xff && ver_release == 0xff) { |
158 | pr_info("gmux device not present\n"); | 463 | if (gmux_is_indexed(gmux_data)) { |
159 | ret = -ENODEV; | 464 | mutex_init(&gmux_data->index_lock); |
160 | goto err_release; | 465 | gmux_data->indexed = true; |
466 | } else { | ||
467 | pr_info("gmux device not present\n"); | ||
468 | ret = -ENODEV; | ||
469 | goto err_release; | ||
470 | } | ||
471 | pr_info("Found indexed gmux\n"); | ||
472 | } else { | ||
473 | pr_info("Found gmux version %d.%d.%d\n", ver_major, ver_minor, | ||
474 | ver_release); | ||
161 | } | 475 | } |
162 | 476 | ||
163 | pr_info("Found gmux version %d.%d.%d\n", ver_major, ver_minor, | ||
164 | ver_release); | ||
165 | |||
166 | memset(&props, 0, sizeof(props)); | 477 | memset(&props, 0, sizeof(props)); |
167 | props.type = BACKLIGHT_PLATFORM; | 478 | props.type = BACKLIGHT_PLATFORM; |
168 | props.max_brightness = gmux_read32(gmux_data, GMUX_PORT_MAX_BRIGHTNESS); | 479 | props.max_brightness = gmux_read32(gmux_data, GMUX_PORT_MAX_BRIGHTNESS); |
@@ -194,13 +505,67 @@ static int __devinit gmux_probe(struct pnp_dev *pnp, | |||
194 | * Disable the other backlight choices. | 505 | * Disable the other backlight choices. |
195 | */ | 506 | */ |
196 | acpi_video_dmi_promote_vendor(); | 507 | acpi_video_dmi_promote_vendor(); |
197 | #ifdef CONFIG_ACPI_VIDEO | 508 | #if defined (CONFIG_ACPI_VIDEO) || defined (CONFIG_ACPI_VIDEO_MODULE) |
198 | acpi_video_unregister(); | 509 | acpi_video_unregister(); |
199 | #endif | 510 | #endif |
200 | apple_bl_unregister(); | 511 | apple_bl_unregister(); |
201 | 512 | ||
513 | gmux_data->power_state = VGA_SWITCHEROO_ON; | ||
514 | |||
515 | gmux_data->dhandle = DEVICE_ACPI_HANDLE(&pnp->dev); | ||
516 | if (!gmux_data->dhandle) { | ||
517 | pr_err("Cannot find acpi handle for pnp device %s\n", | ||
518 | dev_name(&pnp->dev)); | ||
519 | ret = -ENODEV; | ||
520 | goto err_notify; | ||
521 | } | ||
522 | |||
523 | status = acpi_evaluate_integer(gmux_data->dhandle, "GMGP", NULL, &gpe); | ||
524 | if (ACPI_SUCCESS(status)) { | ||
525 | gmux_data->gpe = (int)gpe; | ||
526 | |||
527 | status = acpi_install_notify_handler(gmux_data->dhandle, | ||
528 | ACPI_DEVICE_NOTIFY, | ||
529 | &gmux_notify_handler, pnp); | ||
530 | if (ACPI_FAILURE(status)) { | ||
531 | pr_err("Install notify handler failed: %s\n", | ||
532 | acpi_format_exception(status)); | ||
533 | ret = -ENODEV; | ||
534 | goto err_notify; | ||
535 | } | ||
536 | |||
537 | status = acpi_enable_gpe(NULL, gmux_data->gpe); | ||
538 | if (ACPI_FAILURE(status)) { | ||
539 | pr_err("Cannot enable gpe: %s\n", | ||
540 | acpi_format_exception(status)); | ||
541 | goto err_enable_gpe; | ||
542 | } | ||
543 | } else { | ||
544 | pr_warn("No GPE found for gmux\n"); | ||
545 | gmux_data->gpe = -1; | ||
546 | } | ||
547 | |||
548 | if (vga_switcheroo_register_handler(&gmux_handler)) { | ||
549 | ret = -ENODEV; | ||
550 | goto err_register_handler; | ||
551 | } | ||
552 | |||
553 | init_completion(&gmux_data->powerchange_done); | ||
554 | apple_gmux_data = gmux_data; | ||
555 | gmux_enable_interrupts(gmux_data); | ||
556 | |||
202 | return 0; | 557 | return 0; |
203 | 558 | ||
559 | err_register_handler: | ||
560 | if (gmux_data->gpe >= 0) | ||
561 | acpi_disable_gpe(NULL, gmux_data->gpe); | ||
562 | err_enable_gpe: | ||
563 | if (gmux_data->gpe >= 0) | ||
564 | acpi_remove_notify_handler(gmux_data->dhandle, | ||
565 | ACPI_DEVICE_NOTIFY, | ||
566 | &gmux_notify_handler); | ||
567 | err_notify: | ||
568 | backlight_device_unregister(bdev); | ||
204 | err_release: | 569 | err_release: |
205 | release_region(gmux_data->iostart, gmux_data->iolen); | 570 | release_region(gmux_data->iostart, gmux_data->iolen); |
206 | err_free: | 571 | err_free: |
@@ -212,12 +577,23 @@ static void __devexit gmux_remove(struct pnp_dev *pnp) | |||
212 | { | 577 | { |
213 | struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); | 578 | struct apple_gmux_data *gmux_data = pnp_get_drvdata(pnp); |
214 | 579 | ||
580 | vga_switcheroo_unregister_handler(); | ||
581 | gmux_disable_interrupts(gmux_data); | ||
582 | if (gmux_data->gpe >= 0) { | ||
583 | acpi_disable_gpe(NULL, gmux_data->gpe); | ||
584 | acpi_remove_notify_handler(gmux_data->dhandle, | ||
585 | ACPI_DEVICE_NOTIFY, | ||
586 | &gmux_notify_handler); | ||
587 | } | ||
588 | |||
215 | backlight_device_unregister(gmux_data->bdev); | 589 | backlight_device_unregister(gmux_data->bdev); |
590 | |||
216 | release_region(gmux_data->iostart, gmux_data->iolen); | 591 | release_region(gmux_data->iostart, gmux_data->iolen); |
592 | apple_gmux_data = NULL; | ||
217 | kfree(gmux_data); | 593 | kfree(gmux_data); |
218 | 594 | ||
219 | acpi_video_dmi_demote_vendor(); | 595 | acpi_video_dmi_demote_vendor(); |
220 | #ifdef CONFIG_ACPI_VIDEO | 596 | #if defined (CONFIG_ACPI_VIDEO) || defined (CONFIG_ACPI_VIDEO_MODULE) |
221 | acpi_video_register(); | 597 | acpi_video_register(); |
222 | #endif | 598 | #endif |
223 | apple_bl_register(); | 599 | apple_bl_register(); |
@@ -233,6 +609,8 @@ static struct pnp_driver gmux_pnp_driver = { | |||
233 | .probe = gmux_probe, | 609 | .probe = gmux_probe, |
234 | .remove = __devexit_p(gmux_remove), | 610 | .remove = __devexit_p(gmux_remove), |
235 | .id_table = gmux_device_ids, | 611 | .id_table = gmux_device_ids, |
612 | .suspend = gmux_suspend, | ||
613 | .resume = gmux_resume | ||
236 | }; | 614 | }; |
237 | 615 | ||
238 | static int __init apple_gmux_init(void) | 616 | static int __init apple_gmux_init(void) |
diff --git a/drivers/platform/x86/asus-wmi.c b/drivers/platform/x86/asus-wmi.c index c7a36f6b0580..2eb9fe8e8efd 100644 --- a/drivers/platform/x86/asus-wmi.c +++ b/drivers/platform/x86/asus-wmi.c | |||
@@ -101,6 +101,7 @@ MODULE_LICENSE("GPL"); | |||
101 | #define ASUS_WMI_DEVID_WIRELESS_LED 0x00010002 | 101 | #define ASUS_WMI_DEVID_WIRELESS_LED 0x00010002 |
102 | #define ASUS_WMI_DEVID_CWAP 0x00010003 | 102 | #define ASUS_WMI_DEVID_CWAP 0x00010003 |
103 | #define ASUS_WMI_DEVID_WLAN 0x00010011 | 103 | #define ASUS_WMI_DEVID_WLAN 0x00010011 |
104 | #define ASUS_WMI_DEVID_WLAN_LED 0x00010012 | ||
104 | #define ASUS_WMI_DEVID_BLUETOOTH 0x00010013 | 105 | #define ASUS_WMI_DEVID_BLUETOOTH 0x00010013 |
105 | #define ASUS_WMI_DEVID_GPS 0x00010015 | 106 | #define ASUS_WMI_DEVID_GPS 0x00010015 |
106 | #define ASUS_WMI_DEVID_WIMAX 0x00010017 | 107 | #define ASUS_WMI_DEVID_WIMAX 0x00010017 |
@@ -731,8 +732,21 @@ static int asus_rfkill_set(void *data, bool blocked) | |||
731 | { | 732 | { |
732 | struct asus_rfkill *priv = data; | 733 | struct asus_rfkill *priv = data; |
733 | u32 ctrl_param = !blocked; | 734 | u32 ctrl_param = !blocked; |
735 | u32 dev_id = priv->dev_id; | ||
734 | 736 | ||
735 | return asus_wmi_set_devstate(priv->dev_id, ctrl_param, NULL); | 737 | /* |
738 | * If the user bit is set, BIOS can't set and record the wlan status, | ||
739 | * it will report the value read from id ASUS_WMI_DEVID_WLAN_LED | ||
740 | * while we query the wlan status through WMI(ASUS_WMI_DEVID_WLAN). | ||
741 | * So, we have to record wlan status in id ASUS_WMI_DEVID_WLAN_LED | ||
742 | * while setting the wlan status through WMI. | ||
743 | * This is also the behavior that windows app will do. | ||
744 | */ | ||
745 | if ((dev_id == ASUS_WMI_DEVID_WLAN) && | ||
746 | priv->asus->driver->wlan_ctrl_by_user) | ||
747 | dev_id = ASUS_WMI_DEVID_WLAN_LED; | ||
748 | |||
749 | return asus_wmi_set_devstate(dev_id, ctrl_param, NULL); | ||
736 | } | 750 | } |
737 | 751 | ||
738 | static void asus_rfkill_query(struct rfkill *rfkill, void *data) | 752 | static void asus_rfkill_query(struct rfkill *rfkill, void *data) |
@@ -1653,6 +1667,7 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
1653 | struct asus_wmi *asus; | 1667 | struct asus_wmi *asus; |
1654 | acpi_status status; | 1668 | acpi_status status; |
1655 | int err; | 1669 | int err; |
1670 | u32 result; | ||
1656 | 1671 | ||
1657 | asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL); | 1672 | asus = kzalloc(sizeof(struct asus_wmi), GFP_KERNEL); |
1658 | if (!asus) | 1673 | if (!asus) |
@@ -1711,6 +1726,10 @@ static int asus_wmi_add(struct platform_device *pdev) | |||
1711 | if (err) | 1726 | if (err) |
1712 | goto fail_debugfs; | 1727 | goto fail_debugfs; |
1713 | 1728 | ||
1729 | asus_wmi_get_devstate(asus, ASUS_WMI_DEVID_WLAN, &result); | ||
1730 | if (result & (ASUS_WMI_DSTS_PRESENCE_BIT | ASUS_WMI_DSTS_USER_BIT)) | ||
1731 | asus->driver->wlan_ctrl_by_user = 1; | ||
1732 | |||
1714 | return 0; | 1733 | return 0; |
1715 | 1734 | ||
1716 | fail_debugfs: | 1735 | fail_debugfs: |
diff --git a/drivers/platform/x86/asus-wmi.h b/drivers/platform/x86/asus-wmi.h index 9c1da8b81bea..4c9bd38bb0a2 100644 --- a/drivers/platform/x86/asus-wmi.h +++ b/drivers/platform/x86/asus-wmi.h | |||
@@ -46,6 +46,7 @@ struct quirk_entry { | |||
46 | struct asus_wmi_driver { | 46 | struct asus_wmi_driver { |
47 | int brightness; | 47 | int brightness; |
48 | int panel_power; | 48 | int panel_power; |
49 | int wlan_ctrl_by_user; | ||
49 | 50 | ||
50 | const char *name; | 51 | const char *name; |
51 | struct module *owner; | 52 | struct module *owner; |
diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index 2ca7dd1ab3e4..c87ff16873f9 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c | |||
@@ -350,6 +350,7 @@ static void cmpc_accel_idev_init_v4(struct input_dev *inputdev) | |||
350 | inputdev->close = cmpc_accel_close_v4; | 350 | inputdev->close = cmpc_accel_close_v4; |
351 | } | 351 | } |
352 | 352 | ||
353 | #ifdef CONFIG_PM_SLEEP | ||
353 | static int cmpc_accel_suspend_v4(struct device *dev) | 354 | static int cmpc_accel_suspend_v4(struct device *dev) |
354 | { | 355 | { |
355 | struct input_dev *inputdev; | 356 | struct input_dev *inputdev; |
@@ -384,6 +385,7 @@ static int cmpc_accel_resume_v4(struct device *dev) | |||
384 | 385 | ||
385 | return 0; | 386 | return 0; |
386 | } | 387 | } |
388 | #endif | ||
387 | 389 | ||
388 | static int cmpc_accel_add_v4(struct acpi_device *acpi) | 390 | static int cmpc_accel_add_v4(struct acpi_device *acpi) |
389 | { | 391 | { |
@@ -723,8 +725,10 @@ static void cmpc_tablet_handler(struct acpi_device *dev, u32 event) | |||
723 | struct input_dev *inputdev = dev_get_drvdata(&dev->dev); | 725 | struct input_dev *inputdev = dev_get_drvdata(&dev->dev); |
724 | 726 | ||
725 | if (event == 0x81) { | 727 | if (event == 0x81) { |
726 | if (ACPI_SUCCESS(cmpc_get_tablet(dev->handle, &val))) | 728 | if (ACPI_SUCCESS(cmpc_get_tablet(dev->handle, &val))) { |
727 | input_report_switch(inputdev, SW_TABLET_MODE, !val); | 729 | input_report_switch(inputdev, SW_TABLET_MODE, !val); |
730 | input_sync(inputdev); | ||
731 | } | ||
728 | } | 732 | } |
729 | } | 733 | } |
730 | 734 | ||
@@ -737,8 +741,10 @@ static void cmpc_tablet_idev_init(struct input_dev *inputdev) | |||
737 | set_bit(SW_TABLET_MODE, inputdev->swbit); | 741 | set_bit(SW_TABLET_MODE, inputdev->swbit); |
738 | 742 | ||
739 | acpi = to_acpi_device(inputdev->dev.parent); | 743 | acpi = to_acpi_device(inputdev->dev.parent); |
740 | if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) | 744 | if (ACPI_SUCCESS(cmpc_get_tablet(acpi->handle, &val))) { |
741 | input_report_switch(inputdev, SW_TABLET_MODE, !val); | 745 | input_report_switch(inputdev, SW_TABLET_MODE, !val); |
746 | input_sync(inputdev); | ||
747 | } | ||
742 | } | 748 | } |
743 | 749 | ||
744 | static int cmpc_tablet_add(struct acpi_device *acpi) | 750 | static int cmpc_tablet_add(struct acpi_device *acpi) |
@@ -752,15 +758,19 @@ static int cmpc_tablet_remove(struct acpi_device *acpi, int type) | |||
752 | return cmpc_remove_acpi_notify_device(acpi); | 758 | return cmpc_remove_acpi_notify_device(acpi); |
753 | } | 759 | } |
754 | 760 | ||
761 | #ifdef CONFIG_PM_SLEEP | ||
755 | static int cmpc_tablet_resume(struct device *dev) | 762 | static int cmpc_tablet_resume(struct device *dev) |
756 | { | 763 | { |
757 | struct input_dev *inputdev = dev_get_drvdata(dev); | 764 | struct input_dev *inputdev = dev_get_drvdata(dev); |
758 | 765 | ||
759 | unsigned long long val = 0; | 766 | unsigned long long val = 0; |
760 | if (ACPI_SUCCESS(cmpc_get_tablet(to_acpi_device(dev)->handle, &val))) | 767 | if (ACPI_SUCCESS(cmpc_get_tablet(to_acpi_device(dev)->handle, &val))) { |
761 | input_report_switch(inputdev, SW_TABLET_MODE, !val); | 768 | input_report_switch(inputdev, SW_TABLET_MODE, !val); |
769 | input_sync(inputdev); | ||
770 | } | ||
762 | return 0; | 771 | return 0; |
763 | } | 772 | } |
773 | #endif | ||
764 | 774 | ||
765 | static SIMPLE_DEV_PM_OPS(cmpc_tablet_pm, NULL, cmpc_tablet_resume); | 775 | static SIMPLE_DEV_PM_OPS(cmpc_tablet_pm, NULL, cmpc_tablet_resume); |
766 | 776 | ||
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c index 4e96e8c0b60f..927c33af67ec 100644 --- a/drivers/platform/x86/dell-laptop.c +++ b/drivers/platform/x86/dell-laptop.c | |||
@@ -211,7 +211,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
211 | .ident = "Dell Inspiron 5420", | 211 | .ident = "Dell Inspiron 5420", |
212 | .matches = { | 212 | .matches = { |
213 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 213 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
214 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 5420"), | 214 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5420"), |
215 | }, | 215 | }, |
216 | .driver_data = &quirk_dell_vostro_v130, | 216 | .driver_data = &quirk_dell_vostro_v130, |
217 | }, | 217 | }, |
@@ -220,7 +220,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
220 | .ident = "Dell Inspiron 5520", | 220 | .ident = "Dell Inspiron 5520", |
221 | .matches = { | 221 | .matches = { |
222 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 222 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
223 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 5520"), | 223 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5520"), |
224 | }, | 224 | }, |
225 | .driver_data = &quirk_dell_vostro_v130, | 225 | .driver_data = &quirk_dell_vostro_v130, |
226 | }, | 226 | }, |
@@ -229,7 +229,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
229 | .ident = "Dell Inspiron 5720", | 229 | .ident = "Dell Inspiron 5720", |
230 | .matches = { | 230 | .matches = { |
231 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 231 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
232 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 5720"), | 232 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 5720"), |
233 | }, | 233 | }, |
234 | .driver_data = &quirk_dell_vostro_v130, | 234 | .driver_data = &quirk_dell_vostro_v130, |
235 | }, | 235 | }, |
@@ -238,7 +238,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
238 | .ident = "Dell Inspiron 7420", | 238 | .ident = "Dell Inspiron 7420", |
239 | .matches = { | 239 | .matches = { |
240 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 240 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
241 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 7420"), | 241 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7420"), |
242 | }, | 242 | }, |
243 | .driver_data = &quirk_dell_vostro_v130, | 243 | .driver_data = &quirk_dell_vostro_v130, |
244 | }, | 244 | }, |
@@ -247,7 +247,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
247 | .ident = "Dell Inspiron 7520", | 247 | .ident = "Dell Inspiron 7520", |
248 | .matches = { | 248 | .matches = { |
249 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 249 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
250 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 7520"), | 250 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7520"), |
251 | }, | 251 | }, |
252 | .driver_data = &quirk_dell_vostro_v130, | 252 | .driver_data = &quirk_dell_vostro_v130, |
253 | }, | 253 | }, |
@@ -256,7 +256,7 @@ static struct dmi_system_id __devinitdata dell_quirks[] = { | |||
256 | .ident = "Dell Inspiron 7720", | 256 | .ident = "Dell Inspiron 7720", |
257 | .matches = { | 257 | .matches = { |
258 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), | 258 | DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
259 | DMI_MATCH(DMI_PRODUCT_NAME, "Isnpiron 7720"), | 259 | DMI_MATCH(DMI_PRODUCT_NAME, "Inspiron 7720"), |
260 | }, | 260 | }, |
261 | .driver_data = &quirk_dell_vostro_v130, | 261 | .driver_data = &quirk_dell_vostro_v130, |
262 | }, | 262 | }, |
diff --git a/drivers/platform/x86/fujitsu-tablet.c b/drivers/platform/x86/fujitsu-tablet.c index d2e41735a47b..7acae3f85f3b 100644 --- a/drivers/platform/x86/fujitsu-tablet.c +++ b/drivers/platform/x86/fujitsu-tablet.c | |||
@@ -440,11 +440,13 @@ static int __devexit acpi_fujitsu_remove(struct acpi_device *adev, int type) | |||
440 | return 0; | 440 | return 0; |
441 | } | 441 | } |
442 | 442 | ||
443 | #ifdef CONFIG_PM_SLEEP | ||
443 | static int acpi_fujitsu_resume(struct device *dev) | 444 | static int acpi_fujitsu_resume(struct device *dev) |
444 | { | 445 | { |
445 | fujitsu_reset(); | 446 | fujitsu_reset(); |
446 | return 0; | 447 | return 0; |
447 | } | 448 | } |
449 | #endif | ||
448 | 450 | ||
449 | static SIMPLE_DEV_PM_OPS(acpi_fujitsu_pm, NULL, acpi_fujitsu_resume); | 451 | static SIMPLE_DEV_PM_OPS(acpi_fujitsu_pm, NULL, acpi_fujitsu_resume); |
450 | 452 | ||
diff --git a/drivers/platform/x86/hdaps.c b/drivers/platform/x86/hdaps.c index d9ab6f64dcec..777c7e3dda51 100644 --- a/drivers/platform/x86/hdaps.c +++ b/drivers/platform/x86/hdaps.c | |||
@@ -305,10 +305,12 @@ static int hdaps_probe(struct platform_device *dev) | |||
305 | return 0; | 305 | return 0; |
306 | } | 306 | } |
307 | 307 | ||
308 | #ifdef CONFIG_PM_SLEEP | ||
308 | static int hdaps_resume(struct device *dev) | 309 | static int hdaps_resume(struct device *dev) |
309 | { | 310 | { |
310 | return hdaps_device_init(); | 311 | return hdaps_device_init(); |
311 | } | 312 | } |
313 | #endif | ||
312 | 314 | ||
313 | static SIMPLE_DEV_PM_OPS(hdaps_pm, NULL, hdaps_resume); | 315 | static SIMPLE_DEV_PM_OPS(hdaps_pm, NULL, hdaps_resume); |
314 | 316 | ||
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index f4d91154ad67..6b9af989632b 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c | |||
@@ -352,7 +352,7 @@ static int lis3lv02d_remove(struct acpi_device *device, int type) | |||
352 | } | 352 | } |
353 | 353 | ||
354 | 354 | ||
355 | #ifdef CONFIG_PM | 355 | #ifdef CONFIG_PM_SLEEP |
356 | static int lis3lv02d_suspend(struct device *dev) | 356 | static int lis3lv02d_suspend(struct device *dev) |
357 | { | 357 | { |
358 | /* make sure the device is off when we suspend */ | 358 | /* make sure the device is off when we suspend */ |
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 17f6dfd8dbfb..dae7abe1d711 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <linux/fb.h> | 36 | #include <linux/fb.h> |
37 | #include <linux/debugfs.h> | 37 | #include <linux/debugfs.h> |
38 | #include <linux/seq_file.h> | 38 | #include <linux/seq_file.h> |
39 | #include <linux/i8042.h> | ||
39 | 40 | ||
40 | #define IDEAPAD_RFKILL_DEV_NUM (3) | 41 | #define IDEAPAD_RFKILL_DEV_NUM (3) |
41 | 42 | ||
@@ -63,8 +64,11 @@ enum { | |||
63 | VPCCMD_R_3G, | 64 | VPCCMD_R_3G, |
64 | VPCCMD_W_3G, | 65 | VPCCMD_W_3G, |
65 | VPCCMD_R_ODD, /* 0x21 */ | 66 | VPCCMD_R_ODD, /* 0x21 */ |
66 | VPCCMD_R_RF = 0x23, | 67 | VPCCMD_W_FAN, |
68 | VPCCMD_R_RF, | ||
67 | VPCCMD_W_RF, | 69 | VPCCMD_W_RF, |
70 | VPCCMD_R_FAN = 0x2B, | ||
71 | VPCCMD_R_SPECIAL_BUTTONS = 0x31, | ||
68 | VPCCMD_W_BL_POWER = 0x33, | 72 | VPCCMD_W_BL_POWER = 0x33, |
69 | }; | 73 | }; |
70 | 74 | ||
@@ -356,14 +360,46 @@ static ssize_t store_ideapad_cam(struct device *dev, | |||
356 | return -EINVAL; | 360 | return -EINVAL; |
357 | ret = write_ec_cmd(ideapad_handle, VPCCMD_W_CAMERA, state); | 361 | ret = write_ec_cmd(ideapad_handle, VPCCMD_W_CAMERA, state); |
358 | if (ret < 0) | 362 | if (ret < 0) |
359 | return ret; | 363 | return -EIO; |
360 | return count; | 364 | return count; |
361 | } | 365 | } |
362 | 366 | ||
363 | static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam); | 367 | static DEVICE_ATTR(camera_power, 0644, show_ideapad_cam, store_ideapad_cam); |
364 | 368 | ||
369 | static ssize_t show_ideapad_fan(struct device *dev, | ||
370 | struct device_attribute *attr, | ||
371 | char *buf) | ||
372 | { | ||
373 | unsigned long result; | ||
374 | |||
375 | if (read_ec_data(ideapad_handle, VPCCMD_R_FAN, &result)) | ||
376 | return sprintf(buf, "-1\n"); | ||
377 | return sprintf(buf, "%lu\n", result); | ||
378 | } | ||
379 | |||
380 | static ssize_t store_ideapad_fan(struct device *dev, | ||
381 | struct device_attribute *attr, | ||
382 | const char *buf, size_t count) | ||
383 | { | ||
384 | int ret, state; | ||
385 | |||
386 | if (!count) | ||
387 | return 0; | ||
388 | if (sscanf(buf, "%i", &state) != 1) | ||
389 | return -EINVAL; | ||
390 | if (state < 0 || state > 4 || state == 3) | ||
391 | return -EINVAL; | ||
392 | ret = write_ec_cmd(ideapad_handle, VPCCMD_W_FAN, state); | ||
393 | if (ret < 0) | ||
394 | return -EIO; | ||
395 | return count; | ||
396 | } | ||
397 | |||
398 | static DEVICE_ATTR(fan_mode, 0644, show_ideapad_fan, store_ideapad_fan); | ||
399 | |||
365 | static struct attribute *ideapad_attributes[] = { | 400 | static struct attribute *ideapad_attributes[] = { |
366 | &dev_attr_camera_power.attr, | 401 | &dev_attr_camera_power.attr, |
402 | &dev_attr_fan_mode.attr, | ||
367 | NULL | 403 | NULL |
368 | }; | 404 | }; |
369 | 405 | ||
@@ -377,7 +413,10 @@ static umode_t ideapad_is_visible(struct kobject *kobj, | |||
377 | 413 | ||
378 | if (attr == &dev_attr_camera_power.attr) | 414 | if (attr == &dev_attr_camera_power.attr) |
379 | supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg)); | 415 | supported = test_bit(CFG_CAMERA_BIT, &(priv->cfg)); |
380 | else | 416 | else if (attr == &dev_attr_fan_mode.attr) { |
417 | unsigned long value; | ||
418 | supported = !read_ec_data(ideapad_handle, VPCCMD_R_FAN, &value); | ||
419 | } else | ||
381 | supported = true; | 420 | supported = true; |
382 | 421 | ||
383 | return supported ? attr->mode : 0; | 422 | return supported ? attr->mode : 0; |
@@ -518,9 +557,15 @@ static void ideapad_platform_exit(struct ideapad_private *priv) | |||
518 | */ | 557 | */ |
519 | static const struct key_entry ideapad_keymap[] = { | 558 | static const struct key_entry ideapad_keymap[] = { |
520 | { KE_KEY, 6, { KEY_SWITCHVIDEOMODE } }, | 559 | { KE_KEY, 6, { KEY_SWITCHVIDEOMODE } }, |
560 | { KE_KEY, 7, { KEY_CAMERA } }, | ||
561 | { KE_KEY, 11, { KEY_F16 } }, | ||
521 | { KE_KEY, 13, { KEY_WLAN } }, | 562 | { KE_KEY, 13, { KEY_WLAN } }, |
522 | { KE_KEY, 16, { KEY_PROG1 } }, | 563 | { KE_KEY, 16, { KEY_PROG1 } }, |
523 | { KE_KEY, 17, { KEY_PROG2 } }, | 564 | { KE_KEY, 17, { KEY_PROG2 } }, |
565 | { KE_KEY, 64, { KEY_PROG3 } }, | ||
566 | { KE_KEY, 65, { KEY_PROG4 } }, | ||
567 | { KE_KEY, 66, { KEY_TOUCHPAD_OFF } }, | ||
568 | { KE_KEY, 67, { KEY_TOUCHPAD_ON } }, | ||
524 | { KE_END, 0 }, | 569 | { KE_END, 0 }, |
525 | }; | 570 | }; |
526 | 571 | ||
@@ -587,6 +632,28 @@ static void ideapad_input_novokey(struct ideapad_private *priv) | |||
587 | ideapad_input_report(priv, 16); | 632 | ideapad_input_report(priv, 16); |
588 | } | 633 | } |
589 | 634 | ||
635 | static void ideapad_check_special_buttons(struct ideapad_private *priv) | ||
636 | { | ||
637 | unsigned long bit, value; | ||
638 | |||
639 | read_ec_data(ideapad_handle, VPCCMD_R_SPECIAL_BUTTONS, &value); | ||
640 | |||
641 | for (bit = 0; bit < 16; bit++) { | ||
642 | if (test_bit(bit, &value)) { | ||
643 | switch (bit) { | ||
644 | case 6: | ||
645 | /* Thermal Management button */ | ||
646 | ideapad_input_report(priv, 65); | ||
647 | break; | ||
648 | case 1: | ||
649 | /* OneKey Theater button */ | ||
650 | ideapad_input_report(priv, 64); | ||
651 | break; | ||
652 | } | ||
653 | } | ||
654 | } | ||
655 | } | ||
656 | |||
590 | /* | 657 | /* |
591 | * backlight | 658 | * backlight |
592 | */ | 659 | */ |
@@ -691,6 +758,24 @@ static const struct acpi_device_id ideapad_device_ids[] = { | |||
691 | }; | 758 | }; |
692 | MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); | 759 | MODULE_DEVICE_TABLE(acpi, ideapad_device_ids); |
693 | 760 | ||
761 | static void ideapad_sync_touchpad_state(struct acpi_device *adevice) | ||
762 | { | ||
763 | struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); | ||
764 | unsigned long value; | ||
765 | |||
766 | /* Without reading from EC touchpad LED doesn't switch state */ | ||
767 | if (!read_ec_data(adevice->handle, VPCCMD_R_TOUCHPAD, &value)) { | ||
768 | /* Some IdeaPads don't really turn off touchpad - they only | ||
769 | * switch the LED state. We (de)activate KBC AUX port to turn | ||
770 | * touchpad off and on. We send KEY_TOUCHPAD_OFF and | ||
771 | * KEY_TOUCHPAD_ON to not to get out of sync with LED */ | ||
772 | unsigned char param; | ||
773 | i8042_command(¶m, value ? I8042_CMD_AUX_ENABLE : | ||
774 | I8042_CMD_AUX_DISABLE); | ||
775 | ideapad_input_report(priv, value ? 67 : 66); | ||
776 | } | ||
777 | } | ||
778 | |||
694 | static int __devinit ideapad_acpi_add(struct acpi_device *adevice) | 779 | static int __devinit ideapad_acpi_add(struct acpi_device *adevice) |
695 | { | 780 | { |
696 | int ret, i; | 781 | int ret, i; |
@@ -727,6 +812,7 @@ static int __devinit ideapad_acpi_add(struct acpi_device *adevice) | |||
727 | priv->rfk[i] = NULL; | 812 | priv->rfk[i] = NULL; |
728 | } | 813 | } |
729 | ideapad_sync_rfk_state(priv); | 814 | ideapad_sync_rfk_state(priv); |
815 | ideapad_sync_touchpad_state(adevice); | ||
730 | 816 | ||
731 | if (!acpi_video_backlight_support()) { | 817 | if (!acpi_video_backlight_support()) { |
732 | ret = ideapad_backlight_init(priv); | 818 | ret = ideapad_backlight_init(priv); |
@@ -785,9 +871,14 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) | |||
785 | ideapad_sync_rfk_state(priv); | 871 | ideapad_sync_rfk_state(priv); |
786 | break; | 872 | break; |
787 | case 13: | 873 | case 13: |
874 | case 11: | ||
875 | case 7: | ||
788 | case 6: | 876 | case 6: |
789 | ideapad_input_report(priv, vpc_bit); | 877 | ideapad_input_report(priv, vpc_bit); |
790 | break; | 878 | break; |
879 | case 5: | ||
880 | ideapad_sync_touchpad_state(adevice); | ||
881 | break; | ||
791 | case 4: | 882 | case 4: |
792 | ideapad_backlight_notify_brightness(priv); | 883 | ideapad_backlight_notify_brightness(priv); |
793 | break; | 884 | break; |
@@ -797,6 +888,9 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) | |||
797 | case 2: | 888 | case 2: |
798 | ideapad_backlight_notify_power(priv); | 889 | ideapad_backlight_notify_power(priv); |
799 | break; | 890 | break; |
891 | case 0: | ||
892 | ideapad_check_special_buttons(priv); | ||
893 | break; | ||
800 | default: | 894 | default: |
801 | pr_info("Unknown event: %lu\n", vpc_bit); | 895 | pr_info("Unknown event: %lu\n", vpc_bit); |
802 | } | 896 | } |
@@ -804,6 +898,15 @@ static void ideapad_acpi_notify(struct acpi_device *adevice, u32 event) | |||
804 | } | 898 | } |
805 | } | 899 | } |
806 | 900 | ||
901 | static int ideapad_acpi_resume(struct device *device) | ||
902 | { | ||
903 | ideapad_sync_rfk_state(ideapad_priv); | ||
904 | ideapad_sync_touchpad_state(to_acpi_device(device)); | ||
905 | return 0; | ||
906 | } | ||
907 | |||
908 | static SIMPLE_DEV_PM_OPS(ideapad_pm, NULL, ideapad_acpi_resume); | ||
909 | |||
807 | static struct acpi_driver ideapad_acpi_driver = { | 910 | static struct acpi_driver ideapad_acpi_driver = { |
808 | .name = "ideapad_acpi", | 911 | .name = "ideapad_acpi", |
809 | .class = "IdeaPad", | 912 | .class = "IdeaPad", |
@@ -811,6 +914,7 @@ static struct acpi_driver ideapad_acpi_driver = { | |||
811 | .ops.add = ideapad_acpi_add, | 914 | .ops.add = ideapad_acpi_add, |
812 | .ops.remove = ideapad_acpi_remove, | 915 | .ops.remove = ideapad_acpi_remove, |
813 | .ops.notify = ideapad_acpi_notify, | 916 | .ops.notify = ideapad_acpi_notify, |
917 | .drv.pm = &ideapad_pm, | ||
814 | .owner = THIS_MODULE, | 918 | .owner = THIS_MODULE, |
815 | }; | 919 | }; |
816 | 920 | ||
diff --git a/drivers/platform/x86/msi-laptop.c b/drivers/platform/x86/msi-laptop.c index f64441844317..2111dbb7e1e3 100644 --- a/drivers/platform/x86/msi-laptop.c +++ b/drivers/platform/x86/msi-laptop.c | |||
@@ -85,7 +85,9 @@ | |||
85 | #define MSI_STANDARD_EC_TOUCHPAD_ADDRESS 0xe4 | 85 | #define MSI_STANDARD_EC_TOUCHPAD_ADDRESS 0xe4 |
86 | #define MSI_STANDARD_EC_TOUCHPAD_MASK (1 << 4) | 86 | #define MSI_STANDARD_EC_TOUCHPAD_MASK (1 << 4) |
87 | 87 | ||
88 | #ifdef CONFIG_PM_SLEEP | ||
88 | static int msi_laptop_resume(struct device *device); | 89 | static int msi_laptop_resume(struct device *device); |
90 | #endif | ||
89 | static SIMPLE_DEV_PM_OPS(msi_laptop_pm, NULL, msi_laptop_resume); | 91 | static SIMPLE_DEV_PM_OPS(msi_laptop_pm, NULL, msi_laptop_resume); |
90 | 92 | ||
91 | #define MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS 0x2f | 93 | #define MSI_STANDARD_EC_DEVICES_EXISTS_ADDRESS 0x2f |
@@ -753,6 +755,7 @@ err_bluetooth: | |||
753 | return retval; | 755 | return retval; |
754 | } | 756 | } |
755 | 757 | ||
758 | #ifdef CONFIG_PM_SLEEP | ||
756 | static int msi_laptop_resume(struct device *device) | 759 | static int msi_laptop_resume(struct device *device) |
757 | { | 760 | { |
758 | u8 data; | 761 | u8 data; |
@@ -773,6 +776,7 @@ static int msi_laptop_resume(struct device *device) | |||
773 | 776 | ||
774 | return 0; | 777 | return 0; |
775 | } | 778 | } |
779 | #endif | ||
776 | 780 | ||
777 | static int __init msi_laptop_input_setup(void) | 781 | static int __init msi_laptop_input_setup(void) |
778 | { | 782 | { |
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 24480074bcf0..8e8caa767d6a 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c | |||
@@ -188,7 +188,9 @@ static const struct acpi_device_id pcc_device_ids[] = { | |||
188 | }; | 188 | }; |
189 | MODULE_DEVICE_TABLE(acpi, pcc_device_ids); | 189 | MODULE_DEVICE_TABLE(acpi, pcc_device_ids); |
190 | 190 | ||
191 | #ifdef CONFIG_PM_SLEEP | ||
191 | static int acpi_pcc_hotkey_resume(struct device *dev); | 192 | static int acpi_pcc_hotkey_resume(struct device *dev); |
193 | #endif | ||
192 | static SIMPLE_DEV_PM_OPS(acpi_pcc_hotkey_pm, NULL, acpi_pcc_hotkey_resume); | 194 | static SIMPLE_DEV_PM_OPS(acpi_pcc_hotkey_pm, NULL, acpi_pcc_hotkey_resume); |
193 | 195 | ||
194 | static struct acpi_driver acpi_pcc_driver = { | 196 | static struct acpi_driver acpi_pcc_driver = { |
@@ -540,6 +542,7 @@ static void acpi_pcc_destroy_input(struct pcc_acpi *pcc) | |||
540 | 542 | ||
541 | /* kernel module interface */ | 543 | /* kernel module interface */ |
542 | 544 | ||
545 | #ifdef CONFIG_PM_SLEEP | ||
543 | static int acpi_pcc_hotkey_resume(struct device *dev) | 546 | static int acpi_pcc_hotkey_resume(struct device *dev) |
544 | { | 547 | { |
545 | struct pcc_acpi *pcc; | 548 | struct pcc_acpi *pcc; |
@@ -556,6 +559,7 @@ static int acpi_pcc_hotkey_resume(struct device *dev) | |||
556 | 559 | ||
557 | return acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, pcc->sticky_mode); | 560 | return acpi_pcc_write_sset(pcc, SINF_STICKY_KEY, pcc->sticky_mode); |
558 | } | 561 | } |
562 | #endif | ||
559 | 563 | ||
560 | static int acpi_pcc_hotkey_add(struct acpi_device *device) | 564 | static int acpi_pcc_hotkey_add(struct acpi_device *device) |
561 | { | 565 | { |
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index 9363969ad07a..daaddec68def 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -140,7 +140,10 @@ MODULE_PARM_DESC(kbd_backlight_timeout, | |||
140 | "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout " | 140 | "1 for 30 seconds, 2 for 60 seconds and 3 to disable timeout " |
141 | "(default: 0)"); | 141 | "(default: 0)"); |
142 | 142 | ||
143 | #ifdef CONFIG_PM_SLEEP | ||
143 | static void sony_nc_kbd_backlight_resume(void); | 144 | static void sony_nc_kbd_backlight_resume(void); |
145 | static void sony_nc_thermal_resume(void); | ||
146 | #endif | ||
144 | static int sony_nc_kbd_backlight_setup(struct platform_device *pd, | 147 | static int sony_nc_kbd_backlight_setup(struct platform_device *pd, |
145 | unsigned int handle); | 148 | unsigned int handle); |
146 | static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd); | 149 | static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd); |
@@ -151,7 +154,6 @@ static void sony_nc_battery_care_cleanup(struct platform_device *pd); | |||
151 | 154 | ||
152 | static int sony_nc_thermal_setup(struct platform_device *pd); | 155 | static int sony_nc_thermal_setup(struct platform_device *pd); |
153 | static void sony_nc_thermal_cleanup(struct platform_device *pd); | 156 | static void sony_nc_thermal_cleanup(struct platform_device *pd); |
154 | static void sony_nc_thermal_resume(void); | ||
155 | 157 | ||
156 | static int sony_nc_lid_resume_setup(struct platform_device *pd); | 158 | static int sony_nc_lid_resume_setup(struct platform_device *pd); |
157 | static void sony_nc_lid_resume_cleanup(struct platform_device *pd); | 159 | static void sony_nc_lid_resume_cleanup(struct platform_device *pd); |
@@ -1431,6 +1433,7 @@ static void sony_nc_function_cleanup(struct platform_device *pd) | |||
1431 | sony_nc_handles_cleanup(pd); | 1433 | sony_nc_handles_cleanup(pd); |
1432 | } | 1434 | } |
1433 | 1435 | ||
1436 | #ifdef CONFIG_PM_SLEEP | ||
1434 | static void sony_nc_function_resume(void) | 1437 | static void sony_nc_function_resume(void) |
1435 | { | 1438 | { |
1436 | unsigned int i, result, bitmask, arg; | 1439 | unsigned int i, result, bitmask, arg; |
@@ -1508,6 +1511,7 @@ static int sony_nc_resume(struct device *dev) | |||
1508 | 1511 | ||
1509 | return 0; | 1512 | return 0; |
1510 | } | 1513 | } |
1514 | #endif | ||
1511 | 1515 | ||
1512 | static SIMPLE_DEV_PM_OPS(sony_nc_pm, NULL, sony_nc_resume); | 1516 | static SIMPLE_DEV_PM_OPS(sony_nc_pm, NULL, sony_nc_resume); |
1513 | 1517 | ||
@@ -1872,6 +1876,7 @@ static void sony_nc_kbd_backlight_cleanup(struct platform_device *pd) | |||
1872 | } | 1876 | } |
1873 | } | 1877 | } |
1874 | 1878 | ||
1879 | #ifdef CONFIG_PM_SLEEP | ||
1875 | static void sony_nc_kbd_backlight_resume(void) | 1880 | static void sony_nc_kbd_backlight_resume(void) |
1876 | { | 1881 | { |
1877 | int ignore = 0; | 1882 | int ignore = 0; |
@@ -1888,6 +1893,7 @@ static void sony_nc_kbd_backlight_resume(void) | |||
1888 | (kbdbl_ctl->base + 0x200) | | 1893 | (kbdbl_ctl->base + 0x200) | |
1889 | (kbdbl_ctl->timeout << 0x10), &ignore); | 1894 | (kbdbl_ctl->timeout << 0x10), &ignore); |
1890 | } | 1895 | } |
1896 | #endif | ||
1891 | 1897 | ||
1892 | struct battery_care_control { | 1898 | struct battery_care_control { |
1893 | struct device_attribute attrs[2]; | 1899 | struct device_attribute attrs[2]; |
@@ -2210,6 +2216,7 @@ static void sony_nc_thermal_cleanup(struct platform_device *pd) | |||
2210 | } | 2216 | } |
2211 | } | 2217 | } |
2212 | 2218 | ||
2219 | #ifdef CONFIG_PM_SLEEP | ||
2213 | static void sony_nc_thermal_resume(void) | 2220 | static void sony_nc_thermal_resume(void) |
2214 | { | 2221 | { |
2215 | unsigned int status = sony_nc_thermal_mode_get(); | 2222 | unsigned int status = sony_nc_thermal_mode_get(); |
@@ -2217,6 +2224,7 @@ static void sony_nc_thermal_resume(void) | |||
2217 | if (status != th_handle->mode) | 2224 | if (status != th_handle->mode) |
2218 | sony_nc_thermal_mode_set(th_handle->mode); | 2225 | sony_nc_thermal_mode_set(th_handle->mode); |
2219 | } | 2226 | } |
2227 | #endif | ||
2220 | 2228 | ||
2221 | /* resume on LID open */ | 2229 | /* resume on LID open */ |
2222 | struct snc_lid_resume_control { | 2230 | struct snc_lid_resume_control { |
@@ -4287,6 +4295,7 @@ err_free_resources: | |||
4287 | return result; | 4295 | return result; |
4288 | } | 4296 | } |
4289 | 4297 | ||
4298 | #ifdef CONFIG_PM_SLEEP | ||
4290 | static int sony_pic_suspend(struct device *dev) | 4299 | static int sony_pic_suspend(struct device *dev) |
4291 | { | 4300 | { |
4292 | if (sony_pic_disable(to_acpi_device(dev))) | 4301 | if (sony_pic_disable(to_acpi_device(dev))) |
@@ -4300,6 +4309,7 @@ static int sony_pic_resume(struct device *dev) | |||
4300 | spic_dev.cur_ioport, spic_dev.cur_irq); | 4309 | spic_dev.cur_ioport, spic_dev.cur_irq); |
4301 | return 0; | 4310 | return 0; |
4302 | } | 4311 | } |
4312 | #endif | ||
4303 | 4313 | ||
4304 | static SIMPLE_DEV_PM_OPS(sony_pic_pm, sony_pic_suspend, sony_pic_resume); | 4314 | static SIMPLE_DEV_PM_OPS(sony_pic_pm, sony_pic_suspend, sony_pic_resume); |
4305 | 4315 | ||
diff --git a/drivers/platform/x86/thinkpad_acpi.c b/drivers/platform/x86/thinkpad_acpi.c index e7f73287636c..80e377949314 100644 --- a/drivers/platform/x86/thinkpad_acpi.c +++ b/drivers/platform/x86/thinkpad_acpi.c | |||
@@ -922,6 +922,7 @@ static struct input_dev *tpacpi_inputdev; | |||
922 | static struct mutex tpacpi_inputdev_send_mutex; | 922 | static struct mutex tpacpi_inputdev_send_mutex; |
923 | static LIST_HEAD(tpacpi_all_drivers); | 923 | static LIST_HEAD(tpacpi_all_drivers); |
924 | 924 | ||
925 | #ifdef CONFIG_PM_SLEEP | ||
925 | static int tpacpi_suspend_handler(struct device *dev) | 926 | static int tpacpi_suspend_handler(struct device *dev) |
926 | { | 927 | { |
927 | struct ibm_struct *ibm, *itmp; | 928 | struct ibm_struct *ibm, *itmp; |
@@ -949,6 +950,7 @@ static int tpacpi_resume_handler(struct device *dev) | |||
949 | 950 | ||
950 | return 0; | 951 | return 0; |
951 | } | 952 | } |
953 | #endif | ||
952 | 954 | ||
953 | static SIMPLE_DEV_PM_OPS(tpacpi_pm, | 955 | static SIMPLE_DEV_PM_OPS(tpacpi_pm, |
954 | tpacpi_suspend_handler, tpacpi_resume_handler); | 956 | tpacpi_suspend_handler, tpacpi_resume_handler); |
@@ -8662,6 +8664,13 @@ static int __must_check __init get_thinkpad_model_data( | |||
8662 | tp->model_str = kstrdup(s, GFP_KERNEL); | 8664 | tp->model_str = kstrdup(s, GFP_KERNEL); |
8663 | if (!tp->model_str) | 8665 | if (!tp->model_str) |
8664 | return -ENOMEM; | 8666 | return -ENOMEM; |
8667 | } else { | ||
8668 | s = dmi_get_system_info(DMI_BIOS_VENDOR); | ||
8669 | if (s && !(strnicmp(s, "Lenovo", 6))) { | ||
8670 | tp->model_str = kstrdup(s, GFP_KERNEL); | ||
8671 | if (!tp->model_str) | ||
8672 | return -ENOMEM; | ||
8673 | } | ||
8665 | } | 8674 | } |
8666 | 8675 | ||
8667 | s = dmi_get_system_info(DMI_PRODUCT_NAME); | 8676 | s = dmi_get_system_info(DMI_PRODUCT_NAME); |
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index c13ba5bac93f..5f1256d5e933 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -1296,6 +1296,7 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) | |||
1296 | } | 1296 | } |
1297 | } | 1297 | } |
1298 | 1298 | ||
1299 | #ifdef CONFIG_PM_SLEEP | ||
1299 | static int toshiba_acpi_suspend(struct device *device) | 1300 | static int toshiba_acpi_suspend(struct device *device) |
1300 | { | 1301 | { |
1301 | struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); | 1302 | struct toshiba_acpi_dev *dev = acpi_driver_data(to_acpi_device(device)); |
@@ -1317,6 +1318,7 @@ static int toshiba_acpi_resume(struct device *device) | |||
1317 | 1318 | ||
1318 | return 0; | 1319 | return 0; |
1319 | } | 1320 | } |
1321 | #endif | ||
1320 | 1322 | ||
1321 | static SIMPLE_DEV_PM_OPS(toshiba_acpi_pm, | 1323 | static SIMPLE_DEV_PM_OPS(toshiba_acpi_pm, |
1322 | toshiba_acpi_suspend, toshiba_acpi_resume); | 1324 | toshiba_acpi_suspend, toshiba_acpi_resume); |
diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c index 715a43cb5e3c..5e5d6317d690 100644 --- a/drivers/platform/x86/toshiba_bluetooth.c +++ b/drivers/platform/x86/toshiba_bluetooth.c | |||
@@ -41,7 +41,9 @@ static const struct acpi_device_id bt_device_ids[] = { | |||
41 | }; | 41 | }; |
42 | MODULE_DEVICE_TABLE(acpi, bt_device_ids); | 42 | MODULE_DEVICE_TABLE(acpi, bt_device_ids); |
43 | 43 | ||
44 | #ifdef CONFIG_PM_SLEEP | ||
44 | static int toshiba_bt_resume(struct device *dev); | 45 | static int toshiba_bt_resume(struct device *dev); |
46 | #endif | ||
45 | static SIMPLE_DEV_PM_OPS(toshiba_bt_pm, NULL, toshiba_bt_resume); | 47 | static SIMPLE_DEV_PM_OPS(toshiba_bt_pm, NULL, toshiba_bt_resume); |
46 | 48 | ||
47 | static struct acpi_driver toshiba_bt_rfkill_driver = { | 49 | static struct acpi_driver toshiba_bt_rfkill_driver = { |
@@ -90,10 +92,12 @@ static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event) | |||
90 | toshiba_bluetooth_enable(device->handle); | 92 | toshiba_bluetooth_enable(device->handle); |
91 | } | 93 | } |
92 | 94 | ||
95 | #ifdef CONFIG_PM_SLEEP | ||
93 | static int toshiba_bt_resume(struct device *dev) | 96 | static int toshiba_bt_resume(struct device *dev) |
94 | { | 97 | { |
95 | return toshiba_bluetooth_enable(to_acpi_device(dev)->handle); | 98 | return toshiba_bluetooth_enable(to_acpi_device(dev)->handle); |
96 | } | 99 | } |
100 | #endif | ||
97 | 101 | ||
98 | static int toshiba_bt_rfkill_add(struct acpi_device *device) | 102 | static int toshiba_bt_rfkill_add(struct acpi_device *device) |
99 | { | 103 | { |
diff --git a/drivers/platform/x86/xo1-rfkill.c b/drivers/platform/x86/xo1-rfkill.c index b57ad8641480..1da13ed34b04 100644 --- a/drivers/platform/x86/xo1-rfkill.c +++ b/drivers/platform/x86/xo1-rfkill.c | |||
@@ -12,8 +12,7 @@ | |||
12 | #include <linux/module.h> | 12 | #include <linux/module.h> |
13 | #include <linux/platform_device.h> | 13 | #include <linux/platform_device.h> |
14 | #include <linux/rfkill.h> | 14 | #include <linux/rfkill.h> |
15 | 15 | #include <linux/olpc-ec.h> | |
16 | #include <asm/olpc.h> | ||
17 | 16 | ||
18 | static bool card_blocked; | 17 | static bool card_blocked; |
19 | 18 | ||
diff --git a/drivers/platform/x86/xo15-ebook.c b/drivers/platform/x86/xo15-ebook.c index 849c07c13bf6..38ba39d7ca7d 100644 --- a/drivers/platform/x86/xo15-ebook.c +++ b/drivers/platform/x86/xo15-ebook.c | |||
@@ -77,10 +77,12 @@ static void ebook_switch_notify(struct acpi_device *device, u32 event) | |||
77 | } | 77 | } |
78 | } | 78 | } |
79 | 79 | ||
80 | #ifdef CONFIG_PM_SLEEP | ||
80 | static int ebook_switch_resume(struct device *dev) | 81 | static int ebook_switch_resume(struct device *dev) |
81 | { | 82 | { |
82 | return ebook_send_state(to_acpi_device(dev)); | 83 | return ebook_send_state(to_acpi_device(dev)); |
83 | } | 84 | } |
85 | #endif | ||
84 | 86 | ||
85 | static SIMPLE_DEV_PM_OPS(ebook_switch_pm, NULL, ebook_switch_resume); | 87 | static SIMPLE_DEV_PM_OPS(ebook_switch_pm, NULL, ebook_switch_resume); |
86 | 88 | ||
diff --git a/drivers/power/olpc_battery.c b/drivers/power/olpc_battery.c index 55b10b813353..a89a41acf9c5 100644 --- a/drivers/power/olpc_battery.c +++ b/drivers/power/olpc_battery.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/power_supply.h> | 17 | #include <linux/power_supply.h> |
18 | #include <linux/jiffies.h> | 18 | #include <linux/jiffies.h> |
19 | #include <linux/sched.h> | 19 | #include <linux/sched.h> |
20 | #include <linux/olpc-ec.h> | ||
20 | #include <asm/olpc.h> | 21 | #include <asm/olpc.h> |
21 | 22 | ||
22 | 23 | ||
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 722246cf20ab..5d44252b7342 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c | |||
@@ -435,6 +435,9 @@ static void tsi721_db_dpc(struct work_struct *work) | |||
435 | " info %4.4x\n", DBELL_SID(idb.bytes), | 435 | " info %4.4x\n", DBELL_SID(idb.bytes), |
436 | DBELL_TID(idb.bytes), DBELL_INF(idb.bytes)); | 436 | DBELL_TID(idb.bytes), DBELL_INF(idb.bytes)); |
437 | } | 437 | } |
438 | |||
439 | wr_ptr = ioread32(priv->regs + | ||
440 | TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE; | ||
438 | } | 441 | } |
439 | 442 | ||
440 | iowrite32(rd_ptr & (IDB_QSIZE - 1), | 443 | iowrite32(rd_ptr & (IDB_QSIZE - 1), |
@@ -445,6 +448,10 @@ static void tsi721_db_dpc(struct work_struct *work) | |||
445 | regval |= TSI721_SR_CHINT_IDBQRCV; | 448 | regval |= TSI721_SR_CHINT_IDBQRCV; |
446 | iowrite32(regval, | 449 | iowrite32(regval, |
447 | priv->regs + TSI721_SR_CHINTE(IDB_QUEUE)); | 450 | priv->regs + TSI721_SR_CHINTE(IDB_QUEUE)); |
451 | |||
452 | wr_ptr = ioread32(priv->regs + TSI721_IDQ_WP(IDB_QUEUE)) % IDB_QSIZE; | ||
453 | if (wr_ptr != rd_ptr) | ||
454 | schedule_work(&priv->idb_work); | ||
448 | } | 455 | } |
449 | 456 | ||
450 | /** | 457 | /** |
@@ -2212,7 +2219,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, | |||
2212 | const struct pci_device_id *id) | 2219 | const struct pci_device_id *id) |
2213 | { | 2220 | { |
2214 | struct tsi721_device *priv; | 2221 | struct tsi721_device *priv; |
2215 | int i, cap; | 2222 | int cap; |
2216 | int err; | 2223 | int err; |
2217 | u32 regval; | 2224 | u32 regval; |
2218 | 2225 | ||
@@ -2232,12 +2239,15 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, | |||
2232 | priv->pdev = pdev; | 2239 | priv->pdev = pdev; |
2233 | 2240 | ||
2234 | #ifdef DEBUG | 2241 | #ifdef DEBUG |
2242 | { | ||
2243 | int i; | ||
2235 | for (i = 0; i <= PCI_STD_RESOURCE_END; i++) { | 2244 | for (i = 0; i <= PCI_STD_RESOURCE_END; i++) { |
2236 | dev_dbg(&pdev->dev, "res[%d] @ 0x%llx (0x%lx, 0x%lx)\n", | 2245 | dev_dbg(&pdev->dev, "res[%d] @ 0x%llx (0x%lx, 0x%lx)\n", |
2237 | i, (unsigned long long)pci_resource_start(pdev, i), | 2246 | i, (unsigned long long)pci_resource_start(pdev, i), |
2238 | (unsigned long)pci_resource_len(pdev, i), | 2247 | (unsigned long)pci_resource_len(pdev, i), |
2239 | pci_resource_flags(pdev, i)); | 2248 | pci_resource_flags(pdev, i)); |
2240 | } | 2249 | } |
2250 | } | ||
2241 | #endif | 2251 | #endif |
2242 | /* | 2252 | /* |
2243 | * Verify BAR configuration | 2253 | * Verify BAR configuration |
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c index 182b553059c9..c151fd5d8c97 100644 --- a/drivers/regulator/ab3100.c +++ b/drivers/regulator/ab3100.c | |||
@@ -486,6 +486,7 @@ ab3100_regulator_desc[AB3100_NUM_REGULATORS] = { | |||
486 | .id = AB3100_BUCK, | 486 | .id = AB3100_BUCK, |
487 | .ops = ®ulator_ops_variable_sleepable, | 487 | .ops = ®ulator_ops_variable_sleepable, |
488 | .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), | 488 | .n_voltages = ARRAY_SIZE(ldo_e_buck_typ_voltages), |
489 | .volt_table = ldo_e_buck_typ_voltages, | ||
489 | .type = REGULATOR_VOLTAGE, | 490 | .type = REGULATOR_VOLTAGE, |
490 | .owner = THIS_MODULE, | 491 | .owner = THIS_MODULE, |
491 | .enable_time = 1000, | 492 | .enable_time = 1000, |
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c index e9c2085f9dfb..ce0fe72a428e 100644 --- a/drivers/regulator/anatop-regulator.c +++ b/drivers/regulator/anatop-regulator.c | |||
@@ -64,14 +64,15 @@ static int anatop_set_voltage_sel(struct regulator_dev *reg, unsigned selector) | |||
64 | static int anatop_get_voltage_sel(struct regulator_dev *reg) | 64 | static int anatop_get_voltage_sel(struct regulator_dev *reg) |
65 | { | 65 | { |
66 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); | 66 | struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg); |
67 | u32 val; | 67 | u32 val, mask; |
68 | 68 | ||
69 | if (!anatop_reg->control_reg) | 69 | if (!anatop_reg->control_reg) |
70 | return -ENOTSUPP; | 70 | return -ENOTSUPP; |
71 | 71 | ||
72 | val = anatop_read_reg(anatop_reg->mfd, anatop_reg->control_reg); | 72 | val = anatop_read_reg(anatop_reg->mfd, anatop_reg->control_reg); |
73 | val = (val & ((1 << anatop_reg->vol_bit_width) - 1)) >> | 73 | mask = ((1 << anatop_reg->vol_bit_width) - 1) << |
74 | anatop_reg->vol_bit_shift; | 74 | anatop_reg->vol_bit_shift; |
75 | val = (val & mask) >> anatop_reg->vol_bit_shift; | ||
75 | 76 | ||
76 | return val - anatop_reg->min_bit_val; | 77 | return val - anatop_reg->min_bit_val; |
77 | } | 78 | } |
diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index f092588a078c..48385318175a 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c | |||
@@ -3217,7 +3217,7 @@ regulator_register(const struct regulator_desc *regulator_desc, | |||
3217 | 3217 | ||
3218 | dev_set_drvdata(&rdev->dev, rdev); | 3218 | dev_set_drvdata(&rdev->dev, rdev); |
3219 | 3219 | ||
3220 | if (config->ena_gpio) { | 3220 | if (config->ena_gpio && gpio_is_valid(config->ena_gpio)) { |
3221 | ret = gpio_request_one(config->ena_gpio, | 3221 | ret = gpio_request_one(config->ena_gpio, |
3222 | GPIOF_DIR_OUT | config->ena_gpio_flags, | 3222 | GPIOF_DIR_OUT | config->ena_gpio_flags, |
3223 | rdev_get_name(rdev)); | 3223 | rdev_get_name(rdev)); |
diff --git a/drivers/regulator/gpio-regulator.c b/drivers/regulator/gpio-regulator.c index 34b67bee9323..8b5944f2d7d1 100644 --- a/drivers/regulator/gpio-regulator.c +++ b/drivers/regulator/gpio-regulator.c | |||
@@ -57,16 +57,17 @@ static int gpio_regulator_get_value(struct regulator_dev *dev) | |||
57 | return -EINVAL; | 57 | return -EINVAL; |
58 | } | 58 | } |
59 | 59 | ||
60 | static int gpio_regulator_set_value(struct regulator_dev *dev, | 60 | static int gpio_regulator_set_voltage(struct regulator_dev *dev, |
61 | int min, int max, unsigned *selector) | 61 | int min_uV, int max_uV, |
62 | unsigned *selector) | ||
62 | { | 63 | { |
63 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); | 64 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); |
64 | int ptr, target = 0, state, best_val = INT_MAX; | 65 | int ptr, target = 0, state, best_val = INT_MAX; |
65 | 66 | ||
66 | for (ptr = 0; ptr < data->nr_states; ptr++) | 67 | for (ptr = 0; ptr < data->nr_states; ptr++) |
67 | if (data->states[ptr].value < best_val && | 68 | if (data->states[ptr].value < best_val && |
68 | data->states[ptr].value >= min && | 69 | data->states[ptr].value >= min_uV && |
69 | data->states[ptr].value <= max) { | 70 | data->states[ptr].value <= max_uV) { |
70 | target = data->states[ptr].gpios; | 71 | target = data->states[ptr].gpios; |
71 | best_val = data->states[ptr].value; | 72 | best_val = data->states[ptr].value; |
72 | if (selector) | 73 | if (selector) |
@@ -85,13 +86,6 @@ static int gpio_regulator_set_value(struct regulator_dev *dev, | |||
85 | return 0; | 86 | return 0; |
86 | } | 87 | } |
87 | 88 | ||
88 | static int gpio_regulator_set_voltage(struct regulator_dev *dev, | ||
89 | int min_uV, int max_uV, | ||
90 | unsigned *selector) | ||
91 | { | ||
92 | return gpio_regulator_set_value(dev, min_uV, max_uV, selector); | ||
93 | } | ||
94 | |||
95 | static int gpio_regulator_list_voltage(struct regulator_dev *dev, | 89 | static int gpio_regulator_list_voltage(struct regulator_dev *dev, |
96 | unsigned selector) | 90 | unsigned selector) |
97 | { | 91 | { |
@@ -106,7 +100,27 @@ static int gpio_regulator_list_voltage(struct regulator_dev *dev, | |||
106 | static int gpio_regulator_set_current_limit(struct regulator_dev *dev, | 100 | static int gpio_regulator_set_current_limit(struct regulator_dev *dev, |
107 | int min_uA, int max_uA) | 101 | int min_uA, int max_uA) |
108 | { | 102 | { |
109 | return gpio_regulator_set_value(dev, min_uA, max_uA, NULL); | 103 | struct gpio_regulator_data *data = rdev_get_drvdata(dev); |
104 | int ptr, target = 0, state, best_val = 0; | ||
105 | |||
106 | for (ptr = 0; ptr < data->nr_states; ptr++) | ||
107 | if (data->states[ptr].value > best_val && | ||
108 | data->states[ptr].value >= min_uA && | ||
109 | data->states[ptr].value <= max_uA) { | ||
110 | target = data->states[ptr].gpios; | ||
111 | best_val = data->states[ptr].value; | ||
112 | } | ||
113 | |||
114 | if (best_val == 0) | ||
115 | return -EINVAL; | ||
116 | |||
117 | for (ptr = 0; ptr < data->nr_gpios; ptr++) { | ||
118 | state = (target & (1 << ptr)) >> ptr; | ||
119 | gpio_set_value(data->gpios[ptr].gpio, state); | ||
120 | } | ||
121 | data->state = target; | ||
122 | |||
123 | return 0; | ||
110 | } | 124 | } |
111 | 125 | ||
112 | static struct regulator_ops gpio_regulator_voltage_ops = { | 126 | static struct regulator_ops gpio_regulator_voltage_ops = { |
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c index 17d19fbbc490..46c7e88f8381 100644 --- a/drivers/regulator/palmas-regulator.c +++ b/drivers/regulator/palmas-regulator.c | |||
@@ -486,9 +486,12 @@ static int palmas_map_voltage_ldo(struct regulator_dev *rdev, | |||
486 | { | 486 | { |
487 | int ret, voltage; | 487 | int ret, voltage; |
488 | 488 | ||
489 | ret = ((min_uV - 900000) / 50000) + 1; | 489 | if (min_uV == 0) |
490 | if (ret < 0) | 490 | return 0; |
491 | return ret; | 491 | |
492 | if (min_uV < 900000) | ||
493 | min_uV = 900000; | ||
494 | ret = DIV_ROUND_UP(min_uV - 900000, 50000) + 1; | ||
492 | 495 | ||
493 | /* Map back into a voltage to verify we're still in bounds */ | 496 | /* Map back into a voltage to verify we're still in bounds */ |
494 | voltage = palmas_list_voltage_ldo(rdev, ret); | 497 | voltage = palmas_list_voltage_ldo(rdev, ret); |
@@ -586,7 +589,7 @@ static int palmas_ldo_init(struct palmas *palmas, int id, | |||
586 | 589 | ||
587 | addr = palmas_regs_info[id].ctrl_addr; | 590 | addr = palmas_regs_info[id].ctrl_addr; |
588 | 591 | ||
589 | ret = palmas_smps_read(palmas, addr, ®); | 592 | ret = palmas_ldo_read(palmas, addr, ®); |
590 | if (ret) | 593 | if (ret) |
591 | return ret; | 594 | return ret; |
592 | 595 | ||
@@ -596,7 +599,7 @@ static int palmas_ldo_init(struct palmas *palmas, int id, | |||
596 | if (reg_init->mode_sleep) | 599 | if (reg_init->mode_sleep) |
597 | reg |= PALMAS_LDO1_CTRL_MODE_SLEEP; | 600 | reg |= PALMAS_LDO1_CTRL_MODE_SLEEP; |
598 | 601 | ||
599 | ret = palmas_smps_write(palmas, addr, reg); | 602 | ret = palmas_ldo_write(palmas, addr, reg); |
600 | if (ret) | 603 | if (ret) |
601 | return ret; | 604 | return ret; |
602 | 605 | ||
@@ -630,7 +633,7 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
630 | 633 | ||
631 | ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, ®); | 634 | ret = palmas_smps_read(palmas, PALMAS_SMPS_CTRL, ®); |
632 | if (ret) | 635 | if (ret) |
633 | goto err_unregister_regulator; | 636 | return ret; |
634 | 637 | ||
635 | if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN) | 638 | if (reg & PALMAS_SMPS_CTRL_SMPS12_SMPS123_EN) |
636 | pmic->smps123 = 1; | 639 | pmic->smps123 = 1; |
@@ -676,7 +679,9 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
676 | case PALMAS_REG_SMPS10: | 679 | case PALMAS_REG_SMPS10: |
677 | pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES; | 680 | pmic->desc[id].n_voltages = PALMAS_SMPS10_NUM_VOLTAGES; |
678 | pmic->desc[id].ops = &palmas_ops_smps10; | 681 | pmic->desc[id].ops = &palmas_ops_smps10; |
679 | pmic->desc[id].vsel_reg = PALMAS_SMPS10_CTRL; | 682 | pmic->desc[id].vsel_reg = |
683 | PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, | ||
684 | PALMAS_SMPS10_CTRL); | ||
680 | pmic->desc[id].vsel_mask = SMPS10_VSEL; | 685 | pmic->desc[id].vsel_mask = SMPS10_VSEL; |
681 | pmic->desc[id].enable_reg = | 686 | pmic->desc[id].enable_reg = |
682 | PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, | 687 | PALMAS_BASE_TO_REG(PALMAS_SMPS_BASE, |
@@ -778,8 +783,10 @@ static __devinit int palmas_probe(struct platform_device *pdev) | |||
778 | reg_init = pdata->reg_init[id]; | 783 | reg_init = pdata->reg_init[id]; |
779 | if (reg_init) { | 784 | if (reg_init) { |
780 | ret = palmas_ldo_init(palmas, id, reg_init); | 785 | ret = palmas_ldo_init(palmas, id, reg_init); |
781 | if (ret) | 786 | if (ret) { |
787 | regulator_unregister(pmic->rdev[id]); | ||
782 | goto err_unregister_regulator; | 788 | goto err_unregister_regulator; |
789 | } | ||
783 | } | 790 | } |
784 | } | 791 | } |
785 | } | 792 | } |
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c index e6da90ab5153..19241fc30050 100644 --- a/drivers/regulator/tps6586x-regulator.c +++ b/drivers/regulator/tps6586x-regulator.c | |||
@@ -240,14 +240,16 @@ static struct tps6586x_regulator tps6586x_regulator[] = { | |||
240 | TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), | 240 | TPS6586X_LDO(LDO_9, "vinldo9", ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), |
241 | TPS6586X_LDO(LDO_RTC, NULL, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), | 241 | TPS6586X_LDO(LDO_RTC, NULL, ldo, SUPPLYV4, 3, 3, V4, 7, V4, 7), |
242 | TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), | 242 | TPS6586X_LDO(LDO_1, "vinldo01", dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), |
243 | TPS6586X_LDO(SM_2, "sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), | 243 | TPS6586X_LDO(SM_2, "vin-sm2", sm2, SUPPLYV2, 0, 5, ENC, 7, END, 7), |
244 | 244 | ||
245 | TPS6586X_DVM(LDO_2, "vinldo23", dvm, LDO2BV1, 0, 5, ENA, 3, | 245 | TPS6586X_DVM(LDO_2, "vinldo23", dvm, LDO2BV1, 0, 5, ENA, 3, |
246 | ENB, 3, VCC2, 6), | 246 | ENB, 3, VCC2, 6), |
247 | TPS6586X_DVM(LDO_4, "vinldo4", ldo4, LDO4V1, 0, 5, ENC, 3, | 247 | TPS6586X_DVM(LDO_4, "vinldo4", ldo4, LDO4V1, 0, 5, ENC, 3, |
248 | END, 3, VCC1, 6), | 248 | END, 3, VCC1, 6), |
249 | TPS6586X_DVM(SM_0, "sm0", dvm, SM0V1, 0, 5, ENA, 1, ENB, 1, VCC1, 2), | 249 | TPS6586X_DVM(SM_0, "vin-sm0", dvm, SM0V1, 0, 5, ENA, 1, |
250 | TPS6586X_DVM(SM_1, "sm1", dvm, SM1V1, 0, 5, ENA, 0, ENB, 0, VCC1, 0), | 250 | ENB, 1, VCC1, 2), |
251 | TPS6586X_DVM(SM_1, "vin-sm1", dvm, SM1V1, 0, 5, ENA, 0, | ||
252 | ENB, 0, VCC1, 0), | ||
251 | }; | 253 | }; |
252 | 254 | ||
253 | /* | 255 | /* |
diff --git a/drivers/regulator/twl-regulator.c b/drivers/regulator/twl-regulator.c index 242fe90dc565..77a71a5c17c3 100644 --- a/drivers/regulator/twl-regulator.c +++ b/drivers/regulator/twl-regulator.c | |||
@@ -1037,7 +1037,7 @@ TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300); | |||
1037 | TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300); | 1037 | TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300); |
1038 | TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300); | 1038 | TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300); |
1039 | TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300); | 1039 | TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300); |
1040 | TWL4030_FIXED_LDO(VINTANA2, 0x3f, 1500, 11, 100, 0x08); | 1040 | TWL4030_FIXED_LDO(VINTANA1, 0x3f, 1500, 11, 100, 0x08); |
1041 | TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08); | 1041 | TWL4030_FIXED_LDO(VINTDIG, 0x47, 1500, 13, 100, 0x08); |
1042 | TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08); | 1042 | TWL4030_FIXED_LDO(VUSB1V5, 0x71, 1500, 17, 100, 0x08); |
1043 | TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08); | 1043 | TWL4030_FIXED_LDO(VUSB1V8, 0x74, 1800, 18, 100, 0x08); |
@@ -1048,7 +1048,6 @@ TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 0); | |||
1048 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0); | 1048 | TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 0); |
1049 | TWL6030_FIXED_LDO(V1V8, 0x16, 1800, 0); | 1049 | TWL6030_FIXED_LDO(V1V8, 0x16, 1800, 0); |
1050 | TWL6030_FIXED_LDO(V2V1, 0x1c, 2100, 0); | 1050 | TWL6030_FIXED_LDO(V2V1, 0x1c, 2100, 0); |
1051 | TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 0); | ||
1052 | TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34); | 1051 | TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34); |
1053 | TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10); | 1052 | TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10); |
1054 | TWL6025_ADJUSTABLE_SMPS(VIO, 0x16); | 1053 | TWL6025_ADJUSTABLE_SMPS(VIO, 0x16); |
@@ -1117,7 +1116,7 @@ static const struct of_device_id twl_of_match[] __devinitconst = { | |||
1117 | TWL6025_OF_MATCH("ti,twl6025-ldo6", LDO6), | 1116 | TWL6025_OF_MATCH("ti,twl6025-ldo6", LDO6), |
1118 | TWL6025_OF_MATCH("ti,twl6025-ldoln", LDOLN), | 1117 | TWL6025_OF_MATCH("ti,twl6025-ldoln", LDOLN), |
1119 | TWL6025_OF_MATCH("ti,twl6025-ldousb", LDOUSB), | 1118 | TWL6025_OF_MATCH("ti,twl6025-ldousb", LDOUSB), |
1120 | TWLFIXED_OF_MATCH("ti,twl4030-vintana2", VINTANA2), | 1119 | TWLFIXED_OF_MATCH("ti,twl4030-vintana1", VINTANA1), |
1121 | TWLFIXED_OF_MATCH("ti,twl4030-vintdig", VINTDIG), | 1120 | TWLFIXED_OF_MATCH("ti,twl4030-vintdig", VINTDIG), |
1122 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v5", VUSB1V5), | 1121 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v5", VUSB1V5), |
1123 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v8", VUSB1V8), | 1122 | TWLFIXED_OF_MATCH("ti,twl4030-vusb1v8", VUSB1V8), |
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c index eb415bd76494..9592b936b71b 100644 --- a/drivers/rtc/interface.c +++ b/drivers/rtc/interface.c | |||
@@ -582,6 +582,7 @@ enum hrtimer_restart rtc_pie_update_irq(struct hrtimer *timer) | |||
582 | void rtc_update_irq(struct rtc_device *rtc, | 582 | void rtc_update_irq(struct rtc_device *rtc, |
583 | unsigned long num, unsigned long events) | 583 | unsigned long num, unsigned long events) |
584 | { | 584 | { |
585 | pm_stay_awake(rtc->dev.parent); | ||
585 | schedule_work(&rtc->irqwork); | 586 | schedule_work(&rtc->irqwork); |
586 | } | 587 | } |
587 | EXPORT_SYMBOL_GPL(rtc_update_irq); | 588 | EXPORT_SYMBOL_GPL(rtc_update_irq); |
@@ -844,6 +845,7 @@ void rtc_timer_do_work(struct work_struct *work) | |||
844 | 845 | ||
845 | mutex_lock(&rtc->ops_lock); | 846 | mutex_lock(&rtc->ops_lock); |
846 | again: | 847 | again: |
848 | pm_relax(rtc->dev.parent); | ||
847 | __rtc_read_time(rtc, &tm); | 849 | __rtc_read_time(rtc, &tm); |
848 | now = rtc_tm_to_ktime(tm); | 850 | now = rtc_tm_to_ktime(tm); |
849 | while ((next = timerqueue_getnext(&rtc->timerqueue))) { | 851 | while ((next = timerqueue_getnext(&rtc->timerqueue))) { |
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c index 132333d75408..4267789ca995 100644 --- a/drivers/rtc/rtc-cmos.c +++ b/drivers/rtc/rtc-cmos.c | |||
@@ -568,7 +568,6 @@ static irqreturn_t cmos_interrupt(int irq, void *p) | |||
568 | hpet_mask_rtc_irq_bit(RTC_AIE); | 568 | hpet_mask_rtc_irq_bit(RTC_AIE); |
569 | 569 | ||
570 | CMOS_READ(RTC_INTR_FLAGS); | 570 | CMOS_READ(RTC_INTR_FLAGS); |
571 | pm_wakeup_event(cmos_rtc.dev, 0); | ||
572 | } | 571 | } |
573 | spin_unlock(&rtc_lock); | 572 | spin_unlock(&rtc_lock); |
574 | 573 | ||
diff --git a/drivers/rtc/rtc-pcf2123.c b/drivers/rtc/rtc-pcf2123.c index 836118795c0b..13e4df63974f 100644 --- a/drivers/rtc/rtc-pcf2123.c +++ b/drivers/rtc/rtc-pcf2123.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <linux/rtc.h> | 43 | #include <linux/rtc.h> |
44 | #include <linux/spi/spi.h> | 44 | #include <linux/spi/spi.h> |
45 | #include <linux/module.h> | 45 | #include <linux/module.h> |
46 | #include <linux/sysfs.h> | ||
46 | 47 | ||
47 | #define DRV_VERSION "0.6" | 48 | #define DRV_VERSION "0.6" |
48 | 49 | ||
@@ -292,6 +293,7 @@ static int __devinit pcf2123_probe(struct spi_device *spi) | |||
292 | pdata->rtc = rtc; | 293 | pdata->rtc = rtc; |
293 | 294 | ||
294 | for (i = 0; i < 16; i++) { | 295 | for (i = 0; i < 16; i++) { |
296 | sysfs_attr_init(&pdata->regs[i].attr.attr); | ||
295 | sprintf(pdata->regs[i].name, "%1x", i); | 297 | sprintf(pdata->regs[i].name, "%1x", i); |
296 | pdata->regs[i].attr.attr.mode = S_IRUGO | S_IWUSR; | 298 | pdata->regs[i].attr.attr.mode = S_IRUGO | S_IWUSR; |
297 | pdata->regs[i].attr.attr.name = pdata->regs[i].name; | 299 | pdata->regs[i].attr.attr.name = pdata->regs[i].name; |
diff --git a/drivers/rtc/rtc-rs5c348.c b/drivers/rtc/rtc-rs5c348.c index 77074ccd2850..fd5c7af04ae5 100644 --- a/drivers/rtc/rtc-rs5c348.c +++ b/drivers/rtc/rtc-rs5c348.c | |||
@@ -122,9 +122,12 @@ rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
122 | tm->tm_min = bcd2bin(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK); | 122 | tm->tm_min = bcd2bin(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK); |
123 | tm->tm_hour = bcd2bin(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK); | 123 | tm->tm_hour = bcd2bin(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK); |
124 | if (!pdata->rtc_24h) { | 124 | if (!pdata->rtc_24h) { |
125 | tm->tm_hour %= 12; | 125 | if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) { |
126 | if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) | 126 | tm->tm_hour -= 20; |
127 | tm->tm_hour %= 12; | ||
127 | tm->tm_hour += 12; | 128 | tm->tm_hour += 12; |
129 | } else | ||
130 | tm->tm_hour %= 12; | ||
128 | } | 131 | } |
129 | tm->tm_wday = bcd2bin(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK); | 132 | tm->tm_wday = bcd2bin(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK); |
130 | tm->tm_mday = bcd2bin(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK); | 133 | tm->tm_mday = bcd2bin(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK); |
diff --git a/drivers/s390/char/sclp_sdias.c b/drivers/s390/char/sclp_sdias.c index 6a6f76bf6e3d..b1032931a1c4 100644 --- a/drivers/s390/char/sclp_sdias.c +++ b/drivers/s390/char/sclp_sdias.c | |||
@@ -242,11 +242,13 @@ int sclp_sdias_copy(void *dest, int start_blk, int nr_blks) | |||
242 | switch (sdias_evbuf.event_status) { | 242 | switch (sdias_evbuf.event_status) { |
243 | case EVSTATE_ALL_STORED: | 243 | case EVSTATE_ALL_STORED: |
244 | TRACE("all stored\n"); | 244 | TRACE("all stored\n"); |
245 | break; | ||
245 | case EVSTATE_PART_STORED: | 246 | case EVSTATE_PART_STORED: |
246 | TRACE("part stored: %i\n", sdias_evbuf.blk_cnt); | 247 | TRACE("part stored: %i\n", sdias_evbuf.blk_cnt); |
247 | break; | 248 | break; |
248 | case EVSTATE_NO_DATA: | 249 | case EVSTATE_NO_DATA: |
249 | TRACE("no data\n"); | 250 | TRACE("no data\n"); |
251 | /* fall through */ | ||
250 | default: | 252 | default: |
251 | pr_err("Error from SCLP while copying hsa. " | 253 | pr_err("Error from SCLP while copying hsa. " |
252 | "Event status = %x\n", | 254 | "Event status = %x\n", |
diff --git a/drivers/sh/intc/Kconfig b/drivers/sh/intc/Kconfig index c88cbccc62b0..a305731742a9 100644 --- a/drivers/sh/intc/Kconfig +++ b/drivers/sh/intc/Kconfig | |||
@@ -1,3 +1,7 @@ | |||
1 | config SH_INTC | ||
2 | def_bool y | ||
3 | select IRQ_DOMAIN | ||
4 | |||
1 | comment "Interrupt controller options" | 5 | comment "Interrupt controller options" |
2 | 6 | ||
3 | config INTC_USERIMASK | 7 | config INTC_USERIMASK |
diff --git a/drivers/sh/intc/Makefile b/drivers/sh/intc/Makefile index 44f006d09471..54ec2a0643df 100644 --- a/drivers/sh/intc/Makefile +++ b/drivers/sh/intc/Makefile | |||
@@ -1,4 +1,4 @@ | |||
1 | obj-y := access.o chip.o core.o handle.o virq.o | 1 | obj-y := access.o chip.o core.o handle.o irqdomain.o virq.o |
2 | 2 | ||
3 | obj-$(CONFIG_INTC_BALANCING) += balancing.o | 3 | obj-$(CONFIG_INTC_BALANCING) += balancing.o |
4 | obj-$(CONFIG_INTC_USERIMASK) += userimask.o | 4 | obj-$(CONFIG_INTC_USERIMASK) += userimask.o |
diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c index 7e562ccb6997..32c26d795ed0 100644 --- a/drivers/sh/intc/core.c +++ b/drivers/sh/intc/core.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/stat.h> | 25 | #include <linux/stat.h> |
26 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
27 | #include <linux/sh_intc.h> | 27 | #include <linux/sh_intc.h> |
28 | #include <linux/irqdomain.h> | ||
28 | #include <linux/device.h> | 29 | #include <linux/device.h> |
29 | #include <linux/syscore_ops.h> | 30 | #include <linux/syscore_ops.h> |
30 | #include <linux/list.h> | 31 | #include <linux/list.h> |
@@ -310,6 +311,8 @@ int __init register_intc_controller(struct intc_desc *desc) | |||
310 | 311 | ||
311 | BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ | 312 | BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ |
312 | 313 | ||
314 | intc_irq_domain_init(d, hw); | ||
315 | |||
313 | /* register the vectors one by one */ | 316 | /* register the vectors one by one */ |
314 | for (i = 0; i < hw->nr_vectors; i++) { | 317 | for (i = 0; i < hw->nr_vectors; i++) { |
315 | struct intc_vect *vect = hw->vectors + i; | 318 | struct intc_vect *vect = hw->vectors + i; |
@@ -319,10 +322,18 @@ int __init register_intc_controller(struct intc_desc *desc) | |||
319 | if (!vect->enum_id) | 322 | if (!vect->enum_id) |
320 | continue; | 323 | continue; |
321 | 324 | ||
322 | res = irq_alloc_desc_at(irq, numa_node_id()); | 325 | res = irq_create_identity_mapping(d->domain, irq); |
323 | if (res != irq && res != -EEXIST) { | 326 | if (unlikely(res)) { |
324 | pr_err("can't get irq_desc for %d\n", irq); | 327 | if (res == -EEXIST) { |
325 | continue; | 328 | res = irq_domain_associate(d->domain, irq, irq); |
329 | if (unlikely(res)) { | ||
330 | pr_err("domain association failure\n"); | ||
331 | continue; | ||
332 | } | ||
333 | } else { | ||
334 | pr_err("can't identity map IRQ %d\n", irq); | ||
335 | continue; | ||
336 | } | ||
326 | } | 337 | } |
327 | 338 | ||
328 | intc_irq_xlate_set(irq, vect->enum_id, d); | 339 | intc_irq_xlate_set(irq, vect->enum_id, d); |
@@ -340,10 +351,21 @@ int __init register_intc_controller(struct intc_desc *desc) | |||
340 | * IRQ support, each vector still needs to have | 351 | * IRQ support, each vector still needs to have |
341 | * its own backing irq_desc. | 352 | * its own backing irq_desc. |
342 | */ | 353 | */ |
343 | res = irq_alloc_desc_at(irq2, numa_node_id()); | 354 | res = irq_create_identity_mapping(d->domain, irq2); |
344 | if (res != irq2 && res != -EEXIST) { | 355 | if (unlikely(res)) { |
345 | pr_err("can't get irq_desc for %d\n", irq2); | 356 | if (res == -EEXIST) { |
346 | continue; | 357 | res = irq_domain_associate(d->domain, |
358 | irq, irq); | ||
359 | if (unlikely(res)) { | ||
360 | pr_err("domain association " | ||
361 | "failure\n"); | ||
362 | continue; | ||
363 | } | ||
364 | } else { | ||
365 | pr_err("can't identity map IRQ %d\n", | ||
366 | irq); | ||
367 | continue; | ||
368 | } | ||
347 | } | 369 | } |
348 | 370 | ||
349 | vect2->enum_id = 0; | 371 | vect2->enum_id = 0; |
diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h index f034a979a16f..7dff08e2a071 100644 --- a/drivers/sh/intc/internals.h +++ b/drivers/sh/intc/internals.h | |||
@@ -1,5 +1,6 @@ | |||
1 | #include <linux/sh_intc.h> | 1 | #include <linux/sh_intc.h> |
2 | #include <linux/irq.h> | 2 | #include <linux/irq.h> |
3 | #include <linux/irqdomain.h> | ||
3 | #include <linux/list.h> | 4 | #include <linux/list.h> |
4 | #include <linux/kernel.h> | 5 | #include <linux/kernel.h> |
5 | #include <linux/types.h> | 6 | #include <linux/types.h> |
@@ -66,6 +67,7 @@ struct intc_desc_int { | |||
66 | unsigned int nr_sense; | 67 | unsigned int nr_sense; |
67 | struct intc_window *window; | 68 | struct intc_window *window; |
68 | unsigned int nr_windows; | 69 | unsigned int nr_windows; |
70 | struct irq_domain *domain; | ||
69 | struct irq_chip chip; | 71 | struct irq_chip chip; |
70 | bool skip_suspend; | 72 | bool skip_suspend; |
71 | }; | 73 | }; |
@@ -187,6 +189,9 @@ unsigned long intc_get_ack_handle(unsigned int irq); | |||
187 | void intc_enable_disable_enum(struct intc_desc *desc, struct intc_desc_int *d, | 189 | void intc_enable_disable_enum(struct intc_desc *desc, struct intc_desc_int *d, |
188 | intc_enum enum_id, int enable); | 190 | intc_enum enum_id, int enable); |
189 | 191 | ||
192 | /* irqdomain.c */ | ||
193 | void intc_irq_domain_init(struct intc_desc_int *d, struct intc_hw_desc *hw); | ||
194 | |||
190 | /* virq.c */ | 195 | /* virq.c */ |
191 | void intc_subgroup_init(struct intc_desc *desc, struct intc_desc_int *d); | 196 | void intc_subgroup_init(struct intc_desc *desc, struct intc_desc_int *d); |
192 | void intc_irq_xlate_set(unsigned int irq, intc_enum id, struct intc_desc_int *d); | 197 | void intc_irq_xlate_set(unsigned int irq, intc_enum id, struct intc_desc_int *d); |
diff --git a/drivers/sh/intc/irqdomain.c b/drivers/sh/intc/irqdomain.c new file mode 100644 index 000000000000..3968f1c3c5c3 --- /dev/null +++ b/drivers/sh/intc/irqdomain.c | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * IRQ domain support for SH INTC subsystem | ||
3 | * | ||
4 | * Copyright (C) 2012 Paul Mundt | ||
5 | * | ||
6 | * This file is subject to the terms and conditions of the GNU General Public | ||
7 | * License. See the file "COPYING" in the main directory of this archive | ||
8 | * for more details. | ||
9 | */ | ||
10 | #define pr_fmt(fmt) "intc: " fmt | ||
11 | |||
12 | #include <linux/irqdomain.h> | ||
13 | #include <linux/sh_intc.h> | ||
14 | #include <linux/export.h> | ||
15 | #include "internals.h" | ||
16 | |||
17 | /** | ||
18 | * intc_irq_domain_evt_xlate() - Generic xlate for vectored IRQs. | ||
19 | * | ||
20 | * This takes care of exception vector to hwirq translation through | ||
21 | * by way of evt2irq() translation. | ||
22 | * | ||
23 | * Note: For platforms that use a flat vector space without INTEVT this | ||
24 | * basically just mimics irq_domain_xlate_onecell() by way of a nopped | ||
25 | * out evt2irq() implementation. | ||
26 | */ | ||
27 | static int intc_evt_xlate(struct irq_domain *d, struct device_node *ctrlr, | ||
28 | const u32 *intspec, unsigned int intsize, | ||
29 | unsigned long *out_hwirq, unsigned int *out_type) | ||
30 | { | ||
31 | if (WARN_ON(intsize < 1)) | ||
32 | return -EINVAL; | ||
33 | |||
34 | *out_hwirq = evt2irq(intspec[0]); | ||
35 | *out_type = IRQ_TYPE_NONE; | ||
36 | |||
37 | return 0; | ||
38 | } | ||
39 | |||
40 | static const struct irq_domain_ops intc_evt_ops = { | ||
41 | .xlate = intc_evt_xlate, | ||
42 | }; | ||
43 | |||
44 | void __init intc_irq_domain_init(struct intc_desc_int *d, | ||
45 | struct intc_hw_desc *hw) | ||
46 | { | ||
47 | unsigned int irq_base, irq_end; | ||
48 | |||
49 | /* | ||
50 | * Quick linear revmap check | ||
51 | */ | ||
52 | irq_base = evt2irq(hw->vectors[0].vect); | ||
53 | irq_end = evt2irq(hw->vectors[hw->nr_vectors - 1].vect); | ||
54 | |||
55 | /* | ||
56 | * Linear domains have a hard-wired assertion that IRQs start at | ||
57 | * 0 in order to make some performance optimizations. Lamely | ||
58 | * restrict the linear case to these conditions here, taking the | ||
59 | * tree penalty for linear cases with non-zero hwirq bases. | ||
60 | */ | ||
61 | if (irq_base == 0 && irq_end == (irq_base + hw->nr_vectors - 1)) | ||
62 | d->domain = irq_domain_add_linear(NULL, hw->nr_vectors, | ||
63 | &intc_evt_ops, NULL); | ||
64 | else | ||
65 | d->domain = irq_domain_add_tree(NULL, &intc_evt_ops, NULL); | ||
66 | |||
67 | BUG_ON(!d->domain); | ||
68 | } | ||
diff --git a/drivers/sh/pfc/pinctrl.c b/drivers/sh/pfc/pinctrl.c index 0802b6c0d653..2804eaae804e 100644 --- a/drivers/sh/pfc/pinctrl.c +++ b/drivers/sh/pfc/pinctrl.c | |||
@@ -276,7 +276,6 @@ static int sh_pfc_pinconf_set(struct pinctrl_dev *pctldev, unsigned pin, | |||
276 | unsigned long config) | 276 | unsigned long config) |
277 | { | 277 | { |
278 | struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); | 278 | struct sh_pfc_pinctrl *pmx = pinctrl_dev_get_drvdata(pctldev); |
279 | struct sh_pfc *pfc = pmx->pfc; | ||
280 | 279 | ||
281 | /* Validate the new type */ | 280 | /* Validate the new type */ |
282 | if (config >= PINMUX_FLAG_TYPE) | 281 | if (config >= PINMUX_FLAG_TYPE) |
@@ -326,20 +325,6 @@ static struct pinctrl_desc sh_pfc_pinctrl_desc = { | |||
326 | .confops = &sh_pfc_pinconf_ops, | 325 | .confops = &sh_pfc_pinconf_ops, |
327 | }; | 326 | }; |
328 | 327 | ||
329 | int sh_pfc_register_pinctrl(struct sh_pfc *pfc) | ||
330 | { | ||
331 | sh_pfc_pmx = kzalloc(sizeof(struct sh_pfc_pinctrl), GFP_KERNEL); | ||
332 | if (unlikely(!sh_pfc_pmx)) | ||
333 | return -ENOMEM; | ||
334 | |||
335 | spin_lock_init(&sh_pfc_pmx->lock); | ||
336 | |||
337 | sh_pfc_pmx->pfc = pfc; | ||
338 | |||
339 | return 0; | ||
340 | } | ||
341 | EXPORT_SYMBOL_GPL(sh_pfc_register_pinctrl); | ||
342 | |||
343 | static inline void __devinit sh_pfc_map_one_gpio(struct sh_pfc *pfc, | 328 | static inline void __devinit sh_pfc_map_one_gpio(struct sh_pfc *pfc, |
344 | struct sh_pfc_pinctrl *pmx, | 329 | struct sh_pfc_pinctrl *pmx, |
345 | struct pinmux_gpio *gpio, | 330 | struct pinmux_gpio *gpio, |
@@ -481,7 +466,6 @@ static int __devexit sh_pfc_pinctrl_remove(struct platform_device *pdev) | |||
481 | { | 466 | { |
482 | struct sh_pfc_pinctrl *pmx = platform_get_drvdata(pdev); | 467 | struct sh_pfc_pinctrl *pmx = platform_get_drvdata(pdev); |
483 | 468 | ||
484 | pinctrl_remove_gpio_range(pmx->pctl, &sh_pfc_gpio_range); | ||
485 | pinctrl_unregister(pmx->pctl); | 469 | pinctrl_unregister(pmx->pctl); |
486 | 470 | ||
487 | platform_set_drvdata(pdev, NULL); | 471 | platform_set_drvdata(pdev, NULL); |
@@ -507,7 +491,7 @@ static struct platform_device sh_pfc_pinctrl_device = { | |||
507 | .id = -1, | 491 | .id = -1, |
508 | }; | 492 | }; |
509 | 493 | ||
510 | static int __init sh_pfc_pinctrl_init(void) | 494 | static int sh_pfc_pinctrl_init(void) |
511 | { | 495 | { |
512 | int rc; | 496 | int rc; |
513 | 497 | ||
@@ -521,10 +505,22 @@ static int __init sh_pfc_pinctrl_init(void) | |||
521 | return rc; | 505 | return rc; |
522 | } | 506 | } |
523 | 507 | ||
508 | int sh_pfc_register_pinctrl(struct sh_pfc *pfc) | ||
509 | { | ||
510 | sh_pfc_pmx = kzalloc(sizeof(struct sh_pfc_pinctrl), GFP_KERNEL); | ||
511 | if (unlikely(!sh_pfc_pmx)) | ||
512 | return -ENOMEM; | ||
513 | |||
514 | spin_lock_init(&sh_pfc_pmx->lock); | ||
515 | |||
516 | sh_pfc_pmx->pfc = pfc; | ||
517 | |||
518 | return sh_pfc_pinctrl_init(); | ||
519 | } | ||
520 | EXPORT_SYMBOL_GPL(sh_pfc_register_pinctrl); | ||
521 | |||
524 | static void __exit sh_pfc_pinctrl_exit(void) | 522 | static void __exit sh_pfc_pinctrl_exit(void) |
525 | { | 523 | { |
526 | platform_driver_unregister(&sh_pfc_pinctrl_driver); | 524 | platform_driver_unregister(&sh_pfc_pinctrl_driver); |
527 | } | 525 | } |
528 | |||
529 | subsys_initcall(sh_pfc_pinctrl_init); | ||
530 | module_exit(sh_pfc_pinctrl_exit); | 526 | module_exit(sh_pfc_pinctrl_exit); |
diff --git a/drivers/spi/spi-bcm63xx.c b/drivers/spi/spi-bcm63xx.c index 6e25ef1bce91..ea0aaa3f13d0 100644 --- a/drivers/spi/spi-bcm63xx.c +++ b/drivers/spi/spi-bcm63xx.c | |||
@@ -438,7 +438,7 @@ out: | |||
438 | 438 | ||
439 | static int __devexit bcm63xx_spi_remove(struct platform_device *pdev) | 439 | static int __devexit bcm63xx_spi_remove(struct platform_device *pdev) |
440 | { | 440 | { |
441 | struct spi_master *master = platform_get_drvdata(pdev); | 441 | struct spi_master *master = spi_master_get(platform_get_drvdata(pdev)); |
442 | struct bcm63xx_spi *bs = spi_master_get_devdata(master); | 442 | struct bcm63xx_spi *bs = spi_master_get_devdata(master); |
443 | 443 | ||
444 | spi_unregister_master(master); | 444 | spi_unregister_master(master); |
@@ -452,6 +452,8 @@ static int __devexit bcm63xx_spi_remove(struct platform_device *pdev) | |||
452 | 452 | ||
453 | platform_set_drvdata(pdev, 0); | 453 | platform_set_drvdata(pdev, 0); |
454 | 454 | ||
455 | spi_master_put(master); | ||
456 | |||
455 | return 0; | 457 | return 0; |
456 | } | 458 | } |
457 | 459 | ||
diff --git a/drivers/spi/spi-coldfire-qspi.c b/drivers/spi/spi-coldfire-qspi.c index b2d4b9e4e010..764bfee75920 100644 --- a/drivers/spi/spi-coldfire-qspi.c +++ b/drivers/spi/spi-coldfire-qspi.c | |||
@@ -533,7 +533,6 @@ static int __devexit mcfqspi_remove(struct platform_device *pdev) | |||
533 | iounmap(mcfqspi->iobase); | 533 | iounmap(mcfqspi->iobase); |
534 | release_mem_region(res->start, resource_size(res)); | 534 | release_mem_region(res->start, resource_size(res)); |
535 | spi_unregister_master(master); | 535 | spi_unregister_master(master); |
536 | spi_master_put(master); | ||
537 | 536 | ||
538 | return 0; | 537 | return 0; |
539 | } | 538 | } |
@@ -541,7 +540,7 @@ static int __devexit mcfqspi_remove(struct platform_device *pdev) | |||
541 | #ifdef CONFIG_PM_SLEEP | 540 | #ifdef CONFIG_PM_SLEEP |
542 | static int mcfqspi_suspend(struct device *dev) | 541 | static int mcfqspi_suspend(struct device *dev) |
543 | { | 542 | { |
544 | struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); | 543 | struct spi_master *master = dev_get_drvdata(dev); |
545 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); | 544 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); |
546 | 545 | ||
547 | spi_master_suspend(master); | 546 | spi_master_suspend(master); |
@@ -553,7 +552,7 @@ static int mcfqspi_suspend(struct device *dev) | |||
553 | 552 | ||
554 | static int mcfqspi_resume(struct device *dev) | 553 | static int mcfqspi_resume(struct device *dev) |
555 | { | 554 | { |
556 | struct spi_master *master = spi_master_get(dev_get_drvdata(dev)); | 555 | struct spi_master *master = dev_get_drvdata(dev); |
557 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); | 556 | struct mcfqspi *mcfqspi = spi_master_get_devdata(master); |
558 | 557 | ||
559 | spi_master_resume(master); | 558 | spi_master_resume(master); |
diff --git a/drivers/spi/spi-omap2-mcspi.c b/drivers/spi/spi-omap2-mcspi.c index bc4778175e34..b2fb141da375 100644 --- a/drivers/spi/spi-omap2-mcspi.c +++ b/drivers/spi/spi-omap2-mcspi.c | |||
@@ -1228,18 +1228,16 @@ static int __devinit omap2_mcspi_probe(struct platform_device *pdev) | |||
1228 | 1228 | ||
1229 | status = spi_register_master(master); | 1229 | status = spi_register_master(master); |
1230 | if (status < 0) | 1230 | if (status < 0) |
1231 | goto err_spi_register; | 1231 | goto disable_pm; |
1232 | 1232 | ||
1233 | return status; | 1233 | return status; |
1234 | 1234 | ||
1235 | err_spi_register: | ||
1236 | spi_master_put(master); | ||
1237 | disable_pm: | 1235 | disable_pm: |
1238 | pm_runtime_disable(&pdev->dev); | 1236 | pm_runtime_disable(&pdev->dev); |
1239 | dma_chnl_free: | 1237 | dma_chnl_free: |
1240 | kfree(mcspi->dma_channels); | 1238 | kfree(mcspi->dma_channels); |
1241 | free_master: | 1239 | free_master: |
1242 | kfree(master); | 1240 | spi_master_put(master); |
1243 | platform_set_drvdata(pdev, NULL); | 1241 | platform_set_drvdata(pdev, NULL); |
1244 | return status; | 1242 | return status; |
1245 | } | 1243 | } |
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index aab518ec2bbc..6abbe23c39b4 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -2053,7 +2053,6 @@ pl022_probe(struct amba_device *adev, const struct amba_id *id) | |||
2053 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", | 2053 | printk(KERN_INFO "pl022: mapped registers from 0x%08x to %p\n", |
2054 | adev->res.start, pl022->virtbase); | 2054 | adev->res.start, pl022->virtbase); |
2055 | 2055 | ||
2056 | pm_runtime_enable(dev); | ||
2057 | pm_runtime_resume(dev); | 2056 | pm_runtime_resume(dev); |
2058 | 2057 | ||
2059 | pl022->clk = clk_get(&adev->dev, NULL); | 2058 | pl022->clk = clk_get(&adev->dev, NULL); |
diff --git a/drivers/spi/spi-s3c64xx.c b/drivers/spi/spi-s3c64xx.c index 646a7657fe62..d1c8441f638c 100644 --- a/drivers/spi/spi-s3c64xx.c +++ b/drivers/spi/spi-s3c64xx.c | |||
@@ -826,7 +826,7 @@ static struct s3c64xx_spi_csinfo *s3c64xx_get_slave_ctrldata( | |||
826 | struct spi_device *spi) | 826 | struct spi_device *spi) |
827 | { | 827 | { |
828 | struct s3c64xx_spi_csinfo *cs; | 828 | struct s3c64xx_spi_csinfo *cs; |
829 | struct device_node *slave_np, *data_np; | 829 | struct device_node *slave_np, *data_np = NULL; |
830 | u32 fb_delay = 0; | 830 | u32 fb_delay = 0; |
831 | 831 | ||
832 | slave_np = spi->dev.of_node; | 832 | slave_np = spi->dev.of_node; |
@@ -1479,40 +1479,40 @@ static const struct dev_pm_ops s3c64xx_spi_pm = { | |||
1479 | s3c64xx_spi_runtime_resume, NULL) | 1479 | s3c64xx_spi_runtime_resume, NULL) |
1480 | }; | 1480 | }; |
1481 | 1481 | ||
1482 | struct s3c64xx_spi_port_config s3c2443_spi_port_config = { | 1482 | static struct s3c64xx_spi_port_config s3c2443_spi_port_config = { |
1483 | .fifo_lvl_mask = { 0x7f }, | 1483 | .fifo_lvl_mask = { 0x7f }, |
1484 | .rx_lvl_offset = 13, | 1484 | .rx_lvl_offset = 13, |
1485 | .tx_st_done = 21, | 1485 | .tx_st_done = 21, |
1486 | .high_speed = true, | 1486 | .high_speed = true, |
1487 | }; | 1487 | }; |
1488 | 1488 | ||
1489 | struct s3c64xx_spi_port_config s3c6410_spi_port_config = { | 1489 | static struct s3c64xx_spi_port_config s3c6410_spi_port_config = { |
1490 | .fifo_lvl_mask = { 0x7f, 0x7F }, | 1490 | .fifo_lvl_mask = { 0x7f, 0x7F }, |
1491 | .rx_lvl_offset = 13, | 1491 | .rx_lvl_offset = 13, |
1492 | .tx_st_done = 21, | 1492 | .tx_st_done = 21, |
1493 | }; | 1493 | }; |
1494 | 1494 | ||
1495 | struct s3c64xx_spi_port_config s5p64x0_spi_port_config = { | 1495 | static struct s3c64xx_spi_port_config s5p64x0_spi_port_config = { |
1496 | .fifo_lvl_mask = { 0x1ff, 0x7F }, | 1496 | .fifo_lvl_mask = { 0x1ff, 0x7F }, |
1497 | .rx_lvl_offset = 15, | 1497 | .rx_lvl_offset = 15, |
1498 | .tx_st_done = 25, | 1498 | .tx_st_done = 25, |
1499 | }; | 1499 | }; |
1500 | 1500 | ||
1501 | struct s3c64xx_spi_port_config s5pc100_spi_port_config = { | 1501 | static struct s3c64xx_spi_port_config s5pc100_spi_port_config = { |
1502 | .fifo_lvl_mask = { 0x7f, 0x7F }, | 1502 | .fifo_lvl_mask = { 0x7f, 0x7F }, |
1503 | .rx_lvl_offset = 13, | 1503 | .rx_lvl_offset = 13, |
1504 | .tx_st_done = 21, | 1504 | .tx_st_done = 21, |
1505 | .high_speed = true, | 1505 | .high_speed = true, |
1506 | }; | 1506 | }; |
1507 | 1507 | ||
1508 | struct s3c64xx_spi_port_config s5pv210_spi_port_config = { | 1508 | static struct s3c64xx_spi_port_config s5pv210_spi_port_config = { |
1509 | .fifo_lvl_mask = { 0x1ff, 0x7F }, | 1509 | .fifo_lvl_mask = { 0x1ff, 0x7F }, |
1510 | .rx_lvl_offset = 15, | 1510 | .rx_lvl_offset = 15, |
1511 | .tx_st_done = 25, | 1511 | .tx_st_done = 25, |
1512 | .high_speed = true, | 1512 | .high_speed = true, |
1513 | }; | 1513 | }; |
1514 | 1514 | ||
1515 | struct s3c64xx_spi_port_config exynos4_spi_port_config = { | 1515 | static struct s3c64xx_spi_port_config exynos4_spi_port_config = { |
1516 | .fifo_lvl_mask = { 0x1ff, 0x7F, 0x7F }, | 1516 | .fifo_lvl_mask = { 0x1ff, 0x7F, 0x7F }, |
1517 | .rx_lvl_offset = 15, | 1517 | .rx_lvl_offset = 15, |
1518 | .tx_st_done = 25, | 1518 | .tx_st_done = 25, |
diff --git a/drivers/staging/comedi/drivers.c b/drivers/staging/comedi/drivers.c index c0fdb00783ed..2359151af7e1 100644 --- a/drivers/staging/comedi/drivers.c +++ b/drivers/staging/comedi/drivers.c | |||
@@ -168,7 +168,7 @@ int comedi_device_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
168 | dev->board_ptr = comedi_recognize(driv, it->board_name); | 168 | dev->board_ptr = comedi_recognize(driv, it->board_name); |
169 | if (dev->board_ptr) | 169 | if (dev->board_ptr) |
170 | break; | 170 | break; |
171 | } else if (strcmp(driv->driver_name, it->board_name)) | 171 | } else if (strcmp(driv->driver_name, it->board_name) == 0) |
172 | break; | 172 | break; |
173 | module_put(driv->module); | 173 | module_put(driv->module); |
174 | } | 174 | } |
diff --git a/drivers/staging/comedi/drivers/adv_pci1710.c b/drivers/staging/comedi/drivers/adv_pci1710.c index 31986608eaf1..6b4d0d68e637 100644 --- a/drivers/staging/comedi/drivers/adv_pci1710.c +++ b/drivers/staging/comedi/drivers/adv_pci1710.c | |||
@@ -1349,9 +1349,6 @@ static struct pci_dev *pci1710_find_pci_dev(struct comedi_device *dev, | |||
1349 | } | 1349 | } |
1350 | if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) | 1350 | if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) |
1351 | continue; | 1351 | continue; |
1352 | if (pci_is_enabled(pcidev)) | ||
1353 | continue; | ||
1354 | |||
1355 | if (strcmp(this_board->name, DRV_NAME) == 0) { | 1352 | if (strcmp(this_board->name, DRV_NAME) == 0) { |
1356 | for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { | 1353 | for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { |
1357 | if (pcidev->device == boardtypes[i].device_id) { | 1354 | if (pcidev->device == boardtypes[i].device_id) { |
diff --git a/drivers/staging/comedi/drivers/adv_pci1723.c b/drivers/staging/comedi/drivers/adv_pci1723.c index da5ee69d2c9d..dfde0f6328dd 100644 --- a/drivers/staging/comedi/drivers/adv_pci1723.c +++ b/drivers/staging/comedi/drivers/adv_pci1723.c | |||
@@ -301,8 +301,6 @@ static struct pci_dev *pci1723_find_pci_dev(struct comedi_device *dev, | |||
301 | } | 301 | } |
302 | if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) | 302 | if (pcidev->vendor != PCI_VENDOR_ID_ADVANTECH) |
303 | continue; | 303 | continue; |
304 | if (pci_is_enabled(pcidev)) | ||
305 | continue; | ||
306 | return pcidev; | 304 | return pcidev; |
307 | } | 305 | } |
308 | dev_err(dev->class_dev, | 306 | dev_err(dev->class_dev, |
diff --git a/drivers/staging/comedi/drivers/adv_pci_dio.c b/drivers/staging/comedi/drivers/adv_pci_dio.c index 97f06dc8e48d..2d4cb7f638b2 100644 --- a/drivers/staging/comedi/drivers/adv_pci_dio.c +++ b/drivers/staging/comedi/drivers/adv_pci_dio.c | |||
@@ -1064,8 +1064,6 @@ static struct pci_dev *pci_dio_find_pci_dev(struct comedi_device *dev, | |||
1064 | slot != PCI_SLOT(pcidev->devfn)) | 1064 | slot != PCI_SLOT(pcidev->devfn)) |
1065 | continue; | 1065 | continue; |
1066 | } | 1066 | } |
1067 | if (pci_is_enabled(pcidev)) | ||
1068 | continue; | ||
1069 | for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { | 1067 | for (i = 0; i < ARRAY_SIZE(boardtypes); ++i) { |
1070 | if (boardtypes[i].vendor_id != pcidev->vendor) | 1068 | if (boardtypes[i].vendor_id != pcidev->vendor) |
1071 | continue; | 1069 | continue; |
diff --git a/drivers/staging/comedi/drivers/daqboard2000.c b/drivers/staging/comedi/drivers/daqboard2000.c index ef28385c1482..cad559a1a730 100644 --- a/drivers/staging/comedi/drivers/daqboard2000.c +++ b/drivers/staging/comedi/drivers/daqboard2000.c | |||
@@ -718,7 +718,8 @@ static struct pci_dev *daqboard2000_find_pci_dev(struct comedi_device *dev, | |||
718 | continue; | 718 | continue; |
719 | } | 719 | } |
720 | if (pcidev->vendor != PCI_VENDOR_ID_IOTECH || | 720 | if (pcidev->vendor != PCI_VENDOR_ID_IOTECH || |
721 | pcidev->device != 0x0409) | 721 | pcidev->device != 0x0409 || |
722 | pcidev->subsystem_device != PCI_VENDOR_ID_IOTECH) | ||
722 | continue; | 723 | continue; |
723 | 724 | ||
724 | for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { | 725 | for (i = 0; i < ARRAY_SIZE(boardtypes); i++) { |
@@ -739,6 +740,7 @@ static int daqboard2000_attach(struct comedi_device *dev, | |||
739 | { | 740 | { |
740 | struct pci_dev *pcidev; | 741 | struct pci_dev *pcidev; |
741 | struct comedi_subdevice *s; | 742 | struct comedi_subdevice *s; |
743 | resource_size_t pci_base; | ||
742 | void *aux_data; | 744 | void *aux_data; |
743 | unsigned int aux_len; | 745 | unsigned int aux_len; |
744 | int result; | 746 | int result; |
@@ -758,11 +760,12 @@ static int daqboard2000_attach(struct comedi_device *dev, | |||
758 | "failed to enable PCI device and request regions\n"); | 760 | "failed to enable PCI device and request regions\n"); |
759 | return -EIO; | 761 | return -EIO; |
760 | } | 762 | } |
761 | dev->iobase = pci_resource_start(pcidev, 2); | 763 | dev->iobase = 1; /* the "detach" needs this */ |
762 | 764 | ||
763 | devpriv->plx = | 765 | pci_base = pci_resource_start(pcidev, 0); |
764 | ioremap(pci_resource_start(pcidev, 0), DAQBOARD2000_PLX_SIZE); | 766 | devpriv->plx = ioremap(pci_base, DAQBOARD2000_PLX_SIZE); |
765 | devpriv->daq = ioremap(dev->iobase, DAQBOARD2000_DAQ_SIZE); | 767 | pci_base = pci_resource_start(pcidev, 2); |
768 | devpriv->daq = ioremap(pci_base, DAQBOARD2000_DAQ_SIZE); | ||
766 | if (!devpriv->plx || !devpriv->daq) | 769 | if (!devpriv->plx || !devpriv->daq) |
767 | return -ENOMEM; | 770 | return -ENOMEM; |
768 | 771 | ||
@@ -799,8 +802,6 @@ static int daqboard2000_attach(struct comedi_device *dev, | |||
799 | printk("Interrupt after is: %x\n", interrupt); | 802 | printk("Interrupt after is: %x\n", interrupt); |
800 | */ | 803 | */ |
801 | 804 | ||
802 | dev->iobase = (unsigned long)devpriv->daq; | ||
803 | |||
804 | dev->board_name = this_board->name; | 805 | dev->board_name = this_board->name; |
805 | 806 | ||
806 | s = dev->subdevices + 0; | 807 | s = dev->subdevices + 0; |
@@ -824,7 +825,7 @@ static int daqboard2000_attach(struct comedi_device *dev, | |||
824 | 825 | ||
825 | s = dev->subdevices + 2; | 826 | s = dev->subdevices + 2; |
826 | result = subdev_8255_init(dev, s, daqboard2000_8255_cb, | 827 | result = subdev_8255_init(dev, s, daqboard2000_8255_cb, |
827 | (unsigned long)(dev->iobase + 0x40)); | 828 | (unsigned long)(devpriv->daq + 0x40)); |
828 | 829 | ||
829 | out: | 830 | out: |
830 | return result; | 831 | return result; |
diff --git a/drivers/staging/comedi/drivers/dt3000.c b/drivers/staging/comedi/drivers/dt3000.c index a6fe6c9be87e..3476cda0fff0 100644 --- a/drivers/staging/comedi/drivers/dt3000.c +++ b/drivers/staging/comedi/drivers/dt3000.c | |||
@@ -804,6 +804,7 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
804 | { | 804 | { |
805 | struct pci_dev *pcidev; | 805 | struct pci_dev *pcidev; |
806 | struct comedi_subdevice *s; | 806 | struct comedi_subdevice *s; |
807 | resource_size_t pci_base; | ||
807 | int ret = 0; | 808 | int ret = 0; |
808 | 809 | ||
809 | dev_dbg(dev->class_dev, "dt3000:\n"); | 810 | dev_dbg(dev->class_dev, "dt3000:\n"); |
@@ -820,9 +821,10 @@ static int dt3000_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
820 | ret = comedi_pci_enable(pcidev, "dt3000"); | 821 | ret = comedi_pci_enable(pcidev, "dt3000"); |
821 | if (ret < 0) | 822 | if (ret < 0) |
822 | return ret; | 823 | return ret; |
824 | dev->iobase = 1; /* the "detach" needs this */ | ||
823 | 825 | ||
824 | dev->iobase = pci_resource_start(pcidev, 0); | 826 | pci_base = pci_resource_start(pcidev, 0); |
825 | devpriv->io_addr = ioremap(dev->iobase, DT3000_SIZE); | 827 | devpriv->io_addr = ioremap(pci_base, DT3000_SIZE); |
826 | if (!devpriv->io_addr) | 828 | if (!devpriv->io_addr) |
827 | return -ENOMEM; | 829 | return -ENOMEM; |
828 | 830 | ||
diff --git a/drivers/staging/comedi/drivers/rtd520.c b/drivers/staging/comedi/drivers/rtd520.c index 112fdc3e9c69..5aa8be1e7b92 100644 --- a/drivers/staging/comedi/drivers/rtd520.c +++ b/drivers/staging/comedi/drivers/rtd520.c | |||
@@ -1619,9 +1619,8 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
1619 | struct rtdPrivate *devpriv; | 1619 | struct rtdPrivate *devpriv; |
1620 | struct pci_dev *pcidev; | 1620 | struct pci_dev *pcidev; |
1621 | struct comedi_subdevice *s; | 1621 | struct comedi_subdevice *s; |
1622 | resource_size_t pci_base; | ||
1622 | int ret; | 1623 | int ret; |
1623 | resource_size_t physLas1; /* data area */ | ||
1624 | resource_size_t physLcfg; /* PLX9080 */ | ||
1625 | #ifdef USE_DMA | 1624 | #ifdef USE_DMA |
1626 | int index; | 1625 | int index; |
1627 | #endif | 1626 | #endif |
@@ -1655,20 +1654,15 @@ static int rtd_attach(struct comedi_device *dev, struct comedi_devconfig *it) | |||
1655 | printk(KERN_INFO "Failed to enable PCI device and request regions.\n"); | 1654 | printk(KERN_INFO "Failed to enable PCI device and request regions.\n"); |
1656 | return ret; | 1655 | return ret; |
1657 | } | 1656 | } |
1658 | 1657 | dev->iobase = 1; /* the "detach" needs this */ | |
1659 | /* | 1658 | |
1660 | * Initialize base addresses | 1659 | /* Initialize the base addresses */ |
1661 | */ | 1660 | pci_base = pci_resource_start(pcidev, LAS0_PCIINDEX); |
1662 | /* Get the physical address from PCI config */ | 1661 | devpriv->las0 = ioremap_nocache(pci_base, LAS0_PCISIZE); |
1663 | dev->iobase = pci_resource_start(pcidev, LAS0_PCIINDEX); | 1662 | pci_base = pci_resource_start(pcidev, LAS1_PCIINDEX); |
1664 | physLas1 = pci_resource_start(pcidev, LAS1_PCIINDEX); | 1663 | devpriv->las1 = ioremap_nocache(pci_base, LAS1_PCISIZE); |
1665 | physLcfg = pci_resource_start(pcidev, LCFG_PCIINDEX); | 1664 | pci_base = pci_resource_start(pcidev, LCFG_PCIINDEX); |
1666 | /* Now have the kernel map this into memory */ | 1665 | devpriv->lcfg = ioremap_nocache(pci_base, LCFG_PCISIZE); |
1667 | /* ASSUME page aligned */ | ||
1668 | devpriv->las0 = ioremap_nocache(dev->iobase, LAS0_PCISIZE); | ||
1669 | devpriv->las1 = ioremap_nocache(physLas1, LAS1_PCISIZE); | ||
1670 | devpriv->lcfg = ioremap_nocache(physLcfg, LCFG_PCISIZE); | ||
1671 | |||
1672 | if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg) | 1666 | if (!devpriv->las0 || !devpriv->las1 || !devpriv->lcfg) |
1673 | return -ENOMEM; | 1667 | return -ENOMEM; |
1674 | 1668 | ||
diff --git a/drivers/staging/comedi/drivers/usbdux.c b/drivers/staging/comedi/drivers/usbdux.c index 848c7ec06976..11ee83681da7 100644 --- a/drivers/staging/comedi/drivers/usbdux.c +++ b/drivers/staging/comedi/drivers/usbdux.c | |||
@@ -102,6 +102,7 @@ sampling rate. If you sample two channels you get 4kHz and so on. | |||
102 | #define BULK_TIMEOUT 1000 | 102 | #define BULK_TIMEOUT 1000 |
103 | 103 | ||
104 | /* constants for "firmware" upload and download */ | 104 | /* constants for "firmware" upload and download */ |
105 | #define FIRMWARE "usbdux_firmware.bin" | ||
105 | #define USBDUXSUB_FIRMWARE 0xA0 | 106 | #define USBDUXSUB_FIRMWARE 0xA0 |
106 | #define VENDOR_DIR_IN 0xC0 | 107 | #define VENDOR_DIR_IN 0xC0 |
107 | #define VENDOR_DIR_OUT 0x40 | 108 | #define VENDOR_DIR_OUT 0x40 |
@@ -2791,7 +2792,7 @@ static int usbdux_usb_probe(struct usb_interface *uinterf, | |||
2791 | 2792 | ||
2792 | ret = request_firmware_nowait(THIS_MODULE, | 2793 | ret = request_firmware_nowait(THIS_MODULE, |
2793 | FW_ACTION_HOTPLUG, | 2794 | FW_ACTION_HOTPLUG, |
2794 | "usbdux_firmware.bin", | 2795 | FIRMWARE, |
2795 | &udev->dev, | 2796 | &udev->dev, |
2796 | GFP_KERNEL, | 2797 | GFP_KERNEL, |
2797 | usbduxsub + index, | 2798 | usbduxsub + index, |
@@ -2850,3 +2851,4 @@ module_comedi_usb_driver(usbdux_driver, usbdux_usb_driver); | |||
2850 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); | 2851 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); |
2851 | MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com"); | 2852 | MODULE_DESCRIPTION("Stirling/ITL USB-DUX -- Bernd.Porr@f2s.com"); |
2852 | MODULE_LICENSE("GPL"); | 2853 | MODULE_LICENSE("GPL"); |
2854 | MODULE_FIRMWARE(FIRMWARE); | ||
diff --git a/drivers/staging/comedi/drivers/usbduxfast.c b/drivers/staging/comedi/drivers/usbduxfast.c index d9911588c10a..8eb41257c6ce 100644 --- a/drivers/staging/comedi/drivers/usbduxfast.c +++ b/drivers/staging/comedi/drivers/usbduxfast.c | |||
@@ -57,6 +57,7 @@ | |||
57 | /* | 57 | /* |
58 | * constants for "firmware" upload and download | 58 | * constants for "firmware" upload and download |
59 | */ | 59 | */ |
60 | #define FIRMWARE "usbduxfast_firmware.bin" | ||
60 | #define USBDUXFASTSUB_FIRMWARE 0xA0 | 61 | #define USBDUXFASTSUB_FIRMWARE 0xA0 |
61 | #define VENDOR_DIR_IN 0xC0 | 62 | #define VENDOR_DIR_IN 0xC0 |
62 | #define VENDOR_DIR_OUT 0x40 | 63 | #define VENDOR_DIR_OUT 0x40 |
@@ -1706,7 +1707,7 @@ static int usbduxfast_usb_probe(struct usb_interface *uinterf, | |||
1706 | 1707 | ||
1707 | ret = request_firmware_nowait(THIS_MODULE, | 1708 | ret = request_firmware_nowait(THIS_MODULE, |
1708 | FW_ACTION_HOTPLUG, | 1709 | FW_ACTION_HOTPLUG, |
1709 | "usbduxfast_firmware.bin", | 1710 | FIRMWARE, |
1710 | &udev->dev, | 1711 | &udev->dev, |
1711 | GFP_KERNEL, | 1712 | GFP_KERNEL, |
1712 | usbduxfastsub + index, | 1713 | usbduxfastsub + index, |
@@ -1774,3 +1775,4 @@ module_comedi_usb_driver(usbduxfast_driver, usbduxfast_usb_driver); | |||
1774 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); | 1775 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); |
1775 | MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com"); | 1776 | MODULE_DESCRIPTION("USB-DUXfast, BerndPorr@f2s.com"); |
1776 | MODULE_LICENSE("GPL"); | 1777 | MODULE_LICENSE("GPL"); |
1778 | MODULE_FIRMWARE(FIRMWARE); | ||
diff --git a/drivers/staging/comedi/drivers/usbduxsigma.c b/drivers/staging/comedi/drivers/usbduxsigma.c index 543e604791e2..f54ab8c2fcfd 100644 --- a/drivers/staging/comedi/drivers/usbduxsigma.c +++ b/drivers/staging/comedi/drivers/usbduxsigma.c | |||
@@ -63,6 +63,7 @@ Status: testing | |||
63 | #define BULK_TIMEOUT 1000 | 63 | #define BULK_TIMEOUT 1000 |
64 | 64 | ||
65 | /* constants for "firmware" upload and download */ | 65 | /* constants for "firmware" upload and download */ |
66 | #define FIRMWARE "usbduxsigma_firmware.bin" | ||
66 | #define USBDUXSUB_FIRMWARE 0xA0 | 67 | #define USBDUXSUB_FIRMWARE 0xA0 |
67 | #define VENDOR_DIR_IN 0xC0 | 68 | #define VENDOR_DIR_IN 0xC0 |
68 | #define VENDOR_DIR_OUT 0x40 | 69 | #define VENDOR_DIR_OUT 0x40 |
@@ -2780,7 +2781,7 @@ static int usbduxsigma_usb_probe(struct usb_interface *uinterf, | |||
2780 | 2781 | ||
2781 | ret = request_firmware_nowait(THIS_MODULE, | 2782 | ret = request_firmware_nowait(THIS_MODULE, |
2782 | FW_ACTION_HOTPLUG, | 2783 | FW_ACTION_HOTPLUG, |
2783 | "usbduxsigma_firmware.bin", | 2784 | FIRMWARE, |
2784 | &udev->dev, | 2785 | &udev->dev, |
2785 | GFP_KERNEL, | 2786 | GFP_KERNEL, |
2786 | usbduxsub + index, | 2787 | usbduxsub + index, |
@@ -2845,3 +2846,4 @@ module_comedi_usb_driver(usbduxsigma_driver, usbduxsigma_usb_driver); | |||
2845 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); | 2846 | MODULE_AUTHOR("Bernd Porr, BerndPorr@f2s.com"); |
2846 | MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com"); | 2847 | MODULE_DESCRIPTION("Stirling/ITL USB-DUX SIGMA -- Bernd.Porr@f2s.com"); |
2847 | MODULE_LICENSE("GPL"); | 2848 | MODULE_LICENSE("GPL"); |
2849 | MODULE_FIRMWARE(FIRMWARE); | ||
diff --git a/drivers/staging/csr/Kconfig b/drivers/staging/csr/Kconfig index cee8d48d2af9..ad2a1096e920 100644 --- a/drivers/staging/csr/Kconfig +++ b/drivers/staging/csr/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config CSR_WIFI | 1 | config CSR_WIFI |
2 | tristate "CSR wireless driver" | 2 | tristate "CSR wireless driver" |
3 | depends on MMC && CFG80211_WEXT | 3 | depends on MMC && CFG80211_WEXT && INET |
4 | select WIRELESS_EXT | 4 | select WIRELESS_EXT |
5 | select WEXT_PRIV | 5 | select WEXT_PRIV |
6 | help | 6 | help |
diff --git a/drivers/staging/iio/adc/ad7192.c b/drivers/staging/iio/adc/ad7192.c index 22c3923d55eb..095837285f4f 100644 --- a/drivers/staging/iio/adc/ad7192.c +++ b/drivers/staging/iio/adc/ad7192.c | |||
@@ -754,7 +754,7 @@ static ssize_t ad7192_set(struct device *dev, | |||
754 | else | 754 | else |
755 | st->mode &= ~AD7192_MODE_ACX; | 755 | st->mode &= ~AD7192_MODE_ACX; |
756 | 756 | ||
757 | ad7192_write_reg(st, AD7192_REG_GPOCON, 3, st->mode); | 757 | ad7192_write_reg(st, AD7192_REG_MODE, 3, st->mode); |
758 | break; | 758 | break; |
759 | default: | 759 | default: |
760 | ret = -EINVAL; | 760 | ret = -EINVAL; |
@@ -798,6 +798,11 @@ static const struct attribute_group ad7195_attribute_group = { | |||
798 | .attrs = ad7195_attributes, | 798 | .attrs = ad7195_attributes, |
799 | }; | 799 | }; |
800 | 800 | ||
801 | static unsigned int ad7192_get_temp_scale(bool unipolar) | ||
802 | { | ||
803 | return unipolar ? 2815 * 2 : 2815; | ||
804 | } | ||
805 | |||
801 | static int ad7192_read_raw(struct iio_dev *indio_dev, | 806 | static int ad7192_read_raw(struct iio_dev *indio_dev, |
802 | struct iio_chan_spec const *chan, | 807 | struct iio_chan_spec const *chan, |
803 | int *val, | 808 | int *val, |
@@ -824,19 +829,6 @@ static int ad7192_read_raw(struct iio_dev *indio_dev, | |||
824 | *val = (smpl >> chan->scan_type.shift) & | 829 | *val = (smpl >> chan->scan_type.shift) & |
825 | ((1 << (chan->scan_type.realbits)) - 1); | 830 | ((1 << (chan->scan_type.realbits)) - 1); |
826 | 831 | ||
827 | switch (chan->type) { | ||
828 | case IIO_VOLTAGE: | ||
829 | if (!unipolar) | ||
830 | *val -= (1 << (chan->scan_type.realbits - 1)); | ||
831 | break; | ||
832 | case IIO_TEMP: | ||
833 | *val -= 0x800000; | ||
834 | *val /= 2815; /* temp Kelvin */ | ||
835 | *val -= 273; /* temp Celsius */ | ||
836 | break; | ||
837 | default: | ||
838 | return -EINVAL; | ||
839 | } | ||
840 | return IIO_VAL_INT; | 832 | return IIO_VAL_INT; |
841 | 833 | ||
842 | case IIO_CHAN_INFO_SCALE: | 834 | case IIO_CHAN_INFO_SCALE: |
@@ -848,11 +840,21 @@ static int ad7192_read_raw(struct iio_dev *indio_dev, | |||
848 | mutex_unlock(&indio_dev->mlock); | 840 | mutex_unlock(&indio_dev->mlock); |
849 | return IIO_VAL_INT_PLUS_NANO; | 841 | return IIO_VAL_INT_PLUS_NANO; |
850 | case IIO_TEMP: | 842 | case IIO_TEMP: |
851 | *val = 1000; | 843 | *val = 0; |
852 | return IIO_VAL_INT; | 844 | *val2 = 1000000000 / ad7192_get_temp_scale(unipolar); |
845 | return IIO_VAL_INT_PLUS_NANO; | ||
853 | default: | 846 | default: |
854 | return -EINVAL; | 847 | return -EINVAL; |
855 | } | 848 | } |
849 | case IIO_CHAN_INFO_OFFSET: | ||
850 | if (!unipolar) | ||
851 | *val = -(1 << (chan->scan_type.realbits - 1)); | ||
852 | else | ||
853 | *val = 0; | ||
854 | /* Kelvin to Celsius */ | ||
855 | if (chan->type == IIO_TEMP) | ||
856 | *val -= 273 * ad7192_get_temp_scale(unipolar); | ||
857 | return IIO_VAL_INT; | ||
856 | } | 858 | } |
857 | 859 | ||
858 | return -EINVAL; | 860 | return -EINVAL; |
@@ -890,7 +892,7 @@ static int ad7192_write_raw(struct iio_dev *indio_dev, | |||
890 | } | 892 | } |
891 | ret = 0; | 893 | ret = 0; |
892 | } | 894 | } |
893 | 895 | break; | |
894 | default: | 896 | default: |
895 | ret = -EINVAL; | 897 | ret = -EINVAL; |
896 | } | 898 | } |
@@ -942,20 +944,22 @@ static const struct iio_info ad7195_info = { | |||
942 | .channel = _chan, \ | 944 | .channel = _chan, \ |
943 | .channel2 = _chan2, \ | 945 | .channel2 = _chan2, \ |
944 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ | 946 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ |
945 | IIO_CHAN_INFO_SCALE_SHARED_BIT, \ | 947 | IIO_CHAN_INFO_SCALE_SHARED_BIT | \ |
948 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ | ||
946 | .address = _address, \ | 949 | .address = _address, \ |
947 | .scan_index = _si, \ | 950 | .scan_index = _si, \ |
948 | .scan_type = IIO_ST('s', 24, 32, 0)} | 951 | .scan_type = IIO_ST('u', 24, 32, 0)} |
949 | 952 | ||
950 | #define AD7192_CHAN(_chan, _address, _si) \ | 953 | #define AD7192_CHAN(_chan, _address, _si) \ |
951 | { .type = IIO_VOLTAGE, \ | 954 | { .type = IIO_VOLTAGE, \ |
952 | .indexed = 1, \ | 955 | .indexed = 1, \ |
953 | .channel = _chan, \ | 956 | .channel = _chan, \ |
954 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ | 957 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | \ |
955 | IIO_CHAN_INFO_SCALE_SHARED_BIT, \ | 958 | IIO_CHAN_INFO_SCALE_SHARED_BIT | \ |
959 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, \ | ||
956 | .address = _address, \ | 960 | .address = _address, \ |
957 | .scan_index = _si, \ | 961 | .scan_index = _si, \ |
958 | .scan_type = IIO_ST('s', 24, 32, 0)} | 962 | .scan_type = IIO_ST('u', 24, 32, 0)} |
959 | 963 | ||
960 | #define AD7192_CHAN_TEMP(_chan, _address, _si) \ | 964 | #define AD7192_CHAN_TEMP(_chan, _address, _si) \ |
961 | { .type = IIO_TEMP, \ | 965 | { .type = IIO_TEMP, \ |
@@ -965,7 +969,7 @@ static const struct iio_info ad7195_info = { | |||
965 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ | 969 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, \ |
966 | .address = _address, \ | 970 | .address = _address, \ |
967 | .scan_index = _si, \ | 971 | .scan_index = _si, \ |
968 | .scan_type = IIO_ST('s', 24, 32, 0)} | 972 | .scan_type = IIO_ST('u', 24, 32, 0)} |
969 | 973 | ||
970 | static struct iio_chan_spec ad7192_channels[] = { | 974 | static struct iio_chan_spec ad7192_channels[] = { |
971 | AD7192_CHAN_DIFF(1, 2, NULL, AD7192_CH_AIN1P_AIN2M, 0), | 975 | AD7192_CHAN_DIFF(1, 2, NULL, AD7192_CH_AIN1P_AIN2M, 0), |
diff --git a/drivers/staging/iio/adc/ad7298_ring.c b/drivers/staging/iio/adc/ad7298_ring.c index fd1d855ff57a..506016f01593 100644 --- a/drivers/staging/iio/adc/ad7298_ring.c +++ b/drivers/staging/iio/adc/ad7298_ring.c | |||
@@ -76,7 +76,7 @@ static irqreturn_t ad7298_trigger_handler(int irq, void *p) | |||
76 | struct iio_dev *indio_dev = pf->indio_dev; | 76 | struct iio_dev *indio_dev = pf->indio_dev; |
77 | struct ad7298_state *st = iio_priv(indio_dev); | 77 | struct ad7298_state *st = iio_priv(indio_dev); |
78 | struct iio_buffer *ring = indio_dev->buffer; | 78 | struct iio_buffer *ring = indio_dev->buffer; |
79 | s64 time_ns; | 79 | s64 time_ns = 0; |
80 | __u16 buf[16]; | 80 | __u16 buf[16]; |
81 | int b_sent, i; | 81 | int b_sent, i; |
82 | 82 | ||
diff --git a/drivers/staging/iio/adc/ad7780.c b/drivers/staging/iio/adc/ad7780.c index 1ece2ac8de56..19ee49c95de4 100644 --- a/drivers/staging/iio/adc/ad7780.c +++ b/drivers/staging/iio/adc/ad7780.c | |||
@@ -131,9 +131,10 @@ static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { | |||
131 | .indexed = 1, | 131 | .indexed = 1, |
132 | .channel = 0, | 132 | .channel = 0, |
133 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 133 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
134 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 134 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
135 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
135 | .scan_type = { | 136 | .scan_type = { |
136 | .sign = 's', | 137 | .sign = 'u', |
137 | .realbits = 24, | 138 | .realbits = 24, |
138 | .storagebits = 32, | 139 | .storagebits = 32, |
139 | .shift = 8, | 140 | .shift = 8, |
@@ -146,9 +147,10 @@ static const struct ad7780_chip_info ad7780_chip_info_tbl[] = { | |||
146 | .indexed = 1, | 147 | .indexed = 1, |
147 | .channel = 0, | 148 | .channel = 0, |
148 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 149 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
149 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 150 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
151 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
150 | .scan_type = { | 152 | .scan_type = { |
151 | .sign = 's', | 153 | .sign = 'u', |
152 | .realbits = 20, | 154 | .realbits = 20, |
153 | .storagebits = 32, | 155 | .storagebits = 32, |
154 | .shift = 12, | 156 | .shift = 12, |
diff --git a/drivers/staging/iio/adc/ad7793.c b/drivers/staging/iio/adc/ad7793.c index 76fdd7145fc5..112e2b7b5bc4 100644 --- a/drivers/staging/iio/adc/ad7793.c +++ b/drivers/staging/iio/adc/ad7793.c | |||
@@ -563,8 +563,9 @@ static ssize_t ad7793_show_scale_available(struct device *dev, | |||
563 | return len; | 563 | return len; |
564 | } | 564 | } |
565 | 565 | ||
566 | static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available, in-in_scale_available, | 566 | static IIO_DEVICE_ATTR_NAMED(in_m_in_scale_available, |
567 | S_IRUGO, ad7793_show_scale_available, NULL, 0); | 567 | in_voltage-voltage_scale_available, S_IRUGO, |
568 | ad7793_show_scale_available, NULL, 0); | ||
568 | 569 | ||
569 | static struct attribute *ad7793_attributes[] = { | 570 | static struct attribute *ad7793_attributes[] = { |
570 | &iio_dev_attr_sampling_frequency.dev_attr.attr, | 571 | &iio_dev_attr_sampling_frequency.dev_attr.attr, |
@@ -604,9 +605,6 @@ static int ad7793_read_raw(struct iio_dev *indio_dev, | |||
604 | *val = (smpl >> chan->scan_type.shift) & | 605 | *val = (smpl >> chan->scan_type.shift) & |
605 | ((1 << (chan->scan_type.realbits)) - 1); | 606 | ((1 << (chan->scan_type.realbits)) - 1); |
606 | 607 | ||
607 | if (!unipolar) | ||
608 | *val -= (1 << (chan->scan_type.realbits - 1)); | ||
609 | |||
610 | return IIO_VAL_INT; | 608 | return IIO_VAL_INT; |
611 | 609 | ||
612 | case IIO_CHAN_INFO_SCALE: | 610 | case IIO_CHAN_INFO_SCALE: |
@@ -620,25 +618,38 @@ static int ad7793_read_raw(struct iio_dev *indio_dev, | |||
620 | return IIO_VAL_INT_PLUS_NANO; | 618 | return IIO_VAL_INT_PLUS_NANO; |
621 | } else { | 619 | } else { |
622 | /* 1170mV / 2^23 * 6 */ | 620 | /* 1170mV / 2^23 * 6 */ |
623 | scale_uv = (1170ULL * 100000000ULL * 6ULL) | 621 | scale_uv = (1170ULL * 100000000ULL * 6ULL); |
624 | >> (chan->scan_type.realbits - | ||
625 | (unipolar ? 0 : 1)); | ||
626 | } | 622 | } |
627 | break; | 623 | break; |
628 | case IIO_TEMP: | 624 | case IIO_TEMP: |
629 | /* Always uses unity gain and internal ref */ | 625 | /* 1170mV / 0.81 mV/C / 2^23 */ |
630 | scale_uv = (2500ULL * 100000000ULL) | 626 | scale_uv = 1444444444444ULL; |
631 | >> (chan->scan_type.realbits - | ||
632 | (unipolar ? 0 : 1)); | ||
633 | break; | 627 | break; |
634 | default: | 628 | default: |
635 | return -EINVAL; | 629 | return -EINVAL; |
636 | } | 630 | } |
637 | 631 | ||
638 | *val2 = do_div(scale_uv, 100000000) * 10; | 632 | scale_uv >>= (chan->scan_type.realbits - (unipolar ? 0 : 1)); |
639 | *val = scale_uv; | 633 | *val = 0; |
640 | 634 | *val2 = scale_uv; | |
641 | return IIO_VAL_INT_PLUS_NANO; | 635 | return IIO_VAL_INT_PLUS_NANO; |
636 | case IIO_CHAN_INFO_OFFSET: | ||
637 | if (!unipolar) | ||
638 | *val = -(1 << (chan->scan_type.realbits - 1)); | ||
639 | else | ||
640 | *val = 0; | ||
641 | |||
642 | /* Kelvin to Celsius */ | ||
643 | if (chan->type == IIO_TEMP) { | ||
644 | unsigned long long offset; | ||
645 | unsigned int shift; | ||
646 | |||
647 | shift = chan->scan_type.realbits - (unipolar ? 0 : 1); | ||
648 | offset = 273ULL << shift; | ||
649 | do_div(offset, 1444); | ||
650 | *val -= offset; | ||
651 | } | ||
652 | return IIO_VAL_INT; | ||
642 | } | 653 | } |
643 | return -EINVAL; | 654 | return -EINVAL; |
644 | } | 655 | } |
@@ -676,7 +687,7 @@ static int ad7793_write_raw(struct iio_dev *indio_dev, | |||
676 | } | 687 | } |
677 | ret = 0; | 688 | ret = 0; |
678 | } | 689 | } |
679 | 690 | break; | |
680 | default: | 691 | default: |
681 | ret = -EINVAL; | 692 | ret = -EINVAL; |
682 | } | 693 | } |
@@ -720,9 +731,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
720 | .channel2 = 0, | 731 | .channel2 = 0, |
721 | .address = AD7793_CH_AIN1P_AIN1M, | 732 | .address = AD7793_CH_AIN1P_AIN1M, |
722 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 733 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
723 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 734 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
735 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
724 | .scan_index = 0, | 736 | .scan_index = 0, |
725 | .scan_type = IIO_ST('s', 24, 32, 0) | 737 | .scan_type = IIO_ST('u', 24, 32, 0) |
726 | }, | 738 | }, |
727 | .channel[1] = { | 739 | .channel[1] = { |
728 | .type = IIO_VOLTAGE, | 740 | .type = IIO_VOLTAGE, |
@@ -732,9 +744,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
732 | .channel2 = 1, | 744 | .channel2 = 1, |
733 | .address = AD7793_CH_AIN2P_AIN2M, | 745 | .address = AD7793_CH_AIN2P_AIN2M, |
734 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 746 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
735 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 747 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
748 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
736 | .scan_index = 1, | 749 | .scan_index = 1, |
737 | .scan_type = IIO_ST('s', 24, 32, 0) | 750 | .scan_type = IIO_ST('u', 24, 32, 0) |
738 | }, | 751 | }, |
739 | .channel[2] = { | 752 | .channel[2] = { |
740 | .type = IIO_VOLTAGE, | 753 | .type = IIO_VOLTAGE, |
@@ -744,9 +757,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
744 | .channel2 = 2, | 757 | .channel2 = 2, |
745 | .address = AD7793_CH_AIN3P_AIN3M, | 758 | .address = AD7793_CH_AIN3P_AIN3M, |
746 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 759 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
747 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 760 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
761 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
748 | .scan_index = 2, | 762 | .scan_index = 2, |
749 | .scan_type = IIO_ST('s', 24, 32, 0) | 763 | .scan_type = IIO_ST('u', 24, 32, 0) |
750 | }, | 764 | }, |
751 | .channel[3] = { | 765 | .channel[3] = { |
752 | .type = IIO_VOLTAGE, | 766 | .type = IIO_VOLTAGE, |
@@ -757,9 +771,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
757 | .channel2 = 2, | 771 | .channel2 = 2, |
758 | .address = AD7793_CH_AIN1M_AIN1M, | 772 | .address = AD7793_CH_AIN1M_AIN1M, |
759 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 773 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
760 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 774 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
775 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
761 | .scan_index = 3, | 776 | .scan_index = 3, |
762 | .scan_type = IIO_ST('s', 24, 32, 0) | 777 | .scan_type = IIO_ST('u', 24, 32, 0) |
763 | }, | 778 | }, |
764 | .channel[4] = { | 779 | .channel[4] = { |
765 | .type = IIO_TEMP, | 780 | .type = IIO_TEMP, |
@@ -769,7 +784,7 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
769 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 784 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
770 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, | 785 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, |
771 | .scan_index = 4, | 786 | .scan_index = 4, |
772 | .scan_type = IIO_ST('s', 24, 32, 0), | 787 | .scan_type = IIO_ST('u', 24, 32, 0), |
773 | }, | 788 | }, |
774 | .channel[5] = { | 789 | .channel[5] = { |
775 | .type = IIO_VOLTAGE, | 790 | .type = IIO_VOLTAGE, |
@@ -778,9 +793,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
778 | .channel = 4, | 793 | .channel = 4, |
779 | .address = AD7793_CH_AVDD_MONITOR, | 794 | .address = AD7793_CH_AVDD_MONITOR, |
780 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 795 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
781 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, | 796 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT | |
797 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
782 | .scan_index = 5, | 798 | .scan_index = 5, |
783 | .scan_type = IIO_ST('s', 24, 32, 0), | 799 | .scan_type = IIO_ST('u', 24, 32, 0), |
784 | }, | 800 | }, |
785 | .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), | 801 | .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), |
786 | }, | 802 | }, |
@@ -793,9 +809,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
793 | .channel2 = 0, | 809 | .channel2 = 0, |
794 | .address = AD7793_CH_AIN1P_AIN1M, | 810 | .address = AD7793_CH_AIN1P_AIN1M, |
795 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 811 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
796 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 812 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
813 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
797 | .scan_index = 0, | 814 | .scan_index = 0, |
798 | .scan_type = IIO_ST('s', 16, 32, 0) | 815 | .scan_type = IIO_ST('u', 16, 32, 0) |
799 | }, | 816 | }, |
800 | .channel[1] = { | 817 | .channel[1] = { |
801 | .type = IIO_VOLTAGE, | 818 | .type = IIO_VOLTAGE, |
@@ -805,9 +822,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
805 | .channel2 = 1, | 822 | .channel2 = 1, |
806 | .address = AD7793_CH_AIN2P_AIN2M, | 823 | .address = AD7793_CH_AIN2P_AIN2M, |
807 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 824 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
808 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 825 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
826 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
809 | .scan_index = 1, | 827 | .scan_index = 1, |
810 | .scan_type = IIO_ST('s', 16, 32, 0) | 828 | .scan_type = IIO_ST('u', 16, 32, 0) |
811 | }, | 829 | }, |
812 | .channel[2] = { | 830 | .channel[2] = { |
813 | .type = IIO_VOLTAGE, | 831 | .type = IIO_VOLTAGE, |
@@ -817,9 +835,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
817 | .channel2 = 2, | 835 | .channel2 = 2, |
818 | .address = AD7793_CH_AIN3P_AIN3M, | 836 | .address = AD7793_CH_AIN3P_AIN3M, |
819 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 837 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
820 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 838 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
839 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
821 | .scan_index = 2, | 840 | .scan_index = 2, |
822 | .scan_type = IIO_ST('s', 16, 32, 0) | 841 | .scan_type = IIO_ST('u', 16, 32, 0) |
823 | }, | 842 | }, |
824 | .channel[3] = { | 843 | .channel[3] = { |
825 | .type = IIO_VOLTAGE, | 844 | .type = IIO_VOLTAGE, |
@@ -830,9 +849,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
830 | .channel2 = 2, | 849 | .channel2 = 2, |
831 | .address = AD7793_CH_AIN1M_AIN1M, | 850 | .address = AD7793_CH_AIN1M_AIN1M, |
832 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 851 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
833 | IIO_CHAN_INFO_SCALE_SHARED_BIT, | 852 | IIO_CHAN_INFO_SCALE_SHARED_BIT | |
853 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
834 | .scan_index = 3, | 854 | .scan_index = 3, |
835 | .scan_type = IIO_ST('s', 16, 32, 0) | 855 | .scan_type = IIO_ST('u', 16, 32, 0) |
836 | }, | 856 | }, |
837 | .channel[4] = { | 857 | .channel[4] = { |
838 | .type = IIO_TEMP, | 858 | .type = IIO_TEMP, |
@@ -842,7 +862,7 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
842 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 862 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
843 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, | 863 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, |
844 | .scan_index = 4, | 864 | .scan_index = 4, |
845 | .scan_type = IIO_ST('s', 16, 32, 0), | 865 | .scan_type = IIO_ST('u', 16, 32, 0), |
846 | }, | 866 | }, |
847 | .channel[5] = { | 867 | .channel[5] = { |
848 | .type = IIO_VOLTAGE, | 868 | .type = IIO_VOLTAGE, |
@@ -851,9 +871,10 @@ static const struct ad7793_chip_info ad7793_chip_info_tbl[] = { | |||
851 | .channel = 4, | 871 | .channel = 4, |
852 | .address = AD7793_CH_AVDD_MONITOR, | 872 | .address = AD7793_CH_AVDD_MONITOR, |
853 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | | 873 | .info_mask = IIO_CHAN_INFO_RAW_SEPARATE_BIT | |
854 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT, | 874 | IIO_CHAN_INFO_SCALE_SEPARATE_BIT | |
875 | IIO_CHAN_INFO_OFFSET_SHARED_BIT, | ||
855 | .scan_index = 5, | 876 | .scan_index = 5, |
856 | .scan_type = IIO_ST('s', 16, 32, 0), | 877 | .scan_type = IIO_ST('u', 16, 32, 0), |
857 | }, | 878 | }, |
858 | .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), | 879 | .channel[6] = IIO_CHAN_SOFT_TIMESTAMP(6), |
859 | }, | 880 | }, |
@@ -901,7 +922,7 @@ static int __devinit ad7793_probe(struct spi_device *spi) | |||
901 | else if (voltage_uv) | 922 | else if (voltage_uv) |
902 | st->int_vref_mv = voltage_uv / 1000; | 923 | st->int_vref_mv = voltage_uv / 1000; |
903 | else | 924 | else |
904 | st->int_vref_mv = 2500; /* Build-in ref */ | 925 | st->int_vref_mv = 1170; /* Build-in ref */ |
905 | 926 | ||
906 | spi_set_drvdata(spi, indio_dev); | 927 | spi_set_drvdata(spi, indio_dev); |
907 | st->spi = spi; | 928 | st->spi = spi; |
diff --git a/drivers/staging/olpc_dcon/olpc_dcon.c b/drivers/staging/olpc_dcon/olpc_dcon.c index 992275c0d87c..2c4bd746715a 100644 --- a/drivers/staging/olpc_dcon/olpc_dcon.c +++ b/drivers/staging/olpc_dcon/olpc_dcon.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <linux/uaccess.h> | 27 | #include <linux/uaccess.h> |
28 | #include <linux/ctype.h> | 28 | #include <linux/ctype.h> |
29 | #include <linux/reboot.h> | 29 | #include <linux/reboot.h> |
30 | #include <linux/olpc-ec.h> | ||
30 | #include <asm/tsc.h> | 31 | #include <asm/tsc.h> |
31 | #include <asm/olpc.h> | 32 | #include <asm/olpc.h> |
32 | 33 | ||
diff --git a/drivers/staging/vt6656/main_usb.c b/drivers/staging/vt6656/main_usb.c index b06fd5b723fa..d536756549e6 100644 --- a/drivers/staging/vt6656/main_usb.c +++ b/drivers/staging/vt6656/main_usb.c | |||
@@ -189,7 +189,7 @@ DEVICE_PARAM(b80211hEnable, "802.11h mode"); | |||
189 | // Static vars definitions | 189 | // Static vars definitions |
190 | // | 190 | // |
191 | 191 | ||
192 | static struct usb_device_id vt6656_table[] __devinitdata = { | 192 | static struct usb_device_id vt6656_table[] = { |
193 | {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)}, | 193 | {USB_DEVICE(VNT_USB_VENDOR_ID, VNT_USB_PRODUCT_ID)}, |
194 | {} | 194 | {} |
195 | }; | 195 | }; |
diff --git a/drivers/staging/winbond/wbusb.c b/drivers/staging/winbond/wbusb.c index ef360547ecec..0ca857ac473e 100644 --- a/drivers/staging/winbond/wbusb.c +++ b/drivers/staging/winbond/wbusb.c | |||
@@ -25,7 +25,7 @@ MODULE_DESCRIPTION("IS89C35 802.11bg WLAN USB Driver"); | |||
25 | MODULE_LICENSE("GPL"); | 25 | MODULE_LICENSE("GPL"); |
26 | MODULE_VERSION("0.1"); | 26 | MODULE_VERSION("0.1"); |
27 | 27 | ||
28 | static const struct usb_device_id wb35_table[] __devinitconst = { | 28 | static const struct usb_device_id wb35_table[] = { |
29 | { USB_DEVICE(0x0416, 0x0035) }, | 29 | { USB_DEVICE(0x0416, 0x0035) }, |
30 | { USB_DEVICE(0x18E8, 0x6201) }, | 30 | { USB_DEVICE(0x18E8, 0x6201) }, |
31 | { USB_DEVICE(0x18E8, 0x6206) }, | 31 | { USB_DEVICE(0x18E8, 0x6206) }, |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 070b442c1f81..4720b4ba096a 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -160,10 +160,12 @@ config SERIAL_KS8695_CONSOLE | |||
160 | 160 | ||
161 | config SERIAL_CLPS711X | 161 | config SERIAL_CLPS711X |
162 | tristate "CLPS711X serial port support" | 162 | tristate "CLPS711X serial port support" |
163 | depends on ARM && ARCH_CLPS711X | 163 | depends on ARCH_CLPS711X |
164 | select SERIAL_CORE | 164 | select SERIAL_CORE |
165 | default y | ||
165 | help | 166 | help |
166 | ::: To be written ::: | 167 | This enables the driver for the on-chip UARTs of the Cirrus |
168 | Logic EP711x/EP721x/EP731x processors. | ||
167 | 169 | ||
168 | config SERIAL_CLPS711X_CONSOLE | 170 | config SERIAL_CLPS711X_CONSOLE |
169 | bool "Support for console on CLPS711X serial port" | 171 | bool "Support for console on CLPS711X serial port" |
@@ -173,9 +175,7 @@ config SERIAL_CLPS711X_CONSOLE | |||
173 | Even if you say Y here, the currently visible virtual console | 175 | Even if you say Y here, the currently visible virtual console |
174 | (/dev/tty0) will still be used as the system console by default, but | 176 | (/dev/tty0) will still be used as the system console by default, but |
175 | you can alter that using a kernel command line option such as | 177 | you can alter that using a kernel command line option such as |
176 | "console=ttyCL1". (Try "man bootparam" or see the documentation of | 178 | "console=ttyCL1". |
177 | your boot loader (lilo or loadlin) about how to pass options to the | ||
178 | kernel at boot time.) | ||
179 | 179 | ||
180 | config SERIAL_SAMSUNG | 180 | config SERIAL_SAMSUNG |
181 | tristate "Samsung SoC serial support" | 181 | tristate "Samsung SoC serial support" |
diff --git a/drivers/tty/serial/ifx6x60.c b/drivers/tty/serial/ifx6x60.c index 144cd3987d4c..3ad079ffd049 100644 --- a/drivers/tty/serial/ifx6x60.c +++ b/drivers/tty/serial/ifx6x60.c | |||
@@ -1331,7 +1331,7 @@ static const struct spi_device_id ifx_id_table[] = { | |||
1331 | MODULE_DEVICE_TABLE(spi, ifx_id_table); | 1331 | MODULE_DEVICE_TABLE(spi, ifx_id_table); |
1332 | 1332 | ||
1333 | /* spi operations */ | 1333 | /* spi operations */ |
1334 | static const struct spi_driver ifx_spi_driver = { | 1334 | static struct spi_driver ifx_spi_driver = { |
1335 | .driver = { | 1335 | .driver = { |
1336 | .name = DRVNAME, | 1336 | .name = DRVNAME, |
1337 | .pm = &ifx_spi_pm, | 1337 | .pm = &ifx_spi_pm, |
diff --git a/drivers/tty/serial/mxs-auart.c b/drivers/tty/serial/mxs-auart.c index 2e341b81ff89..3a667eed63d6 100644 --- a/drivers/tty/serial/mxs-auart.c +++ b/drivers/tty/serial/mxs-auart.c | |||
@@ -73,6 +73,7 @@ | |||
73 | #define AUART_CTRL0_CLKGATE (1 << 30) | 73 | #define AUART_CTRL0_CLKGATE (1 << 30) |
74 | 74 | ||
75 | #define AUART_CTRL2_CTSEN (1 << 15) | 75 | #define AUART_CTRL2_CTSEN (1 << 15) |
76 | #define AUART_CTRL2_RTSEN (1 << 14) | ||
76 | #define AUART_CTRL2_RTS (1 << 11) | 77 | #define AUART_CTRL2_RTS (1 << 11) |
77 | #define AUART_CTRL2_RXE (1 << 9) | 78 | #define AUART_CTRL2_RXE (1 << 9) |
78 | #define AUART_CTRL2_TXE (1 << 8) | 79 | #define AUART_CTRL2_TXE (1 << 8) |
@@ -259,9 +260,12 @@ static void mxs_auart_set_mctrl(struct uart_port *u, unsigned mctrl) | |||
259 | 260 | ||
260 | u32 ctrl = readl(u->membase + AUART_CTRL2); | 261 | u32 ctrl = readl(u->membase + AUART_CTRL2); |
261 | 262 | ||
262 | ctrl &= ~AUART_CTRL2_RTS; | 263 | ctrl &= ~AUART_CTRL2_RTSEN; |
263 | if (mctrl & TIOCM_RTS) | 264 | if (mctrl & TIOCM_RTS) { |
264 | ctrl |= AUART_CTRL2_RTS; | 265 | if (u->state->port.flags & ASYNC_CTS_FLOW) |
266 | ctrl |= AUART_CTRL2_RTSEN; | ||
267 | } | ||
268 | |||
265 | s->ctrl = mctrl; | 269 | s->ctrl = mctrl; |
266 | writel(ctrl, u->membase + AUART_CTRL2); | 270 | writel(ctrl, u->membase + AUART_CTRL2); |
267 | } | 271 | } |
@@ -359,9 +363,9 @@ static void mxs_auart_settermios(struct uart_port *u, | |||
359 | 363 | ||
360 | /* figure out the hardware flow control settings */ | 364 | /* figure out the hardware flow control settings */ |
361 | if (cflag & CRTSCTS) | 365 | if (cflag & CRTSCTS) |
362 | ctrl2 |= AUART_CTRL2_CTSEN; | 366 | ctrl2 |= AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN; |
363 | else | 367 | else |
364 | ctrl2 &= ~AUART_CTRL2_CTSEN; | 368 | ctrl2 &= ~(AUART_CTRL2_CTSEN | AUART_CTRL2_RTSEN); |
365 | 369 | ||
366 | /* set baud rate */ | 370 | /* set baud rate */ |
367 | baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk); | 371 | baud = uart_get_baud_rate(u, termios, old, 0, u->uartclk); |
diff --git a/drivers/tty/serial/pmac_zilog.c b/drivers/tty/serial/pmac_zilog.c index 654755a990df..333c8d012b0e 100644 --- a/drivers/tty/serial/pmac_zilog.c +++ b/drivers/tty/serial/pmac_zilog.c | |||
@@ -1348,10 +1348,16 @@ static int pmz_verify_port(struct uart_port *port, struct serial_struct *ser) | |||
1348 | static int pmz_poll_get_char(struct uart_port *port) | 1348 | static int pmz_poll_get_char(struct uart_port *port) |
1349 | { | 1349 | { |
1350 | struct uart_pmac_port *uap = (struct uart_pmac_port *)port; | 1350 | struct uart_pmac_port *uap = (struct uart_pmac_port *)port; |
1351 | int tries = 2; | ||
1351 | 1352 | ||
1352 | while ((read_zsreg(uap, R0) & Rx_CH_AV) == 0) | 1353 | while (tries) { |
1353 | udelay(5); | 1354 | if ((read_zsreg(uap, R0) & Rx_CH_AV) != 0) |
1354 | return read_zsdata(uap); | 1355 | return read_zsdata(uap); |
1356 | if (tries--) | ||
1357 | udelay(5); | ||
1358 | } | ||
1359 | |||
1360 | return NO_POLL_CHAR; | ||
1355 | } | 1361 | } |
1356 | 1362 | ||
1357 | static void pmz_poll_put_char(struct uart_port *port, unsigned char c) | 1363 | static void pmz_poll_put_char(struct uart_port *port, unsigned char c) |
diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index d4d8c9453cd8..9be296cf7295 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c | |||
@@ -25,6 +25,7 @@ | |||
25 | 25 | ||
26 | #include <linux/module.h> | 26 | #include <linux/module.h> |
27 | #include <linux/errno.h> | 27 | #include <linux/errno.h> |
28 | #include <linux/sh_dma.h> | ||
28 | #include <linux/timer.h> | 29 | #include <linux/timer.h> |
29 | #include <linux/interrupt.h> | 30 | #include <linux/interrupt.h> |
30 | #include <linux/tty.h> | 31 | #include <linux/tty.h> |
@@ -1410,8 +1411,8 @@ static void work_fn_rx(struct work_struct *work) | |||
1410 | /* Handle incomplete DMA receive */ | 1411 | /* Handle incomplete DMA receive */ |
1411 | struct tty_struct *tty = port->state->port.tty; | 1412 | struct tty_struct *tty = port->state->port.tty; |
1412 | struct dma_chan *chan = s->chan_rx; | 1413 | struct dma_chan *chan = s->chan_rx; |
1413 | struct sh_desc *sh_desc = container_of(desc, struct sh_desc, | 1414 | struct shdma_desc *sh_desc = container_of(desc, |
1414 | async_tx); | 1415 | struct shdma_desc, async_tx); |
1415 | unsigned long flags; | 1416 | unsigned long flags; |
1416 | int count; | 1417 | int count; |
1417 | 1418 | ||
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig index a7773a3e02b1..7065df6036ca 100644 --- a/drivers/usb/Kconfig +++ b/drivers/usb/Kconfig | |||
@@ -13,7 +13,7 @@ config USB_ARCH_HAS_OHCI | |||
13 | default y if PXA3xx | 13 | default y if PXA3xx |
14 | default y if ARCH_EP93XX | 14 | default y if ARCH_EP93XX |
15 | default y if ARCH_AT91 | 15 | default y if ARCH_AT91 |
16 | default y if ARCH_PNX4008 && I2C | 16 | default y if ARCH_PNX4008 |
17 | default y if MFD_TC6393XB | 17 | default y if MFD_TC6393XB |
18 | default y if ARCH_W90X900 | 18 | default y if ARCH_W90X900 |
19 | default y if ARCH_DAVINCI_DA8XX | 19 | default y if ARCH_DAVINCI_DA8XX |
diff --git a/drivers/usb/chipidea/Kconfig b/drivers/usb/chipidea/Kconfig index 8337fb5d988d..47e499c9c0b6 100644 --- a/drivers/usb/chipidea/Kconfig +++ b/drivers/usb/chipidea/Kconfig | |||
@@ -1,9 +1,9 @@ | |||
1 | config USB_CHIPIDEA | 1 | config USB_CHIPIDEA |
2 | tristate "ChipIdea Highspeed Dual Role Controller" | 2 | tristate "ChipIdea Highspeed Dual Role Controller" |
3 | depends on USB | 3 | depends on USB || USB_GADGET |
4 | help | 4 | help |
5 | Say Y here if your system has a dual role high speed USB | 5 | Say Y here if your system has a dual role high speed USB |
6 | controller based on ChipIdea silicon IP. Currently, only the | 6 | controller based on ChipIdea silicon IP. Currently, only the |
7 | peripheral mode is supported. | 7 | peripheral mode is supported. |
8 | 8 | ||
9 | When compiled dynamically, the module will be called ci-hdrc.ko. | 9 | When compiled dynamically, the module will be called ci-hdrc.ko. |
@@ -12,7 +12,7 @@ if USB_CHIPIDEA | |||
12 | 12 | ||
13 | config USB_CHIPIDEA_UDC | 13 | config USB_CHIPIDEA_UDC |
14 | bool "ChipIdea device controller" | 14 | bool "ChipIdea device controller" |
15 | depends on USB_GADGET | 15 | depends on USB_GADGET=y || USB_GADGET=USB_CHIPIDEA |
16 | select USB_GADGET_DUALSPEED | 16 | select USB_GADGET_DUALSPEED |
17 | help | 17 | help |
18 | Say Y here to enable device controller functionality of the | 18 | Say Y here to enable device controller functionality of the |
@@ -20,6 +20,7 @@ config USB_CHIPIDEA_UDC | |||
20 | 20 | ||
21 | config USB_CHIPIDEA_HOST | 21 | config USB_CHIPIDEA_HOST |
22 | bool "ChipIdea host controller" | 22 | bool "ChipIdea host controller" |
23 | depends on USB=y || USB=USB_CHIPIDEA | ||
23 | select USB_EHCI_ROOT_HUB_TT | 24 | select USB_EHCI_ROOT_HUB_TT |
24 | help | 25 | help |
25 | Say Y here to enable host controller functionality of the | 26 | Say Y here to enable host controller functionality of the |
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c index 56d6bf668488..f763ed7ba91e 100644 --- a/drivers/usb/class/cdc-acm.c +++ b/drivers/usb/class/cdc-acm.c | |||
@@ -1104,7 +1104,8 @@ skip_normal_probe: | |||
1104 | } | 1104 | } |
1105 | 1105 | ||
1106 | 1106 | ||
1107 | if (data_interface->cur_altsetting->desc.bNumEndpoints < 2) | 1107 | if (data_interface->cur_altsetting->desc.bNumEndpoints < 2 || |
1108 | control_interface->cur_altsetting->desc.bNumEndpoints == 0) | ||
1108 | return -EINVAL; | 1109 | return -EINVAL; |
1109 | 1110 | ||
1110 | epctrl = &control_interface->cur_altsetting->endpoint[0].desc; | 1111 | epctrl = &control_interface->cur_altsetting->endpoint[0].desc; |
diff --git a/drivers/usb/early/ehci-dbgp.c b/drivers/usb/early/ehci-dbgp.c index ee0ebacf8227..89dcf155d57e 100644 --- a/drivers/usb/early/ehci-dbgp.c +++ b/drivers/usb/early/ehci-dbgp.c | |||
@@ -450,7 +450,7 @@ static int dbgp_ehci_startup(void) | |||
450 | writel(FLAG_CF, &ehci_regs->configured_flag); | 450 | writel(FLAG_CF, &ehci_regs->configured_flag); |
451 | 451 | ||
452 | /* Wait until the controller is no longer halted */ | 452 | /* Wait until the controller is no longer halted */ |
453 | loop = 10; | 453 | loop = 1000; |
454 | do { | 454 | do { |
455 | status = readl(&ehci_regs->status); | 455 | status = readl(&ehci_regs->status); |
456 | if (!(status & STS_HALT)) | 456 | if (!(status & STS_HALT)) |
diff --git a/drivers/usb/gadget/u_ether.c b/drivers/usb/gadget/u_ether.c index 90e82e288eb9..0e5230926154 100644 --- a/drivers/usb/gadget/u_ether.c +++ b/drivers/usb/gadget/u_ether.c | |||
@@ -669,6 +669,8 @@ static int eth_stop(struct net_device *net) | |||
669 | spin_lock_irqsave(&dev->lock, flags); | 669 | spin_lock_irqsave(&dev->lock, flags); |
670 | if (dev->port_usb) { | 670 | if (dev->port_usb) { |
671 | struct gether *link = dev->port_usb; | 671 | struct gether *link = dev->port_usb; |
672 | const struct usb_endpoint_descriptor *in; | ||
673 | const struct usb_endpoint_descriptor *out; | ||
672 | 674 | ||
673 | if (link->close) | 675 | if (link->close) |
674 | link->close(link); | 676 | link->close(link); |
@@ -682,10 +684,14 @@ static int eth_stop(struct net_device *net) | |||
682 | * their own pace; the network stack can handle old packets. | 684 | * their own pace; the network stack can handle old packets. |
683 | * For the moment we leave this here, since it works. | 685 | * For the moment we leave this here, since it works. |
684 | */ | 686 | */ |
687 | in = link->in_ep->desc; | ||
688 | out = link->out_ep->desc; | ||
685 | usb_ep_disable(link->in_ep); | 689 | usb_ep_disable(link->in_ep); |
686 | usb_ep_disable(link->out_ep); | 690 | usb_ep_disable(link->out_ep); |
687 | if (netif_carrier_ok(net)) { | 691 | if (netif_carrier_ok(net)) { |
688 | DBG(dev, "host still using in/out endpoints\n"); | 692 | DBG(dev, "host still using in/out endpoints\n"); |
693 | link->in_ep->desc = in; | ||
694 | link->out_ep->desc = out; | ||
689 | usb_ep_enable(link->in_ep); | 695 | usb_ep_enable(link->in_ep); |
690 | usb_ep_enable(link->out_ep); | 696 | usb_ep_enable(link->out_ep); |
691 | } | 697 | } |
diff --git a/drivers/usb/host/ehci-omap.c b/drivers/usb/host/ehci-omap.c index bb55eb4a7d48..d7fe287d0678 100644 --- a/drivers/usb/host/ehci-omap.c +++ b/drivers/usb/host/ehci-omap.c | |||
@@ -56,15 +56,6 @@ | |||
56 | #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 | 56 | #define EHCI_INSNREG05_ULPI_EXTREGADD_SHIFT 8 |
57 | #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 | 57 | #define EHCI_INSNREG05_ULPI_WRDATA_SHIFT 0 |
58 | 58 | ||
59 | /* Errata i693 */ | ||
60 | static struct clk *utmi_p1_fck; | ||
61 | static struct clk *utmi_p2_fck; | ||
62 | static struct clk *xclk60mhsp1_ck; | ||
63 | static struct clk *xclk60mhsp2_ck; | ||
64 | static struct clk *usbhost_p1_fck; | ||
65 | static struct clk *usbhost_p2_fck; | ||
66 | static struct clk *init_60m_fclk; | ||
67 | |||
68 | /*-------------------------------------------------------------------------*/ | 59 | /*-------------------------------------------------------------------------*/ |
69 | 60 | ||
70 | static const struct hc_driver ehci_omap_hc_driver; | 61 | static const struct hc_driver ehci_omap_hc_driver; |
@@ -80,40 +71,6 @@ static inline u32 ehci_read(void __iomem *base, u32 reg) | |||
80 | return __raw_readl(base + reg); | 71 | return __raw_readl(base + reg); |
81 | } | 72 | } |
82 | 73 | ||
83 | /* Erratum i693 workaround sequence */ | ||
84 | static void omap_ehci_erratum_i693(struct ehci_hcd *ehci) | ||
85 | { | ||
86 | int ret = 0; | ||
87 | |||
88 | /* Switch to the internal 60 MHz clock */ | ||
89 | ret = clk_set_parent(utmi_p1_fck, init_60m_fclk); | ||
90 | if (ret != 0) | ||
91 | ehci_err(ehci, "init_60m_fclk set parent" | ||
92 | "failed error:%d\n", ret); | ||
93 | |||
94 | ret = clk_set_parent(utmi_p2_fck, init_60m_fclk); | ||
95 | if (ret != 0) | ||
96 | ehci_err(ehci, "init_60m_fclk set parent" | ||
97 | "failed error:%d\n", ret); | ||
98 | |||
99 | clk_enable(usbhost_p1_fck); | ||
100 | clk_enable(usbhost_p2_fck); | ||
101 | |||
102 | /* Wait 1ms and switch back to the external clock */ | ||
103 | mdelay(1); | ||
104 | ret = clk_set_parent(utmi_p1_fck, xclk60mhsp1_ck); | ||
105 | if (ret != 0) | ||
106 | ehci_err(ehci, "xclk60mhsp1_ck set parent" | ||
107 | "failed error:%d\n", ret); | ||
108 | |||
109 | ret = clk_set_parent(utmi_p2_fck, xclk60mhsp2_ck); | ||
110 | if (ret != 0) | ||
111 | ehci_err(ehci, "xclk60mhsp2_ck set parent" | ||
112 | "failed error:%d\n", ret); | ||
113 | |||
114 | clk_disable(usbhost_p1_fck); | ||
115 | clk_disable(usbhost_p2_fck); | ||
116 | } | ||
117 | 74 | ||
118 | static void omap_ehci_soft_phy_reset(struct usb_hcd *hcd, u8 port) | 75 | static void omap_ehci_soft_phy_reset(struct usb_hcd *hcd, u8 port) |
119 | { | 76 | { |
@@ -195,50 +152,6 @@ static int omap_ehci_init(struct usb_hcd *hcd) | |||
195 | return rc; | 152 | return rc; |
196 | } | 153 | } |
197 | 154 | ||
198 | static int omap_ehci_hub_control( | ||
199 | struct usb_hcd *hcd, | ||
200 | u16 typeReq, | ||
201 | u16 wValue, | ||
202 | u16 wIndex, | ||
203 | char *buf, | ||
204 | u16 wLength | ||
205 | ) | ||
206 | { | ||
207 | struct ehci_hcd *ehci = hcd_to_ehci(hcd); | ||
208 | u32 __iomem *status_reg = &ehci->regs->port_status[ | ||
209 | (wIndex & 0xff) - 1]; | ||
210 | u32 temp; | ||
211 | unsigned long flags; | ||
212 | int retval = 0; | ||
213 | |||
214 | spin_lock_irqsave(&ehci->lock, flags); | ||
215 | |||
216 | if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) { | ||
217 | temp = ehci_readl(ehci, status_reg); | ||
218 | if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) { | ||
219 | retval = -EPIPE; | ||
220 | goto done; | ||
221 | } | ||
222 | |||
223 | temp &= ~PORT_WKCONN_E; | ||
224 | temp |= PORT_WKDISC_E | PORT_WKOC_E; | ||
225 | ehci_writel(ehci, temp | PORT_SUSPEND, status_reg); | ||
226 | |||
227 | omap_ehci_erratum_i693(ehci); | ||
228 | |||
229 | set_bit((wIndex & 0xff) - 1, &ehci->suspended_ports); | ||
230 | goto done; | ||
231 | } | ||
232 | |||
233 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
234 | |||
235 | /* Handle the hub control events here */ | ||
236 | return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); | ||
237 | done: | ||
238 | spin_unlock_irqrestore(&ehci->lock, flags); | ||
239 | return retval; | ||
240 | } | ||
241 | |||
242 | static void disable_put_regulator( | 155 | static void disable_put_regulator( |
243 | struct ehci_hcd_omap_platform_data *pdata) | 156 | struct ehci_hcd_omap_platform_data *pdata) |
244 | { | 157 | { |
@@ -351,79 +264,9 @@ static int ehci_hcd_omap_probe(struct platform_device *pdev) | |||
351 | goto err_pm_runtime; | 264 | goto err_pm_runtime; |
352 | } | 265 | } |
353 | 266 | ||
354 | /* get clocks */ | ||
355 | utmi_p1_fck = clk_get(dev, "utmi_p1_gfclk"); | ||
356 | if (IS_ERR(utmi_p1_fck)) { | ||
357 | ret = PTR_ERR(utmi_p1_fck); | ||
358 | dev_err(dev, "utmi_p1_gfclk failed error:%d\n", ret); | ||
359 | goto err_add_hcd; | ||
360 | } | ||
361 | |||
362 | xclk60mhsp1_ck = clk_get(dev, "xclk60mhsp1_ck"); | ||
363 | if (IS_ERR(xclk60mhsp1_ck)) { | ||
364 | ret = PTR_ERR(xclk60mhsp1_ck); | ||
365 | dev_err(dev, "xclk60mhsp1_ck failed error:%d\n", ret); | ||
366 | goto err_utmi_p1_fck; | ||
367 | } | ||
368 | |||
369 | utmi_p2_fck = clk_get(dev, "utmi_p2_gfclk"); | ||
370 | if (IS_ERR(utmi_p2_fck)) { | ||
371 | ret = PTR_ERR(utmi_p2_fck); | ||
372 | dev_err(dev, "utmi_p2_gfclk failed error:%d\n", ret); | ||
373 | goto err_xclk60mhsp1_ck; | ||
374 | } | ||
375 | |||
376 | xclk60mhsp2_ck = clk_get(dev, "xclk60mhsp2_ck"); | ||
377 | if (IS_ERR(xclk60mhsp2_ck)) { | ||
378 | ret = PTR_ERR(xclk60mhsp2_ck); | ||
379 | dev_err(dev, "xclk60mhsp2_ck failed error:%d\n", ret); | ||
380 | goto err_utmi_p2_fck; | ||
381 | } | ||
382 | |||
383 | usbhost_p1_fck = clk_get(dev, "usb_host_hs_utmi_p1_clk"); | ||
384 | if (IS_ERR(usbhost_p1_fck)) { | ||
385 | ret = PTR_ERR(usbhost_p1_fck); | ||
386 | dev_err(dev, "usbhost_p1_fck failed error:%d\n", ret); | ||
387 | goto err_xclk60mhsp2_ck; | ||
388 | } | ||
389 | |||
390 | usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk"); | ||
391 | if (IS_ERR(usbhost_p2_fck)) { | ||
392 | ret = PTR_ERR(usbhost_p2_fck); | ||
393 | dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret); | ||
394 | goto err_usbhost_p1_fck; | ||
395 | } | ||
396 | |||
397 | init_60m_fclk = clk_get(dev, "init_60m_fclk"); | ||
398 | if (IS_ERR(init_60m_fclk)) { | ||
399 | ret = PTR_ERR(init_60m_fclk); | ||
400 | dev_err(dev, "init_60m_fclk failed error:%d\n", ret); | ||
401 | goto err_usbhost_p2_fck; | ||
402 | } | ||
403 | 267 | ||
404 | return 0; | 268 | return 0; |
405 | 269 | ||
406 | err_usbhost_p2_fck: | ||
407 | clk_put(usbhost_p2_fck); | ||
408 | |||
409 | err_usbhost_p1_fck: | ||
410 | clk_put(usbhost_p1_fck); | ||
411 | |||
412 | err_xclk60mhsp2_ck: | ||
413 | clk_put(xclk60mhsp2_ck); | ||
414 | |||
415 | err_utmi_p2_fck: | ||
416 | clk_put(utmi_p2_fck); | ||
417 | |||
418 | err_xclk60mhsp1_ck: | ||
419 | clk_put(xclk60mhsp1_ck); | ||
420 | |||
421 | err_utmi_p1_fck: | ||
422 | clk_put(utmi_p1_fck); | ||
423 | |||
424 | err_add_hcd: | ||
425 | usb_remove_hcd(hcd); | ||
426 | |||
427 | err_pm_runtime: | 270 | err_pm_runtime: |
428 | disable_put_regulator(pdata); | 271 | disable_put_regulator(pdata); |
429 | pm_runtime_put_sync(dev); | 272 | pm_runtime_put_sync(dev); |
@@ -454,14 +297,6 @@ static int ehci_hcd_omap_remove(struct platform_device *pdev) | |||
454 | iounmap(hcd->regs); | 297 | iounmap(hcd->regs); |
455 | usb_put_hcd(hcd); | 298 | usb_put_hcd(hcd); |
456 | 299 | ||
457 | clk_put(utmi_p1_fck); | ||
458 | clk_put(utmi_p2_fck); | ||
459 | clk_put(xclk60mhsp1_ck); | ||
460 | clk_put(xclk60mhsp2_ck); | ||
461 | clk_put(usbhost_p1_fck); | ||
462 | clk_put(usbhost_p2_fck); | ||
463 | clk_put(init_60m_fclk); | ||
464 | |||
465 | pm_runtime_put_sync(dev); | 300 | pm_runtime_put_sync(dev); |
466 | pm_runtime_disable(dev); | 301 | pm_runtime_disable(dev); |
467 | 302 | ||
@@ -532,7 +367,7 @@ static const struct hc_driver ehci_omap_hc_driver = { | |||
532 | * root hub support | 367 | * root hub support |
533 | */ | 368 | */ |
534 | .hub_status_data = ehci_hub_status_data, | 369 | .hub_status_data = ehci_hub_status_data, |
535 | .hub_control = omap_ehci_hub_control, | 370 | .hub_control = ehci_hub_control, |
536 | .bus_suspend = ehci_bus_suspend, | 371 | .bus_suspend = ehci_bus_suspend, |
537 | .bus_resume = ehci_bus_resume, | 372 | .bus_resume = ehci_bus_resume, |
538 | 373 | ||
diff --git a/drivers/usb/host/ehci-sead3.c b/drivers/usb/host/ehci-sead3.c index 58c96bd50d22..0c9e43cfaff5 100644 --- a/drivers/usb/host/ehci-sead3.c +++ b/drivers/usb/host/ehci-sead3.c | |||
@@ -40,7 +40,7 @@ static int ehci_sead3_setup(struct usb_hcd *hcd) | |||
40 | ehci->need_io_watchdog = 0; | 40 | ehci->need_io_watchdog = 0; |
41 | 41 | ||
42 | /* Set burst length to 16 words. */ | 42 | /* Set burst length to 16 words. */ |
43 | ehci_writel(ehci, 0x1010, &ehci->regs->reserved[1]); | 43 | ehci_writel(ehci, 0x1010, &ehci->regs->reserved1[1]); |
44 | 44 | ||
45 | return ret; | 45 | return ret; |
46 | } | 46 | } |
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 950e95efa381..26dedb30ad0b 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c | |||
@@ -799,11 +799,12 @@ static int tegra_ehci_remove(struct platform_device *pdev) | |||
799 | #endif | 799 | #endif |
800 | 800 | ||
801 | usb_remove_hcd(hcd); | 801 | usb_remove_hcd(hcd); |
802 | usb_put_hcd(hcd); | ||
803 | 802 | ||
804 | tegra_usb_phy_close(tegra->phy); | 803 | tegra_usb_phy_close(tegra->phy); |
805 | iounmap(hcd->regs); | 804 | iounmap(hcd->regs); |
806 | 805 | ||
806 | usb_put_hcd(hcd); | ||
807 | |||
807 | clk_disable_unprepare(tegra->clk); | 808 | clk_disable_unprepare(tegra->clk); |
808 | clk_put(tegra->clk); | 809 | clk_put(tegra->clk); |
809 | 810 | ||
diff --git a/drivers/usb/host/isp1362-hcd.c b/drivers/usb/host/isp1362-hcd.c index 2ed112d3e159..256326322cfd 100644 --- a/drivers/usb/host/isp1362-hcd.c +++ b/drivers/usb/host/isp1362-hcd.c | |||
@@ -543,12 +543,12 @@ static void postproc_ep(struct isp1362_hcd *isp1362_hcd, struct isp1362_ep *ep) | |||
543 | usb_pipein(urb->pipe) ? "IN" : "OUT", ep->nextpid, | 543 | usb_pipein(urb->pipe) ? "IN" : "OUT", ep->nextpid, |
544 | short_ok ? "" : "not_", | 544 | short_ok ? "" : "not_", |
545 | PTD_GET_COUNT(ptd), ep->maxpacket, len); | 545 | PTD_GET_COUNT(ptd), ep->maxpacket, len); |
546 | /* save the data underrun error code for later and | ||
547 | * proceed with the status stage | ||
548 | */ | ||
549 | urb->actual_length += PTD_GET_COUNT(ptd); | ||
546 | if (usb_pipecontrol(urb->pipe)) { | 550 | if (usb_pipecontrol(urb->pipe)) { |
547 | ep->nextpid = USB_PID_ACK; | 551 | ep->nextpid = USB_PID_ACK; |
548 | /* save the data underrun error code for later and | ||
549 | * proceed with the status stage | ||
550 | */ | ||
551 | urb->actual_length += PTD_GET_COUNT(ptd); | ||
552 | BUG_ON(urb->actual_length > urb->transfer_buffer_length); | 552 | BUG_ON(urb->actual_length > urb->transfer_buffer_length); |
553 | 553 | ||
554 | if (urb->status == -EINPROGRESS) | 554 | if (urb->status == -EINPROGRESS) |
diff --git a/drivers/usb/host/ohci-omap.c b/drivers/usb/host/ohci-omap.c index e7d75d295988..f8b2d91851f7 100644 --- a/drivers/usb/host/ohci-omap.c +++ b/drivers/usb/host/ohci-omap.c | |||
@@ -403,8 +403,6 @@ err0: | |||
403 | static inline void | 403 | static inline void |
404 | usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) | 404 | usb_hcd_omap_remove (struct usb_hcd *hcd, struct platform_device *pdev) |
405 | { | 405 | { |
406 | struct ohci_hcd *ohci = hcd_to_ohci (hcd); | ||
407 | |||
408 | usb_remove_hcd(hcd); | 406 | usb_remove_hcd(hcd); |
409 | if (!IS_ERR_OR_NULL(hcd->phy)) { | 407 | if (!IS_ERR_OR_NULL(hcd->phy)) { |
410 | (void) otg_set_host(hcd->phy->otg, 0); | 408 | (void) otg_set_host(hcd->phy->otg, 0); |
diff --git a/drivers/usb/host/pci-quirks.c b/drivers/usb/host/pci-quirks.c index df0828cb2aa3..c5e9e4a76f14 100644 --- a/drivers/usb/host/pci-quirks.c +++ b/drivers/usb/host/pci-quirks.c | |||
@@ -800,6 +800,13 @@ void usb_enable_xhci_ports(struct pci_dev *xhci_pdev) | |||
800 | } | 800 | } |
801 | EXPORT_SYMBOL_GPL(usb_enable_xhci_ports); | 801 | EXPORT_SYMBOL_GPL(usb_enable_xhci_ports); |
802 | 802 | ||
803 | void usb_disable_xhci_ports(struct pci_dev *xhci_pdev) | ||
804 | { | ||
805 | pci_write_config_dword(xhci_pdev, USB_INTEL_USB3_PSSEN, 0x0); | ||
806 | pci_write_config_dword(xhci_pdev, USB_INTEL_XUSB2PR, 0x0); | ||
807 | } | ||
808 | EXPORT_SYMBOL_GPL(usb_disable_xhci_ports); | ||
809 | |||
803 | /** | 810 | /** |
804 | * PCI Quirks for xHCI. | 811 | * PCI Quirks for xHCI. |
805 | * | 812 | * |
diff --git a/drivers/usb/host/pci-quirks.h b/drivers/usb/host/pci-quirks.h index b1002a8ef96f..ef004a5de20f 100644 --- a/drivers/usb/host/pci-quirks.h +++ b/drivers/usb/host/pci-quirks.h | |||
@@ -10,6 +10,7 @@ void usb_amd_quirk_pll_disable(void); | |||
10 | void usb_amd_quirk_pll_enable(void); | 10 | void usb_amd_quirk_pll_enable(void); |
11 | bool usb_is_intel_switchable_xhci(struct pci_dev *pdev); | 11 | bool usb_is_intel_switchable_xhci(struct pci_dev *pdev); |
12 | void usb_enable_xhci_ports(struct pci_dev *xhci_pdev); | 12 | void usb_enable_xhci_ports(struct pci_dev *xhci_pdev); |
13 | void usb_disable_xhci_ports(struct pci_dev *xhci_pdev); | ||
13 | #else | 14 | #else |
14 | static inline void usb_amd_quirk_pll_disable(void) {} | 15 | static inline void usb_amd_quirk_pll_disable(void) {} |
15 | static inline void usb_amd_quirk_pll_enable(void) {} | 16 | static inline void usb_amd_quirk_pll_enable(void) {} |
diff --git a/drivers/usb/host/xhci-pci.c b/drivers/usb/host/xhci-pci.c index 18b231b0c5d3..9bfd4ca1153c 100644 --- a/drivers/usb/host/xhci-pci.c +++ b/drivers/usb/host/xhci-pci.c | |||
@@ -94,11 +94,21 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) | |||
94 | xhci->quirks |= XHCI_EP_LIMIT_QUIRK; | 94 | xhci->quirks |= XHCI_EP_LIMIT_QUIRK; |
95 | xhci->limit_active_eps = 64; | 95 | xhci->limit_active_eps = 64; |
96 | xhci->quirks |= XHCI_SW_BW_CHECKING; | 96 | xhci->quirks |= XHCI_SW_BW_CHECKING; |
97 | /* | ||
98 | * PPT desktop boards DH77EB and DH77DF will power back on after | ||
99 | * a few seconds of being shutdown. The fix for this is to | ||
100 | * switch the ports from xHCI to EHCI on shutdown. We can't use | ||
101 | * DMI information to find those particular boards (since each | ||
102 | * vendor will change the board name), so we have to key off all | ||
103 | * PPT chipsets. | ||
104 | */ | ||
105 | xhci->quirks |= XHCI_SPURIOUS_REBOOT; | ||
97 | } | 106 | } |
98 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && | 107 | if (pdev->vendor == PCI_VENDOR_ID_ETRON && |
99 | pdev->device == PCI_DEVICE_ID_ASROCK_P67) { | 108 | pdev->device == PCI_DEVICE_ID_ASROCK_P67) { |
100 | xhci->quirks |= XHCI_RESET_ON_RESUME; | 109 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
101 | xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); | 110 | xhci_dbg(xhci, "QUIRK: Resetting on resume\n"); |
111 | xhci->quirks |= XHCI_TRUST_TX_LENGTH; | ||
102 | } | 112 | } |
103 | if (pdev->vendor == PCI_VENDOR_ID_VIA) | 113 | if (pdev->vendor == PCI_VENDOR_ID_VIA) |
104 | xhci->quirks |= XHCI_RESET_ON_RESUME; | 114 | xhci->quirks |= XHCI_RESET_ON_RESUME; |
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c index 8275645889da..643c2f3f3e73 100644 --- a/drivers/usb/host/xhci-ring.c +++ b/drivers/usb/host/xhci-ring.c | |||
@@ -145,29 +145,37 @@ static void next_trb(struct xhci_hcd *xhci, | |||
145 | */ | 145 | */ |
146 | static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) | 146 | static void inc_deq(struct xhci_hcd *xhci, struct xhci_ring *ring) |
147 | { | 147 | { |
148 | union xhci_trb *next; | ||
149 | unsigned long long addr; | 148 | unsigned long long addr; |
150 | 149 | ||
151 | ring->deq_updates++; | 150 | ring->deq_updates++; |
152 | 151 | ||
153 | /* If this is not event ring, there is one more usable TRB */ | 152 | /* |
153 | * If this is not event ring, and the dequeue pointer | ||
154 | * is not on a link TRB, there is one more usable TRB | ||
155 | */ | ||
154 | if (ring->type != TYPE_EVENT && | 156 | if (ring->type != TYPE_EVENT && |
155 | !last_trb(xhci, ring, ring->deq_seg, ring->dequeue)) | 157 | !last_trb(xhci, ring, ring->deq_seg, ring->dequeue)) |
156 | ring->num_trbs_free++; | 158 | ring->num_trbs_free++; |
157 | next = ++(ring->dequeue); | ||
158 | 159 | ||
159 | /* Update the dequeue pointer further if that was a link TRB or we're at | 160 | do { |
160 | * the end of an event ring segment (which doesn't have link TRBS) | 161 | /* |
161 | */ | 162 | * Update the dequeue pointer further if that was a link TRB or |
162 | while (last_trb(xhci, ring, ring->deq_seg, next)) { | 163 | * we're at the end of an event ring segment (which doesn't have |
163 | if (ring->type == TYPE_EVENT && last_trb_on_last_seg(xhci, | 164 | * link TRBS) |
164 | ring, ring->deq_seg, next)) { | 165 | */ |
165 | ring->cycle_state = (ring->cycle_state ? 0 : 1); | 166 | if (last_trb(xhci, ring, ring->deq_seg, ring->dequeue)) { |
167 | if (ring->type == TYPE_EVENT && | ||
168 | last_trb_on_last_seg(xhci, ring, | ||
169 | ring->deq_seg, ring->dequeue)) { | ||
170 | ring->cycle_state = (ring->cycle_state ? 0 : 1); | ||
171 | } | ||
172 | ring->deq_seg = ring->deq_seg->next; | ||
173 | ring->dequeue = ring->deq_seg->trbs; | ||
174 | } else { | ||
175 | ring->dequeue++; | ||
166 | } | 176 | } |
167 | ring->deq_seg = ring->deq_seg->next; | 177 | } while (last_trb(xhci, ring, ring->deq_seg, ring->dequeue)); |
168 | ring->dequeue = ring->deq_seg->trbs; | 178 | |
169 | next = ring->dequeue; | ||
170 | } | ||
171 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); | 179 | addr = (unsigned long long) xhci_trb_virt_to_dma(ring->deq_seg, ring->dequeue); |
172 | } | 180 | } |
173 | 181 | ||
@@ -2073,8 +2081,8 @@ static int handle_tx_event(struct xhci_hcd *xhci, | |||
2073 | if (xhci->quirks & XHCI_TRUST_TX_LENGTH) | 2081 | if (xhci->quirks & XHCI_TRUST_TX_LENGTH) |
2074 | trb_comp_code = COMP_SHORT_TX; | 2082 | trb_comp_code = COMP_SHORT_TX; |
2075 | else | 2083 | else |
2076 | xhci_warn(xhci, "WARN Successful completion on short TX: " | 2084 | xhci_warn_ratelimited(xhci, |
2077 | "needs XHCI_TRUST_TX_LENGTH quirk?\n"); | 2085 | "WARN Successful completion on short TX: needs XHCI_TRUST_TX_LENGTH quirk?\n"); |
2078 | case COMP_SHORT_TX: | 2086 | case COMP_SHORT_TX: |
2079 | break; | 2087 | break; |
2080 | case COMP_STOP: | 2088 | case COMP_STOP: |
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 7648b2d4b268..c59d5b5b6c7d 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c | |||
@@ -166,7 +166,7 @@ int xhci_reset(struct xhci_hcd *xhci) | |||
166 | xhci_writel(xhci, command, &xhci->op_regs->command); | 166 | xhci_writel(xhci, command, &xhci->op_regs->command); |
167 | 167 | ||
168 | ret = handshake(xhci, &xhci->op_regs->command, | 168 | ret = handshake(xhci, &xhci->op_regs->command, |
169 | CMD_RESET, 0, 250 * 1000); | 169 | CMD_RESET, 0, 10 * 1000 * 1000); |
170 | if (ret) | 170 | if (ret) |
171 | return ret; | 171 | return ret; |
172 | 172 | ||
@@ -175,7 +175,8 @@ int xhci_reset(struct xhci_hcd *xhci) | |||
175 | * xHCI cannot write to any doorbells or operational registers other | 175 | * xHCI cannot write to any doorbells or operational registers other |
176 | * than status until the "Controller Not Ready" flag is cleared. | 176 | * than status until the "Controller Not Ready" flag is cleared. |
177 | */ | 177 | */ |
178 | ret = handshake(xhci, &xhci->op_regs->status, STS_CNR, 0, 250 * 1000); | 178 | ret = handshake(xhci, &xhci->op_regs->status, |
179 | STS_CNR, 0, 10 * 1000 * 1000); | ||
179 | 180 | ||
180 | for (i = 0; i < 2; ++i) { | 181 | for (i = 0; i < 2; ++i) { |
181 | xhci->bus_state[i].port_c_suspend = 0; | 182 | xhci->bus_state[i].port_c_suspend = 0; |
@@ -658,6 +659,9 @@ void xhci_shutdown(struct usb_hcd *hcd) | |||
658 | { | 659 | { |
659 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); | 660 | struct xhci_hcd *xhci = hcd_to_xhci(hcd); |
660 | 661 | ||
662 | if (xhci->quirks && XHCI_SPURIOUS_REBOOT) | ||
663 | usb_disable_xhci_ports(to_pci_dev(hcd->self.controller)); | ||
664 | |||
661 | spin_lock_irq(&xhci->lock); | 665 | spin_lock_irq(&xhci->lock); |
662 | xhci_halt(xhci); | 666 | xhci_halt(xhci); |
663 | spin_unlock_irq(&xhci->lock); | 667 | spin_unlock_irq(&xhci->lock); |
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 55c0785810c9..c713256297ac 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h | |||
@@ -1494,6 +1494,7 @@ struct xhci_hcd { | |||
1494 | #define XHCI_TRUST_TX_LENGTH (1 << 10) | 1494 | #define XHCI_TRUST_TX_LENGTH (1 << 10) |
1495 | #define XHCI_LPM_SUPPORT (1 << 11) | 1495 | #define XHCI_LPM_SUPPORT (1 << 11) |
1496 | #define XHCI_INTEL_HOST (1 << 12) | 1496 | #define XHCI_INTEL_HOST (1 << 12) |
1497 | #define XHCI_SPURIOUS_REBOOT (1 << 13) | ||
1497 | unsigned int num_active_eps; | 1498 | unsigned int num_active_eps; |
1498 | unsigned int limit_active_eps; | 1499 | unsigned int limit_active_eps; |
1499 | /* There are two roothubs to keep track of bus suspend info for */ | 1500 | /* There are two roothubs to keep track of bus suspend info for */ |
@@ -1537,6 +1538,8 @@ static inline struct usb_hcd *xhci_to_hcd(struct xhci_hcd *xhci) | |||
1537 | dev_err(xhci_to_hcd(xhci)->self.controller , fmt , ## args) | 1538 | dev_err(xhci_to_hcd(xhci)->self.controller , fmt , ## args) |
1538 | #define xhci_warn(xhci, fmt, args...) \ | 1539 | #define xhci_warn(xhci, fmt, args...) \ |
1539 | dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args) | 1540 | dev_warn(xhci_to_hcd(xhci)->self.controller , fmt , ## args) |
1541 | #define xhci_warn_ratelimited(xhci, fmt, args...) \ | ||
1542 | dev_warn_ratelimited(xhci_to_hcd(xhci)->self.controller , fmt , ## args) | ||
1540 | 1543 | ||
1541 | /* TODO: copied from ehci.h - can be refactored? */ | 1544 | /* TODO: copied from ehci.h - can be refactored? */ |
1542 | /* xHCI spec says all registers are little endian */ | 1545 | /* xHCI spec says all registers are little endian */ |
diff --git a/drivers/usb/misc/emi62.c b/drivers/usb/misc/emi62.c index ff08015b230c..ae794b90766b 100644 --- a/drivers/usb/misc/emi62.c +++ b/drivers/usb/misc/emi62.c | |||
@@ -232,7 +232,7 @@ wraperr: | |||
232 | return err; | 232 | return err; |
233 | } | 233 | } |
234 | 234 | ||
235 | static const struct usb_device_id id_table[] __devinitconst = { | 235 | static const struct usb_device_id id_table[] = { |
236 | { USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) }, | 236 | { USB_DEVICE(EMI62_VENDOR_ID, EMI62_PRODUCT_ID) }, |
237 | { } /* Terminating entry */ | 237 | { } /* Terminating entry */ |
238 | }; | 238 | }; |
diff --git a/drivers/usb/musb/Kconfig b/drivers/usb/musb/Kconfig index ef0c3f9f0947..6259f0d99324 100644 --- a/drivers/usb/musb/Kconfig +++ b/drivers/usb/musb/Kconfig | |||
@@ -8,7 +8,7 @@ config USB_MUSB_HDRC | |||
8 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' | 8 | tristate 'Inventra Highspeed Dual Role Controller (TI, ADI, ...)' |
9 | depends on USB && USB_GADGET | 9 | depends on USB && USB_GADGET |
10 | select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN) | 10 | select NOP_USB_XCEIV if (ARCH_DAVINCI || MACH_OMAP3EVM || BLACKFIN) |
11 | select NOP_USB_XCEIV if (SOC_OMAPTI81XX || SOC_OMAPAM33XX) | 11 | select NOP_USB_XCEIV if (SOC_TI81XX || SOC_AM33XX) |
12 | select TWL4030_USB if MACH_OMAP_3430SDP | 12 | select TWL4030_USB if MACH_OMAP_3430SDP |
13 | select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA | 13 | select TWL6030_USB if MACH_OMAP_4430SDP || MACH_OMAP4_PANDA |
14 | select USB_OTG_UTILS | 14 | select USB_OTG_UTILS |
@@ -57,7 +57,7 @@ config USB_MUSB_AM35X | |||
57 | 57 | ||
58 | config USB_MUSB_DSPS | 58 | config USB_MUSB_DSPS |
59 | tristate "TI DSPS platforms" | 59 | tristate "TI DSPS platforms" |
60 | depends on SOC_OMAPTI81XX || SOC_OMAPAM33XX | 60 | depends on SOC_TI81XX || SOC_AM33XX |
61 | 61 | ||
62 | config USB_MUSB_BLACKFIN | 62 | config USB_MUSB_BLACKFIN |
63 | tristate "Blackfin" | 63 | tristate "Blackfin" |
diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c index 217808d9fbe1..494772fc9e23 100644 --- a/drivers/usb/musb/musb_dsps.c +++ b/drivers/usb/musb/musb_dsps.c | |||
@@ -479,9 +479,9 @@ static int __devinit dsps_create_musb_pdev(struct dsps_glue *glue, u8 id) | |||
479 | ret = -ENODEV; | 479 | ret = -ENODEV; |
480 | goto err0; | 480 | goto err0; |
481 | } | 481 | } |
482 | strcpy((u8 *)res->name, "mc"); | ||
483 | res->parent = NULL; | 482 | res->parent = NULL; |
484 | resources[1] = *res; | 483 | resources[1] = *res; |
484 | resources[1].name = "mc"; | ||
485 | 485 | ||
486 | /* allocate the child platform device */ | 486 | /* allocate the child platform device */ |
487 | musb = platform_device_alloc("musb-hdrc", -1); | 487 | musb = platform_device_alloc("musb-hdrc", -1); |
@@ -566,27 +566,28 @@ static int __devinit dsps_probe(struct platform_device *pdev) | |||
566 | } | 566 | } |
567 | platform_set_drvdata(pdev, glue); | 567 | platform_set_drvdata(pdev, glue); |
568 | 568 | ||
569 | /* create the child platform device for first instances of musb */ | ||
570 | ret = dsps_create_musb_pdev(glue, 0); | ||
571 | if (ret != 0) { | ||
572 | dev_err(&pdev->dev, "failed to create child pdev\n"); | ||
573 | goto err2; | ||
574 | } | ||
575 | |||
576 | /* enable the usbss clocks */ | 569 | /* enable the usbss clocks */ |
577 | pm_runtime_enable(&pdev->dev); | 570 | pm_runtime_enable(&pdev->dev); |
578 | 571 | ||
579 | ret = pm_runtime_get_sync(&pdev->dev); | 572 | ret = pm_runtime_get_sync(&pdev->dev); |
580 | if (ret < 0) { | 573 | if (ret < 0) { |
581 | dev_err(&pdev->dev, "pm_runtime_get_sync FAILED"); | 574 | dev_err(&pdev->dev, "pm_runtime_get_sync FAILED"); |
575 | goto err2; | ||
576 | } | ||
577 | |||
578 | /* create the child platform device for first instances of musb */ | ||
579 | ret = dsps_create_musb_pdev(glue, 0); | ||
580 | if (ret != 0) { | ||
581 | dev_err(&pdev->dev, "failed to create child pdev\n"); | ||
582 | goto err3; | 582 | goto err3; |
583 | } | 583 | } |
584 | 584 | ||
585 | return 0; | 585 | return 0; |
586 | 586 | ||
587 | err3: | 587 | err3: |
588 | pm_runtime_disable(&pdev->dev); | 588 | pm_runtime_put(&pdev->dev); |
589 | err2: | 589 | err2: |
590 | pm_runtime_disable(&pdev->dev); | ||
590 | kfree(glue->wrp); | 591 | kfree(glue->wrp); |
591 | err1: | 592 | err1: |
592 | kfree(glue); | 593 | kfree(glue); |
diff --git a/drivers/usb/renesas_usbhs/common.c b/drivers/usb/renesas_usbhs/common.c index 8c9bb1ad3069..681da06170c2 100644 --- a/drivers/usb/renesas_usbhs/common.c +++ b/drivers/usb/renesas_usbhs/common.c | |||
@@ -603,12 +603,12 @@ static int usbhsc_resume(struct device *dev) | |||
603 | struct usbhs_priv *priv = dev_get_drvdata(dev); | 603 | struct usbhs_priv *priv = dev_get_drvdata(dev); |
604 | struct platform_device *pdev = usbhs_priv_to_pdev(priv); | 604 | struct platform_device *pdev = usbhs_priv_to_pdev(priv); |
605 | 605 | ||
606 | usbhs_platform_call(priv, phy_reset, pdev); | ||
607 | |||
608 | if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) | 606 | if (!usbhsc_flags_has(priv, USBHSF_RUNTIME_PWCTRL)) |
609 | usbhsc_power_ctrl(priv, 1); | 607 | usbhsc_power_ctrl(priv, 1); |
610 | 608 | ||
611 | usbhsc_hotplug(priv); | 609 | usbhs_platform_call(priv, phy_reset, pdev); |
610 | |||
611 | usbhsc_drvcllbck_notify_hotplug(pdev); | ||
612 | 612 | ||
613 | return 0; | 613 | return 0; |
614 | } | 614 | } |
diff --git a/drivers/usb/renesas_usbhs/mod_host.c b/drivers/usb/renesas_usbhs/mod_host.c index 1834cf50888c..9b69a1323294 100644 --- a/drivers/usb/renesas_usbhs/mod_host.c +++ b/drivers/usb/renesas_usbhs/mod_host.c | |||
@@ -1266,6 +1266,12 @@ static int usbhsh_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue, | |||
1266 | return ret; | 1266 | return ret; |
1267 | } | 1267 | } |
1268 | 1268 | ||
1269 | static int usbhsh_bus_nop(struct usb_hcd *hcd) | ||
1270 | { | ||
1271 | /* nothing to do */ | ||
1272 | return 0; | ||
1273 | } | ||
1274 | |||
1269 | static struct hc_driver usbhsh_driver = { | 1275 | static struct hc_driver usbhsh_driver = { |
1270 | .description = usbhsh_hcd_name, | 1276 | .description = usbhsh_hcd_name, |
1271 | .hcd_priv_size = sizeof(struct usbhsh_hpriv), | 1277 | .hcd_priv_size = sizeof(struct usbhsh_hpriv), |
@@ -1290,6 +1296,8 @@ static struct hc_driver usbhsh_driver = { | |||
1290 | */ | 1296 | */ |
1291 | .hub_status_data = usbhsh_hub_status_data, | 1297 | .hub_status_data = usbhsh_hub_status_data, |
1292 | .hub_control = usbhsh_hub_control, | 1298 | .hub_control = usbhsh_hub_control, |
1299 | .bus_suspend = usbhsh_bus_nop, | ||
1300 | .bus_resume = usbhsh_bus_nop, | ||
1293 | }; | 1301 | }; |
1294 | 1302 | ||
1295 | /* | 1303 | /* |
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index f398d1e34474..c15f2e7cefc7 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c | |||
@@ -61,18 +61,23 @@ static int usb_serial_device_probe(struct device *dev) | |||
61 | goto exit; | 61 | goto exit; |
62 | } | 62 | } |
63 | 63 | ||
64 | /* make sure suspend/resume doesn't race against port_probe */ | ||
65 | retval = usb_autopm_get_interface(port->serial->interface); | ||
66 | if (retval) | ||
67 | goto exit; | ||
68 | |||
64 | driver = port->serial->type; | 69 | driver = port->serial->type; |
65 | if (driver->port_probe) { | 70 | if (driver->port_probe) { |
66 | retval = driver->port_probe(port); | 71 | retval = driver->port_probe(port); |
67 | if (retval) | 72 | if (retval) |
68 | goto exit; | 73 | goto exit_with_autopm; |
69 | } | 74 | } |
70 | 75 | ||
71 | retval = device_create_file(dev, &dev_attr_port_number); | 76 | retval = device_create_file(dev, &dev_attr_port_number); |
72 | if (retval) { | 77 | if (retval) { |
73 | if (driver->port_remove) | 78 | if (driver->port_remove) |
74 | retval = driver->port_remove(port); | 79 | retval = driver->port_remove(port); |
75 | goto exit; | 80 | goto exit_with_autopm; |
76 | } | 81 | } |
77 | 82 | ||
78 | minor = port->number; | 83 | minor = port->number; |
@@ -81,6 +86,8 @@ static int usb_serial_device_probe(struct device *dev) | |||
81 | "%s converter now attached to ttyUSB%d\n", | 86 | "%s converter now attached to ttyUSB%d\n", |
82 | driver->description, minor); | 87 | driver->description, minor); |
83 | 88 | ||
89 | exit_with_autopm: | ||
90 | usb_autopm_put_interface(port->serial->interface); | ||
84 | exit: | 91 | exit: |
85 | return retval; | 92 | return retval; |
86 | } | 93 | } |
@@ -96,6 +103,9 @@ static int usb_serial_device_remove(struct device *dev) | |||
96 | if (!port) | 103 | if (!port) |
97 | return -ENODEV; | 104 | return -ENODEV; |
98 | 105 | ||
106 | /* make sure suspend/resume doesn't race against port_remove */ | ||
107 | usb_autopm_get_interface(port->serial->interface); | ||
108 | |||
99 | device_remove_file(&port->dev, &dev_attr_port_number); | 109 | device_remove_file(&port->dev, &dev_attr_port_number); |
100 | 110 | ||
101 | driver = port->serial->type; | 111 | driver = port->serial->type; |
@@ -107,6 +117,7 @@ static int usb_serial_device_remove(struct device *dev) | |||
107 | dev_info(dev, "%s converter now disconnected from ttyUSB%d\n", | 117 | dev_info(dev, "%s converter now disconnected from ttyUSB%d\n", |
108 | driver->description, minor); | 118 | driver->description, minor); |
109 | 119 | ||
120 | usb_autopm_put_interface(port->serial->interface); | ||
110 | return retval; | 121 | return retval; |
111 | } | 122 | } |
112 | 123 | ||
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c index bc912e5a3beb..5620db6469e5 100644 --- a/drivers/usb/serial/ftdi_sio.c +++ b/drivers/usb/serial/ftdi_sio.c | |||
@@ -811,6 +811,7 @@ static struct usb_device_id id_table_combined [] = { | |||
811 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, | 811 | { USB_DEVICE(LARSENBRUSGAARD_VID, LB_ALTITRACK_PID) }, |
812 | { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, | 812 | { USB_DEVICE(GN_OTOMETRICS_VID, AURICAL_USB_PID) }, |
813 | { USB_DEVICE(PI_VID, PI_E861_PID) }, | 813 | { USB_DEVICE(PI_VID, PI_E861_PID) }, |
814 | { USB_DEVICE(KONDO_VID, KONDO_USB_SERIAL_PID) }, | ||
814 | { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, | 815 | { USB_DEVICE(BAYER_VID, BAYER_CONTOUR_CABLE_PID) }, |
815 | { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), | 816 | { USB_DEVICE(FTDI_VID, MARVELL_OPENRD_PID), |
816 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, | 817 | .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk }, |
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h index 5661c7e2d415..5dd96ca6c380 100644 --- a/drivers/usb/serial/ftdi_sio_ids.h +++ b/drivers/usb/serial/ftdi_sio_ids.h | |||
@@ -795,6 +795,13 @@ | |||
795 | #define PI_E861_PID 0x1008 /* E-861 piezo controller USB connection */ | 795 | #define PI_E861_PID 0x1008 /* E-861 piezo controller USB connection */ |
796 | 796 | ||
797 | /* | 797 | /* |
798 | * Kondo Kagaku Co.Ltd. | ||
799 | * http://www.kondo-robot.com/EN | ||
800 | */ | ||
801 | #define KONDO_VID 0x165c | ||
802 | #define KONDO_USB_SERIAL_PID 0x0002 | ||
803 | |||
804 | /* | ||
798 | * Bayer Ascensia Contour blood glucose meter USB-converter cable. | 805 | * Bayer Ascensia Contour blood glucose meter USB-converter cable. |
799 | * http://winglucofacts.com/cables/ | 806 | * http://winglucofacts.com/cables/ |
800 | */ | 807 | */ |
diff --git a/drivers/usb/serial/ipw.c b/drivers/usb/serial/ipw.c index 5811d34b6c6b..2cb30c535839 100644 --- a/drivers/usb/serial/ipw.c +++ b/drivers/usb/serial/ipw.c | |||
@@ -227,7 +227,6 @@ static void ipw_release(struct usb_serial *serial) | |||
227 | { | 227 | { |
228 | struct usb_wwan_intf_private *data = usb_get_serial_data(serial); | 228 | struct usb_wwan_intf_private *data = usb_get_serial_data(serial); |
229 | 229 | ||
230 | usb_wwan_release(serial); | ||
231 | usb_set_serial_data(serial, NULL); | 230 | usb_set_serial_data(serial, NULL); |
232 | kfree(data); | 231 | kfree(data); |
233 | } | 232 | } |
@@ -309,12 +308,12 @@ static struct usb_serial_driver ipw_device = { | |||
309 | .description = "IPWireless converter", | 308 | .description = "IPWireless converter", |
310 | .id_table = id_table, | 309 | .id_table = id_table, |
311 | .num_ports = 1, | 310 | .num_ports = 1, |
312 | .disconnect = usb_wwan_disconnect, | ||
313 | .open = ipw_open, | 311 | .open = ipw_open, |
314 | .close = ipw_close, | 312 | .close = ipw_close, |
315 | .probe = ipw_probe, | 313 | .probe = ipw_probe, |
316 | .attach = usb_wwan_startup, | 314 | .attach = usb_wwan_startup, |
317 | .release = ipw_release, | 315 | .release = ipw_release, |
316 | .port_remove = usb_wwan_port_remove, | ||
318 | .dtr_rts = ipw_dtr_rts, | 317 | .dtr_rts = ipw_dtr_rts, |
319 | .write = usb_wwan_write, | 318 | .write = usb_wwan_write, |
320 | }; | 319 | }; |
diff --git a/drivers/usb/serial/mos7840.c b/drivers/usb/serial/mos7840.c index 57eca2448424..2f6da1e89bfa 100644 --- a/drivers/usb/serial/mos7840.c +++ b/drivers/usb/serial/mos7840.c | |||
@@ -82,8 +82,7 @@ | |||
82 | * Defines used for sending commands to port | 82 | * Defines used for sending commands to port |
83 | */ | 83 | */ |
84 | 84 | ||
85 | #define WAIT_FOR_EVER (HZ * 0) /* timeout urb is wait for ever */ | 85 | #define MOS_WDR_TIMEOUT 5000 /* default urb timeout */ |
86 | #define MOS_WDR_TIMEOUT (HZ * 5) /* default urb timeout */ | ||
87 | 86 | ||
88 | #define MOS_PORT1 0x0200 | 87 | #define MOS_PORT1 0x0200 |
89 | #define MOS_PORT2 0x0300 | 88 | #define MOS_PORT2 0x0300 |
@@ -1232,9 +1231,12 @@ static int mos7840_chars_in_buffer(struct tty_struct *tty) | |||
1232 | return 0; | 1231 | return 0; |
1233 | 1232 | ||
1234 | spin_lock_irqsave(&mos7840_port->pool_lock, flags); | 1233 | spin_lock_irqsave(&mos7840_port->pool_lock, flags); |
1235 | for (i = 0; i < NUM_URBS; ++i) | 1234 | for (i = 0; i < NUM_URBS; ++i) { |
1236 | if (mos7840_port->busy[i]) | 1235 | if (mos7840_port->busy[i]) { |
1237 | chars += URB_TRANSFER_BUFFER_SIZE; | 1236 | struct urb *urb = mos7840_port->write_urb_pool[i]; |
1237 | chars += urb->transfer_buffer_length; | ||
1238 | } | ||
1239 | } | ||
1238 | spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); | 1240 | spin_unlock_irqrestore(&mos7840_port->pool_lock, flags); |
1239 | dbg("%s - returns %d", __func__, chars); | 1241 | dbg("%s - returns %d", __func__, chars); |
1240 | return chars; | 1242 | return chars; |
@@ -1344,7 +1346,7 @@ static void mos7840_close(struct usb_serial_port *port) | |||
1344 | static void mos7840_block_until_chase_response(struct tty_struct *tty, | 1346 | static void mos7840_block_until_chase_response(struct tty_struct *tty, |
1345 | struct moschip_port *mos7840_port) | 1347 | struct moschip_port *mos7840_port) |
1346 | { | 1348 | { |
1347 | int timeout = 1 * HZ; | 1349 | int timeout = msecs_to_jiffies(1000); |
1348 | int wait = 10; | 1350 | int wait = 10; |
1349 | int count; | 1351 | int count; |
1350 | 1352 | ||
@@ -2672,7 +2674,7 @@ static int mos7840_startup(struct usb_serial *serial) | |||
2672 | 2674 | ||
2673 | /* setting configuration feature to one */ | 2675 | /* setting configuration feature to one */ |
2674 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), | 2676 | usb_control_msg(serial->dev, usb_sndctrlpipe(serial->dev, 0), |
2675 | (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, 5 * HZ); | 2677 | (__u8) 0x03, 0x00, 0x01, 0x00, NULL, 0x00, MOS_WDR_TIMEOUT); |
2676 | return 0; | 2678 | return 0; |
2677 | error: | 2679 | error: |
2678 | for (/* nothing */; i >= 0; i--) { | 2680 | for (/* nothing */; i >= 0; i--) { |
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c index 08ff9b862049..cc40f47ecea1 100644 --- a/drivers/usb/serial/option.c +++ b/drivers/usb/serial/option.c | |||
@@ -80,85 +80,9 @@ static void option_instat_callback(struct urb *urb); | |||
80 | #define OPTION_PRODUCT_GTM380_MODEM 0x7201 | 80 | #define OPTION_PRODUCT_GTM380_MODEM 0x7201 |
81 | 81 | ||
82 | #define HUAWEI_VENDOR_ID 0x12D1 | 82 | #define HUAWEI_VENDOR_ID 0x12D1 |
83 | #define HUAWEI_PRODUCT_E600 0x1001 | ||
84 | #define HUAWEI_PRODUCT_E220 0x1003 | ||
85 | #define HUAWEI_PRODUCT_E220BIS 0x1004 | ||
86 | #define HUAWEI_PRODUCT_E1401 0x1401 | ||
87 | #define HUAWEI_PRODUCT_E1402 0x1402 | ||
88 | #define HUAWEI_PRODUCT_E1403 0x1403 | ||
89 | #define HUAWEI_PRODUCT_E1404 0x1404 | ||
90 | #define HUAWEI_PRODUCT_E1405 0x1405 | ||
91 | #define HUAWEI_PRODUCT_E1406 0x1406 | ||
92 | #define HUAWEI_PRODUCT_E1407 0x1407 | ||
93 | #define HUAWEI_PRODUCT_E1408 0x1408 | ||
94 | #define HUAWEI_PRODUCT_E1409 0x1409 | ||
95 | #define HUAWEI_PRODUCT_E140A 0x140A | ||
96 | #define HUAWEI_PRODUCT_E140B 0x140B | ||
97 | #define HUAWEI_PRODUCT_E140C 0x140C | ||
98 | #define HUAWEI_PRODUCT_E140D 0x140D | ||
99 | #define HUAWEI_PRODUCT_E140E 0x140E | ||
100 | #define HUAWEI_PRODUCT_E140F 0x140F | ||
101 | #define HUAWEI_PRODUCT_E1410 0x1410 | ||
102 | #define HUAWEI_PRODUCT_E1411 0x1411 | ||
103 | #define HUAWEI_PRODUCT_E1412 0x1412 | ||
104 | #define HUAWEI_PRODUCT_E1413 0x1413 | ||
105 | #define HUAWEI_PRODUCT_E1414 0x1414 | ||
106 | #define HUAWEI_PRODUCT_E1415 0x1415 | ||
107 | #define HUAWEI_PRODUCT_E1416 0x1416 | ||
108 | #define HUAWEI_PRODUCT_E1417 0x1417 | ||
109 | #define HUAWEI_PRODUCT_E1418 0x1418 | ||
110 | #define HUAWEI_PRODUCT_E1419 0x1419 | ||
111 | #define HUAWEI_PRODUCT_E141A 0x141A | ||
112 | #define HUAWEI_PRODUCT_E141B 0x141B | ||
113 | #define HUAWEI_PRODUCT_E141C 0x141C | ||
114 | #define HUAWEI_PRODUCT_E141D 0x141D | ||
115 | #define HUAWEI_PRODUCT_E141E 0x141E | ||
116 | #define HUAWEI_PRODUCT_E141F 0x141F | ||
117 | #define HUAWEI_PRODUCT_E1420 0x1420 | ||
118 | #define HUAWEI_PRODUCT_E1421 0x1421 | ||
119 | #define HUAWEI_PRODUCT_E1422 0x1422 | ||
120 | #define HUAWEI_PRODUCT_E1423 0x1423 | ||
121 | #define HUAWEI_PRODUCT_E1424 0x1424 | ||
122 | #define HUAWEI_PRODUCT_E1425 0x1425 | ||
123 | #define HUAWEI_PRODUCT_E1426 0x1426 | ||
124 | #define HUAWEI_PRODUCT_E1427 0x1427 | ||
125 | #define HUAWEI_PRODUCT_E1428 0x1428 | ||
126 | #define HUAWEI_PRODUCT_E1429 0x1429 | ||
127 | #define HUAWEI_PRODUCT_E142A 0x142A | ||
128 | #define HUAWEI_PRODUCT_E142B 0x142B | ||
129 | #define HUAWEI_PRODUCT_E142C 0x142C | ||
130 | #define HUAWEI_PRODUCT_E142D 0x142D | ||
131 | #define HUAWEI_PRODUCT_E142E 0x142E | ||
132 | #define HUAWEI_PRODUCT_E142F 0x142F | ||
133 | #define HUAWEI_PRODUCT_E1430 0x1430 | ||
134 | #define HUAWEI_PRODUCT_E1431 0x1431 | ||
135 | #define HUAWEI_PRODUCT_E1432 0x1432 | ||
136 | #define HUAWEI_PRODUCT_E1433 0x1433 | ||
137 | #define HUAWEI_PRODUCT_E1434 0x1434 | ||
138 | #define HUAWEI_PRODUCT_E1435 0x1435 | ||
139 | #define HUAWEI_PRODUCT_E1436 0x1436 | ||
140 | #define HUAWEI_PRODUCT_E1437 0x1437 | ||
141 | #define HUAWEI_PRODUCT_E1438 0x1438 | ||
142 | #define HUAWEI_PRODUCT_E1439 0x1439 | ||
143 | #define HUAWEI_PRODUCT_E143A 0x143A | ||
144 | #define HUAWEI_PRODUCT_E143B 0x143B | ||
145 | #define HUAWEI_PRODUCT_E143C 0x143C | ||
146 | #define HUAWEI_PRODUCT_E143D 0x143D | ||
147 | #define HUAWEI_PRODUCT_E143E 0x143E | ||
148 | #define HUAWEI_PRODUCT_E143F 0x143F | ||
149 | #define HUAWEI_PRODUCT_K4505 0x1464 | 83 | #define HUAWEI_PRODUCT_K4505 0x1464 |
150 | #define HUAWEI_PRODUCT_K3765 0x1465 | 84 | #define HUAWEI_PRODUCT_K3765 0x1465 |
151 | #define HUAWEI_PRODUCT_E14AC 0x14AC | ||
152 | #define HUAWEI_PRODUCT_K3806 0x14AE | ||
153 | #define HUAWEI_PRODUCT_K4605 0x14C6 | 85 | #define HUAWEI_PRODUCT_K4605 0x14C6 |
154 | #define HUAWEI_PRODUCT_K5005 0x14C8 | ||
155 | #define HUAWEI_PRODUCT_K3770 0x14C9 | ||
156 | #define HUAWEI_PRODUCT_K3771 0x14CA | ||
157 | #define HUAWEI_PRODUCT_K4510 0x14CB | ||
158 | #define HUAWEI_PRODUCT_K4511 0x14CC | ||
159 | #define HUAWEI_PRODUCT_ETS1220 0x1803 | ||
160 | #define HUAWEI_PRODUCT_E353 0x1506 | ||
161 | #define HUAWEI_PRODUCT_E173S 0x1C05 | ||
162 | 86 | ||
163 | #define QUANTA_VENDOR_ID 0x0408 | 87 | #define QUANTA_VENDOR_ID 0x0408 |
164 | #define QUANTA_PRODUCT_Q101 0xEA02 | 88 | #define QUANTA_PRODUCT_Q101 0xEA02 |
@@ -615,104 +539,123 @@ static const struct usb_device_id option_ids[] = { | |||
615 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, | 539 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLX) }, |
616 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, | 540 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GKE) }, |
617 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, | 541 | { USB_DEVICE(QUANTA_VENDOR_ID, QUANTA_PRODUCT_GLE) }, |
618 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600, 0xff, 0xff, 0xff) }, | ||
619 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220, 0xff, 0xff, 0xff) }, | ||
620 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220BIS, 0xff, 0xff, 0xff) }, | ||
621 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1401, 0xff, 0xff, 0xff) }, | ||
622 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1402, 0xff, 0xff, 0xff) }, | ||
623 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1403, 0xff, 0xff, 0xff) }, | ||
624 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1404, 0xff, 0xff, 0xff) }, | ||
625 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1405, 0xff, 0xff, 0xff) }, | ||
626 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1406, 0xff, 0xff, 0xff) }, | ||
627 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1407, 0xff, 0xff, 0xff) }, | ||
628 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1408, 0xff, 0xff, 0xff) }, | ||
629 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1409, 0xff, 0xff, 0xff) }, | ||
630 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140A, 0xff, 0xff, 0xff) }, | ||
631 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140B, 0xff, 0xff, 0xff) }, | ||
632 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140C, 0xff, 0xff, 0xff) }, | ||
633 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140D, 0xff, 0xff, 0xff) }, | ||
634 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140E, 0xff, 0xff, 0xff) }, | ||
635 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E140F, 0xff, 0xff, 0xff) }, | ||
636 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1410, 0xff, 0xff, 0xff) }, | ||
637 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1411, 0xff, 0xff, 0xff) }, | ||
638 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1412, 0xff, 0xff, 0xff) }, | ||
639 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1413, 0xff, 0xff, 0xff) }, | ||
640 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1414, 0xff, 0xff, 0xff) }, | ||
641 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1415, 0xff, 0xff, 0xff) }, | ||
642 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1416, 0xff, 0xff, 0xff) }, | ||
643 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1417, 0xff, 0xff, 0xff) }, | ||
644 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1418, 0xff, 0xff, 0xff) }, | ||
645 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1419, 0xff, 0xff, 0xff) }, | ||
646 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141A, 0xff, 0xff, 0xff) }, | ||
647 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141B, 0xff, 0xff, 0xff) }, | ||
648 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141C, 0xff, 0xff, 0xff) }, | ||
649 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141D, 0xff, 0xff, 0xff) }, | ||
650 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141E, 0xff, 0xff, 0xff) }, | ||
651 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E141F, 0xff, 0xff, 0xff) }, | ||
652 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1420, 0xff, 0xff, 0xff) }, | ||
653 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1421, 0xff, 0xff, 0xff) }, | ||
654 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1422, 0xff, 0xff, 0xff) }, | ||
655 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1423, 0xff, 0xff, 0xff) }, | ||
656 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1424, 0xff, 0xff, 0xff) }, | ||
657 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1425, 0xff, 0xff, 0xff) }, | ||
658 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1426, 0xff, 0xff, 0xff) }, | ||
659 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1427, 0xff, 0xff, 0xff) }, | ||
660 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1428, 0xff, 0xff, 0xff) }, | ||
661 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1429, 0xff, 0xff, 0xff) }, | ||
662 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142A, 0xff, 0xff, 0xff) }, | ||
663 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142B, 0xff, 0xff, 0xff) }, | ||
664 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142C, 0xff, 0xff, 0xff) }, | ||
665 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142D, 0xff, 0xff, 0xff) }, | ||
666 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142E, 0xff, 0xff, 0xff) }, | ||
667 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E142F, 0xff, 0xff, 0xff) }, | ||
668 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1430, 0xff, 0xff, 0xff) }, | ||
669 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1431, 0xff, 0xff, 0xff) }, | ||
670 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1432, 0xff, 0xff, 0xff) }, | ||
671 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1433, 0xff, 0xff, 0xff) }, | ||
672 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1434, 0xff, 0xff, 0xff) }, | ||
673 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1435, 0xff, 0xff, 0xff) }, | ||
674 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1436, 0xff, 0xff, 0xff) }, | ||
675 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1437, 0xff, 0xff, 0xff) }, | ||
676 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1438, 0xff, 0xff, 0xff) }, | ||
677 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E1439, 0xff, 0xff, 0xff) }, | ||
678 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143A, 0xff, 0xff, 0xff) }, | ||
679 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143B, 0xff, 0xff, 0xff) }, | ||
680 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143C, 0xff, 0xff, 0xff) }, | ||
681 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143D, 0xff, 0xff, 0xff) }, | ||
682 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143E, 0xff, 0xff, 0xff) }, | ||
683 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E143F, 0xff, 0xff, 0xff) }, | ||
684 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E173S, 0xff, 0xff, 0xff) }, | ||
685 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), | 542 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4505, 0xff, 0xff, 0xff), |
686 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, | 543 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, |
687 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), | 544 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3765, 0xff, 0xff, 0xff), |
688 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, | 545 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, |
689 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ETS1220, 0xff, 0xff, 0xff) }, | ||
690 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E14AC, 0xff, 0xff, 0xff) }, | ||
691 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3806, 0xff, 0xff, 0xff) }, | ||
692 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), | 546 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0xff, 0xff), |
693 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, | 547 | .driver_info = (kernel_ulong_t) &huawei_cdc12_blacklist }, |
694 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x31) }, | 548 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0xff, 0xff) }, |
695 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4605, 0xff, 0x01, 0x32) }, | 549 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x01) }, |
696 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x31) }, | 550 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x02) }, |
697 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x32) }, | 551 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x03) }, |
698 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K5005, 0xff, 0x01, 0x33) }, | 552 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x04) }, |
699 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x31) }, | 553 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x05) }, |
700 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3770, 0xff, 0x02, 0x32) }, | 554 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x06) }, |
701 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x31) }, | 555 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0A) }, |
702 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K3771, 0xff, 0x02, 0x32) }, | 556 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0B) }, |
703 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x31) }, | 557 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0D) }, |
704 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4510, 0xff, 0x01, 0x32) }, | 558 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0E) }, |
705 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x31) }, | 559 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x0F) }, |
706 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_K4511, 0xff, 0x01, 0x32) }, | 560 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x10) }, |
707 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x01) }, | 561 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x12) }, |
708 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x02) }, | 562 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x13) }, |
709 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x03) }, | 563 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x14) }, |
710 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x10) }, | 564 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x15) }, |
711 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x12) }, | 565 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x17) }, |
712 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x01, 0x13) }, | 566 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x18) }, |
713 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x01) }, /* E398 3G Modem */ | 567 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x19) }, |
714 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x02) }, /* E398 3G PC UI Interface */ | 568 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1A) }, |
715 | { USB_DEVICE_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E353, 0xff, 0x02, 0x03) }, /* E398 3G Application Interface */ | 569 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1B) }, |
570 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x1C) }, | ||
571 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x31) }, | ||
572 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x32) }, | ||
573 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x33) }, | ||
574 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x34) }, | ||
575 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x35) }, | ||
576 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x36) }, | ||
577 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3A) }, | ||
578 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3B) }, | ||
579 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3D) }, | ||
580 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3E) }, | ||
581 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x3F) }, | ||
582 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x48) }, | ||
583 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x49) }, | ||
584 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4A) }, | ||
585 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4B) }, | ||
586 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x4C) }, | ||
587 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x61) }, | ||
588 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x62) }, | ||
589 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x63) }, | ||
590 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x64) }, | ||
591 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x65) }, | ||
592 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x66) }, | ||
593 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6A) }, | ||
594 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6B) }, | ||
595 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6D) }, | ||
596 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6E) }, | ||
597 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x6F) }, | ||
598 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x78) }, | ||
599 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x79) }, | ||
600 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7A) }, | ||
601 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7B) }, | ||
602 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x01, 0x7C) }, | ||
603 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x01) }, | ||
604 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x02) }, | ||
605 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x03) }, | ||
606 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x04) }, | ||
607 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x05) }, | ||
608 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x06) }, | ||
609 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0A) }, | ||
610 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0B) }, | ||
611 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0D) }, | ||
612 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0E) }, | ||
613 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x0F) }, | ||
614 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x10) }, | ||
615 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x12) }, | ||
616 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x13) }, | ||
617 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x14) }, | ||
618 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x15) }, | ||
619 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x17) }, | ||
620 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x18) }, | ||
621 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x19) }, | ||
622 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1A) }, | ||
623 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1B) }, | ||
624 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x1C) }, | ||
625 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x31) }, | ||
626 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x32) }, | ||
627 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x33) }, | ||
628 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x34) }, | ||
629 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x35) }, | ||
630 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x36) }, | ||
631 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3A) }, | ||
632 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3B) }, | ||
633 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3D) }, | ||
634 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3E) }, | ||
635 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x3F) }, | ||
636 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x48) }, | ||
637 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x49) }, | ||
638 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4A) }, | ||
639 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4B) }, | ||
640 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x4C) }, | ||
641 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x61) }, | ||
642 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x62) }, | ||
643 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x63) }, | ||
644 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x64) }, | ||
645 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x65) }, | ||
646 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x66) }, | ||
647 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6A) }, | ||
648 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6B) }, | ||
649 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6D) }, | ||
650 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6E) }, | ||
651 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x6F) }, | ||
652 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x78) }, | ||
653 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x79) }, | ||
654 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7A) }, | ||
655 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7B) }, | ||
656 | { USB_VENDOR_AND_INTERFACE_INFO(HUAWEI_VENDOR_ID, 0xff, 0x02, 0x7C) }, | ||
657 | |||
658 | |||
716 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, | 659 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V640) }, |
717 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, | 660 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V620) }, |
718 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, | 661 | { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID, NOVATELWIRELESS_PRODUCT_V740) }, |
@@ -943,6 +886,8 @@ static const struct usb_device_id option_ids[] = { | |||
943 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), | 886 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1010, 0xff, 0xff, 0xff), |
944 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, | 887 | .driver_info = (kernel_ulong_t)&net_intf4_blacklist }, |
945 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, | 888 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1012, 0xff, 0xff, 0xff) }, |
889 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1018, 0xff, 0xff, 0xff), | ||
890 | .driver_info = (kernel_ulong_t)&net_intf3_blacklist }, | ||
946 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, | 891 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1057, 0xff, 0xff, 0xff) }, |
947 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, | 892 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1058, 0xff, 0xff, 0xff) }, |
948 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, | 893 | { USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, 0x1059, 0xff, 0xff, 0xff) }, |
@@ -1297,8 +1242,8 @@ static struct usb_serial_driver option_1port_device = { | |||
1297 | .tiocmset = usb_wwan_tiocmset, | 1242 | .tiocmset = usb_wwan_tiocmset, |
1298 | .ioctl = usb_wwan_ioctl, | 1243 | .ioctl = usb_wwan_ioctl, |
1299 | .attach = usb_wwan_startup, | 1244 | .attach = usb_wwan_startup, |
1300 | .disconnect = usb_wwan_disconnect, | ||
1301 | .release = option_release, | 1245 | .release = option_release, |
1246 | .port_remove = usb_wwan_port_remove, | ||
1302 | .read_int_callback = option_instat_callback, | 1247 | .read_int_callback = option_instat_callback, |
1303 | #ifdef CONFIG_PM | 1248 | #ifdef CONFIG_PM |
1304 | .suspend = usb_wwan_suspend, | 1249 | .suspend = usb_wwan_suspend, |
@@ -1414,8 +1359,6 @@ static void option_release(struct usb_serial *serial) | |||
1414 | struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial); | 1359 | struct usb_wwan_intf_private *intfdata = usb_get_serial_data(serial); |
1415 | struct option_private *priv = intfdata->private; | 1360 | struct option_private *priv = intfdata->private; |
1416 | 1361 | ||
1417 | usb_wwan_release(serial); | ||
1418 | |||
1419 | kfree(priv); | 1362 | kfree(priv); |
1420 | kfree(intfdata); | 1363 | kfree(intfdata); |
1421 | } | 1364 | } |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 8d103019d6aa..bfd50779f0c9 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -199,43 +199,49 @@ static int qcprobe(struct usb_serial *serial, const struct usb_device_id *id) | |||
199 | 199 | ||
200 | /* default to enabling interface */ | 200 | /* default to enabling interface */ |
201 | altsetting = 0; | 201 | altsetting = 0; |
202 | switch (ifnum) { | ||
203 | /* Composite mode; don't bind to the QMI/net interface as that | ||
204 | * gets handled by other drivers. | ||
205 | */ | ||
206 | 202 | ||
203 | /* Composite mode; don't bind to the QMI/net interface as that | ||
204 | * gets handled by other drivers. | ||
205 | */ | ||
206 | |||
207 | if (is_gobi1k) { | ||
207 | /* Gobi 1K USB layout: | 208 | /* Gobi 1K USB layout: |
208 | * 0: serial port (doesn't respond) | 209 | * 0: serial port (doesn't respond) |
209 | * 1: serial port (doesn't respond) | 210 | * 1: serial port (doesn't respond) |
210 | * 2: AT-capable modem port | 211 | * 2: AT-capable modem port |
211 | * 3: QMI/net | 212 | * 3: QMI/net |
212 | * | 213 | */ |
213 | * Gobi 2K+ USB layout: | 214 | if (ifnum == 2) |
215 | dev_dbg(dev, "Modem port found\n"); | ||
216 | else | ||
217 | altsetting = -1; | ||
218 | } else { | ||
219 | /* Gobi 2K+ USB layout: | ||
214 | * 0: QMI/net | 220 | * 0: QMI/net |
215 | * 1: DM/DIAG (use libqcdm from ModemManager for communication) | 221 | * 1: DM/DIAG (use libqcdm from ModemManager for communication) |
216 | * 2: AT-capable modem port | 222 | * 2: AT-capable modem port |
217 | * 3: NMEA | 223 | * 3: NMEA |
218 | */ | 224 | */ |
219 | 225 | switch (ifnum) { | |
220 | case 1: | 226 | case 0: |
221 | if (is_gobi1k) | 227 | /* Don't claim the QMI/net interface */ |
222 | altsetting = -1; | 228 | altsetting = -1; |
223 | else | 229 | break; |
230 | case 1: | ||
224 | dev_dbg(dev, "Gobi 2K+ DM/DIAG interface found\n"); | 231 | dev_dbg(dev, "Gobi 2K+ DM/DIAG interface found\n"); |
225 | break; | 232 | break; |
226 | case 2: | 233 | case 2: |
227 | dev_dbg(dev, "Modem port found\n"); | 234 | dev_dbg(dev, "Modem port found\n"); |
228 | break; | 235 | break; |
229 | case 3: | 236 | case 3: |
230 | if (is_gobi1k) | ||
231 | altsetting = -1; | ||
232 | else | ||
233 | /* | 237 | /* |
234 | * NMEA (serial line 9600 8N1) | 238 | * NMEA (serial line 9600 8N1) |
235 | * # echo "\$GPS_START" > /dev/ttyUSBx | 239 | * # echo "\$GPS_START" > /dev/ttyUSBx |
236 | * # echo "\$GPS_STOP" > /dev/ttyUSBx | 240 | * # echo "\$GPS_STOP" > /dev/ttyUSBx |
237 | */ | 241 | */ |
238 | dev_dbg(dev, "Gobi 2K+ NMEA GPS interface found\n"); | 242 | dev_dbg(dev, "Gobi 2K+ NMEA GPS interface found\n"); |
243 | break; | ||
244 | } | ||
239 | } | 245 | } |
240 | 246 | ||
241 | done: | 247 | done: |
@@ -262,8 +268,7 @@ static void qc_release(struct usb_serial *serial) | |||
262 | { | 268 | { |
263 | struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); | 269 | struct usb_wwan_intf_private *priv = usb_get_serial_data(serial); |
264 | 270 | ||
265 | /* Call usb_wwan release & free the private data allocated in qcprobe */ | 271 | /* Free the private data allocated in qcprobe */ |
266 | usb_wwan_release(serial); | ||
267 | usb_set_serial_data(serial, NULL); | 272 | usb_set_serial_data(serial, NULL); |
268 | kfree(priv); | 273 | kfree(priv); |
269 | } | 274 | } |
@@ -283,8 +288,8 @@ static struct usb_serial_driver qcdevice = { | |||
283 | .write_room = usb_wwan_write_room, | 288 | .write_room = usb_wwan_write_room, |
284 | .chars_in_buffer = usb_wwan_chars_in_buffer, | 289 | .chars_in_buffer = usb_wwan_chars_in_buffer, |
285 | .attach = usb_wwan_startup, | 290 | .attach = usb_wwan_startup, |
286 | .disconnect = usb_wwan_disconnect, | ||
287 | .release = qc_release, | 291 | .release = qc_release, |
292 | .port_remove = usb_wwan_port_remove, | ||
288 | #ifdef CONFIG_PM | 293 | #ifdef CONFIG_PM |
289 | .suspend = usb_wwan_suspend, | 294 | .suspend = usb_wwan_suspend, |
290 | .resume = usb_wwan_resume, | 295 | .resume = usb_wwan_resume, |
diff --git a/drivers/usb/serial/usb-wwan.h b/drivers/usb/serial/usb-wwan.h index c47b6ec03063..1f034d2397c6 100644 --- a/drivers/usb/serial/usb-wwan.h +++ b/drivers/usb/serial/usb-wwan.h | |||
@@ -9,8 +9,7 @@ extern void usb_wwan_dtr_rts(struct usb_serial_port *port, int on); | |||
9 | extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); | 9 | extern int usb_wwan_open(struct tty_struct *tty, struct usb_serial_port *port); |
10 | extern void usb_wwan_close(struct usb_serial_port *port); | 10 | extern void usb_wwan_close(struct usb_serial_port *port); |
11 | extern int usb_wwan_startup(struct usb_serial *serial); | 11 | extern int usb_wwan_startup(struct usb_serial *serial); |
12 | extern void usb_wwan_disconnect(struct usb_serial *serial); | 12 | extern int usb_wwan_port_remove(struct usb_serial_port *port); |
13 | extern void usb_wwan_release(struct usb_serial *serial); | ||
14 | extern int usb_wwan_write_room(struct tty_struct *tty); | 13 | extern int usb_wwan_write_room(struct tty_struct *tty); |
15 | extern void usb_wwan_set_termios(struct tty_struct *tty, | 14 | extern void usb_wwan_set_termios(struct tty_struct *tty, |
16 | struct usb_serial_port *port, | 15 | struct usb_serial_port *port, |
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c index f35971dff4a5..6855d5ed0331 100644 --- a/drivers/usb/serial/usb_wwan.c +++ b/drivers/usb/serial/usb_wwan.c | |||
@@ -565,62 +565,52 @@ bail_out_error: | |||
565 | } | 565 | } |
566 | EXPORT_SYMBOL(usb_wwan_startup); | 566 | EXPORT_SYMBOL(usb_wwan_startup); |
567 | 567 | ||
568 | static void stop_read_write_urbs(struct usb_serial *serial) | 568 | int usb_wwan_port_remove(struct usb_serial_port *port) |
569 | { | 569 | { |
570 | int i, j; | 570 | int i; |
571 | struct usb_serial_port *port; | ||
572 | struct usb_wwan_port_private *portdata; | 571 | struct usb_wwan_port_private *portdata; |
573 | 572 | ||
574 | /* Stop reading/writing urbs */ | 573 | portdata = usb_get_serial_port_data(port); |
575 | for (i = 0; i < serial->num_ports; ++i) { | 574 | usb_set_serial_port_data(port, NULL); |
576 | port = serial->port[i]; | 575 | |
577 | portdata = usb_get_serial_port_data(port); | 576 | /* Stop reading/writing urbs and free them */ |
578 | for (j = 0; j < N_IN_URB; j++) | 577 | for (i = 0; i < N_IN_URB; i++) { |
579 | usb_kill_urb(portdata->in_urbs[j]); | 578 | usb_kill_urb(portdata->in_urbs[i]); |
580 | for (j = 0; j < N_OUT_URB; j++) | 579 | usb_free_urb(portdata->in_urbs[i]); |
581 | usb_kill_urb(portdata->out_urbs[j]); | 580 | free_page((unsigned long)portdata->in_buffer[i]); |
581 | } | ||
582 | for (i = 0; i < N_OUT_URB; i++) { | ||
583 | usb_kill_urb(portdata->out_urbs[i]); | ||
584 | usb_free_urb(portdata->out_urbs[i]); | ||
585 | kfree(portdata->out_buffer[i]); | ||
582 | } | 586 | } |
583 | } | ||
584 | 587 | ||
585 | void usb_wwan_disconnect(struct usb_serial *serial) | 588 | /* Now free port private data */ |
586 | { | 589 | kfree(portdata); |
587 | stop_read_write_urbs(serial); | 590 | return 0; |
588 | } | 591 | } |
589 | EXPORT_SYMBOL(usb_wwan_disconnect); | 592 | EXPORT_SYMBOL(usb_wwan_port_remove); |
590 | 593 | ||
591 | void usb_wwan_release(struct usb_serial *serial) | 594 | #ifdef CONFIG_PM |
595 | static void stop_read_write_urbs(struct usb_serial *serial) | ||
592 | { | 596 | { |
593 | int i, j; | 597 | int i, j; |
594 | struct usb_serial_port *port; | 598 | struct usb_serial_port *port; |
595 | struct usb_wwan_port_private *portdata; | 599 | struct usb_wwan_port_private *portdata; |
596 | 600 | ||
597 | /* Now free them */ | 601 | /* Stop reading/writing urbs */ |
598 | for (i = 0; i < serial->num_ports; ++i) { | 602 | for (i = 0; i < serial->num_ports; ++i) { |
599 | port = serial->port[i]; | 603 | port = serial->port[i]; |
600 | portdata = usb_get_serial_port_data(port); | 604 | portdata = usb_get_serial_port_data(port); |
601 | 605 | if (!portdata) | |
602 | for (j = 0; j < N_IN_URB; j++) { | 606 | continue; |
603 | usb_free_urb(portdata->in_urbs[j]); | 607 | for (j = 0; j < N_IN_URB; j++) |
604 | free_page((unsigned long) | 608 | usb_kill_urb(portdata->in_urbs[j]); |
605 | portdata->in_buffer[j]); | 609 | for (j = 0; j < N_OUT_URB; j++) |
606 | portdata->in_urbs[j] = NULL; | 610 | usb_kill_urb(portdata->out_urbs[j]); |
607 | } | ||
608 | for (j = 0; j < N_OUT_URB; j++) { | ||
609 | usb_free_urb(portdata->out_urbs[j]); | ||
610 | kfree(portdata->out_buffer[j]); | ||
611 | portdata->out_urbs[j] = NULL; | ||
612 | } | ||
613 | } | ||
614 | |||
615 | /* Now free per port private data */ | ||
616 | for (i = 0; i < serial->num_ports; i++) { | ||
617 | port = serial->port[i]; | ||
618 | kfree(usb_get_serial_port_data(port)); | ||
619 | } | 611 | } |
620 | } | 612 | } |
621 | EXPORT_SYMBOL(usb_wwan_release); | ||
622 | 613 | ||
623 | #ifdef CONFIG_PM | ||
624 | int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message) | 614 | int usb_wwan_suspend(struct usb_serial *serial, pm_message_t message) |
625 | { | 615 | { |
626 | struct usb_wwan_intf_private *intfdata = serial->private; | 616 | struct usb_wwan_intf_private *intfdata = serial->private; |
@@ -712,7 +702,7 @@ int usb_wwan_resume(struct usb_serial *serial) | |||
712 | 702 | ||
713 | /* skip closed ports */ | 703 | /* skip closed ports */ |
714 | spin_lock_irq(&intfdata->susp_lock); | 704 | spin_lock_irq(&intfdata->susp_lock); |
715 | if (!portdata->opened) { | 705 | if (!portdata || !portdata->opened) { |
716 | spin_unlock_irq(&intfdata->susp_lock); | 706 | spin_unlock_irq(&intfdata->susp_lock); |
717 | continue; | 707 | continue; |
718 | } | 708 | } |
diff --git a/drivers/vhost/Kconfig b/drivers/vhost/Kconfig index e4e2fd1b5107..202bba6c997c 100644 --- a/drivers/vhost/Kconfig +++ b/drivers/vhost/Kconfig | |||
@@ -9,3 +9,6 @@ config VHOST_NET | |||
9 | To compile this driver as a module, choose M here: the module will | 9 | To compile this driver as a module, choose M here: the module will |
10 | be called vhost_net. | 10 | be called vhost_net. |
11 | 11 | ||
12 | if STAGING | ||
13 | source "drivers/vhost/Kconfig.tcm" | ||
14 | endif | ||
diff --git a/drivers/vhost/Kconfig.tcm b/drivers/vhost/Kconfig.tcm new file mode 100644 index 000000000000..a9c6f76e3208 --- /dev/null +++ b/drivers/vhost/Kconfig.tcm | |||
@@ -0,0 +1,6 @@ | |||
1 | config TCM_VHOST | ||
2 | tristate "TCM_VHOST fabric module (EXPERIMENTAL)" | ||
3 | depends on TARGET_CORE && EVENTFD && EXPERIMENTAL && m | ||
4 | default n | ||
5 | ---help--- | ||
6 | Say M here to enable the TCM_VHOST fabric module for use with virtio-scsi guests | ||
diff --git a/drivers/vhost/Makefile b/drivers/vhost/Makefile index 72dd02050bb9..a27b053bc9ab 100644 --- a/drivers/vhost/Makefile +++ b/drivers/vhost/Makefile | |||
@@ -1,2 +1,4 @@ | |||
1 | obj-$(CONFIG_VHOST_NET) += vhost_net.o | 1 | obj-$(CONFIG_VHOST_NET) += vhost_net.o |
2 | vhost_net-y := vhost.o net.o | 2 | vhost_net-y := vhost.o net.o |
3 | |||
4 | obj-$(CONFIG_TCM_VHOST) += tcm_vhost.o | ||
diff --git a/drivers/vhost/tcm_vhost.c b/drivers/vhost/tcm_vhost.c new file mode 100644 index 000000000000..fb366540ed54 --- /dev/null +++ b/drivers/vhost/tcm_vhost.c | |||
@@ -0,0 +1,1628 @@ | |||
1 | /******************************************************************************* | ||
2 | * Vhost kernel TCM fabric driver for virtio SCSI initiators | ||
3 | * | ||
4 | * (C) Copyright 2010-2012 RisingTide Systems LLC. | ||
5 | * (C) Copyright 2010-2012 IBM Corp. | ||
6 | * | ||
7 | * Licensed to the Linux Foundation under the General Public License (GPL) version 2. | ||
8 | * | ||
9 | * Authors: Nicholas A. Bellinger <nab@risingtidesystems.com> | ||
10 | * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com> | ||
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 as published by | ||
14 | * the Free Software Foundation; either version 2 of the License, or | ||
15 | * (at your option) any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | ****************************************************************************/ | ||
23 | |||
24 | #include <linux/module.h> | ||
25 | #include <linux/moduleparam.h> | ||
26 | #include <generated/utsrelease.h> | ||
27 | #include <linux/utsname.h> | ||
28 | #include <linux/init.h> | ||
29 | #include <linux/slab.h> | ||
30 | #include <linux/kthread.h> | ||
31 | #include <linux/types.h> | ||
32 | #include <linux/string.h> | ||
33 | #include <linux/configfs.h> | ||
34 | #include <linux/ctype.h> | ||
35 | #include <linux/compat.h> | ||
36 | #include <linux/eventfd.h> | ||
37 | #include <linux/vhost.h> | ||
38 | #include <linux/fs.h> | ||
39 | #include <linux/miscdevice.h> | ||
40 | #include <asm/unaligned.h> | ||
41 | #include <scsi/scsi.h> | ||
42 | #include <scsi/scsi_tcq.h> | ||
43 | #include <target/target_core_base.h> | ||
44 | #include <target/target_core_fabric.h> | ||
45 | #include <target/target_core_fabric_configfs.h> | ||
46 | #include <target/target_core_configfs.h> | ||
47 | #include <target/configfs_macros.h> | ||
48 | #include <linux/vhost.h> | ||
49 | #include <linux/virtio_net.h> /* TODO vhost.h currently depends on this */ | ||
50 | #include <linux/virtio_scsi.h> | ||
51 | |||
52 | #include "vhost.c" | ||
53 | #include "vhost.h" | ||
54 | #include "tcm_vhost.h" | ||
55 | |||
56 | struct vhost_scsi { | ||
57 | atomic_t vhost_ref_cnt; | ||
58 | struct tcm_vhost_tpg *vs_tpg; | ||
59 | struct vhost_dev dev; | ||
60 | struct vhost_virtqueue vqs[3]; | ||
61 | |||
62 | struct vhost_work vs_completion_work; /* cmd completion work item */ | ||
63 | struct list_head vs_completion_list; /* cmd completion queue */ | ||
64 | spinlock_t vs_completion_lock; /* protects s_completion_list */ | ||
65 | }; | ||
66 | |||
67 | /* Local pointer to allocated TCM configfs fabric module */ | ||
68 | static struct target_fabric_configfs *tcm_vhost_fabric_configfs; | ||
69 | |||
70 | static struct workqueue_struct *tcm_vhost_workqueue; | ||
71 | |||
72 | /* Global spinlock to protect tcm_vhost TPG list for vhost IOCTL access */ | ||
73 | static DEFINE_MUTEX(tcm_vhost_mutex); | ||
74 | static LIST_HEAD(tcm_vhost_list); | ||
75 | |||
76 | static int tcm_vhost_check_true(struct se_portal_group *se_tpg) | ||
77 | { | ||
78 | return 1; | ||
79 | } | ||
80 | |||
81 | static int tcm_vhost_check_false(struct se_portal_group *se_tpg) | ||
82 | { | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | static char *tcm_vhost_get_fabric_name(void) | ||
87 | { | ||
88 | return "vhost"; | ||
89 | } | ||
90 | |||
91 | static u8 tcm_vhost_get_fabric_proto_ident(struct se_portal_group *se_tpg) | ||
92 | { | ||
93 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | ||
94 | struct tcm_vhost_tpg, se_tpg); | ||
95 | struct tcm_vhost_tport *tport = tpg->tport; | ||
96 | |||
97 | switch (tport->tport_proto_id) { | ||
98 | case SCSI_PROTOCOL_SAS: | ||
99 | return sas_get_fabric_proto_ident(se_tpg); | ||
100 | case SCSI_PROTOCOL_FCP: | ||
101 | return fc_get_fabric_proto_ident(se_tpg); | ||
102 | case SCSI_PROTOCOL_ISCSI: | ||
103 | return iscsi_get_fabric_proto_ident(se_tpg); | ||
104 | default: | ||
105 | pr_err("Unknown tport_proto_id: 0x%02x, using" | ||
106 | " SAS emulation\n", tport->tport_proto_id); | ||
107 | break; | ||
108 | } | ||
109 | |||
110 | return sas_get_fabric_proto_ident(se_tpg); | ||
111 | } | ||
112 | |||
113 | static char *tcm_vhost_get_fabric_wwn(struct se_portal_group *se_tpg) | ||
114 | { | ||
115 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | ||
116 | struct tcm_vhost_tpg, se_tpg); | ||
117 | struct tcm_vhost_tport *tport = tpg->tport; | ||
118 | |||
119 | return &tport->tport_name[0]; | ||
120 | } | ||
121 | |||
122 | static u16 tcm_vhost_get_tag(struct se_portal_group *se_tpg) | ||
123 | { | ||
124 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | ||
125 | struct tcm_vhost_tpg, se_tpg); | ||
126 | return tpg->tport_tpgt; | ||
127 | } | ||
128 | |||
129 | static u32 tcm_vhost_get_default_depth(struct se_portal_group *se_tpg) | ||
130 | { | ||
131 | return 1; | ||
132 | } | ||
133 | |||
134 | static u32 tcm_vhost_get_pr_transport_id( | ||
135 | struct se_portal_group *se_tpg, | ||
136 | struct se_node_acl *se_nacl, | ||
137 | struct t10_pr_registration *pr_reg, | ||
138 | int *format_code, | ||
139 | unsigned char *buf) | ||
140 | { | ||
141 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | ||
142 | struct tcm_vhost_tpg, se_tpg); | ||
143 | struct tcm_vhost_tport *tport = tpg->tport; | ||
144 | |||
145 | switch (tport->tport_proto_id) { | ||
146 | case SCSI_PROTOCOL_SAS: | ||
147 | return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg, | ||
148 | format_code, buf); | ||
149 | case SCSI_PROTOCOL_FCP: | ||
150 | return fc_get_pr_transport_id(se_tpg, se_nacl, pr_reg, | ||
151 | format_code, buf); | ||
152 | case SCSI_PROTOCOL_ISCSI: | ||
153 | return iscsi_get_pr_transport_id(se_tpg, se_nacl, pr_reg, | ||
154 | format_code, buf); | ||
155 | default: | ||
156 | pr_err("Unknown tport_proto_id: 0x%02x, using" | ||
157 | " SAS emulation\n", tport->tport_proto_id); | ||
158 | break; | ||
159 | } | ||
160 | |||
161 | return sas_get_pr_transport_id(se_tpg, se_nacl, pr_reg, | ||
162 | format_code, buf); | ||
163 | } | ||
164 | |||
165 | static u32 tcm_vhost_get_pr_transport_id_len( | ||
166 | struct se_portal_group *se_tpg, | ||
167 | struct se_node_acl *se_nacl, | ||
168 | struct t10_pr_registration *pr_reg, | ||
169 | int *format_code) | ||
170 | { | ||
171 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | ||
172 | struct tcm_vhost_tpg, se_tpg); | ||
173 | struct tcm_vhost_tport *tport = tpg->tport; | ||
174 | |||
175 | switch (tport->tport_proto_id) { | ||
176 | case SCSI_PROTOCOL_SAS: | ||
177 | return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, | ||
178 | format_code); | ||
179 | case SCSI_PROTOCOL_FCP: | ||
180 | return fc_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, | ||
181 | format_code); | ||
182 | case SCSI_PROTOCOL_ISCSI: | ||
183 | return iscsi_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, | ||
184 | format_code); | ||
185 | default: | ||
186 | pr_err("Unknown tport_proto_id: 0x%02x, using" | ||
187 | " SAS emulation\n", tport->tport_proto_id); | ||
188 | break; | ||
189 | } | ||
190 | |||
191 | return sas_get_pr_transport_id_len(se_tpg, se_nacl, pr_reg, | ||
192 | format_code); | ||
193 | } | ||
194 | |||
195 | static char *tcm_vhost_parse_pr_out_transport_id( | ||
196 | struct se_portal_group *se_tpg, | ||
197 | const char *buf, | ||
198 | u32 *out_tid_len, | ||
199 | char **port_nexus_ptr) | ||
200 | { | ||
201 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | ||
202 | struct tcm_vhost_tpg, se_tpg); | ||
203 | struct tcm_vhost_tport *tport = tpg->tport; | ||
204 | |||
205 | switch (tport->tport_proto_id) { | ||
206 | case SCSI_PROTOCOL_SAS: | ||
207 | return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, | ||
208 | port_nexus_ptr); | ||
209 | case SCSI_PROTOCOL_FCP: | ||
210 | return fc_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, | ||
211 | port_nexus_ptr); | ||
212 | case SCSI_PROTOCOL_ISCSI: | ||
213 | return iscsi_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, | ||
214 | port_nexus_ptr); | ||
215 | default: | ||
216 | pr_err("Unknown tport_proto_id: 0x%02x, using" | ||
217 | " SAS emulation\n", tport->tport_proto_id); | ||
218 | break; | ||
219 | } | ||
220 | |||
221 | return sas_parse_pr_out_transport_id(se_tpg, buf, out_tid_len, | ||
222 | port_nexus_ptr); | ||
223 | } | ||
224 | |||
225 | static struct se_node_acl *tcm_vhost_alloc_fabric_acl( | ||
226 | struct se_portal_group *se_tpg) | ||
227 | { | ||
228 | struct tcm_vhost_nacl *nacl; | ||
229 | |||
230 | nacl = kzalloc(sizeof(struct tcm_vhost_nacl), GFP_KERNEL); | ||
231 | if (!nacl) { | ||
232 | pr_err("Unable to alocate struct tcm_vhost_nacl\n"); | ||
233 | return NULL; | ||
234 | } | ||
235 | |||
236 | return &nacl->se_node_acl; | ||
237 | } | ||
238 | |||
239 | static void tcm_vhost_release_fabric_acl( | ||
240 | struct se_portal_group *se_tpg, | ||
241 | struct se_node_acl *se_nacl) | ||
242 | { | ||
243 | struct tcm_vhost_nacl *nacl = container_of(se_nacl, | ||
244 | struct tcm_vhost_nacl, se_node_acl); | ||
245 | kfree(nacl); | ||
246 | } | ||
247 | |||
248 | static u32 tcm_vhost_tpg_get_inst_index(struct se_portal_group *se_tpg) | ||
249 | { | ||
250 | return 1; | ||
251 | } | ||
252 | |||
253 | static void tcm_vhost_release_cmd(struct se_cmd *se_cmd) | ||
254 | { | ||
255 | return; | ||
256 | } | ||
257 | |||
258 | static int tcm_vhost_shutdown_session(struct se_session *se_sess) | ||
259 | { | ||
260 | return 0; | ||
261 | } | ||
262 | |||
263 | static void tcm_vhost_close_session(struct se_session *se_sess) | ||
264 | { | ||
265 | return; | ||
266 | } | ||
267 | |||
268 | static u32 tcm_vhost_sess_get_index(struct se_session *se_sess) | ||
269 | { | ||
270 | return 0; | ||
271 | } | ||
272 | |||
273 | static int tcm_vhost_write_pending(struct se_cmd *se_cmd) | ||
274 | { | ||
275 | /* Go ahead and process the write immediately */ | ||
276 | target_execute_cmd(se_cmd); | ||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | static int tcm_vhost_write_pending_status(struct se_cmd *se_cmd) | ||
281 | { | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static void tcm_vhost_set_default_node_attrs(struct se_node_acl *nacl) | ||
286 | { | ||
287 | return; | ||
288 | } | ||
289 | |||
290 | static u32 tcm_vhost_get_task_tag(struct se_cmd *se_cmd) | ||
291 | { | ||
292 | return 0; | ||
293 | } | ||
294 | |||
295 | static int tcm_vhost_get_cmd_state(struct se_cmd *se_cmd) | ||
296 | { | ||
297 | return 0; | ||
298 | } | ||
299 | |||
300 | static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *); | ||
301 | |||
302 | static int tcm_vhost_queue_data_in(struct se_cmd *se_cmd) | ||
303 | { | ||
304 | struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd, | ||
305 | struct tcm_vhost_cmd, tvc_se_cmd); | ||
306 | vhost_scsi_complete_cmd(tv_cmd); | ||
307 | return 0; | ||
308 | } | ||
309 | |||
310 | static int tcm_vhost_queue_status(struct se_cmd *se_cmd) | ||
311 | { | ||
312 | struct tcm_vhost_cmd *tv_cmd = container_of(se_cmd, | ||
313 | struct tcm_vhost_cmd, tvc_se_cmd); | ||
314 | vhost_scsi_complete_cmd(tv_cmd); | ||
315 | return 0; | ||
316 | } | ||
317 | |||
318 | static int tcm_vhost_queue_tm_rsp(struct se_cmd *se_cmd) | ||
319 | { | ||
320 | return 0; | ||
321 | } | ||
322 | |||
323 | static u16 tcm_vhost_set_fabric_sense_len(struct se_cmd *se_cmd, | ||
324 | u32 sense_length) | ||
325 | { | ||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static u16 tcm_vhost_get_fabric_sense_len(void) | ||
330 | { | ||
331 | return 0; | ||
332 | } | ||
333 | |||
334 | static void vhost_scsi_free_cmd(struct tcm_vhost_cmd *tv_cmd) | ||
335 | { | ||
336 | struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; | ||
337 | |||
338 | /* TODO locking against target/backend threads? */ | ||
339 | transport_generic_free_cmd(se_cmd, 1); | ||
340 | |||
341 | if (tv_cmd->tvc_sgl_count) { | ||
342 | u32 i; | ||
343 | for (i = 0; i < tv_cmd->tvc_sgl_count; i++) | ||
344 | put_page(sg_page(&tv_cmd->tvc_sgl[i])); | ||
345 | |||
346 | kfree(tv_cmd->tvc_sgl); | ||
347 | } | ||
348 | |||
349 | kfree(tv_cmd); | ||
350 | } | ||
351 | |||
352 | /* Dequeue a command from the completion list */ | ||
353 | static struct tcm_vhost_cmd *vhost_scsi_get_cmd_from_completion( | ||
354 | struct vhost_scsi *vs) | ||
355 | { | ||
356 | struct tcm_vhost_cmd *tv_cmd = NULL; | ||
357 | |||
358 | spin_lock_bh(&vs->vs_completion_lock); | ||
359 | if (list_empty(&vs->vs_completion_list)) { | ||
360 | spin_unlock_bh(&vs->vs_completion_lock); | ||
361 | return NULL; | ||
362 | } | ||
363 | |||
364 | list_for_each_entry(tv_cmd, &vs->vs_completion_list, | ||
365 | tvc_completion_list) { | ||
366 | list_del(&tv_cmd->tvc_completion_list); | ||
367 | break; | ||
368 | } | ||
369 | spin_unlock_bh(&vs->vs_completion_lock); | ||
370 | return tv_cmd; | ||
371 | } | ||
372 | |||
373 | /* Fill in status and signal that we are done processing this command | ||
374 | * | ||
375 | * This is scheduled in the vhost work queue so we are called with the owner | ||
376 | * process mm and can access the vring. | ||
377 | */ | ||
378 | static void vhost_scsi_complete_cmd_work(struct vhost_work *work) | ||
379 | { | ||
380 | struct vhost_scsi *vs = container_of(work, struct vhost_scsi, | ||
381 | vs_completion_work); | ||
382 | struct tcm_vhost_cmd *tv_cmd; | ||
383 | |||
384 | while ((tv_cmd = vhost_scsi_get_cmd_from_completion(vs)) != NULL) { | ||
385 | struct virtio_scsi_cmd_resp v_rsp; | ||
386 | struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; | ||
387 | int ret; | ||
388 | |||
389 | pr_debug("%s tv_cmd %p resid %u status %#02x\n", __func__, | ||
390 | tv_cmd, se_cmd->residual_count, se_cmd->scsi_status); | ||
391 | |||
392 | memset(&v_rsp, 0, sizeof(v_rsp)); | ||
393 | v_rsp.resid = se_cmd->residual_count; | ||
394 | /* TODO is status_qualifier field needed? */ | ||
395 | v_rsp.status = se_cmd->scsi_status; | ||
396 | v_rsp.sense_len = se_cmd->scsi_sense_length; | ||
397 | memcpy(v_rsp.sense, tv_cmd->tvc_sense_buf, | ||
398 | v_rsp.sense_len); | ||
399 | ret = copy_to_user(tv_cmd->tvc_resp, &v_rsp, sizeof(v_rsp)); | ||
400 | if (likely(ret == 0)) | ||
401 | vhost_add_used(&vs->vqs[2], tv_cmd->tvc_vq_desc, 0); | ||
402 | else | ||
403 | pr_err("Faulted on virtio_scsi_cmd_resp\n"); | ||
404 | |||
405 | vhost_scsi_free_cmd(tv_cmd); | ||
406 | } | ||
407 | |||
408 | vhost_signal(&vs->dev, &vs->vqs[2]); | ||
409 | } | ||
410 | |||
411 | static void vhost_scsi_complete_cmd(struct tcm_vhost_cmd *tv_cmd) | ||
412 | { | ||
413 | struct vhost_scsi *vs = tv_cmd->tvc_vhost; | ||
414 | |||
415 | pr_debug("%s tv_cmd %p\n", __func__, tv_cmd); | ||
416 | |||
417 | spin_lock_bh(&vs->vs_completion_lock); | ||
418 | list_add_tail(&tv_cmd->tvc_completion_list, &vs->vs_completion_list); | ||
419 | spin_unlock_bh(&vs->vs_completion_lock); | ||
420 | |||
421 | vhost_work_queue(&vs->dev, &vs->vs_completion_work); | ||
422 | } | ||
423 | |||
424 | static struct tcm_vhost_cmd *vhost_scsi_allocate_cmd( | ||
425 | struct tcm_vhost_tpg *tv_tpg, | ||
426 | struct virtio_scsi_cmd_req *v_req, | ||
427 | u32 exp_data_len, | ||
428 | int data_direction) | ||
429 | { | ||
430 | struct tcm_vhost_cmd *tv_cmd; | ||
431 | struct tcm_vhost_nexus *tv_nexus; | ||
432 | struct se_portal_group *se_tpg = &tv_tpg->se_tpg; | ||
433 | struct se_session *se_sess; | ||
434 | struct se_cmd *se_cmd; | ||
435 | int sam_task_attr; | ||
436 | |||
437 | tv_nexus = tv_tpg->tpg_nexus; | ||
438 | if (!tv_nexus) { | ||
439 | pr_err("Unable to locate active struct tcm_vhost_nexus\n"); | ||
440 | return ERR_PTR(-EIO); | ||
441 | } | ||
442 | se_sess = tv_nexus->tvn_se_sess; | ||
443 | |||
444 | tv_cmd = kzalloc(sizeof(struct tcm_vhost_cmd), GFP_ATOMIC); | ||
445 | if (!tv_cmd) { | ||
446 | pr_err("Unable to allocate struct tcm_vhost_cmd\n"); | ||
447 | return ERR_PTR(-ENOMEM); | ||
448 | } | ||
449 | INIT_LIST_HEAD(&tv_cmd->tvc_completion_list); | ||
450 | tv_cmd->tvc_tag = v_req->tag; | ||
451 | |||
452 | se_cmd = &tv_cmd->tvc_se_cmd; | ||
453 | /* | ||
454 | * Locate the SAM Task Attr from virtio_scsi_cmd_req | ||
455 | */ | ||
456 | sam_task_attr = v_req->task_attr; | ||
457 | /* | ||
458 | * Initialize struct se_cmd descriptor from TCM infrastructure | ||
459 | */ | ||
460 | transport_init_se_cmd(se_cmd, se_tpg->se_tpg_tfo, se_sess, exp_data_len, | ||
461 | data_direction, sam_task_attr, | ||
462 | &tv_cmd->tvc_sense_buf[0]); | ||
463 | |||
464 | #if 0 /* FIXME: vhost_scsi_allocate_cmd() BIDI operation */ | ||
465 | if (bidi) | ||
466 | se_cmd->se_cmd_flags |= SCF_BIDI; | ||
467 | #endif | ||
468 | return tv_cmd; | ||
469 | } | ||
470 | |||
471 | /* | ||
472 | * Map a user memory range into a scatterlist | ||
473 | * | ||
474 | * Returns the number of scatterlist entries used or -errno on error. | ||
475 | */ | ||
476 | static int vhost_scsi_map_to_sgl(struct scatterlist *sgl, | ||
477 | unsigned int sgl_count, void __user *ptr, size_t len, int write) | ||
478 | { | ||
479 | struct scatterlist *sg = sgl; | ||
480 | unsigned int npages = 0; | ||
481 | int ret; | ||
482 | |||
483 | while (len > 0) { | ||
484 | struct page *page; | ||
485 | unsigned int offset = (uintptr_t)ptr & ~PAGE_MASK; | ||
486 | unsigned int nbytes = min_t(unsigned int, | ||
487 | PAGE_SIZE - offset, len); | ||
488 | |||
489 | if (npages == sgl_count) { | ||
490 | ret = -ENOBUFS; | ||
491 | goto err; | ||
492 | } | ||
493 | |||
494 | ret = get_user_pages_fast((unsigned long)ptr, 1, write, &page); | ||
495 | BUG_ON(ret == 0); /* we should either get our page or fail */ | ||
496 | if (ret < 0) | ||
497 | goto err; | ||
498 | |||
499 | sg_set_page(sg, page, nbytes, offset); | ||
500 | ptr += nbytes; | ||
501 | len -= nbytes; | ||
502 | sg++; | ||
503 | npages++; | ||
504 | } | ||
505 | return npages; | ||
506 | |||
507 | err: | ||
508 | /* Put pages that we hold */ | ||
509 | for (sg = sgl; sg != &sgl[npages]; sg++) | ||
510 | put_page(sg_page(sg)); | ||
511 | return ret; | ||
512 | } | ||
513 | |||
514 | static int vhost_scsi_map_iov_to_sgl(struct tcm_vhost_cmd *tv_cmd, | ||
515 | struct iovec *iov, unsigned int niov, int write) | ||
516 | { | ||
517 | int ret; | ||
518 | unsigned int i; | ||
519 | u32 sgl_count; | ||
520 | struct scatterlist *sg; | ||
521 | |||
522 | /* | ||
523 | * Find out how long sglist needs to be | ||
524 | */ | ||
525 | sgl_count = 0; | ||
526 | for (i = 0; i < niov; i++) { | ||
527 | sgl_count += (((uintptr_t)iov[i].iov_base + iov[i].iov_len + | ||
528 | PAGE_SIZE - 1) >> PAGE_SHIFT) - | ||
529 | ((uintptr_t)iov[i].iov_base >> PAGE_SHIFT); | ||
530 | } | ||
531 | /* TODO overflow checking */ | ||
532 | |||
533 | sg = kmalloc(sizeof(tv_cmd->tvc_sgl[0]) * sgl_count, GFP_ATOMIC); | ||
534 | if (!sg) | ||
535 | return -ENOMEM; | ||
536 | pr_debug("%s sg %p sgl_count %u is_err %ld\n", __func__, | ||
537 | sg, sgl_count, IS_ERR(sg)); | ||
538 | sg_init_table(sg, sgl_count); | ||
539 | |||
540 | tv_cmd->tvc_sgl = sg; | ||
541 | tv_cmd->tvc_sgl_count = sgl_count; | ||
542 | |||
543 | pr_debug("Mapping %u iovecs for %u pages\n", niov, sgl_count); | ||
544 | for (i = 0; i < niov; i++) { | ||
545 | ret = vhost_scsi_map_to_sgl(sg, sgl_count, iov[i].iov_base, | ||
546 | iov[i].iov_len, write); | ||
547 | if (ret < 0) { | ||
548 | for (i = 0; i < tv_cmd->tvc_sgl_count; i++) | ||
549 | put_page(sg_page(&tv_cmd->tvc_sgl[i])); | ||
550 | kfree(tv_cmd->tvc_sgl); | ||
551 | tv_cmd->tvc_sgl = NULL; | ||
552 | tv_cmd->tvc_sgl_count = 0; | ||
553 | return ret; | ||
554 | } | ||
555 | |||
556 | sg += ret; | ||
557 | sgl_count -= ret; | ||
558 | } | ||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | static void tcm_vhost_submission_work(struct work_struct *work) | ||
563 | { | ||
564 | struct tcm_vhost_cmd *tv_cmd = | ||
565 | container_of(work, struct tcm_vhost_cmd, work); | ||
566 | struct se_cmd *se_cmd = &tv_cmd->tvc_se_cmd; | ||
567 | struct scatterlist *sg_ptr, *sg_bidi_ptr = NULL; | ||
568 | int rc, sg_no_bidi = 0; | ||
569 | /* | ||
570 | * Locate the struct se_lun pointer based on v_req->lun, and | ||
571 | * attach it to struct se_cmd | ||
572 | */ | ||
573 | rc = transport_lookup_cmd_lun(&tv_cmd->tvc_se_cmd, tv_cmd->tvc_lun); | ||
574 | if (rc < 0) { | ||
575 | pr_err("Failed to look up lun: %d\n", tv_cmd->tvc_lun); | ||
576 | transport_send_check_condition_and_sense(&tv_cmd->tvc_se_cmd, | ||
577 | tv_cmd->tvc_se_cmd.scsi_sense_reason, 0); | ||
578 | transport_generic_free_cmd(se_cmd, 0); | ||
579 | return; | ||
580 | } | ||
581 | |||
582 | rc = target_setup_cmd_from_cdb(se_cmd, tv_cmd->tvc_cdb); | ||
583 | if (rc == -ENOMEM) { | ||
584 | transport_send_check_condition_and_sense(se_cmd, | ||
585 | TCM_LOGICAL_UNIT_COMMUNICATION_FAILURE, 0); | ||
586 | transport_generic_free_cmd(se_cmd, 0); | ||
587 | return; | ||
588 | } else if (rc < 0) { | ||
589 | if (se_cmd->se_cmd_flags & SCF_SCSI_RESERVATION_CONFLICT) | ||
590 | tcm_vhost_queue_status(se_cmd); | ||
591 | else | ||
592 | transport_send_check_condition_and_sense(se_cmd, | ||
593 | se_cmd->scsi_sense_reason, 0); | ||
594 | transport_generic_free_cmd(se_cmd, 0); | ||
595 | return; | ||
596 | } | ||
597 | |||
598 | if (tv_cmd->tvc_sgl_count) { | ||
599 | sg_ptr = tv_cmd->tvc_sgl; | ||
600 | /* | ||
601 | * For BIDI commands, pass in the extra READ buffer | ||
602 | * to transport_generic_map_mem_to_cmd() below.. | ||
603 | */ | ||
604 | /* FIXME: Fix BIDI operation in tcm_vhost_submission_work() */ | ||
605 | #if 0 | ||
606 | if (se_cmd->se_cmd_flags & SCF_BIDI) { | ||
607 | sg_bidi_ptr = NULL; | ||
608 | sg_no_bidi = 0; | ||
609 | } | ||
610 | #endif | ||
611 | } else { | ||
612 | sg_ptr = NULL; | ||
613 | } | ||
614 | |||
615 | rc = transport_generic_map_mem_to_cmd(se_cmd, sg_ptr, | ||
616 | tv_cmd->tvc_sgl_count, sg_bidi_ptr, | ||
617 | sg_no_bidi); | ||
618 | if (rc < 0) { | ||
619 | transport_send_check_condition_and_sense(se_cmd, | ||
620 | se_cmd->scsi_sense_reason, 0); | ||
621 | transport_generic_free_cmd(se_cmd, 0); | ||
622 | return; | ||
623 | } | ||
624 | transport_handle_cdb_direct(se_cmd); | ||
625 | } | ||
626 | |||
627 | static void vhost_scsi_handle_vq(struct vhost_scsi *vs) | ||
628 | { | ||
629 | struct vhost_virtqueue *vq = &vs->vqs[2]; | ||
630 | struct virtio_scsi_cmd_req v_req; | ||
631 | struct tcm_vhost_tpg *tv_tpg; | ||
632 | struct tcm_vhost_cmd *tv_cmd; | ||
633 | u32 exp_data_len, data_first, data_num, data_direction; | ||
634 | unsigned out, in, i; | ||
635 | int head, ret; | ||
636 | |||
637 | /* Must use ioctl VHOST_SCSI_SET_ENDPOINT */ | ||
638 | tv_tpg = vs->vs_tpg; | ||
639 | if (unlikely(!tv_tpg)) { | ||
640 | pr_err("%s endpoint not set\n", __func__); | ||
641 | return; | ||
642 | } | ||
643 | |||
644 | mutex_lock(&vq->mutex); | ||
645 | vhost_disable_notify(&vs->dev, vq); | ||
646 | |||
647 | for (;;) { | ||
648 | head = vhost_get_vq_desc(&vs->dev, vq, vq->iov, | ||
649 | ARRAY_SIZE(vq->iov), &out, &in, | ||
650 | NULL, NULL); | ||
651 | pr_debug("vhost_get_vq_desc: head: %d, out: %u in: %u\n", | ||
652 | head, out, in); | ||
653 | /* On error, stop handling until the next kick. */ | ||
654 | if (unlikely(head < 0)) | ||
655 | break; | ||
656 | /* Nothing new? Wait for eventfd to tell us they refilled. */ | ||
657 | if (head == vq->num) { | ||
658 | if (unlikely(vhost_enable_notify(&vs->dev, vq))) { | ||
659 | vhost_disable_notify(&vs->dev, vq); | ||
660 | continue; | ||
661 | } | ||
662 | break; | ||
663 | } | ||
664 | |||
665 | /* FIXME: BIDI operation */ | ||
666 | if (out == 1 && in == 1) { | ||
667 | data_direction = DMA_NONE; | ||
668 | data_first = 0; | ||
669 | data_num = 0; | ||
670 | } else if (out == 1 && in > 1) { | ||
671 | data_direction = DMA_FROM_DEVICE; | ||
672 | data_first = out + 1; | ||
673 | data_num = in - 1; | ||
674 | } else if (out > 1 && in == 1) { | ||
675 | data_direction = DMA_TO_DEVICE; | ||
676 | data_first = 1; | ||
677 | data_num = out - 1; | ||
678 | } else { | ||
679 | vq_err(vq, "Invalid buffer layout out: %u in: %u\n", | ||
680 | out, in); | ||
681 | break; | ||
682 | } | ||
683 | |||
684 | /* | ||
685 | * Check for a sane resp buffer so we can report errors to | ||
686 | * the guest. | ||
687 | */ | ||
688 | if (unlikely(vq->iov[out].iov_len != | ||
689 | sizeof(struct virtio_scsi_cmd_resp))) { | ||
690 | vq_err(vq, "Expecting virtio_scsi_cmd_resp, got %zu" | ||
691 | " bytes\n", vq->iov[out].iov_len); | ||
692 | break; | ||
693 | } | ||
694 | |||
695 | if (unlikely(vq->iov[0].iov_len != sizeof(v_req))) { | ||
696 | vq_err(vq, "Expecting virtio_scsi_cmd_req, got %zu" | ||
697 | " bytes\n", vq->iov[0].iov_len); | ||
698 | break; | ||
699 | } | ||
700 | pr_debug("Calling __copy_from_user: vq->iov[0].iov_base: %p," | ||
701 | " len: %zu\n", vq->iov[0].iov_base, sizeof(v_req)); | ||
702 | ret = __copy_from_user(&v_req, vq->iov[0].iov_base, | ||
703 | sizeof(v_req)); | ||
704 | if (unlikely(ret)) { | ||
705 | vq_err(vq, "Faulted on virtio_scsi_cmd_req\n"); | ||
706 | break; | ||
707 | } | ||
708 | |||
709 | exp_data_len = 0; | ||
710 | for (i = 0; i < data_num; i++) | ||
711 | exp_data_len += vq->iov[data_first + i].iov_len; | ||
712 | |||
713 | tv_cmd = vhost_scsi_allocate_cmd(tv_tpg, &v_req, | ||
714 | exp_data_len, data_direction); | ||
715 | if (IS_ERR(tv_cmd)) { | ||
716 | vq_err(vq, "vhost_scsi_allocate_cmd failed %ld\n", | ||
717 | PTR_ERR(tv_cmd)); | ||
718 | break; | ||
719 | } | ||
720 | pr_debug("Allocated tv_cmd: %p exp_data_len: %d, data_direction" | ||
721 | ": %d\n", tv_cmd, exp_data_len, data_direction); | ||
722 | |||
723 | tv_cmd->tvc_vhost = vs; | ||
724 | |||
725 | if (unlikely(vq->iov[out].iov_len != | ||
726 | sizeof(struct virtio_scsi_cmd_resp))) { | ||
727 | vq_err(vq, "Expecting virtio_scsi_cmd_resp, got %zu" | ||
728 | " bytes, out: %d, in: %d\n", | ||
729 | vq->iov[out].iov_len, out, in); | ||
730 | break; | ||
731 | } | ||
732 | |||
733 | tv_cmd->tvc_resp = vq->iov[out].iov_base; | ||
734 | |||
735 | /* | ||
736 | * Copy in the recieved CDB descriptor into tv_cmd->tvc_cdb | ||
737 | * that will be used by tcm_vhost_new_cmd_map() and down into | ||
738 | * target_setup_cmd_from_cdb() | ||
739 | */ | ||
740 | memcpy(tv_cmd->tvc_cdb, v_req.cdb, TCM_VHOST_MAX_CDB_SIZE); | ||
741 | /* | ||
742 | * Check that the recieved CDB size does not exceeded our | ||
743 | * hardcoded max for tcm_vhost | ||
744 | */ | ||
745 | /* TODO what if cdb was too small for varlen cdb header? */ | ||
746 | if (unlikely(scsi_command_size(tv_cmd->tvc_cdb) > | ||
747 | TCM_VHOST_MAX_CDB_SIZE)) { | ||
748 | vq_err(vq, "Received SCSI CDB with command_size: %d that" | ||
749 | " exceeds SCSI_MAX_VARLEN_CDB_SIZE: %d\n", | ||
750 | scsi_command_size(tv_cmd->tvc_cdb), | ||
751 | TCM_VHOST_MAX_CDB_SIZE); | ||
752 | break; /* TODO */ | ||
753 | } | ||
754 | tv_cmd->tvc_lun = ((v_req.lun[2] << 8) | v_req.lun[3]) & 0x3FFF; | ||
755 | |||
756 | pr_debug("vhost_scsi got command opcode: %#02x, lun: %d\n", | ||
757 | tv_cmd->tvc_cdb[0], tv_cmd->tvc_lun); | ||
758 | |||
759 | if (data_direction != DMA_NONE) { | ||
760 | ret = vhost_scsi_map_iov_to_sgl(tv_cmd, | ||
761 | &vq->iov[data_first], data_num, | ||
762 | data_direction == DMA_TO_DEVICE); | ||
763 | if (unlikely(ret)) { | ||
764 | vq_err(vq, "Failed to map iov to sgl\n"); | ||
765 | break; /* TODO */ | ||
766 | } | ||
767 | } | ||
768 | |||
769 | /* | ||
770 | * Save the descriptor from vhost_get_vq_desc() to be used to | ||
771 | * complete the virtio-scsi request in TCM callback context via | ||
772 | * tcm_vhost_queue_data_in() and tcm_vhost_queue_status() | ||
773 | */ | ||
774 | tv_cmd->tvc_vq_desc = head; | ||
775 | /* | ||
776 | * Dispatch tv_cmd descriptor for cmwq execution in process | ||
777 | * context provided by tcm_vhost_workqueue. This also ensures | ||
778 | * tv_cmd is executed on the same kworker CPU as this vhost | ||
779 | * thread to gain positive L2 cache locality effects.. | ||
780 | */ | ||
781 | INIT_WORK(&tv_cmd->work, tcm_vhost_submission_work); | ||
782 | queue_work(tcm_vhost_workqueue, &tv_cmd->work); | ||
783 | } | ||
784 | |||
785 | mutex_unlock(&vq->mutex); | ||
786 | } | ||
787 | |||
788 | static void vhost_scsi_ctl_handle_kick(struct vhost_work *work) | ||
789 | { | ||
790 | pr_err("%s: The handling func for control queue.\n", __func__); | ||
791 | } | ||
792 | |||
793 | static void vhost_scsi_evt_handle_kick(struct vhost_work *work) | ||
794 | { | ||
795 | pr_err("%s: The handling func for event queue.\n", __func__); | ||
796 | } | ||
797 | |||
798 | static void vhost_scsi_handle_kick(struct vhost_work *work) | ||
799 | { | ||
800 | struct vhost_virtqueue *vq = container_of(work, struct vhost_virtqueue, | ||
801 | poll.work); | ||
802 | struct vhost_scsi *vs = container_of(vq->dev, struct vhost_scsi, dev); | ||
803 | |||
804 | vhost_scsi_handle_vq(vs); | ||
805 | } | ||
806 | |||
807 | /* | ||
808 | * Called from vhost_scsi_ioctl() context to walk the list of available | ||
809 | * tcm_vhost_tpg with an active struct tcm_vhost_nexus | ||
810 | */ | ||
811 | static int vhost_scsi_set_endpoint( | ||
812 | struct vhost_scsi *vs, | ||
813 | struct vhost_scsi_target *t) | ||
814 | { | ||
815 | struct tcm_vhost_tport *tv_tport; | ||
816 | struct tcm_vhost_tpg *tv_tpg; | ||
817 | int index; | ||
818 | |||
819 | mutex_lock(&vs->dev.mutex); | ||
820 | /* Verify that ring has been setup correctly. */ | ||
821 | for (index = 0; index < vs->dev.nvqs; ++index) { | ||
822 | /* Verify that ring has been setup correctly. */ | ||
823 | if (!vhost_vq_access_ok(&vs->vqs[index])) { | ||
824 | mutex_unlock(&vs->dev.mutex); | ||
825 | return -EFAULT; | ||
826 | } | ||
827 | } | ||
828 | |||
829 | if (vs->vs_tpg) { | ||
830 | mutex_unlock(&vs->dev.mutex); | ||
831 | return -EEXIST; | ||
832 | } | ||
833 | mutex_unlock(&vs->dev.mutex); | ||
834 | |||
835 | mutex_lock(&tcm_vhost_mutex); | ||
836 | list_for_each_entry(tv_tpg, &tcm_vhost_list, tv_tpg_list) { | ||
837 | mutex_lock(&tv_tpg->tv_tpg_mutex); | ||
838 | if (!tv_tpg->tpg_nexus) { | ||
839 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
840 | continue; | ||
841 | } | ||
842 | if (atomic_read(&tv_tpg->tv_tpg_vhost_count)) { | ||
843 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
844 | continue; | ||
845 | } | ||
846 | tv_tport = tv_tpg->tport; | ||
847 | |||
848 | if (!strcmp(tv_tport->tport_name, t->vhost_wwpn) && | ||
849 | (tv_tpg->tport_tpgt == t->vhost_tpgt)) { | ||
850 | atomic_inc(&tv_tpg->tv_tpg_vhost_count); | ||
851 | smp_mb__after_atomic_inc(); | ||
852 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
853 | mutex_unlock(&tcm_vhost_mutex); | ||
854 | |||
855 | mutex_lock(&vs->dev.mutex); | ||
856 | vs->vs_tpg = tv_tpg; | ||
857 | atomic_inc(&vs->vhost_ref_cnt); | ||
858 | smp_mb__after_atomic_inc(); | ||
859 | mutex_unlock(&vs->dev.mutex); | ||
860 | return 0; | ||
861 | } | ||
862 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
863 | } | ||
864 | mutex_unlock(&tcm_vhost_mutex); | ||
865 | return -EINVAL; | ||
866 | } | ||
867 | |||
868 | static int vhost_scsi_clear_endpoint( | ||
869 | struct vhost_scsi *vs, | ||
870 | struct vhost_scsi_target *t) | ||
871 | { | ||
872 | struct tcm_vhost_tport *tv_tport; | ||
873 | struct tcm_vhost_tpg *tv_tpg; | ||
874 | int index; | ||
875 | |||
876 | mutex_lock(&vs->dev.mutex); | ||
877 | /* Verify that ring has been setup correctly. */ | ||
878 | for (index = 0; index < vs->dev.nvqs; ++index) { | ||
879 | if (!vhost_vq_access_ok(&vs->vqs[index])) { | ||
880 | mutex_unlock(&vs->dev.mutex); | ||
881 | return -EFAULT; | ||
882 | } | ||
883 | } | ||
884 | |||
885 | if (!vs->vs_tpg) { | ||
886 | mutex_unlock(&vs->dev.mutex); | ||
887 | return -ENODEV; | ||
888 | } | ||
889 | tv_tpg = vs->vs_tpg; | ||
890 | tv_tport = tv_tpg->tport; | ||
891 | |||
892 | if (strcmp(tv_tport->tport_name, t->vhost_wwpn) || | ||
893 | (tv_tpg->tport_tpgt != t->vhost_tpgt)) { | ||
894 | mutex_unlock(&vs->dev.mutex); | ||
895 | pr_warn("tv_tport->tport_name: %s, tv_tpg->tport_tpgt: %hu" | ||
896 | " does not match t->vhost_wwpn: %s, t->vhost_tpgt: %hu\n", | ||
897 | tv_tport->tport_name, tv_tpg->tport_tpgt, | ||
898 | t->vhost_wwpn, t->vhost_tpgt); | ||
899 | return -EINVAL; | ||
900 | } | ||
901 | atomic_dec(&tv_tpg->tv_tpg_vhost_count); | ||
902 | vs->vs_tpg = NULL; | ||
903 | mutex_unlock(&vs->dev.mutex); | ||
904 | |||
905 | return 0; | ||
906 | } | ||
907 | |||
908 | static int vhost_scsi_open(struct inode *inode, struct file *f) | ||
909 | { | ||
910 | struct vhost_scsi *s; | ||
911 | int r; | ||
912 | |||
913 | s = kzalloc(sizeof(*s), GFP_KERNEL); | ||
914 | if (!s) | ||
915 | return -ENOMEM; | ||
916 | |||
917 | vhost_work_init(&s->vs_completion_work, vhost_scsi_complete_cmd_work); | ||
918 | INIT_LIST_HEAD(&s->vs_completion_list); | ||
919 | spin_lock_init(&s->vs_completion_lock); | ||
920 | |||
921 | s->vqs[0].handle_kick = vhost_scsi_ctl_handle_kick; | ||
922 | s->vqs[1].handle_kick = vhost_scsi_evt_handle_kick; | ||
923 | s->vqs[2].handle_kick = vhost_scsi_handle_kick; | ||
924 | r = vhost_dev_init(&s->dev, s->vqs, 3); | ||
925 | if (r < 0) { | ||
926 | kfree(s); | ||
927 | return r; | ||
928 | } | ||
929 | |||
930 | f->private_data = s; | ||
931 | return 0; | ||
932 | } | ||
933 | |||
934 | static int vhost_scsi_release(struct inode *inode, struct file *f) | ||
935 | { | ||
936 | struct vhost_scsi *s = f->private_data; | ||
937 | |||
938 | if (s->vs_tpg && s->vs_tpg->tport) { | ||
939 | struct vhost_scsi_target backend; | ||
940 | |||
941 | memcpy(backend.vhost_wwpn, s->vs_tpg->tport->tport_name, | ||
942 | sizeof(backend.vhost_wwpn)); | ||
943 | backend.vhost_tpgt = s->vs_tpg->tport_tpgt; | ||
944 | vhost_scsi_clear_endpoint(s, &backend); | ||
945 | } | ||
946 | |||
947 | vhost_dev_cleanup(&s->dev, false); | ||
948 | kfree(s); | ||
949 | return 0; | ||
950 | } | ||
951 | |||
952 | static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features) | ||
953 | { | ||
954 | if (features & ~VHOST_FEATURES) | ||
955 | return -EOPNOTSUPP; | ||
956 | |||
957 | mutex_lock(&vs->dev.mutex); | ||
958 | if ((features & (1 << VHOST_F_LOG_ALL)) && | ||
959 | !vhost_log_access_ok(&vs->dev)) { | ||
960 | mutex_unlock(&vs->dev.mutex); | ||
961 | return -EFAULT; | ||
962 | } | ||
963 | vs->dev.acked_features = features; | ||
964 | /* TODO possibly smp_wmb() and flush vqs */ | ||
965 | mutex_unlock(&vs->dev.mutex); | ||
966 | return 0; | ||
967 | } | ||
968 | |||
969 | static long vhost_scsi_ioctl(struct file *f, unsigned int ioctl, | ||
970 | unsigned long arg) | ||
971 | { | ||
972 | struct vhost_scsi *vs = f->private_data; | ||
973 | struct vhost_scsi_target backend; | ||
974 | void __user *argp = (void __user *)arg; | ||
975 | u64 __user *featurep = argp; | ||
976 | u64 features; | ||
977 | int r; | ||
978 | |||
979 | switch (ioctl) { | ||
980 | case VHOST_SCSI_SET_ENDPOINT: | ||
981 | if (copy_from_user(&backend, argp, sizeof backend)) | ||
982 | return -EFAULT; | ||
983 | |||
984 | return vhost_scsi_set_endpoint(vs, &backend); | ||
985 | case VHOST_SCSI_CLEAR_ENDPOINT: | ||
986 | if (copy_from_user(&backend, argp, sizeof backend)) | ||
987 | return -EFAULT; | ||
988 | |||
989 | return vhost_scsi_clear_endpoint(vs, &backend); | ||
990 | case VHOST_SCSI_GET_ABI_VERSION: | ||
991 | if (copy_from_user(&backend, argp, sizeof backend)) | ||
992 | return -EFAULT; | ||
993 | |||
994 | backend.abi_version = VHOST_SCSI_ABI_VERSION; | ||
995 | |||
996 | if (copy_to_user(argp, &backend, sizeof backend)) | ||
997 | return -EFAULT; | ||
998 | return 0; | ||
999 | case VHOST_GET_FEATURES: | ||
1000 | features = VHOST_FEATURES; | ||
1001 | if (copy_to_user(featurep, &features, sizeof features)) | ||
1002 | return -EFAULT; | ||
1003 | return 0; | ||
1004 | case VHOST_SET_FEATURES: | ||
1005 | if (copy_from_user(&features, featurep, sizeof features)) | ||
1006 | return -EFAULT; | ||
1007 | return vhost_scsi_set_features(vs, features); | ||
1008 | default: | ||
1009 | mutex_lock(&vs->dev.mutex); | ||
1010 | r = vhost_dev_ioctl(&vs->dev, ioctl, arg); | ||
1011 | mutex_unlock(&vs->dev.mutex); | ||
1012 | return r; | ||
1013 | } | ||
1014 | } | ||
1015 | |||
1016 | static const struct file_operations vhost_scsi_fops = { | ||
1017 | .owner = THIS_MODULE, | ||
1018 | .release = vhost_scsi_release, | ||
1019 | .unlocked_ioctl = vhost_scsi_ioctl, | ||
1020 | /* TODO compat ioctl? */ | ||
1021 | .open = vhost_scsi_open, | ||
1022 | .llseek = noop_llseek, | ||
1023 | }; | ||
1024 | |||
1025 | static struct miscdevice vhost_scsi_misc = { | ||
1026 | MISC_DYNAMIC_MINOR, | ||
1027 | "vhost-scsi", | ||
1028 | &vhost_scsi_fops, | ||
1029 | }; | ||
1030 | |||
1031 | static int __init vhost_scsi_register(void) | ||
1032 | { | ||
1033 | return misc_register(&vhost_scsi_misc); | ||
1034 | } | ||
1035 | |||
1036 | static int vhost_scsi_deregister(void) | ||
1037 | { | ||
1038 | return misc_deregister(&vhost_scsi_misc); | ||
1039 | } | ||
1040 | |||
1041 | static char *tcm_vhost_dump_proto_id(struct tcm_vhost_tport *tport) | ||
1042 | { | ||
1043 | switch (tport->tport_proto_id) { | ||
1044 | case SCSI_PROTOCOL_SAS: | ||
1045 | return "SAS"; | ||
1046 | case SCSI_PROTOCOL_FCP: | ||
1047 | return "FCP"; | ||
1048 | case SCSI_PROTOCOL_ISCSI: | ||
1049 | return "iSCSI"; | ||
1050 | default: | ||
1051 | break; | ||
1052 | } | ||
1053 | |||
1054 | return "Unknown"; | ||
1055 | } | ||
1056 | |||
1057 | static int tcm_vhost_port_link( | ||
1058 | struct se_portal_group *se_tpg, | ||
1059 | struct se_lun *lun) | ||
1060 | { | ||
1061 | struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, | ||
1062 | struct tcm_vhost_tpg, se_tpg); | ||
1063 | |||
1064 | atomic_inc(&tv_tpg->tv_tpg_port_count); | ||
1065 | smp_mb__after_atomic_inc(); | ||
1066 | |||
1067 | return 0; | ||
1068 | } | ||
1069 | |||
1070 | static void tcm_vhost_port_unlink( | ||
1071 | struct se_portal_group *se_tpg, | ||
1072 | struct se_lun *se_lun) | ||
1073 | { | ||
1074 | struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, | ||
1075 | struct tcm_vhost_tpg, se_tpg); | ||
1076 | |||
1077 | atomic_dec(&tv_tpg->tv_tpg_port_count); | ||
1078 | smp_mb__after_atomic_dec(); | ||
1079 | } | ||
1080 | |||
1081 | static struct se_node_acl *tcm_vhost_make_nodeacl( | ||
1082 | struct se_portal_group *se_tpg, | ||
1083 | struct config_group *group, | ||
1084 | const char *name) | ||
1085 | { | ||
1086 | struct se_node_acl *se_nacl, *se_nacl_new; | ||
1087 | struct tcm_vhost_nacl *nacl; | ||
1088 | u64 wwpn = 0; | ||
1089 | u32 nexus_depth; | ||
1090 | |||
1091 | /* tcm_vhost_parse_wwn(name, &wwpn, 1) < 0) | ||
1092 | return ERR_PTR(-EINVAL); */ | ||
1093 | se_nacl_new = tcm_vhost_alloc_fabric_acl(se_tpg); | ||
1094 | if (!se_nacl_new) | ||
1095 | return ERR_PTR(-ENOMEM); | ||
1096 | |||
1097 | nexus_depth = 1; | ||
1098 | /* | ||
1099 | * se_nacl_new may be released by core_tpg_add_initiator_node_acl() | ||
1100 | * when converting a NodeACL from demo mode -> explict | ||
1101 | */ | ||
1102 | se_nacl = core_tpg_add_initiator_node_acl(se_tpg, se_nacl_new, | ||
1103 | name, nexus_depth); | ||
1104 | if (IS_ERR(se_nacl)) { | ||
1105 | tcm_vhost_release_fabric_acl(se_tpg, se_nacl_new); | ||
1106 | return se_nacl; | ||
1107 | } | ||
1108 | /* | ||
1109 | * Locate our struct tcm_vhost_nacl and set the FC Nport WWPN | ||
1110 | */ | ||
1111 | nacl = container_of(se_nacl, struct tcm_vhost_nacl, se_node_acl); | ||
1112 | nacl->iport_wwpn = wwpn; | ||
1113 | |||
1114 | return se_nacl; | ||
1115 | } | ||
1116 | |||
1117 | static void tcm_vhost_drop_nodeacl(struct se_node_acl *se_acl) | ||
1118 | { | ||
1119 | struct tcm_vhost_nacl *nacl = container_of(se_acl, | ||
1120 | struct tcm_vhost_nacl, se_node_acl); | ||
1121 | core_tpg_del_initiator_node_acl(se_acl->se_tpg, se_acl, 1); | ||
1122 | kfree(nacl); | ||
1123 | } | ||
1124 | |||
1125 | static int tcm_vhost_make_nexus( | ||
1126 | struct tcm_vhost_tpg *tv_tpg, | ||
1127 | const char *name) | ||
1128 | { | ||
1129 | struct se_portal_group *se_tpg; | ||
1130 | struct tcm_vhost_nexus *tv_nexus; | ||
1131 | |||
1132 | mutex_lock(&tv_tpg->tv_tpg_mutex); | ||
1133 | if (tv_tpg->tpg_nexus) { | ||
1134 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1135 | pr_debug("tv_tpg->tpg_nexus already exists\n"); | ||
1136 | return -EEXIST; | ||
1137 | } | ||
1138 | se_tpg = &tv_tpg->se_tpg; | ||
1139 | |||
1140 | tv_nexus = kzalloc(sizeof(struct tcm_vhost_nexus), GFP_KERNEL); | ||
1141 | if (!tv_nexus) { | ||
1142 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1143 | pr_err("Unable to allocate struct tcm_vhost_nexus\n"); | ||
1144 | return -ENOMEM; | ||
1145 | } | ||
1146 | /* | ||
1147 | * Initialize the struct se_session pointer | ||
1148 | */ | ||
1149 | tv_nexus->tvn_se_sess = transport_init_session(); | ||
1150 | if (IS_ERR(tv_nexus->tvn_se_sess)) { | ||
1151 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1152 | kfree(tv_nexus); | ||
1153 | return -ENOMEM; | ||
1154 | } | ||
1155 | /* | ||
1156 | * Since we are running in 'demo mode' this call with generate a | ||
1157 | * struct se_node_acl for the tcm_vhost struct se_portal_group with | ||
1158 | * the SCSI Initiator port name of the passed configfs group 'name'. | ||
1159 | */ | ||
1160 | tv_nexus->tvn_se_sess->se_node_acl = core_tpg_check_initiator_node_acl( | ||
1161 | se_tpg, (unsigned char *)name); | ||
1162 | if (!tv_nexus->tvn_se_sess->se_node_acl) { | ||
1163 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1164 | pr_debug("core_tpg_check_initiator_node_acl() failed" | ||
1165 | " for %s\n", name); | ||
1166 | transport_free_session(tv_nexus->tvn_se_sess); | ||
1167 | kfree(tv_nexus); | ||
1168 | return -ENOMEM; | ||
1169 | } | ||
1170 | /* | ||
1171 | * Now register the TCM vHost virtual I_T Nexus as active with the | ||
1172 | * call to __transport_register_session() | ||
1173 | */ | ||
1174 | __transport_register_session(se_tpg, tv_nexus->tvn_se_sess->se_node_acl, | ||
1175 | tv_nexus->tvn_se_sess, tv_nexus); | ||
1176 | tv_tpg->tpg_nexus = tv_nexus; | ||
1177 | |||
1178 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1179 | return 0; | ||
1180 | } | ||
1181 | |||
1182 | static int tcm_vhost_drop_nexus( | ||
1183 | struct tcm_vhost_tpg *tpg) | ||
1184 | { | ||
1185 | struct se_session *se_sess; | ||
1186 | struct tcm_vhost_nexus *tv_nexus; | ||
1187 | |||
1188 | mutex_lock(&tpg->tv_tpg_mutex); | ||
1189 | tv_nexus = tpg->tpg_nexus; | ||
1190 | if (!tv_nexus) { | ||
1191 | mutex_unlock(&tpg->tv_tpg_mutex); | ||
1192 | return -ENODEV; | ||
1193 | } | ||
1194 | |||
1195 | se_sess = tv_nexus->tvn_se_sess; | ||
1196 | if (!se_sess) { | ||
1197 | mutex_unlock(&tpg->tv_tpg_mutex); | ||
1198 | return -ENODEV; | ||
1199 | } | ||
1200 | |||
1201 | if (atomic_read(&tpg->tv_tpg_port_count)) { | ||
1202 | mutex_unlock(&tpg->tv_tpg_mutex); | ||
1203 | pr_err("Unable to remove TCM_vHost I_T Nexus with" | ||
1204 | " active TPG port count: %d\n", | ||
1205 | atomic_read(&tpg->tv_tpg_port_count)); | ||
1206 | return -EPERM; | ||
1207 | } | ||
1208 | |||
1209 | if (atomic_read(&tpg->tv_tpg_vhost_count)) { | ||
1210 | mutex_unlock(&tpg->tv_tpg_mutex); | ||
1211 | pr_err("Unable to remove TCM_vHost I_T Nexus with" | ||
1212 | " active TPG vhost count: %d\n", | ||
1213 | atomic_read(&tpg->tv_tpg_vhost_count)); | ||
1214 | return -EPERM; | ||
1215 | } | ||
1216 | |||
1217 | pr_debug("TCM_vHost_ConfigFS: Removing I_T Nexus to emulated" | ||
1218 | " %s Initiator Port: %s\n", tcm_vhost_dump_proto_id(tpg->tport), | ||
1219 | tv_nexus->tvn_se_sess->se_node_acl->initiatorname); | ||
1220 | /* | ||
1221 | * Release the SCSI I_T Nexus to the emulated vHost Target Port | ||
1222 | */ | ||
1223 | transport_deregister_session(tv_nexus->tvn_se_sess); | ||
1224 | tpg->tpg_nexus = NULL; | ||
1225 | mutex_unlock(&tpg->tv_tpg_mutex); | ||
1226 | |||
1227 | kfree(tv_nexus); | ||
1228 | return 0; | ||
1229 | } | ||
1230 | |||
1231 | static ssize_t tcm_vhost_tpg_show_nexus( | ||
1232 | struct se_portal_group *se_tpg, | ||
1233 | char *page) | ||
1234 | { | ||
1235 | struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, | ||
1236 | struct tcm_vhost_tpg, se_tpg); | ||
1237 | struct tcm_vhost_nexus *tv_nexus; | ||
1238 | ssize_t ret; | ||
1239 | |||
1240 | mutex_lock(&tv_tpg->tv_tpg_mutex); | ||
1241 | tv_nexus = tv_tpg->tpg_nexus; | ||
1242 | if (!tv_nexus) { | ||
1243 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1244 | return -ENODEV; | ||
1245 | } | ||
1246 | ret = snprintf(page, PAGE_SIZE, "%s\n", | ||
1247 | tv_nexus->tvn_se_sess->se_node_acl->initiatorname); | ||
1248 | mutex_unlock(&tv_tpg->tv_tpg_mutex); | ||
1249 | |||
1250 | return ret; | ||
1251 | } | ||
1252 | |||
1253 | static ssize_t tcm_vhost_tpg_store_nexus( | ||
1254 | struct se_portal_group *se_tpg, | ||
1255 | const char *page, | ||
1256 | size_t count) | ||
1257 | { | ||
1258 | struct tcm_vhost_tpg *tv_tpg = container_of(se_tpg, | ||
1259 | struct tcm_vhost_tpg, se_tpg); | ||
1260 | struct tcm_vhost_tport *tport_wwn = tv_tpg->tport; | ||
1261 | unsigned char i_port[TCM_VHOST_NAMELEN], *ptr, *port_ptr; | ||
1262 | int ret; | ||
1263 | /* | ||
1264 | * Shutdown the active I_T nexus if 'NULL' is passed.. | ||
1265 | */ | ||
1266 | if (!strncmp(page, "NULL", 4)) { | ||
1267 | ret = tcm_vhost_drop_nexus(tv_tpg); | ||
1268 | return (!ret) ? count : ret; | ||
1269 | } | ||
1270 | /* | ||
1271 | * Otherwise make sure the passed virtual Initiator port WWN matches | ||
1272 | * the fabric protocol_id set in tcm_vhost_make_tport(), and call | ||
1273 | * tcm_vhost_make_nexus(). | ||
1274 | */ | ||
1275 | if (strlen(page) >= TCM_VHOST_NAMELEN) { | ||
1276 | pr_err("Emulated NAA Sas Address: %s, exceeds" | ||
1277 | " max: %d\n", page, TCM_VHOST_NAMELEN); | ||
1278 | return -EINVAL; | ||
1279 | } | ||
1280 | snprintf(&i_port[0], TCM_VHOST_NAMELEN, "%s", page); | ||
1281 | |||
1282 | ptr = strstr(i_port, "naa."); | ||
1283 | if (ptr) { | ||
1284 | if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_SAS) { | ||
1285 | pr_err("Passed SAS Initiator Port %s does not" | ||
1286 | " match target port protoid: %s\n", i_port, | ||
1287 | tcm_vhost_dump_proto_id(tport_wwn)); | ||
1288 | return -EINVAL; | ||
1289 | } | ||
1290 | port_ptr = &i_port[0]; | ||
1291 | goto check_newline; | ||
1292 | } | ||
1293 | ptr = strstr(i_port, "fc."); | ||
1294 | if (ptr) { | ||
1295 | if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_FCP) { | ||
1296 | pr_err("Passed FCP Initiator Port %s does not" | ||
1297 | " match target port protoid: %s\n", i_port, | ||
1298 | tcm_vhost_dump_proto_id(tport_wwn)); | ||
1299 | return -EINVAL; | ||
1300 | } | ||
1301 | port_ptr = &i_port[3]; /* Skip over "fc." */ | ||
1302 | goto check_newline; | ||
1303 | } | ||
1304 | ptr = strstr(i_port, "iqn."); | ||
1305 | if (ptr) { | ||
1306 | if (tport_wwn->tport_proto_id != SCSI_PROTOCOL_ISCSI) { | ||
1307 | pr_err("Passed iSCSI Initiator Port %s does not" | ||
1308 | " match target port protoid: %s\n", i_port, | ||
1309 | tcm_vhost_dump_proto_id(tport_wwn)); | ||
1310 | return -EINVAL; | ||
1311 | } | ||
1312 | port_ptr = &i_port[0]; | ||
1313 | goto check_newline; | ||
1314 | } | ||
1315 | pr_err("Unable to locate prefix for emulated Initiator Port:" | ||
1316 | " %s\n", i_port); | ||
1317 | return -EINVAL; | ||
1318 | /* | ||
1319 | * Clear any trailing newline for the NAA WWN | ||
1320 | */ | ||
1321 | check_newline: | ||
1322 | if (i_port[strlen(i_port)-1] == '\n') | ||
1323 | i_port[strlen(i_port)-1] = '\0'; | ||
1324 | |||
1325 | ret = tcm_vhost_make_nexus(tv_tpg, port_ptr); | ||
1326 | if (ret < 0) | ||
1327 | return ret; | ||
1328 | |||
1329 | return count; | ||
1330 | } | ||
1331 | |||
1332 | TF_TPG_BASE_ATTR(tcm_vhost, nexus, S_IRUGO | S_IWUSR); | ||
1333 | |||
1334 | static struct configfs_attribute *tcm_vhost_tpg_attrs[] = { | ||
1335 | &tcm_vhost_tpg_nexus.attr, | ||
1336 | NULL, | ||
1337 | }; | ||
1338 | |||
1339 | static struct se_portal_group *tcm_vhost_make_tpg( | ||
1340 | struct se_wwn *wwn, | ||
1341 | struct config_group *group, | ||
1342 | const char *name) | ||
1343 | { | ||
1344 | struct tcm_vhost_tport *tport = container_of(wwn, | ||
1345 | struct tcm_vhost_tport, tport_wwn); | ||
1346 | |||
1347 | struct tcm_vhost_tpg *tpg; | ||
1348 | unsigned long tpgt; | ||
1349 | int ret; | ||
1350 | |||
1351 | if (strstr(name, "tpgt_") != name) | ||
1352 | return ERR_PTR(-EINVAL); | ||
1353 | if (kstrtoul(name + 5, 10, &tpgt) || tpgt > UINT_MAX) | ||
1354 | return ERR_PTR(-EINVAL); | ||
1355 | |||
1356 | tpg = kzalloc(sizeof(struct tcm_vhost_tpg), GFP_KERNEL); | ||
1357 | if (!tpg) { | ||
1358 | pr_err("Unable to allocate struct tcm_vhost_tpg"); | ||
1359 | return ERR_PTR(-ENOMEM); | ||
1360 | } | ||
1361 | mutex_init(&tpg->tv_tpg_mutex); | ||
1362 | INIT_LIST_HEAD(&tpg->tv_tpg_list); | ||
1363 | tpg->tport = tport; | ||
1364 | tpg->tport_tpgt = tpgt; | ||
1365 | |||
1366 | ret = core_tpg_register(&tcm_vhost_fabric_configfs->tf_ops, wwn, | ||
1367 | &tpg->se_tpg, tpg, TRANSPORT_TPG_TYPE_NORMAL); | ||
1368 | if (ret < 0) { | ||
1369 | kfree(tpg); | ||
1370 | return NULL; | ||
1371 | } | ||
1372 | mutex_lock(&tcm_vhost_mutex); | ||
1373 | list_add_tail(&tpg->tv_tpg_list, &tcm_vhost_list); | ||
1374 | mutex_unlock(&tcm_vhost_mutex); | ||
1375 | |||
1376 | return &tpg->se_tpg; | ||
1377 | } | ||
1378 | |||
1379 | static void tcm_vhost_drop_tpg(struct se_portal_group *se_tpg) | ||
1380 | { | ||
1381 | struct tcm_vhost_tpg *tpg = container_of(se_tpg, | ||
1382 | struct tcm_vhost_tpg, se_tpg); | ||
1383 | |||
1384 | mutex_lock(&tcm_vhost_mutex); | ||
1385 | list_del(&tpg->tv_tpg_list); | ||
1386 | mutex_unlock(&tcm_vhost_mutex); | ||
1387 | /* | ||
1388 | * Release the virtual I_T Nexus for this vHost TPG | ||
1389 | */ | ||
1390 | tcm_vhost_drop_nexus(tpg); | ||
1391 | /* | ||
1392 | * Deregister the se_tpg from TCM.. | ||
1393 | */ | ||
1394 | core_tpg_deregister(se_tpg); | ||
1395 | kfree(tpg); | ||
1396 | } | ||
1397 | |||
1398 | static struct se_wwn *tcm_vhost_make_tport( | ||
1399 | struct target_fabric_configfs *tf, | ||
1400 | struct config_group *group, | ||
1401 | const char *name) | ||
1402 | { | ||
1403 | struct tcm_vhost_tport *tport; | ||
1404 | char *ptr; | ||
1405 | u64 wwpn = 0; | ||
1406 | int off = 0; | ||
1407 | |||
1408 | /* if (tcm_vhost_parse_wwn(name, &wwpn, 1) < 0) | ||
1409 | return ERR_PTR(-EINVAL); */ | ||
1410 | |||
1411 | tport = kzalloc(sizeof(struct tcm_vhost_tport), GFP_KERNEL); | ||
1412 | if (!tport) { | ||
1413 | pr_err("Unable to allocate struct tcm_vhost_tport"); | ||
1414 | return ERR_PTR(-ENOMEM); | ||
1415 | } | ||
1416 | tport->tport_wwpn = wwpn; | ||
1417 | /* | ||
1418 | * Determine the emulated Protocol Identifier and Target Port Name | ||
1419 | * based on the incoming configfs directory name. | ||
1420 | */ | ||
1421 | ptr = strstr(name, "naa."); | ||
1422 | if (ptr) { | ||
1423 | tport->tport_proto_id = SCSI_PROTOCOL_SAS; | ||
1424 | goto check_len; | ||
1425 | } | ||
1426 | ptr = strstr(name, "fc."); | ||
1427 | if (ptr) { | ||
1428 | tport->tport_proto_id = SCSI_PROTOCOL_FCP; | ||
1429 | off = 3; /* Skip over "fc." */ | ||
1430 | goto check_len; | ||
1431 | } | ||
1432 | ptr = strstr(name, "iqn."); | ||
1433 | if (ptr) { | ||
1434 | tport->tport_proto_id = SCSI_PROTOCOL_ISCSI; | ||
1435 | goto check_len; | ||
1436 | } | ||
1437 | |||
1438 | pr_err("Unable to locate prefix for emulated Target Port:" | ||
1439 | " %s\n", name); | ||
1440 | kfree(tport); | ||
1441 | return ERR_PTR(-EINVAL); | ||
1442 | |||
1443 | check_len: | ||
1444 | if (strlen(name) >= TCM_VHOST_NAMELEN) { | ||
1445 | pr_err("Emulated %s Address: %s, exceeds" | ||
1446 | " max: %d\n", name, tcm_vhost_dump_proto_id(tport), | ||
1447 | TCM_VHOST_NAMELEN); | ||
1448 | kfree(tport); | ||
1449 | return ERR_PTR(-EINVAL); | ||
1450 | } | ||
1451 | snprintf(&tport->tport_name[0], TCM_VHOST_NAMELEN, "%s", &name[off]); | ||
1452 | |||
1453 | pr_debug("TCM_VHost_ConfigFS: Allocated emulated Target" | ||
1454 | " %s Address: %s\n", tcm_vhost_dump_proto_id(tport), name); | ||
1455 | |||
1456 | return &tport->tport_wwn; | ||
1457 | } | ||
1458 | |||
1459 | static void tcm_vhost_drop_tport(struct se_wwn *wwn) | ||
1460 | { | ||
1461 | struct tcm_vhost_tport *tport = container_of(wwn, | ||
1462 | struct tcm_vhost_tport, tport_wwn); | ||
1463 | |||
1464 | pr_debug("TCM_VHost_ConfigFS: Deallocating emulated Target" | ||
1465 | " %s Address: %s\n", tcm_vhost_dump_proto_id(tport), | ||
1466 | tport->tport_name); | ||
1467 | |||
1468 | kfree(tport); | ||
1469 | } | ||
1470 | |||
1471 | static ssize_t tcm_vhost_wwn_show_attr_version( | ||
1472 | struct target_fabric_configfs *tf, | ||
1473 | char *page) | ||
1474 | { | ||
1475 | return sprintf(page, "TCM_VHOST fabric module %s on %s/%s" | ||
1476 | "on "UTS_RELEASE"\n", TCM_VHOST_VERSION, utsname()->sysname, | ||
1477 | utsname()->machine); | ||
1478 | } | ||
1479 | |||
1480 | TF_WWN_ATTR_RO(tcm_vhost, version); | ||
1481 | |||
1482 | static struct configfs_attribute *tcm_vhost_wwn_attrs[] = { | ||
1483 | &tcm_vhost_wwn_version.attr, | ||
1484 | NULL, | ||
1485 | }; | ||
1486 | |||
1487 | static struct target_core_fabric_ops tcm_vhost_ops = { | ||
1488 | .get_fabric_name = tcm_vhost_get_fabric_name, | ||
1489 | .get_fabric_proto_ident = tcm_vhost_get_fabric_proto_ident, | ||
1490 | .tpg_get_wwn = tcm_vhost_get_fabric_wwn, | ||
1491 | .tpg_get_tag = tcm_vhost_get_tag, | ||
1492 | .tpg_get_default_depth = tcm_vhost_get_default_depth, | ||
1493 | .tpg_get_pr_transport_id = tcm_vhost_get_pr_transport_id, | ||
1494 | .tpg_get_pr_transport_id_len = tcm_vhost_get_pr_transport_id_len, | ||
1495 | .tpg_parse_pr_out_transport_id = tcm_vhost_parse_pr_out_transport_id, | ||
1496 | .tpg_check_demo_mode = tcm_vhost_check_true, | ||
1497 | .tpg_check_demo_mode_cache = tcm_vhost_check_true, | ||
1498 | .tpg_check_demo_mode_write_protect = tcm_vhost_check_false, | ||
1499 | .tpg_check_prod_mode_write_protect = tcm_vhost_check_false, | ||
1500 | .tpg_alloc_fabric_acl = tcm_vhost_alloc_fabric_acl, | ||
1501 | .tpg_release_fabric_acl = tcm_vhost_release_fabric_acl, | ||
1502 | .tpg_get_inst_index = tcm_vhost_tpg_get_inst_index, | ||
1503 | .release_cmd = tcm_vhost_release_cmd, | ||
1504 | .shutdown_session = tcm_vhost_shutdown_session, | ||
1505 | .close_session = tcm_vhost_close_session, | ||
1506 | .sess_get_index = tcm_vhost_sess_get_index, | ||
1507 | .sess_get_initiator_sid = NULL, | ||
1508 | .write_pending = tcm_vhost_write_pending, | ||
1509 | .write_pending_status = tcm_vhost_write_pending_status, | ||
1510 | .set_default_node_attributes = tcm_vhost_set_default_node_attrs, | ||
1511 | .get_task_tag = tcm_vhost_get_task_tag, | ||
1512 | .get_cmd_state = tcm_vhost_get_cmd_state, | ||
1513 | .queue_data_in = tcm_vhost_queue_data_in, | ||
1514 | .queue_status = tcm_vhost_queue_status, | ||
1515 | .queue_tm_rsp = tcm_vhost_queue_tm_rsp, | ||
1516 | .get_fabric_sense_len = tcm_vhost_get_fabric_sense_len, | ||
1517 | .set_fabric_sense_len = tcm_vhost_set_fabric_sense_len, | ||
1518 | /* | ||
1519 | * Setup callers for generic logic in target_core_fabric_configfs.c | ||
1520 | */ | ||
1521 | .fabric_make_wwn = tcm_vhost_make_tport, | ||
1522 | .fabric_drop_wwn = tcm_vhost_drop_tport, | ||
1523 | .fabric_make_tpg = tcm_vhost_make_tpg, | ||
1524 | .fabric_drop_tpg = tcm_vhost_drop_tpg, | ||
1525 | .fabric_post_link = tcm_vhost_port_link, | ||
1526 | .fabric_pre_unlink = tcm_vhost_port_unlink, | ||
1527 | .fabric_make_np = NULL, | ||
1528 | .fabric_drop_np = NULL, | ||
1529 | .fabric_make_nodeacl = tcm_vhost_make_nodeacl, | ||
1530 | .fabric_drop_nodeacl = tcm_vhost_drop_nodeacl, | ||
1531 | }; | ||
1532 | |||
1533 | static int tcm_vhost_register_configfs(void) | ||
1534 | { | ||
1535 | struct target_fabric_configfs *fabric; | ||
1536 | int ret; | ||
1537 | |||
1538 | pr_debug("TCM_VHOST fabric module %s on %s/%s" | ||
1539 | " on "UTS_RELEASE"\n", TCM_VHOST_VERSION, utsname()->sysname, | ||
1540 | utsname()->machine); | ||
1541 | /* | ||
1542 | * Register the top level struct config_item_type with TCM core | ||
1543 | */ | ||
1544 | fabric = target_fabric_configfs_init(THIS_MODULE, "vhost"); | ||
1545 | if (IS_ERR(fabric)) { | ||
1546 | pr_err("target_fabric_configfs_init() failed\n"); | ||
1547 | return PTR_ERR(fabric); | ||
1548 | } | ||
1549 | /* | ||
1550 | * Setup fabric->tf_ops from our local tcm_vhost_ops | ||
1551 | */ | ||
1552 | fabric->tf_ops = tcm_vhost_ops; | ||
1553 | /* | ||
1554 | * Setup default attribute lists for various fabric->tf_cit_tmpl | ||
1555 | */ | ||
1556 | TF_CIT_TMPL(fabric)->tfc_wwn_cit.ct_attrs = tcm_vhost_wwn_attrs; | ||
1557 | TF_CIT_TMPL(fabric)->tfc_tpg_base_cit.ct_attrs = tcm_vhost_tpg_attrs; | ||
1558 | TF_CIT_TMPL(fabric)->tfc_tpg_attrib_cit.ct_attrs = NULL; | ||
1559 | TF_CIT_TMPL(fabric)->tfc_tpg_param_cit.ct_attrs = NULL; | ||
1560 | TF_CIT_TMPL(fabric)->tfc_tpg_np_base_cit.ct_attrs = NULL; | ||
1561 | TF_CIT_TMPL(fabric)->tfc_tpg_nacl_base_cit.ct_attrs = NULL; | ||
1562 | TF_CIT_TMPL(fabric)->tfc_tpg_nacl_attrib_cit.ct_attrs = NULL; | ||
1563 | TF_CIT_TMPL(fabric)->tfc_tpg_nacl_auth_cit.ct_attrs = NULL; | ||
1564 | TF_CIT_TMPL(fabric)->tfc_tpg_nacl_param_cit.ct_attrs = NULL; | ||
1565 | /* | ||
1566 | * Register the fabric for use within TCM | ||
1567 | */ | ||
1568 | ret = target_fabric_configfs_register(fabric); | ||
1569 | if (ret < 0) { | ||
1570 | pr_err("target_fabric_configfs_register() failed" | ||
1571 | " for TCM_VHOST\n"); | ||
1572 | return ret; | ||
1573 | } | ||
1574 | /* | ||
1575 | * Setup our local pointer to *fabric | ||
1576 | */ | ||
1577 | tcm_vhost_fabric_configfs = fabric; | ||
1578 | pr_debug("TCM_VHOST[0] - Set fabric -> tcm_vhost_fabric_configfs\n"); | ||
1579 | return 0; | ||
1580 | }; | ||
1581 | |||
1582 | static void tcm_vhost_deregister_configfs(void) | ||
1583 | { | ||
1584 | if (!tcm_vhost_fabric_configfs) | ||
1585 | return; | ||
1586 | |||
1587 | target_fabric_configfs_deregister(tcm_vhost_fabric_configfs); | ||
1588 | tcm_vhost_fabric_configfs = NULL; | ||
1589 | pr_debug("TCM_VHOST[0] - Cleared tcm_vhost_fabric_configfs\n"); | ||
1590 | }; | ||
1591 | |||
1592 | static int __init tcm_vhost_init(void) | ||
1593 | { | ||
1594 | int ret = -ENOMEM; | ||
1595 | |||
1596 | tcm_vhost_workqueue = alloc_workqueue("tcm_vhost", 0, 0); | ||
1597 | if (!tcm_vhost_workqueue) | ||
1598 | goto out; | ||
1599 | |||
1600 | ret = vhost_scsi_register(); | ||
1601 | if (ret < 0) | ||
1602 | goto out_destroy_workqueue; | ||
1603 | |||
1604 | ret = tcm_vhost_register_configfs(); | ||
1605 | if (ret < 0) | ||
1606 | goto out_vhost_scsi_deregister; | ||
1607 | |||
1608 | return 0; | ||
1609 | |||
1610 | out_vhost_scsi_deregister: | ||
1611 | vhost_scsi_deregister(); | ||
1612 | out_destroy_workqueue: | ||
1613 | destroy_workqueue(tcm_vhost_workqueue); | ||
1614 | out: | ||
1615 | return ret; | ||
1616 | }; | ||
1617 | |||
1618 | static void tcm_vhost_exit(void) | ||
1619 | { | ||
1620 | tcm_vhost_deregister_configfs(); | ||
1621 | vhost_scsi_deregister(); | ||
1622 | destroy_workqueue(tcm_vhost_workqueue); | ||
1623 | }; | ||
1624 | |||
1625 | MODULE_DESCRIPTION("TCM_VHOST series fabric driver"); | ||
1626 | MODULE_LICENSE("GPL"); | ||
1627 | module_init(tcm_vhost_init); | ||
1628 | module_exit(tcm_vhost_exit); | ||
diff --git a/drivers/vhost/tcm_vhost.h b/drivers/vhost/tcm_vhost.h new file mode 100644 index 000000000000..c983ed21e413 --- /dev/null +++ b/drivers/vhost/tcm_vhost.h | |||
@@ -0,0 +1,101 @@ | |||
1 | #define TCM_VHOST_VERSION "v0.1" | ||
2 | #define TCM_VHOST_NAMELEN 256 | ||
3 | #define TCM_VHOST_MAX_CDB_SIZE 32 | ||
4 | |||
5 | struct tcm_vhost_cmd { | ||
6 | /* Descriptor from vhost_get_vq_desc() for virt_queue segment */ | ||
7 | int tvc_vq_desc; | ||
8 | /* The Tag from include/linux/virtio_scsi.h:struct virtio_scsi_cmd_req */ | ||
9 | u64 tvc_tag; | ||
10 | /* The number of scatterlists associated with this cmd */ | ||
11 | u32 tvc_sgl_count; | ||
12 | /* Saved unpacked SCSI LUN for tcm_vhost_submission_work() */ | ||
13 | u32 tvc_lun; | ||
14 | /* Pointer to the SGL formatted memory from virtio-scsi */ | ||
15 | struct scatterlist *tvc_sgl; | ||
16 | /* Pointer to response */ | ||
17 | struct virtio_scsi_cmd_resp __user *tvc_resp; | ||
18 | /* Pointer to vhost_scsi for our device */ | ||
19 | struct vhost_scsi *tvc_vhost; | ||
20 | /* The TCM I/O descriptor that is accessed via container_of() */ | ||
21 | struct se_cmd tvc_se_cmd; | ||
22 | /* work item used for cmwq dispatch to tcm_vhost_submission_work() */ | ||
23 | struct work_struct work; | ||
24 | /* Copy of the incoming SCSI command descriptor block (CDB) */ | ||
25 | unsigned char tvc_cdb[TCM_VHOST_MAX_CDB_SIZE]; | ||
26 | /* Sense buffer that will be mapped into outgoing status */ | ||
27 | unsigned char tvc_sense_buf[TRANSPORT_SENSE_BUFFER]; | ||
28 | /* Completed commands list, serviced from vhost worker thread */ | ||
29 | struct list_head tvc_completion_list; | ||
30 | }; | ||
31 | |||
32 | struct tcm_vhost_nexus { | ||
33 | /* Pointer to TCM session for I_T Nexus */ | ||
34 | struct se_session *tvn_se_sess; | ||
35 | }; | ||
36 | |||
37 | struct tcm_vhost_nacl { | ||
38 | /* Binary World Wide unique Port Name for Vhost Initiator port */ | ||
39 | u64 iport_wwpn; | ||
40 | /* ASCII formatted WWPN for Sas Initiator port */ | ||
41 | char iport_name[TCM_VHOST_NAMELEN]; | ||
42 | /* Returned by tcm_vhost_make_nodeacl() */ | ||
43 | struct se_node_acl se_node_acl; | ||
44 | }; | ||
45 | |||
46 | struct tcm_vhost_tpg { | ||
47 | /* Vhost port target portal group tag for TCM */ | ||
48 | u16 tport_tpgt; | ||
49 | /* Used to track number of TPG Port/Lun Links wrt to explict I_T Nexus shutdown */ | ||
50 | atomic_t tv_tpg_port_count; | ||
51 | /* Used for vhost_scsi device reference to tpg_nexus */ | ||
52 | atomic_t tv_tpg_vhost_count; | ||
53 | /* list for tcm_vhost_list */ | ||
54 | struct list_head tv_tpg_list; | ||
55 | /* Used to protect access for tpg_nexus */ | ||
56 | struct mutex tv_tpg_mutex; | ||
57 | /* Pointer to the TCM VHost I_T Nexus for this TPG endpoint */ | ||
58 | struct tcm_vhost_nexus *tpg_nexus; | ||
59 | /* Pointer back to tcm_vhost_tport */ | ||
60 | struct tcm_vhost_tport *tport; | ||
61 | /* Returned by tcm_vhost_make_tpg() */ | ||
62 | struct se_portal_group se_tpg; | ||
63 | }; | ||
64 | |||
65 | struct tcm_vhost_tport { | ||
66 | /* SCSI protocol the tport is providing */ | ||
67 | u8 tport_proto_id; | ||
68 | /* Binary World Wide unique Port Name for Vhost Target port */ | ||
69 | u64 tport_wwpn; | ||
70 | /* ASCII formatted WWPN for Vhost Target port */ | ||
71 | char tport_name[TCM_VHOST_NAMELEN]; | ||
72 | /* Returned by tcm_vhost_make_tport() */ | ||
73 | struct se_wwn tport_wwn; | ||
74 | }; | ||
75 | |||
76 | /* | ||
77 | * As per request from MST, keep TCM_VHOST related ioctl defines out of | ||
78 | * linux/vhost.h (user-space) for now.. | ||
79 | */ | ||
80 | |||
81 | #include <linux/vhost.h> | ||
82 | |||
83 | /* | ||
84 | * Used by QEMU userspace to ensure a consistent vhost-scsi ABI. | ||
85 | * | ||
86 | * ABI Rev 0: July 2012 version starting point for v3.6-rc merge candidate + | ||
87 | * RFC-v2 vhost-scsi userspace. Add GET_ABI_VERSION ioctl usage | ||
88 | */ | ||
89 | |||
90 | #define VHOST_SCSI_ABI_VERSION 0 | ||
91 | |||
92 | struct vhost_scsi_target { | ||
93 | int abi_version; | ||
94 | unsigned char vhost_wwpn[TRANSPORT_IQN_LEN]; | ||
95 | unsigned short vhost_tpgt; | ||
96 | }; | ||
97 | |||
98 | /* VHOST_SCSI specific defines */ | ||
99 | #define VHOST_SCSI_SET_ENDPOINT _IOW(VHOST_VIRTIO, 0x40, struct vhost_scsi_target) | ||
100 | #define VHOST_SCSI_CLEAR_ENDPOINT _IOW(VHOST_VIRTIO, 0x41, struct vhost_scsi_target) | ||
101 | #define VHOST_SCSI_GET_ABI_VERSION _IOW(VHOST_VIRTIO, 0x42, struct vhost_scsi_target) | ||
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c index 2e471c22abf5..f8a79fca4a22 100644 --- a/drivers/video/console/fbcon.c +++ b/drivers/video/console/fbcon.c | |||
@@ -372,8 +372,12 @@ static void fb_flashcursor(struct work_struct *work) | |||
372 | struct vc_data *vc = NULL; | 372 | struct vc_data *vc = NULL; |
373 | int c; | 373 | int c; |
374 | int mode; | 374 | int mode; |
375 | int ret; | ||
376 | |||
377 | ret = console_trylock(); | ||
378 | if (ret == 0) | ||
379 | return; | ||
375 | 380 | ||
376 | console_lock(); | ||
377 | if (ops && ops->currcon != -1) | 381 | if (ops && ops->currcon != -1) |
378 | vc = vc_cons[ops->currcon].d; | 382 | vc = vc_cons[ops->currcon].d; |
379 | 383 | ||
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index d90062b211f8..92d08e7fcba2 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c | |||
@@ -91,6 +91,11 @@ static struct w1_family w1_therm_family_DS28EA00 = { | |||
91 | .fops = &w1_therm_fops, | 91 | .fops = &w1_therm_fops, |
92 | }; | 92 | }; |
93 | 93 | ||
94 | static struct w1_family w1_therm_family_DS1825 = { | ||
95 | .fid = W1_THERM_DS1825, | ||
96 | .fops = &w1_therm_fops, | ||
97 | }; | ||
98 | |||
94 | struct w1_therm_family_converter | 99 | struct w1_therm_family_converter |
95 | { | 100 | { |
96 | u8 broken; | 101 | u8 broken; |
@@ -120,6 +125,10 @@ static struct w1_therm_family_converter w1_therm_families[] = { | |||
120 | .f = &w1_therm_family_DS28EA00, | 125 | .f = &w1_therm_family_DS28EA00, |
121 | .convert = w1_DS18B20_convert_temp | 126 | .convert = w1_DS18B20_convert_temp |
122 | }, | 127 | }, |
128 | { | ||
129 | .f = &w1_therm_family_DS1825, | ||
130 | .convert = w1_DS18B20_convert_temp | ||
131 | } | ||
123 | }; | 132 | }; |
124 | 133 | ||
125 | static inline int w1_DS18B20_convert_temp(u8 rom[9]) | 134 | static inline int w1_DS18B20_convert_temp(u8 rom[9]) |
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h index b00ada44a89b..a1f0ce151d53 100644 --- a/drivers/w1/w1_family.h +++ b/drivers/w1/w1_family.h | |||
@@ -39,6 +39,7 @@ | |||
39 | #define W1_EEPROM_DS2431 0x2D | 39 | #define W1_EEPROM_DS2431 0x2D |
40 | #define W1_FAMILY_DS2760 0x30 | 40 | #define W1_FAMILY_DS2760 0x30 |
41 | #define W1_FAMILY_DS2780 0x32 | 41 | #define W1_FAMILY_DS2780 0x32 |
42 | #define W1_THERM_DS1825 0x3B | ||
42 | #define W1_FAMILY_DS2781 0x3D | 43 | #define W1_FAMILY_DS2781 0x3D |
43 | #define W1_THERM_DS28EA00 0x42 | 44 | #define W1_THERM_DS28EA00 0x42 |
44 | 45 | ||
diff --git a/drivers/watchdog/orion_wdt.c b/drivers/watchdog/orion_wdt.c index a73bea4aa1ba..c20f96b579d9 100644 --- a/drivers/watchdog/orion_wdt.c +++ b/drivers/watchdog/orion_wdt.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include <linux/spinlock.h> | 24 | #include <linux/spinlock.h> |
25 | #include <linux/clk.h> | 25 | #include <linux/clk.h> |
26 | #include <linux/err.h> | 26 | #include <linux/err.h> |
27 | #include <linux/of.h> | ||
27 | #include <mach/bridge-regs.h> | 28 | #include <mach/bridge-regs.h> |
28 | 29 | ||
29 | /* | 30 | /* |
@@ -192,6 +193,12 @@ static void orion_wdt_shutdown(struct platform_device *pdev) | |||
192 | orion_wdt_stop(&orion_wdt); | 193 | orion_wdt_stop(&orion_wdt); |
193 | } | 194 | } |
194 | 195 | ||
196 | static const struct of_device_id orion_wdt_of_match_table[] __devinitdata = { | ||
197 | { .compatible = "marvell,orion-wdt", }, | ||
198 | {}, | ||
199 | }; | ||
200 | MODULE_DEVICE_TABLE(of, orion_wdt_of_match_table); | ||
201 | |||
195 | static struct platform_driver orion_wdt_driver = { | 202 | static struct platform_driver orion_wdt_driver = { |
196 | .probe = orion_wdt_probe, | 203 | .probe = orion_wdt_probe, |
197 | .remove = __devexit_p(orion_wdt_remove), | 204 | .remove = __devexit_p(orion_wdt_remove), |
@@ -199,6 +206,7 @@ static struct platform_driver orion_wdt_driver = { | |||
199 | .driver = { | 206 | .driver = { |
200 | .owner = THIS_MODULE, | 207 | .owner = THIS_MODULE, |
201 | .name = "orion_wdt", | 208 | .name = "orion_wdt", |
209 | .of_match_table = of_match_ptr(orion_wdt_of_match_table), | ||
202 | }, | 210 | }, |
203 | }; | 211 | }; |
204 | 212 | ||
diff --git a/drivers/zorro/zorro.c b/drivers/zorro/zorro.c index 181fa8158a8b..858c9714b2f3 100644 --- a/drivers/zorro/zorro.c +++ b/drivers/zorro/zorro.c | |||
@@ -37,7 +37,6 @@ struct zorro_dev zorro_autocon[ZORRO_NUM_AUTO]; | |||
37 | */ | 37 | */ |
38 | 38 | ||
39 | struct zorro_bus { | 39 | struct zorro_bus { |
40 | struct list_head devices; /* list of devices on this bus */ | ||
41 | struct device dev; | 40 | struct device dev; |
42 | }; | 41 | }; |
43 | 42 | ||
@@ -136,7 +135,6 @@ static int __init amiga_zorro_probe(struct platform_device *pdev) | |||
136 | if (!bus) | 135 | if (!bus) |
137 | return -ENOMEM; | 136 | return -ENOMEM; |
138 | 137 | ||
139 | INIT_LIST_HEAD(&bus->devices); | ||
140 | bus->dev.parent = &pdev->dev; | 138 | bus->dev.parent = &pdev->dev; |
141 | dev_set_name(&bus->dev, "zorro"); | 139 | dev_set_name(&bus->dev, "zorro"); |
142 | error = device_register(&bus->dev); | 140 | error = device_register(&bus->dev); |
diff --git a/fs/autofs4/expire.c b/fs/autofs4/expire.c index 1feb68ecef95..842d00048a65 100644 --- a/fs/autofs4/expire.c +++ b/fs/autofs4/expire.c | |||
@@ -94,25 +94,21 @@ static struct dentry *get_next_positive_subdir(struct dentry *prev, | |||
94 | { | 94 | { |
95 | struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb); | 95 | struct autofs_sb_info *sbi = autofs4_sbi(root->d_sb); |
96 | struct list_head *next; | 96 | struct list_head *next; |
97 | struct dentry *p, *q; | 97 | struct dentry *q; |
98 | 98 | ||
99 | spin_lock(&sbi->lookup_lock); | 99 | spin_lock(&sbi->lookup_lock); |
100 | spin_lock(&root->d_lock); | ||
100 | 101 | ||
101 | if (prev == NULL) { | 102 | if (prev) |
102 | spin_lock(&root->d_lock); | 103 | next = prev->d_u.d_child.next; |
104 | else { | ||
103 | prev = dget_dlock(root); | 105 | prev = dget_dlock(root); |
104 | next = prev->d_subdirs.next; | 106 | next = prev->d_subdirs.next; |
105 | p = prev; | ||
106 | goto start; | ||
107 | } | 107 | } |
108 | 108 | ||
109 | p = prev; | 109 | cont: |
110 | spin_lock(&p->d_lock); | ||
111 | again: | ||
112 | next = p->d_u.d_child.next; | ||
113 | start: | ||
114 | if (next == &root->d_subdirs) { | 110 | if (next == &root->d_subdirs) { |
115 | spin_unlock(&p->d_lock); | 111 | spin_unlock(&root->d_lock); |
116 | spin_unlock(&sbi->lookup_lock); | 112 | spin_unlock(&sbi->lookup_lock); |
117 | dput(prev); | 113 | dput(prev); |
118 | return NULL; | 114 | return NULL; |
@@ -121,16 +117,15 @@ start: | |||
121 | q = list_entry(next, struct dentry, d_u.d_child); | 117 | q = list_entry(next, struct dentry, d_u.d_child); |
122 | 118 | ||
123 | spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED); | 119 | spin_lock_nested(&q->d_lock, DENTRY_D_LOCK_NESTED); |
124 | /* Negative dentry - try next */ | 120 | /* Already gone or negative dentry (under construction) - try next */ |
125 | if (!simple_positive(q)) { | 121 | if (q->d_count == 0 || !simple_positive(q)) { |
126 | spin_unlock(&p->d_lock); | 122 | spin_unlock(&q->d_lock); |
127 | lock_set_subclass(&q->d_lock.dep_map, 0, _RET_IP_); | 123 | next = q->d_u.d_child.next; |
128 | p = q; | 124 | goto cont; |
129 | goto again; | ||
130 | } | 125 | } |
131 | dget_dlock(q); | 126 | dget_dlock(q); |
132 | spin_unlock(&q->d_lock); | 127 | spin_unlock(&q->d_lock); |
133 | spin_unlock(&p->d_lock); | 128 | spin_unlock(&root->d_lock); |
134 | spin_unlock(&sbi->lookup_lock); | 129 | spin_unlock(&sbi->lookup_lock); |
135 | 130 | ||
136 | dput(prev); | 131 | dput(prev); |
@@ -404,11 +399,6 @@ struct dentry *autofs4_expire_indirect(struct super_block *sb, | |||
404 | DPRINTK("checking mountpoint %p %.*s", | 399 | DPRINTK("checking mountpoint %p %.*s", |
405 | dentry, (int)dentry->d_name.len, dentry->d_name.name); | 400 | dentry, (int)dentry->d_name.len, dentry->d_name.name); |
406 | 401 | ||
407 | /* Path walk currently on this dentry? */ | ||
408 | ino_count = atomic_read(&ino->count) + 2; | ||
409 | if (dentry->d_count > ino_count) | ||
410 | goto next; | ||
411 | |||
412 | /* Can we umount this guy */ | 402 | /* Can we umount this guy */ |
413 | if (autofs4_mount_busy(mnt, dentry)) | 403 | if (autofs4_mount_busy(mnt, dentry)) |
414 | goto next; | 404 | goto next; |
@@ -1312,7 +1312,7 @@ EXPORT_SYMBOL(bio_copy_kern); | |||
1312 | * Note that this code is very hard to test under normal circumstances because | 1312 | * Note that this code is very hard to test under normal circumstances because |
1313 | * direct-io pins the pages with get_user_pages(). This makes | 1313 | * direct-io pins the pages with get_user_pages(). This makes |
1314 | * is_page_cache_freeable return false, and the VM will not clean the pages. | 1314 | * is_page_cache_freeable return false, and the VM will not clean the pages. |
1315 | * But other code (eg, pdflush) could clean the pages if they are mapped | 1315 | * But other code (eg, flusher threads) could clean the pages if they are mapped |
1316 | * pagecache. | 1316 | * pagecache. |
1317 | * | 1317 | * |
1318 | * Simply disabling the call to bio_set_pages_dirty() is a good way to test the | 1318 | * Simply disabling the call to bio_set_pages_dirty() is a good way to test the |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index 83baec24946d..6e8f416773d4 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -324,7 +324,8 @@ static noinline int add_async_extent(struct async_cow *cow, | |||
324 | * If this code finds it can't get good compression, it puts an | 324 | * If this code finds it can't get good compression, it puts an |
325 | * entry onto the work queue to write the uncompressed bytes. This | 325 | * entry onto the work queue to write the uncompressed bytes. This |
326 | * makes sure that both compressed inodes and uncompressed inodes | 326 | * makes sure that both compressed inodes and uncompressed inodes |
327 | * are written in the same order that pdflush sent them down. | 327 | * are written in the same order that the flusher thread sent them |
328 | * down. | ||
328 | */ | 329 | */ |
329 | static noinline int compress_file_range(struct inode *inode, | 330 | static noinline int compress_file_range(struct inode *inode, |
330 | struct page *locked_page, | 331 | struct page *locked_page, |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index bc2f6ffff3cf..7bb755677a22 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -664,10 +664,6 @@ static noinline int btrfs_mksubvol(struct path *parent, | |||
664 | struct dentry *dentry; | 664 | struct dentry *dentry; |
665 | int error; | 665 | int error; |
666 | 666 | ||
667 | error = mnt_want_write(parent->mnt); | ||
668 | if (error) | ||
669 | return error; | ||
670 | |||
671 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); | 667 | mutex_lock_nested(&dir->i_mutex, I_MUTEX_PARENT); |
672 | 668 | ||
673 | dentry = lookup_one_len(name, parent->dentry, namelen); | 669 | dentry = lookup_one_len(name, parent->dentry, namelen); |
@@ -703,7 +699,6 @@ out_dput: | |||
703 | dput(dentry); | 699 | dput(dentry); |
704 | out_unlock: | 700 | out_unlock: |
705 | mutex_unlock(&dir->i_mutex); | 701 | mutex_unlock(&dir->i_mutex); |
706 | mnt_drop_write(parent->mnt); | ||
707 | return error; | 702 | return error; |
708 | } | 703 | } |
709 | 704 | ||
diff --git a/fs/btrfs/ordered-data.c b/fs/btrfs/ordered-data.c index 643335a4fe3c..051c7fe551dd 100644 --- a/fs/btrfs/ordered-data.c +++ b/fs/btrfs/ordered-data.c | |||
@@ -596,7 +596,7 @@ void btrfs_start_ordered_extent(struct inode *inode, | |||
596 | /* | 596 | /* |
597 | * pages in the range can be dirty, clean or writeback. We | 597 | * pages in the range can be dirty, clean or writeback. We |
598 | * start IO on any dirty ones so the wait doesn't stall waiting | 598 | * start IO on any dirty ones so the wait doesn't stall waiting |
599 | * for pdflush to find them | 599 | * for the flusher thread to find them |
600 | */ | 600 | */ |
601 | if (!test_bit(BTRFS_ORDERED_DIRECT, &entry->flags)) | 601 | if (!test_bit(BTRFS_ORDERED_DIRECT, &entry->flags)) |
602 | filemap_fdatawrite_range(inode->i_mapping, start, end); | 602 | filemap_fdatawrite_range(inode->i_mapping, start, end); |
diff --git a/fs/btrfs/super.c b/fs/btrfs/super.c index 8c6e61d6eed5..f2eb24c477a3 100644 --- a/fs/btrfs/super.c +++ b/fs/btrfs/super.c | |||
@@ -100,10 +100,6 @@ static void __save_error_info(struct btrfs_fs_info *fs_info) | |||
100 | fs_info->fs_state = BTRFS_SUPER_FLAG_ERROR; | 100 | fs_info->fs_state = BTRFS_SUPER_FLAG_ERROR; |
101 | } | 101 | } |
102 | 102 | ||
103 | /* NOTE: | ||
104 | * We move write_super stuff at umount in order to avoid deadlock | ||
105 | * for umount hold all lock. | ||
106 | */ | ||
107 | static void save_error_info(struct btrfs_fs_info *fs_info) | 103 | static void save_error_info(struct btrfs_fs_info *fs_info) |
108 | { | 104 | { |
109 | __save_error_info(fs_info); | 105 | __save_error_info(fs_info); |
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c index b8708f994e67..e86ae04abe6a 100644 --- a/fs/btrfs/volumes.c +++ b/fs/btrfs/volumes.c | |||
@@ -1744,10 +1744,6 @@ int btrfs_init_new_device(struct btrfs_root *root, char *device_path) | |||
1744 | 1744 | ||
1745 | device->fs_devices = root->fs_info->fs_devices; | 1745 | device->fs_devices = root->fs_info->fs_devices; |
1746 | 1746 | ||
1747 | /* | ||
1748 | * we don't want write_supers to jump in here with our device | ||
1749 | * half setup | ||
1750 | */ | ||
1751 | mutex_lock(&root->fs_info->fs_devices->device_list_mutex); | 1747 | mutex_lock(&root->fs_info->fs_devices->device_list_mutex); |
1752 | list_add_rcu(&device->dev_list, &root->fs_info->fs_devices->devices); | 1748 | list_add_rcu(&device->dev_list, &root->fs_info->fs_devices->devices); |
1753 | list_add(&device->dev_alloc_list, | 1749 | list_add(&device->dev_alloc_list, |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index f391f1e75414..e5b77319c97b 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -633,44 +633,6 @@ static struct dentry *ceph_lookup(struct inode *dir, struct dentry *dentry, | |||
633 | return dentry; | 633 | return dentry; |
634 | } | 634 | } |
635 | 635 | ||
636 | int ceph_atomic_open(struct inode *dir, struct dentry *dentry, | ||
637 | struct file *file, unsigned flags, umode_t mode, | ||
638 | int *opened) | ||
639 | { | ||
640 | int err; | ||
641 | struct dentry *res = NULL; | ||
642 | |||
643 | if (!(flags & O_CREAT)) { | ||
644 | if (dentry->d_name.len > NAME_MAX) | ||
645 | return -ENAMETOOLONG; | ||
646 | |||
647 | err = ceph_init_dentry(dentry); | ||
648 | if (err < 0) | ||
649 | return err; | ||
650 | |||
651 | return ceph_lookup_open(dir, dentry, file, flags, mode, opened); | ||
652 | } | ||
653 | |||
654 | if (d_unhashed(dentry)) { | ||
655 | res = ceph_lookup(dir, dentry, 0); | ||
656 | if (IS_ERR(res)) | ||
657 | return PTR_ERR(res); | ||
658 | |||
659 | if (res) | ||
660 | dentry = res; | ||
661 | } | ||
662 | |||
663 | /* We don't deal with positive dentries here */ | ||
664 | if (dentry->d_inode) | ||
665 | return finish_no_open(file, res); | ||
666 | |||
667 | *opened |= FILE_CREATED; | ||
668 | err = ceph_lookup_open(dir, dentry, file, flags, mode, opened); | ||
669 | dput(res); | ||
670 | |||
671 | return err; | ||
672 | } | ||
673 | |||
674 | /* | 636 | /* |
675 | * If we do a create but get no trace back from the MDS, follow up with | 637 | * If we do a create but get no trace back from the MDS, follow up with |
676 | * a lookup (the VFS expects us to link up the provided dentry). | 638 | * a lookup (the VFS expects us to link up the provided dentry). |
diff --git a/fs/ceph/file.c b/fs/ceph/file.c index 1b81d6c31878..ecebbc09bfc7 100644 --- a/fs/ceph/file.c +++ b/fs/ceph/file.c | |||
@@ -4,6 +4,7 @@ | |||
4 | #include <linux/sched.h> | 4 | #include <linux/sched.h> |
5 | #include <linux/slab.h> | 5 | #include <linux/slab.h> |
6 | #include <linux/file.h> | 6 | #include <linux/file.h> |
7 | #include <linux/mount.h> | ||
7 | #include <linux/namei.h> | 8 | #include <linux/namei.h> |
8 | #include <linux/writeback.h> | 9 | #include <linux/writeback.h> |
9 | 10 | ||
@@ -106,9 +107,6 @@ static int ceph_init_file(struct inode *inode, struct file *file, int fmode) | |||
106 | } | 107 | } |
107 | 108 | ||
108 | /* | 109 | /* |
109 | * If the filp already has private_data, that means the file was | ||
110 | * already opened by intent during lookup, and we do nothing. | ||
111 | * | ||
112 | * If we already have the requisite capabilities, we can satisfy | 110 | * If we already have the requisite capabilities, we can satisfy |
113 | * the open request locally (no need to request new caps from the | 111 | * the open request locally (no need to request new caps from the |
114 | * MDS). We do, however, need to inform the MDS (asynchronously) | 112 | * MDS). We do, however, need to inform the MDS (asynchronously) |
@@ -207,24 +205,29 @@ out: | |||
207 | 205 | ||
208 | 206 | ||
209 | /* | 207 | /* |
210 | * Do a lookup + open with a single request. | 208 | * Do a lookup + open with a single request. If we get a non-existent |
211 | * | 209 | * file or symlink, return 1 so the VFS can retry. |
212 | * If this succeeds, but some subsequent check in the vfs | ||
213 | * may_open() fails, the struct *file gets cleaned up (i.e. | ||
214 | * ceph_release gets called). So fear not! | ||
215 | */ | 210 | */ |
216 | int ceph_lookup_open(struct inode *dir, struct dentry *dentry, | 211 | int ceph_atomic_open(struct inode *dir, struct dentry *dentry, |
217 | struct file *file, unsigned flags, umode_t mode, | 212 | struct file *file, unsigned flags, umode_t mode, |
218 | int *opened) | 213 | int *opened) |
219 | { | 214 | { |
220 | struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); | 215 | struct ceph_fs_client *fsc = ceph_sb_to_client(dir->i_sb); |
221 | struct ceph_mds_client *mdsc = fsc->mdsc; | 216 | struct ceph_mds_client *mdsc = fsc->mdsc; |
222 | struct ceph_mds_request *req; | 217 | struct ceph_mds_request *req; |
223 | struct dentry *ret; | 218 | struct dentry *dn; |
224 | int err; | 219 | int err; |
225 | 220 | ||
226 | dout("ceph_lookup_open dentry %p '%.*s' flags %d mode 0%o\n", | 221 | dout("atomic_open %p dentry %p '%.*s' %s flags %d mode 0%o\n", |
227 | dentry, dentry->d_name.len, dentry->d_name.name, flags, mode); | 222 | dir, dentry, dentry->d_name.len, dentry->d_name.name, |
223 | d_unhashed(dentry) ? "unhashed" : "hashed", flags, mode); | ||
224 | |||
225 | if (dentry->d_name.len > NAME_MAX) | ||
226 | return -ENAMETOOLONG; | ||
227 | |||
228 | err = ceph_init_dentry(dentry); | ||
229 | if (err < 0) | ||
230 | return err; | ||
228 | 231 | ||
229 | /* do the open */ | 232 | /* do the open */ |
230 | req = prepare_open_request(dir->i_sb, flags, mode); | 233 | req = prepare_open_request(dir->i_sb, flags, mode); |
@@ -241,22 +244,31 @@ int ceph_lookup_open(struct inode *dir, struct dentry *dentry, | |||
241 | (flags & (O_CREAT|O_TRUNC)) ? dir : NULL, | 244 | (flags & (O_CREAT|O_TRUNC)) ? dir : NULL, |
242 | req); | 245 | req); |
243 | err = ceph_handle_snapdir(req, dentry, err); | 246 | err = ceph_handle_snapdir(req, dentry, err); |
244 | if (err) | 247 | if (err == 0 && (flags & O_CREAT) && !req->r_reply_info.head->is_dentry) |
245 | goto out; | ||
246 | if ((flags & O_CREAT) && !req->r_reply_info.head->is_dentry) | ||
247 | err = ceph_handle_notrace_create(dir, dentry); | 248 | err = ceph_handle_notrace_create(dir, dentry); |
248 | if (err) | ||
249 | goto out; | ||
250 | err = finish_open(file, req->r_dentry, ceph_open, opened); | ||
251 | out: | ||
252 | ret = ceph_finish_lookup(req, dentry, err); | ||
253 | ceph_mdsc_put_request(req); | ||
254 | dout("ceph_lookup_open result=%p\n", ret); | ||
255 | 249 | ||
256 | if (IS_ERR(ret)) | 250 | if (d_unhashed(dentry)) { |
257 | return PTR_ERR(ret); | 251 | dn = ceph_finish_lookup(req, dentry, err); |
252 | if (IS_ERR(dn)) | ||
253 | err = PTR_ERR(dn); | ||
254 | } else { | ||
255 | /* we were given a hashed negative dentry */ | ||
256 | dn = NULL; | ||
257 | } | ||
258 | if (err) | ||
259 | goto out_err; | ||
260 | if (dn || dentry->d_inode == NULL || S_ISLNK(dentry->d_inode->i_mode)) { | ||
261 | /* make vfs retry on splice, ENOENT, or symlink */ | ||
262 | dout("atomic_open finish_no_open on dn %p\n", dn); | ||
263 | err = finish_no_open(file, dn); | ||
264 | } else { | ||
265 | dout("atomic_open finish_open on dn %p\n", dn); | ||
266 | err = finish_open(file, dentry, ceph_open, opened); | ||
267 | } | ||
258 | 268 | ||
259 | dput(ret); | 269 | out_err: |
270 | ceph_mdsc_put_request(req); | ||
271 | dout("atomic_open result=%d\n", err); | ||
260 | return err; | 272 | return err; |
261 | } | 273 | } |
262 | 274 | ||
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index ebc95cc652be..66ebe720e40d 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -806,9 +806,9 @@ extern int ceph_copy_from_page_vector(struct page **pages, | |||
806 | loff_t off, size_t len); | 806 | loff_t off, size_t len); |
807 | extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags); | 807 | extern struct page **ceph_alloc_page_vector(int num_pages, gfp_t flags); |
808 | extern int ceph_open(struct inode *inode, struct file *file); | 808 | extern int ceph_open(struct inode *inode, struct file *file); |
809 | extern int ceph_lookup_open(struct inode *dir, struct dentry *dentry, | 809 | extern int ceph_atomic_open(struct inode *dir, struct dentry *dentry, |
810 | struct file *od, unsigned flags, | 810 | struct file *file, unsigned flags, umode_t mode, |
811 | umode_t mode, int *opened); | 811 | int *opened); |
812 | extern int ceph_release(struct inode *inode, struct file *filp); | 812 | extern int ceph_release(struct inode *inode, struct file *filp); |
813 | 813 | ||
814 | /* dir.c */ | 814 | /* dir.c */ |
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 497da5ce704c..977dc0e85ccb 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h | |||
@@ -246,6 +246,16 @@ struct smb_version_operations { | |||
246 | bool (*can_echo)(struct TCP_Server_Info *); | 246 | bool (*can_echo)(struct TCP_Server_Info *); |
247 | /* send echo request */ | 247 | /* send echo request */ |
248 | int (*echo)(struct TCP_Server_Info *); | 248 | int (*echo)(struct TCP_Server_Info *); |
249 | /* create directory */ | ||
250 | int (*mkdir)(const unsigned int, struct cifs_tcon *, const char *, | ||
251 | struct cifs_sb_info *); | ||
252 | /* set info on created directory */ | ||
253 | void (*mkdir_setinfo)(struct inode *, const char *, | ||
254 | struct cifs_sb_info *, struct cifs_tcon *, | ||
255 | const unsigned int); | ||
256 | /* remove directory */ | ||
257 | int (*rmdir)(const unsigned int, struct cifs_tcon *, const char *, | ||
258 | struct cifs_sb_info *); | ||
249 | }; | 259 | }; |
250 | 260 | ||
251 | struct smb_version_values { | 261 | struct smb_version_values { |
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h index cf7fb185103c..f1bbf8305d3a 100644 --- a/fs/cifs/cifsproto.h +++ b/fs/cifs/cifsproto.h | |||
@@ -289,18 +289,15 @@ extern int CIFSSMBUnixSetFileInfo(const unsigned int xid, | |||
289 | u16 fid, u32 pid_of_opener); | 289 | u16 fid, u32 pid_of_opener); |
290 | 290 | ||
291 | extern int CIFSSMBUnixSetPathInfo(const unsigned int xid, | 291 | extern int CIFSSMBUnixSetPathInfo(const unsigned int xid, |
292 | struct cifs_tcon *tcon, char *file_name, | 292 | struct cifs_tcon *tcon, const char *file_name, |
293 | const struct cifs_unix_set_info_args *args, | 293 | const struct cifs_unix_set_info_args *args, |
294 | const struct nls_table *nls_codepage, | 294 | const struct nls_table *nls_codepage, |
295 | int remap_special_chars); | 295 | int remap); |
296 | 296 | ||
297 | extern int CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, | 297 | extern int CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, |
298 | const char *newName, | 298 | const char *name, struct cifs_sb_info *cifs_sb); |
299 | const struct nls_table *nls_codepage, | ||
300 | int remap_special_chars); | ||
301 | extern int CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, | 299 | extern int CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, |
302 | const char *name, const struct nls_table *nls_codepage, | 300 | const char *name, struct cifs_sb_info *cifs_sb); |
303 | int remap_special_chars); | ||
304 | extern int CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon, | 301 | extern int CIFSPOSIXDelFile(const unsigned int xid, struct cifs_tcon *tcon, |
305 | const char *name, __u16 type, | 302 | const char *name, __u16 type, |
306 | const struct nls_table *nls_codepage, | 303 | const struct nls_table *nls_codepage, |
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index cabc7a01f5df..074923ce593d 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c | |||
@@ -948,15 +948,15 @@ DelFileRetry: | |||
948 | } | 948 | } |
949 | 949 | ||
950 | int | 950 | int |
951 | CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, | 951 | CIFSSMBRmDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, |
952 | const char *dirName, const struct nls_table *nls_codepage, | 952 | struct cifs_sb_info *cifs_sb) |
953 | int remap) | ||
954 | { | 953 | { |
955 | DELETE_DIRECTORY_REQ *pSMB = NULL; | 954 | DELETE_DIRECTORY_REQ *pSMB = NULL; |
956 | DELETE_DIRECTORY_RSP *pSMBr = NULL; | 955 | DELETE_DIRECTORY_RSP *pSMBr = NULL; |
957 | int rc = 0; | 956 | int rc = 0; |
958 | int bytes_returned; | 957 | int bytes_returned; |
959 | int name_len; | 958 | int name_len; |
959 | int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR; | ||
960 | 960 | ||
961 | cFYI(1, "In CIFSSMBRmDir"); | 961 | cFYI(1, "In CIFSSMBRmDir"); |
962 | RmDirRetry: | 962 | RmDirRetry: |
@@ -966,14 +966,15 @@ RmDirRetry: | |||
966 | return rc; | 966 | return rc; |
967 | 967 | ||
968 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 968 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
969 | name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, dirName, | 969 | name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, |
970 | PATH_MAX, nls_codepage, remap); | 970 | PATH_MAX, cifs_sb->local_nls, |
971 | remap); | ||
971 | name_len++; /* trailing null */ | 972 | name_len++; /* trailing null */ |
972 | name_len *= 2; | 973 | name_len *= 2; |
973 | } else { /* BB improve check for buffer overruns BB */ | 974 | } else { /* BB improve check for buffer overruns BB */ |
974 | name_len = strnlen(dirName, PATH_MAX); | 975 | name_len = strnlen(name, PATH_MAX); |
975 | name_len++; /* trailing null */ | 976 | name_len++; /* trailing null */ |
976 | strncpy(pSMB->DirName, dirName, name_len); | 977 | strncpy(pSMB->DirName, name, name_len); |
977 | } | 978 | } |
978 | 979 | ||
979 | pSMB->BufferFormat = 0x04; | 980 | pSMB->BufferFormat = 0x04; |
@@ -992,14 +993,15 @@ RmDirRetry: | |||
992 | } | 993 | } |
993 | 994 | ||
994 | int | 995 | int |
995 | CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, | 996 | CIFSSMBMkDir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, |
996 | const char *name, const struct nls_table *nls_codepage, int remap) | 997 | struct cifs_sb_info *cifs_sb) |
997 | { | 998 | { |
998 | int rc = 0; | 999 | int rc = 0; |
999 | CREATE_DIRECTORY_REQ *pSMB = NULL; | 1000 | CREATE_DIRECTORY_REQ *pSMB = NULL; |
1000 | CREATE_DIRECTORY_RSP *pSMBr = NULL; | 1001 | CREATE_DIRECTORY_RSP *pSMBr = NULL; |
1001 | int bytes_returned; | 1002 | int bytes_returned; |
1002 | int name_len; | 1003 | int name_len; |
1004 | int remap = cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR; | ||
1003 | 1005 | ||
1004 | cFYI(1, "In CIFSSMBMkDir"); | 1006 | cFYI(1, "In CIFSSMBMkDir"); |
1005 | MkDirRetry: | 1007 | MkDirRetry: |
@@ -1010,7 +1012,8 @@ MkDirRetry: | |||
1010 | 1012 | ||
1011 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 1013 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
1012 | name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, | 1014 | name_len = cifsConvertToUTF16((__le16 *) pSMB->DirName, name, |
1013 | PATH_MAX, nls_codepage, remap); | 1015 | PATH_MAX, cifs_sb->local_nls, |
1016 | remap); | ||
1014 | name_len++; /* trailing null */ | 1017 | name_len++; /* trailing null */ |
1015 | name_len *= 2; | 1018 | name_len *= 2; |
1016 | } else { /* BB improve check for buffer overruns BB */ | 1019 | } else { /* BB improve check for buffer overruns BB */ |
@@ -5943,7 +5946,7 @@ CIFSSMBUnixSetFileInfo(const unsigned int xid, struct cifs_tcon *tcon, | |||
5943 | 5946 | ||
5944 | int | 5947 | int |
5945 | CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, | 5948 | CIFSSMBUnixSetPathInfo(const unsigned int xid, struct cifs_tcon *tcon, |
5946 | char *fileName, | 5949 | const char *file_name, |
5947 | const struct cifs_unix_set_info_args *args, | 5950 | const struct cifs_unix_set_info_args *args, |
5948 | const struct nls_table *nls_codepage, int remap) | 5951 | const struct nls_table *nls_codepage, int remap) |
5949 | { | 5952 | { |
@@ -5964,14 +5967,14 @@ setPermsRetry: | |||
5964 | 5967 | ||
5965 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { | 5968 | if (pSMB->hdr.Flags2 & SMBFLG2_UNICODE) { |
5966 | name_len = | 5969 | name_len = |
5967 | cifsConvertToUTF16((__le16 *) pSMB->FileName, fileName, | 5970 | cifsConvertToUTF16((__le16 *) pSMB->FileName, file_name, |
5968 | PATH_MAX, nls_codepage, remap); | 5971 | PATH_MAX, nls_codepage, remap); |
5969 | name_len++; /* trailing null */ | 5972 | name_len++; /* trailing null */ |
5970 | name_len *= 2; | 5973 | name_len *= 2; |
5971 | } else { /* BB improve the check for buffer overruns BB */ | 5974 | } else { /* BB improve the check for buffer overruns BB */ |
5972 | name_len = strnlen(fileName, PATH_MAX); | 5975 | name_len = strnlen(file_name, PATH_MAX); |
5973 | name_len++; /* trailing null */ | 5976 | name_len++; /* trailing null */ |
5974 | strncpy(pSMB->FileName, fileName, name_len); | 5977 | strncpy(pSMB->FileName, file_name, name_len); |
5975 | } | 5978 | } |
5976 | 5979 | ||
5977 | params = 6 + name_len; | 5980 | params = 6 + name_len; |
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c index 35cb6a374a45..7354877fa3bd 100644 --- a/fs/cifs/inode.c +++ b/fs/cifs/inode.c | |||
@@ -1219,16 +1219,153 @@ unlink_out: | |||
1219 | return rc; | 1219 | return rc; |
1220 | } | 1220 | } |
1221 | 1221 | ||
1222 | static int | ||
1223 | cifs_mkdir_qinfo(struct inode *inode, struct dentry *dentry, umode_t mode, | ||
1224 | const char *full_path, struct cifs_sb_info *cifs_sb, | ||
1225 | struct cifs_tcon *tcon, const unsigned int xid) | ||
1226 | { | ||
1227 | int rc = 0; | ||
1228 | struct inode *newinode = NULL; | ||
1229 | |||
1230 | if (tcon->unix_ext) | ||
1231 | rc = cifs_get_inode_info_unix(&newinode, full_path, inode->i_sb, | ||
1232 | xid); | ||
1233 | else | ||
1234 | rc = cifs_get_inode_info(&newinode, full_path, NULL, | ||
1235 | inode->i_sb, xid, NULL); | ||
1236 | if (rc) | ||
1237 | return rc; | ||
1238 | |||
1239 | d_instantiate(dentry, newinode); | ||
1240 | /* | ||
1241 | * setting nlink not necessary except in cases where we failed to get it | ||
1242 | * from the server or was set bogus | ||
1243 | */ | ||
1244 | if ((dentry->d_inode) && (dentry->d_inode->i_nlink < 2)) | ||
1245 | set_nlink(dentry->d_inode, 2); | ||
1246 | |||
1247 | mode &= ~current_umask(); | ||
1248 | /* must turn on setgid bit if parent dir has it */ | ||
1249 | if (inode->i_mode & S_ISGID) | ||
1250 | mode |= S_ISGID; | ||
1251 | |||
1252 | if (tcon->unix_ext) { | ||
1253 | struct cifs_unix_set_info_args args = { | ||
1254 | .mode = mode, | ||
1255 | .ctime = NO_CHANGE_64, | ||
1256 | .atime = NO_CHANGE_64, | ||
1257 | .mtime = NO_CHANGE_64, | ||
1258 | .device = 0, | ||
1259 | }; | ||
1260 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | ||
1261 | args.uid = (__u64)current_fsuid(); | ||
1262 | if (inode->i_mode & S_ISGID) | ||
1263 | args.gid = (__u64)inode->i_gid; | ||
1264 | else | ||
1265 | args.gid = (__u64)current_fsgid(); | ||
1266 | } else { | ||
1267 | args.uid = NO_CHANGE_64; | ||
1268 | args.gid = NO_CHANGE_64; | ||
1269 | } | ||
1270 | CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, | ||
1271 | cifs_sb->local_nls, | ||
1272 | cifs_sb->mnt_cifs_flags & | ||
1273 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1274 | } else { | ||
1275 | struct TCP_Server_Info *server = tcon->ses->server; | ||
1276 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && | ||
1277 | (mode & S_IWUGO) == 0 && server->ops->mkdir_setinfo) | ||
1278 | server->ops->mkdir_setinfo(newinode, full_path, cifs_sb, | ||
1279 | tcon, xid); | ||
1280 | if (dentry->d_inode) { | ||
1281 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM) | ||
1282 | dentry->d_inode->i_mode = (mode | S_IFDIR); | ||
1283 | |||
1284 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | ||
1285 | dentry->d_inode->i_uid = current_fsuid(); | ||
1286 | if (inode->i_mode & S_ISGID) | ||
1287 | dentry->d_inode->i_gid = inode->i_gid; | ||
1288 | else | ||
1289 | dentry->d_inode->i_gid = | ||
1290 | current_fsgid(); | ||
1291 | } | ||
1292 | } | ||
1293 | } | ||
1294 | return rc; | ||
1295 | } | ||
1296 | |||
1297 | static int | ||
1298 | cifs_posix_mkdir(struct inode *inode, struct dentry *dentry, umode_t mode, | ||
1299 | const char *full_path, struct cifs_sb_info *cifs_sb, | ||
1300 | struct cifs_tcon *tcon, const unsigned int xid) | ||
1301 | { | ||
1302 | int rc = 0; | ||
1303 | u32 oplock = 0; | ||
1304 | FILE_UNIX_BASIC_INFO *info = NULL; | ||
1305 | struct inode *newinode = NULL; | ||
1306 | struct cifs_fattr fattr; | ||
1307 | |||
1308 | info = kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); | ||
1309 | if (info == NULL) { | ||
1310 | rc = -ENOMEM; | ||
1311 | goto posix_mkdir_out; | ||
1312 | } | ||
1313 | |||
1314 | mode &= ~current_umask(); | ||
1315 | rc = CIFSPOSIXCreate(xid, tcon, SMB_O_DIRECTORY | SMB_O_CREAT, mode, | ||
1316 | NULL /* netfid */, info, &oplock, full_path, | ||
1317 | cifs_sb->local_nls, cifs_sb->mnt_cifs_flags & | ||
1318 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1319 | if (rc == -EOPNOTSUPP) | ||
1320 | goto posix_mkdir_out; | ||
1321 | else if (rc) { | ||
1322 | cFYI(1, "posix mkdir returned 0x%x", rc); | ||
1323 | d_drop(dentry); | ||
1324 | goto posix_mkdir_out; | ||
1325 | } | ||
1326 | |||
1327 | if (info->Type == cpu_to_le32(-1)) | ||
1328 | /* no return info, go query for it */ | ||
1329 | goto posix_mkdir_get_info; | ||
1330 | /* | ||
1331 | * BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if | ||
1332 | * need to set uid/gid. | ||
1333 | */ | ||
1334 | |||
1335 | cifs_unix_basic_to_fattr(&fattr, info, cifs_sb); | ||
1336 | cifs_fill_uniqueid(inode->i_sb, &fattr); | ||
1337 | newinode = cifs_iget(inode->i_sb, &fattr); | ||
1338 | if (!newinode) | ||
1339 | goto posix_mkdir_get_info; | ||
1340 | |||
1341 | d_instantiate(dentry, newinode); | ||
1342 | |||
1343 | #ifdef CONFIG_CIFS_DEBUG2 | ||
1344 | cFYI(1, "instantiated dentry %p %s to inode %p", dentry, | ||
1345 | dentry->d_name.name, newinode); | ||
1346 | |||
1347 | if (newinode->i_nlink != 2) | ||
1348 | cFYI(1, "unexpected number of links %d", newinode->i_nlink); | ||
1349 | #endif | ||
1350 | |||
1351 | posix_mkdir_out: | ||
1352 | kfree(info); | ||
1353 | return rc; | ||
1354 | posix_mkdir_get_info: | ||
1355 | rc = cifs_mkdir_qinfo(inode, dentry, mode, full_path, cifs_sb, tcon, | ||
1356 | xid); | ||
1357 | goto posix_mkdir_out; | ||
1358 | } | ||
1359 | |||
1222 | int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) | 1360 | int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) |
1223 | { | 1361 | { |
1224 | int rc = 0, tmprc; | 1362 | int rc = 0; |
1225 | unsigned int xid; | 1363 | unsigned int xid; |
1226 | struct cifs_sb_info *cifs_sb; | 1364 | struct cifs_sb_info *cifs_sb; |
1227 | struct tcon_link *tlink; | 1365 | struct tcon_link *tlink; |
1228 | struct cifs_tcon *tcon; | 1366 | struct cifs_tcon *tcon; |
1229 | char *full_path = NULL; | 1367 | struct TCP_Server_Info *server; |
1230 | struct inode *newinode = NULL; | 1368 | char *full_path; |
1231 | struct cifs_fattr fattr; | ||
1232 | 1369 | ||
1233 | cFYI(1, "In cifs_mkdir, mode = 0x%hx inode = 0x%p", mode, inode); | 1370 | cFYI(1, "In cifs_mkdir, mode = 0x%hx inode = 0x%p", mode, inode); |
1234 | 1371 | ||
@@ -1248,145 +1385,29 @@ int cifs_mkdir(struct inode *inode, struct dentry *direntry, umode_t mode) | |||
1248 | 1385 | ||
1249 | if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP & | 1386 | if (cap_unix(tcon->ses) && (CIFS_UNIX_POSIX_PATH_OPS_CAP & |
1250 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { | 1387 | le64_to_cpu(tcon->fsUnixInfo.Capability))) { |
1251 | u32 oplock = 0; | 1388 | rc = cifs_posix_mkdir(inode, direntry, mode, full_path, cifs_sb, |
1252 | FILE_UNIX_BASIC_INFO *pInfo = | 1389 | tcon, xid); |
1253 | kzalloc(sizeof(FILE_UNIX_BASIC_INFO), GFP_KERNEL); | 1390 | if (rc != -EOPNOTSUPP) |
1254 | if (pInfo == NULL) { | ||
1255 | rc = -ENOMEM; | ||
1256 | goto mkdir_out; | 1391 | goto mkdir_out; |
1257 | } | 1392 | } |
1258 | |||
1259 | mode &= ~current_umask(); | ||
1260 | rc = CIFSPOSIXCreate(xid, tcon, SMB_O_DIRECTORY | SMB_O_CREAT, | ||
1261 | mode, NULL /* netfid */, pInfo, &oplock, | ||
1262 | full_path, cifs_sb->local_nls, | ||
1263 | cifs_sb->mnt_cifs_flags & | ||
1264 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1265 | if (rc == -EOPNOTSUPP) { | ||
1266 | kfree(pInfo); | ||
1267 | goto mkdir_retry_old; | ||
1268 | } else if (rc) { | ||
1269 | cFYI(1, "posix mkdir returned 0x%x", rc); | ||
1270 | d_drop(direntry); | ||
1271 | } else { | ||
1272 | if (pInfo->Type == cpu_to_le32(-1)) { | ||
1273 | /* no return info, go query for it */ | ||
1274 | kfree(pInfo); | ||
1275 | goto mkdir_get_info; | ||
1276 | } | ||
1277 | /*BB check (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID ) to see if need | ||
1278 | to set uid/gid */ | ||
1279 | |||
1280 | cifs_unix_basic_to_fattr(&fattr, pInfo, cifs_sb); | ||
1281 | cifs_fill_uniqueid(inode->i_sb, &fattr); | ||
1282 | newinode = cifs_iget(inode->i_sb, &fattr); | ||
1283 | if (!newinode) { | ||
1284 | kfree(pInfo); | ||
1285 | goto mkdir_get_info; | ||
1286 | } | ||
1287 | |||
1288 | d_instantiate(direntry, newinode); | ||
1289 | 1393 | ||
1290 | #ifdef CONFIG_CIFS_DEBUG2 | 1394 | server = tcon->ses->server; |
1291 | cFYI(1, "instantiated dentry %p %s to inode %p", | ||
1292 | direntry, direntry->d_name.name, newinode); | ||
1293 | 1395 | ||
1294 | if (newinode->i_nlink != 2) | 1396 | if (!server->ops->mkdir) { |
1295 | cFYI(1, "unexpected number of links %d", | 1397 | rc = -ENOSYS; |
1296 | newinode->i_nlink); | ||
1297 | #endif | ||
1298 | } | ||
1299 | kfree(pInfo); | ||
1300 | goto mkdir_out; | 1398 | goto mkdir_out; |
1301 | } | 1399 | } |
1302 | mkdir_retry_old: | 1400 | |
1303 | /* BB add setting the equivalent of mode via CreateX w/ACLs */ | 1401 | /* BB add setting the equivalent of mode via CreateX w/ACLs */ |
1304 | rc = CIFSSMBMkDir(xid, tcon, full_path, cifs_sb->local_nls, | 1402 | rc = server->ops->mkdir(xid, tcon, full_path, cifs_sb); |
1305 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1306 | if (rc) { | 1403 | if (rc) { |
1307 | cFYI(1, "cifs_mkdir returned 0x%x", rc); | 1404 | cFYI(1, "cifs_mkdir returned 0x%x", rc); |
1308 | d_drop(direntry); | 1405 | d_drop(direntry); |
1309 | } else { | 1406 | goto mkdir_out; |
1310 | mkdir_get_info: | ||
1311 | if (tcon->unix_ext) | ||
1312 | rc = cifs_get_inode_info_unix(&newinode, full_path, | ||
1313 | inode->i_sb, xid); | ||
1314 | else | ||
1315 | rc = cifs_get_inode_info(&newinode, full_path, NULL, | ||
1316 | inode->i_sb, xid, NULL); | ||
1317 | |||
1318 | d_instantiate(direntry, newinode); | ||
1319 | /* setting nlink not necessary except in cases where we | ||
1320 | * failed to get it from the server or was set bogus */ | ||
1321 | if ((direntry->d_inode) && (direntry->d_inode->i_nlink < 2)) | ||
1322 | set_nlink(direntry->d_inode, 2); | ||
1323 | |||
1324 | mode &= ~current_umask(); | ||
1325 | /* must turn on setgid bit if parent dir has it */ | ||
1326 | if (inode->i_mode & S_ISGID) | ||
1327 | mode |= S_ISGID; | ||
1328 | |||
1329 | if (tcon->unix_ext) { | ||
1330 | struct cifs_unix_set_info_args args = { | ||
1331 | .mode = mode, | ||
1332 | .ctime = NO_CHANGE_64, | ||
1333 | .atime = NO_CHANGE_64, | ||
1334 | .mtime = NO_CHANGE_64, | ||
1335 | .device = 0, | ||
1336 | }; | ||
1337 | if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_SET_UID) { | ||
1338 | args.uid = (__u64)current_fsuid(); | ||
1339 | if (inode->i_mode & S_ISGID) | ||
1340 | args.gid = (__u64)inode->i_gid; | ||
1341 | else | ||
1342 | args.gid = (__u64)current_fsgid(); | ||
1343 | } else { | ||
1344 | args.uid = NO_CHANGE_64; | ||
1345 | args.gid = NO_CHANGE_64; | ||
1346 | } | ||
1347 | CIFSSMBUnixSetPathInfo(xid, tcon, full_path, &args, | ||
1348 | cifs_sb->local_nls, | ||
1349 | cifs_sb->mnt_cifs_flags & | ||
1350 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1351 | } else { | ||
1352 | if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_ACL) && | ||
1353 | (mode & S_IWUGO) == 0) { | ||
1354 | FILE_BASIC_INFO pInfo; | ||
1355 | struct cifsInodeInfo *cifsInode; | ||
1356 | u32 dosattrs; | ||
1357 | |||
1358 | memset(&pInfo, 0, sizeof(pInfo)); | ||
1359 | cifsInode = CIFS_I(newinode); | ||
1360 | dosattrs = cifsInode->cifsAttrs|ATTR_READONLY; | ||
1361 | pInfo.Attributes = cpu_to_le32(dosattrs); | ||
1362 | tmprc = CIFSSMBSetPathInfo(xid, tcon, | ||
1363 | full_path, &pInfo, | ||
1364 | cifs_sb->local_nls, | ||
1365 | cifs_sb->mnt_cifs_flags & | ||
1366 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1367 | if (tmprc == 0) | ||
1368 | cifsInode->cifsAttrs = dosattrs; | ||
1369 | } | ||
1370 | if (direntry->d_inode) { | ||
1371 | if (cifs_sb->mnt_cifs_flags & | ||
1372 | CIFS_MOUNT_DYNPERM) | ||
1373 | direntry->d_inode->i_mode = | ||
1374 | (mode | S_IFDIR); | ||
1375 | |||
1376 | if (cifs_sb->mnt_cifs_flags & | ||
1377 | CIFS_MOUNT_SET_UID) { | ||
1378 | direntry->d_inode->i_uid = | ||
1379 | current_fsuid(); | ||
1380 | if (inode->i_mode & S_ISGID) | ||
1381 | direntry->d_inode->i_gid = | ||
1382 | inode->i_gid; | ||
1383 | else | ||
1384 | direntry->d_inode->i_gid = | ||
1385 | current_fsgid(); | ||
1386 | } | ||
1387 | } | ||
1388 | } | ||
1389 | } | 1407 | } |
1408 | |||
1409 | rc = cifs_mkdir_qinfo(inode, direntry, mode, full_path, cifs_sb, tcon, | ||
1410 | xid); | ||
1390 | mkdir_out: | 1411 | mkdir_out: |
1391 | /* | 1412 | /* |
1392 | * Force revalidate to get parent dir info when needed since cached | 1413 | * Force revalidate to get parent dir info when needed since cached |
@@ -1405,7 +1426,8 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) | |||
1405 | unsigned int xid; | 1426 | unsigned int xid; |
1406 | struct cifs_sb_info *cifs_sb; | 1427 | struct cifs_sb_info *cifs_sb; |
1407 | struct tcon_link *tlink; | 1428 | struct tcon_link *tlink; |
1408 | struct cifs_tcon *pTcon; | 1429 | struct cifs_tcon *tcon; |
1430 | struct TCP_Server_Info *server; | ||
1409 | char *full_path = NULL; | 1431 | char *full_path = NULL; |
1410 | struct cifsInodeInfo *cifsInode; | 1432 | struct cifsInodeInfo *cifsInode; |
1411 | 1433 | ||
@@ -1425,10 +1447,16 @@ int cifs_rmdir(struct inode *inode, struct dentry *direntry) | |||
1425 | rc = PTR_ERR(tlink); | 1447 | rc = PTR_ERR(tlink); |
1426 | goto rmdir_exit; | 1448 | goto rmdir_exit; |
1427 | } | 1449 | } |
1428 | pTcon = tlink_tcon(tlink); | 1450 | tcon = tlink_tcon(tlink); |
1451 | server = tcon->ses->server; | ||
1452 | |||
1453 | if (!server->ops->rmdir) { | ||
1454 | rc = -ENOSYS; | ||
1455 | cifs_put_tlink(tlink); | ||
1456 | goto rmdir_exit; | ||
1457 | } | ||
1429 | 1458 | ||
1430 | rc = CIFSSMBRmDir(xid, pTcon, full_path, cifs_sb->local_nls, | 1459 | rc = server->ops->rmdir(xid, tcon, full_path, cifs_sb); |
1431 | cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
1432 | cifs_put_tlink(tlink); | 1460 | cifs_put_tlink(tlink); |
1433 | 1461 | ||
1434 | if (!rc) { | 1462 | if (!rc) { |
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c index c40356d24c5c..3129ac74b819 100644 --- a/fs/cifs/smb1ops.c +++ b/fs/cifs/smb1ops.c | |||
@@ -586,6 +586,27 @@ cifs_print_stats(struct seq_file *m, struct cifs_tcon *tcon) | |||
586 | #endif | 586 | #endif |
587 | } | 587 | } |
588 | 588 | ||
589 | static void | ||
590 | cifs_mkdir_setinfo(struct inode *inode, const char *full_path, | ||
591 | struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon, | ||
592 | const unsigned int xid) | ||
593 | { | ||
594 | FILE_BASIC_INFO info; | ||
595 | struct cifsInodeInfo *cifsInode; | ||
596 | u32 dosattrs; | ||
597 | int rc; | ||
598 | |||
599 | memset(&info, 0, sizeof(info)); | ||
600 | cifsInode = CIFS_I(inode); | ||
601 | dosattrs = cifsInode->cifsAttrs|ATTR_READONLY; | ||
602 | info.Attributes = cpu_to_le32(dosattrs); | ||
603 | rc = CIFSSMBSetPathInfo(xid, tcon, full_path, &info, cifs_sb->local_nls, | ||
604 | cifs_sb->mnt_cifs_flags & | ||
605 | CIFS_MOUNT_MAP_SPECIAL_CHR); | ||
606 | if (rc == 0) | ||
607 | cifsInode->cifsAttrs = dosattrs; | ||
608 | } | ||
609 | |||
589 | struct smb_version_operations smb1_operations = { | 610 | struct smb_version_operations smb1_operations = { |
590 | .send_cancel = send_nt_cancel, | 611 | .send_cancel = send_nt_cancel, |
591 | .compare_fids = cifs_compare_fids, | 612 | .compare_fids = cifs_compare_fids, |
@@ -620,6 +641,9 @@ struct smb_version_operations smb1_operations = { | |||
620 | .get_srv_inum = cifs_get_srv_inum, | 641 | .get_srv_inum = cifs_get_srv_inum, |
621 | .build_path_to_root = cifs_build_path_to_root, | 642 | .build_path_to_root = cifs_build_path_to_root, |
622 | .echo = CIFSSMBEcho, | 643 | .echo = CIFSSMBEcho, |
644 | .mkdir = CIFSSMBMkDir, | ||
645 | .mkdir_setinfo = cifs_mkdir_setinfo, | ||
646 | .rmdir = CIFSSMBRmDir, | ||
623 | }; | 647 | }; |
624 | 648 | ||
625 | struct smb_version_values smb1_values = { | 649 | struct smb_version_values smb1_values = { |
diff --git a/fs/cifs/smb2inode.c b/fs/cifs/smb2inode.c index 1ba5c405315c..2aa5cb08c526 100644 --- a/fs/cifs/smb2inode.c +++ b/fs/cifs/smb2inode.c | |||
@@ -122,3 +122,42 @@ out: | |||
122 | kfree(smb2_data); | 122 | kfree(smb2_data); |
123 | return rc; | 123 | return rc; |
124 | } | 124 | } |
125 | |||
126 | int | ||
127 | smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, | ||
128 | struct cifs_sb_info *cifs_sb) | ||
129 | { | ||
130 | return smb2_open_op_close(xid, tcon, cifs_sb, name, | ||
131 | FILE_WRITE_ATTRIBUTES, FILE_CREATE, 0, | ||
132 | CREATE_NOT_FILE, NULL, SMB2_OP_MKDIR); | ||
133 | } | ||
134 | |||
135 | void | ||
136 | smb2_mkdir_setinfo(struct inode *inode, const char *name, | ||
137 | struct cifs_sb_info *cifs_sb, struct cifs_tcon *tcon, | ||
138 | const unsigned int xid) | ||
139 | { | ||
140 | FILE_BASIC_INFO data; | ||
141 | struct cifsInodeInfo *cifs_i; | ||
142 | u32 dosattrs; | ||
143 | int tmprc; | ||
144 | |||
145 | memset(&data, 0, sizeof(data)); | ||
146 | cifs_i = CIFS_I(inode); | ||
147 | dosattrs = cifs_i->cifsAttrs | ATTR_READONLY; | ||
148 | data.Attributes = cpu_to_le32(dosattrs); | ||
149 | tmprc = smb2_open_op_close(xid, tcon, cifs_sb, name, | ||
150 | FILE_WRITE_ATTRIBUTES, FILE_CREATE, 0, | ||
151 | CREATE_NOT_FILE, &data, SMB2_OP_SET_INFO); | ||
152 | if (tmprc == 0) | ||
153 | cifs_i->cifsAttrs = dosattrs; | ||
154 | } | ||
155 | |||
156 | int | ||
157 | smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, const char *name, | ||
158 | struct cifs_sb_info *cifs_sb) | ||
159 | { | ||
160 | return smb2_open_op_close(xid, tcon, cifs_sb, name, DELETE, FILE_OPEN, | ||
161 | 0, CREATE_NOT_FILE | CREATE_DELETE_ON_CLOSE, | ||
162 | NULL, SMB2_OP_DELETE); | ||
163 | } | ||
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c index 410cf925ea26..826209bf3684 100644 --- a/fs/cifs/smb2ops.c +++ b/fs/cifs/smb2ops.c | |||
@@ -318,6 +318,9 @@ struct smb_version_operations smb21_operations = { | |||
318 | .query_path_info = smb2_query_path_info, | 318 | .query_path_info = smb2_query_path_info, |
319 | .get_srv_inum = smb2_get_srv_inum, | 319 | .get_srv_inum = smb2_get_srv_inum, |
320 | .build_path_to_root = smb2_build_path_to_root, | 320 | .build_path_to_root = smb2_build_path_to_root, |
321 | .mkdir = smb2_mkdir, | ||
322 | .mkdir_setinfo = smb2_mkdir_setinfo, | ||
323 | .rmdir = smb2_rmdir, | ||
321 | }; | 324 | }; |
322 | 325 | ||
323 | struct smb_version_values smb21_values = { | 326 | struct smb_version_values smb21_values = { |
diff --git a/fs/cifs/smb2proto.h b/fs/cifs/smb2proto.h index 902bbe2b5ad3..bfaa7b148afd 100644 --- a/fs/cifs/smb2proto.h +++ b/fs/cifs/smb2proto.h | |||
@@ -52,6 +52,14 @@ extern int smb2_query_path_info(const unsigned int xid, struct cifs_tcon *tcon, | |||
52 | struct cifs_sb_info *cifs_sb, | 52 | struct cifs_sb_info *cifs_sb, |
53 | const char *full_path, FILE_ALL_INFO *data, | 53 | const char *full_path, FILE_ALL_INFO *data, |
54 | bool *adjust_tz); | 54 | bool *adjust_tz); |
55 | extern int smb2_mkdir(const unsigned int xid, struct cifs_tcon *tcon, | ||
56 | const char *name, struct cifs_sb_info *cifs_sb); | ||
57 | extern void smb2_mkdir_setinfo(struct inode *inode, const char *full_path, | ||
58 | struct cifs_sb_info *cifs_sb, | ||
59 | struct cifs_tcon *tcon, const unsigned int xid); | ||
60 | extern int smb2_rmdir(const unsigned int xid, struct cifs_tcon *tcon, | ||
61 | const char *name, struct cifs_sb_info *cifs_sb); | ||
62 | |||
55 | /* | 63 | /* |
56 | * SMB2 Worker functions - most of protocol specific implementation details | 64 | * SMB2 Worker functions - most of protocol specific implementation details |
57 | * are contained within these calls. | 65 | * are contained within these calls. |
diff --git a/fs/compat.c b/fs/compat.c index 6161255fac45..1bdb350ea5d3 100644 --- a/fs/compat.c +++ b/fs/compat.c | |||
@@ -1155,11 +1155,14 @@ compat_sys_readv(unsigned long fd, const struct compat_iovec __user *vec, | |||
1155 | struct file *file; | 1155 | struct file *file; |
1156 | int fput_needed; | 1156 | int fput_needed; |
1157 | ssize_t ret; | 1157 | ssize_t ret; |
1158 | loff_t pos; | ||
1158 | 1159 | ||
1159 | file = fget_light(fd, &fput_needed); | 1160 | file = fget_light(fd, &fput_needed); |
1160 | if (!file) | 1161 | if (!file) |
1161 | return -EBADF; | 1162 | return -EBADF; |
1162 | ret = compat_readv(file, vec, vlen, &file->f_pos); | 1163 | pos = file->f_pos; |
1164 | ret = compat_readv(file, vec, vlen, &pos); | ||
1165 | file->f_pos = pos; | ||
1163 | fput_light(file, fput_needed); | 1166 | fput_light(file, fput_needed); |
1164 | return ret; | 1167 | return ret; |
1165 | } | 1168 | } |
@@ -1221,11 +1224,14 @@ compat_sys_writev(unsigned long fd, const struct compat_iovec __user *vec, | |||
1221 | struct file *file; | 1224 | struct file *file; |
1222 | int fput_needed; | 1225 | int fput_needed; |
1223 | ssize_t ret; | 1226 | ssize_t ret; |
1227 | loff_t pos; | ||
1224 | 1228 | ||
1225 | file = fget_light(fd, &fput_needed); | 1229 | file = fget_light(fd, &fput_needed); |
1226 | if (!file) | 1230 | if (!file) |
1227 | return -EBADF; | 1231 | return -EBADF; |
1228 | ret = compat_writev(file, vec, vlen, &file->f_pos); | 1232 | pos = file->f_pos; |
1233 | ret = compat_writev(file, vec, vlen, &pos); | ||
1234 | file->f_pos = pos; | ||
1229 | fput_light(file, fput_needed); | 1235 | fput_light(file, fput_needed); |
1230 | return ret; | 1236 | return ret; |
1231 | } | 1237 | } |
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h index 989e034f02bd..cfb4b9fed520 100644 --- a/fs/ecryptfs/ecryptfs_kernel.h +++ b/fs/ecryptfs/ecryptfs_kernel.h | |||
@@ -385,8 +385,6 @@ struct ecryptfs_msg_ctx { | |||
385 | struct mutex mux; | 385 | struct mutex mux; |
386 | }; | 386 | }; |
387 | 387 | ||
388 | struct ecryptfs_daemon; | ||
389 | |||
390 | struct ecryptfs_daemon { | 388 | struct ecryptfs_daemon { |
391 | #define ECRYPTFS_DAEMON_IN_READ 0x00000001 | 389 | #define ECRYPTFS_DAEMON_IN_READ 0x00000001 |
392 | #define ECRYPTFS_DAEMON_IN_POLL 0x00000002 | 390 | #define ECRYPTFS_DAEMON_IN_POLL 0x00000002 |
@@ -394,10 +392,7 @@ struct ecryptfs_daemon { | |||
394 | #define ECRYPTFS_DAEMON_MISCDEV_OPEN 0x00000008 | 392 | #define ECRYPTFS_DAEMON_MISCDEV_OPEN 0x00000008 |
395 | u32 flags; | 393 | u32 flags; |
396 | u32 num_queued_msg_ctx; | 394 | u32 num_queued_msg_ctx; |
397 | struct pid *pid; | 395 | struct file *file; |
398 | uid_t euid; | ||
399 | struct user_namespace *user_ns; | ||
400 | struct task_struct *task; | ||
401 | struct mutex mux; | 396 | struct mutex mux; |
402 | struct list_head msg_ctx_out_queue; | 397 | struct list_head msg_ctx_out_queue; |
403 | wait_queue_head_t wait; | 398 | wait_queue_head_t wait; |
@@ -554,6 +549,8 @@ extern struct kmem_cache *ecryptfs_key_tfm_cache; | |||
554 | struct inode *ecryptfs_get_inode(struct inode *lower_inode, | 549 | struct inode *ecryptfs_get_inode(struct inode *lower_inode, |
555 | struct super_block *sb); | 550 | struct super_block *sb); |
556 | void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); | 551 | void ecryptfs_i_size_init(const char *page_virt, struct inode *inode); |
552 | int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, | ||
553 | struct inode *ecryptfs_inode); | ||
557 | int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, | 554 | int ecryptfs_decode_and_decrypt_filename(char **decrypted_name, |
558 | size_t *decrypted_name_size, | 555 | size_t *decrypted_name_size, |
559 | struct dentry *ecryptfs_dentry, | 556 | struct dentry *ecryptfs_dentry, |
@@ -607,13 +604,8 @@ int | |||
607 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 604 | ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
608 | size_t size, int flags); | 605 | size_t size, int flags); |
609 | int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode); | 606 | int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode); |
610 | int ecryptfs_process_helo(uid_t euid, struct user_namespace *user_ns, | 607 | int ecryptfs_process_response(struct ecryptfs_daemon *daemon, |
611 | struct pid *pid); | 608 | struct ecryptfs_message *msg, u32 seq); |
612 | int ecryptfs_process_quit(uid_t euid, struct user_namespace *user_ns, | ||
613 | struct pid *pid); | ||
614 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | ||
615 | struct user_namespace *user_ns, struct pid *pid, | ||
616 | u32 seq); | ||
617 | int ecryptfs_send_message(char *data, int data_len, | 609 | int ecryptfs_send_message(char *data, int data_len, |
618 | struct ecryptfs_msg_ctx **msg_ctx); | 610 | struct ecryptfs_msg_ctx **msg_ctx); |
619 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, | 611 | int ecryptfs_wait_for_response(struct ecryptfs_msg_ctx *msg_ctx, |
@@ -658,8 +650,7 @@ int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs, | |||
658 | struct inode *ecryptfs_inode); | 650 | struct inode *ecryptfs_inode); |
659 | struct page *ecryptfs_get_locked_page(struct inode *inode, loff_t index); | 651 | struct page *ecryptfs_get_locked_page(struct inode *inode, loff_t index); |
660 | int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon); | 652 | int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon); |
661 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid, | 653 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon); |
662 | struct user_namespace *user_ns); | ||
663 | int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, | 654 | int ecryptfs_parse_packet_length(unsigned char *data, size_t *size, |
664 | size_t *length_size); | 655 | size_t *length_size); |
665 | int ecryptfs_write_packet_length(char *dest, size_t size, | 656 | int ecryptfs_write_packet_length(char *dest, size_t size, |
@@ -671,8 +662,7 @@ int ecryptfs_send_miscdev(char *data, size_t data_size, | |||
671 | u16 msg_flags, struct ecryptfs_daemon *daemon); | 662 | u16 msg_flags, struct ecryptfs_daemon *daemon); |
672 | void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx); | 663 | void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx); |
673 | int | 664 | int |
674 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, | 665 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, struct file *file); |
675 | struct user_namespace *user_ns, struct pid *pid); | ||
676 | int ecryptfs_init_kthread(void); | 666 | int ecryptfs_init_kthread(void); |
677 | void ecryptfs_destroy_kthread(void); | 667 | void ecryptfs_destroy_kthread(void); |
678 | int ecryptfs_privileged_open(struct file **lower_file, | 668 | int ecryptfs_privileged_open(struct file **lower_file, |
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c index 2b17f2f9b121..44ce5c6a541d 100644 --- a/fs/ecryptfs/file.c +++ b/fs/ecryptfs/file.c | |||
@@ -138,29 +138,50 @@ out: | |||
138 | return rc; | 138 | return rc; |
139 | } | 139 | } |
140 | 140 | ||
141 | static void ecryptfs_vma_close(struct vm_area_struct *vma) | 141 | struct kmem_cache *ecryptfs_file_info_cache; |
142 | { | ||
143 | filemap_write_and_wait(vma->vm_file->f_mapping); | ||
144 | } | ||
145 | |||
146 | static const struct vm_operations_struct ecryptfs_file_vm_ops = { | ||
147 | .close = ecryptfs_vma_close, | ||
148 | .fault = filemap_fault, | ||
149 | }; | ||
150 | 142 | ||
151 | static int ecryptfs_file_mmap(struct file *file, struct vm_area_struct *vma) | 143 | static int read_or_initialize_metadata(struct dentry *dentry) |
152 | { | 144 | { |
145 | struct inode *inode = dentry->d_inode; | ||
146 | struct ecryptfs_mount_crypt_stat *mount_crypt_stat; | ||
147 | struct ecryptfs_crypt_stat *crypt_stat; | ||
153 | int rc; | 148 | int rc; |
154 | 149 | ||
155 | rc = generic_file_mmap(file, vma); | 150 | crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; |
151 | mount_crypt_stat = &ecryptfs_superblock_to_private( | ||
152 | inode->i_sb)->mount_crypt_stat; | ||
153 | mutex_lock(&crypt_stat->cs_mutex); | ||
154 | |||
155 | if (crypt_stat->flags & ECRYPTFS_POLICY_APPLIED && | ||
156 | crypt_stat->flags & ECRYPTFS_KEY_VALID) { | ||
157 | rc = 0; | ||
158 | goto out; | ||
159 | } | ||
160 | |||
161 | rc = ecryptfs_read_metadata(dentry); | ||
156 | if (!rc) | 162 | if (!rc) |
157 | vma->vm_ops = &ecryptfs_file_vm_ops; | 163 | goto out; |
164 | |||
165 | if (mount_crypt_stat->flags & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED) { | ||
166 | crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED | ||
167 | | ECRYPTFS_ENCRYPTED); | ||
168 | rc = 0; | ||
169 | goto out; | ||
170 | } | ||
158 | 171 | ||
172 | if (!(mount_crypt_stat->flags & ECRYPTFS_XATTR_METADATA_ENABLED) && | ||
173 | !i_size_read(ecryptfs_inode_to_lower(inode))) { | ||
174 | rc = ecryptfs_initialize_file(dentry, inode); | ||
175 | if (!rc) | ||
176 | goto out; | ||
177 | } | ||
178 | |||
179 | rc = -EIO; | ||
180 | out: | ||
181 | mutex_unlock(&crypt_stat->cs_mutex); | ||
159 | return rc; | 182 | return rc; |
160 | } | 183 | } |
161 | 184 | ||
162 | struct kmem_cache *ecryptfs_file_info_cache; | ||
163 | |||
164 | /** | 185 | /** |
165 | * ecryptfs_open | 186 | * ecryptfs_open |
166 | * @inode: inode speciying file to open | 187 | * @inode: inode speciying file to open |
@@ -236,32 +257,9 @@ static int ecryptfs_open(struct inode *inode, struct file *file) | |||
236 | rc = 0; | 257 | rc = 0; |
237 | goto out; | 258 | goto out; |
238 | } | 259 | } |
239 | mutex_lock(&crypt_stat->cs_mutex); | 260 | rc = read_or_initialize_metadata(ecryptfs_dentry); |
240 | if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) | 261 | if (rc) |
241 | || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { | 262 | goto out_put; |
242 | rc = ecryptfs_read_metadata(ecryptfs_dentry); | ||
243 | if (rc) { | ||
244 | ecryptfs_printk(KERN_DEBUG, | ||
245 | "Valid headers not found\n"); | ||
246 | if (!(mount_crypt_stat->flags | ||
247 | & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { | ||
248 | rc = -EIO; | ||
249 | printk(KERN_WARNING "Either the lower file " | ||
250 | "is not in a valid eCryptfs format, " | ||
251 | "or the key could not be retrieved. " | ||
252 | "Plaintext passthrough mode is not " | ||
253 | "enabled; returning -EIO\n"); | ||
254 | mutex_unlock(&crypt_stat->cs_mutex); | ||
255 | goto out_put; | ||
256 | } | ||
257 | rc = 0; | ||
258 | crypt_stat->flags &= ~(ECRYPTFS_I_SIZE_INITIALIZED | ||
259 | | ECRYPTFS_ENCRYPTED); | ||
260 | mutex_unlock(&crypt_stat->cs_mutex); | ||
261 | goto out; | ||
262 | } | ||
263 | } | ||
264 | mutex_unlock(&crypt_stat->cs_mutex); | ||
265 | ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = " | 263 | ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = " |
266 | "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, | 264 | "[0x%.16lx] size: [0x%.16llx]\n", inode, inode->i_ino, |
267 | (unsigned long long)i_size_read(inode)); | 265 | (unsigned long long)i_size_read(inode)); |
@@ -292,15 +290,7 @@ static int ecryptfs_release(struct inode *inode, struct file *file) | |||
292 | static int | 290 | static int |
293 | ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) | 291 | ecryptfs_fsync(struct file *file, loff_t start, loff_t end, int datasync) |
294 | { | 292 | { |
295 | int rc = 0; | 293 | return vfs_fsync(ecryptfs_file_to_lower(file), datasync); |
296 | |||
297 | rc = generic_file_fsync(file, start, end, datasync); | ||
298 | if (rc) | ||
299 | goto out; | ||
300 | rc = vfs_fsync_range(ecryptfs_file_to_lower(file), start, end, | ||
301 | datasync); | ||
302 | out: | ||
303 | return rc; | ||
304 | } | 294 | } |
305 | 295 | ||
306 | static int ecryptfs_fasync(int fd, struct file *file, int flag) | 296 | static int ecryptfs_fasync(int fd, struct file *file, int flag) |
@@ -369,7 +359,7 @@ const struct file_operations ecryptfs_main_fops = { | |||
369 | #ifdef CONFIG_COMPAT | 359 | #ifdef CONFIG_COMPAT |
370 | .compat_ioctl = ecryptfs_compat_ioctl, | 360 | .compat_ioctl = ecryptfs_compat_ioctl, |
371 | #endif | 361 | #endif |
372 | .mmap = ecryptfs_file_mmap, | 362 | .mmap = generic_file_mmap, |
373 | .open = ecryptfs_open, | 363 | .open = ecryptfs_open, |
374 | .flush = ecryptfs_flush, | 364 | .flush = ecryptfs_flush, |
375 | .release = ecryptfs_release, | 365 | .release = ecryptfs_release, |
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c index c3ca12c33ca2..534b129ea676 100644 --- a/fs/ecryptfs/inode.c +++ b/fs/ecryptfs/inode.c | |||
@@ -143,6 +143,31 @@ static int ecryptfs_interpose(struct dentry *lower_dentry, | |||
143 | return 0; | 143 | return 0; |
144 | } | 144 | } |
145 | 145 | ||
146 | static int ecryptfs_do_unlink(struct inode *dir, struct dentry *dentry, | ||
147 | struct inode *inode) | ||
148 | { | ||
149 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
150 | struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); | ||
151 | struct dentry *lower_dir_dentry; | ||
152 | int rc; | ||
153 | |||
154 | dget(lower_dentry); | ||
155 | lower_dir_dentry = lock_parent(lower_dentry); | ||
156 | rc = vfs_unlink(lower_dir_inode, lower_dentry); | ||
157 | if (rc) { | ||
158 | printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); | ||
159 | goto out_unlock; | ||
160 | } | ||
161 | fsstack_copy_attr_times(dir, lower_dir_inode); | ||
162 | set_nlink(inode, ecryptfs_inode_to_lower(inode)->i_nlink); | ||
163 | inode->i_ctime = dir->i_ctime; | ||
164 | d_drop(dentry); | ||
165 | out_unlock: | ||
166 | unlock_dir(lower_dir_dentry); | ||
167 | dput(lower_dentry); | ||
168 | return rc; | ||
169 | } | ||
170 | |||
146 | /** | 171 | /** |
147 | * ecryptfs_do_create | 172 | * ecryptfs_do_create |
148 | * @directory_inode: inode of the new file's dentry's parent in ecryptfs | 173 | * @directory_inode: inode of the new file's dentry's parent in ecryptfs |
@@ -182,8 +207,10 @@ ecryptfs_do_create(struct inode *directory_inode, | |||
182 | } | 207 | } |
183 | inode = __ecryptfs_get_inode(lower_dentry->d_inode, | 208 | inode = __ecryptfs_get_inode(lower_dentry->d_inode, |
184 | directory_inode->i_sb); | 209 | directory_inode->i_sb); |
185 | if (IS_ERR(inode)) | 210 | if (IS_ERR(inode)) { |
211 | vfs_unlink(lower_dir_dentry->d_inode, lower_dentry); | ||
186 | goto out_lock; | 212 | goto out_lock; |
213 | } | ||
187 | fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); | 214 | fsstack_copy_attr_times(directory_inode, lower_dir_dentry->d_inode); |
188 | fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode); | 215 | fsstack_copy_inode_size(directory_inode, lower_dir_dentry->d_inode); |
189 | out_lock: | 216 | out_lock: |
@@ -200,8 +227,8 @@ out: | |||
200 | * | 227 | * |
201 | * Returns zero on success | 228 | * Returns zero on success |
202 | */ | 229 | */ |
203 | static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, | 230 | int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry, |
204 | struct inode *ecryptfs_inode) | 231 | struct inode *ecryptfs_inode) |
205 | { | 232 | { |
206 | struct ecryptfs_crypt_stat *crypt_stat = | 233 | struct ecryptfs_crypt_stat *crypt_stat = |
207 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; | 234 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
@@ -264,7 +291,9 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry, | |||
264 | * that this on disk file is prepared to be an ecryptfs file */ | 291 | * that this on disk file is prepared to be an ecryptfs file */ |
265 | rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode); | 292 | rc = ecryptfs_initialize_file(ecryptfs_dentry, ecryptfs_inode); |
266 | if (rc) { | 293 | if (rc) { |
267 | drop_nlink(ecryptfs_inode); | 294 | ecryptfs_do_unlink(directory_inode, ecryptfs_dentry, |
295 | ecryptfs_inode); | ||
296 | make_bad_inode(ecryptfs_inode); | ||
268 | unlock_new_inode(ecryptfs_inode); | 297 | unlock_new_inode(ecryptfs_inode); |
269 | iput(ecryptfs_inode); | 298 | iput(ecryptfs_inode); |
270 | goto out; | 299 | goto out; |
@@ -466,27 +495,7 @@ out_lock: | |||
466 | 495 | ||
467 | static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) | 496 | static int ecryptfs_unlink(struct inode *dir, struct dentry *dentry) |
468 | { | 497 | { |
469 | int rc = 0; | 498 | return ecryptfs_do_unlink(dir, dentry, dentry->d_inode); |
470 | struct dentry *lower_dentry = ecryptfs_dentry_to_lower(dentry); | ||
471 | struct inode *lower_dir_inode = ecryptfs_inode_to_lower(dir); | ||
472 | struct dentry *lower_dir_dentry; | ||
473 | |||
474 | dget(lower_dentry); | ||
475 | lower_dir_dentry = lock_parent(lower_dentry); | ||
476 | rc = vfs_unlink(lower_dir_inode, lower_dentry); | ||
477 | if (rc) { | ||
478 | printk(KERN_ERR "Error in vfs_unlink; rc = [%d]\n", rc); | ||
479 | goto out_unlock; | ||
480 | } | ||
481 | fsstack_copy_attr_times(dir, lower_dir_inode); | ||
482 | set_nlink(dentry->d_inode, | ||
483 | ecryptfs_inode_to_lower(dentry->d_inode)->i_nlink); | ||
484 | dentry->d_inode->i_ctime = dir->i_ctime; | ||
485 | d_drop(dentry); | ||
486 | out_unlock: | ||
487 | unlock_dir(lower_dir_dentry); | ||
488 | dput(lower_dentry); | ||
489 | return rc; | ||
490 | } | 499 | } |
491 | 500 | ||
492 | static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, | 501 | static int ecryptfs_symlink(struct inode *dir, struct dentry *dentry, |
@@ -961,12 +970,6 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia) | |||
961 | goto out; | 970 | goto out; |
962 | } | 971 | } |
963 | 972 | ||
964 | if (S_ISREG(inode->i_mode)) { | ||
965 | rc = filemap_write_and_wait(inode->i_mapping); | ||
966 | if (rc) | ||
967 | goto out; | ||
968 | fsstack_copy_attr_all(inode, lower_inode); | ||
969 | } | ||
970 | memcpy(&lower_ia, ia, sizeof(lower_ia)); | 973 | memcpy(&lower_ia, ia, sizeof(lower_ia)); |
971 | if (ia->ia_valid & ATTR_FILE) | 974 | if (ia->ia_valid & ATTR_FILE) |
972 | lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); | 975 | lower_ia.ia_file = ecryptfs_file_to_lower(ia->ia_file); |
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c index 1c0b3b6b75c6..2768138eefee 100644 --- a/fs/ecryptfs/main.c +++ b/fs/ecryptfs/main.c | |||
@@ -279,6 +279,7 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, | |||
279 | char *fnek_src; | 279 | char *fnek_src; |
280 | char *cipher_key_bytes_src; | 280 | char *cipher_key_bytes_src; |
281 | char *fn_cipher_key_bytes_src; | 281 | char *fn_cipher_key_bytes_src; |
282 | u8 cipher_code; | ||
282 | 283 | ||
283 | *check_ruid = 0; | 284 | *check_ruid = 0; |
284 | 285 | ||
@@ -420,6 +421,18 @@ static int ecryptfs_parse_options(struct ecryptfs_sb_info *sbi, char *options, | |||
420 | && !fn_cipher_key_bytes_set) | 421 | && !fn_cipher_key_bytes_set) |
421 | mount_crypt_stat->global_default_fn_cipher_key_bytes = | 422 | mount_crypt_stat->global_default_fn_cipher_key_bytes = |
422 | mount_crypt_stat->global_default_cipher_key_size; | 423 | mount_crypt_stat->global_default_cipher_key_size; |
424 | |||
425 | cipher_code = ecryptfs_code_for_cipher_string( | ||
426 | mount_crypt_stat->global_default_cipher_name, | ||
427 | mount_crypt_stat->global_default_cipher_key_size); | ||
428 | if (!cipher_code) { | ||
429 | ecryptfs_printk(KERN_ERR, | ||
430 | "eCryptfs doesn't support cipher: %s", | ||
431 | mount_crypt_stat->global_default_cipher_name); | ||
432 | rc = -EINVAL; | ||
433 | goto out; | ||
434 | } | ||
435 | |||
423 | mutex_lock(&key_tfm_list_mutex); | 436 | mutex_lock(&key_tfm_list_mutex); |
424 | if (!ecryptfs_tfm_exists(mount_crypt_stat->global_default_cipher_name, | 437 | if (!ecryptfs_tfm_exists(mount_crypt_stat->global_default_cipher_name, |
425 | NULL)) { | 438 | NULL)) { |
@@ -540,6 +553,15 @@ static struct dentry *ecryptfs_mount(struct file_system_type *fs_type, int flags | |||
540 | } | 553 | } |
541 | 554 | ||
542 | ecryptfs_set_superblock_lower(s, path.dentry->d_sb); | 555 | ecryptfs_set_superblock_lower(s, path.dentry->d_sb); |
556 | |||
557 | /** | ||
558 | * Set the POSIX ACL flag based on whether they're enabled in the lower | ||
559 | * mount. Force a read-only eCryptfs mount if the lower mount is ro. | ||
560 | * Allow a ro eCryptfs mount even when the lower mount is rw. | ||
561 | */ | ||
562 | s->s_flags = flags & ~MS_POSIXACL; | ||
563 | s->s_flags |= path.dentry->d_sb->s_flags & (MS_RDONLY | MS_POSIXACL); | ||
564 | |||
543 | s->s_maxbytes = path.dentry->d_sb->s_maxbytes; | 565 | s->s_maxbytes = path.dentry->d_sb->s_maxbytes; |
544 | s->s_blocksize = path.dentry->d_sb->s_blocksize; | 566 | s->s_blocksize = path.dentry->d_sb->s_blocksize; |
545 | s->s_magic = ECRYPTFS_SUPER_MAGIC; | 567 | s->s_magic = ECRYPTFS_SUPER_MAGIC; |
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c index a750f957b145..b29bb8bfa8d9 100644 --- a/fs/ecryptfs/messaging.c +++ b/fs/ecryptfs/messaging.c | |||
@@ -32,8 +32,8 @@ static struct mutex ecryptfs_msg_ctx_lists_mux; | |||
32 | static struct hlist_head *ecryptfs_daemon_hash; | 32 | static struct hlist_head *ecryptfs_daemon_hash; |
33 | struct mutex ecryptfs_daemon_hash_mux; | 33 | struct mutex ecryptfs_daemon_hash_mux; |
34 | static int ecryptfs_hash_bits; | 34 | static int ecryptfs_hash_bits; |
35 | #define ecryptfs_uid_hash(uid) \ | 35 | #define ecryptfs_current_euid_hash(uid) \ |
36 | hash_long((unsigned long)uid, ecryptfs_hash_bits) | 36 | hash_long((unsigned long)current_euid(), ecryptfs_hash_bits) |
37 | 37 | ||
38 | static u32 ecryptfs_msg_counter; | 38 | static u32 ecryptfs_msg_counter; |
39 | static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; | 39 | static struct ecryptfs_msg_ctx *ecryptfs_msg_ctx_arr; |
@@ -105,26 +105,24 @@ void ecryptfs_msg_ctx_alloc_to_free(struct ecryptfs_msg_ctx *msg_ctx) | |||
105 | 105 | ||
106 | /** | 106 | /** |
107 | * ecryptfs_find_daemon_by_euid | 107 | * ecryptfs_find_daemon_by_euid |
108 | * @euid: The effective user id which maps to the desired daemon id | ||
109 | * @user_ns: The namespace in which @euid applies | ||
110 | * @daemon: If return value is zero, points to the desired daemon pointer | 108 | * @daemon: If return value is zero, points to the desired daemon pointer |
111 | * | 109 | * |
112 | * Must be called with ecryptfs_daemon_hash_mux held. | 110 | * Must be called with ecryptfs_daemon_hash_mux held. |
113 | * | 111 | * |
114 | * Search the hash list for the given user id. | 112 | * Search the hash list for the current effective user id. |
115 | * | 113 | * |
116 | * Returns zero if the user id exists in the list; non-zero otherwise. | 114 | * Returns zero if the user id exists in the list; non-zero otherwise. |
117 | */ | 115 | */ |
118 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon, uid_t euid, | 116 | int ecryptfs_find_daemon_by_euid(struct ecryptfs_daemon **daemon) |
119 | struct user_namespace *user_ns) | ||
120 | { | 117 | { |
121 | struct hlist_node *elem; | 118 | struct hlist_node *elem; |
122 | int rc; | 119 | int rc; |
123 | 120 | ||
124 | hlist_for_each_entry(*daemon, elem, | 121 | hlist_for_each_entry(*daemon, elem, |
125 | &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)], | 122 | &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()], |
126 | euid_chain) { | 123 | euid_chain) { |
127 | if ((*daemon)->euid == euid && (*daemon)->user_ns == user_ns) { | 124 | if ((*daemon)->file->f_cred->euid == current_euid() && |
125 | (*daemon)->file->f_cred->user_ns == current_user_ns()) { | ||
128 | rc = 0; | 126 | rc = 0; |
129 | goto out; | 127 | goto out; |
130 | } | 128 | } |
@@ -137,9 +135,7 @@ out: | |||
137 | /** | 135 | /** |
138 | * ecryptfs_spawn_daemon - Create and initialize a new daemon struct | 136 | * ecryptfs_spawn_daemon - Create and initialize a new daemon struct |
139 | * @daemon: Pointer to set to newly allocated daemon struct | 137 | * @daemon: Pointer to set to newly allocated daemon struct |
140 | * @euid: Effective user id for the daemon | 138 | * @file: File used when opening /dev/ecryptfs |
141 | * @user_ns: The namespace in which @euid applies | ||
142 | * @pid: Process id for the daemon | ||
143 | * | 139 | * |
144 | * Must be called ceremoniously while in possession of | 140 | * Must be called ceremoniously while in possession of |
145 | * ecryptfs_sacred_daemon_hash_mux | 141 | * ecryptfs_sacred_daemon_hash_mux |
@@ -147,8 +143,7 @@ out: | |||
147 | * Returns zero on success; non-zero otherwise | 143 | * Returns zero on success; non-zero otherwise |
148 | */ | 144 | */ |
149 | int | 145 | int |
150 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, | 146 | ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, struct file *file) |
151 | struct user_namespace *user_ns, struct pid *pid) | ||
152 | { | 147 | { |
153 | int rc = 0; | 148 | int rc = 0; |
154 | 149 | ||
@@ -159,16 +154,13 @@ ecryptfs_spawn_daemon(struct ecryptfs_daemon **daemon, uid_t euid, | |||
159 | "GFP_KERNEL memory\n", __func__, sizeof(**daemon)); | 154 | "GFP_KERNEL memory\n", __func__, sizeof(**daemon)); |
160 | goto out; | 155 | goto out; |
161 | } | 156 | } |
162 | (*daemon)->euid = euid; | 157 | (*daemon)->file = file; |
163 | (*daemon)->user_ns = get_user_ns(user_ns); | ||
164 | (*daemon)->pid = get_pid(pid); | ||
165 | (*daemon)->task = current; | ||
166 | mutex_init(&(*daemon)->mux); | 158 | mutex_init(&(*daemon)->mux); |
167 | INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue); | 159 | INIT_LIST_HEAD(&(*daemon)->msg_ctx_out_queue); |
168 | init_waitqueue_head(&(*daemon)->wait); | 160 | init_waitqueue_head(&(*daemon)->wait); |
169 | (*daemon)->num_queued_msg_ctx = 0; | 161 | (*daemon)->num_queued_msg_ctx = 0; |
170 | hlist_add_head(&(*daemon)->euid_chain, | 162 | hlist_add_head(&(*daemon)->euid_chain, |
171 | &ecryptfs_daemon_hash[ecryptfs_uid_hash(euid)]); | 163 | &ecryptfs_daemon_hash[ecryptfs_current_euid_hash()]); |
172 | out: | 164 | out: |
173 | return rc; | 165 | return rc; |
174 | } | 166 | } |
@@ -188,9 +180,6 @@ int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon) | |||
188 | if ((daemon->flags & ECRYPTFS_DAEMON_IN_READ) | 180 | if ((daemon->flags & ECRYPTFS_DAEMON_IN_READ) |
189 | || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) { | 181 | || (daemon->flags & ECRYPTFS_DAEMON_IN_POLL)) { |
190 | rc = -EBUSY; | 182 | rc = -EBUSY; |
191 | printk(KERN_WARNING "%s: Attempt to destroy daemon with pid " | ||
192 | "[0x%p], but it is in the midst of a read or a poll\n", | ||
193 | __func__, daemon->pid); | ||
194 | mutex_unlock(&daemon->mux); | 183 | mutex_unlock(&daemon->mux); |
195 | goto out; | 184 | goto out; |
196 | } | 185 | } |
@@ -203,12 +192,6 @@ int ecryptfs_exorcise_daemon(struct ecryptfs_daemon *daemon) | |||
203 | ecryptfs_msg_ctx_alloc_to_free(msg_ctx); | 192 | ecryptfs_msg_ctx_alloc_to_free(msg_ctx); |
204 | } | 193 | } |
205 | hlist_del(&daemon->euid_chain); | 194 | hlist_del(&daemon->euid_chain); |
206 | if (daemon->task) | ||
207 | wake_up_process(daemon->task); | ||
208 | if (daemon->pid) | ||
209 | put_pid(daemon->pid); | ||
210 | if (daemon->user_ns) | ||
211 | put_user_ns(daemon->user_ns); | ||
212 | mutex_unlock(&daemon->mux); | 195 | mutex_unlock(&daemon->mux); |
213 | kzfree(daemon); | 196 | kzfree(daemon); |
214 | out: | 197 | out: |
@@ -216,42 +199,9 @@ out: | |||
216 | } | 199 | } |
217 | 200 | ||
218 | /** | 201 | /** |
219 | * ecryptfs_process_quit | ||
220 | * @euid: The user ID owner of the message | ||
221 | * @user_ns: The namespace in which @euid applies | ||
222 | * @pid: The process ID for the userspace program that sent the | ||
223 | * message | ||
224 | * | ||
225 | * Deletes the corresponding daemon for the given euid and pid, if | ||
226 | * it is the registered that is requesting the deletion. Returns zero | ||
227 | * after deleting the desired daemon; non-zero otherwise. | ||
228 | */ | ||
229 | int ecryptfs_process_quit(uid_t euid, struct user_namespace *user_ns, | ||
230 | struct pid *pid) | ||
231 | { | ||
232 | struct ecryptfs_daemon *daemon; | ||
233 | int rc; | ||
234 | |||
235 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
236 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, user_ns); | ||
237 | if (rc || !daemon) { | ||
238 | rc = -EINVAL; | ||
239 | printk(KERN_ERR "Received request from user [%d] to " | ||
240 | "unregister unrecognized daemon [0x%p]\n", euid, pid); | ||
241 | goto out_unlock; | ||
242 | } | ||
243 | rc = ecryptfs_exorcise_daemon(daemon); | ||
244 | out_unlock: | ||
245 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
246 | return rc; | ||
247 | } | ||
248 | |||
249 | /** | ||
250 | * ecryptfs_process_reponse | 202 | * ecryptfs_process_reponse |
251 | * @msg: The ecryptfs message received; the caller should sanity check | 203 | * @msg: The ecryptfs message received; the caller should sanity check |
252 | * msg->data_len and free the memory | 204 | * msg->data_len and free the memory |
253 | * @pid: The process ID of the userspace application that sent the | ||
254 | * message | ||
255 | * @seq: The sequence number of the message; must match the sequence | 205 | * @seq: The sequence number of the message; must match the sequence |
256 | * number for the existing message context waiting for this | 206 | * number for the existing message context waiting for this |
257 | * response | 207 | * response |
@@ -270,16 +220,11 @@ out_unlock: | |||
270 | * | 220 | * |
271 | * Returns zero on success; non-zero otherwise | 221 | * Returns zero on success; non-zero otherwise |
272 | */ | 222 | */ |
273 | int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | 223 | int ecryptfs_process_response(struct ecryptfs_daemon *daemon, |
274 | struct user_namespace *user_ns, struct pid *pid, | 224 | struct ecryptfs_message *msg, u32 seq) |
275 | u32 seq) | ||
276 | { | 225 | { |
277 | struct ecryptfs_daemon *uninitialized_var(daemon); | ||
278 | struct ecryptfs_msg_ctx *msg_ctx; | 226 | struct ecryptfs_msg_ctx *msg_ctx; |
279 | size_t msg_size; | 227 | size_t msg_size; |
280 | struct nsproxy *nsproxy; | ||
281 | struct user_namespace *tsk_user_ns; | ||
282 | uid_t ctx_euid; | ||
283 | int rc; | 228 | int rc; |
284 | 229 | ||
285 | if (msg->index >= ecryptfs_message_buf_len) { | 230 | if (msg->index >= ecryptfs_message_buf_len) { |
@@ -292,51 +237,6 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | |||
292 | } | 237 | } |
293 | msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; | 238 | msg_ctx = &ecryptfs_msg_ctx_arr[msg->index]; |
294 | mutex_lock(&msg_ctx->mux); | 239 | mutex_lock(&msg_ctx->mux); |
295 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
296 | rcu_read_lock(); | ||
297 | nsproxy = task_nsproxy(msg_ctx->task); | ||
298 | if (nsproxy == NULL) { | ||
299 | rc = -EBADMSG; | ||
300 | printk(KERN_ERR "%s: Receiving process is a zombie. Dropping " | ||
301 | "message.\n", __func__); | ||
302 | rcu_read_unlock(); | ||
303 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
304 | goto wake_up; | ||
305 | } | ||
306 | tsk_user_ns = __task_cred(msg_ctx->task)->user_ns; | ||
307 | ctx_euid = task_euid(msg_ctx->task); | ||
308 | rc = ecryptfs_find_daemon_by_euid(&daemon, ctx_euid, tsk_user_ns); | ||
309 | rcu_read_unlock(); | ||
310 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
311 | if (rc) { | ||
312 | rc = -EBADMSG; | ||
313 | printk(KERN_WARNING "%s: User [%d] received a " | ||
314 | "message response from process [0x%p] but does " | ||
315 | "not have a registered daemon\n", __func__, | ||
316 | ctx_euid, pid); | ||
317 | goto wake_up; | ||
318 | } | ||
319 | if (ctx_euid != euid) { | ||
320 | rc = -EBADMSG; | ||
321 | printk(KERN_WARNING "%s: Received message from user " | ||
322 | "[%d]; expected message from user [%d]\n", __func__, | ||
323 | euid, ctx_euid); | ||
324 | goto unlock; | ||
325 | } | ||
326 | if (tsk_user_ns != user_ns) { | ||
327 | rc = -EBADMSG; | ||
328 | printk(KERN_WARNING "%s: Received message from user_ns " | ||
329 | "[0x%p]; expected message from user_ns [0x%p]\n", | ||
330 | __func__, user_ns, tsk_user_ns); | ||
331 | goto unlock; | ||
332 | } | ||
333 | if (daemon->pid != pid) { | ||
334 | rc = -EBADMSG; | ||
335 | printk(KERN_ERR "%s: User [%d] sent a message response " | ||
336 | "from an unrecognized process [0x%p]\n", | ||
337 | __func__, ctx_euid, pid); | ||
338 | goto unlock; | ||
339 | } | ||
340 | if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) { | 240 | if (msg_ctx->state != ECRYPTFS_MSG_CTX_STATE_PENDING) { |
341 | rc = -EINVAL; | 241 | rc = -EINVAL; |
342 | printk(KERN_WARNING "%s: Desired context element is not " | 242 | printk(KERN_WARNING "%s: Desired context element is not " |
@@ -359,9 +259,8 @@ int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t euid, | |||
359 | } | 259 | } |
360 | memcpy(msg_ctx->msg, msg, msg_size); | 260 | memcpy(msg_ctx->msg, msg, msg_size); |
361 | msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_DONE; | 261 | msg_ctx->state = ECRYPTFS_MSG_CTX_STATE_DONE; |
362 | rc = 0; | ||
363 | wake_up: | ||
364 | wake_up_process(msg_ctx->task); | 262 | wake_up_process(msg_ctx->task); |
263 | rc = 0; | ||
365 | unlock: | 264 | unlock: |
366 | mutex_unlock(&msg_ctx->mux); | 265 | mutex_unlock(&msg_ctx->mux); |
367 | out: | 266 | out: |
@@ -383,14 +282,11 @@ ecryptfs_send_message_locked(char *data, int data_len, u8 msg_type, | |||
383 | struct ecryptfs_msg_ctx **msg_ctx) | 282 | struct ecryptfs_msg_ctx **msg_ctx) |
384 | { | 283 | { |
385 | struct ecryptfs_daemon *daemon; | 284 | struct ecryptfs_daemon *daemon; |
386 | uid_t euid = current_euid(); | ||
387 | int rc; | 285 | int rc; |
388 | 286 | ||
389 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | 287 | rc = ecryptfs_find_daemon_by_euid(&daemon); |
390 | if (rc || !daemon) { | 288 | if (rc || !daemon) { |
391 | rc = -ENOTCONN; | 289 | rc = -ENOTCONN; |
392 | printk(KERN_ERR "%s: User [%d] does not have a daemon " | ||
393 | "registered\n", __func__, euid); | ||
394 | goto out; | 290 | goto out; |
395 | } | 291 | } |
396 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); | 292 | mutex_lock(&ecryptfs_msg_ctx_lists_mux); |
diff --git a/fs/ecryptfs/miscdev.c b/fs/ecryptfs/miscdev.c index c0038f6566d4..412e6eda25f8 100644 --- a/fs/ecryptfs/miscdev.c +++ b/fs/ecryptfs/miscdev.c | |||
@@ -33,7 +33,7 @@ static atomic_t ecryptfs_num_miscdev_opens; | |||
33 | 33 | ||
34 | /** | 34 | /** |
35 | * ecryptfs_miscdev_poll | 35 | * ecryptfs_miscdev_poll |
36 | * @file: dev file (ignored) | 36 | * @file: dev file |
37 | * @pt: dev poll table (ignored) | 37 | * @pt: dev poll table (ignored) |
38 | * | 38 | * |
39 | * Returns the poll mask | 39 | * Returns the poll mask |
@@ -41,20 +41,10 @@ static atomic_t ecryptfs_num_miscdev_opens; | |||
41 | static unsigned int | 41 | static unsigned int |
42 | ecryptfs_miscdev_poll(struct file *file, poll_table *pt) | 42 | ecryptfs_miscdev_poll(struct file *file, poll_table *pt) |
43 | { | 43 | { |
44 | struct ecryptfs_daemon *daemon; | 44 | struct ecryptfs_daemon *daemon = file->private_data; |
45 | unsigned int mask = 0; | 45 | unsigned int mask = 0; |
46 | uid_t euid = current_euid(); | ||
47 | int rc; | ||
48 | 46 | ||
49 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
50 | /* TODO: Just use file->private_data? */ | ||
51 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | ||
52 | if (rc || !daemon) { | ||
53 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
54 | return -EINVAL; | ||
55 | } | ||
56 | mutex_lock(&daemon->mux); | 47 | mutex_lock(&daemon->mux); |
57 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
58 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { | 48 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { |
59 | printk(KERN_WARNING "%s: Attempt to poll on zombified " | 49 | printk(KERN_WARNING "%s: Attempt to poll on zombified " |
60 | "daemon\n", __func__); | 50 | "daemon\n", __func__); |
@@ -79,7 +69,7 @@ out_unlock_daemon: | |||
79 | /** | 69 | /** |
80 | * ecryptfs_miscdev_open | 70 | * ecryptfs_miscdev_open |
81 | * @inode: inode of miscdev handle (ignored) | 71 | * @inode: inode of miscdev handle (ignored) |
82 | * @file: file for miscdev handle (ignored) | 72 | * @file: file for miscdev handle |
83 | * | 73 | * |
84 | * Returns zero on success; non-zero otherwise | 74 | * Returns zero on success; non-zero otherwise |
85 | */ | 75 | */ |
@@ -87,7 +77,6 @@ static int | |||
87 | ecryptfs_miscdev_open(struct inode *inode, struct file *file) | 77 | ecryptfs_miscdev_open(struct inode *inode, struct file *file) |
88 | { | 78 | { |
89 | struct ecryptfs_daemon *daemon = NULL; | 79 | struct ecryptfs_daemon *daemon = NULL; |
90 | uid_t euid = current_euid(); | ||
91 | int rc; | 80 | int rc; |
92 | 81 | ||
93 | mutex_lock(&ecryptfs_daemon_hash_mux); | 82 | mutex_lock(&ecryptfs_daemon_hash_mux); |
@@ -98,30 +87,20 @@ ecryptfs_miscdev_open(struct inode *inode, struct file *file) | |||
98 | "count; rc = [%d]\n", __func__, rc); | 87 | "count; rc = [%d]\n", __func__, rc); |
99 | goto out_unlock_daemon_list; | 88 | goto out_unlock_daemon_list; |
100 | } | 89 | } |
101 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | 90 | rc = ecryptfs_find_daemon_by_euid(&daemon); |
102 | if (rc || !daemon) { | 91 | if (!rc) { |
103 | rc = ecryptfs_spawn_daemon(&daemon, euid, current_user_ns(), | ||
104 | task_pid(current)); | ||
105 | if (rc) { | ||
106 | printk(KERN_ERR "%s: Error attempting to spawn daemon; " | ||
107 | "rc = [%d]\n", __func__, rc); | ||
108 | goto out_module_put_unlock_daemon_list; | ||
109 | } | ||
110 | } | ||
111 | mutex_lock(&daemon->mux); | ||
112 | if (daemon->pid != task_pid(current)) { | ||
113 | rc = -EINVAL; | 92 | rc = -EINVAL; |
114 | printk(KERN_ERR "%s: pid [0x%p] has registered with euid [%d], " | 93 | goto out_unlock_daemon_list; |
115 | "but pid [0x%p] has attempted to open the handle " | 94 | } |
116 | "instead\n", __func__, daemon->pid, daemon->euid, | 95 | rc = ecryptfs_spawn_daemon(&daemon, file); |
117 | task_pid(current)); | 96 | if (rc) { |
118 | goto out_unlock_daemon; | 97 | printk(KERN_ERR "%s: Error attempting to spawn daemon; " |
98 | "rc = [%d]\n", __func__, rc); | ||
99 | goto out_module_put_unlock_daemon_list; | ||
119 | } | 100 | } |
101 | mutex_lock(&daemon->mux); | ||
120 | if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) { | 102 | if (daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN) { |
121 | rc = -EBUSY; | 103 | rc = -EBUSY; |
122 | printk(KERN_ERR "%s: Miscellaneous device handle may only be " | ||
123 | "opened once per daemon; pid [0x%p] already has this " | ||
124 | "handle open\n", __func__, daemon->pid); | ||
125 | goto out_unlock_daemon; | 104 | goto out_unlock_daemon; |
126 | } | 105 | } |
127 | daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN; | 106 | daemon->flags |= ECRYPTFS_DAEMON_MISCDEV_OPEN; |
@@ -140,7 +119,7 @@ out_unlock_daemon_list: | |||
140 | /** | 119 | /** |
141 | * ecryptfs_miscdev_release | 120 | * ecryptfs_miscdev_release |
142 | * @inode: inode of fs/ecryptfs/euid handle (ignored) | 121 | * @inode: inode of fs/ecryptfs/euid handle (ignored) |
143 | * @file: file for fs/ecryptfs/euid handle (ignored) | 122 | * @file: file for fs/ecryptfs/euid handle |
144 | * | 123 | * |
145 | * This keeps the daemon registered until the daemon sends another | 124 | * This keeps the daemon registered until the daemon sends another |
146 | * ioctl to fs/ecryptfs/ctl or until the kernel module unregisters. | 125 | * ioctl to fs/ecryptfs/ctl or until the kernel module unregisters. |
@@ -150,20 +129,18 @@ out_unlock_daemon_list: | |||
150 | static int | 129 | static int |
151 | ecryptfs_miscdev_release(struct inode *inode, struct file *file) | 130 | ecryptfs_miscdev_release(struct inode *inode, struct file *file) |
152 | { | 131 | { |
153 | struct ecryptfs_daemon *daemon = NULL; | 132 | struct ecryptfs_daemon *daemon = file->private_data; |
154 | uid_t euid = current_euid(); | ||
155 | int rc; | 133 | int rc; |
156 | 134 | ||
157 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
158 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | ||
159 | if (rc || !daemon) | ||
160 | daemon = file->private_data; | ||
161 | mutex_lock(&daemon->mux); | 135 | mutex_lock(&daemon->mux); |
162 | BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN)); | 136 | BUG_ON(!(daemon->flags & ECRYPTFS_DAEMON_MISCDEV_OPEN)); |
163 | daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN; | 137 | daemon->flags &= ~ECRYPTFS_DAEMON_MISCDEV_OPEN; |
164 | atomic_dec(&ecryptfs_num_miscdev_opens); | 138 | atomic_dec(&ecryptfs_num_miscdev_opens); |
165 | mutex_unlock(&daemon->mux); | 139 | mutex_unlock(&daemon->mux); |
140 | |||
141 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
166 | rc = ecryptfs_exorcise_daemon(daemon); | 142 | rc = ecryptfs_exorcise_daemon(daemon); |
143 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
167 | if (rc) { | 144 | if (rc) { |
168 | printk(KERN_CRIT "%s: Fatal error whilst attempting to " | 145 | printk(KERN_CRIT "%s: Fatal error whilst attempting to " |
169 | "shut down daemon; rc = [%d]. Please report this " | 146 | "shut down daemon; rc = [%d]. Please report this " |
@@ -171,7 +148,6 @@ ecryptfs_miscdev_release(struct inode *inode, struct file *file) | |||
171 | BUG(); | 148 | BUG(); |
172 | } | 149 | } |
173 | module_put(THIS_MODULE); | 150 | module_put(THIS_MODULE); |
174 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
175 | return rc; | 151 | return rc; |
176 | } | 152 | } |
177 | 153 | ||
@@ -248,7 +224,7 @@ int ecryptfs_send_miscdev(char *data, size_t data_size, | |||
248 | 224 | ||
249 | /** | 225 | /** |
250 | * ecryptfs_miscdev_read - format and send message from queue | 226 | * ecryptfs_miscdev_read - format and send message from queue |
251 | * @file: fs/ecryptfs/euid miscdevfs handle (ignored) | 227 | * @file: miscdevfs handle |
252 | * @buf: User buffer into which to copy the next message on the daemon queue | 228 | * @buf: User buffer into which to copy the next message on the daemon queue |
253 | * @count: Amount of space available in @buf | 229 | * @count: Amount of space available in @buf |
254 | * @ppos: Offset in file (ignored) | 230 | * @ppos: Offset in file (ignored) |
@@ -262,43 +238,27 @@ static ssize_t | |||
262 | ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, | 238 | ecryptfs_miscdev_read(struct file *file, char __user *buf, size_t count, |
263 | loff_t *ppos) | 239 | loff_t *ppos) |
264 | { | 240 | { |
265 | struct ecryptfs_daemon *daemon; | 241 | struct ecryptfs_daemon *daemon = file->private_data; |
266 | struct ecryptfs_msg_ctx *msg_ctx; | 242 | struct ecryptfs_msg_ctx *msg_ctx; |
267 | size_t packet_length_size; | 243 | size_t packet_length_size; |
268 | char packet_length[ECRYPTFS_MAX_PKT_LEN_SIZE]; | 244 | char packet_length[ECRYPTFS_MAX_PKT_LEN_SIZE]; |
269 | size_t i; | 245 | size_t i; |
270 | size_t total_length; | 246 | size_t total_length; |
271 | uid_t euid = current_euid(); | ||
272 | int rc; | 247 | int rc; |
273 | 248 | ||
274 | mutex_lock(&ecryptfs_daemon_hash_mux); | ||
275 | /* TODO: Just use file->private_data? */ | ||
276 | rc = ecryptfs_find_daemon_by_euid(&daemon, euid, current_user_ns()); | ||
277 | if (rc || !daemon) { | ||
278 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
279 | return -EINVAL; | ||
280 | } | ||
281 | mutex_lock(&daemon->mux); | 249 | mutex_lock(&daemon->mux); |
282 | if (task_pid(current) != daemon->pid) { | ||
283 | mutex_unlock(&daemon->mux); | ||
284 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
285 | return -EPERM; | ||
286 | } | ||
287 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { | 250 | if (daemon->flags & ECRYPTFS_DAEMON_ZOMBIE) { |
288 | rc = 0; | 251 | rc = 0; |
289 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
290 | printk(KERN_WARNING "%s: Attempt to read from zombified " | 252 | printk(KERN_WARNING "%s: Attempt to read from zombified " |
291 | "daemon\n", __func__); | 253 | "daemon\n", __func__); |
292 | goto out_unlock_daemon; | 254 | goto out_unlock_daemon; |
293 | } | 255 | } |
294 | if (daemon->flags & ECRYPTFS_DAEMON_IN_READ) { | 256 | if (daemon->flags & ECRYPTFS_DAEMON_IN_READ) { |
295 | rc = 0; | 257 | rc = 0; |
296 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
297 | goto out_unlock_daemon; | 258 | goto out_unlock_daemon; |
298 | } | 259 | } |
299 | /* This daemon will not go away so long as this flag is set */ | 260 | /* This daemon will not go away so long as this flag is set */ |
300 | daemon->flags |= ECRYPTFS_DAEMON_IN_READ; | 261 | daemon->flags |= ECRYPTFS_DAEMON_IN_READ; |
301 | mutex_unlock(&ecryptfs_daemon_hash_mux); | ||
302 | check_list: | 262 | check_list: |
303 | if (list_empty(&daemon->msg_ctx_out_queue)) { | 263 | if (list_empty(&daemon->msg_ctx_out_queue)) { |
304 | mutex_unlock(&daemon->mux); | 264 | mutex_unlock(&daemon->mux); |
@@ -382,16 +342,12 @@ out_unlock_daemon: | |||
382 | * ecryptfs_miscdev_response - miscdevess response to message previously sent to daemon | 342 | * ecryptfs_miscdev_response - miscdevess response to message previously sent to daemon |
383 | * @data: Bytes comprising struct ecryptfs_message | 343 | * @data: Bytes comprising struct ecryptfs_message |
384 | * @data_size: sizeof(struct ecryptfs_message) + data len | 344 | * @data_size: sizeof(struct ecryptfs_message) + data len |
385 | * @euid: Effective user id of miscdevess sending the miscdev response | ||
386 | * @user_ns: The namespace in which @euid applies | ||
387 | * @pid: Miscdevess id of miscdevess sending the miscdev response | ||
388 | * @seq: Sequence number for miscdev response packet | 345 | * @seq: Sequence number for miscdev response packet |
389 | * | 346 | * |
390 | * Returns zero on success; non-zero otherwise | 347 | * Returns zero on success; non-zero otherwise |
391 | */ | 348 | */ |
392 | static int ecryptfs_miscdev_response(char *data, size_t data_size, | 349 | static int ecryptfs_miscdev_response(struct ecryptfs_daemon *daemon, char *data, |
393 | uid_t euid, struct user_namespace *user_ns, | 350 | size_t data_size, u32 seq) |
394 | struct pid *pid, u32 seq) | ||
395 | { | 351 | { |
396 | struct ecryptfs_message *msg = (struct ecryptfs_message *)data; | 352 | struct ecryptfs_message *msg = (struct ecryptfs_message *)data; |
397 | int rc; | 353 | int rc; |
@@ -403,7 +359,7 @@ static int ecryptfs_miscdev_response(char *data, size_t data_size, | |||
403 | rc = -EINVAL; | 359 | rc = -EINVAL; |
404 | goto out; | 360 | goto out; |
405 | } | 361 | } |
406 | rc = ecryptfs_process_response(msg, euid, user_ns, pid, seq); | 362 | rc = ecryptfs_process_response(daemon, msg, seq); |
407 | if (rc) | 363 | if (rc) |
408 | printk(KERN_ERR | 364 | printk(KERN_ERR |
409 | "Error processing response message; rc = [%d]\n", rc); | 365 | "Error processing response message; rc = [%d]\n", rc); |
@@ -413,7 +369,7 @@ out: | |||
413 | 369 | ||
414 | /** | 370 | /** |
415 | * ecryptfs_miscdev_write - handle write to daemon miscdev handle | 371 | * ecryptfs_miscdev_write - handle write to daemon miscdev handle |
416 | * @file: File for misc dev handle (ignored) | 372 | * @file: File for misc dev handle |
417 | * @buf: Buffer containing user data | 373 | * @buf: Buffer containing user data |
418 | * @count: Amount of data in @buf | 374 | * @count: Amount of data in @buf |
419 | * @ppos: Pointer to offset in file (ignored) | 375 | * @ppos: Pointer to offset in file (ignored) |
@@ -428,7 +384,6 @@ ecryptfs_miscdev_write(struct file *file, const char __user *buf, | |||
428 | u32 seq; | 384 | u32 seq; |
429 | size_t packet_size, packet_size_length; | 385 | size_t packet_size, packet_size_length; |
430 | char *data; | 386 | char *data; |
431 | uid_t euid = current_euid(); | ||
432 | unsigned char packet_size_peek[ECRYPTFS_MAX_PKT_LEN_SIZE]; | 387 | unsigned char packet_size_peek[ECRYPTFS_MAX_PKT_LEN_SIZE]; |
433 | ssize_t rc; | 388 | ssize_t rc; |
434 | 389 | ||
@@ -488,10 +443,9 @@ memdup: | |||
488 | } | 443 | } |
489 | memcpy(&counter_nbo, &data[PKT_CTR_OFFSET], PKT_CTR_SIZE); | 444 | memcpy(&counter_nbo, &data[PKT_CTR_OFFSET], PKT_CTR_SIZE); |
490 | seq = be32_to_cpu(counter_nbo); | 445 | seq = be32_to_cpu(counter_nbo); |
491 | rc = ecryptfs_miscdev_response( | 446 | rc = ecryptfs_miscdev_response(file->private_data, |
492 | &data[PKT_LEN_OFFSET + packet_size_length], | 447 | &data[PKT_LEN_OFFSET + packet_size_length], |
493 | packet_size, euid, current_user_ns(), | 448 | packet_size, seq); |
494 | task_pid(current), seq); | ||
495 | if (rc) { | 449 | if (rc) { |
496 | printk(KERN_WARNING "%s: Failed to deliver miscdev " | 450 | printk(KERN_WARNING "%s: Failed to deliver miscdev " |
497 | "response to requesting operation; rc = [%zd]\n", | 451 | "response to requesting operation; rc = [%zd]\n", |
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c index a46b3a8fee1e..bd1d57f98f74 100644 --- a/fs/ecryptfs/mmap.c +++ b/fs/ecryptfs/mmap.c | |||
@@ -66,18 +66,6 @@ static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc) | |||
66 | { | 66 | { |
67 | int rc; | 67 | int rc; |
68 | 68 | ||
69 | /* | ||
70 | * Refuse to write the page out if we are called from reclaim context | ||
71 | * since our writepage() path may potentially allocate memory when | ||
72 | * calling into the lower fs vfs_write() which may in turn invoke | ||
73 | * us again. | ||
74 | */ | ||
75 | if (current->flags & PF_MEMALLOC) { | ||
76 | redirty_page_for_writepage(wbc, page); | ||
77 | rc = 0; | ||
78 | goto out; | ||
79 | } | ||
80 | |||
81 | rc = ecryptfs_encrypt_page(page); | 69 | rc = ecryptfs_encrypt_page(page); |
82 | if (rc) { | 70 | if (rc) { |
83 | ecryptfs_printk(KERN_WARNING, "Error encrypting " | 71 | ecryptfs_printk(KERN_WARNING, "Error encrypting " |
@@ -498,7 +486,6 @@ static int ecryptfs_write_end(struct file *file, | |||
498 | struct ecryptfs_crypt_stat *crypt_stat = | 486 | struct ecryptfs_crypt_stat *crypt_stat = |
499 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; | 487 | &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat; |
500 | int rc; | 488 | int rc; |
501 | int need_unlock_page = 1; | ||
502 | 489 | ||
503 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" | 490 | ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" |
504 | "(page w/ index = [0x%.16lx], to = [%d])\n", index, to); | 491 | "(page w/ index = [0x%.16lx], to = [%d])\n", index, to); |
@@ -519,26 +506,26 @@ static int ecryptfs_write_end(struct file *file, | |||
519 | "zeros in page with index = [0x%.16lx]\n", index); | 506 | "zeros in page with index = [0x%.16lx]\n", index); |
520 | goto out; | 507 | goto out; |
521 | } | 508 | } |
522 | set_page_dirty(page); | 509 | rc = ecryptfs_encrypt_page(page); |
523 | unlock_page(page); | 510 | if (rc) { |
524 | need_unlock_page = 0; | 511 | ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " |
512 | "index [0x%.16lx])\n", index); | ||
513 | goto out; | ||
514 | } | ||
525 | if (pos + copied > i_size_read(ecryptfs_inode)) { | 515 | if (pos + copied > i_size_read(ecryptfs_inode)) { |
526 | i_size_write(ecryptfs_inode, pos + copied); | 516 | i_size_write(ecryptfs_inode, pos + copied); |
527 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " | 517 | ecryptfs_printk(KERN_DEBUG, "Expanded file size to " |
528 | "[0x%.16llx]\n", | 518 | "[0x%.16llx]\n", |
529 | (unsigned long long)i_size_read(ecryptfs_inode)); | 519 | (unsigned long long)i_size_read(ecryptfs_inode)); |
530 | balance_dirty_pages_ratelimited(mapping); | ||
531 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); | ||
532 | if (rc) { | ||
533 | printk(KERN_ERR "Error writing inode size to metadata; " | ||
534 | "rc = [%d]\n", rc); | ||
535 | goto out; | ||
536 | } | ||
537 | } | 520 | } |
538 | rc = copied; | 521 | rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode); |
522 | if (rc) | ||
523 | printk(KERN_ERR "Error writing inode size to metadata; " | ||
524 | "rc = [%d]\n", rc); | ||
525 | else | ||
526 | rc = copied; | ||
539 | out: | 527 | out: |
540 | if (need_unlock_page) | 528 | unlock_page(page); |
541 | unlock_page(page); | ||
542 | page_cache_release(page); | 529 | page_cache_release(page); |
543 | return rc; | 530 | return rc; |
544 | } | 531 | } |
diff --git a/fs/exofs/inode.c b/fs/exofs/inode.c index 5badb0c039de..1562c27a2fab 100644 --- a/fs/exofs/inode.c +++ b/fs/exofs/inode.c | |||
@@ -37,15 +37,12 @@ | |||
37 | 37 | ||
38 | #define EXOFS_DBGMSG2(M...) do {} while (0) | 38 | #define EXOFS_DBGMSG2(M...) do {} while (0) |
39 | 39 | ||
40 | enum {MAX_PAGES_KMALLOC = PAGE_SIZE / sizeof(struct page *), }; | ||
41 | |||
42 | unsigned exofs_max_io_pages(struct ore_layout *layout, | 40 | unsigned exofs_max_io_pages(struct ore_layout *layout, |
43 | unsigned expected_pages) | 41 | unsigned expected_pages) |
44 | { | 42 | { |
45 | unsigned pages = min_t(unsigned, expected_pages, MAX_PAGES_KMALLOC); | 43 | unsigned pages = min_t(unsigned, expected_pages, |
44 | layout->max_io_length / PAGE_SIZE); | ||
46 | 45 | ||
47 | /* TODO: easily support bio chaining */ | ||
48 | pages = min_t(unsigned, pages, layout->max_io_length / PAGE_SIZE); | ||
49 | return pages; | 46 | return pages; |
50 | } | 47 | } |
51 | 48 | ||
@@ -101,7 +98,8 @@ static void _pcol_reset(struct page_collect *pcol) | |||
101 | * it might not end here. don't be left with nothing | 98 | * it might not end here. don't be left with nothing |
102 | */ | 99 | */ |
103 | if (!pcol->expected_pages) | 100 | if (!pcol->expected_pages) |
104 | pcol->expected_pages = MAX_PAGES_KMALLOC; | 101 | pcol->expected_pages = |
102 | exofs_max_io_pages(&pcol->sbi->layout, ~0); | ||
105 | } | 103 | } |
106 | 104 | ||
107 | static int pcol_try_alloc(struct page_collect *pcol) | 105 | static int pcol_try_alloc(struct page_collect *pcol) |
@@ -389,6 +387,8 @@ static int readpage_strip(void *data, struct page *page) | |||
389 | size_t len; | 387 | size_t len; |
390 | int ret; | 388 | int ret; |
391 | 389 | ||
390 | BUG_ON(!PageLocked(page)); | ||
391 | |||
392 | /* FIXME: Just for debugging, will be removed */ | 392 | /* FIXME: Just for debugging, will be removed */ |
393 | if (PageUptodate(page)) | 393 | if (PageUptodate(page)) |
394 | EXOFS_ERR("PageUptodate(0x%lx, 0x%lx)\n", pcol->inode->i_ino, | 394 | EXOFS_ERR("PageUptodate(0x%lx, 0x%lx)\n", pcol->inode->i_ino, |
@@ -572,8 +572,16 @@ static struct page *__r4w_get_page(void *priv, u64 offset, bool *uptodate) | |||
572 | 572 | ||
573 | if (!pcol->that_locked_page || | 573 | if (!pcol->that_locked_page || |
574 | (pcol->that_locked_page->index != index)) { | 574 | (pcol->that_locked_page->index != index)) { |
575 | struct page *page = find_get_page(pcol->inode->i_mapping, index); | 575 | struct page *page; |
576 | loff_t i_size = i_size_read(pcol->inode); | ||
577 | |||
578 | if (offset >= i_size) { | ||
579 | *uptodate = true; | ||
580 | EXOFS_DBGMSG("offset >= i_size index=0x%lx\n", index); | ||
581 | return ZERO_PAGE(0); | ||
582 | } | ||
576 | 583 | ||
584 | page = find_get_page(pcol->inode->i_mapping, index); | ||
577 | if (!page) { | 585 | if (!page) { |
578 | page = find_or_create_page(pcol->inode->i_mapping, | 586 | page = find_or_create_page(pcol->inode->i_mapping, |
579 | index, GFP_NOFS); | 587 | index, GFP_NOFS); |
@@ -602,12 +610,13 @@ static void __r4w_put_page(void *priv, struct page *page) | |||
602 | { | 610 | { |
603 | struct page_collect *pcol = priv; | 611 | struct page_collect *pcol = priv; |
604 | 612 | ||
605 | if (pcol->that_locked_page != page) { | 613 | if ((pcol->that_locked_page != page) && (ZERO_PAGE(0) != page)) { |
606 | EXOFS_DBGMSG("index=0x%lx\n", page->index); | 614 | EXOFS_DBGMSG("index=0x%lx\n", page->index); |
607 | page_cache_release(page); | 615 | page_cache_release(page); |
608 | return; | 616 | return; |
609 | } | 617 | } |
610 | EXOFS_DBGMSG("that_locked_page index=0x%lx\n", page->index); | 618 | EXOFS_DBGMSG("that_locked_page index=0x%lx\n", |
619 | ZERO_PAGE(0) == page ? -1 : page->index); | ||
611 | } | 620 | } |
612 | 621 | ||
613 | static const struct _ore_r4w_op _r4w_op = { | 622 | static const struct _ore_r4w_op _r4w_op = { |
diff --git a/fs/exofs/ore.c b/fs/exofs/ore.c index 24a49d47e935..1585db1aa365 100644 --- a/fs/exofs/ore.c +++ b/fs/exofs/ore.c | |||
@@ -837,11 +837,11 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp) | |||
837 | bio->bi_rw |= REQ_WRITE; | 837 | bio->bi_rw |= REQ_WRITE; |
838 | } | 838 | } |
839 | 839 | ||
840 | osd_req_write(or, _ios_obj(ios, dev), per_dev->offset, | 840 | osd_req_write(or, _ios_obj(ios, cur_comp), |
841 | bio, per_dev->length); | 841 | per_dev->offset, bio, per_dev->length); |
842 | ORE_DBGMSG("write(0x%llx) offset=0x%llx " | 842 | ORE_DBGMSG("write(0x%llx) offset=0x%llx " |
843 | "length=0x%llx dev=%d\n", | 843 | "length=0x%llx dev=%d\n", |
844 | _LLU(_ios_obj(ios, dev)->id), | 844 | _LLU(_ios_obj(ios, cur_comp)->id), |
845 | _LLU(per_dev->offset), | 845 | _LLU(per_dev->offset), |
846 | _LLU(per_dev->length), dev); | 846 | _LLU(per_dev->length), dev); |
847 | } else if (ios->kern_buff) { | 847 | } else if (ios->kern_buff) { |
@@ -853,20 +853,20 @@ static int _write_mirror(struct ore_io_state *ios, int cur_comp) | |||
853 | (ios->si.unit_off + ios->length > | 853 | (ios->si.unit_off + ios->length > |
854 | ios->layout->stripe_unit)); | 854 | ios->layout->stripe_unit)); |
855 | 855 | ||
856 | ret = osd_req_write_kern(or, _ios_obj(ios, per_dev->dev), | 856 | ret = osd_req_write_kern(or, _ios_obj(ios, cur_comp), |
857 | per_dev->offset, | 857 | per_dev->offset, |
858 | ios->kern_buff, ios->length); | 858 | ios->kern_buff, ios->length); |
859 | if (unlikely(ret)) | 859 | if (unlikely(ret)) |
860 | goto out; | 860 | goto out; |
861 | ORE_DBGMSG2("write_kern(0x%llx) offset=0x%llx " | 861 | ORE_DBGMSG2("write_kern(0x%llx) offset=0x%llx " |
862 | "length=0x%llx dev=%d\n", | 862 | "length=0x%llx dev=%d\n", |
863 | _LLU(_ios_obj(ios, dev)->id), | 863 | _LLU(_ios_obj(ios, cur_comp)->id), |
864 | _LLU(per_dev->offset), | 864 | _LLU(per_dev->offset), |
865 | _LLU(ios->length), per_dev->dev); | 865 | _LLU(ios->length), per_dev->dev); |
866 | } else { | 866 | } else { |
867 | osd_req_set_attributes(or, _ios_obj(ios, dev)); | 867 | osd_req_set_attributes(or, _ios_obj(ios, cur_comp)); |
868 | ORE_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d\n", | 868 | ORE_DBGMSG2("obj(0x%llx) set_attributes=%d dev=%d\n", |
869 | _LLU(_ios_obj(ios, dev)->id), | 869 | _LLU(_ios_obj(ios, cur_comp)->id), |
870 | ios->out_attr_len, dev); | 870 | ios->out_attr_len, dev); |
871 | } | 871 | } |
872 | 872 | ||
diff --git a/fs/exofs/super.c b/fs/exofs/super.c index 433783624d10..dde41a75c7c8 100644 --- a/fs/exofs/super.c +++ b/fs/exofs/super.c | |||
@@ -400,8 +400,6 @@ static int exofs_sync_fs(struct super_block *sb, int wait) | |||
400 | ret = ore_write(ios); | 400 | ret = ore_write(ios); |
401 | if (unlikely(ret)) | 401 | if (unlikely(ret)) |
402 | EXOFS_ERR("%s: ore_write failed.\n", __func__); | 402 | EXOFS_ERR("%s: ore_write failed.\n", __func__); |
403 | else | ||
404 | sb->s_dirt = 0; | ||
405 | 403 | ||
406 | 404 | ||
407 | unlock_super(sb); | 405 | unlock_super(sb); |
@@ -412,14 +410,6 @@ out: | |||
412 | return ret; | 410 | return ret; |
413 | } | 411 | } |
414 | 412 | ||
415 | static void exofs_write_super(struct super_block *sb) | ||
416 | { | ||
417 | if (!(sb->s_flags & MS_RDONLY)) | ||
418 | exofs_sync_fs(sb, 1); | ||
419 | else | ||
420 | sb->s_dirt = 0; | ||
421 | } | ||
422 | |||
423 | static void _exofs_print_device(const char *msg, const char *dev_path, | 413 | static void _exofs_print_device(const char *msg, const char *dev_path, |
424 | struct osd_dev *od, u64 pid) | 414 | struct osd_dev *od, u64 pid) |
425 | { | 415 | { |
@@ -952,7 +942,6 @@ static const struct super_operations exofs_sops = { | |||
952 | .write_inode = exofs_write_inode, | 942 | .write_inode = exofs_write_inode, |
953 | .evict_inode = exofs_evict_inode, | 943 | .evict_inode = exofs_evict_inode, |
954 | .put_super = exofs_put_super, | 944 | .put_super = exofs_put_super, |
955 | .write_super = exofs_write_super, | ||
956 | .sync_fs = exofs_sync_fs, | 945 | .sync_fs = exofs_sync_fs, |
957 | .statfs = exofs_statfs, | 946 | .statfs = exofs_statfs, |
958 | }; | 947 | }; |
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c index 9a4a5c48b1c9..a07597307fd1 100644 --- a/fs/ext3/inode.c +++ b/fs/ext3/inode.c | |||
@@ -3459,14 +3459,6 @@ ext3_reserve_inode_write(handle_t *handle, struct inode *inode, | |||
3459 | * inode out, but prune_icache isn't a user-visible syncing function. | 3459 | * inode out, but prune_icache isn't a user-visible syncing function. |
3460 | * Whenever the user wants stuff synced (sys_sync, sys_msync, sys_fsync) | 3460 | * Whenever the user wants stuff synced (sys_sync, sys_msync, sys_fsync) |
3461 | * we start and wait on commits. | 3461 | * we start and wait on commits. |
3462 | * | ||
3463 | * Is this efficient/effective? Well, we're being nice to the system | ||
3464 | * by cleaning up our inodes proactively so they can be reaped | ||
3465 | * without I/O. But we are potentially leaving up to five seconds' | ||
3466 | * worth of inodes floating about which prune_icache wants us to | ||
3467 | * write out. One way to fix that would be to get prune_icache() | ||
3468 | * to do a write_super() to free up some memory. It has the desired | ||
3469 | * effect. | ||
3470 | */ | 3462 | */ |
3471 | int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode) | 3463 | int ext3_mark_inode_dirty(handle_t *handle, struct inode *inode) |
3472 | { | 3464 | { |
diff --git a/fs/ext3/super.c b/fs/ext3/super.c index ff9bcdc5b0d5..8c892e93d8e7 100644 --- a/fs/ext3/super.c +++ b/fs/ext3/super.c | |||
@@ -64,11 +64,6 @@ static int ext3_freeze(struct super_block *sb); | |||
64 | 64 | ||
65 | /* | 65 | /* |
66 | * Wrappers for journal_start/end. | 66 | * Wrappers for journal_start/end. |
67 | * | ||
68 | * The only special thing we need to do here is to make sure that all | ||
69 | * journal_end calls result in the superblock being marked dirty, so | ||
70 | * that sync() will call the filesystem's write_super callback if | ||
71 | * appropriate. | ||
72 | */ | 67 | */ |
73 | handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks) | 68 | handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks) |
74 | { | 69 | { |
@@ -90,12 +85,6 @@ handle_t *ext3_journal_start_sb(struct super_block *sb, int nblocks) | |||
90 | return journal_start(journal, nblocks); | 85 | return journal_start(journal, nblocks); |
91 | } | 86 | } |
92 | 87 | ||
93 | /* | ||
94 | * The only special thing we need to do here is to make sure that all | ||
95 | * journal_stop calls result in the superblock being marked dirty, so | ||
96 | * that sync() will call the filesystem's write_super callback if | ||
97 | * appropriate. | ||
98 | */ | ||
99 | int __ext3_journal_stop(const char *where, handle_t *handle) | 88 | int __ext3_journal_stop(const char *where, handle_t *handle) |
100 | { | 89 | { |
101 | struct super_block *sb; | 90 | struct super_block *sb; |
diff --git a/fs/ext4/balloc.c b/fs/ext4/balloc.c index d23b31ca9d7a..1b5089067d01 100644 --- a/fs/ext4/balloc.c +++ b/fs/ext4/balloc.c | |||
@@ -280,14 +280,18 @@ struct ext4_group_desc * ext4_get_group_desc(struct super_block *sb, | |||
280 | return desc; | 280 | return desc; |
281 | } | 281 | } |
282 | 282 | ||
283 | static int ext4_valid_block_bitmap(struct super_block *sb, | 283 | /* |
284 | struct ext4_group_desc *desc, | 284 | * Return the block number which was discovered to be invalid, or 0 if |
285 | unsigned int block_group, | 285 | * the block bitmap is valid. |
286 | struct buffer_head *bh) | 286 | */ |
287 | static ext4_fsblk_t ext4_valid_block_bitmap(struct super_block *sb, | ||
288 | struct ext4_group_desc *desc, | ||
289 | unsigned int block_group, | ||
290 | struct buffer_head *bh) | ||
287 | { | 291 | { |
288 | ext4_grpblk_t offset; | 292 | ext4_grpblk_t offset; |
289 | ext4_grpblk_t next_zero_bit; | 293 | ext4_grpblk_t next_zero_bit; |
290 | ext4_fsblk_t bitmap_blk; | 294 | ext4_fsblk_t blk; |
291 | ext4_fsblk_t group_first_block; | 295 | ext4_fsblk_t group_first_block; |
292 | 296 | ||
293 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { | 297 | if (EXT4_HAS_INCOMPAT_FEATURE(sb, EXT4_FEATURE_INCOMPAT_FLEX_BG)) { |
@@ -297,37 +301,33 @@ static int ext4_valid_block_bitmap(struct super_block *sb, | |||
297 | * or it has to also read the block group where the bitmaps | 301 | * or it has to also read the block group where the bitmaps |
298 | * are located to verify they are set. | 302 | * are located to verify they are set. |
299 | */ | 303 | */ |
300 | return 1; | 304 | return 0; |
301 | } | 305 | } |
302 | group_first_block = ext4_group_first_block_no(sb, block_group); | 306 | group_first_block = ext4_group_first_block_no(sb, block_group); |
303 | 307 | ||
304 | /* check whether block bitmap block number is set */ | 308 | /* check whether block bitmap block number is set */ |
305 | bitmap_blk = ext4_block_bitmap(sb, desc); | 309 | blk = ext4_block_bitmap(sb, desc); |
306 | offset = bitmap_blk - group_first_block; | 310 | offset = blk - group_first_block; |
307 | if (!ext4_test_bit(offset, bh->b_data)) | 311 | if (!ext4_test_bit(offset, bh->b_data)) |
308 | /* bad block bitmap */ | 312 | /* bad block bitmap */ |
309 | goto err_out; | 313 | return blk; |
310 | 314 | ||
311 | /* check whether the inode bitmap block number is set */ | 315 | /* check whether the inode bitmap block number is set */ |
312 | bitmap_blk = ext4_inode_bitmap(sb, desc); | 316 | blk = ext4_inode_bitmap(sb, desc); |
313 | offset = bitmap_blk - group_first_block; | 317 | offset = blk - group_first_block; |
314 | if (!ext4_test_bit(offset, bh->b_data)) | 318 | if (!ext4_test_bit(offset, bh->b_data)) |
315 | /* bad block bitmap */ | 319 | /* bad block bitmap */ |
316 | goto err_out; | 320 | return blk; |
317 | 321 | ||
318 | /* check whether the inode table block number is set */ | 322 | /* check whether the inode table block number is set */ |
319 | bitmap_blk = ext4_inode_table(sb, desc); | 323 | blk = ext4_inode_table(sb, desc); |
320 | offset = bitmap_blk - group_first_block; | 324 | offset = blk - group_first_block; |
321 | next_zero_bit = ext4_find_next_zero_bit(bh->b_data, | 325 | next_zero_bit = ext4_find_next_zero_bit(bh->b_data, |
322 | offset + EXT4_SB(sb)->s_itb_per_group, | 326 | offset + EXT4_SB(sb)->s_itb_per_group, |
323 | offset); | 327 | offset); |
324 | if (next_zero_bit >= offset + EXT4_SB(sb)->s_itb_per_group) | 328 | if (next_zero_bit < offset + EXT4_SB(sb)->s_itb_per_group) |
325 | /* good bitmap for inode tables */ | 329 | /* bad bitmap for inode tables */ |
326 | return 1; | 330 | return blk; |
327 | |||
328 | err_out: | ||
329 | ext4_error(sb, "Invalid block bitmap - block_group = %d, block = %llu", | ||
330 | block_group, bitmap_blk); | ||
331 | return 0; | 331 | return 0; |
332 | } | 332 | } |
333 | 333 | ||
@@ -336,14 +336,26 @@ void ext4_validate_block_bitmap(struct super_block *sb, | |||
336 | unsigned int block_group, | 336 | unsigned int block_group, |
337 | struct buffer_head *bh) | 337 | struct buffer_head *bh) |
338 | { | 338 | { |
339 | ext4_fsblk_t blk; | ||
340 | |||
339 | if (buffer_verified(bh)) | 341 | if (buffer_verified(bh)) |
340 | return; | 342 | return; |
341 | 343 | ||
342 | ext4_lock_group(sb, block_group); | 344 | ext4_lock_group(sb, block_group); |
343 | if (ext4_valid_block_bitmap(sb, desc, block_group, bh) && | 345 | blk = ext4_valid_block_bitmap(sb, desc, block_group, bh); |
344 | ext4_block_bitmap_csum_verify(sb, block_group, desc, bh, | 346 | if (unlikely(blk != 0)) { |
345 | EXT4_BLOCKS_PER_GROUP(sb) / 8)) | 347 | ext4_unlock_group(sb, block_group); |
346 | set_buffer_verified(bh); | 348 | ext4_error(sb, "bg %u: block %llu: invalid block bitmap", |
349 | block_group, blk); | ||
350 | return; | ||
351 | } | ||
352 | if (unlikely(!ext4_block_bitmap_csum_verify(sb, block_group, | ||
353 | desc, bh, EXT4_BLOCKS_PER_GROUP(sb) / 8))) { | ||
354 | ext4_unlock_group(sb, block_group); | ||
355 | ext4_error(sb, "bg %u: bad block bitmap checksum", block_group); | ||
356 | return; | ||
357 | } | ||
358 | set_buffer_verified(bh); | ||
347 | ext4_unlock_group(sb, block_group); | 359 | ext4_unlock_group(sb, block_group); |
348 | } | 360 | } |
349 | 361 | ||
diff --git a/fs/ext4/bitmap.c b/fs/ext4/bitmap.c index f8716eab9995..5c2d1813ebe9 100644 --- a/fs/ext4/bitmap.c +++ b/fs/ext4/bitmap.c | |||
@@ -79,7 +79,6 @@ int ext4_block_bitmap_csum_verify(struct super_block *sb, ext4_group_t group, | |||
79 | if (provided == calculated) | 79 | if (provided == calculated) |
80 | return 1; | 80 | return 1; |
81 | 81 | ||
82 | ext4_error(sb, "Bad block bitmap checksum: block_group = %u", group); | ||
83 | return 0; | 82 | return 0; |
84 | } | 83 | } |
85 | 84 | ||
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index cd0c7ed06772..aabbb3f53683 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -2662,6 +2662,7 @@ cont: | |||
2662 | } | 2662 | } |
2663 | path[0].p_depth = depth; | 2663 | path[0].p_depth = depth; |
2664 | path[0].p_hdr = ext_inode_hdr(inode); | 2664 | path[0].p_hdr = ext_inode_hdr(inode); |
2665 | i = 0; | ||
2665 | 2666 | ||
2666 | if (ext4_ext_check(inode, path[0].p_hdr, depth)) { | 2667 | if (ext4_ext_check(inode, path[0].p_hdr, depth)) { |
2667 | err = -EIO; | 2668 | err = -EIO; |
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 6324f74e0342..dff171c3a123 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c | |||
@@ -1970,7 +1970,7 @@ static void ext4_end_io_buffer_write(struct buffer_head *bh, int uptodate); | |||
1970 | * This function can get called via... | 1970 | * This function can get called via... |
1971 | * - ext4_da_writepages after taking page lock (have journal handle) | 1971 | * - ext4_da_writepages after taking page lock (have journal handle) |
1972 | * - journal_submit_inode_data_buffers (no journal handle) | 1972 | * - journal_submit_inode_data_buffers (no journal handle) |
1973 | * - shrink_page_list via pdflush (no journal handle) | 1973 | * - shrink_page_list via the kswapd/direct reclaim (no journal handle) |
1974 | * - grab_page_cache when doing write_begin (have journal handle) | 1974 | * - grab_page_cache when doing write_begin (have journal handle) |
1975 | * | 1975 | * |
1976 | * We don't do any block allocation in this function. If we have page with | 1976 | * We don't do any block allocation in this function. If we have page with |
@@ -4589,14 +4589,6 @@ static int ext4_expand_extra_isize(struct inode *inode, | |||
4589 | * inode out, but prune_icache isn't a user-visible syncing function. | 4589 | * inode out, but prune_icache isn't a user-visible syncing function. |
4590 | * Whenever the user wants stuff synced (sys_sync, sys_msync, sys_fsync) | 4590 | * Whenever the user wants stuff synced (sys_sync, sys_msync, sys_fsync) |
4591 | * we start and wait on commits. | 4591 | * we start and wait on commits. |
4592 | * | ||
4593 | * Is this efficient/effective? Well, we're being nice to the system | ||
4594 | * by cleaning up our inodes proactively so they can be reaped | ||
4595 | * without I/O. But we are potentially leaving up to five seconds' | ||
4596 | * worth of inodes floating about which prune_icache wants us to | ||
4597 | * write out. One way to fix that would be to get prune_icache() | ||
4598 | * to do a write_super() to free up some memory. It has the desired | ||
4599 | * effect. | ||
4600 | */ | 4592 | */ |
4601 | int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) | 4593 | int ext4_mark_inode_dirty(handle_t *handle, struct inode *inode) |
4602 | { | 4594 | { |
diff --git a/fs/ext4/super.c b/fs/ext4/super.c index d76ec8277d3f..c6e0cb3d1f4a 100644 --- a/fs/ext4/super.c +++ b/fs/ext4/super.c | |||
@@ -326,11 +326,6 @@ static void ext4_put_nojournal(handle_t *handle) | |||
326 | 326 | ||
327 | /* | 327 | /* |
328 | * Wrappers for jbd2_journal_start/end. | 328 | * Wrappers for jbd2_journal_start/end. |
329 | * | ||
330 | * The only special thing we need to do here is to make sure that all | ||
331 | * journal_end calls result in the superblock being marked dirty, so | ||
332 | * that sync() will call the filesystem's write_super callback if | ||
333 | * appropriate. | ||
334 | */ | 329 | */ |
335 | handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks) | 330 | handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks) |
336 | { | 331 | { |
@@ -356,12 +351,6 @@ handle_t *ext4_journal_start_sb(struct super_block *sb, int nblocks) | |||
356 | return jbd2_journal_start(journal, nblocks); | 351 | return jbd2_journal_start(journal, nblocks); |
357 | } | 352 | } |
358 | 353 | ||
359 | /* | ||
360 | * The only special thing we need to do here is to make sure that all | ||
361 | * jbd2_journal_stop calls result in the superblock being marked dirty, so | ||
362 | * that sync() will call the filesystem's write_super callback if | ||
363 | * appropriate. | ||
364 | */ | ||
365 | int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle) | 354 | int __ext4_journal_stop(const char *where, unsigned int line, handle_t *handle) |
366 | { | 355 | { |
367 | struct super_block *sb; | 356 | struct super_block *sb; |
@@ -959,6 +948,7 @@ static struct inode *ext4_alloc_inode(struct super_block *sb) | |||
959 | ei->i_reserved_meta_blocks = 0; | 948 | ei->i_reserved_meta_blocks = 0; |
960 | ei->i_allocated_meta_blocks = 0; | 949 | ei->i_allocated_meta_blocks = 0; |
961 | ei->i_da_metadata_calc_len = 0; | 950 | ei->i_da_metadata_calc_len = 0; |
951 | ei->i_da_metadata_calc_last_lblock = 0; | ||
962 | spin_lock_init(&(ei->i_block_reservation_lock)); | 952 | spin_lock_init(&(ei->i_block_reservation_lock)); |
963 | #ifdef CONFIG_QUOTA | 953 | #ifdef CONFIG_QUOTA |
964 | ei->i_reserved_quota = 0; | 954 | ei->i_reserved_quota = 0; |
@@ -3119,6 +3109,10 @@ static int count_overhead(struct super_block *sb, ext4_group_t grp, | |||
3119 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); | 3109 | ext4_group_t i, ngroups = ext4_get_groups_count(sb); |
3120 | int s, j, count = 0; | 3110 | int s, j, count = 0; |
3121 | 3111 | ||
3112 | if (!EXT4_HAS_RO_COMPAT_FEATURE(sb, EXT4_FEATURE_RO_COMPAT_BIGALLOC)) | ||
3113 | return (ext4_bg_has_super(sb, grp) + ext4_bg_num_gdb(sb, grp) + | ||
3114 | sbi->s_itb_per_group + 2); | ||
3115 | |||
3122 | first_block = le32_to_cpu(sbi->s_es->s_first_data_block) + | 3116 | first_block = le32_to_cpu(sbi->s_es->s_first_data_block) + |
3123 | (grp * EXT4_BLOCKS_PER_GROUP(sb)); | 3117 | (grp * EXT4_BLOCKS_PER_GROUP(sb)); |
3124 | last_block = first_block + EXT4_BLOCKS_PER_GROUP(sb) - 1; | 3118 | last_block = first_block + EXT4_BLOCKS_PER_GROUP(sb) - 1; |
@@ -4430,6 +4424,7 @@ static void ext4_clear_journal_err(struct super_block *sb, | |||
4430 | ext4_commit_super(sb, 1); | 4424 | ext4_commit_super(sb, 1); |
4431 | 4425 | ||
4432 | jbd2_journal_clear_err(journal); | 4426 | jbd2_journal_clear_err(journal); |
4427 | jbd2_journal_update_sb_errno(journal); | ||
4433 | } | 4428 | } |
4434 | } | 4429 | } |
4435 | 4430 | ||
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 8964cf3999b2..324bc0850534 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -383,6 +383,9 @@ static int fuse_create_open(struct inode *dir, struct dentry *entry, | |||
383 | struct fuse_entry_out outentry; | 383 | struct fuse_entry_out outentry; |
384 | struct fuse_file *ff; | 384 | struct fuse_file *ff; |
385 | 385 | ||
386 | /* Userspace expects S_IFREG in create mode */ | ||
387 | BUG_ON((mode & S_IFMT) != S_IFREG); | ||
388 | |||
386 | forget = fuse_alloc_forget(); | 389 | forget = fuse_alloc_forget(); |
387 | err = -ENOMEM; | 390 | err = -ENOMEM; |
388 | if (!forget) | 391 | if (!forget) |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 93d8d6c9494d..aba15f1b7ad2 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -703,13 +703,16 @@ static ssize_t fuse_file_aio_read(struct kiocb *iocb, const struct iovec *iov, | |||
703 | unsigned long nr_segs, loff_t pos) | 703 | unsigned long nr_segs, loff_t pos) |
704 | { | 704 | { |
705 | struct inode *inode = iocb->ki_filp->f_mapping->host; | 705 | struct inode *inode = iocb->ki_filp->f_mapping->host; |
706 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
706 | 707 | ||
707 | if (pos + iov_length(iov, nr_segs) > i_size_read(inode)) { | 708 | /* |
709 | * In auto invalidate mode, always update attributes on read. | ||
710 | * Otherwise, only update if we attempt to read past EOF (to ensure | ||
711 | * i_size is up to date). | ||
712 | */ | ||
713 | if (fc->auto_inval_data || | ||
714 | (pos + iov_length(iov, nr_segs) > i_size_read(inode))) { | ||
708 | int err; | 715 | int err; |
709 | /* | ||
710 | * If trying to read past EOF, make sure the i_size | ||
711 | * attribute is up-to-date. | ||
712 | */ | ||
713 | err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL); | 716 | err = fuse_update_attributes(inode, NULL, iocb->ki_filp, NULL); |
714 | if (err) | 717 | if (err) |
715 | return err; | 718 | return err; |
@@ -1700,7 +1703,7 @@ static int fuse_verify_ioctl_iov(struct iovec *iov, size_t count) | |||
1700 | size_t n; | 1703 | size_t n; |
1701 | u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT; | 1704 | u32 max = FUSE_MAX_PAGES_PER_REQ << PAGE_SHIFT; |
1702 | 1705 | ||
1703 | for (n = 0; n < count; n++) { | 1706 | for (n = 0; n < count; n++, iov++) { |
1704 | if (iov->iov_len > (size_t) max) | 1707 | if (iov->iov_len > (size_t) max) |
1705 | return -ENOMEM; | 1708 | return -ENOMEM; |
1706 | max -= iov->iov_len; | 1709 | max -= iov->iov_len; |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index 771fb6322c07..e24dd74e3068 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -484,6 +484,9 @@ struct fuse_conn { | |||
484 | /** Is fallocate not implemented by fs? */ | 484 | /** Is fallocate not implemented by fs? */ |
485 | unsigned no_fallocate:1; | 485 | unsigned no_fallocate:1; |
486 | 486 | ||
487 | /** Use enhanced/automatic page cache invalidation. */ | ||
488 | unsigned auto_inval_data:1; | ||
489 | |||
487 | /** The number of requests waiting for completion */ | 490 | /** The number of requests waiting for completion */ |
488 | atomic_t num_waiting; | 491 | atomic_t num_waiting; |
489 | 492 | ||
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 1cd61652018c..ce0a2838ccd0 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -197,6 +197,7 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, | |||
197 | struct fuse_conn *fc = get_fuse_conn(inode); | 197 | struct fuse_conn *fc = get_fuse_conn(inode); |
198 | struct fuse_inode *fi = get_fuse_inode(inode); | 198 | struct fuse_inode *fi = get_fuse_inode(inode); |
199 | loff_t oldsize; | 199 | loff_t oldsize; |
200 | struct timespec old_mtime; | ||
200 | 201 | ||
201 | spin_lock(&fc->lock); | 202 | spin_lock(&fc->lock); |
202 | if (attr_version != 0 && fi->attr_version > attr_version) { | 203 | if (attr_version != 0 && fi->attr_version > attr_version) { |
@@ -204,15 +205,35 @@ void fuse_change_attributes(struct inode *inode, struct fuse_attr *attr, | |||
204 | return; | 205 | return; |
205 | } | 206 | } |
206 | 207 | ||
208 | old_mtime = inode->i_mtime; | ||
207 | fuse_change_attributes_common(inode, attr, attr_valid); | 209 | fuse_change_attributes_common(inode, attr, attr_valid); |
208 | 210 | ||
209 | oldsize = inode->i_size; | 211 | oldsize = inode->i_size; |
210 | i_size_write(inode, attr->size); | 212 | i_size_write(inode, attr->size); |
211 | spin_unlock(&fc->lock); | 213 | spin_unlock(&fc->lock); |
212 | 214 | ||
213 | if (S_ISREG(inode->i_mode) && oldsize != attr->size) { | 215 | if (S_ISREG(inode->i_mode)) { |
214 | truncate_pagecache(inode, oldsize, attr->size); | 216 | bool inval = false; |
215 | invalidate_inode_pages2(inode->i_mapping); | 217 | |
218 | if (oldsize != attr->size) { | ||
219 | truncate_pagecache(inode, oldsize, attr->size); | ||
220 | inval = true; | ||
221 | } else if (fc->auto_inval_data) { | ||
222 | struct timespec new_mtime = { | ||
223 | .tv_sec = attr->mtime, | ||
224 | .tv_nsec = attr->mtimensec, | ||
225 | }; | ||
226 | |||
227 | /* | ||
228 | * Auto inval mode also checks and invalidates if mtime | ||
229 | * has changed. | ||
230 | */ | ||
231 | if (!timespec_equal(&old_mtime, &new_mtime)) | ||
232 | inval = true; | ||
233 | } | ||
234 | |||
235 | if (inval) | ||
236 | invalidate_inode_pages2(inode->i_mapping); | ||
216 | } | 237 | } |
217 | } | 238 | } |
218 | 239 | ||
@@ -834,6 +855,8 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
834 | fc->big_writes = 1; | 855 | fc->big_writes = 1; |
835 | if (arg->flags & FUSE_DONT_MASK) | 856 | if (arg->flags & FUSE_DONT_MASK) |
836 | fc->dont_mask = 1; | 857 | fc->dont_mask = 1; |
858 | if (arg->flags & FUSE_AUTO_INVAL_DATA) | ||
859 | fc->auto_inval_data = 1; | ||
837 | } else { | 860 | } else { |
838 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; | 861 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; |
839 | fc->no_lock = 1; | 862 | fc->no_lock = 1; |
@@ -859,7 +882,8 @@ static void fuse_send_init(struct fuse_conn *fc, struct fuse_req *req) | |||
859 | arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE; | 882 | arg->max_readahead = fc->bdi.ra_pages * PAGE_CACHE_SIZE; |
860 | arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC | | 883 | arg->flags |= FUSE_ASYNC_READ | FUSE_POSIX_LOCKS | FUSE_ATOMIC_O_TRUNC | |
861 | FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK | | 884 | FUSE_EXPORT_SUPPORT | FUSE_BIG_WRITES | FUSE_DONT_MASK | |
862 | FUSE_FLOCK_LOCKS; | 885 | FUSE_SPLICE_WRITE | FUSE_SPLICE_MOVE | FUSE_SPLICE_READ | |
886 | FUSE_FLOCK_LOCKS | FUSE_IOCTL_DIR | FUSE_AUTO_INVAL_DATA; | ||
863 | req->in.h.opcode = FUSE_INIT; | 887 | req->in.h.opcode = FUSE_INIT; |
864 | req->in.numargs = 1; | 888 | req->in.numargs = 1; |
865 | req->in.args[0].size = sizeof(*arg); | 889 | req->in.args[0].size = sizeof(*arg); |
diff --git a/fs/gfs2/meta_io.c b/fs/gfs2/meta_io.c index 3a56c8d94de0..22255d96b27e 100644 --- a/fs/gfs2/meta_io.c +++ b/fs/gfs2/meta_io.c | |||
@@ -52,7 +52,7 @@ static int gfs2_aspace_writepage(struct page *page, struct writeback_control *wb | |||
52 | /* | 52 | /* |
53 | * If it's a fully non-blocking write attempt and we cannot | 53 | * If it's a fully non-blocking write attempt and we cannot |
54 | * lock the buffer then redirty the page. Note that this can | 54 | * lock the buffer then redirty the page. Note that this can |
55 | * potentially cause a busy-wait loop from pdflush and kswapd | 55 | * potentially cause a busy-wait loop from flusher thread and kswapd |
56 | * activity, but those code paths have their own higher-level | 56 | * activity, but those code paths have their own higher-level |
57 | * throttling. | 57 | * throttling. |
58 | */ | 58 | */ |
diff --git a/fs/hfs/mdb.c b/fs/hfs/mdb.c index 5fd51a5833ff..b7ec224910c5 100644 --- a/fs/hfs/mdb.c +++ b/fs/hfs/mdb.c | |||
@@ -236,10 +236,10 @@ out: | |||
236 | * hfs_mdb_commit() | 236 | * hfs_mdb_commit() |
237 | * | 237 | * |
238 | * Description: | 238 | * Description: |
239 | * This updates the MDB on disk (look also at hfs_write_super()). | 239 | * This updates the MDB on disk. |
240 | * It does not check, if the superblock has been modified, or | 240 | * It does not check, if the superblock has been modified, or |
241 | * if the filesystem has been mounted read-only. It is mainly | 241 | * if the filesystem has been mounted read-only. It is mainly |
242 | * called by hfs_write_super() and hfs_btree_extend(). | 242 | * called by hfs_sync_fs() and flush_mdb(). |
243 | * Input Variable(s): | 243 | * Input Variable(s): |
244 | * struct hfs_mdb *mdb: Pointer to the hfs MDB | 244 | * struct hfs_mdb *mdb: Pointer to the hfs MDB |
245 | * int backup; | 245 | * int backup; |
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c index 425c2f2cf170..09357508ec9a 100644 --- a/fs/jbd/journal.c +++ b/fs/jbd/journal.c | |||
@@ -534,8 +534,8 @@ int journal_start_commit(journal_t *journal, tid_t *ptid) | |||
534 | ret = 1; | 534 | ret = 1; |
535 | } else if (journal->j_committing_transaction) { | 535 | } else if (journal->j_committing_transaction) { |
536 | /* | 536 | /* |
537 | * If ext3_write_super() recently started a commit, then we | 537 | * If commit has been started, then we have to wait for |
538 | * have to wait for completion of that transaction | 538 | * completion of that transaction. |
539 | */ | 539 | */ |
540 | if (ptid) | 540 | if (ptid) |
541 | *ptid = journal->j_committing_transaction->t_tid; | 541 | *ptid = journal->j_committing_transaction->t_tid; |
diff --git a/fs/jbd2/journal.c b/fs/jbd2/journal.c index e9a3c4c85594..e149b99a7ffb 100644 --- a/fs/jbd2/journal.c +++ b/fs/jbd2/journal.c | |||
@@ -612,8 +612,8 @@ int jbd2_journal_start_commit(journal_t *journal, tid_t *ptid) | |||
612 | ret = 1; | 612 | ret = 1; |
613 | } else if (journal->j_committing_transaction) { | 613 | } else if (journal->j_committing_transaction) { |
614 | /* | 614 | /* |
615 | * If ext3_write_super() recently started a commit, then we | 615 | * If commit has been started, then we have to wait for |
616 | * have to wait for completion of that transaction | 616 | * completion of that transaction. |
617 | */ | 617 | */ |
618 | if (ptid) | 618 | if (ptid) |
619 | *ptid = journal->j_committing_transaction->t_tid; | 619 | *ptid = journal->j_committing_transaction->t_tid; |
@@ -1377,7 +1377,7 @@ static void jbd2_mark_journal_empty(journal_t *journal) | |||
1377 | * Update a journal's errno. Write updated superblock to disk waiting for IO | 1377 | * Update a journal's errno. Write updated superblock to disk waiting for IO |
1378 | * to complete. | 1378 | * to complete. |
1379 | */ | 1379 | */ |
1380 | static void jbd2_journal_update_sb_errno(journal_t *journal) | 1380 | void jbd2_journal_update_sb_errno(journal_t *journal) |
1381 | { | 1381 | { |
1382 | journal_superblock_t *sb = journal->j_superblock; | 1382 | journal_superblock_t *sb = journal->j_superblock; |
1383 | 1383 | ||
@@ -1390,6 +1390,7 @@ static void jbd2_journal_update_sb_errno(journal_t *journal) | |||
1390 | 1390 | ||
1391 | jbd2_write_superblock(journal, WRITE_SYNC); | 1391 | jbd2_write_superblock(journal, WRITE_SYNC); |
1392 | } | 1392 | } |
1393 | EXPORT_SYMBOL(jbd2_journal_update_sb_errno); | ||
1393 | 1394 | ||
1394 | /* | 1395 | /* |
1395 | * Read the superblock for a given journal, performing initial | 1396 | * Read the superblock for a given journal, performing initial |
diff --git a/fs/namei.c b/fs/namei.c index 1b464390dde8..db76b866a097 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -2414,7 +2414,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2414 | goto out; | 2414 | goto out; |
2415 | } | 2415 | } |
2416 | 2416 | ||
2417 | mode = op->mode & S_IALLUGO; | 2417 | mode = op->mode; |
2418 | if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) | 2418 | if ((open_flag & O_CREAT) && !IS_POSIXACL(dir)) |
2419 | mode &= ~current_umask(); | 2419 | mode &= ~current_umask(); |
2420 | 2420 | ||
@@ -2452,7 +2452,7 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2452 | } | 2452 | } |
2453 | 2453 | ||
2454 | if (open_flag & O_CREAT) { | 2454 | if (open_flag & O_CREAT) { |
2455 | error = may_o_create(&nd->path, dentry, op->mode); | 2455 | error = may_o_create(&nd->path, dentry, mode); |
2456 | if (error) { | 2456 | if (error) { |
2457 | create_error = error; | 2457 | create_error = error; |
2458 | if (open_flag & O_EXCL) | 2458 | if (open_flag & O_EXCL) |
@@ -2489,6 +2489,10 @@ static int atomic_open(struct nameidata *nd, struct dentry *dentry, | |||
2489 | dput(dentry); | 2489 | dput(dentry); |
2490 | dentry = file->f_path.dentry; | 2490 | dentry = file->f_path.dentry; |
2491 | } | 2491 | } |
2492 | if (create_error && dentry->d_inode == NULL) { | ||
2493 | error = create_error; | ||
2494 | goto out; | ||
2495 | } | ||
2492 | goto looked_up; | 2496 | goto looked_up; |
2493 | } | 2497 | } |
2494 | 2498 | ||
diff --git a/fs/nilfs2/super.c b/fs/nilfs2/super.c index 6522cac6057c..6a10812711c1 100644 --- a/fs/nilfs2/super.c +++ b/fs/nilfs2/super.c | |||
@@ -676,17 +676,13 @@ static const struct super_operations nilfs_sops = { | |||
676 | .alloc_inode = nilfs_alloc_inode, | 676 | .alloc_inode = nilfs_alloc_inode, |
677 | .destroy_inode = nilfs_destroy_inode, | 677 | .destroy_inode = nilfs_destroy_inode, |
678 | .dirty_inode = nilfs_dirty_inode, | 678 | .dirty_inode = nilfs_dirty_inode, |
679 | /* .write_inode = nilfs_write_inode, */ | ||
680 | /* .drop_inode = nilfs_drop_inode, */ | ||
681 | .evict_inode = nilfs_evict_inode, | 679 | .evict_inode = nilfs_evict_inode, |
682 | .put_super = nilfs_put_super, | 680 | .put_super = nilfs_put_super, |
683 | /* .write_super = nilfs_write_super, */ | ||
684 | .sync_fs = nilfs_sync_fs, | 681 | .sync_fs = nilfs_sync_fs, |
685 | .freeze_fs = nilfs_freeze, | 682 | .freeze_fs = nilfs_freeze, |
686 | .unfreeze_fs = nilfs_unfreeze, | 683 | .unfreeze_fs = nilfs_unfreeze, |
687 | .statfs = nilfs_statfs, | 684 | .statfs = nilfs_statfs, |
688 | .remount_fs = nilfs_remount, | 685 | .remount_fs = nilfs_remount, |
689 | /* .umount_begin */ | ||
690 | .show_options = nilfs_show_options | 686 | .show_options = nilfs_show_options |
691 | }; | 687 | }; |
692 | 688 | ||
diff --git a/fs/nilfs2/the_nilfs.h b/fs/nilfs2/the_nilfs.h index 6eee4177807b..be1267a34cea 100644 --- a/fs/nilfs2/the_nilfs.h +++ b/fs/nilfs2/the_nilfs.h | |||
@@ -107,8 +107,6 @@ struct the_nilfs { | |||
107 | * used for | 107 | * used for |
108 | * - loading the latest checkpoint exclusively. | 108 | * - loading the latest checkpoint exclusively. |
109 | * - allocating a new full segment. | 109 | * - allocating a new full segment. |
110 | * - protecting s_dirt in the super_block struct | ||
111 | * (see nilfs_write_super) and the following fields. | ||
112 | */ | 110 | */ |
113 | struct buffer_head *ns_sbh[2]; | 111 | struct buffer_head *ns_sbh[2]; |
114 | struct nilfs_super_block *ns_sbp[2]; | 112 | struct nilfs_super_block *ns_sbp[2]; |
@@ -717,7 +717,7 @@ cleanup_all: | |||
717 | * here, so just reset the state. | 717 | * here, so just reset the state. |
718 | */ | 718 | */ |
719 | file_reset_write(f); | 719 | file_reset_write(f); |
720 | mnt_drop_write(f->f_path.mnt); | 720 | __mnt_drop_write(f->f_path.mnt); |
721 | } | 721 | } |
722 | } | 722 | } |
723 | cleanup_file: | 723 | cleanup_file: |
@@ -852,9 +852,10 @@ static inline int build_open_flags(int flags, umode_t mode, struct open_flags *o | |||
852 | int lookup_flags = 0; | 852 | int lookup_flags = 0; |
853 | int acc_mode; | 853 | int acc_mode; |
854 | 854 | ||
855 | if (!(flags & O_CREAT)) | 855 | if (flags & O_CREAT) |
856 | mode = 0; | 856 | op->mode = (mode & S_IALLUGO) | S_IFREG; |
857 | op->mode = mode; | 857 | else |
858 | op->mode = 0; | ||
858 | 859 | ||
859 | /* Must never be set by userspace */ | 860 | /* Must never be set by userspace */ |
860 | flags &= ~FMODE_NONOTIFY; | 861 | flags &= ~FMODE_NONOTIFY; |
diff --git a/fs/super.c b/fs/super.c index b05cf47463d0..0902cfa6a12e 100644 --- a/fs/super.c +++ b/fs/super.c | |||
@@ -537,46 +537,6 @@ void drop_super(struct super_block *sb) | |||
537 | EXPORT_SYMBOL(drop_super); | 537 | EXPORT_SYMBOL(drop_super); |
538 | 538 | ||
539 | /** | 539 | /** |
540 | * sync_supers - helper for periodic superblock writeback | ||
541 | * | ||
542 | * Call the write_super method if present on all dirty superblocks in | ||
543 | * the system. This is for the periodic writeback used by most older | ||
544 | * filesystems. For data integrity superblock writeback use | ||
545 | * sync_filesystems() instead. | ||
546 | * | ||
547 | * Note: check the dirty flag before waiting, so we don't | ||
548 | * hold up the sync while mounting a device. (The newly | ||
549 | * mounted device won't need syncing.) | ||
550 | */ | ||
551 | void sync_supers(void) | ||
552 | { | ||
553 | struct super_block *sb, *p = NULL; | ||
554 | |||
555 | spin_lock(&sb_lock); | ||
556 | list_for_each_entry(sb, &super_blocks, s_list) { | ||
557 | if (hlist_unhashed(&sb->s_instances)) | ||
558 | continue; | ||
559 | if (sb->s_op->write_super && sb->s_dirt) { | ||
560 | sb->s_count++; | ||
561 | spin_unlock(&sb_lock); | ||
562 | |||
563 | down_read(&sb->s_umount); | ||
564 | if (sb->s_root && sb->s_dirt && (sb->s_flags & MS_BORN)) | ||
565 | sb->s_op->write_super(sb); | ||
566 | up_read(&sb->s_umount); | ||
567 | |||
568 | spin_lock(&sb_lock); | ||
569 | if (p) | ||
570 | __put_super(p); | ||
571 | p = sb; | ||
572 | } | ||
573 | } | ||
574 | if (p) | ||
575 | __put_super(p); | ||
576 | spin_unlock(&sb_lock); | ||
577 | } | ||
578 | |||
579 | /** | ||
580 | * iterate_supers - call function for all active superblocks | 540 | * iterate_supers - call function for all active superblocks |
581 | * @f: function to call | 541 | * @f: function to call |
582 | * @arg: argument to pass to it | 542 | * @arg: argument to pass to it |
diff --git a/fs/ubifs/file.c b/fs/ubifs/file.c index 35389ca2d267..7bd6e72afd11 100644 --- a/fs/ubifs/file.c +++ b/fs/ubifs/file.c | |||
@@ -37,11 +37,11 @@ | |||
37 | * | 37 | * |
38 | * A thing to keep in mind: inode @i_mutex is locked in most VFS operations we | 38 | * A thing to keep in mind: inode @i_mutex is locked in most VFS operations we |
39 | * implement. However, this is not true for 'ubifs_writepage()', which may be | 39 | * implement. However, this is not true for 'ubifs_writepage()', which may be |
40 | * called with @i_mutex unlocked. For example, when pdflush is doing background | 40 | * called with @i_mutex unlocked. For example, when flusher thread is doing |
41 | * write-back, it calls 'ubifs_writepage()' with unlocked @i_mutex. At "normal" | 41 | * background write-back, it calls 'ubifs_writepage()' with unlocked @i_mutex. |
42 | * work-paths the @i_mutex is locked in 'ubifs_writepage()', e.g. in the | 42 | * At "normal" work-paths the @i_mutex is locked in 'ubifs_writepage()', e.g. |
43 | * "sys_write -> alloc_pages -> direct reclaim path". So, in 'ubifs_writepage()' | 43 | * in the "sys_write -> alloc_pages -> direct reclaim path". So, in |
44 | * we are only guaranteed that the page is locked. | 44 | * 'ubifs_writepage()' we are only guaranteed that the page is locked. |
45 | * | 45 | * |
46 | * Similarly, @i_mutex is not always locked in 'ubifs_readpage()', e.g., the | 46 | * Similarly, @i_mutex is not always locked in 'ubifs_readpage()', e.g., the |
47 | * read-ahead path does not lock it ("sys_read -> generic_file_aio_read -> | 47 | * read-ahead path does not lock it ("sys_read -> generic_file_aio_read -> |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index 1c766c39c038..c3fa6c5327a3 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -303,7 +303,7 @@ static int ubifs_write_inode(struct inode *inode, struct writeback_control *wbc) | |||
303 | mutex_lock(&ui->ui_mutex); | 303 | mutex_lock(&ui->ui_mutex); |
304 | /* | 304 | /* |
305 | * Due to races between write-back forced by budgeting | 305 | * Due to races between write-back forced by budgeting |
306 | * (see 'sync_some_inodes()') and pdflush write-back, the inode may | 306 | * (see 'sync_some_inodes()') and background write-back, the inode may |
307 | * have already been synchronized, do not do this again. This might | 307 | * have already been synchronized, do not do this again. This might |
308 | * also happen if it was synchronized in an VFS operation, e.g. | 308 | * also happen if it was synchronized in an VFS operation, e.g. |
309 | * 'ubifs_link()'. | 309 | * 'ubifs_link()'. |
diff --git a/include/acpi/acpixf.h b/include/acpi/acpixf.h index 2c744c7a5b3d..26a92fc28a59 100644 --- a/include/acpi/acpixf.h +++ b/include/acpi/acpixf.h | |||
@@ -491,11 +491,11 @@ acpi_get_sleep_type_data(u8 sleep_state, u8 * slp_typ_a, u8 * slp_typ_b); | |||
491 | 491 | ||
492 | acpi_status acpi_enter_sleep_state_prep(u8 sleep_state); | 492 | acpi_status acpi_enter_sleep_state_prep(u8 sleep_state); |
493 | 493 | ||
494 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state, u8 flags); | 494 | acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state); |
495 | 495 | ||
496 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)) | 496 | ACPI_HW_DEPENDENT_RETURN_STATUS(acpi_status asmlinkage acpi_enter_sleep_state_s4bios(void)) |
497 | 497 | ||
498 | acpi_status acpi_leave_sleep_state_prep(u8 sleep_state, u8 flags); | 498 | acpi_status acpi_leave_sleep_state_prep(u8 sleep_state); |
499 | 499 | ||
500 | acpi_status acpi_leave_sleep_state(u8 sleep_state); | 500 | acpi_status acpi_leave_sleep_state(u8 sleep_state); |
501 | 501 | ||
diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h index 3af87de6a68c..3d00bd5bd7e3 100644 --- a/include/acpi/actypes.h +++ b/include/acpi/actypes.h | |||
@@ -803,7 +803,7 @@ typedef u8 acpi_adr_space_type; | |||
803 | 803 | ||
804 | /* Sleep function dispatch */ | 804 | /* Sleep function dispatch */ |
805 | 805 | ||
806 | typedef acpi_status(*ACPI_SLEEP_FUNCTION) (u8 sleep_state, u8 flags); | 806 | typedef acpi_status(*ACPI_SLEEP_FUNCTION) (u8 sleep_state); |
807 | 807 | ||
808 | struct acpi_sleep_functions { | 808 | struct acpi_sleep_functions { |
809 | ACPI_SLEEP_FUNCTION legacy_function; | 809 | ACPI_SLEEP_FUNCTION legacy_function; |
diff --git a/include/asm-generic/mutex-xchg.h b/include/asm-generic/mutex-xchg.h index 580a6d35c700..c04e0db8a2d6 100644 --- a/include/asm-generic/mutex-xchg.h +++ b/include/asm-generic/mutex-xchg.h | |||
@@ -26,7 +26,13 @@ static inline void | |||
26 | __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) | 26 | __mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *)) |
27 | { | 27 | { |
28 | if (unlikely(atomic_xchg(count, 0) != 1)) | 28 | if (unlikely(atomic_xchg(count, 0) != 1)) |
29 | fail_fn(count); | 29 | /* |
30 | * We failed to acquire the lock, so mark it contended | ||
31 | * to ensure that any waiting tasks are woken up by the | ||
32 | * unlock slow path. | ||
33 | */ | ||
34 | if (likely(atomic_xchg(count, -1) != 1)) | ||
35 | fail_fn(count); | ||
30 | } | 36 | } |
31 | 37 | ||
32 | /** | 38 | /** |
@@ -43,7 +49,8 @@ static inline int | |||
43 | __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) | 49 | __mutex_fastpath_lock_retval(atomic_t *count, int (*fail_fn)(atomic_t *)) |
44 | { | 50 | { |
45 | if (unlikely(atomic_xchg(count, 0) != 1)) | 51 | if (unlikely(atomic_xchg(count, 0) != 1)) |
46 | return fail_fn(count); | 52 | if (likely(atomic_xchg(count, -1) != 1)) |
53 | return fail_fn(count); | ||
47 | return 0; | 54 | return 0; |
48 | } | 55 | } |
49 | 56 | ||
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 7ff5c99b1638..c78bb997e2c6 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h | |||
@@ -213,9 +213,12 @@ | |||
213 | {0x1002, 0x6800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 213 | {0x1002, 0x6800, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
214 | {0x1002, 0x6801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 214 | {0x1002, 0x6801, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
215 | {0x1002, 0x6802, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 215 | {0x1002, 0x6802, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
216 | {0x1002, 0x6806, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | ||
216 | {0x1002, 0x6808, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | 217 | {0x1002, 0x6808, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ |
217 | {0x1002, 0x6809, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | 218 | {0x1002, 0x6809, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ |
218 | {0x1002, 0x6810, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | 219 | {0x1002, 0x6810, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ |
220 | {0x1002, 0x6816, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | ||
221 | {0x1002, 0x6817, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | ||
219 | {0x1002, 0x6818, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | 222 | {0x1002, 0x6818, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ |
220 | {0x1002, 0x6819, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ | 223 | {0x1002, 0x6819, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PITCAIRN|RADEON_NEW_MEMMAP}, \ |
221 | {0x1002, 0x6820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ | 224 | {0x1002, 0x6820, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_VERDE|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \ |
diff --git a/include/drm/radeon_drm.h b/include/drm/radeon_drm.h index 58056865b8e9..dc3a8cd7db8a 100644 --- a/include/drm/radeon_drm.h +++ b/include/drm/radeon_drm.h | |||
@@ -964,6 +964,8 @@ struct drm_radeon_cs { | |||
964 | #define RADEON_INFO_IB_VM_MAX_SIZE 0x0f | 964 | #define RADEON_INFO_IB_VM_MAX_SIZE 0x0f |
965 | /* max pipes - needed for compute shaders */ | 965 | /* max pipes - needed for compute shaders */ |
966 | #define RADEON_INFO_MAX_PIPES 0x10 | 966 | #define RADEON_INFO_MAX_PIPES 0x10 |
967 | /* timestamp for GL_ARB_timer_query (OpenGL), returns the current GPU clock */ | ||
968 | #define RADEON_INFO_TIMESTAMP 0x11 | ||
967 | 969 | ||
968 | struct drm_radeon_info { | 970 | struct drm_radeon_info { |
969 | uint32_t request; | 971 | uint32_t request; |
diff --git a/include/linux/Kbuild b/include/linux/Kbuild index d823d603dadd..1f2c1c787f17 100644 --- a/include/linux/Kbuild +++ b/include/linux/Kbuild | |||
@@ -392,6 +392,7 @@ header-y += v4l2-dv-timings.h | |||
392 | header-y += v4l2-mediabus.h | 392 | header-y += v4l2-mediabus.h |
393 | header-y += v4l2-subdev.h | 393 | header-y += v4l2-subdev.h |
394 | header-y += veth.h | 394 | header-y += veth.h |
395 | header-y += vfio.h | ||
395 | header-y += vhost.h | 396 | header-y += vhost.h |
396 | header-y += videodev2.h | 397 | header-y += videodev2.h |
397 | header-y += virtio_9p.h | 398 | header-y += virtio_9p.h |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 3ad510b25283..4f2a76224509 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -96,7 +96,7 @@ void acpi_table_print_madt_entry (struct acpi_subtable_header *madt); | |||
96 | void acpi_numa_slit_init (struct acpi_table_slit *slit); | 96 | void acpi_numa_slit_init (struct acpi_table_slit *slit); |
97 | void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa); | 97 | void acpi_numa_processor_affinity_init (struct acpi_srat_cpu_affinity *pa); |
98 | void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa); | 98 | void acpi_numa_x2apic_affinity_init(struct acpi_srat_x2apic_cpu_affinity *pa); |
99 | void acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma); | 99 | int acpi_numa_memory_affinity_init (struct acpi_srat_mem_affinity *ma); |
100 | void acpi_numa_arch_fixup(void); | 100 | void acpi_numa_arch_fixup(void); |
101 | 101 | ||
102 | #ifdef CONFIG_ACPI_HOTPLUG_CPU | 102 | #ifdef CONFIG_ACPI_HOTPLUG_CPU |
diff --git a/include/linux/backing-dev.h b/include/linux/backing-dev.h index c97c6b9cd38e..2a9a9abc9126 100644 --- a/include/linux/backing-dev.h +++ b/include/linux/backing-dev.h | |||
@@ -124,7 +124,6 @@ void bdi_start_writeback(struct backing_dev_info *bdi, long nr_pages, | |||
124 | void bdi_start_background_writeback(struct backing_dev_info *bdi); | 124 | void bdi_start_background_writeback(struct backing_dev_info *bdi); |
125 | int bdi_writeback_thread(void *data); | 125 | int bdi_writeback_thread(void *data); |
126 | int bdi_has_dirty_io(struct backing_dev_info *bdi); | 126 | int bdi_has_dirty_io(struct backing_dev_info *bdi); |
127 | void bdi_arm_supers_timer(void); | ||
128 | void bdi_wakeup_thread_delayed(struct backing_dev_info *bdi); | 127 | void bdi_wakeup_thread_delayed(struct backing_dev_info *bdi); |
129 | void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2); | 128 | void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2); |
130 | 129 | ||
diff --git a/include/linux/can.h b/include/linux/can.h index 018055efc034..e52958d7c2d1 100644 --- a/include/linux/can.h +++ b/include/linux/can.h | |||
@@ -74,20 +74,21 @@ struct can_frame { | |||
74 | /* | 74 | /* |
75 | * defined bits for canfd_frame.flags | 75 | * defined bits for canfd_frame.flags |
76 | * | 76 | * |
77 | * As the default for CAN FD should be to support the high data rate in the | 77 | * The use of struct canfd_frame implies the Extended Data Length (EDL) bit to |
78 | * payload section of the frame (HDR) and to support up to 64 byte in the | 78 | * be set in the CAN frame bitstream on the wire. The EDL bit switch turns |
79 | * data section (EDL) the bits are only set in the non-default case. | 79 | * the CAN controllers bitstream processor into the CAN FD mode which creates |
80 | * Btw. as long as there's no real implementation for CAN FD network driver | 80 | * two new options within the CAN FD frame specification: |
81 | * these bits are only preliminary. | ||
82 | * | 81 | * |
83 | * RX: NOHDR/NOEDL - info about received CAN FD frame | 82 | * Bit Rate Switch - to indicate a second bitrate is/was used for the payload |
84 | * ESI - bit from originating CAN controller | 83 | * Error State Indicator - represents the error state of the transmitting node |
85 | * TX: NOHDR/NOEDL - control per-frame settings if supported by CAN controller | 84 | * |
86 | * ESI - bit is set by local CAN controller | 85 | * As the CANFD_ESI bit is internally generated by the transmitting CAN |
86 | * controller only the CANFD_BRS bit is relevant for real CAN controllers when | ||
87 | * building a CAN FD frame for transmission. Setting the CANFD_ESI bit can make | ||
88 | * sense for virtual CAN interfaces to test applications with echoed frames. | ||
87 | */ | 89 | */ |
88 | #define CANFD_NOHDR 0x01 /* frame without high data rate */ | 90 | #define CANFD_BRS 0x01 /* bit rate switch (second bitrate for payload data) */ |
89 | #define CANFD_NOEDL 0x02 /* frame without extended data length */ | 91 | #define CANFD_ESI 0x02 /* error state indicator of the transmitting node */ |
90 | #define CANFD_ESI 0x04 /* error state indicator */ | ||
91 | 92 | ||
92 | /** | 93 | /** |
93 | * struct canfd_frame - CAN flexible data rate frame structure | 94 | * struct canfd_frame - CAN flexible data rate frame structure |
diff --git a/include/linux/compaction.h b/include/linux/compaction.h index 133ddcf83397..ef658147e4e8 100644 --- a/include/linux/compaction.h +++ b/include/linux/compaction.h | |||
@@ -22,7 +22,7 @@ extern int sysctl_extfrag_handler(struct ctl_table *table, int write, | |||
22 | extern int fragmentation_index(struct zone *zone, unsigned int order); | 22 | extern int fragmentation_index(struct zone *zone, unsigned int order); |
23 | extern unsigned long try_to_compact_pages(struct zonelist *zonelist, | 23 | extern unsigned long try_to_compact_pages(struct zonelist *zonelist, |
24 | int order, gfp_t gfp_mask, nodemask_t *mask, | 24 | int order, gfp_t gfp_mask, nodemask_t *mask, |
25 | bool sync); | 25 | bool sync, bool *contended); |
26 | extern int compact_pgdat(pg_data_t *pgdat, int order); | 26 | extern int compact_pgdat(pg_data_t *pgdat, int order); |
27 | extern unsigned long compaction_suitable(struct zone *zone, int order); | 27 | extern unsigned long compaction_suitable(struct zone *zone, int order); |
28 | 28 | ||
@@ -64,7 +64,7 @@ static inline bool compaction_deferred(struct zone *zone, int order) | |||
64 | #else | 64 | #else |
65 | static inline unsigned long try_to_compact_pages(struct zonelist *zonelist, | 65 | static inline unsigned long try_to_compact_pages(struct zonelist *zonelist, |
66 | int order, gfp_t gfp_mask, nodemask_t *nodemask, | 66 | int order, gfp_t gfp_mask, nodemask_t *nodemask, |
67 | bool sync) | 67 | bool sync, bool *contended) |
68 | { | 68 | { |
69 | return COMPACT_CONTINUE; | 69 | return COMPACT_CONTINUE; |
70 | } | 70 | } |
diff --git a/include/linux/efi.h b/include/linux/efi.h index 103adc6d7e3a..ec45ccd8708a 100644 --- a/include/linux/efi.h +++ b/include/linux/efi.h | |||
@@ -503,6 +503,8 @@ extern u64 efi_mem_attribute (unsigned long phys_addr, unsigned long size); | |||
503 | extern int __init efi_uart_console_only (void); | 503 | extern int __init efi_uart_console_only (void); |
504 | extern void efi_initialize_iomem_resources(struct resource *code_resource, | 504 | extern void efi_initialize_iomem_resources(struct resource *code_resource, |
505 | struct resource *data_resource, struct resource *bss_resource); | 505 | struct resource *data_resource, struct resource *bss_resource); |
506 | extern unsigned long efi_get_time(void); | ||
507 | extern int efi_set_rtc_mmss(unsigned long nowtime); | ||
506 | extern void efi_reserve_boot_services(void); | 508 | extern void efi_reserve_boot_services(void); |
507 | extern struct efi_memory_map memmap; | 509 | extern struct efi_memory_map memmap; |
508 | 510 | ||
diff --git a/include/linux/fs.h b/include/linux/fs.h index 38dba16c4176..aa110476a95b 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h | |||
@@ -1491,7 +1491,6 @@ struct sb_writers { | |||
1491 | struct super_block { | 1491 | struct super_block { |
1492 | struct list_head s_list; /* Keep this first */ | 1492 | struct list_head s_list; /* Keep this first */ |
1493 | dev_t s_dev; /* search index; _not_ kdev_t */ | 1493 | dev_t s_dev; /* search index; _not_ kdev_t */ |
1494 | unsigned char s_dirt; | ||
1495 | unsigned char s_blocksize_bits; | 1494 | unsigned char s_blocksize_bits; |
1496 | unsigned long s_blocksize; | 1495 | unsigned long s_blocksize; |
1497 | loff_t s_maxbytes; /* Max file size */ | 1496 | loff_t s_maxbytes; /* Max file size */ |
@@ -1861,7 +1860,6 @@ struct super_operations { | |||
1861 | int (*drop_inode) (struct inode *); | 1860 | int (*drop_inode) (struct inode *); |
1862 | void (*evict_inode) (struct inode *); | 1861 | void (*evict_inode) (struct inode *); |
1863 | void (*put_super) (struct super_block *); | 1862 | void (*put_super) (struct super_block *); |
1864 | void (*write_super) (struct super_block *); | ||
1865 | int (*sync_fs)(struct super_block *sb, int wait); | 1863 | int (*sync_fs)(struct super_block *sb, int wait); |
1866 | int (*freeze_fs) (struct super_block *); | 1864 | int (*freeze_fs) (struct super_block *); |
1867 | int (*unfreeze_fs) (struct super_block *); | 1865 | int (*unfreeze_fs) (struct super_block *); |
@@ -2397,7 +2395,6 @@ extern int vfs_fsync_range(struct file *file, loff_t start, loff_t end, | |||
2397 | int datasync); | 2395 | int datasync); |
2398 | extern int vfs_fsync(struct file *file, int datasync); | 2396 | extern int vfs_fsync(struct file *file, int datasync); |
2399 | extern int generic_write_sync(struct file *file, loff_t pos, loff_t count); | 2397 | extern int generic_write_sync(struct file *file, loff_t pos, loff_t count); |
2400 | extern void sync_supers(void); | ||
2401 | extern void emergency_sync(void); | 2398 | extern void emergency_sync(void); |
2402 | extern void emergency_remount(void); | 2399 | extern void emergency_remount(void); |
2403 | #ifdef CONFIG_BLOCK | 2400 | #ifdef CONFIG_BLOCK |
diff --git a/include/linux/ftrace_event.h b/include/linux/ftrace_event.h index af961d6f7ab1..642928cf57b4 100644 --- a/include/linux/ftrace_event.h +++ b/include/linux/ftrace_event.h | |||
@@ -306,9 +306,10 @@ extern void *perf_trace_buf_prepare(int size, unsigned short type, | |||
306 | 306 | ||
307 | static inline void | 307 | static inline void |
308 | perf_trace_buf_submit(void *raw_data, int size, int rctx, u64 addr, | 308 | perf_trace_buf_submit(void *raw_data, int size, int rctx, u64 addr, |
309 | u64 count, struct pt_regs *regs, void *head) | 309 | u64 count, struct pt_regs *regs, void *head, |
310 | struct task_struct *task) | ||
310 | { | 311 | { |
311 | perf_tp_event(addr, count, raw_data, size, regs, head, rctx); | 312 | perf_tp_event(addr, count, raw_data, size, regs, head, rctx, task); |
312 | } | 313 | } |
313 | #endif | 314 | #endif |
314 | 315 | ||
diff --git a/include/linux/fuse.h b/include/linux/fuse.h index 9303348965fb..d8c713e148e3 100644 --- a/include/linux/fuse.h +++ b/include/linux/fuse.h | |||
@@ -57,6 +57,9 @@ | |||
57 | * | 57 | * |
58 | * 7.19 | 58 | * 7.19 |
59 | * - add FUSE_FALLOCATE | 59 | * - add FUSE_FALLOCATE |
60 | * | ||
61 | * 7.20 | ||
62 | * - add FUSE_AUTO_INVAL_DATA | ||
60 | */ | 63 | */ |
61 | 64 | ||
62 | #ifndef _LINUX_FUSE_H | 65 | #ifndef _LINUX_FUSE_H |
@@ -88,7 +91,7 @@ | |||
88 | #define FUSE_KERNEL_VERSION 7 | 91 | #define FUSE_KERNEL_VERSION 7 |
89 | 92 | ||
90 | /** Minor version number of this interface */ | 93 | /** Minor version number of this interface */ |
91 | #define FUSE_KERNEL_MINOR_VERSION 19 | 94 | #define FUSE_KERNEL_MINOR_VERSION 20 |
92 | 95 | ||
93 | /** The node ID of the root inode */ | 96 | /** The node ID of the root inode */ |
94 | #define FUSE_ROOT_ID 1 | 97 | #define FUSE_ROOT_ID 1 |
@@ -163,10 +166,19 @@ struct fuse_file_lock { | |||
163 | /** | 166 | /** |
164 | * INIT request/reply flags | 167 | * INIT request/reply flags |
165 | * | 168 | * |
169 | * FUSE_ASYNC_READ: asynchronous read requests | ||
166 | * FUSE_POSIX_LOCKS: remote locking for POSIX file locks | 170 | * FUSE_POSIX_LOCKS: remote locking for POSIX file locks |
171 | * FUSE_FILE_OPS: kernel sends file handle for fstat, etc... (not yet supported) | ||
172 | * FUSE_ATOMIC_O_TRUNC: handles the O_TRUNC open flag in the filesystem | ||
167 | * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".." | 173 | * FUSE_EXPORT_SUPPORT: filesystem handles lookups of "." and ".." |
174 | * FUSE_BIG_WRITES: filesystem can handle write size larger than 4kB | ||
168 | * FUSE_DONT_MASK: don't apply umask to file mode on create operations | 175 | * FUSE_DONT_MASK: don't apply umask to file mode on create operations |
176 | * FUSE_SPLICE_WRITE: kernel supports splice write on the device | ||
177 | * FUSE_SPLICE_MOVE: kernel supports splice move on the device | ||
178 | * FUSE_SPLICE_READ: kernel supports splice read on the device | ||
169 | * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks | 179 | * FUSE_FLOCK_LOCKS: remote locking for BSD style file locks |
180 | * FUSE_HAS_IOCTL_DIR: kernel supports ioctl on directories | ||
181 | * FUSE_AUTO_INVAL_DATA: automatically invalidate cached pages | ||
170 | */ | 182 | */ |
171 | #define FUSE_ASYNC_READ (1 << 0) | 183 | #define FUSE_ASYNC_READ (1 << 0) |
172 | #define FUSE_POSIX_LOCKS (1 << 1) | 184 | #define FUSE_POSIX_LOCKS (1 << 1) |
@@ -175,7 +187,12 @@ struct fuse_file_lock { | |||
175 | #define FUSE_EXPORT_SUPPORT (1 << 4) | 187 | #define FUSE_EXPORT_SUPPORT (1 << 4) |
176 | #define FUSE_BIG_WRITES (1 << 5) | 188 | #define FUSE_BIG_WRITES (1 << 5) |
177 | #define FUSE_DONT_MASK (1 << 6) | 189 | #define FUSE_DONT_MASK (1 << 6) |
190 | #define FUSE_SPLICE_WRITE (1 << 7) | ||
191 | #define FUSE_SPLICE_MOVE (1 << 8) | ||
192 | #define FUSE_SPLICE_READ (1 << 9) | ||
178 | #define FUSE_FLOCK_LOCKS (1 << 10) | 193 | #define FUSE_FLOCK_LOCKS (1 << 10) |
194 | #define FUSE_HAS_IOCTL_DIR (1 << 11) | ||
195 | #define FUSE_AUTO_INVAL_DATA (1 << 12) | ||
179 | 196 | ||
180 | /** | 197 | /** |
181 | * CUSE INIT request/reply flags | 198 | * CUSE INIT request/reply flags |
diff --git a/include/linux/hardirq.h b/include/linux/hardirq.h index bb7f30971858..305f23cd7cff 100644 --- a/include/linux/hardirq.h +++ b/include/linux/hardirq.h | |||
@@ -22,7 +22,7 @@ | |||
22 | * | 22 | * |
23 | * - bits 16-25 are the hardirq count (max # of nested hardirqs: 1024) | 23 | * - bits 16-25 are the hardirq count (max # of nested hardirqs: 1024) |
24 | * - bit 26 is the NMI_MASK | 24 | * - bit 26 is the NMI_MASK |
25 | * - bit 28 is the PREEMPT_ACTIVE flag | 25 | * - bit 27 is the PREEMPT_ACTIVE flag |
26 | * | 26 | * |
27 | * PREEMPT_MASK: 0x000000ff | 27 | * PREEMPT_MASK: 0x000000ff |
28 | * SOFTIRQ_MASK: 0x0000ff00 | 28 | * SOFTIRQ_MASK: 0x0000ff00 |
diff --git a/include/linux/if_team.h b/include/linux/if_team.h index 8b000b295730..6d88a7f57680 100644 --- a/include/linux/if_team.h +++ b/include/linux/if_team.h | |||
@@ -99,21 +99,6 @@ static inline void team_netpoll_send_skb(struct team_port *port, | |||
99 | } | 99 | } |
100 | #endif | 100 | #endif |
101 | 101 | ||
102 | static inline int team_dev_queue_xmit(struct team *team, struct team_port *port, | ||
103 | struct sk_buff *skb) | ||
104 | { | ||
105 | BUILD_BUG_ON(sizeof(skb->queue_mapping) != | ||
106 | sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping)); | ||
107 | skb_set_queue_mapping(skb, qdisc_skb_cb(skb)->slave_dev_queue_mapping); | ||
108 | |||
109 | skb->dev = port->dev; | ||
110 | if (unlikely(netpoll_tx_running(port->dev))) { | ||
111 | team_netpoll_send_skb(port, skb); | ||
112 | return 0; | ||
113 | } | ||
114 | return dev_queue_xmit(skb); | ||
115 | } | ||
116 | |||
117 | struct team_mode_ops { | 102 | struct team_mode_ops { |
118 | int (*init)(struct team *team); | 103 | int (*init)(struct team *team); |
119 | void (*exit)(struct team *team); | 104 | void (*exit)(struct team *team); |
@@ -207,6 +192,21 @@ struct team { | |||
207 | long mode_priv[TEAM_MODE_PRIV_LONGS]; | 192 | long mode_priv[TEAM_MODE_PRIV_LONGS]; |
208 | }; | 193 | }; |
209 | 194 | ||
195 | static inline int team_dev_queue_xmit(struct team *team, struct team_port *port, | ||
196 | struct sk_buff *skb) | ||
197 | { | ||
198 | BUILD_BUG_ON(sizeof(skb->queue_mapping) != | ||
199 | sizeof(qdisc_skb_cb(skb)->slave_dev_queue_mapping)); | ||
200 | skb_set_queue_mapping(skb, qdisc_skb_cb(skb)->slave_dev_queue_mapping); | ||
201 | |||
202 | skb->dev = port->dev; | ||
203 | if (unlikely(netpoll_tx_running(team->dev))) { | ||
204 | team_netpoll_send_skb(port, skb); | ||
205 | return 0; | ||
206 | } | ||
207 | return dev_queue_xmit(skb); | ||
208 | } | ||
209 | |||
210 | static inline struct hlist_head *team_port_index_hash(struct team *team, | 210 | static inline struct hlist_head *team_port_index_hash(struct team *team, |
211 | int port_index) | 211 | int port_index) |
212 | { | 212 | { |
diff --git a/include/linux/iio/frequency/adf4350.h b/include/linux/iio/frequency/adf4350.h index b76b4a87065e..be91f344d5fc 100644 --- a/include/linux/iio/frequency/adf4350.h +++ b/include/linux/iio/frequency/adf4350.h | |||
@@ -87,6 +87,8 @@ | |||
87 | #define ADF4350_MAX_BANDSEL_CLK 125000 /* Hz */ | 87 | #define ADF4350_MAX_BANDSEL_CLK 125000 /* Hz */ |
88 | #define ADF4350_MAX_FREQ_REFIN 250000000 /* Hz */ | 88 | #define ADF4350_MAX_FREQ_REFIN 250000000 /* Hz */ |
89 | #define ADF4350_MAX_MODULUS 4095 | 89 | #define ADF4350_MAX_MODULUS 4095 |
90 | #define ADF4350_MAX_R_CNT 1023 | ||
91 | |||
90 | 92 | ||
91 | /** | 93 | /** |
92 | * struct adf4350_platform_data - platform specific information | 94 | * struct adf4350_platform_data - platform specific information |
diff --git a/include/linux/input/eeti_ts.h b/include/linux/input/eeti_ts.h index f875b316249d..16625d799b6f 100644 --- a/include/linux/input/eeti_ts.h +++ b/include/linux/input/eeti_ts.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define LINUX_INPUT_EETI_TS_H | 2 | #define LINUX_INPUT_EETI_TS_H |
3 | 3 | ||
4 | struct eeti_ts_platform_data { | 4 | struct eeti_ts_platform_data { |
5 | int irq_gpio; | ||
5 | unsigned int irq_active_high; | 6 | unsigned int irq_active_high; |
6 | }; | 7 | }; |
7 | 8 | ||
diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 54d6d690073c..7e83370e6fd2 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #define __LINUX_IOMMU_H | 20 | #define __LINUX_IOMMU_H |
21 | 21 | ||
22 | #include <linux/errno.h> | 22 | #include <linux/errno.h> |
23 | #include <linux/types.h> | ||
23 | 24 | ||
24 | #define IOMMU_READ (1) | 25 | #define IOMMU_READ (1) |
25 | #define IOMMU_WRITE (2) | 26 | #define IOMMU_WRITE (2) |
@@ -30,6 +31,7 @@ struct iommu_group; | |||
30 | struct bus_type; | 31 | struct bus_type; |
31 | struct device; | 32 | struct device; |
32 | struct iommu_domain; | 33 | struct iommu_domain; |
34 | struct notifier_block; | ||
33 | 35 | ||
34 | /* iommu fault flags */ | 36 | /* iommu fault flags */ |
35 | #define IOMMU_FAULT_READ 0x0 | 37 | #define IOMMU_FAULT_READ 0x0 |
diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h index 379e433e15e0..879db26ec401 100644 --- a/include/linux/ipv6.h +++ b/include/linux/ipv6.h | |||
@@ -369,6 +369,7 @@ struct ipv6_pinfo { | |||
369 | __u8 rcv_tclass; | 369 | __u8 rcv_tclass; |
370 | 370 | ||
371 | __u32 dst_cookie; | 371 | __u32 dst_cookie; |
372 | __u32 rx_dst_cookie; | ||
372 | 373 | ||
373 | struct ipv6_mc_socklist __rcu *ipv6_mc_list; | 374 | struct ipv6_mc_socklist __rcu *ipv6_mc_list; |
374 | struct ipv6_ac_socklist *ipv6_ac_list; | 375 | struct ipv6_ac_socklist *ipv6_ac_list; |
diff --git a/include/linux/irq.h b/include/linux/irq.h index 553fb66da130..216b0ba109d7 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -349,6 +349,7 @@ enum { | |||
349 | IRQCHIP_MASK_ON_SUSPEND = (1 << 2), | 349 | IRQCHIP_MASK_ON_SUSPEND = (1 << 2), |
350 | IRQCHIP_ONOFFLINE_ENABLED = (1 << 3), | 350 | IRQCHIP_ONOFFLINE_ENABLED = (1 << 3), |
351 | IRQCHIP_SKIP_SET_WAKE = (1 << 4), | 351 | IRQCHIP_SKIP_SET_WAKE = (1 << 4), |
352 | IRQCHIP_ONESHOT_SAFE = (1 << 5), | ||
352 | }; | 353 | }; |
353 | 354 | ||
354 | /* This include will go away once we isolated irq_desc usage to core code */ | 355 | /* This include will go away once we isolated irq_desc usage to core code */ |
diff --git a/include/linux/jbd2.h b/include/linux/jbd2.h index f334c7fab967..3efc43f3f162 100644 --- a/include/linux/jbd2.h +++ b/include/linux/jbd2.h | |||
@@ -1125,6 +1125,7 @@ extern int jbd2_journal_destroy (journal_t *); | |||
1125 | extern int jbd2_journal_recover (journal_t *journal); | 1125 | extern int jbd2_journal_recover (journal_t *journal); |
1126 | extern int jbd2_journal_wipe (journal_t *, int); | 1126 | extern int jbd2_journal_wipe (journal_t *, int); |
1127 | extern int jbd2_journal_skip_recovery (journal_t *); | 1127 | extern int jbd2_journal_skip_recovery (journal_t *); |
1128 | extern void jbd2_journal_update_sb_errno(journal_t *); | ||
1128 | extern void jbd2_journal_update_sb_log_tail (journal_t *, tid_t, | 1129 | extern void jbd2_journal_update_sb_log_tail (journal_t *, tid_t, |
1129 | unsigned long, int); | 1130 | unsigned long, int); |
1130 | extern void __jbd2_journal_abort_hard (journal_t *); | 1131 | extern void __jbd2_journal_abort_hard (journal_t *); |
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h index aded9b1ac5ca..05e3c2c7a8cf 100644 --- a/include/linux/jiffies.h +++ b/include/linux/jiffies.h | |||
@@ -39,9 +39,6 @@ | |||
39 | # error Invalid value of HZ. | 39 | # error Invalid value of HZ. |
40 | #endif | 40 | #endif |
41 | 41 | ||
42 | /* LATCH is used in the interval timer and ftape setup. */ | ||
43 | #define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */ | ||
44 | |||
45 | /* Suppose we want to divide two numbers NOM and DEN: NOM/DEN, then we can | 42 | /* Suppose we want to divide two numbers NOM and DEN: NOM/DEN, then we can |
46 | * improve accuracy by shifting LSH bits, hence calculating: | 43 | * improve accuracy by shifting LSH bits, hence calculating: |
47 | * (NOM << LSH) / DEN | 44 | * (NOM << LSH) / DEN |
@@ -54,18 +51,30 @@ | |||
54 | #define SH_DIV(NOM,DEN,LSH) ( (((NOM) / (DEN)) << (LSH)) \ | 51 | #define SH_DIV(NOM,DEN,LSH) ( (((NOM) / (DEN)) << (LSH)) \ |
55 | + ((((NOM) % (DEN)) << (LSH)) + (DEN) / 2) / (DEN)) | 52 | + ((((NOM) % (DEN)) << (LSH)) + (DEN) / 2) / (DEN)) |
56 | 53 | ||
57 | /* HZ is the requested value. ACTHZ is actual HZ ("<< 8" is for accuracy) */ | 54 | #ifdef CLOCK_TICK_RATE |
58 | #define ACTHZ (SH_DIV (CLOCK_TICK_RATE, LATCH, 8)) | 55 | /* LATCH is used in the interval timer and ftape setup. */ |
56 | # define LATCH ((CLOCK_TICK_RATE + HZ/2) / HZ) /* For divider */ | ||
57 | |||
58 | /* | ||
59 | * HZ is the requested value. However the CLOCK_TICK_RATE may not allow | ||
60 | * for exactly HZ. So SHIFTED_HZ is high res HZ ("<< 8" is for accuracy) | ||
61 | */ | ||
62 | # define SHIFTED_HZ (SH_DIV(CLOCK_TICK_RATE, LATCH, 8)) | ||
63 | #else | ||
64 | # define SHIFTED_HZ (HZ << 8) | ||
65 | #endif | ||
59 | 66 | ||
60 | /* TICK_NSEC is the time between ticks in nsec assuming real ACTHZ */ | 67 | /* TICK_NSEC is the time between ticks in nsec assuming SHIFTED_HZ */ |
61 | #define TICK_NSEC (SH_DIV (1000000UL * 1000, ACTHZ, 8)) | 68 | #define TICK_NSEC (SH_DIV(1000000UL * 1000, SHIFTED_HZ, 8)) |
62 | 69 | ||
63 | /* TICK_USEC is the time between ticks in usec assuming fake USER_HZ */ | 70 | /* TICK_USEC is the time between ticks in usec assuming fake USER_HZ */ |
64 | #define TICK_USEC ((1000000UL + USER_HZ/2) / USER_HZ) | 71 | #define TICK_USEC ((1000000UL + USER_HZ/2) / USER_HZ) |
65 | 72 | ||
66 | /* TICK_USEC_TO_NSEC is the time between ticks in nsec assuming real ACTHZ and */ | 73 | /* |
67 | /* a value TUSEC for TICK_USEC (can be set bij adjtimex) */ | 74 | * TICK_USEC_TO_NSEC is the time between ticks in nsec assuming SHIFTED_HZ and |
68 | #define TICK_USEC_TO_NSEC(TUSEC) (SH_DIV (TUSEC * USER_HZ * 1000, ACTHZ, 8)) | 75 | * a value TUSEC for TICK_USEC (can be set bij adjtimex) |
76 | */ | ||
77 | #define TICK_USEC_TO_NSEC(TUSEC) (SH_DIV(TUSEC * USER_HZ * 1000, SHIFTED_HZ, 8)) | ||
69 | 78 | ||
70 | /* some arch's have a small-data section that can be accessed register-relative | 79 | /* some arch's have a small-data section that can be accessed register-relative |
71 | * but that can only take up to, say, 4-byte variables. jiffies being part of | 80 | * but that can only take up to, say, 4-byte variables. jiffies being part of |
diff --git a/include/linux/kdb.h b/include/linux/kdb.h index 064725854db8..42d9e863a313 100644 --- a/include/linux/kdb.h +++ b/include/linux/kdb.h | |||
@@ -75,8 +75,6 @@ extern const char *kdb_diemsg; | |||
75 | #define KDB_FLAG_CATASTROPHIC (1 << 1) /* A catastrophic event has occurred */ | 75 | #define KDB_FLAG_CATASTROPHIC (1 << 1) /* A catastrophic event has occurred */ |
76 | #define KDB_FLAG_CMD_INTERRUPT (1 << 2) /* Previous command was interrupted */ | 76 | #define KDB_FLAG_CMD_INTERRUPT (1 << 2) /* Previous command was interrupted */ |
77 | #define KDB_FLAG_NOIPI (1 << 3) /* Do not send IPIs */ | 77 | #define KDB_FLAG_NOIPI (1 << 3) /* Do not send IPIs */ |
78 | #define KDB_FLAG_ONLY_DO_DUMP (1 << 4) /* Only do a dump, used when | ||
79 | * kdb is off */ | ||
80 | #define KDB_FLAG_NO_CONSOLE (1 << 5) /* No console is available, | 78 | #define KDB_FLAG_NO_CONSOLE (1 << 5) /* No console is available, |
81 | * kdb is disabled */ | 79 | * kdb is disabled */ |
82 | #define KDB_FLAG_NO_VT_CONSOLE (1 << 6) /* No VT console is available, do | 80 | #define KDB_FLAG_NO_VT_CONSOLE (1 << 6) /* No VT console is available, do |
diff --git a/include/linux/mfd/ezx-pcap.h b/include/linux/mfd/ezx-pcap.h index 40c372165f3e..32a1b5cfeba1 100644 --- a/include/linux/mfd/ezx-pcap.h +++ b/include/linux/mfd/ezx-pcap.h | |||
@@ -16,6 +16,7 @@ struct pcap_subdev { | |||
16 | struct pcap_platform_data { | 16 | struct pcap_platform_data { |
17 | unsigned int irq_base; | 17 | unsigned int irq_base; |
18 | unsigned int config; | 18 | unsigned int config; |
19 | int gpio; | ||
19 | void (*init) (void *); /* board specific init */ | 20 | void (*init) (void *); /* board specific init */ |
20 | int num_subdevs; | 21 | int num_subdevs; |
21 | struct pcap_subdev *subdevs; | 22 | struct pcap_subdev *subdevs; |
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h index 1d6ab69c1f3f..4936f09a9333 100644 --- a/include/linux/netdevice.h +++ b/include/linux/netdevice.h | |||
@@ -953,7 +953,8 @@ struct net_device_ops { | |||
953 | #ifdef CONFIG_NET_POLL_CONTROLLER | 953 | #ifdef CONFIG_NET_POLL_CONTROLLER |
954 | void (*ndo_poll_controller)(struct net_device *dev); | 954 | void (*ndo_poll_controller)(struct net_device *dev); |
955 | int (*ndo_netpoll_setup)(struct net_device *dev, | 955 | int (*ndo_netpoll_setup)(struct net_device *dev, |
956 | struct netpoll_info *info); | 956 | struct netpoll_info *info, |
957 | gfp_t gfp); | ||
957 | void (*ndo_netpoll_cleanup)(struct net_device *dev); | 958 | void (*ndo_netpoll_cleanup)(struct net_device *dev); |
958 | #endif | 959 | #endif |
959 | int (*ndo_set_vf_mac)(struct net_device *dev, | 960 | int (*ndo_set_vf_mac)(struct net_device *dev, |
@@ -1521,6 +1522,8 @@ struct packet_type { | |||
1521 | struct sk_buff **(*gro_receive)(struct sk_buff **head, | 1522 | struct sk_buff **(*gro_receive)(struct sk_buff **head, |
1522 | struct sk_buff *skb); | 1523 | struct sk_buff *skb); |
1523 | int (*gro_complete)(struct sk_buff *skb); | 1524 | int (*gro_complete)(struct sk_buff *skb); |
1525 | bool (*id_match)(struct packet_type *ptype, | ||
1526 | struct sock *sk); | ||
1524 | void *af_packet_priv; | 1527 | void *af_packet_priv; |
1525 | struct list_head list; | 1528 | struct list_head list; |
1526 | }; | 1529 | }; |
diff --git a/include/linux/netfilter/nf_conntrack_sip.h b/include/linux/netfilter/nf_conntrack_sip.h index 0dfc8b7210a3..89f2a627f3f0 100644 --- a/include/linux/netfilter/nf_conntrack_sip.h +++ b/include/linux/netfilter/nf_conntrack_sip.h | |||
@@ -164,7 +164,7 @@ extern int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr | |||
164 | unsigned int dataoff, unsigned int datalen, | 164 | unsigned int dataoff, unsigned int datalen, |
165 | const char *name, | 165 | const char *name, |
166 | unsigned int *matchoff, unsigned int *matchlen, | 166 | unsigned int *matchoff, unsigned int *matchlen, |
167 | union nf_inet_addr *addr); | 167 | union nf_inet_addr *addr, bool delim); |
168 | extern int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr, | 168 | extern int ct_sip_parse_numerical_param(const struct nf_conn *ct, const char *dptr, |
169 | unsigned int off, unsigned int datalen, | 169 | unsigned int off, unsigned int datalen, |
170 | const char *name, | 170 | const char *name, |
diff --git a/include/linux/netpoll.h b/include/linux/netpoll.h index 28f5389c924b..66d5379c305e 100644 --- a/include/linux/netpoll.h +++ b/include/linux/netpoll.h | |||
@@ -23,6 +23,7 @@ struct netpoll { | |||
23 | u8 remote_mac[ETH_ALEN]; | 23 | u8 remote_mac[ETH_ALEN]; |
24 | 24 | ||
25 | struct list_head rx; /* rx_np list element */ | 25 | struct list_head rx; /* rx_np list element */ |
26 | struct rcu_head rcu; | ||
26 | }; | 27 | }; |
27 | 28 | ||
28 | struct netpoll_info { | 29 | struct netpoll_info { |
@@ -38,28 +39,40 @@ struct netpoll_info { | |||
38 | struct delayed_work tx_work; | 39 | struct delayed_work tx_work; |
39 | 40 | ||
40 | struct netpoll *netpoll; | 41 | struct netpoll *netpoll; |
42 | struct rcu_head rcu; | ||
41 | }; | 43 | }; |
42 | 44 | ||
43 | void netpoll_send_udp(struct netpoll *np, const char *msg, int len); | 45 | void netpoll_send_udp(struct netpoll *np, const char *msg, int len); |
44 | void netpoll_print_options(struct netpoll *np); | 46 | void netpoll_print_options(struct netpoll *np); |
45 | int netpoll_parse_options(struct netpoll *np, char *opt); | 47 | int netpoll_parse_options(struct netpoll *np, char *opt); |
46 | int __netpoll_setup(struct netpoll *np, struct net_device *ndev); | 48 | int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp); |
47 | int netpoll_setup(struct netpoll *np); | 49 | int netpoll_setup(struct netpoll *np); |
48 | int netpoll_trap(void); | 50 | int netpoll_trap(void); |
49 | void netpoll_set_trap(int trap); | 51 | void netpoll_set_trap(int trap); |
50 | void __netpoll_cleanup(struct netpoll *np); | 52 | void __netpoll_cleanup(struct netpoll *np); |
53 | void __netpoll_free_rcu(struct netpoll *np); | ||
51 | void netpoll_cleanup(struct netpoll *np); | 54 | void netpoll_cleanup(struct netpoll *np); |
52 | int __netpoll_rx(struct sk_buff *skb); | 55 | int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo); |
53 | void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, | 56 | void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, |
54 | struct net_device *dev); | 57 | struct net_device *dev); |
55 | static inline void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) | 58 | static inline void netpoll_send_skb(struct netpoll *np, struct sk_buff *skb) |
56 | { | 59 | { |
60 | unsigned long flags; | ||
61 | local_irq_save(flags); | ||
57 | netpoll_send_skb_on_dev(np, skb, np->dev); | 62 | netpoll_send_skb_on_dev(np, skb, np->dev); |
63 | local_irq_restore(flags); | ||
58 | } | 64 | } |
59 | 65 | ||
60 | 66 | ||
61 | 67 | ||
62 | #ifdef CONFIG_NETPOLL | 68 | #ifdef CONFIG_NETPOLL |
69 | static inline bool netpoll_rx_on(struct sk_buff *skb) | ||
70 | { | ||
71 | struct netpoll_info *npinfo = rcu_dereference_bh(skb->dev->npinfo); | ||
72 | |||
73 | return npinfo && (!list_empty(&npinfo->rx_np) || npinfo->rx_flags); | ||
74 | } | ||
75 | |||
63 | static inline bool netpoll_rx(struct sk_buff *skb) | 76 | static inline bool netpoll_rx(struct sk_buff *skb) |
64 | { | 77 | { |
65 | struct netpoll_info *npinfo; | 78 | struct netpoll_info *npinfo; |
@@ -67,14 +80,14 @@ static inline bool netpoll_rx(struct sk_buff *skb) | |||
67 | bool ret = false; | 80 | bool ret = false; |
68 | 81 | ||
69 | local_irq_save(flags); | 82 | local_irq_save(flags); |
70 | npinfo = rcu_dereference_bh(skb->dev->npinfo); | ||
71 | 83 | ||
72 | if (!npinfo || (list_empty(&npinfo->rx_np) && !npinfo->rx_flags)) | 84 | if (!netpoll_rx_on(skb)) |
73 | goto out; | 85 | goto out; |
74 | 86 | ||
87 | npinfo = rcu_dereference_bh(skb->dev->npinfo); | ||
75 | spin_lock(&npinfo->rx_lock); | 88 | spin_lock(&npinfo->rx_lock); |
76 | /* check rx_flags again with the lock held */ | 89 | /* check rx_flags again with the lock held */ |
77 | if (npinfo->rx_flags && __netpoll_rx(skb)) | 90 | if (npinfo->rx_flags && __netpoll_rx(skb, npinfo)) |
78 | ret = true; | 91 | ret = true; |
79 | spin_unlock(&npinfo->rx_lock); | 92 | spin_unlock(&npinfo->rx_lock); |
80 | 93 | ||
@@ -83,13 +96,6 @@ out: | |||
83 | return ret; | 96 | return ret; |
84 | } | 97 | } |
85 | 98 | ||
86 | static inline int netpoll_rx_on(struct sk_buff *skb) | ||
87 | { | ||
88 | struct netpoll_info *npinfo = rcu_dereference_bh(skb->dev->npinfo); | ||
89 | |||
90 | return npinfo && (!list_empty(&npinfo->rx_np) || npinfo->rx_flags); | ||
91 | } | ||
92 | |||
93 | static inline int netpoll_receive_skb(struct sk_buff *skb) | 99 | static inline int netpoll_receive_skb(struct sk_buff *skb) |
94 | { | 100 | { |
95 | if (!list_empty(&skb->dev->napi_list)) | 101 | if (!list_empty(&skb->dev->napi_list)) |
@@ -119,7 +125,7 @@ static inline void netpoll_poll_unlock(void *have) | |||
119 | } | 125 | } |
120 | } | 126 | } |
121 | 127 | ||
122 | static inline int netpoll_tx_running(struct net_device *dev) | 128 | static inline bool netpoll_tx_running(struct net_device *dev) |
123 | { | 129 | { |
124 | return irqs_disabled(); | 130 | return irqs_disabled(); |
125 | } | 131 | } |
@@ -127,11 +133,11 @@ static inline int netpoll_tx_running(struct net_device *dev) | |||
127 | #else | 133 | #else |
128 | static inline bool netpoll_rx(struct sk_buff *skb) | 134 | static inline bool netpoll_rx(struct sk_buff *skb) |
129 | { | 135 | { |
130 | return 0; | 136 | return false; |
131 | } | 137 | } |
132 | static inline int netpoll_rx_on(struct sk_buff *skb) | 138 | static inline bool netpoll_rx_on(struct sk_buff *skb) |
133 | { | 139 | { |
134 | return 0; | 140 | return false; |
135 | } | 141 | } |
136 | static inline int netpoll_receive_skb(struct sk_buff *skb) | 142 | static inline int netpoll_receive_skb(struct sk_buff *skb) |
137 | { | 143 | { |
@@ -147,9 +153,9 @@ static inline void netpoll_poll_unlock(void *have) | |||
147 | static inline void netpoll_netdev_init(struct net_device *dev) | 153 | static inline void netpoll_netdev_init(struct net_device *dev) |
148 | { | 154 | { |
149 | } | 155 | } |
150 | static inline int netpoll_tx_running(struct net_device *dev) | 156 | static inline bool netpoll_tx_running(struct net_device *dev) |
151 | { | 157 | { |
152 | return 0; | 158 | return false; |
153 | } | 159 | } |
154 | #endif | 160 | #endif |
155 | 161 | ||
diff --git a/include/linux/of.h b/include/linux/of.h index 5919ee33f2b7..1b1163225f3b 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
@@ -190,10 +190,17 @@ extern struct device_node *of_get_parent(const struct device_node *node); | |||
190 | extern struct device_node *of_get_next_parent(struct device_node *node); | 190 | extern struct device_node *of_get_next_parent(struct device_node *node); |
191 | extern struct device_node *of_get_next_child(const struct device_node *node, | 191 | extern struct device_node *of_get_next_child(const struct device_node *node, |
192 | struct device_node *prev); | 192 | struct device_node *prev); |
193 | extern struct device_node *of_get_next_available_child( | ||
194 | const struct device_node *node, struct device_node *prev); | ||
195 | |||
193 | #define for_each_child_of_node(parent, child) \ | 196 | #define for_each_child_of_node(parent, child) \ |
194 | for (child = of_get_next_child(parent, NULL); child != NULL; \ | 197 | for (child = of_get_next_child(parent, NULL); child != NULL; \ |
195 | child = of_get_next_child(parent, child)) | 198 | child = of_get_next_child(parent, child)) |
196 | 199 | ||
200 | #define for_each_available_child_of_node(parent, child) \ | ||
201 | for (child = of_get_next_available_child(parent, NULL); child != NULL; \ | ||
202 | child = of_get_next_available_child(parent, child)) | ||
203 | |||
197 | static inline int of_get_child_count(const struct device_node *np) | 204 | static inline int of_get_child_count(const struct device_node *np) |
198 | { | 205 | { |
199 | struct device_node *child; | 206 | struct device_node *child; |
diff --git a/include/linux/olpc-ec.h b/include/linux/olpc-ec.h new file mode 100644 index 000000000000..5bb6e760aa61 --- /dev/null +++ b/include/linux/olpc-ec.h | |||
@@ -0,0 +1,41 @@ | |||
1 | #ifndef _LINUX_OLPC_EC_H | ||
2 | #define _LINUX_OLPC_EC_H | ||
3 | |||
4 | /* XO-1 EC commands */ | ||
5 | #define EC_FIRMWARE_REV 0x08 | ||
6 | #define EC_WRITE_SCI_MASK 0x1b | ||
7 | #define EC_WAKE_UP_WLAN 0x24 | ||
8 | #define EC_WLAN_LEAVE_RESET 0x25 | ||
9 | #define EC_READ_EB_MODE 0x2a | ||
10 | #define EC_SET_SCI_INHIBIT 0x32 | ||
11 | #define EC_SET_SCI_INHIBIT_RELEASE 0x34 | ||
12 | #define EC_WLAN_ENTER_RESET 0x35 | ||
13 | #define EC_WRITE_EXT_SCI_MASK 0x38 | ||
14 | #define EC_SCI_QUERY 0x84 | ||
15 | #define EC_EXT_SCI_QUERY 0x85 | ||
16 | |||
17 | struct platform_device; | ||
18 | |||
19 | struct olpc_ec_driver { | ||
20 | int (*probe)(struct platform_device *); | ||
21 | int (*suspend)(struct platform_device *); | ||
22 | int (*resume)(struct platform_device *); | ||
23 | |||
24 | int (*ec_cmd)(u8, u8 *, size_t, u8 *, size_t, void *); | ||
25 | }; | ||
26 | |||
27 | #ifdef CONFIG_OLPC | ||
28 | |||
29 | extern void olpc_ec_driver_register(struct olpc_ec_driver *drv, void *arg); | ||
30 | |||
31 | extern int olpc_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *outbuf, | ||
32 | size_t outlen); | ||
33 | |||
34 | #else | ||
35 | |||
36 | static inline int olpc_ec_cmd(u8 cmd, u8 *inbuf, size_t inlen, u8 *outbuf, | ||
37 | size_t outlen) { return -ENODEV; } | ||
38 | |||
39 | #endif /* CONFIG_OLPC */ | ||
40 | |||
41 | #endif /* _LINUX_OLPC_EC_H */ | ||
diff --git a/include/linux/perf_event.h b/include/linux/perf_event.h index 76c5c8b724a7..7602ccb3f40e 100644 --- a/include/linux/perf_event.h +++ b/include/linux/perf_event.h | |||
@@ -1272,7 +1272,8 @@ static inline bool perf_paranoid_kernel(void) | |||
1272 | extern void perf_event_init(void); | 1272 | extern void perf_event_init(void); |
1273 | extern void perf_tp_event(u64 addr, u64 count, void *record, | 1273 | extern void perf_tp_event(u64 addr, u64 count, void *record, |
1274 | int entry_size, struct pt_regs *regs, | 1274 | int entry_size, struct pt_regs *regs, |
1275 | struct hlist_head *head, int rctx); | 1275 | struct hlist_head *head, int rctx, |
1276 | struct task_struct *task); | ||
1276 | extern void perf_bp_event(struct perf_event *event, void *data); | 1277 | extern void perf_bp_event(struct perf_event *event, void *data); |
1277 | 1278 | ||
1278 | #ifndef perf_misc_flags | 1279 | #ifndef perf_misc_flags |
diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h index 6dd96fb45482..e9b7f4350844 100644 --- a/include/linux/pinctrl/consumer.h +++ b/include/linux/pinctrl/consumer.h | |||
@@ -20,6 +20,7 @@ | |||
20 | /* This struct is private to the core and should be regarded as a cookie */ | 20 | /* This struct is private to the core and should be regarded as a cookie */ |
21 | struct pinctrl; | 21 | struct pinctrl; |
22 | struct pinctrl_state; | 22 | struct pinctrl_state; |
23 | struct device; | ||
23 | 24 | ||
24 | #ifdef CONFIG_PINCTRL | 25 | #ifdef CONFIG_PINCTRL |
25 | 26 | ||
diff --git a/include/linux/sched.h b/include/linux/sched.h index c147e7024f11..b8c86648a2f9 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -334,14 +334,6 @@ static inline void lockup_detector_init(void) | |||
334 | } | 334 | } |
335 | #endif | 335 | #endif |
336 | 336 | ||
337 | #if defined(CONFIG_LOCKUP_DETECTOR) && defined(CONFIG_SUSPEND) | ||
338 | void lockup_detector_bootcpu_resume(void); | ||
339 | #else | ||
340 | static inline void lockup_detector_bootcpu_resume(void) | ||
341 | { | ||
342 | } | ||
343 | #endif | ||
344 | |||
345 | #ifdef CONFIG_DETECT_HUNG_TASK | 337 | #ifdef CONFIG_DETECT_HUNG_TASK |
346 | extern unsigned int sysctl_hung_task_panic; | 338 | extern unsigned int sysctl_hung_task_panic; |
347 | extern unsigned long sysctl_hung_task_check_count; | 339 | extern unsigned long sysctl_hung_task_check_count; |
diff --git a/include/linux/security.h b/include/linux/security.h index 4e5a73cdbbef..3dea6a9d568f 100644 --- a/include/linux/security.h +++ b/include/linux/security.h | |||
@@ -1242,8 +1242,6 @@ static inline void security_free_mnt_opts(struct security_mnt_opts *opts) | |||
1242 | * Check that the @parent process has sufficient permission to trace the | 1242 | * Check that the @parent process has sufficient permission to trace the |
1243 | * current process before allowing the current process to present itself | 1243 | * current process before allowing the current process to present itself |
1244 | * to the @parent process for tracing. | 1244 | * to the @parent process for tracing. |
1245 | * The parent process will still have to undergo the ptrace_access_check | ||
1246 | * checks before it is allowed to trace this one. | ||
1247 | * @parent contains the task_struct structure for debugger process. | 1245 | * @parent contains the task_struct structure for debugger process. |
1248 | * Return 0 if permission is granted. | 1246 | * Return 0 if permission is granted. |
1249 | * @capget: | 1247 | * @capget: |
diff --git a/include/linux/shdma-base.h b/include/linux/shdma-base.h index 93f9821554b6..a3728bf66f0e 100644 --- a/include/linux/shdma-base.h +++ b/include/linux/shdma-base.h | |||
@@ -50,6 +50,7 @@ struct shdma_desc { | |||
50 | struct list_head node; | 50 | struct list_head node; |
51 | struct dma_async_tx_descriptor async_tx; | 51 | struct dma_async_tx_descriptor async_tx; |
52 | enum dma_transfer_direction direction; | 52 | enum dma_transfer_direction direction; |
53 | size_t partial; | ||
53 | dma_cookie_t cookie; | 54 | dma_cookie_t cookie; |
54 | int chunks; | 55 | int chunks; |
55 | int mark; | 56 | int mark; |
@@ -98,6 +99,7 @@ struct shdma_ops { | |||
98 | void (*start_xfer)(struct shdma_chan *, struct shdma_desc *); | 99 | void (*start_xfer)(struct shdma_chan *, struct shdma_desc *); |
99 | struct shdma_desc *(*embedded_desc)(void *, int); | 100 | struct shdma_desc *(*embedded_desc)(void *, int); |
100 | bool (*chan_irq)(struct shdma_chan *, int); | 101 | bool (*chan_irq)(struct shdma_chan *, int); |
102 | size_t (*get_partial)(struct shdma_chan *, struct shdma_desc *); | ||
101 | }; | 103 | }; |
102 | 104 | ||
103 | struct shdma_dev { | 105 | struct shdma_dev { |
diff --git a/include/linux/string.h b/include/linux/string.h index ffe0442e18d2..b9178812d9df 100644 --- a/include/linux/string.h +++ b/include/linux/string.h | |||
@@ -144,8 +144,8 @@ static inline bool strstarts(const char *str, const char *prefix) | |||
144 | { | 144 | { |
145 | return strncmp(str, prefix, strlen(prefix)) == 0; | 145 | return strncmp(str, prefix, strlen(prefix)) == 0; |
146 | } | 146 | } |
147 | #endif | ||
148 | 147 | ||
149 | extern size_t memweight(const void *ptr, size_t bytes); | 148 | extern size_t memweight(const void *ptr, size_t bytes); |
150 | 149 | ||
150 | #endif /* __KERNEL__ */ | ||
151 | #endif /* _LINUX_STRING_H_ */ | 151 | #endif /* _LINUX_STRING_H_ */ |
diff --git a/include/linux/timex.h b/include/linux/timex.h index 99bc88b1fc02..7c5ceb20e03a 100644 --- a/include/linux/timex.h +++ b/include/linux/timex.h | |||
@@ -232,7 +232,7 @@ struct timex { | |||
232 | * estimated error = NTP dispersion. | 232 | * estimated error = NTP dispersion. |
233 | */ | 233 | */ |
234 | extern unsigned long tick_usec; /* USER_HZ period (usec) */ | 234 | extern unsigned long tick_usec; /* USER_HZ period (usec) */ |
235 | extern unsigned long tick_nsec; /* ACTHZ period (nsec) */ | 235 | extern unsigned long tick_nsec; /* SHIFTED_HZ period (nsec) */ |
236 | 236 | ||
237 | extern void ntp_init(void); | 237 | extern void ntp_init(void); |
238 | extern void ntp_clear(void); | 238 | extern void ntp_clear(void); |
diff --git a/include/linux/topology.h b/include/linux/topology.h index e91cd43394df..fec12d667211 100644 --- a/include/linux/topology.h +++ b/include/linux/topology.h | |||
@@ -164,6 +164,7 @@ int arch_update_cpu_topology(void); | |||
164 | | 0*SD_SHARE_CPUPOWER \ | 164 | | 0*SD_SHARE_CPUPOWER \ |
165 | | 0*SD_SHARE_PKG_RESOURCES \ | 165 | | 0*SD_SHARE_PKG_RESOURCES \ |
166 | | 0*SD_SERIALIZE \ | 166 | | 0*SD_SERIALIZE \ |
167 | | 1*SD_PREFER_SIBLING \ | ||
167 | , \ | 168 | , \ |
168 | .last_balance = jiffies, \ | 169 | .last_balance = jiffies, \ |
169 | .balance_interval = 1, \ | 170 | .balance_interval = 1, \ |
diff --git a/include/linux/writeback.h b/include/linux/writeback.h index c66fe3332d83..50c3e8fa06a8 100644 --- a/include/linux/writeback.h +++ b/include/linux/writeback.h | |||
@@ -104,7 +104,6 @@ static inline void wait_on_inode(struct inode *inode) | |||
104 | wait_on_bit(&inode->i_state, __I_NEW, inode_wait, TASK_UNINTERRUPTIBLE); | 104 | wait_on_bit(&inode->i_state, __I_NEW, inode_wait, TASK_UNINTERRUPTIBLE); |
105 | } | 105 | } |
106 | 106 | ||
107 | |||
108 | /* | 107 | /* |
109 | * mm/page-writeback.c | 108 | * mm/page-writeback.c |
110 | */ | 109 | */ |
diff --git a/include/net/codel.h b/include/net/codel.h index 550debfc2403..389cf621161d 100644 --- a/include/net/codel.h +++ b/include/net/codel.h | |||
@@ -305,6 +305,8 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch, | |||
305 | } | 305 | } |
306 | } | 306 | } |
307 | } else if (drop) { | 307 | } else if (drop) { |
308 | u32 delta; | ||
309 | |||
308 | if (params->ecn && INET_ECN_set_ce(skb)) { | 310 | if (params->ecn && INET_ECN_set_ce(skb)) { |
309 | stats->ecn_mark++; | 311 | stats->ecn_mark++; |
310 | } else { | 312 | } else { |
@@ -320,9 +322,11 @@ static struct sk_buff *codel_dequeue(struct Qdisc *sch, | |||
320 | * assume that the drop rate that controlled the queue on the | 322 | * assume that the drop rate that controlled the queue on the |
321 | * last cycle is a good starting point to control it now. | 323 | * last cycle is a good starting point to control it now. |
322 | */ | 324 | */ |
323 | if (codel_time_before(now - vars->drop_next, | 325 | delta = vars->count - vars->lastcount; |
326 | if (delta > 1 && | ||
327 | codel_time_before(now - vars->drop_next, | ||
324 | 16 * params->interval)) { | 328 | 16 * params->interval)) { |
325 | vars->count = (vars->count - vars->lastcount) | 1; | 329 | vars->count = delta; |
326 | /* we dont care if rec_inv_sqrt approximation | 330 | /* we dont care if rec_inv_sqrt approximation |
327 | * is not very precise : | 331 | * is not very precise : |
328 | * Next Newton steps will correct it quadratically. | 332 | * Next Newton steps will correct it quadratically. |
diff --git a/include/net/dst.h b/include/net/dst.h index 77f52f7dc823..9a7881066fb3 100644 --- a/include/net/dst.h +++ b/include/net/dst.h | |||
@@ -110,7 +110,7 @@ struct dst_entry { | |||
110 | }; | 110 | }; |
111 | 111 | ||
112 | extern u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old); | 112 | extern u32 *dst_cow_metrics_generic(struct dst_entry *dst, unsigned long old); |
113 | extern const u32 dst_default_metrics[RTAX_MAX]; | 113 | extern const u32 dst_default_metrics[]; |
114 | 114 | ||
115 | #define DST_METRICS_READ_ONLY 0x1UL | 115 | #define DST_METRICS_READ_ONLY 0x1UL |
116 | #define __DST_METRICS_PTR(Y) \ | 116 | #define __DST_METRICS_PTR(Y) \ |
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h index 5ee66f517b4f..ba1d3615acbb 100644 --- a/include/net/inet_connection_sock.h +++ b/include/net/inet_connection_sock.h | |||
@@ -39,6 +39,7 @@ struct inet_connection_sock_af_ops { | |||
39 | int (*queue_xmit)(struct sk_buff *skb, struct flowi *fl); | 39 | int (*queue_xmit)(struct sk_buff *skb, struct flowi *fl); |
40 | void (*send_check)(struct sock *sk, struct sk_buff *skb); | 40 | void (*send_check)(struct sock *sk, struct sk_buff *skb); |
41 | int (*rebuild_header)(struct sock *sk); | 41 | int (*rebuild_header)(struct sock *sk); |
42 | void (*sk_rx_dst_set)(struct sock *sk, const struct sk_buff *skb); | ||
42 | int (*conn_request)(struct sock *sk, struct sk_buff *skb); | 43 | int (*conn_request)(struct sock *sk, struct sk_buff *skb); |
43 | struct sock *(*syn_recv_sock)(struct sock *sk, struct sk_buff *skb, | 44 | struct sock *(*syn_recv_sock)(struct sock *sk, struct sk_buff *skb, |
44 | struct request_sock *req, | 45 | struct request_sock *req, |
diff --git a/include/net/inet_sock.h b/include/net/inet_sock.h index 83b567fe1941..613cfa401672 100644 --- a/include/net/inet_sock.h +++ b/include/net/inet_sock.h | |||
@@ -249,13 +249,4 @@ static inline __u8 inet_sk_flowi_flags(const struct sock *sk) | |||
249 | return flags; | 249 | return flags; |
250 | } | 250 | } |
251 | 251 | ||
252 | static inline void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) | ||
253 | { | ||
254 | struct dst_entry *dst = skb_dst(skb); | ||
255 | |||
256 | dst_hold(dst); | ||
257 | sk->sk_rx_dst = dst; | ||
258 | inet_sk(sk)->rx_dst_ifindex = skb->skb_iif; | ||
259 | } | ||
260 | |||
261 | #endif /* _INET_SOCK_H */ | 252 | #endif /* _INET_SOCK_H */ |
diff --git a/include/net/ip.h b/include/net/ip.h index bd5e444a19ce..5a5d84d3d2c6 100644 --- a/include/net/ip.h +++ b/include/net/ip.h | |||
@@ -120,7 +120,7 @@ extern struct sk_buff *__ip_make_skb(struct sock *sk, | |||
120 | struct flowi4 *fl4, | 120 | struct flowi4 *fl4, |
121 | struct sk_buff_head *queue, | 121 | struct sk_buff_head *queue, |
122 | struct inet_cork *cork); | 122 | struct inet_cork *cork); |
123 | extern int ip_send_skb(struct sk_buff *skb); | 123 | extern int ip_send_skb(struct net *net, struct sk_buff *skb); |
124 | extern int ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4); | 124 | extern int ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4); |
125 | extern void ip_flush_pending_frames(struct sock *sk); | 125 | extern void ip_flush_pending_frames(struct sock *sk); |
126 | extern struct sk_buff *ip_make_skb(struct sock *sk, | 126 | extern struct sk_buff *ip_make_skb(struct sock *sk, |
diff --git a/include/net/llc.h b/include/net/llc.h index 226c846cab08..f2d0fc570527 100644 --- a/include/net/llc.h +++ b/include/net/llc.h | |||
@@ -133,7 +133,7 @@ extern int llc_build_and_send_ui_pkt(struct llc_sap *sap, struct sk_buff *skb, | |||
133 | extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb); | 133 | extern void llc_sap_handler(struct llc_sap *sap, struct sk_buff *skb); |
134 | extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb); | 134 | extern void llc_conn_handler(struct llc_sap *sap, struct sk_buff *skb); |
135 | 135 | ||
136 | extern int llc_station_init(void); | 136 | extern void llc_station_init(void); |
137 | extern void llc_station_exit(void); | 137 | extern void llc_station_exit(void); |
138 | 138 | ||
139 | #ifdef CONFIG_PROC_FS | 139 | #ifdef CONFIG_PROC_FS |
diff --git a/include/net/scm.h b/include/net/scm.h index 079d7887dac1..7dc0854f0b38 100644 --- a/include/net/scm.h +++ b/include/net/scm.h | |||
@@ -70,9 +70,11 @@ static __inline__ void scm_destroy(struct scm_cookie *scm) | |||
70 | } | 70 | } |
71 | 71 | ||
72 | static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, | 72 | static __inline__ int scm_send(struct socket *sock, struct msghdr *msg, |
73 | struct scm_cookie *scm) | 73 | struct scm_cookie *scm, bool forcecreds) |
74 | { | 74 | { |
75 | memset(scm, 0, sizeof(*scm)); | 75 | memset(scm, 0, sizeof(*scm)); |
76 | if (forcecreds) | ||
77 | scm_set_cred(scm, task_tgid(current), current_cred()); | ||
76 | unix_get_peersec_dgram(sock, scm); | 78 | unix_get_peersec_dgram(sock, scm); |
77 | if (msg->msg_controllen <= 0) | 79 | if (msg->msg_controllen <= 0) |
78 | return 0; | 80 | return 0; |
diff --git a/include/net/tcp.h b/include/net/tcp.h index e19124b84cd2..1f000ffe7075 100644 --- a/include/net/tcp.h +++ b/include/net/tcp.h | |||
@@ -464,6 +464,7 @@ extern int tcp_disconnect(struct sock *sk, int flags); | |||
464 | void tcp_connect_init(struct sock *sk); | 464 | void tcp_connect_init(struct sock *sk); |
465 | void tcp_finish_connect(struct sock *sk, struct sk_buff *skb); | 465 | void tcp_finish_connect(struct sock *sk, struct sk_buff *skb); |
466 | int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size); | 466 | int tcp_send_rcvq(struct sock *sk, struct msghdr *msg, size_t size); |
467 | void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb); | ||
467 | 468 | ||
468 | /* From syncookies.c */ | 469 | /* From syncookies.c */ |
469 | extern __u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS]; | 470 | extern __u32 syncookie_secret[2][16-4+SHA_DIGEST_WORDS]; |
diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 5e1662dbb83c..36ad56ba648b 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h | |||
@@ -292,6 +292,8 @@ struct xfrm_policy_afinfo { | |||
292 | struct flowi *fl, | 292 | struct flowi *fl, |
293 | int reverse); | 293 | int reverse); |
294 | int (*get_tos)(const struct flowi *fl); | 294 | int (*get_tos)(const struct flowi *fl); |
295 | void (*init_dst)(struct net *net, | ||
296 | struct xfrm_dst *dst); | ||
295 | int (*init_path)(struct xfrm_dst *path, | 297 | int (*init_path)(struct xfrm_dst *path, |
296 | struct dst_entry *dst, | 298 | struct dst_entry *dst, |
297 | int nfheader_len); | 299 | int nfheader_len); |
diff --git a/include/sound/pcm.h b/include/sound/pcm.h index c75c0d1a85e2..cdca2ab1e711 100644 --- a/include/sound/pcm.h +++ b/include/sound/pcm.h | |||
@@ -1075,7 +1075,8 @@ static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max) | |||
1075 | const char *snd_pcm_format_name(snd_pcm_format_t format); | 1075 | const char *snd_pcm_format_name(snd_pcm_format_t format); |
1076 | 1076 | ||
1077 | /** | 1077 | /** |
1078 | * Get a string naming the direction of a stream | 1078 | * snd_pcm_stream_str - Get a string naming the direction of a stream |
1079 | * @substream: the pcm substream instance | ||
1079 | */ | 1080 | */ |
1080 | static inline const char *snd_pcm_stream_str(struct snd_pcm_substream *substream) | 1081 | static inline const char *snd_pcm_stream_str(struct snd_pcm_substream *substream) |
1081 | { | 1082 | { |
diff --git a/include/trace/events/sched.h b/include/trace/events/sched.h index ea7a2035456d..5a8671e8a67f 100644 --- a/include/trace/events/sched.h +++ b/include/trace/events/sched.h | |||
@@ -73,6 +73,9 @@ DECLARE_EVENT_CLASS(sched_wakeup_template, | |||
73 | __entry->prio = p->prio; | 73 | __entry->prio = p->prio; |
74 | __entry->success = success; | 74 | __entry->success = success; |
75 | __entry->target_cpu = task_cpu(p); | 75 | __entry->target_cpu = task_cpu(p); |
76 | ) | ||
77 | TP_perf_assign( | ||
78 | __perf_task(p); | ||
76 | ), | 79 | ), |
77 | 80 | ||
78 | TP_printk("comm=%s pid=%d prio=%d success=%d target_cpu=%03d", | 81 | TP_printk("comm=%s pid=%d prio=%d success=%d target_cpu=%03d", |
@@ -325,6 +328,7 @@ DECLARE_EVENT_CLASS(sched_stat_template, | |||
325 | ) | 328 | ) |
326 | TP_perf_assign( | 329 | TP_perf_assign( |
327 | __perf_count(delay); | 330 | __perf_count(delay); |
331 | __perf_task(tsk); | ||
328 | ), | 332 | ), |
329 | 333 | ||
330 | TP_printk("comm=%s pid=%d delay=%Lu [ns]", | 334 | TP_printk("comm=%s pid=%d delay=%Lu [ns]", |
diff --git a/include/trace/ftrace.h b/include/trace/ftrace.h index c6bc2faaf261..a763888a36f9 100644 --- a/include/trace/ftrace.h +++ b/include/trace/ftrace.h | |||
@@ -712,6 +712,9 @@ __attribute__((section("_ftrace_events"))) *__event_##call = &event_##call | |||
712 | #undef __perf_count | 712 | #undef __perf_count |
713 | #define __perf_count(c) __count = (c) | 713 | #define __perf_count(c) __count = (c) |
714 | 714 | ||
715 | #undef __perf_task | ||
716 | #define __perf_task(t) __task = (t) | ||
717 | |||
715 | #undef TP_perf_assign | 718 | #undef TP_perf_assign |
716 | #define TP_perf_assign(args...) args | 719 | #define TP_perf_assign(args...) args |
717 | 720 | ||
@@ -725,6 +728,7 @@ perf_trace_##call(void *__data, proto) \ | |||
725 | struct ftrace_raw_##call *entry; \ | 728 | struct ftrace_raw_##call *entry; \ |
726 | struct pt_regs __regs; \ | 729 | struct pt_regs __regs; \ |
727 | u64 __addr = 0, __count = 1; \ | 730 | u64 __addr = 0, __count = 1; \ |
731 | struct task_struct *__task = NULL; \ | ||
728 | struct hlist_head *head; \ | 732 | struct hlist_head *head; \ |
729 | int __entry_size; \ | 733 | int __entry_size; \ |
730 | int __data_size; \ | 734 | int __data_size; \ |
@@ -752,7 +756,7 @@ perf_trace_##call(void *__data, proto) \ | |||
752 | \ | 756 | \ |
753 | head = this_cpu_ptr(event_call->perf_events); \ | 757 | head = this_cpu_ptr(event_call->perf_events); \ |
754 | perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \ | 758 | perf_trace_buf_submit(entry, __entry_size, rctx, __addr, \ |
755 | __count, &__regs, head); \ | 759 | __count, &__regs, head, __task); \ |
756 | } | 760 | } |
757 | 761 | ||
758 | /* | 762 | /* |
diff --git a/init/main.c b/init/main.c index e60679de61c3..b28673087ac0 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -461,10 +461,6 @@ static void __init mm_init(void) | |||
461 | percpu_init_late(); | 461 | percpu_init_late(); |
462 | pgtable_cache_init(); | 462 | pgtable_cache_init(); |
463 | vmalloc_init(); | 463 | vmalloc_init(); |
464 | #ifdef CONFIG_X86 | ||
465 | if (efi_enabled) | ||
466 | efi_enter_virtual_mode(); | ||
467 | #endif | ||
468 | } | 464 | } |
469 | 465 | ||
470 | asmlinkage void __init start_kernel(void) | 466 | asmlinkage void __init start_kernel(void) |
@@ -606,6 +602,10 @@ asmlinkage void __init start_kernel(void) | |||
606 | calibrate_delay(); | 602 | calibrate_delay(); |
607 | pidmap_init(); | 603 | pidmap_init(); |
608 | anon_vma_init(); | 604 | anon_vma_init(); |
605 | #ifdef CONFIG_X86 | ||
606 | if (efi_enabled) | ||
607 | efi_enter_virtual_mode(); | ||
608 | #endif | ||
609 | thread_info_cache_init(); | 609 | thread_info_cache_init(); |
610 | cred_init(); | 610 | cred_init(); |
611 | fork_init(totalram_pages); | 611 | fork_init(totalram_pages); |
diff --git a/kernel/audit_tree.c b/kernel/audit_tree.c index 3a5ca582ba1e..ed206fd88cca 100644 --- a/kernel/audit_tree.c +++ b/kernel/audit_tree.c | |||
@@ -250,7 +250,6 @@ static void untag_chunk(struct node *p) | |||
250 | spin_unlock(&hash_lock); | 250 | spin_unlock(&hash_lock); |
251 | spin_unlock(&entry->lock); | 251 | spin_unlock(&entry->lock); |
252 | fsnotify_destroy_mark(entry); | 252 | fsnotify_destroy_mark(entry); |
253 | fsnotify_put_mark(entry); | ||
254 | goto out; | 253 | goto out; |
255 | } | 254 | } |
256 | 255 | ||
@@ -259,7 +258,7 @@ static void untag_chunk(struct node *p) | |||
259 | 258 | ||
260 | fsnotify_duplicate_mark(&new->mark, entry); | 259 | fsnotify_duplicate_mark(&new->mark, entry); |
261 | if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.i.inode, NULL, 1)) { | 260 | if (fsnotify_add_mark(&new->mark, new->mark.group, new->mark.i.inode, NULL, 1)) { |
262 | free_chunk(new); | 261 | fsnotify_put_mark(&new->mark); |
263 | goto Fallback; | 262 | goto Fallback; |
264 | } | 263 | } |
265 | 264 | ||
@@ -293,7 +292,7 @@ static void untag_chunk(struct node *p) | |||
293 | spin_unlock(&hash_lock); | 292 | spin_unlock(&hash_lock); |
294 | spin_unlock(&entry->lock); | 293 | spin_unlock(&entry->lock); |
295 | fsnotify_destroy_mark(entry); | 294 | fsnotify_destroy_mark(entry); |
296 | fsnotify_put_mark(entry); | 295 | fsnotify_put_mark(&new->mark); /* drop initial reference */ |
297 | goto out; | 296 | goto out; |
298 | 297 | ||
299 | Fallback: | 298 | Fallback: |
@@ -322,7 +321,7 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree) | |||
322 | 321 | ||
323 | entry = &chunk->mark; | 322 | entry = &chunk->mark; |
324 | if (fsnotify_add_mark(entry, audit_tree_group, inode, NULL, 0)) { | 323 | if (fsnotify_add_mark(entry, audit_tree_group, inode, NULL, 0)) { |
325 | free_chunk(chunk); | 324 | fsnotify_put_mark(entry); |
326 | return -ENOSPC; | 325 | return -ENOSPC; |
327 | } | 326 | } |
328 | 327 | ||
@@ -347,6 +346,7 @@ static int create_chunk(struct inode *inode, struct audit_tree *tree) | |||
347 | insert_hash(chunk); | 346 | insert_hash(chunk); |
348 | spin_unlock(&hash_lock); | 347 | spin_unlock(&hash_lock); |
349 | spin_unlock(&entry->lock); | 348 | spin_unlock(&entry->lock); |
349 | fsnotify_put_mark(entry); /* drop initial reference */ | ||
350 | return 0; | 350 | return 0; |
351 | } | 351 | } |
352 | 352 | ||
@@ -396,7 +396,7 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) | |||
396 | fsnotify_duplicate_mark(chunk_entry, old_entry); | 396 | fsnotify_duplicate_mark(chunk_entry, old_entry); |
397 | if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->i.inode, NULL, 1)) { | 397 | if (fsnotify_add_mark(chunk_entry, chunk_entry->group, chunk_entry->i.inode, NULL, 1)) { |
398 | spin_unlock(&old_entry->lock); | 398 | spin_unlock(&old_entry->lock); |
399 | free_chunk(chunk); | 399 | fsnotify_put_mark(chunk_entry); |
400 | fsnotify_put_mark(old_entry); | 400 | fsnotify_put_mark(old_entry); |
401 | return -ENOSPC; | 401 | return -ENOSPC; |
402 | } | 402 | } |
@@ -444,8 +444,8 @@ static int tag_chunk(struct inode *inode, struct audit_tree *tree) | |||
444 | spin_unlock(&chunk_entry->lock); | 444 | spin_unlock(&chunk_entry->lock); |
445 | spin_unlock(&old_entry->lock); | 445 | spin_unlock(&old_entry->lock); |
446 | fsnotify_destroy_mark(old_entry); | 446 | fsnotify_destroy_mark(old_entry); |
447 | fsnotify_put_mark(chunk_entry); /* drop initial reference */ | ||
447 | fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */ | 448 | fsnotify_put_mark(old_entry); /* pair to fsnotify_find mark_entry */ |
448 | fsnotify_put_mark(old_entry); /* and kill it */ | ||
449 | return 0; | 449 | return 0; |
450 | } | 450 | } |
451 | 451 | ||
@@ -916,7 +916,12 @@ static void audit_tree_freeing_mark(struct fsnotify_mark *entry, struct fsnotify | |||
916 | struct audit_chunk *chunk = container_of(entry, struct audit_chunk, mark); | 916 | struct audit_chunk *chunk = container_of(entry, struct audit_chunk, mark); |
917 | 917 | ||
918 | evict_chunk(chunk); | 918 | evict_chunk(chunk); |
919 | fsnotify_put_mark(entry); | 919 | |
920 | /* | ||
921 | * We are guaranteed to have at least one reference to the mark from | ||
922 | * either the inode or the caller of fsnotify_destroy_mark(). | ||
923 | */ | ||
924 | BUG_ON(atomic_read(&entry->refcnt) < 1); | ||
920 | } | 925 | } |
921 | 926 | ||
922 | static bool audit_tree_send_event(struct fsnotify_group *group, struct inode *inode, | 927 | static bool audit_tree_send_event(struct fsnotify_group *group, struct inode *inode, |
diff --git a/kernel/debug/kdb/kdb_debugger.c b/kernel/debug/kdb/kdb_debugger.c index 8b68ce78ff17..be7b33b73d30 100644 --- a/kernel/debug/kdb/kdb_debugger.c +++ b/kernel/debug/kdb/kdb_debugger.c | |||
@@ -12,6 +12,7 @@ | |||
12 | #include <linux/kdb.h> | 12 | #include <linux/kdb.h> |
13 | #include <linux/kdebug.h> | 13 | #include <linux/kdebug.h> |
14 | #include <linux/export.h> | 14 | #include <linux/export.h> |
15 | #include <linux/hardirq.h> | ||
15 | #include "kdb_private.h" | 16 | #include "kdb_private.h" |
16 | #include "../debug_core.h" | 17 | #include "../debug_core.h" |
17 | 18 | ||
@@ -52,6 +53,9 @@ int kdb_stub(struct kgdb_state *ks) | |||
52 | if (atomic_read(&kgdb_setting_breakpoint)) | 53 | if (atomic_read(&kgdb_setting_breakpoint)) |
53 | reason = KDB_REASON_KEYBOARD; | 54 | reason = KDB_REASON_KEYBOARD; |
54 | 55 | ||
56 | if (in_nmi()) | ||
57 | reason = KDB_REASON_NMI; | ||
58 | |||
55 | for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) { | 59 | for (i = 0, bp = kdb_breakpoints; i < KDB_MAXBPT; i++, bp++) { |
56 | if ((bp->bp_enabled) && (bp->bp_addr == addr)) { | 60 | if ((bp->bp_enabled) && (bp->bp_addr == addr)) { |
57 | reason = KDB_REASON_BREAK; | 61 | reason = KDB_REASON_BREAK; |
diff --git a/kernel/debug/kdb/kdb_io.c b/kernel/debug/kdb/kdb_io.c index bb9520f0f6ff..0a69d2adc4f3 100644 --- a/kernel/debug/kdb/kdb_io.c +++ b/kernel/debug/kdb/kdb_io.c | |||
@@ -715,9 +715,6 @@ kdb_printit: | |||
715 | /* check for having reached the LINES number of printed lines */ | 715 | /* check for having reached the LINES number of printed lines */ |
716 | if (kdb_nextline == linecount) { | 716 | if (kdb_nextline == linecount) { |
717 | char buf1[16] = ""; | 717 | char buf1[16] = ""; |
718 | #if defined(CONFIG_SMP) | ||
719 | char buf2[32]; | ||
720 | #endif | ||
721 | 718 | ||
722 | /* Watch out for recursion here. Any routine that calls | 719 | /* Watch out for recursion here. Any routine that calls |
723 | * kdb_printf will come back through here. And kdb_read | 720 | * kdb_printf will come back through here. And kdb_read |
@@ -732,14 +729,6 @@ kdb_printit: | |||
732 | if (moreprompt == NULL) | 729 | if (moreprompt == NULL) |
733 | moreprompt = "more> "; | 730 | moreprompt = "more> "; |
734 | 731 | ||
735 | #if defined(CONFIG_SMP) | ||
736 | if (strchr(moreprompt, '%')) { | ||
737 | sprintf(buf2, moreprompt, get_cpu()); | ||
738 | put_cpu(); | ||
739 | moreprompt = buf2; | ||
740 | } | ||
741 | #endif | ||
742 | |||
743 | kdb_input_flush(); | 732 | kdb_input_flush(); |
744 | c = console_drivers; | 733 | c = console_drivers; |
745 | 734 | ||
diff --git a/kernel/debug/kdb/kdb_main.c b/kernel/debug/kdb/kdb_main.c index 1f91413edb87..31df1706b9a9 100644 --- a/kernel/debug/kdb/kdb_main.c +++ b/kernel/debug/kdb/kdb_main.c | |||
@@ -139,11 +139,10 @@ static const int __nkdb_err = sizeof(kdbmsgs) / sizeof(kdbmsg_t); | |||
139 | static char *__env[] = { | 139 | static char *__env[] = { |
140 | #if defined(CONFIG_SMP) | 140 | #if defined(CONFIG_SMP) |
141 | "PROMPT=[%d]kdb> ", | 141 | "PROMPT=[%d]kdb> ", |
142 | "MOREPROMPT=[%d]more> ", | ||
143 | #else | 142 | #else |
144 | "PROMPT=kdb> ", | 143 | "PROMPT=kdb> ", |
145 | "MOREPROMPT=more> ", | ||
146 | #endif | 144 | #endif |
145 | "MOREPROMPT=more> ", | ||
147 | "RADIX=16", | 146 | "RADIX=16", |
148 | "MDCOUNT=8", /* lines of md output */ | 147 | "MDCOUNT=8", /* lines of md output */ |
149 | KDB_PLATFORM_ENV, | 148 | KDB_PLATFORM_ENV, |
@@ -1236,18 +1235,6 @@ static int kdb_local(kdb_reason_t reason, int error, struct pt_regs *regs, | |||
1236 | *cmdbuf = '\0'; | 1235 | *cmdbuf = '\0'; |
1237 | *(cmd_hist[cmd_head]) = '\0'; | 1236 | *(cmd_hist[cmd_head]) = '\0'; |
1238 | 1237 | ||
1239 | if (KDB_FLAG(ONLY_DO_DUMP)) { | ||
1240 | /* kdb is off but a catastrophic error requires a dump. | ||
1241 | * Take the dump and reboot. | ||
1242 | * Turn on logging so the kdb output appears in the log | ||
1243 | * buffer in the dump. | ||
1244 | */ | ||
1245 | const char *setargs[] = { "set", "LOGGING", "1" }; | ||
1246 | kdb_set(2, setargs); | ||
1247 | kdb_reboot(0, NULL); | ||
1248 | /*NOTREACHED*/ | ||
1249 | } | ||
1250 | |||
1251 | do_full_getstr: | 1238 | do_full_getstr: |
1252 | #if defined(CONFIG_SMP) | 1239 | #if defined(CONFIG_SMP) |
1253 | snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT"), | 1240 | snprintf(kdb_prompt_str, CMD_BUFLEN, kdbgetenv("PROMPT"), |
diff --git a/kernel/events/callchain.c b/kernel/events/callchain.c index 6581a040f399..98d4597f43d6 100644 --- a/kernel/events/callchain.c +++ b/kernel/events/callchain.c | |||
@@ -153,7 +153,8 @@ put_callchain_entry(int rctx) | |||
153 | put_recursion_context(__get_cpu_var(callchain_recursion), rctx); | 153 | put_recursion_context(__get_cpu_var(callchain_recursion), rctx); |
154 | } | 154 | } |
155 | 155 | ||
156 | struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | 156 | struct perf_callchain_entry * |
157 | perf_callchain(struct perf_event *event, struct pt_regs *regs) | ||
157 | { | 158 | { |
158 | int rctx; | 159 | int rctx; |
159 | struct perf_callchain_entry *entry; | 160 | struct perf_callchain_entry *entry; |
@@ -178,6 +179,12 @@ struct perf_callchain_entry *perf_callchain(struct pt_regs *regs) | |||
178 | } | 179 | } |
179 | 180 | ||
180 | if (regs) { | 181 | if (regs) { |
182 | /* | ||
183 | * Disallow cross-task user callchains. | ||
184 | */ | ||
185 | if (event->ctx->task && event->ctx->task != current) | ||
186 | goto exit_put; | ||
187 | |||
181 | perf_callchain_store(entry, PERF_CONTEXT_USER); | 188 | perf_callchain_store(entry, PERF_CONTEXT_USER); |
182 | perf_callchain_user(entry, regs); | 189 | perf_callchain_user(entry, regs); |
183 | } | 190 | } |
diff --git a/kernel/events/core.c b/kernel/events/core.c index f1cf0edeb39a..b7935fcec7d9 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c | |||
@@ -4039,7 +4039,7 @@ void perf_prepare_sample(struct perf_event_header *header, | |||
4039 | if (sample_type & PERF_SAMPLE_CALLCHAIN) { | 4039 | if (sample_type & PERF_SAMPLE_CALLCHAIN) { |
4040 | int size = 1; | 4040 | int size = 1; |
4041 | 4041 | ||
4042 | data->callchain = perf_callchain(regs); | 4042 | data->callchain = perf_callchain(event, regs); |
4043 | 4043 | ||
4044 | if (data->callchain) | 4044 | if (data->callchain) |
4045 | size += data->callchain->nr; | 4045 | size += data->callchain->nr; |
@@ -5209,7 +5209,8 @@ static int perf_tp_event_match(struct perf_event *event, | |||
5209 | } | 5209 | } |
5210 | 5210 | ||
5211 | void perf_tp_event(u64 addr, u64 count, void *record, int entry_size, | 5211 | void perf_tp_event(u64 addr, u64 count, void *record, int entry_size, |
5212 | struct pt_regs *regs, struct hlist_head *head, int rctx) | 5212 | struct pt_regs *regs, struct hlist_head *head, int rctx, |
5213 | struct task_struct *task) | ||
5213 | { | 5214 | { |
5214 | struct perf_sample_data data; | 5215 | struct perf_sample_data data; |
5215 | struct perf_event *event; | 5216 | struct perf_event *event; |
@@ -5228,6 +5229,31 @@ void perf_tp_event(u64 addr, u64 count, void *record, int entry_size, | |||
5228 | perf_swevent_event(event, count, &data, regs); | 5229 | perf_swevent_event(event, count, &data, regs); |
5229 | } | 5230 | } |
5230 | 5231 | ||
5232 | /* | ||
5233 | * If we got specified a target task, also iterate its context and | ||
5234 | * deliver this event there too. | ||
5235 | */ | ||
5236 | if (task && task != current) { | ||
5237 | struct perf_event_context *ctx; | ||
5238 | struct trace_entry *entry = record; | ||
5239 | |||
5240 | rcu_read_lock(); | ||
5241 | ctx = rcu_dereference(task->perf_event_ctxp[perf_sw_context]); | ||
5242 | if (!ctx) | ||
5243 | goto unlock; | ||
5244 | |||
5245 | list_for_each_entry_rcu(event, &ctx->event_list, event_entry) { | ||
5246 | if (event->attr.type != PERF_TYPE_TRACEPOINT) | ||
5247 | continue; | ||
5248 | if (event->attr.config != entry->type) | ||
5249 | continue; | ||
5250 | if (perf_tp_event_match(event, &data, regs)) | ||
5251 | perf_swevent_event(event, count, &data, regs); | ||
5252 | } | ||
5253 | unlock: | ||
5254 | rcu_read_unlock(); | ||
5255 | } | ||
5256 | |||
5231 | perf_swevent_put_recursion_context(rctx); | 5257 | perf_swevent_put_recursion_context(rctx); |
5232 | } | 5258 | } |
5233 | EXPORT_SYMBOL_GPL(perf_tp_event); | 5259 | EXPORT_SYMBOL_GPL(perf_tp_event); |
diff --git a/kernel/events/internal.h b/kernel/events/internal.h index b0b107f90afc..a096c19f2c2a 100644 --- a/kernel/events/internal.h +++ b/kernel/events/internal.h | |||
@@ -101,7 +101,8 @@ __output_copy(struct perf_output_handle *handle, | |||
101 | } | 101 | } |
102 | 102 | ||
103 | /* Callchain handling */ | 103 | /* Callchain handling */ |
104 | extern struct perf_callchain_entry *perf_callchain(struct pt_regs *regs); | 104 | extern struct perf_callchain_entry * |
105 | perf_callchain(struct perf_event *event, struct pt_regs *regs); | ||
105 | extern int get_callchain_buffers(void); | 106 | extern int get_callchain_buffers(void); |
106 | extern void put_callchain_buffers(void); | 107 | extern void put_callchain_buffers(void); |
107 | 108 | ||
diff --git a/kernel/futex.c b/kernel/futex.c index e2b0fb9a0b3b..3717e7b306e0 100644 --- a/kernel/futex.c +++ b/kernel/futex.c | |||
@@ -2231,11 +2231,11 @@ int handle_early_requeue_pi_wakeup(struct futex_hash_bucket *hb, | |||
2231 | * @uaddr2: the pi futex we will take prior to returning to user-space | 2231 | * @uaddr2: the pi futex we will take prior to returning to user-space |
2232 | * | 2232 | * |
2233 | * The caller will wait on uaddr and will be requeued by futex_requeue() to | 2233 | * The caller will wait on uaddr and will be requeued by futex_requeue() to |
2234 | * uaddr2 which must be PI aware. Normal wakeup will wake on uaddr2 and | 2234 | * uaddr2 which must be PI aware and unique from uaddr. Normal wakeup will wake |
2235 | * complete the acquisition of the rt_mutex prior to returning to userspace. | 2235 | * on uaddr2 and complete the acquisition of the rt_mutex prior to returning to |
2236 | * This ensures the rt_mutex maintains an owner when it has waiters; without | 2236 | * userspace. This ensures the rt_mutex maintains an owner when it has waiters; |
2237 | * one, the pi logic wouldn't know which task to boost/deboost, if there was a | 2237 | * without one, the pi logic would not know which task to boost/deboost, if |
2238 | * need to. | 2238 | * there was a need to. |
2239 | * | 2239 | * |
2240 | * We call schedule in futex_wait_queue_me() when we enqueue and return there | 2240 | * We call schedule in futex_wait_queue_me() when we enqueue and return there |
2241 | * via the following: | 2241 | * via the following: |
@@ -2272,6 +2272,9 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, | |||
2272 | struct futex_q q = futex_q_init; | 2272 | struct futex_q q = futex_q_init; |
2273 | int res, ret; | 2273 | int res, ret; |
2274 | 2274 | ||
2275 | if (uaddr == uaddr2) | ||
2276 | return -EINVAL; | ||
2277 | |||
2275 | if (!bitset) | 2278 | if (!bitset) |
2276 | return -EINVAL; | 2279 | return -EINVAL; |
2277 | 2280 | ||
@@ -2343,7 +2346,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, | |||
2343 | * signal. futex_unlock_pi() will not destroy the lock_ptr nor | 2346 | * signal. futex_unlock_pi() will not destroy the lock_ptr nor |
2344 | * the pi_state. | 2347 | * the pi_state. |
2345 | */ | 2348 | */ |
2346 | WARN_ON(!&q.pi_state); | 2349 | WARN_ON(!q.pi_state); |
2347 | pi_mutex = &q.pi_state->pi_mutex; | 2350 | pi_mutex = &q.pi_state->pi_mutex; |
2348 | ret = rt_mutex_finish_proxy_lock(pi_mutex, to, &rt_waiter, 1); | 2351 | ret = rt_mutex_finish_proxy_lock(pi_mutex, to, &rt_waiter, 1); |
2349 | debug_rt_mutex_free_waiter(&rt_waiter); | 2352 | debug_rt_mutex_free_waiter(&rt_waiter); |
@@ -2370,7 +2373,7 @@ static int futex_wait_requeue_pi(u32 __user *uaddr, unsigned int flags, | |||
2370 | * fault, unlock the rt_mutex and return the fault to userspace. | 2373 | * fault, unlock the rt_mutex and return the fault to userspace. |
2371 | */ | 2374 | */ |
2372 | if (ret == -EFAULT) { | 2375 | if (ret == -EFAULT) { |
2373 | if (rt_mutex_owner(pi_mutex) == current) | 2376 | if (pi_mutex && rt_mutex_owner(pi_mutex) == current) |
2374 | rt_mutex_unlock(pi_mutex); | 2377 | rt_mutex_unlock(pi_mutex); |
2375 | } else if (ret == -EINTR) { | 2378 | } else if (ret == -EINTR) { |
2376 | /* | 2379 | /* |
diff --git a/kernel/irq/manage.c b/kernel/irq/manage.c index 0a8e8f059627..4c69326aa773 100644 --- a/kernel/irq/manage.c +++ b/kernel/irq/manage.c | |||
@@ -944,6 +944,18 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
944 | } | 944 | } |
945 | 945 | ||
946 | /* | 946 | /* |
947 | * Drivers are often written to work w/o knowledge about the | ||
948 | * underlying irq chip implementation, so a request for a | ||
949 | * threaded irq without a primary hard irq context handler | ||
950 | * requires the ONESHOT flag to be set. Some irq chips like | ||
951 | * MSI based interrupts are per se one shot safe. Check the | ||
952 | * chip flags, so we can avoid the unmask dance at the end of | ||
953 | * the threaded handler for those. | ||
954 | */ | ||
955 | if (desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE) | ||
956 | new->flags &= ~IRQF_ONESHOT; | ||
957 | |||
958 | /* | ||
947 | * The following block of code has to be executed atomically | 959 | * The following block of code has to be executed atomically |
948 | */ | 960 | */ |
949 | raw_spin_lock_irqsave(&desc->lock, flags); | 961 | raw_spin_lock_irqsave(&desc->lock, flags); |
@@ -1017,7 +1029,8 @@ __setup_irq(unsigned int irq, struct irq_desc *desc, struct irqaction *new) | |||
1017 | */ | 1029 | */ |
1018 | new->thread_mask = 1 << ffz(thread_mask); | 1030 | new->thread_mask = 1 << ffz(thread_mask); |
1019 | 1031 | ||
1020 | } else if (new->handler == irq_default_primary_handler) { | 1032 | } else if (new->handler == irq_default_primary_handler && |
1033 | !(desc->irq_data.chip->flags & IRQCHIP_ONESHOT_SAFE)) { | ||
1021 | /* | 1034 | /* |
1022 | * The interrupt was requested with handler = NULL, so | 1035 | * The interrupt was requested with handler = NULL, so |
1023 | * we use the default primary handler for it. But it | 1036 | * we use the default primary handler for it. But it |
diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 1da39ea248fd..c8b7446b27df 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c | |||
@@ -178,9 +178,6 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) | |||
178 | arch_suspend_enable_irqs(); | 178 | arch_suspend_enable_irqs(); |
179 | BUG_ON(irqs_disabled()); | 179 | BUG_ON(irqs_disabled()); |
180 | 180 | ||
181 | /* Kick the lockup detector */ | ||
182 | lockup_detector_bootcpu_resume(); | ||
183 | |||
184 | Enable_cpus: | 181 | Enable_cpus: |
185 | enable_nonboot_cpus(); | 182 | enable_nonboot_cpus(); |
186 | 183 | ||
diff --git a/kernel/printk.c b/kernel/printk.c index 6a76ab9d4476..66a2ea37b576 100644 --- a/kernel/printk.c +++ b/kernel/printk.c | |||
@@ -1034,6 +1034,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) | |||
1034 | struct log *msg = log_from_idx(idx); | 1034 | struct log *msg = log_from_idx(idx); |
1035 | 1035 | ||
1036 | len += msg_print_text(msg, prev, true, NULL, 0); | 1036 | len += msg_print_text(msg, prev, true, NULL, 0); |
1037 | prev = msg->flags; | ||
1037 | idx = log_next(idx); | 1038 | idx = log_next(idx); |
1038 | seq++; | 1039 | seq++; |
1039 | } | 1040 | } |
@@ -1046,6 +1047,7 @@ static int syslog_print_all(char __user *buf, int size, bool clear) | |||
1046 | struct log *msg = log_from_idx(idx); | 1047 | struct log *msg = log_from_idx(idx); |
1047 | 1048 | ||
1048 | len -= msg_print_text(msg, prev, true, NULL, 0); | 1049 | len -= msg_print_text(msg, prev, true, NULL, 0); |
1050 | prev = msg->flags; | ||
1049 | idx = log_next(idx); | 1051 | idx = log_next(idx); |
1050 | seq++; | 1052 | seq++; |
1051 | } | 1053 | } |
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index d325c4b2dcbb..fbf1fd098dc6 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -3142,6 +3142,20 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | |||
3142 | # define nsecs_to_cputime(__nsecs) nsecs_to_jiffies(__nsecs) | 3142 | # define nsecs_to_cputime(__nsecs) nsecs_to_jiffies(__nsecs) |
3143 | #endif | 3143 | #endif |
3144 | 3144 | ||
3145 | static cputime_t scale_utime(cputime_t utime, cputime_t rtime, cputime_t total) | ||
3146 | { | ||
3147 | u64 temp = (__force u64) rtime; | ||
3148 | |||
3149 | temp *= (__force u64) utime; | ||
3150 | |||
3151 | if (sizeof(cputime_t) == 4) | ||
3152 | temp = div_u64(temp, (__force u32) total); | ||
3153 | else | ||
3154 | temp = div64_u64(temp, (__force u64) total); | ||
3155 | |||
3156 | return (__force cputime_t) temp; | ||
3157 | } | ||
3158 | |||
3145 | void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | 3159 | void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st) |
3146 | { | 3160 | { |
3147 | cputime_t rtime, utime = p->utime, total = utime + p->stime; | 3161 | cputime_t rtime, utime = p->utime, total = utime + p->stime; |
@@ -3151,13 +3165,9 @@ void task_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | |||
3151 | */ | 3165 | */ |
3152 | rtime = nsecs_to_cputime(p->se.sum_exec_runtime); | 3166 | rtime = nsecs_to_cputime(p->se.sum_exec_runtime); |
3153 | 3167 | ||
3154 | if (total) { | 3168 | if (total) |
3155 | u64 temp = (__force u64) rtime; | 3169 | utime = scale_utime(utime, rtime, total); |
3156 | 3170 | else | |
3157 | temp *= (__force u64) utime; | ||
3158 | do_div(temp, (__force u32) total); | ||
3159 | utime = (__force cputime_t) temp; | ||
3160 | } else | ||
3161 | utime = rtime; | 3171 | utime = rtime; |
3162 | 3172 | ||
3163 | /* | 3173 | /* |
@@ -3184,13 +3194,9 @@ void thread_group_times(struct task_struct *p, cputime_t *ut, cputime_t *st) | |||
3184 | total = cputime.utime + cputime.stime; | 3194 | total = cputime.utime + cputime.stime; |
3185 | rtime = nsecs_to_cputime(cputime.sum_exec_runtime); | 3195 | rtime = nsecs_to_cputime(cputime.sum_exec_runtime); |
3186 | 3196 | ||
3187 | if (total) { | 3197 | if (total) |
3188 | u64 temp = (__force u64) rtime; | 3198 | utime = scale_utime(cputime.utime, rtime, total); |
3189 | 3199 | else | |
3190 | temp *= (__force u64) cputime.utime; | ||
3191 | do_div(temp, (__force u32) total); | ||
3192 | utime = (__force cputime_t) temp; | ||
3193 | } else | ||
3194 | utime = rtime; | 3200 | utime = rtime; |
3195 | 3201 | ||
3196 | sig->prev_utime = max(sig->prev_utime, utime); | 3202 | sig->prev_utime = max(sig->prev_utime, utime); |
@@ -4340,9 +4346,7 @@ recheck: | |||
4340 | */ | 4346 | */ |
4341 | if (unlikely(policy == p->policy && (!rt_policy(policy) || | 4347 | if (unlikely(policy == p->policy && (!rt_policy(policy) || |
4342 | param->sched_priority == p->rt_priority))) { | 4348 | param->sched_priority == p->rt_priority))) { |
4343 | 4349 | task_rq_unlock(rq, p, &flags); | |
4344 | __task_rq_unlock(rq); | ||
4345 | raw_spin_unlock_irqrestore(&p->pi_lock, flags); | ||
4346 | return 0; | 4350 | return 0; |
4347 | } | 4351 | } |
4348 | 4352 | ||
@@ -7248,6 +7252,7 @@ int in_sched_functions(unsigned long addr) | |||
7248 | 7252 | ||
7249 | #ifdef CONFIG_CGROUP_SCHED | 7253 | #ifdef CONFIG_CGROUP_SCHED |
7250 | struct task_group root_task_group; | 7254 | struct task_group root_task_group; |
7255 | LIST_HEAD(task_groups); | ||
7251 | #endif | 7256 | #endif |
7252 | 7257 | ||
7253 | DECLARE_PER_CPU(cpumask_var_t, load_balance_tmpmask); | 7258 | DECLARE_PER_CPU(cpumask_var_t, load_balance_tmpmask); |
diff --git a/kernel/sched/cpupri.c b/kernel/sched/cpupri.c index d72586fdf660..23aa789c53ee 100644 --- a/kernel/sched/cpupri.c +++ b/kernel/sched/cpupri.c | |||
@@ -65,8 +65,8 @@ static int convert_prio(int prio) | |||
65 | int cpupri_find(struct cpupri *cp, struct task_struct *p, | 65 | int cpupri_find(struct cpupri *cp, struct task_struct *p, |
66 | struct cpumask *lowest_mask) | 66 | struct cpumask *lowest_mask) |
67 | { | 67 | { |
68 | int idx = 0; | 68 | int idx = 0; |
69 | int task_pri = convert_prio(p->prio); | 69 | int task_pri = convert_prio(p->prio); |
70 | 70 | ||
71 | if (task_pri >= MAX_RT_PRIO) | 71 | if (task_pri >= MAX_RT_PRIO) |
72 | return 0; | 72 | return 0; |
@@ -137,9 +137,9 @@ int cpupri_find(struct cpupri *cp, struct task_struct *p, | |||
137 | */ | 137 | */ |
138 | void cpupri_set(struct cpupri *cp, int cpu, int newpri) | 138 | void cpupri_set(struct cpupri *cp, int cpu, int newpri) |
139 | { | 139 | { |
140 | int *currpri = &cp->cpu_to_pri[cpu]; | 140 | int *currpri = &cp->cpu_to_pri[cpu]; |
141 | int oldpri = *currpri; | 141 | int oldpri = *currpri; |
142 | int do_mb = 0; | 142 | int do_mb = 0; |
143 | 143 | ||
144 | newpri = convert_prio(newpri); | 144 | newpri = convert_prio(newpri); |
145 | 145 | ||
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c index 22321db64952..c219bf8d704c 100644 --- a/kernel/sched/fair.c +++ b/kernel/sched/fair.c | |||
@@ -3069,6 +3069,9 @@ struct lb_env { | |||
3069 | int new_dst_cpu; | 3069 | int new_dst_cpu; |
3070 | enum cpu_idle_type idle; | 3070 | enum cpu_idle_type idle; |
3071 | long imbalance; | 3071 | long imbalance; |
3072 | /* The set of CPUs under consideration for load-balancing */ | ||
3073 | struct cpumask *cpus; | ||
3074 | |||
3072 | unsigned int flags; | 3075 | unsigned int flags; |
3073 | 3076 | ||
3074 | unsigned int loop; | 3077 | unsigned int loop; |
@@ -3384,6 +3387,14 @@ static int tg_load_down(struct task_group *tg, void *data) | |||
3384 | 3387 | ||
3385 | static void update_h_load(long cpu) | 3388 | static void update_h_load(long cpu) |
3386 | { | 3389 | { |
3390 | struct rq *rq = cpu_rq(cpu); | ||
3391 | unsigned long now = jiffies; | ||
3392 | |||
3393 | if (rq->h_load_throttle == now) | ||
3394 | return; | ||
3395 | |||
3396 | rq->h_load_throttle = now; | ||
3397 | |||
3387 | rcu_read_lock(); | 3398 | rcu_read_lock(); |
3388 | walk_tg_tree(tg_load_down, tg_nop, (void *)cpu); | 3399 | walk_tg_tree(tg_load_down, tg_nop, (void *)cpu); |
3389 | rcu_read_unlock(); | 3400 | rcu_read_unlock(); |
@@ -3653,8 +3664,7 @@ fix_small_capacity(struct sched_domain *sd, struct sched_group *group) | |||
3653 | */ | 3664 | */ |
3654 | static inline void update_sg_lb_stats(struct lb_env *env, | 3665 | static inline void update_sg_lb_stats(struct lb_env *env, |
3655 | struct sched_group *group, int load_idx, | 3666 | struct sched_group *group, int load_idx, |
3656 | int local_group, const struct cpumask *cpus, | 3667 | int local_group, int *balance, struct sg_lb_stats *sgs) |
3657 | int *balance, struct sg_lb_stats *sgs) | ||
3658 | { | 3668 | { |
3659 | unsigned long nr_running, max_nr_running, min_nr_running; | 3669 | unsigned long nr_running, max_nr_running, min_nr_running; |
3660 | unsigned long load, max_cpu_load, min_cpu_load; | 3670 | unsigned long load, max_cpu_load, min_cpu_load; |
@@ -3671,7 +3681,7 @@ static inline void update_sg_lb_stats(struct lb_env *env, | |||
3671 | max_nr_running = 0; | 3681 | max_nr_running = 0; |
3672 | min_nr_running = ~0UL; | 3682 | min_nr_running = ~0UL; |
3673 | 3683 | ||
3674 | for_each_cpu_and(i, sched_group_cpus(group), cpus) { | 3684 | for_each_cpu_and(i, sched_group_cpus(group), env->cpus) { |
3675 | struct rq *rq = cpu_rq(i); | 3685 | struct rq *rq = cpu_rq(i); |
3676 | 3686 | ||
3677 | nr_running = rq->nr_running; | 3687 | nr_running = rq->nr_running; |
@@ -3800,8 +3810,7 @@ static bool update_sd_pick_busiest(struct lb_env *env, | |||
3800 | * @sds: variable to hold the statistics for this sched_domain. | 3810 | * @sds: variable to hold the statistics for this sched_domain. |
3801 | */ | 3811 | */ |
3802 | static inline void update_sd_lb_stats(struct lb_env *env, | 3812 | static inline void update_sd_lb_stats(struct lb_env *env, |
3803 | const struct cpumask *cpus, | 3813 | int *balance, struct sd_lb_stats *sds) |
3804 | int *balance, struct sd_lb_stats *sds) | ||
3805 | { | 3814 | { |
3806 | struct sched_domain *child = env->sd->child; | 3815 | struct sched_domain *child = env->sd->child; |
3807 | struct sched_group *sg = env->sd->groups; | 3816 | struct sched_group *sg = env->sd->groups; |
@@ -3818,8 +3827,7 @@ static inline void update_sd_lb_stats(struct lb_env *env, | |||
3818 | 3827 | ||
3819 | local_group = cpumask_test_cpu(env->dst_cpu, sched_group_cpus(sg)); | 3828 | local_group = cpumask_test_cpu(env->dst_cpu, sched_group_cpus(sg)); |
3820 | memset(&sgs, 0, sizeof(sgs)); | 3829 | memset(&sgs, 0, sizeof(sgs)); |
3821 | update_sg_lb_stats(env, sg, load_idx, local_group, | 3830 | update_sg_lb_stats(env, sg, load_idx, local_group, balance, &sgs); |
3822 | cpus, balance, &sgs); | ||
3823 | 3831 | ||
3824 | if (local_group && !(*balance)) | 3832 | if (local_group && !(*balance)) |
3825 | return; | 3833 | return; |
@@ -4055,7 +4063,6 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s | |||
4055 | * to restore balance. | 4063 | * to restore balance. |
4056 | * | 4064 | * |
4057 | * @env: The load balancing environment. | 4065 | * @env: The load balancing environment. |
4058 | * @cpus: The set of CPUs under consideration for load-balancing. | ||
4059 | * @balance: Pointer to a variable indicating if this_cpu | 4066 | * @balance: Pointer to a variable indicating if this_cpu |
4060 | * is the appropriate cpu to perform load balancing at this_level. | 4067 | * is the appropriate cpu to perform load balancing at this_level. |
4061 | * | 4068 | * |
@@ -4065,7 +4072,7 @@ static inline void calculate_imbalance(struct lb_env *env, struct sd_lb_stats *s | |||
4065 | * put to idle by rebalancing its tasks onto our group. | 4072 | * put to idle by rebalancing its tasks onto our group. |
4066 | */ | 4073 | */ |
4067 | static struct sched_group * | 4074 | static struct sched_group * |
4068 | find_busiest_group(struct lb_env *env, const struct cpumask *cpus, int *balance) | 4075 | find_busiest_group(struct lb_env *env, int *balance) |
4069 | { | 4076 | { |
4070 | struct sd_lb_stats sds; | 4077 | struct sd_lb_stats sds; |
4071 | 4078 | ||
@@ -4075,7 +4082,7 @@ find_busiest_group(struct lb_env *env, const struct cpumask *cpus, int *balance) | |||
4075 | * Compute the various statistics relavent for load balancing at | 4082 | * Compute the various statistics relavent for load balancing at |
4076 | * this level. | 4083 | * this level. |
4077 | */ | 4084 | */ |
4078 | update_sd_lb_stats(env, cpus, balance, &sds); | 4085 | update_sd_lb_stats(env, balance, &sds); |
4079 | 4086 | ||
4080 | /* | 4087 | /* |
4081 | * this_cpu is not the appropriate cpu to perform load balancing at | 4088 | * this_cpu is not the appropriate cpu to perform load balancing at |
@@ -4155,8 +4162,7 @@ ret: | |||
4155 | * find_busiest_queue - find the busiest runqueue among the cpus in group. | 4162 | * find_busiest_queue - find the busiest runqueue among the cpus in group. |
4156 | */ | 4163 | */ |
4157 | static struct rq *find_busiest_queue(struct lb_env *env, | 4164 | static struct rq *find_busiest_queue(struct lb_env *env, |
4158 | struct sched_group *group, | 4165 | struct sched_group *group) |
4159 | const struct cpumask *cpus) | ||
4160 | { | 4166 | { |
4161 | struct rq *busiest = NULL, *rq; | 4167 | struct rq *busiest = NULL, *rq; |
4162 | unsigned long max_load = 0; | 4168 | unsigned long max_load = 0; |
@@ -4171,7 +4177,7 @@ static struct rq *find_busiest_queue(struct lb_env *env, | |||
4171 | if (!capacity) | 4177 | if (!capacity) |
4172 | capacity = fix_small_capacity(env->sd, group); | 4178 | capacity = fix_small_capacity(env->sd, group); |
4173 | 4179 | ||
4174 | if (!cpumask_test_cpu(i, cpus)) | 4180 | if (!cpumask_test_cpu(i, env->cpus)) |
4175 | continue; | 4181 | continue; |
4176 | 4182 | ||
4177 | rq = cpu_rq(i); | 4183 | rq = cpu_rq(i); |
@@ -4252,6 +4258,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, | |||
4252 | .dst_grpmask = sched_group_cpus(sd->groups), | 4258 | .dst_grpmask = sched_group_cpus(sd->groups), |
4253 | .idle = idle, | 4259 | .idle = idle, |
4254 | .loop_break = sched_nr_migrate_break, | 4260 | .loop_break = sched_nr_migrate_break, |
4261 | .cpus = cpus, | ||
4255 | }; | 4262 | }; |
4256 | 4263 | ||
4257 | cpumask_copy(cpus, cpu_active_mask); | 4264 | cpumask_copy(cpus, cpu_active_mask); |
@@ -4260,7 +4267,7 @@ static int load_balance(int this_cpu, struct rq *this_rq, | |||
4260 | schedstat_inc(sd, lb_count[idle]); | 4267 | schedstat_inc(sd, lb_count[idle]); |
4261 | 4268 | ||
4262 | redo: | 4269 | redo: |
4263 | group = find_busiest_group(&env, cpus, balance); | 4270 | group = find_busiest_group(&env, balance); |
4264 | 4271 | ||
4265 | if (*balance == 0) | 4272 | if (*balance == 0) |
4266 | goto out_balanced; | 4273 | goto out_balanced; |
@@ -4270,7 +4277,7 @@ redo: | |||
4270 | goto out_balanced; | 4277 | goto out_balanced; |
4271 | } | 4278 | } |
4272 | 4279 | ||
4273 | busiest = find_busiest_queue(&env, group, cpus); | 4280 | busiest = find_busiest_queue(&env, group); |
4274 | if (!busiest) { | 4281 | if (!busiest) { |
4275 | schedstat_inc(sd, lb_nobusyq[idle]); | 4282 | schedstat_inc(sd, lb_nobusyq[idle]); |
4276 | goto out_balanced; | 4283 | goto out_balanced; |
@@ -4294,11 +4301,10 @@ redo: | |||
4294 | env.src_rq = busiest; | 4301 | env.src_rq = busiest; |
4295 | env.loop_max = min(sysctl_sched_nr_migrate, busiest->nr_running); | 4302 | env.loop_max = min(sysctl_sched_nr_migrate, busiest->nr_running); |
4296 | 4303 | ||
4304 | update_h_load(env.src_cpu); | ||
4297 | more_balance: | 4305 | more_balance: |
4298 | local_irq_save(flags); | 4306 | local_irq_save(flags); |
4299 | double_rq_lock(this_rq, busiest); | 4307 | double_rq_lock(this_rq, busiest); |
4300 | if (!env.loop) | ||
4301 | update_h_load(env.src_cpu); | ||
4302 | 4308 | ||
4303 | /* | 4309 | /* |
4304 | * cur_ld_moved - load moved in current iteration | 4310 | * cur_ld_moved - load moved in current iteration |
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c index 573e1ca01102..944cb68420e9 100644 --- a/kernel/sched/rt.c +++ b/kernel/sched/rt.c | |||
@@ -788,6 +788,19 @@ static int do_sched_rt_period_timer(struct rt_bandwidth *rt_b, int overrun) | |||
788 | const struct cpumask *span; | 788 | const struct cpumask *span; |
789 | 789 | ||
790 | span = sched_rt_period_mask(); | 790 | span = sched_rt_period_mask(); |
791 | #ifdef CONFIG_RT_GROUP_SCHED | ||
792 | /* | ||
793 | * FIXME: isolated CPUs should really leave the root task group, | ||
794 | * whether they are isolcpus or were isolated via cpusets, lest | ||
795 | * the timer run on a CPU which does not service all runqueues, | ||
796 | * potentially leaving other CPUs indefinitely throttled. If | ||
797 | * isolation is really required, the user will turn the throttle | ||
798 | * off to kill the perturbations it causes anyway. Meanwhile, | ||
799 | * this maintains functionality for boot and/or troubleshooting. | ||
800 | */ | ||
801 | if (rt_b == &root_task_group.rt_bandwidth) | ||
802 | span = cpu_online_mask; | ||
803 | #endif | ||
791 | for_each_cpu(i, span) { | 804 | for_each_cpu(i, span) { |
792 | int enqueue = 0; | 805 | int enqueue = 0; |
793 | struct rt_rq *rt_rq = sched_rt_period_rt_rq(rt_b, i); | 806 | struct rt_rq *rt_rq = sched_rt_period_rt_rq(rt_b, i); |
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h index c35a1a7dd4d6..f6714d009e77 100644 --- a/kernel/sched/sched.h +++ b/kernel/sched/sched.h | |||
@@ -80,7 +80,7 @@ extern struct mutex sched_domains_mutex; | |||
80 | struct cfs_rq; | 80 | struct cfs_rq; |
81 | struct rt_rq; | 81 | struct rt_rq; |
82 | 82 | ||
83 | static LIST_HEAD(task_groups); | 83 | extern struct list_head task_groups; |
84 | 84 | ||
85 | struct cfs_bandwidth { | 85 | struct cfs_bandwidth { |
86 | #ifdef CONFIG_CFS_BANDWIDTH | 86 | #ifdef CONFIG_CFS_BANDWIDTH |
@@ -374,7 +374,11 @@ struct rq { | |||
374 | #ifdef CONFIG_FAIR_GROUP_SCHED | 374 | #ifdef CONFIG_FAIR_GROUP_SCHED |
375 | /* list of leaf cfs_rq on this cpu: */ | 375 | /* list of leaf cfs_rq on this cpu: */ |
376 | struct list_head leaf_cfs_rq_list; | 376 | struct list_head leaf_cfs_rq_list; |
377 | #endif | 377 | #ifdef CONFIG_SMP |
378 | unsigned long h_load_throttle; | ||
379 | #endif /* CONFIG_SMP */ | ||
380 | #endif /* CONFIG_FAIR_GROUP_SCHED */ | ||
381 | |||
378 | #ifdef CONFIG_RT_GROUP_SCHED | 382 | #ifdef CONFIG_RT_GROUP_SCHED |
379 | struct list_head leaf_rt_rq_list; | 383 | struct list_head leaf_rt_rq_list; |
380 | #endif | 384 | #endif |
diff --git a/kernel/sched/stop_task.c b/kernel/sched/stop_task.c index 7b386e86fd23..da5eb5bed84a 100644 --- a/kernel/sched/stop_task.c +++ b/kernel/sched/stop_task.c | |||
@@ -27,8 +27,10 @@ static struct task_struct *pick_next_task_stop(struct rq *rq) | |||
27 | { | 27 | { |
28 | struct task_struct *stop = rq->stop; | 28 | struct task_struct *stop = rq->stop; |
29 | 29 | ||
30 | if (stop && stop->on_rq) | 30 | if (stop && stop->on_rq) { |
31 | stop->se.exec_start = rq->clock_task; | ||
31 | return stop; | 32 | return stop; |
33 | } | ||
32 | 34 | ||
33 | return NULL; | 35 | return NULL; |
34 | } | 36 | } |
@@ -52,6 +54,21 @@ static void yield_task_stop(struct rq *rq) | |||
52 | 54 | ||
53 | static void put_prev_task_stop(struct rq *rq, struct task_struct *prev) | 55 | static void put_prev_task_stop(struct rq *rq, struct task_struct *prev) |
54 | { | 56 | { |
57 | struct task_struct *curr = rq->curr; | ||
58 | u64 delta_exec; | ||
59 | |||
60 | delta_exec = rq->clock_task - curr->se.exec_start; | ||
61 | if (unlikely((s64)delta_exec < 0)) | ||
62 | delta_exec = 0; | ||
63 | |||
64 | schedstat_set(curr->se.statistics.exec_max, | ||
65 | max(curr->se.statistics.exec_max, delta_exec)); | ||
66 | |||
67 | curr->se.sum_exec_runtime += delta_exec; | ||
68 | account_group_exec_runtime(curr, delta_exec); | ||
69 | |||
70 | curr->se.exec_start = rq->clock_task; | ||
71 | cpuacct_charge(curr, delta_exec); | ||
55 | } | 72 | } |
56 | 73 | ||
57 | static void task_tick_stop(struct rq *rq, struct task_struct *curr, int queued) | 74 | static void task_tick_stop(struct rq *rq, struct task_struct *curr, int queued) |
@@ -60,6 +77,9 @@ static void task_tick_stop(struct rq *rq, struct task_struct *curr, int queued) | |||
60 | 77 | ||
61 | static void set_curr_task_stop(struct rq *rq) | 78 | static void set_curr_task_stop(struct rq *rq) |
62 | { | 79 | { |
80 | struct task_struct *stop = rq->stop; | ||
81 | |||
82 | stop->se.exec_start = rq->clock_task; | ||
63 | } | 83 | } |
64 | 84 | ||
65 | static void switched_to_stop(struct rq *rq, struct task_struct *p) | 85 | static void switched_to_stop(struct rq *rq, struct task_struct *p) |
diff --git a/kernel/task_work.c b/kernel/task_work.c index 91d4e1742a0c..d320d44903bd 100644 --- a/kernel/task_work.c +++ b/kernel/task_work.c | |||
@@ -75,6 +75,7 @@ void task_work_run(void) | |||
75 | p = q->next; | 75 | p = q->next; |
76 | q->func(q); | 76 | q->func(q); |
77 | q = p; | 77 | q = p; |
78 | cond_resched(); | ||
78 | } | 79 | } |
79 | } | 80 | } |
80 | } | 81 | } |
diff --git a/kernel/time/jiffies.c b/kernel/time/jiffies.c index a470154e0408..46da0537c10b 100644 --- a/kernel/time/jiffies.c +++ b/kernel/time/jiffies.c | |||
@@ -37,7 +37,7 @@ | |||
37 | * requested HZ value. It is also not recommended | 37 | * requested HZ value. It is also not recommended |
38 | * for "tick-less" systems. | 38 | * for "tick-less" systems. |
39 | */ | 39 | */ |
40 | #define NSEC_PER_JIFFY ((u32)((((u64)NSEC_PER_SEC)<<8)/ACTHZ)) | 40 | #define NSEC_PER_JIFFY ((u32)((((u64)NSEC_PER_SEC)<<8)/SHIFTED_HZ)) |
41 | 41 | ||
42 | /* Since jiffies uses a simple NSEC_PER_JIFFY multiplier | 42 | /* Since jiffies uses a simple NSEC_PER_JIFFY multiplier |
43 | * conversion, the .shift value could be zero. However | 43 | * conversion, the .shift value could be zero. However |
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c index b7fbadc5c973..24174b4d669b 100644 --- a/kernel/time/ntp.c +++ b/kernel/time/ntp.c | |||
@@ -28,7 +28,7 @@ DEFINE_SPINLOCK(ntp_lock); | |||
28 | /* USER_HZ period (usecs): */ | 28 | /* USER_HZ period (usecs): */ |
29 | unsigned long tick_usec = TICK_USEC; | 29 | unsigned long tick_usec = TICK_USEC; |
30 | 30 | ||
31 | /* ACTHZ period (nsecs): */ | 31 | /* SHIFTED_HZ period (nsecs): */ |
32 | unsigned long tick_nsec; | 32 | unsigned long tick_nsec; |
33 | 33 | ||
34 | static u64 tick_length; | 34 | static u64 tick_length; |
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c index f045cc50832d..e16af197a2bc 100644 --- a/kernel/time/timekeeping.c +++ b/kernel/time/timekeeping.c | |||
@@ -65,14 +65,14 @@ struct timekeeper { | |||
65 | * used instead. | 65 | * used instead. |
66 | */ | 66 | */ |
67 | struct timespec wall_to_monotonic; | 67 | struct timespec wall_to_monotonic; |
68 | /* time spent in suspend */ | ||
69 | struct timespec total_sleep_time; | ||
70 | /* The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. */ | ||
71 | struct timespec raw_time; | ||
72 | /* Offset clock monotonic -> clock realtime */ | 68 | /* Offset clock monotonic -> clock realtime */ |
73 | ktime_t offs_real; | 69 | ktime_t offs_real; |
70 | /* time spent in suspend */ | ||
71 | struct timespec total_sleep_time; | ||
74 | /* Offset clock monotonic -> clock boottime */ | 72 | /* Offset clock monotonic -> clock boottime */ |
75 | ktime_t offs_boot; | 73 | ktime_t offs_boot; |
74 | /* The raw monotonic time for the CLOCK_MONOTONIC_RAW posix clock. */ | ||
75 | struct timespec raw_time; | ||
76 | /* Seqlock for all timekeeper values */ | 76 | /* Seqlock for all timekeeper values */ |
77 | seqlock_t lock; | 77 | seqlock_t lock; |
78 | }; | 78 | }; |
@@ -108,13 +108,38 @@ static struct timespec tk_xtime(struct timekeeper *tk) | |||
108 | static void tk_set_xtime(struct timekeeper *tk, const struct timespec *ts) | 108 | static void tk_set_xtime(struct timekeeper *tk, const struct timespec *ts) |
109 | { | 109 | { |
110 | tk->xtime_sec = ts->tv_sec; | 110 | tk->xtime_sec = ts->tv_sec; |
111 | tk->xtime_nsec = ts->tv_nsec << tk->shift; | 111 | tk->xtime_nsec = (u64)ts->tv_nsec << tk->shift; |
112 | } | 112 | } |
113 | 113 | ||
114 | static void tk_xtime_add(struct timekeeper *tk, const struct timespec *ts) | 114 | static void tk_xtime_add(struct timekeeper *tk, const struct timespec *ts) |
115 | { | 115 | { |
116 | tk->xtime_sec += ts->tv_sec; | 116 | tk->xtime_sec += ts->tv_sec; |
117 | tk->xtime_nsec += ts->tv_nsec << tk->shift; | 117 | tk->xtime_nsec += (u64)ts->tv_nsec << tk->shift; |
118 | } | ||
119 | |||
120 | static void tk_set_wall_to_mono(struct timekeeper *tk, struct timespec wtm) | ||
121 | { | ||
122 | struct timespec tmp; | ||
123 | |||
124 | /* | ||
125 | * Verify consistency of: offset_real = -wall_to_monotonic | ||
126 | * before modifying anything | ||
127 | */ | ||
128 | set_normalized_timespec(&tmp, -tk->wall_to_monotonic.tv_sec, | ||
129 | -tk->wall_to_monotonic.tv_nsec); | ||
130 | WARN_ON_ONCE(tk->offs_real.tv64 != timespec_to_ktime(tmp).tv64); | ||
131 | tk->wall_to_monotonic = wtm; | ||
132 | set_normalized_timespec(&tmp, -wtm.tv_sec, -wtm.tv_nsec); | ||
133 | tk->offs_real = timespec_to_ktime(tmp); | ||
134 | } | ||
135 | |||
136 | static void tk_set_sleep_time(struct timekeeper *tk, struct timespec t) | ||
137 | { | ||
138 | /* Verify consistency before modifying */ | ||
139 | WARN_ON_ONCE(tk->offs_boot.tv64 != timespec_to_ktime(tk->total_sleep_time).tv64); | ||
140 | |||
141 | tk->total_sleep_time = t; | ||
142 | tk->offs_boot = timespec_to_ktime(t); | ||
118 | } | 143 | } |
119 | 144 | ||
120 | /** | 145 | /** |
@@ -217,14 +242,6 @@ static inline s64 timekeeping_get_ns_raw(struct timekeeper *tk) | |||
217 | return nsec + arch_gettimeoffset(); | 242 | return nsec + arch_gettimeoffset(); |
218 | } | 243 | } |
219 | 244 | ||
220 | static void update_rt_offset(struct timekeeper *tk) | ||
221 | { | ||
222 | struct timespec tmp, *wtm = &tk->wall_to_monotonic; | ||
223 | |||
224 | set_normalized_timespec(&tmp, -wtm->tv_sec, -wtm->tv_nsec); | ||
225 | tk->offs_real = timespec_to_ktime(tmp); | ||
226 | } | ||
227 | |||
228 | /* must hold write on timekeeper.lock */ | 245 | /* must hold write on timekeeper.lock */ |
229 | static void timekeeping_update(struct timekeeper *tk, bool clearntp) | 246 | static void timekeeping_update(struct timekeeper *tk, bool clearntp) |
230 | { | 247 | { |
@@ -234,12 +251,10 @@ static void timekeeping_update(struct timekeeper *tk, bool clearntp) | |||
234 | tk->ntp_error = 0; | 251 | tk->ntp_error = 0; |
235 | ntp_clear(); | 252 | ntp_clear(); |
236 | } | 253 | } |
237 | update_rt_offset(tk); | ||
238 | xt = tk_xtime(tk); | 254 | xt = tk_xtime(tk); |
239 | update_vsyscall(&xt, &tk->wall_to_monotonic, tk->clock, tk->mult); | 255 | update_vsyscall(&xt, &tk->wall_to_monotonic, tk->clock, tk->mult); |
240 | } | 256 | } |
241 | 257 | ||
242 | |||
243 | /** | 258 | /** |
244 | * timekeeping_forward_now - update clock to the current time | 259 | * timekeeping_forward_now - update clock to the current time |
245 | * | 260 | * |
@@ -277,18 +292,19 @@ static void timekeeping_forward_now(struct timekeeper *tk) | |||
277 | */ | 292 | */ |
278 | void getnstimeofday(struct timespec *ts) | 293 | void getnstimeofday(struct timespec *ts) |
279 | { | 294 | { |
295 | struct timekeeper *tk = &timekeeper; | ||
280 | unsigned long seq; | 296 | unsigned long seq; |
281 | s64 nsecs = 0; | 297 | s64 nsecs = 0; |
282 | 298 | ||
283 | WARN_ON(timekeeping_suspended); | 299 | WARN_ON(timekeeping_suspended); |
284 | 300 | ||
285 | do { | 301 | do { |
286 | seq = read_seqbegin(&timekeeper.lock); | 302 | seq = read_seqbegin(&tk->lock); |
287 | 303 | ||
288 | ts->tv_sec = timekeeper.xtime_sec; | 304 | ts->tv_sec = tk->xtime_sec; |
289 | ts->tv_nsec = timekeeping_get_ns(&timekeeper); | 305 | ts->tv_nsec = timekeeping_get_ns(tk); |
290 | 306 | ||
291 | } while (read_seqretry(&timekeeper.lock, seq)); | 307 | } while (read_seqretry(&tk->lock, seq)); |
292 | 308 | ||
293 | timespec_add_ns(ts, nsecs); | 309 | timespec_add_ns(ts, nsecs); |
294 | } | 310 | } |
@@ -296,19 +312,18 @@ EXPORT_SYMBOL(getnstimeofday); | |||
296 | 312 | ||
297 | ktime_t ktime_get(void) | 313 | ktime_t ktime_get(void) |
298 | { | 314 | { |
315 | struct timekeeper *tk = &timekeeper; | ||
299 | unsigned int seq; | 316 | unsigned int seq; |
300 | s64 secs, nsecs; | 317 | s64 secs, nsecs; |
301 | 318 | ||
302 | WARN_ON(timekeeping_suspended); | 319 | WARN_ON(timekeeping_suspended); |
303 | 320 | ||
304 | do { | 321 | do { |
305 | seq = read_seqbegin(&timekeeper.lock); | 322 | seq = read_seqbegin(&tk->lock); |
306 | secs = timekeeper.xtime_sec + | 323 | secs = tk->xtime_sec + tk->wall_to_monotonic.tv_sec; |
307 | timekeeper.wall_to_monotonic.tv_sec; | 324 | nsecs = timekeeping_get_ns(tk) + tk->wall_to_monotonic.tv_nsec; |
308 | nsecs = timekeeping_get_ns(&timekeeper) + | ||
309 | timekeeper.wall_to_monotonic.tv_nsec; | ||
310 | 325 | ||
311 | } while (read_seqretry(&timekeeper.lock, seq)); | 326 | } while (read_seqretry(&tk->lock, seq)); |
312 | /* | 327 | /* |
313 | * Use ktime_set/ktime_add_ns to create a proper ktime on | 328 | * Use ktime_set/ktime_add_ns to create a proper ktime on |
314 | * 32-bit architectures without CONFIG_KTIME_SCALAR. | 329 | * 32-bit architectures without CONFIG_KTIME_SCALAR. |
@@ -327,18 +342,19 @@ EXPORT_SYMBOL_GPL(ktime_get); | |||
327 | */ | 342 | */ |
328 | void ktime_get_ts(struct timespec *ts) | 343 | void ktime_get_ts(struct timespec *ts) |
329 | { | 344 | { |
345 | struct timekeeper *tk = &timekeeper; | ||
330 | struct timespec tomono; | 346 | struct timespec tomono; |
331 | unsigned int seq; | 347 | unsigned int seq; |
332 | 348 | ||
333 | WARN_ON(timekeeping_suspended); | 349 | WARN_ON(timekeeping_suspended); |
334 | 350 | ||
335 | do { | 351 | do { |
336 | seq = read_seqbegin(&timekeeper.lock); | 352 | seq = read_seqbegin(&tk->lock); |
337 | ts->tv_sec = timekeeper.xtime_sec; | 353 | ts->tv_sec = tk->xtime_sec; |
338 | ts->tv_nsec = timekeeping_get_ns(&timekeeper); | 354 | ts->tv_nsec = timekeeping_get_ns(tk); |
339 | tomono = timekeeper.wall_to_monotonic; | 355 | tomono = tk->wall_to_monotonic; |
340 | 356 | ||
341 | } while (read_seqretry(&timekeeper.lock, seq)); | 357 | } while (read_seqretry(&tk->lock, seq)); |
342 | 358 | ||
343 | set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec, | 359 | set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec, |
344 | ts->tv_nsec + tomono.tv_nsec); | 360 | ts->tv_nsec + tomono.tv_nsec); |
@@ -358,22 +374,23 @@ EXPORT_SYMBOL_GPL(ktime_get_ts); | |||
358 | */ | 374 | */ |
359 | void getnstime_raw_and_real(struct timespec *ts_raw, struct timespec *ts_real) | 375 | void getnstime_raw_and_real(struct timespec *ts_raw, struct timespec *ts_real) |
360 | { | 376 | { |
377 | struct timekeeper *tk = &timekeeper; | ||
361 | unsigned long seq; | 378 | unsigned long seq; |
362 | s64 nsecs_raw, nsecs_real; | 379 | s64 nsecs_raw, nsecs_real; |
363 | 380 | ||
364 | WARN_ON_ONCE(timekeeping_suspended); | 381 | WARN_ON_ONCE(timekeeping_suspended); |
365 | 382 | ||
366 | do { | 383 | do { |
367 | seq = read_seqbegin(&timekeeper.lock); | 384 | seq = read_seqbegin(&tk->lock); |
368 | 385 | ||
369 | *ts_raw = timekeeper.raw_time; | 386 | *ts_raw = tk->raw_time; |
370 | ts_real->tv_sec = timekeeper.xtime_sec; | 387 | ts_real->tv_sec = tk->xtime_sec; |
371 | ts_real->tv_nsec = 0; | 388 | ts_real->tv_nsec = 0; |
372 | 389 | ||
373 | nsecs_raw = timekeeping_get_ns_raw(&timekeeper); | 390 | nsecs_raw = timekeeping_get_ns_raw(tk); |
374 | nsecs_real = timekeeping_get_ns(&timekeeper); | 391 | nsecs_real = timekeeping_get_ns(tk); |
375 | 392 | ||
376 | } while (read_seqretry(&timekeeper.lock, seq)); | 393 | } while (read_seqretry(&tk->lock, seq)); |
377 | 394 | ||
378 | timespec_add_ns(ts_raw, nsecs_raw); | 395 | timespec_add_ns(ts_raw, nsecs_raw); |
379 | timespec_add_ns(ts_real, nsecs_real); | 396 | timespec_add_ns(ts_real, nsecs_real); |
@@ -406,28 +423,28 @@ EXPORT_SYMBOL(do_gettimeofday); | |||
406 | */ | 423 | */ |
407 | int do_settimeofday(const struct timespec *tv) | 424 | int do_settimeofday(const struct timespec *tv) |
408 | { | 425 | { |
426 | struct timekeeper *tk = &timekeeper; | ||
409 | struct timespec ts_delta, xt; | 427 | struct timespec ts_delta, xt; |
410 | unsigned long flags; | 428 | unsigned long flags; |
411 | 429 | ||
412 | if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) | 430 | if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC) |
413 | return -EINVAL; | 431 | return -EINVAL; |
414 | 432 | ||
415 | write_seqlock_irqsave(&timekeeper.lock, flags); | 433 | write_seqlock_irqsave(&tk->lock, flags); |
416 | 434 | ||
417 | timekeeping_forward_now(&timekeeper); | 435 | timekeeping_forward_now(tk); |
418 | 436 | ||
419 | xt = tk_xtime(&timekeeper); | 437 | xt = tk_xtime(tk); |
420 | ts_delta.tv_sec = tv->tv_sec - xt.tv_sec; | 438 | ts_delta.tv_sec = tv->tv_sec - xt.tv_sec; |
421 | ts_delta.tv_nsec = tv->tv_nsec - xt.tv_nsec; | 439 | ts_delta.tv_nsec = tv->tv_nsec - xt.tv_nsec; |
422 | 440 | ||
423 | timekeeper.wall_to_monotonic = | 441 | tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, ts_delta)); |
424 | timespec_sub(timekeeper.wall_to_monotonic, ts_delta); | ||
425 | 442 | ||
426 | tk_set_xtime(&timekeeper, tv); | 443 | tk_set_xtime(tk, tv); |
427 | 444 | ||
428 | timekeeping_update(&timekeeper, true); | 445 | timekeeping_update(tk, true); |
429 | 446 | ||
430 | write_sequnlock_irqrestore(&timekeeper.lock, flags); | 447 | write_sequnlock_irqrestore(&tk->lock, flags); |
431 | 448 | ||
432 | /* signal hrtimers about time change */ | 449 | /* signal hrtimers about time change */ |
433 | clock_was_set(); | 450 | clock_was_set(); |
@@ -436,7 +453,6 @@ int do_settimeofday(const struct timespec *tv) | |||
436 | } | 453 | } |
437 | EXPORT_SYMBOL(do_settimeofday); | 454 | EXPORT_SYMBOL(do_settimeofday); |
438 | 455 | ||
439 | |||
440 | /** | 456 | /** |
441 | * timekeeping_inject_offset - Adds or subtracts from the current time. | 457 | * timekeeping_inject_offset - Adds or subtracts from the current time. |
442 | * @tv: pointer to the timespec variable containing the offset | 458 | * @tv: pointer to the timespec variable containing the offset |
@@ -445,23 +461,23 @@ EXPORT_SYMBOL(do_settimeofday); | |||
445 | */ | 461 | */ |
446 | int timekeeping_inject_offset(struct timespec *ts) | 462 | int timekeeping_inject_offset(struct timespec *ts) |
447 | { | 463 | { |
464 | struct timekeeper *tk = &timekeeper; | ||
448 | unsigned long flags; | 465 | unsigned long flags; |
449 | 466 | ||
450 | if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) | 467 | if ((unsigned long)ts->tv_nsec >= NSEC_PER_SEC) |
451 | return -EINVAL; | 468 | return -EINVAL; |
452 | 469 | ||
453 | write_seqlock_irqsave(&timekeeper.lock, flags); | 470 | write_seqlock_irqsave(&tk->lock, flags); |
454 | 471 | ||
455 | timekeeping_forward_now(&timekeeper); | 472 | timekeeping_forward_now(tk); |
456 | 473 | ||
457 | 474 | ||
458 | tk_xtime_add(&timekeeper, ts); | 475 | tk_xtime_add(tk, ts); |
459 | timekeeper.wall_to_monotonic = | 476 | tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, *ts)); |
460 | timespec_sub(timekeeper.wall_to_monotonic, *ts); | ||
461 | 477 | ||
462 | timekeeping_update(&timekeeper, true); | 478 | timekeeping_update(tk, true); |
463 | 479 | ||
464 | write_sequnlock_irqrestore(&timekeeper.lock, flags); | 480 | write_sequnlock_irqrestore(&tk->lock, flags); |
465 | 481 | ||
466 | /* signal hrtimers about time change */ | 482 | /* signal hrtimers about time change */ |
467 | clock_was_set(); | 483 | clock_was_set(); |
@@ -477,23 +493,24 @@ EXPORT_SYMBOL(timekeeping_inject_offset); | |||
477 | */ | 493 | */ |
478 | static int change_clocksource(void *data) | 494 | static int change_clocksource(void *data) |
479 | { | 495 | { |
496 | struct timekeeper *tk = &timekeeper; | ||
480 | struct clocksource *new, *old; | 497 | struct clocksource *new, *old; |
481 | unsigned long flags; | 498 | unsigned long flags; |
482 | 499 | ||
483 | new = (struct clocksource *) data; | 500 | new = (struct clocksource *) data; |
484 | 501 | ||
485 | write_seqlock_irqsave(&timekeeper.lock, flags); | 502 | write_seqlock_irqsave(&tk->lock, flags); |
486 | 503 | ||
487 | timekeeping_forward_now(&timekeeper); | 504 | timekeeping_forward_now(tk); |
488 | if (!new->enable || new->enable(new) == 0) { | 505 | if (!new->enable || new->enable(new) == 0) { |
489 | old = timekeeper.clock; | 506 | old = tk->clock; |
490 | tk_setup_internals(&timekeeper, new); | 507 | tk_setup_internals(tk, new); |
491 | if (old->disable) | 508 | if (old->disable) |
492 | old->disable(old); | 509 | old->disable(old); |
493 | } | 510 | } |
494 | timekeeping_update(&timekeeper, true); | 511 | timekeeping_update(tk, true); |
495 | 512 | ||
496 | write_sequnlock_irqrestore(&timekeeper.lock, flags); | 513 | write_sequnlock_irqrestore(&tk->lock, flags); |
497 | 514 | ||
498 | return 0; | 515 | return 0; |
499 | } | 516 | } |
@@ -507,7 +524,9 @@ static int change_clocksource(void *data) | |||
507 | */ | 524 | */ |
508 | void timekeeping_notify(struct clocksource *clock) | 525 | void timekeeping_notify(struct clocksource *clock) |
509 | { | 526 | { |
510 | if (timekeeper.clock == clock) | 527 | struct timekeeper *tk = &timekeeper; |
528 | |||
529 | if (tk->clock == clock) | ||
511 | return; | 530 | return; |
512 | stop_machine(change_clocksource, clock, NULL); | 531 | stop_machine(change_clocksource, clock, NULL); |
513 | tick_clock_notify(); | 532 | tick_clock_notify(); |
@@ -536,35 +555,36 @@ EXPORT_SYMBOL_GPL(ktime_get_real); | |||
536 | */ | 555 | */ |
537 | void getrawmonotonic(struct timespec *ts) | 556 | void getrawmonotonic(struct timespec *ts) |
538 | { | 557 | { |
558 | struct timekeeper *tk = &timekeeper; | ||
539 | unsigned long seq; | 559 | unsigned long seq; |
540 | s64 nsecs; | 560 | s64 nsecs; |
541 | 561 | ||
542 | do { | 562 | do { |
543 | seq = read_seqbegin(&timekeeper.lock); | 563 | seq = read_seqbegin(&tk->lock); |
544 | nsecs = timekeeping_get_ns_raw(&timekeeper); | 564 | nsecs = timekeeping_get_ns_raw(tk); |
545 | *ts = timekeeper.raw_time; | 565 | *ts = tk->raw_time; |
546 | 566 | ||
547 | } while (read_seqretry(&timekeeper.lock, seq)); | 567 | } while (read_seqretry(&tk->lock, seq)); |
548 | 568 | ||
549 | timespec_add_ns(ts, nsecs); | 569 | timespec_add_ns(ts, nsecs); |
550 | } | 570 | } |
551 | EXPORT_SYMBOL(getrawmonotonic); | 571 | EXPORT_SYMBOL(getrawmonotonic); |
552 | 572 | ||
553 | |||
554 | /** | 573 | /** |
555 | * timekeeping_valid_for_hres - Check if timekeeping is suitable for hres | 574 | * timekeeping_valid_for_hres - Check if timekeeping is suitable for hres |
556 | */ | 575 | */ |
557 | int timekeeping_valid_for_hres(void) | 576 | int timekeeping_valid_for_hres(void) |
558 | { | 577 | { |
578 | struct timekeeper *tk = &timekeeper; | ||
559 | unsigned long seq; | 579 | unsigned long seq; |
560 | int ret; | 580 | int ret; |
561 | 581 | ||
562 | do { | 582 | do { |
563 | seq = read_seqbegin(&timekeeper.lock); | 583 | seq = read_seqbegin(&tk->lock); |
564 | 584 | ||
565 | ret = timekeeper.clock->flags & CLOCK_SOURCE_VALID_FOR_HRES; | 585 | ret = tk->clock->flags & CLOCK_SOURCE_VALID_FOR_HRES; |
566 | 586 | ||
567 | } while (read_seqretry(&timekeeper.lock, seq)); | 587 | } while (read_seqretry(&tk->lock, seq)); |
568 | 588 | ||
569 | return ret; | 589 | return ret; |
570 | } | 590 | } |
@@ -574,15 +594,16 @@ int timekeeping_valid_for_hres(void) | |||
574 | */ | 594 | */ |
575 | u64 timekeeping_max_deferment(void) | 595 | u64 timekeeping_max_deferment(void) |
576 | { | 596 | { |
597 | struct timekeeper *tk = &timekeeper; | ||
577 | unsigned long seq; | 598 | unsigned long seq; |
578 | u64 ret; | 599 | u64 ret; |
579 | 600 | ||
580 | do { | 601 | do { |
581 | seq = read_seqbegin(&timekeeper.lock); | 602 | seq = read_seqbegin(&tk->lock); |
582 | 603 | ||
583 | ret = timekeeper.clock->max_idle_ns; | 604 | ret = tk->clock->max_idle_ns; |
584 | 605 | ||
585 | } while (read_seqretry(&timekeeper.lock, seq)); | 606 | } while (read_seqretry(&tk->lock, seq)); |
586 | 607 | ||
587 | return ret; | 608 | return ret; |
588 | } | 609 | } |
@@ -622,46 +643,43 @@ void __attribute__((weak)) read_boot_clock(struct timespec *ts) | |||
622 | */ | 643 | */ |
623 | void __init timekeeping_init(void) | 644 | void __init timekeeping_init(void) |
624 | { | 645 | { |
646 | struct timekeeper *tk = &timekeeper; | ||
625 | struct clocksource *clock; | 647 | struct clocksource *clock; |
626 | unsigned long flags; | 648 | unsigned long flags; |
627 | struct timespec now, boot; | 649 | struct timespec now, boot, tmp; |
628 | 650 | ||
629 | read_persistent_clock(&now); | 651 | read_persistent_clock(&now); |
630 | read_boot_clock(&boot); | 652 | read_boot_clock(&boot); |
631 | 653 | ||
632 | seqlock_init(&timekeeper.lock); | 654 | seqlock_init(&tk->lock); |
633 | 655 | ||
634 | ntp_init(); | 656 | ntp_init(); |
635 | 657 | ||
636 | write_seqlock_irqsave(&timekeeper.lock, flags); | 658 | write_seqlock_irqsave(&tk->lock, flags); |
637 | clock = clocksource_default_clock(); | 659 | clock = clocksource_default_clock(); |
638 | if (clock->enable) | 660 | if (clock->enable) |
639 | clock->enable(clock); | 661 | clock->enable(clock); |
640 | tk_setup_internals(&timekeeper, clock); | 662 | tk_setup_internals(tk, clock); |
641 | 663 | ||
642 | tk_set_xtime(&timekeeper, &now); | 664 | tk_set_xtime(tk, &now); |
643 | timekeeper.raw_time.tv_sec = 0; | 665 | tk->raw_time.tv_sec = 0; |
644 | timekeeper.raw_time.tv_nsec = 0; | 666 | tk->raw_time.tv_nsec = 0; |
645 | if (boot.tv_sec == 0 && boot.tv_nsec == 0) | 667 | if (boot.tv_sec == 0 && boot.tv_nsec == 0) |
646 | boot = tk_xtime(&timekeeper); | 668 | boot = tk_xtime(tk); |
647 | 669 | ||
648 | set_normalized_timespec(&timekeeper.wall_to_monotonic, | 670 | set_normalized_timespec(&tmp, -boot.tv_sec, -boot.tv_nsec); |
649 | -boot.tv_sec, -boot.tv_nsec); | 671 | tk_set_wall_to_mono(tk, tmp); |
650 | update_rt_offset(&timekeeper); | 672 | |
651 | timekeeper.total_sleep_time.tv_sec = 0; | 673 | tmp.tv_sec = 0; |
652 | timekeeper.total_sleep_time.tv_nsec = 0; | 674 | tmp.tv_nsec = 0; |
653 | write_sequnlock_irqrestore(&timekeeper.lock, flags); | 675 | tk_set_sleep_time(tk, tmp); |
676 | |||
677 | write_sequnlock_irqrestore(&tk->lock, flags); | ||
654 | } | 678 | } |
655 | 679 | ||
656 | /* time in seconds when suspend began */ | 680 | /* time in seconds when suspend began */ |
657 | static struct timespec timekeeping_suspend_time; | 681 | static struct timespec timekeeping_suspend_time; |
658 | 682 | ||
659 | static void update_sleep_time(struct timespec t) | ||
660 | { | ||
661 | timekeeper.total_sleep_time = t; | ||
662 | timekeeper.offs_boot = timespec_to_ktime(t); | ||
663 | } | ||
664 | |||
665 | /** | 683 | /** |
666 | * __timekeeping_inject_sleeptime - Internal function to add sleep interval | 684 | * __timekeeping_inject_sleeptime - Internal function to add sleep interval |
667 | * @delta: pointer to a timespec delta value | 685 | * @delta: pointer to a timespec delta value |
@@ -677,13 +695,11 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk, | |||
677 | "sleep delta value!\n"); | 695 | "sleep delta value!\n"); |
678 | return; | 696 | return; |
679 | } | 697 | } |
680 | |||
681 | tk_xtime_add(tk, delta); | 698 | tk_xtime_add(tk, delta); |
682 | tk->wall_to_monotonic = timespec_sub(tk->wall_to_monotonic, *delta); | 699 | tk_set_wall_to_mono(tk, timespec_sub(tk->wall_to_monotonic, *delta)); |
683 | update_sleep_time(timespec_add(tk->total_sleep_time, *delta)); | 700 | tk_set_sleep_time(tk, timespec_add(tk->total_sleep_time, *delta)); |
684 | } | 701 | } |
685 | 702 | ||
686 | |||
687 | /** | 703 | /** |
688 | * timekeeping_inject_sleeptime - Adds suspend interval to timeekeeping values | 704 | * timekeeping_inject_sleeptime - Adds suspend interval to timeekeeping values |
689 | * @delta: pointer to a timespec delta value | 705 | * @delta: pointer to a timespec delta value |
@@ -696,6 +712,7 @@ static void __timekeeping_inject_sleeptime(struct timekeeper *tk, | |||
696 | */ | 712 | */ |
697 | void timekeeping_inject_sleeptime(struct timespec *delta) | 713 | void timekeeping_inject_sleeptime(struct timespec *delta) |
698 | { | 714 | { |
715 | struct timekeeper *tk = &timekeeper; | ||
699 | unsigned long flags; | 716 | unsigned long flags; |
700 | struct timespec ts; | 717 | struct timespec ts; |
701 | 718 | ||
@@ -704,21 +721,20 @@ void timekeeping_inject_sleeptime(struct timespec *delta) | |||
704 | if (!(ts.tv_sec == 0 && ts.tv_nsec == 0)) | 721 | if (!(ts.tv_sec == 0 && ts.tv_nsec == 0)) |
705 | return; | 722 | return; |
706 | 723 | ||
707 | write_seqlock_irqsave(&timekeeper.lock, flags); | 724 | write_seqlock_irqsave(&tk->lock, flags); |
708 | 725 | ||
709 | timekeeping_forward_now(&timekeeper); | 726 | timekeeping_forward_now(tk); |
710 | 727 | ||
711 | __timekeeping_inject_sleeptime(&timekeeper, delta); | 728 | __timekeeping_inject_sleeptime(tk, delta); |
712 | 729 | ||
713 | timekeeping_update(&timekeeper, true); | 730 | timekeeping_update(tk, true); |
714 | 731 | ||
715 | write_sequnlock_irqrestore(&timekeeper.lock, flags); | 732 | write_sequnlock_irqrestore(&tk->lock, flags); |
716 | 733 | ||
717 | /* signal hrtimers about time change */ | 734 | /* signal hrtimers about time change */ |
718 | clock_was_set(); | 735 | clock_was_set(); |
719 | } | 736 | } |
720 | 737 | ||
721 | |||
722 | /** | 738 | /** |
723 | * timekeeping_resume - Resumes the generic timekeeping subsystem. | 739 | * timekeeping_resume - Resumes the generic timekeeping subsystem. |
724 | * | 740 | * |
@@ -728,6 +744,7 @@ void timekeeping_inject_sleeptime(struct timespec *delta) | |||
728 | */ | 744 | */ |
729 | static void timekeeping_resume(void) | 745 | static void timekeeping_resume(void) |
730 | { | 746 | { |
747 | struct timekeeper *tk = &timekeeper; | ||
731 | unsigned long flags; | 748 | unsigned long flags; |
732 | struct timespec ts; | 749 | struct timespec ts; |
733 | 750 | ||
@@ -735,18 +752,18 @@ static void timekeeping_resume(void) | |||
735 | 752 | ||
736 | clocksource_resume(); | 753 | clocksource_resume(); |
737 | 754 | ||
738 | write_seqlock_irqsave(&timekeeper.lock, flags); | 755 | write_seqlock_irqsave(&tk->lock, flags); |
739 | 756 | ||
740 | if (timespec_compare(&ts, &timekeeping_suspend_time) > 0) { | 757 | if (timespec_compare(&ts, &timekeeping_suspend_time) > 0) { |
741 | ts = timespec_sub(ts, timekeeping_suspend_time); | 758 | ts = timespec_sub(ts, timekeeping_suspend_time); |
742 | __timekeeping_inject_sleeptime(&timekeeper, &ts); | 759 | __timekeeping_inject_sleeptime(tk, &ts); |
743 | } | 760 | } |
744 | /* re-base the last cycle value */ | 761 | /* re-base the last cycle value */ |
745 | timekeeper.clock->cycle_last = timekeeper.clock->read(timekeeper.clock); | 762 | tk->clock->cycle_last = tk->clock->read(tk->clock); |
746 | timekeeper.ntp_error = 0; | 763 | tk->ntp_error = 0; |
747 | timekeeping_suspended = 0; | 764 | timekeeping_suspended = 0; |
748 | timekeeping_update(&timekeeper, false); | 765 | timekeeping_update(tk, false); |
749 | write_sequnlock_irqrestore(&timekeeper.lock, flags); | 766 | write_sequnlock_irqrestore(&tk->lock, flags); |
750 | 767 | ||
751 | touch_softlockup_watchdog(); | 768 | touch_softlockup_watchdog(); |
752 | 769 | ||
@@ -758,14 +775,15 @@ static void timekeeping_resume(void) | |||
758 | 775 | ||
759 | static int timekeeping_suspend(void) | 776 | static int timekeeping_suspend(void) |
760 | { | 777 | { |
778 | struct timekeeper *tk = &timekeeper; | ||
761 | unsigned long flags; | 779 | unsigned long flags; |
762 | struct timespec delta, delta_delta; | 780 | struct timespec delta, delta_delta; |
763 | static struct timespec old_delta; | 781 | static struct timespec old_delta; |
764 | 782 | ||
765 | read_persistent_clock(&timekeeping_suspend_time); | 783 | read_persistent_clock(&timekeeping_suspend_time); |
766 | 784 | ||
767 | write_seqlock_irqsave(&timekeeper.lock, flags); | 785 | write_seqlock_irqsave(&tk->lock, flags); |
768 | timekeeping_forward_now(&timekeeper); | 786 | timekeeping_forward_now(tk); |
769 | timekeeping_suspended = 1; | 787 | timekeeping_suspended = 1; |
770 | 788 | ||
771 | /* | 789 | /* |
@@ -774,7 +792,7 @@ static int timekeeping_suspend(void) | |||
774 | * try to compensate so the difference in system time | 792 | * try to compensate so the difference in system time |
775 | * and persistent_clock time stays close to constant. | 793 | * and persistent_clock time stays close to constant. |
776 | */ | 794 | */ |
777 | delta = timespec_sub(tk_xtime(&timekeeper), timekeeping_suspend_time); | 795 | delta = timespec_sub(tk_xtime(tk), timekeeping_suspend_time); |
778 | delta_delta = timespec_sub(delta, old_delta); | 796 | delta_delta = timespec_sub(delta, old_delta); |
779 | if (abs(delta_delta.tv_sec) >= 2) { | 797 | if (abs(delta_delta.tv_sec) >= 2) { |
780 | /* | 798 | /* |
@@ -787,7 +805,7 @@ static int timekeeping_suspend(void) | |||
787 | timekeeping_suspend_time = | 805 | timekeeping_suspend_time = |
788 | timespec_add(timekeeping_suspend_time, delta_delta); | 806 | timespec_add(timekeeping_suspend_time, delta_delta); |
789 | } | 807 | } |
790 | write_sequnlock_irqrestore(&timekeeper.lock, flags); | 808 | write_sequnlock_irqrestore(&tk->lock, flags); |
791 | 809 | ||
792 | clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL); | 810 | clockevents_notify(CLOCK_EVT_NOTIFY_SUSPEND, NULL); |
793 | clocksource_suspend(); | 811 | clocksource_suspend(); |
@@ -898,27 +916,29 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset) | |||
898 | * the error. This causes the likely below to be unlikely. | 916 | * the error. This causes the likely below to be unlikely. |
899 | * | 917 | * |
900 | * The proper fix is to avoid rounding up by using | 918 | * The proper fix is to avoid rounding up by using |
901 | * the high precision timekeeper.xtime_nsec instead of | 919 | * the high precision tk->xtime_nsec instead of |
902 | * xtime.tv_nsec everywhere. Fixing this will take some | 920 | * xtime.tv_nsec everywhere. Fixing this will take some |
903 | * time. | 921 | * time. |
904 | */ | 922 | */ |
905 | if (likely(error <= interval)) | 923 | if (likely(error <= interval)) |
906 | adj = 1; | 924 | adj = 1; |
907 | else | 925 | else |
908 | adj = timekeeping_bigadjust(tk, error, &interval, | 926 | adj = timekeeping_bigadjust(tk, error, &interval, &offset); |
909 | &offset); | 927 | } else { |
910 | } else if (error < -interval) { | 928 | if (error < -interval) { |
911 | /* See comment above, this is just switched for the negative */ | 929 | /* See comment above, this is just switched for the negative */ |
912 | error >>= 2; | 930 | error >>= 2; |
913 | if (likely(error >= -interval)) { | 931 | if (likely(error >= -interval)) { |
914 | adj = -1; | 932 | adj = -1; |
915 | interval = -interval; | 933 | interval = -interval; |
916 | offset = -offset; | 934 | offset = -offset; |
917 | } else | 935 | } else { |
918 | adj = timekeeping_bigadjust(tk, error, &interval, | 936 | adj = timekeeping_bigadjust(tk, error, &interval, &offset); |
919 | &offset); | 937 | } |
920 | } else | 938 | } else { |
921 | return; | 939 | goto out_adjust; |
940 | } | ||
941 | } | ||
922 | 942 | ||
923 | if (unlikely(tk->clock->maxadj && | 943 | if (unlikely(tk->clock->maxadj && |
924 | (tk->mult + adj > tk->clock->mult + tk->clock->maxadj))) { | 944 | (tk->mult + adj > tk->clock->mult + tk->clock->maxadj))) { |
@@ -981,6 +1001,7 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset) | |||
981 | tk->xtime_nsec -= offset; | 1001 | tk->xtime_nsec -= offset; |
982 | tk->ntp_error -= (interval - offset) << tk->ntp_error_shift; | 1002 | tk->ntp_error -= (interval - offset) << tk->ntp_error_shift; |
983 | 1003 | ||
1004 | out_adjust: | ||
984 | /* | 1005 | /* |
985 | * It may be possible that when we entered this function, xtime_nsec | 1006 | * It may be possible that when we entered this function, xtime_nsec |
986 | * was very small. Further, if we're slightly speeding the clocksource | 1007 | * was very small. Further, if we're slightly speeding the clocksource |
@@ -1003,7 +1024,6 @@ static void timekeeping_adjust(struct timekeeper *tk, s64 offset) | |||
1003 | 1024 | ||
1004 | } | 1025 | } |
1005 | 1026 | ||
1006 | |||
1007 | /** | 1027 | /** |
1008 | * accumulate_nsecs_to_secs - Accumulates nsecs into secs | 1028 | * accumulate_nsecs_to_secs - Accumulates nsecs into secs |
1009 | * | 1029 | * |
@@ -1024,15 +1044,21 @@ static inline void accumulate_nsecs_to_secs(struct timekeeper *tk) | |||
1024 | 1044 | ||
1025 | /* Figure out if its a leap sec and apply if needed */ | 1045 | /* Figure out if its a leap sec and apply if needed */ |
1026 | leap = second_overflow(tk->xtime_sec); | 1046 | leap = second_overflow(tk->xtime_sec); |
1027 | tk->xtime_sec += leap; | 1047 | if (unlikely(leap)) { |
1028 | tk->wall_to_monotonic.tv_sec -= leap; | 1048 | struct timespec ts; |
1029 | if (leap) | 1049 | |
1030 | clock_was_set_delayed(); | 1050 | tk->xtime_sec += leap; |
1051 | |||
1052 | ts.tv_sec = leap; | ||
1053 | ts.tv_nsec = 0; | ||
1054 | tk_set_wall_to_mono(tk, | ||
1055 | timespec_sub(tk->wall_to_monotonic, ts)); | ||
1031 | 1056 | ||
1057 | clock_was_set_delayed(); | ||
1058 | } | ||
1032 | } | 1059 | } |
1033 | } | 1060 | } |
1034 | 1061 | ||
1035 | |||
1036 | /** | 1062 | /** |
1037 | * logarithmic_accumulation - shifted accumulation of cycles | 1063 | * logarithmic_accumulation - shifted accumulation of cycles |
1038 | * | 1064 | * |
@@ -1076,7 +1102,6 @@ static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset, | |||
1076 | return offset; | 1102 | return offset; |
1077 | } | 1103 | } |
1078 | 1104 | ||
1079 | |||
1080 | /** | 1105 | /** |
1081 | * update_wall_time - Uses the current clocksource to increment the wall time | 1106 | * update_wall_time - Uses the current clocksource to increment the wall time |
1082 | * | 1107 | * |
@@ -1084,21 +1109,22 @@ static cycle_t logarithmic_accumulation(struct timekeeper *tk, cycle_t offset, | |||
1084 | static void update_wall_time(void) | 1109 | static void update_wall_time(void) |
1085 | { | 1110 | { |
1086 | struct clocksource *clock; | 1111 | struct clocksource *clock; |
1112 | struct timekeeper *tk = &timekeeper; | ||
1087 | cycle_t offset; | 1113 | cycle_t offset; |
1088 | int shift = 0, maxshift; | 1114 | int shift = 0, maxshift; |
1089 | unsigned long flags; | 1115 | unsigned long flags; |
1090 | s64 remainder; | 1116 | s64 remainder; |
1091 | 1117 | ||
1092 | write_seqlock_irqsave(&timekeeper.lock, flags); | 1118 | write_seqlock_irqsave(&tk->lock, flags); |
1093 | 1119 | ||
1094 | /* Make sure we're fully resumed: */ | 1120 | /* Make sure we're fully resumed: */ |
1095 | if (unlikely(timekeeping_suspended)) | 1121 | if (unlikely(timekeeping_suspended)) |
1096 | goto out; | 1122 | goto out; |
1097 | 1123 | ||
1098 | clock = timekeeper.clock; | 1124 | clock = tk->clock; |
1099 | 1125 | ||
1100 | #ifdef CONFIG_ARCH_USES_GETTIMEOFFSET | 1126 | #ifdef CONFIG_ARCH_USES_GETTIMEOFFSET |
1101 | offset = timekeeper.cycle_interval; | 1127 | offset = tk->cycle_interval; |
1102 | #else | 1128 | #else |
1103 | offset = (clock->read(clock) - clock->cycle_last) & clock->mask; | 1129 | offset = (clock->read(clock) - clock->cycle_last) & clock->mask; |
1104 | #endif | 1130 | #endif |
@@ -1111,19 +1137,19 @@ static void update_wall_time(void) | |||
1111 | * chunk in one go, and then try to consume the next smaller | 1137 | * chunk in one go, and then try to consume the next smaller |
1112 | * doubled multiple. | 1138 | * doubled multiple. |
1113 | */ | 1139 | */ |
1114 | shift = ilog2(offset) - ilog2(timekeeper.cycle_interval); | 1140 | shift = ilog2(offset) - ilog2(tk->cycle_interval); |
1115 | shift = max(0, shift); | 1141 | shift = max(0, shift); |
1116 | /* Bound shift to one less than what overflows tick_length */ | 1142 | /* Bound shift to one less than what overflows tick_length */ |
1117 | maxshift = (64 - (ilog2(ntp_tick_length())+1)) - 1; | 1143 | maxshift = (64 - (ilog2(ntp_tick_length())+1)) - 1; |
1118 | shift = min(shift, maxshift); | 1144 | shift = min(shift, maxshift); |
1119 | while (offset >= timekeeper.cycle_interval) { | 1145 | while (offset >= tk->cycle_interval) { |
1120 | offset = logarithmic_accumulation(&timekeeper, offset, shift); | 1146 | offset = logarithmic_accumulation(tk, offset, shift); |
1121 | if(offset < timekeeper.cycle_interval<<shift) | 1147 | if (offset < tk->cycle_interval<<shift) |
1122 | shift--; | 1148 | shift--; |
1123 | } | 1149 | } |
1124 | 1150 | ||
1125 | /* correct the clock when NTP error is too big */ | 1151 | /* correct the clock when NTP error is too big */ |
1126 | timekeeping_adjust(&timekeeper, offset); | 1152 | timekeeping_adjust(tk, offset); |
1127 | 1153 | ||
1128 | 1154 | ||
1129 | /* | 1155 | /* |
@@ -1135,21 +1161,21 @@ static void update_wall_time(void) | |||
1135 | * the vsyscall implementations are converted to use xtime_nsec | 1161 | * the vsyscall implementations are converted to use xtime_nsec |
1136 | * (shifted nanoseconds), this can be killed. | 1162 | * (shifted nanoseconds), this can be killed. |
1137 | */ | 1163 | */ |
1138 | remainder = timekeeper.xtime_nsec & ((1 << timekeeper.shift) - 1); | 1164 | remainder = tk->xtime_nsec & ((1 << tk->shift) - 1); |
1139 | timekeeper.xtime_nsec -= remainder; | 1165 | tk->xtime_nsec -= remainder; |
1140 | timekeeper.xtime_nsec += 1 << timekeeper.shift; | 1166 | tk->xtime_nsec += 1 << tk->shift; |
1141 | timekeeper.ntp_error += remainder << timekeeper.ntp_error_shift; | 1167 | tk->ntp_error += remainder << tk->ntp_error_shift; |
1142 | 1168 | ||
1143 | /* | 1169 | /* |
1144 | * Finally, make sure that after the rounding | 1170 | * Finally, make sure that after the rounding |
1145 | * xtime_nsec isn't larger than NSEC_PER_SEC | 1171 | * xtime_nsec isn't larger than NSEC_PER_SEC |
1146 | */ | 1172 | */ |
1147 | accumulate_nsecs_to_secs(&timekeeper); | 1173 | accumulate_nsecs_to_secs(tk); |
1148 | 1174 | ||
1149 | timekeeping_update(&timekeeper, false); | 1175 | timekeeping_update(tk, false); |
1150 | 1176 | ||
1151 | out: | 1177 | out: |
1152 | write_sequnlock_irqrestore(&timekeeper.lock, flags); | 1178 | write_sequnlock_irqrestore(&tk->lock, flags); |
1153 | 1179 | ||
1154 | } | 1180 | } |
1155 | 1181 | ||
@@ -1166,18 +1192,18 @@ out: | |||
1166 | */ | 1192 | */ |
1167 | void getboottime(struct timespec *ts) | 1193 | void getboottime(struct timespec *ts) |
1168 | { | 1194 | { |
1195 | struct timekeeper *tk = &timekeeper; | ||
1169 | struct timespec boottime = { | 1196 | struct timespec boottime = { |
1170 | .tv_sec = timekeeper.wall_to_monotonic.tv_sec + | 1197 | .tv_sec = tk->wall_to_monotonic.tv_sec + |
1171 | timekeeper.total_sleep_time.tv_sec, | 1198 | tk->total_sleep_time.tv_sec, |
1172 | .tv_nsec = timekeeper.wall_to_monotonic.tv_nsec + | 1199 | .tv_nsec = tk->wall_to_monotonic.tv_nsec + |
1173 | timekeeper.total_sleep_time.tv_nsec | 1200 | tk->total_sleep_time.tv_nsec |
1174 | }; | 1201 | }; |
1175 | 1202 | ||
1176 | set_normalized_timespec(ts, -boottime.tv_sec, -boottime.tv_nsec); | 1203 | set_normalized_timespec(ts, -boottime.tv_sec, -boottime.tv_nsec); |
1177 | } | 1204 | } |
1178 | EXPORT_SYMBOL_GPL(getboottime); | 1205 | EXPORT_SYMBOL_GPL(getboottime); |
1179 | 1206 | ||
1180 | |||
1181 | /** | 1207 | /** |
1182 | * get_monotonic_boottime - Returns monotonic time since boot | 1208 | * get_monotonic_boottime - Returns monotonic time since boot |
1183 | * @ts: pointer to the timespec to be set | 1209 | * @ts: pointer to the timespec to be set |
@@ -1189,19 +1215,20 @@ EXPORT_SYMBOL_GPL(getboottime); | |||
1189 | */ | 1215 | */ |
1190 | void get_monotonic_boottime(struct timespec *ts) | 1216 | void get_monotonic_boottime(struct timespec *ts) |
1191 | { | 1217 | { |
1218 | struct timekeeper *tk = &timekeeper; | ||
1192 | struct timespec tomono, sleep; | 1219 | struct timespec tomono, sleep; |
1193 | unsigned int seq; | 1220 | unsigned int seq; |
1194 | 1221 | ||
1195 | WARN_ON(timekeeping_suspended); | 1222 | WARN_ON(timekeeping_suspended); |
1196 | 1223 | ||
1197 | do { | 1224 | do { |
1198 | seq = read_seqbegin(&timekeeper.lock); | 1225 | seq = read_seqbegin(&tk->lock); |
1199 | ts->tv_sec = timekeeper.xtime_sec; | 1226 | ts->tv_sec = tk->xtime_sec; |
1200 | ts->tv_nsec = timekeeping_get_ns(&timekeeper); | 1227 | ts->tv_nsec = timekeeping_get_ns(tk); |
1201 | tomono = timekeeper.wall_to_monotonic; | 1228 | tomono = tk->wall_to_monotonic; |
1202 | sleep = timekeeper.total_sleep_time; | 1229 | sleep = tk->total_sleep_time; |
1203 | 1230 | ||
1204 | } while (read_seqretry(&timekeeper.lock, seq)); | 1231 | } while (read_seqretry(&tk->lock, seq)); |
1205 | 1232 | ||
1206 | set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec + sleep.tv_sec, | 1233 | set_normalized_timespec(ts, ts->tv_sec + tomono.tv_sec + sleep.tv_sec, |
1207 | ts->tv_nsec + tomono.tv_nsec + sleep.tv_nsec); | 1234 | ts->tv_nsec + tomono.tv_nsec + sleep.tv_nsec); |
@@ -1231,31 +1258,38 @@ EXPORT_SYMBOL_GPL(ktime_get_boottime); | |||
1231 | */ | 1258 | */ |
1232 | void monotonic_to_bootbased(struct timespec *ts) | 1259 | void monotonic_to_bootbased(struct timespec *ts) |
1233 | { | 1260 | { |
1234 | *ts = timespec_add(*ts, timekeeper.total_sleep_time); | 1261 | struct timekeeper *tk = &timekeeper; |
1262 | |||
1263 | *ts = timespec_add(*ts, tk->total_sleep_time); | ||
1235 | } | 1264 | } |
1236 | EXPORT_SYMBOL_GPL(monotonic_to_bootbased); | 1265 | EXPORT_SYMBOL_GPL(monotonic_to_bootbased); |
1237 | 1266 | ||
1238 | unsigned long get_seconds(void) | 1267 | unsigned long get_seconds(void) |
1239 | { | 1268 | { |
1240 | return timekeeper.xtime_sec; | 1269 | struct timekeeper *tk = &timekeeper; |
1270 | |||
1271 | return tk->xtime_sec; | ||
1241 | } | 1272 | } |
1242 | EXPORT_SYMBOL(get_seconds); | 1273 | EXPORT_SYMBOL(get_seconds); |
1243 | 1274 | ||
1244 | struct timespec __current_kernel_time(void) | 1275 | struct timespec __current_kernel_time(void) |
1245 | { | 1276 | { |
1246 | return tk_xtime(&timekeeper); | 1277 | struct timekeeper *tk = &timekeeper; |
1278 | |||
1279 | return tk_xtime(tk); | ||
1247 | } | 1280 | } |
1248 | 1281 | ||
1249 | struct timespec current_kernel_time(void) | 1282 | struct timespec current_kernel_time(void) |
1250 | { | 1283 | { |
1284 | struct timekeeper *tk = &timekeeper; | ||
1251 | struct timespec now; | 1285 | struct timespec now; |
1252 | unsigned long seq; | 1286 | unsigned long seq; |
1253 | 1287 | ||
1254 | do { | 1288 | do { |
1255 | seq = read_seqbegin(&timekeeper.lock); | 1289 | seq = read_seqbegin(&tk->lock); |
1256 | 1290 | ||
1257 | now = tk_xtime(&timekeeper); | 1291 | now = tk_xtime(tk); |
1258 | } while (read_seqretry(&timekeeper.lock, seq)); | 1292 | } while (read_seqretry(&tk->lock, seq)); |
1259 | 1293 | ||
1260 | return now; | 1294 | return now; |
1261 | } | 1295 | } |
@@ -1263,15 +1297,16 @@ EXPORT_SYMBOL(current_kernel_time); | |||
1263 | 1297 | ||
1264 | struct timespec get_monotonic_coarse(void) | 1298 | struct timespec get_monotonic_coarse(void) |
1265 | { | 1299 | { |
1300 | struct timekeeper *tk = &timekeeper; | ||
1266 | struct timespec now, mono; | 1301 | struct timespec now, mono; |
1267 | unsigned long seq; | 1302 | unsigned long seq; |
1268 | 1303 | ||
1269 | do { | 1304 | do { |
1270 | seq = read_seqbegin(&timekeeper.lock); | 1305 | seq = read_seqbegin(&tk->lock); |
1271 | 1306 | ||
1272 | now = tk_xtime(&timekeeper); | 1307 | now = tk_xtime(tk); |
1273 | mono = timekeeper.wall_to_monotonic; | 1308 | mono = tk->wall_to_monotonic; |
1274 | } while (read_seqretry(&timekeeper.lock, seq)); | 1309 | } while (read_seqretry(&tk->lock, seq)); |
1275 | 1310 | ||
1276 | set_normalized_timespec(&now, now.tv_sec + mono.tv_sec, | 1311 | set_normalized_timespec(&now, now.tv_sec + mono.tv_sec, |
1277 | now.tv_nsec + mono.tv_nsec); | 1312 | now.tv_nsec + mono.tv_nsec); |
@@ -1300,14 +1335,15 @@ void do_timer(unsigned long ticks) | |||
1300 | void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, | 1335 | void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, |
1301 | struct timespec *wtom, struct timespec *sleep) | 1336 | struct timespec *wtom, struct timespec *sleep) |
1302 | { | 1337 | { |
1338 | struct timekeeper *tk = &timekeeper; | ||
1303 | unsigned long seq; | 1339 | unsigned long seq; |
1304 | 1340 | ||
1305 | do { | 1341 | do { |
1306 | seq = read_seqbegin(&timekeeper.lock); | 1342 | seq = read_seqbegin(&tk->lock); |
1307 | *xtim = tk_xtime(&timekeeper); | 1343 | *xtim = tk_xtime(tk); |
1308 | *wtom = timekeeper.wall_to_monotonic; | 1344 | *wtom = tk->wall_to_monotonic; |
1309 | *sleep = timekeeper.total_sleep_time; | 1345 | *sleep = tk->total_sleep_time; |
1310 | } while (read_seqretry(&timekeeper.lock, seq)); | 1346 | } while (read_seqretry(&tk->lock, seq)); |
1311 | } | 1347 | } |
1312 | 1348 | ||
1313 | #ifdef CONFIG_HIGH_RES_TIMERS | 1349 | #ifdef CONFIG_HIGH_RES_TIMERS |
@@ -1321,19 +1357,20 @@ void get_xtime_and_monotonic_and_sleep_offset(struct timespec *xtim, | |||
1321 | */ | 1357 | */ |
1322 | ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot) | 1358 | ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot) |
1323 | { | 1359 | { |
1360 | struct timekeeper *tk = &timekeeper; | ||
1324 | ktime_t now; | 1361 | ktime_t now; |
1325 | unsigned int seq; | 1362 | unsigned int seq; |
1326 | u64 secs, nsecs; | 1363 | u64 secs, nsecs; |
1327 | 1364 | ||
1328 | do { | 1365 | do { |
1329 | seq = read_seqbegin(&timekeeper.lock); | 1366 | seq = read_seqbegin(&tk->lock); |
1330 | 1367 | ||
1331 | secs = timekeeper.xtime_sec; | 1368 | secs = tk->xtime_sec; |
1332 | nsecs = timekeeping_get_ns(&timekeeper); | 1369 | nsecs = timekeeping_get_ns(tk); |
1333 | 1370 | ||
1334 | *offs_real = timekeeper.offs_real; | 1371 | *offs_real = tk->offs_real; |
1335 | *offs_boot = timekeeper.offs_boot; | 1372 | *offs_boot = tk->offs_boot; |
1336 | } while (read_seqretry(&timekeeper.lock, seq)); | 1373 | } while (read_seqretry(&tk->lock, seq)); |
1337 | 1374 | ||
1338 | now = ktime_add_ns(ktime_set(secs, 0), nsecs); | 1375 | now = ktime_add_ns(ktime_set(secs, 0), nsecs); |
1339 | now = ktime_sub(now, *offs_real); | 1376 | now = ktime_sub(now, *offs_real); |
@@ -1346,19 +1383,19 @@ ktime_t ktime_get_update_offsets(ktime_t *offs_real, ktime_t *offs_boot) | |||
1346 | */ | 1383 | */ |
1347 | ktime_t ktime_get_monotonic_offset(void) | 1384 | ktime_t ktime_get_monotonic_offset(void) |
1348 | { | 1385 | { |
1386 | struct timekeeper *tk = &timekeeper; | ||
1349 | unsigned long seq; | 1387 | unsigned long seq; |
1350 | struct timespec wtom; | 1388 | struct timespec wtom; |
1351 | 1389 | ||
1352 | do { | 1390 | do { |
1353 | seq = read_seqbegin(&timekeeper.lock); | 1391 | seq = read_seqbegin(&tk->lock); |
1354 | wtom = timekeeper.wall_to_monotonic; | 1392 | wtom = tk->wall_to_monotonic; |
1355 | } while (read_seqretry(&timekeeper.lock, seq)); | 1393 | } while (read_seqretry(&tk->lock, seq)); |
1356 | 1394 | ||
1357 | return timespec_to_ktime(wtom); | 1395 | return timespec_to_ktime(wtom); |
1358 | } | 1396 | } |
1359 | EXPORT_SYMBOL_GPL(ktime_get_monotonic_offset); | 1397 | EXPORT_SYMBOL_GPL(ktime_get_monotonic_offset); |
1360 | 1398 | ||
1361 | |||
1362 | /** | 1399 | /** |
1363 | * xtime_update() - advances the timekeeping infrastructure | 1400 | * xtime_update() - advances the timekeeping infrastructure |
1364 | * @ticks: number of ticks, that have elapsed since the last call. | 1401 | * @ticks: number of ticks, that have elapsed since the last call. |
diff --git a/kernel/timer.c b/kernel/timer.c index a61c09374eba..8c5e7b908c68 100644 --- a/kernel/timer.c +++ b/kernel/timer.c | |||
@@ -1407,13 +1407,6 @@ SYSCALL_DEFINE1(alarm, unsigned int, seconds) | |||
1407 | 1407 | ||
1408 | #endif | 1408 | #endif |
1409 | 1409 | ||
1410 | #ifndef __alpha__ | ||
1411 | |||
1412 | /* | ||
1413 | * The Alpha uses getxpid, getxuid, and getxgid instead. Maybe this | ||
1414 | * should be moved into arch/i386 instead? | ||
1415 | */ | ||
1416 | |||
1417 | /** | 1410 | /** |
1418 | * sys_getpid - return the thread group id of the current process | 1411 | * sys_getpid - return the thread group id of the current process |
1419 | * | 1412 | * |
@@ -1469,8 +1462,6 @@ SYSCALL_DEFINE0(getegid) | |||
1469 | return from_kgid_munged(current_user_ns(), current_egid()); | 1462 | return from_kgid_munged(current_user_ns(), current_egid()); |
1470 | } | 1463 | } |
1471 | 1464 | ||
1472 | #endif | ||
1473 | |||
1474 | static void process_timeout(unsigned long __data) | 1465 | static void process_timeout(unsigned long __data) |
1475 | { | 1466 | { |
1476 | wake_up_process((struct task_struct *)__data); | 1467 | wake_up_process((struct task_struct *)__data); |
diff --git a/kernel/trace/trace_event_perf.c b/kernel/trace/trace_event_perf.c index fee3752ae8f6..8a6d2ee2086c 100644 --- a/kernel/trace/trace_event_perf.c +++ b/kernel/trace/trace_event_perf.c | |||
@@ -281,7 +281,7 @@ perf_ftrace_function_call(unsigned long ip, unsigned long parent_ip) | |||
281 | 281 | ||
282 | head = this_cpu_ptr(event_function.perf_events); | 282 | head = this_cpu_ptr(event_function.perf_events); |
283 | perf_trace_buf_submit(entry, ENTRY_SIZE, rctx, 0, | 283 | perf_trace_buf_submit(entry, ENTRY_SIZE, rctx, 0, |
284 | 1, ®s, head); | 284 | 1, ®s, head, NULL); |
285 | 285 | ||
286 | #undef ENTRY_SIZE | 286 | #undef ENTRY_SIZE |
287 | } | 287 | } |
diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c index b31d3d5699fe..1a2117043bb1 100644 --- a/kernel/trace/trace_kprobe.c +++ b/kernel/trace/trace_kprobe.c | |||
@@ -1002,7 +1002,8 @@ static __kprobes void kprobe_perf_func(struct kprobe *kp, | |||
1002 | store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); | 1002 | store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); |
1003 | 1003 | ||
1004 | head = this_cpu_ptr(call->perf_events); | 1004 | head = this_cpu_ptr(call->perf_events); |
1005 | perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head); | 1005 | perf_trace_buf_submit(entry, size, rctx, |
1006 | entry->ip, 1, regs, head, NULL); | ||
1006 | } | 1007 | } |
1007 | 1008 | ||
1008 | /* Kretprobe profile handler */ | 1009 | /* Kretprobe profile handler */ |
@@ -1033,7 +1034,8 @@ static __kprobes void kretprobe_perf_func(struct kretprobe_instance *ri, | |||
1033 | store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); | 1034 | store_trace_args(sizeof(*entry), tp, regs, (u8 *)&entry[1], dsize); |
1034 | 1035 | ||
1035 | head = this_cpu_ptr(call->perf_events); | 1036 | head = this_cpu_ptr(call->perf_events); |
1036 | perf_trace_buf_submit(entry, size, rctx, entry->ret_ip, 1, regs, head); | 1037 | perf_trace_buf_submit(entry, size, rctx, |
1038 | entry->ret_ip, 1, regs, head, NULL); | ||
1037 | } | 1039 | } |
1038 | #endif /* CONFIG_PERF_EVENTS */ | 1040 | #endif /* CONFIG_PERF_EVENTS */ |
1039 | 1041 | ||
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c index 96fc73369099..60e4d7875672 100644 --- a/kernel/trace/trace_syscalls.c +++ b/kernel/trace/trace_syscalls.c | |||
@@ -532,7 +532,7 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id) | |||
532 | (unsigned long *)&rec->args); | 532 | (unsigned long *)&rec->args); |
533 | 533 | ||
534 | head = this_cpu_ptr(sys_data->enter_event->perf_events); | 534 | head = this_cpu_ptr(sys_data->enter_event->perf_events); |
535 | perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head); | 535 | perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head, NULL); |
536 | } | 536 | } |
537 | 537 | ||
538 | int perf_sysenter_enable(struct ftrace_event_call *call) | 538 | int perf_sysenter_enable(struct ftrace_event_call *call) |
@@ -608,7 +608,7 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret) | |||
608 | rec->ret = syscall_get_return_value(current, regs); | 608 | rec->ret = syscall_get_return_value(current, regs); |
609 | 609 | ||
610 | head = this_cpu_ptr(sys_data->exit_event->perf_events); | 610 | head = this_cpu_ptr(sys_data->exit_event->perf_events); |
611 | perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head); | 611 | perf_trace_buf_submit(rec, size, rctx, 0, 1, regs, head, NULL); |
612 | } | 612 | } |
613 | 613 | ||
614 | int perf_sysexit_enable(struct ftrace_event_call *call) | 614 | int perf_sysexit_enable(struct ftrace_event_call *call) |
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c index 2b36ac68549e..03003cd7dd96 100644 --- a/kernel/trace/trace_uprobe.c +++ b/kernel/trace/trace_uprobe.c | |||
@@ -670,7 +670,7 @@ static void uprobe_perf_func(struct trace_uprobe *tu, struct pt_regs *regs) | |||
670 | call_fetch(&tu->args[i].fetch, regs, data + tu->args[i].offset); | 670 | call_fetch(&tu->args[i].fetch, regs, data + tu->args[i].offset); |
671 | 671 | ||
672 | head = this_cpu_ptr(call->perf_events); | 672 | head = this_cpu_ptr(call->perf_events); |
673 | perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head); | 673 | perf_trace_buf_submit(entry, size, rctx, entry->ip, 1, regs, head, NULL); |
674 | 674 | ||
675 | out: | 675 | out: |
676 | preempt_enable(); | 676 | preempt_enable(); |
diff --git a/kernel/watchdog.c b/kernel/watchdog.c index 69add8a9da68..4b1dfba70f7c 100644 --- a/kernel/watchdog.c +++ b/kernel/watchdog.c | |||
@@ -575,7 +575,7 @@ out: | |||
575 | /* | 575 | /* |
576 | * Create/destroy watchdog threads as CPUs come and go: | 576 | * Create/destroy watchdog threads as CPUs come and go: |
577 | */ | 577 | */ |
578 | static int | 578 | static int __cpuinit |
579 | cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | 579 | cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) |
580 | { | 580 | { |
581 | int hotcpu = (unsigned long)hcpu; | 581 | int hotcpu = (unsigned long)hcpu; |
@@ -610,27 +610,10 @@ cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) | |||
610 | return NOTIFY_OK; | 610 | return NOTIFY_OK; |
611 | } | 611 | } |
612 | 612 | ||
613 | static struct notifier_block cpu_nfb = { | 613 | static struct notifier_block __cpuinitdata cpu_nfb = { |
614 | .notifier_call = cpu_callback | 614 | .notifier_call = cpu_callback |
615 | }; | 615 | }; |
616 | 616 | ||
617 | #ifdef CONFIG_SUSPEND | ||
618 | /* | ||
619 | * On exit from suspend we force an offline->online transition on the boot CPU | ||
620 | * so that the PMU state that was lost while in suspended state gets set up | ||
621 | * properly for the boot CPU. This information is required for restarting the | ||
622 | * NMI watchdog. | ||
623 | */ | ||
624 | void lockup_detector_bootcpu_resume(void) | ||
625 | { | ||
626 | void *cpu = (void *)(long)smp_processor_id(); | ||
627 | |||
628 | cpu_callback(&cpu_nfb, CPU_DEAD_FROZEN, cpu); | ||
629 | cpu_callback(&cpu_nfb, CPU_UP_PREPARE_FROZEN, cpu); | ||
630 | cpu_callback(&cpu_nfb, CPU_ONLINE_FROZEN, cpu); | ||
631 | } | ||
632 | #endif | ||
633 | |||
634 | void __init lockup_detector_init(void) | 617 | void __init lockup_detector_init(void) |
635 | { | 618 | { |
636 | void *cpu = (void *)(long)smp_processor_id(); | 619 | void *cpu = (void *)(long)smp_processor_id(); |
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index 6b4718e2ee34..b41823cc05e6 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -39,12 +39,6 @@ DEFINE_SPINLOCK(bdi_lock); | |||
39 | LIST_HEAD(bdi_list); | 39 | LIST_HEAD(bdi_list); |
40 | LIST_HEAD(bdi_pending_list); | 40 | LIST_HEAD(bdi_pending_list); |
41 | 41 | ||
42 | static struct task_struct *sync_supers_tsk; | ||
43 | static struct timer_list sync_supers_timer; | ||
44 | |||
45 | static int bdi_sync_supers(void *); | ||
46 | static void sync_supers_timer_fn(unsigned long); | ||
47 | |||
48 | void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2) | 42 | void bdi_lock_two(struct bdi_writeback *wb1, struct bdi_writeback *wb2) |
49 | { | 43 | { |
50 | if (wb1 < wb2) { | 44 | if (wb1 < wb2) { |
@@ -250,12 +244,6 @@ static int __init default_bdi_init(void) | |||
250 | { | 244 | { |
251 | int err; | 245 | int err; |
252 | 246 | ||
253 | sync_supers_tsk = kthread_run(bdi_sync_supers, NULL, "sync_supers"); | ||
254 | BUG_ON(IS_ERR(sync_supers_tsk)); | ||
255 | |||
256 | setup_timer(&sync_supers_timer, sync_supers_timer_fn, 0); | ||
257 | bdi_arm_supers_timer(); | ||
258 | |||
259 | err = bdi_init(&default_backing_dev_info); | 247 | err = bdi_init(&default_backing_dev_info); |
260 | if (!err) | 248 | if (!err) |
261 | bdi_register(&default_backing_dev_info, NULL, "default"); | 249 | bdi_register(&default_backing_dev_info, NULL, "default"); |
@@ -270,46 +258,6 @@ int bdi_has_dirty_io(struct backing_dev_info *bdi) | |||
270 | return wb_has_dirty_io(&bdi->wb); | 258 | return wb_has_dirty_io(&bdi->wb); |
271 | } | 259 | } |
272 | 260 | ||
273 | /* | ||
274 | * kupdated() used to do this. We cannot do it from the bdi_forker_thread() | ||
275 | * or we risk deadlocking on ->s_umount. The longer term solution would be | ||
276 | * to implement sync_supers_bdi() or similar and simply do it from the | ||
277 | * bdi writeback thread individually. | ||
278 | */ | ||
279 | static int bdi_sync_supers(void *unused) | ||
280 | { | ||
281 | set_user_nice(current, 0); | ||
282 | |||
283 | while (!kthread_should_stop()) { | ||
284 | set_current_state(TASK_INTERRUPTIBLE); | ||
285 | schedule(); | ||
286 | |||
287 | /* | ||
288 | * Do this periodically, like kupdated() did before. | ||
289 | */ | ||
290 | sync_supers(); | ||
291 | } | ||
292 | |||
293 | return 0; | ||
294 | } | ||
295 | |||
296 | void bdi_arm_supers_timer(void) | ||
297 | { | ||
298 | unsigned long next; | ||
299 | |||
300 | if (!dirty_writeback_interval) | ||
301 | return; | ||
302 | |||
303 | next = msecs_to_jiffies(dirty_writeback_interval * 10) + jiffies; | ||
304 | mod_timer(&sync_supers_timer, round_jiffies_up(next)); | ||
305 | } | ||
306 | |||
307 | static void sync_supers_timer_fn(unsigned long unused) | ||
308 | { | ||
309 | wake_up_process(sync_supers_tsk); | ||
310 | bdi_arm_supers_timer(); | ||
311 | } | ||
312 | |||
313 | static void wakeup_timer_fn(unsigned long data) | 261 | static void wakeup_timer_fn(unsigned long data) |
314 | { | 262 | { |
315 | struct backing_dev_info *bdi = (struct backing_dev_info *)data; | 263 | struct backing_dev_info *bdi = (struct backing_dev_info *)data; |
diff --git a/mm/compaction.c b/mm/compaction.c index e78cb9688421..7fcd3a52e68d 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
@@ -51,6 +51,47 @@ static inline bool migrate_async_suitable(int migratetype) | |||
51 | } | 51 | } |
52 | 52 | ||
53 | /* | 53 | /* |
54 | * Compaction requires the taking of some coarse locks that are potentially | ||
55 | * very heavily contended. Check if the process needs to be scheduled or | ||
56 | * if the lock is contended. For async compaction, back out in the event | ||
57 | * if contention is severe. For sync compaction, schedule. | ||
58 | * | ||
59 | * Returns true if the lock is held. | ||
60 | * Returns false if the lock is released and compaction should abort | ||
61 | */ | ||
62 | static bool compact_checklock_irqsave(spinlock_t *lock, unsigned long *flags, | ||
63 | bool locked, struct compact_control *cc) | ||
64 | { | ||
65 | if (need_resched() || spin_is_contended(lock)) { | ||
66 | if (locked) { | ||
67 | spin_unlock_irqrestore(lock, *flags); | ||
68 | locked = false; | ||
69 | } | ||
70 | |||
71 | /* async aborts if taking too long or contended */ | ||
72 | if (!cc->sync) { | ||
73 | if (cc->contended) | ||
74 | *cc->contended = true; | ||
75 | return false; | ||
76 | } | ||
77 | |||
78 | cond_resched(); | ||
79 | if (fatal_signal_pending(current)) | ||
80 | return false; | ||
81 | } | ||
82 | |||
83 | if (!locked) | ||
84 | spin_lock_irqsave(lock, *flags); | ||
85 | return true; | ||
86 | } | ||
87 | |||
88 | static inline bool compact_trylock_irqsave(spinlock_t *lock, | ||
89 | unsigned long *flags, struct compact_control *cc) | ||
90 | { | ||
91 | return compact_checklock_irqsave(lock, flags, false, cc); | ||
92 | } | ||
93 | |||
94 | /* | ||
54 | * Isolate free pages onto a private freelist. Caller must hold zone->lock. | 95 | * Isolate free pages onto a private freelist. Caller must hold zone->lock. |
55 | * If @strict is true, will abort returning 0 on any invalid PFNs or non-free | 96 | * If @strict is true, will abort returning 0 on any invalid PFNs or non-free |
56 | * pages inside of the pageblock (even though it may still end up isolating | 97 | * pages inside of the pageblock (even though it may still end up isolating |
@@ -173,7 +214,7 @@ isolate_freepages_range(unsigned long start_pfn, unsigned long end_pfn) | |||
173 | } | 214 | } |
174 | 215 | ||
175 | /* Update the number of anon and file isolated pages in the zone */ | 216 | /* Update the number of anon and file isolated pages in the zone */ |
176 | static void acct_isolated(struct zone *zone, struct compact_control *cc) | 217 | static void acct_isolated(struct zone *zone, bool locked, struct compact_control *cc) |
177 | { | 218 | { |
178 | struct page *page; | 219 | struct page *page; |
179 | unsigned int count[2] = { 0, }; | 220 | unsigned int count[2] = { 0, }; |
@@ -181,8 +222,14 @@ static void acct_isolated(struct zone *zone, struct compact_control *cc) | |||
181 | list_for_each_entry(page, &cc->migratepages, lru) | 222 | list_for_each_entry(page, &cc->migratepages, lru) |
182 | count[!!page_is_file_cache(page)]++; | 223 | count[!!page_is_file_cache(page)]++; |
183 | 224 | ||
184 | __mod_zone_page_state(zone, NR_ISOLATED_ANON, count[0]); | 225 | /* If locked we can use the interrupt unsafe versions */ |
185 | __mod_zone_page_state(zone, NR_ISOLATED_FILE, count[1]); | 226 | if (locked) { |
227 | __mod_zone_page_state(zone, NR_ISOLATED_ANON, count[0]); | ||
228 | __mod_zone_page_state(zone, NR_ISOLATED_FILE, count[1]); | ||
229 | } else { | ||
230 | mod_zone_page_state(zone, NR_ISOLATED_ANON, count[0]); | ||
231 | mod_zone_page_state(zone, NR_ISOLATED_FILE, count[1]); | ||
232 | } | ||
186 | } | 233 | } |
187 | 234 | ||
188 | /* Similar to reclaim, but different enough that they don't share logic */ | 235 | /* Similar to reclaim, but different enough that they don't share logic */ |
@@ -228,6 +275,8 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc, | |||
228 | struct list_head *migratelist = &cc->migratepages; | 275 | struct list_head *migratelist = &cc->migratepages; |
229 | isolate_mode_t mode = 0; | 276 | isolate_mode_t mode = 0; |
230 | struct lruvec *lruvec; | 277 | struct lruvec *lruvec; |
278 | unsigned long flags; | ||
279 | bool locked; | ||
231 | 280 | ||
232 | /* | 281 | /* |
233 | * Ensure that there are not too many pages isolated from the LRU | 282 | * Ensure that there are not too many pages isolated from the LRU |
@@ -247,25 +296,22 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc, | |||
247 | 296 | ||
248 | /* Time to isolate some pages for migration */ | 297 | /* Time to isolate some pages for migration */ |
249 | cond_resched(); | 298 | cond_resched(); |
250 | spin_lock_irq(&zone->lru_lock); | 299 | spin_lock_irqsave(&zone->lru_lock, flags); |
300 | locked = true; | ||
251 | for (; low_pfn < end_pfn; low_pfn++) { | 301 | for (; low_pfn < end_pfn; low_pfn++) { |
252 | struct page *page; | 302 | struct page *page; |
253 | bool locked = true; | ||
254 | 303 | ||
255 | /* give a chance to irqs before checking need_resched() */ | 304 | /* give a chance to irqs before checking need_resched() */ |
256 | if (!((low_pfn+1) % SWAP_CLUSTER_MAX)) { | 305 | if (!((low_pfn+1) % SWAP_CLUSTER_MAX)) { |
257 | spin_unlock_irq(&zone->lru_lock); | 306 | spin_unlock_irqrestore(&zone->lru_lock, flags); |
258 | locked = false; | 307 | locked = false; |
259 | } | 308 | } |
260 | if (need_resched() || spin_is_contended(&zone->lru_lock)) { | 309 | |
261 | if (locked) | 310 | /* Check if it is ok to still hold the lock */ |
262 | spin_unlock_irq(&zone->lru_lock); | 311 | locked = compact_checklock_irqsave(&zone->lru_lock, &flags, |
263 | cond_resched(); | 312 | locked, cc); |
264 | spin_lock_irq(&zone->lru_lock); | 313 | if (!locked) |
265 | if (fatal_signal_pending(current)) | 314 | break; |
266 | break; | ||
267 | } else if (!locked) | ||
268 | spin_lock_irq(&zone->lru_lock); | ||
269 | 315 | ||
270 | /* | 316 | /* |
271 | * migrate_pfn does not necessarily start aligned to a | 317 | * migrate_pfn does not necessarily start aligned to a |
@@ -349,9 +395,10 @@ isolate_migratepages_range(struct zone *zone, struct compact_control *cc, | |||
349 | } | 395 | } |
350 | } | 396 | } |
351 | 397 | ||
352 | acct_isolated(zone, cc); | 398 | acct_isolated(zone, locked, cc); |
353 | 399 | ||
354 | spin_unlock_irq(&zone->lru_lock); | 400 | if (locked) |
401 | spin_unlock_irqrestore(&zone->lru_lock, flags); | ||
355 | 402 | ||
356 | trace_mm_compaction_isolate_migratepages(nr_scanned, nr_isolated); | 403 | trace_mm_compaction_isolate_migratepages(nr_scanned, nr_isolated); |
357 | 404 | ||
@@ -384,6 +431,20 @@ static bool suitable_migration_target(struct page *page) | |||
384 | } | 431 | } |
385 | 432 | ||
386 | /* | 433 | /* |
434 | * Returns the start pfn of the last page block in a zone. This is the starting | ||
435 | * point for full compaction of a zone. Compaction searches for free pages from | ||
436 | * the end of each zone, while isolate_freepages_block scans forward inside each | ||
437 | * page block. | ||
438 | */ | ||
439 | static unsigned long start_free_pfn(struct zone *zone) | ||
440 | { | ||
441 | unsigned long free_pfn; | ||
442 | free_pfn = zone->zone_start_pfn + zone->spanned_pages; | ||
443 | free_pfn &= ~(pageblock_nr_pages-1); | ||
444 | return free_pfn; | ||
445 | } | ||
446 | |||
447 | /* | ||
387 | * Based on information in the current compact_control, find blocks | 448 | * Based on information in the current compact_control, find blocks |
388 | * suitable for isolating free pages from and then isolate them. | 449 | * suitable for isolating free pages from and then isolate them. |
389 | */ | 450 | */ |
@@ -422,17 +483,6 @@ static void isolate_freepages(struct zone *zone, | |||
422 | pfn -= pageblock_nr_pages) { | 483 | pfn -= pageblock_nr_pages) { |
423 | unsigned long isolated; | 484 | unsigned long isolated; |
424 | 485 | ||
425 | /* | ||
426 | * Skip ahead if another thread is compacting in the area | ||
427 | * simultaneously. If we wrapped around, we can only skip | ||
428 | * ahead if zone->compact_cached_free_pfn also wrapped to | ||
429 | * above our starting point. | ||
430 | */ | ||
431 | if (cc->order > 0 && (!cc->wrapped || | ||
432 | zone->compact_cached_free_pfn > | ||
433 | cc->start_free_pfn)) | ||
434 | pfn = min(pfn, zone->compact_cached_free_pfn); | ||
435 | |||
436 | if (!pfn_valid(pfn)) | 486 | if (!pfn_valid(pfn)) |
437 | continue; | 487 | continue; |
438 | 488 | ||
@@ -458,7 +508,16 @@ static void isolate_freepages(struct zone *zone, | |||
458 | * are disabled | 508 | * are disabled |
459 | */ | 509 | */ |
460 | isolated = 0; | 510 | isolated = 0; |
461 | spin_lock_irqsave(&zone->lock, flags); | 511 | |
512 | /* | ||
513 | * The zone lock must be held to isolate freepages. This | ||
514 | * unfortunately this is a very coarse lock and can be | ||
515 | * heavily contended if there are parallel allocations | ||
516 | * or parallel compactions. For async compaction do not | ||
517 | * spin on the lock | ||
518 | */ | ||
519 | if (!compact_trylock_irqsave(&zone->lock, &flags, cc)) | ||
520 | break; | ||
462 | if (suitable_migration_target(page)) { | 521 | if (suitable_migration_target(page)) { |
463 | end_pfn = min(pfn + pageblock_nr_pages, zone_end_pfn); | 522 | end_pfn = min(pfn + pageblock_nr_pages, zone_end_pfn); |
464 | isolated = isolate_freepages_block(pfn, end_pfn, | 523 | isolated = isolate_freepages_block(pfn, end_pfn, |
@@ -474,7 +533,15 @@ static void isolate_freepages(struct zone *zone, | |||
474 | */ | 533 | */ |
475 | if (isolated) { | 534 | if (isolated) { |
476 | high_pfn = max(high_pfn, pfn); | 535 | high_pfn = max(high_pfn, pfn); |
477 | if (cc->order > 0) | 536 | |
537 | /* | ||
538 | * If the free scanner has wrapped, update | ||
539 | * compact_cached_free_pfn to point to the highest | ||
540 | * pageblock with free pages. This reduces excessive | ||
541 | * scanning of full pageblocks near the end of the | ||
542 | * zone | ||
543 | */ | ||
544 | if (cc->order > 0 && cc->wrapped) | ||
478 | zone->compact_cached_free_pfn = high_pfn; | 545 | zone->compact_cached_free_pfn = high_pfn; |
479 | } | 546 | } |
480 | } | 547 | } |
@@ -484,6 +551,11 @@ static void isolate_freepages(struct zone *zone, | |||
484 | 551 | ||
485 | cc->free_pfn = high_pfn; | 552 | cc->free_pfn = high_pfn; |
486 | cc->nr_freepages = nr_freepages; | 553 | cc->nr_freepages = nr_freepages; |
554 | |||
555 | /* If compact_cached_free_pfn is reset then set it now */ | ||
556 | if (cc->order > 0 && !cc->wrapped && | ||
557 | zone->compact_cached_free_pfn == start_free_pfn(zone)) | ||
558 | zone->compact_cached_free_pfn = high_pfn; | ||
487 | } | 559 | } |
488 | 560 | ||
489 | /* | 561 | /* |
@@ -570,20 +642,6 @@ static isolate_migrate_t isolate_migratepages(struct zone *zone, | |||
570 | return ISOLATE_SUCCESS; | 642 | return ISOLATE_SUCCESS; |
571 | } | 643 | } |
572 | 644 | ||
573 | /* | ||
574 | * Returns the start pfn of the last page block in a zone. This is the starting | ||
575 | * point for full compaction of a zone. Compaction searches for free pages from | ||
576 | * the end of each zone, while isolate_freepages_block scans forward inside each | ||
577 | * page block. | ||
578 | */ | ||
579 | static unsigned long start_free_pfn(struct zone *zone) | ||
580 | { | ||
581 | unsigned long free_pfn; | ||
582 | free_pfn = zone->zone_start_pfn + zone->spanned_pages; | ||
583 | free_pfn &= ~(pageblock_nr_pages-1); | ||
584 | return free_pfn; | ||
585 | } | ||
586 | |||
587 | static int compact_finished(struct zone *zone, | 645 | static int compact_finished(struct zone *zone, |
588 | struct compact_control *cc) | 646 | struct compact_control *cc) |
589 | { | 647 | { |
@@ -771,7 +829,7 @@ out: | |||
771 | 829 | ||
772 | static unsigned long compact_zone_order(struct zone *zone, | 830 | static unsigned long compact_zone_order(struct zone *zone, |
773 | int order, gfp_t gfp_mask, | 831 | int order, gfp_t gfp_mask, |
774 | bool sync) | 832 | bool sync, bool *contended) |
775 | { | 833 | { |
776 | struct compact_control cc = { | 834 | struct compact_control cc = { |
777 | .nr_freepages = 0, | 835 | .nr_freepages = 0, |
@@ -780,6 +838,7 @@ static unsigned long compact_zone_order(struct zone *zone, | |||
780 | .migratetype = allocflags_to_migratetype(gfp_mask), | 838 | .migratetype = allocflags_to_migratetype(gfp_mask), |
781 | .zone = zone, | 839 | .zone = zone, |
782 | .sync = sync, | 840 | .sync = sync, |
841 | .contended = contended, | ||
783 | }; | 842 | }; |
784 | INIT_LIST_HEAD(&cc.freepages); | 843 | INIT_LIST_HEAD(&cc.freepages); |
785 | INIT_LIST_HEAD(&cc.migratepages); | 844 | INIT_LIST_HEAD(&cc.migratepages); |
@@ -801,7 +860,7 @@ int sysctl_extfrag_threshold = 500; | |||
801 | */ | 860 | */ |
802 | unsigned long try_to_compact_pages(struct zonelist *zonelist, | 861 | unsigned long try_to_compact_pages(struct zonelist *zonelist, |
803 | int order, gfp_t gfp_mask, nodemask_t *nodemask, | 862 | int order, gfp_t gfp_mask, nodemask_t *nodemask, |
804 | bool sync) | 863 | bool sync, bool *contended) |
805 | { | 864 | { |
806 | enum zone_type high_zoneidx = gfp_zone(gfp_mask); | 865 | enum zone_type high_zoneidx = gfp_zone(gfp_mask); |
807 | int may_enter_fs = gfp_mask & __GFP_FS; | 866 | int may_enter_fs = gfp_mask & __GFP_FS; |
@@ -825,7 +884,8 @@ unsigned long try_to_compact_pages(struct zonelist *zonelist, | |||
825 | nodemask) { | 884 | nodemask) { |
826 | int status; | 885 | int status; |
827 | 886 | ||
828 | status = compact_zone_order(zone, order, gfp_mask, sync); | 887 | status = compact_zone_order(zone, order, gfp_mask, sync, |
888 | contended); | ||
829 | rc = max(status, rc); | 889 | rc = max(status, rc); |
830 | 890 | ||
831 | /* If a normal allocation would succeed, stop compacting */ | 891 | /* If a normal allocation would succeed, stop compacting */ |
@@ -861,7 +921,7 @@ static int __compact_pgdat(pg_data_t *pgdat, struct compact_control *cc) | |||
861 | if (cc->order > 0) { | 921 | if (cc->order > 0) { |
862 | int ok = zone_watermark_ok(zone, cc->order, | 922 | int ok = zone_watermark_ok(zone, cc->order, |
863 | low_wmark_pages(zone), 0, 0); | 923 | low_wmark_pages(zone), 0, 0); |
864 | if (ok && cc->order > zone->compact_order_failed) | 924 | if (ok && cc->order >= zone->compact_order_failed) |
865 | zone->compact_order_failed = cc->order + 1; | 925 | zone->compact_order_failed = cc->order + 1; |
866 | /* Currently async compaction is never deferred. */ | 926 | /* Currently async compaction is never deferred. */ |
867 | else if (!ok && cc->sync) | 927 | else if (!ok && cc->sync) |
diff --git a/mm/internal.h b/mm/internal.h index 3314f79d775a..b8c91b342e24 100644 --- a/mm/internal.h +++ b/mm/internal.h | |||
@@ -130,6 +130,7 @@ struct compact_control { | |||
130 | int order; /* order a direct compactor needs */ | 130 | int order; /* order a direct compactor needs */ |
131 | int migratetype; /* MOVABLE, RECLAIMABLE etc */ | 131 | int migratetype; /* MOVABLE, RECLAIMABLE etc */ |
132 | struct zone *zone; | 132 | struct zone *zone; |
133 | bool *contended; /* True if a lock was contended */ | ||
133 | }; | 134 | }; |
134 | 135 | ||
135 | unsigned long | 136 | unsigned long |
@@ -2309,7 +2309,7 @@ void exit_mmap(struct mm_struct *mm) | |||
2309 | } | 2309 | } |
2310 | vm_unacct_memory(nr_accounted); | 2310 | vm_unacct_memory(nr_accounted); |
2311 | 2311 | ||
2312 | BUG_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT); | 2312 | WARN_ON(mm->nr_ptes > (FIRST_USER_ADDRESS+PMD_SIZE-1)>>PMD_SHIFT); |
2313 | } | 2313 | } |
2314 | 2314 | ||
2315 | /* Insert vm structure into process list sorted by address | 2315 | /* Insert vm structure into process list sorted by address |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index e5363f34e025..5ad5ce23c1e0 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -1532,7 +1532,6 @@ int dirty_writeback_centisecs_handler(ctl_table *table, int write, | |||
1532 | void __user *buffer, size_t *length, loff_t *ppos) | 1532 | void __user *buffer, size_t *length, loff_t *ppos) |
1533 | { | 1533 | { |
1534 | proc_dointvec(table, write, buffer, length, ppos); | 1534 | proc_dointvec(table, write, buffer, length, ppos); |
1535 | bdi_arm_supers_timer(); | ||
1536 | return 0; | 1535 | return 0; |
1537 | } | 1536 | } |
1538 | 1537 | ||
diff --git a/mm/page_alloc.c b/mm/page_alloc.c index 889532b8e6c1..c66fb875104a 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c | |||
@@ -1928,6 +1928,17 @@ this_zone_full: | |||
1928 | zlc_active = 0; | 1928 | zlc_active = 0; |
1929 | goto zonelist_scan; | 1929 | goto zonelist_scan; |
1930 | } | 1930 | } |
1931 | |||
1932 | if (page) | ||
1933 | /* | ||
1934 | * page->pfmemalloc is set when ALLOC_NO_WATERMARKS was | ||
1935 | * necessary to allocate the page. The expectation is | ||
1936 | * that the caller is taking steps that will free more | ||
1937 | * memory. The caller should avoid the page being used | ||
1938 | * for !PFMEMALLOC purposes. | ||
1939 | */ | ||
1940 | page->pfmemalloc = !!(alloc_flags & ALLOC_NO_WATERMARKS); | ||
1941 | |||
1931 | return page; | 1942 | return page; |
1932 | } | 1943 | } |
1933 | 1944 | ||
@@ -2091,7 +2102,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, | |||
2091 | struct zonelist *zonelist, enum zone_type high_zoneidx, | 2102 | struct zonelist *zonelist, enum zone_type high_zoneidx, |
2092 | nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone, | 2103 | nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone, |
2093 | int migratetype, bool sync_migration, | 2104 | int migratetype, bool sync_migration, |
2094 | bool *deferred_compaction, | 2105 | bool *contended_compaction, bool *deferred_compaction, |
2095 | unsigned long *did_some_progress) | 2106 | unsigned long *did_some_progress) |
2096 | { | 2107 | { |
2097 | struct page *page; | 2108 | struct page *page; |
@@ -2106,7 +2117,8 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, | |||
2106 | 2117 | ||
2107 | current->flags |= PF_MEMALLOC; | 2118 | current->flags |= PF_MEMALLOC; |
2108 | *did_some_progress = try_to_compact_pages(zonelist, order, gfp_mask, | 2119 | *did_some_progress = try_to_compact_pages(zonelist, order, gfp_mask, |
2109 | nodemask, sync_migration); | 2120 | nodemask, sync_migration, |
2121 | contended_compaction); | ||
2110 | current->flags &= ~PF_MEMALLOC; | 2122 | current->flags &= ~PF_MEMALLOC; |
2111 | if (*did_some_progress != COMPACT_SKIPPED) { | 2123 | if (*did_some_progress != COMPACT_SKIPPED) { |
2112 | 2124 | ||
@@ -2152,7 +2164,7 @@ __alloc_pages_direct_compact(gfp_t gfp_mask, unsigned int order, | |||
2152 | struct zonelist *zonelist, enum zone_type high_zoneidx, | 2164 | struct zonelist *zonelist, enum zone_type high_zoneidx, |
2153 | nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone, | 2165 | nodemask_t *nodemask, int alloc_flags, struct zone *preferred_zone, |
2154 | int migratetype, bool sync_migration, | 2166 | int migratetype, bool sync_migration, |
2155 | bool *deferred_compaction, | 2167 | bool *contended_compaction, bool *deferred_compaction, |
2156 | unsigned long *did_some_progress) | 2168 | unsigned long *did_some_progress) |
2157 | { | 2169 | { |
2158 | return NULL; | 2170 | return NULL; |
@@ -2325,6 +2337,7 @@ __alloc_pages_slowpath(gfp_t gfp_mask, unsigned int order, | |||
2325 | unsigned long did_some_progress; | 2337 | unsigned long did_some_progress; |
2326 | bool sync_migration = false; | 2338 | bool sync_migration = false; |
2327 | bool deferred_compaction = false; | 2339 | bool deferred_compaction = false; |
2340 | bool contended_compaction = false; | ||
2328 | 2341 | ||
2329 | /* | 2342 | /* |
2330 | * In the slowpath, we sanity check order to avoid ever trying to | 2343 | * In the slowpath, we sanity check order to avoid ever trying to |
@@ -2389,14 +2402,6 @@ rebalance: | |||
2389 | zonelist, high_zoneidx, nodemask, | 2402 | zonelist, high_zoneidx, nodemask, |
2390 | preferred_zone, migratetype); | 2403 | preferred_zone, migratetype); |
2391 | if (page) { | 2404 | if (page) { |
2392 | /* | ||
2393 | * page->pfmemalloc is set when ALLOC_NO_WATERMARKS was | ||
2394 | * necessary to allocate the page. The expectation is | ||
2395 | * that the caller is taking steps that will free more | ||
2396 | * memory. The caller should avoid the page being used | ||
2397 | * for !PFMEMALLOC purposes. | ||
2398 | */ | ||
2399 | page->pfmemalloc = true; | ||
2400 | goto got_pg; | 2405 | goto got_pg; |
2401 | } | 2406 | } |
2402 | } | 2407 | } |
@@ -2422,6 +2427,7 @@ rebalance: | |||
2422 | nodemask, | 2427 | nodemask, |
2423 | alloc_flags, preferred_zone, | 2428 | alloc_flags, preferred_zone, |
2424 | migratetype, sync_migration, | 2429 | migratetype, sync_migration, |
2430 | &contended_compaction, | ||
2425 | &deferred_compaction, | 2431 | &deferred_compaction, |
2426 | &did_some_progress); | 2432 | &did_some_progress); |
2427 | if (page) | 2433 | if (page) |
@@ -2431,10 +2437,11 @@ rebalance: | |||
2431 | /* | 2437 | /* |
2432 | * If compaction is deferred for high-order allocations, it is because | 2438 | * If compaction is deferred for high-order allocations, it is because |
2433 | * sync compaction recently failed. In this is the case and the caller | 2439 | * sync compaction recently failed. In this is the case and the caller |
2434 | * has requested the system not be heavily disrupted, fail the | 2440 | * requested a movable allocation that does not heavily disrupt the |
2435 | * allocation now instead of entering direct reclaim | 2441 | * system then fail the allocation instead of entering direct reclaim. |
2436 | */ | 2442 | */ |
2437 | if (deferred_compaction && (gfp_mask & __GFP_NO_KSWAPD)) | 2443 | if ((deferred_compaction || contended_compaction) && |
2444 | (gfp_mask & __GFP_NO_KSWAPD)) | ||
2438 | goto nopage; | 2445 | goto nopage; |
2439 | 2446 | ||
2440 | /* Try direct reclaim and then allocating */ | 2447 | /* Try direct reclaim and then allocating */ |
@@ -2505,6 +2512,7 @@ rebalance: | |||
2505 | nodemask, | 2512 | nodemask, |
2506 | alloc_flags, preferred_zone, | 2513 | alloc_flags, preferred_zone, |
2507 | migratetype, sync_migration, | 2514 | migratetype, sync_migration, |
2515 | &contended_compaction, | ||
2508 | &deferred_compaction, | 2516 | &deferred_compaction, |
2509 | &did_some_progress); | 2517 | &did_some_progress); |
2510 | if (page) | 2518 | if (page) |
@@ -2569,8 +2577,6 @@ retry_cpuset: | |||
2569 | page = __alloc_pages_slowpath(gfp_mask, order, | 2577 | page = __alloc_pages_slowpath(gfp_mask, order, |
2570 | zonelist, high_zoneidx, nodemask, | 2578 | zonelist, high_zoneidx, nodemask, |
2571 | preferred_zone, migratetype); | 2579 | preferred_zone, migratetype); |
2572 | else | ||
2573 | page->pfmemalloc = false; | ||
2574 | 2580 | ||
2575 | trace_mm_page_alloc(page, order, gfp_mask, migratetype); | 2581 | trace_mm_page_alloc(page, order, gfp_mask, migratetype); |
2576 | 2582 | ||
@@ -4511,7 +4517,7 @@ void __paginginit free_area_init_node(int nid, unsigned long *zones_size, | |||
4511 | pg_data_t *pgdat = NODE_DATA(nid); | 4517 | pg_data_t *pgdat = NODE_DATA(nid); |
4512 | 4518 | ||
4513 | /* pg_data_t should be reset to zero when it's allocated */ | 4519 | /* pg_data_t should be reset to zero when it's allocated */ |
4514 | WARN_ON(pgdat->nr_zones || pgdat->node_start_pfn || pgdat->classzone_idx); | 4520 | WARN_ON(pgdat->nr_zones || pgdat->classzone_idx); |
4515 | 4521 | ||
4516 | pgdat->node_id = nid; | 4522 | pgdat->node_id = nid; |
4517 | pgdat->node_start_pfn = node_start_pfn; | 4523 | pgdat->node_start_pfn = node_start_pfn; |
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 73a2a83ee2da..402442402af7 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -137,9 +137,21 @@ static int vlan_dev_hard_header(struct sk_buff *skb, struct net_device *dev, | |||
137 | return rc; | 137 | return rc; |
138 | } | 138 | } |
139 | 139 | ||
140 | static inline netdev_tx_t vlan_netpoll_send_skb(struct vlan_dev_priv *vlan, struct sk_buff *skb) | ||
141 | { | ||
142 | #ifdef CONFIG_NET_POLL_CONTROLLER | ||
143 | if (vlan->netpoll) | ||
144 | netpoll_send_skb(vlan->netpoll, skb); | ||
145 | #else | ||
146 | BUG(); | ||
147 | #endif | ||
148 | return NETDEV_TX_OK; | ||
149 | } | ||
150 | |||
140 | static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, | 151 | static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, |
141 | struct net_device *dev) | 152 | struct net_device *dev) |
142 | { | 153 | { |
154 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); | ||
143 | struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); | 155 | struct vlan_ethhdr *veth = (struct vlan_ethhdr *)(skb->data); |
144 | unsigned int len; | 156 | unsigned int len; |
145 | int ret; | 157 | int ret; |
@@ -150,29 +162,30 @@ static netdev_tx_t vlan_dev_hard_start_xmit(struct sk_buff *skb, | |||
150 | * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... | 162 | * OTHER THINGS LIKE FDDI/TokenRing/802.3 SNAPs... |
151 | */ | 163 | */ |
152 | if (veth->h_vlan_proto != htons(ETH_P_8021Q) || | 164 | if (veth->h_vlan_proto != htons(ETH_P_8021Q) || |
153 | vlan_dev_priv(dev)->flags & VLAN_FLAG_REORDER_HDR) { | 165 | vlan->flags & VLAN_FLAG_REORDER_HDR) { |
154 | u16 vlan_tci; | 166 | u16 vlan_tci; |
155 | vlan_tci = vlan_dev_priv(dev)->vlan_id; | 167 | vlan_tci = vlan->vlan_id; |
156 | vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); | 168 | vlan_tci |= vlan_dev_get_egress_qos_mask(dev, skb); |
157 | skb = __vlan_hwaccel_put_tag(skb, vlan_tci); | 169 | skb = __vlan_hwaccel_put_tag(skb, vlan_tci); |
158 | } | 170 | } |
159 | 171 | ||
160 | skb->dev = vlan_dev_priv(dev)->real_dev; | 172 | skb->dev = vlan->real_dev; |
161 | len = skb->len; | 173 | len = skb->len; |
162 | if (netpoll_tx_running(dev)) | 174 | if (unlikely(netpoll_tx_running(dev))) |
163 | return skb->dev->netdev_ops->ndo_start_xmit(skb, skb->dev); | 175 | return vlan_netpoll_send_skb(vlan, skb); |
176 | |||
164 | ret = dev_queue_xmit(skb); | 177 | ret = dev_queue_xmit(skb); |
165 | 178 | ||
166 | if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { | 179 | if (likely(ret == NET_XMIT_SUCCESS || ret == NET_XMIT_CN)) { |
167 | struct vlan_pcpu_stats *stats; | 180 | struct vlan_pcpu_stats *stats; |
168 | 181 | ||
169 | stats = this_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats); | 182 | stats = this_cpu_ptr(vlan->vlan_pcpu_stats); |
170 | u64_stats_update_begin(&stats->syncp); | 183 | u64_stats_update_begin(&stats->syncp); |
171 | stats->tx_packets++; | 184 | stats->tx_packets++; |
172 | stats->tx_bytes += len; | 185 | stats->tx_bytes += len; |
173 | u64_stats_update_end(&stats->syncp); | 186 | u64_stats_update_end(&stats->syncp); |
174 | } else { | 187 | } else { |
175 | this_cpu_inc(vlan_dev_priv(dev)->vlan_pcpu_stats->tx_dropped); | 188 | this_cpu_inc(vlan->vlan_pcpu_stats->tx_dropped); |
176 | } | 189 | } |
177 | 190 | ||
178 | return ret; | 191 | return ret; |
@@ -669,25 +682,26 @@ static void vlan_dev_poll_controller(struct net_device *dev) | |||
669 | return; | 682 | return; |
670 | } | 683 | } |
671 | 684 | ||
672 | static int vlan_dev_netpoll_setup(struct net_device *dev, struct netpoll_info *npinfo) | 685 | static int vlan_dev_netpoll_setup(struct net_device *dev, struct netpoll_info *npinfo, |
686 | gfp_t gfp) | ||
673 | { | 687 | { |
674 | struct vlan_dev_priv *info = vlan_dev_priv(dev); | 688 | struct vlan_dev_priv *vlan = vlan_dev_priv(dev); |
675 | struct net_device *real_dev = info->real_dev; | 689 | struct net_device *real_dev = vlan->real_dev; |
676 | struct netpoll *netpoll; | 690 | struct netpoll *netpoll; |
677 | int err = 0; | 691 | int err = 0; |
678 | 692 | ||
679 | netpoll = kzalloc(sizeof(*netpoll), GFP_KERNEL); | 693 | netpoll = kzalloc(sizeof(*netpoll), gfp); |
680 | err = -ENOMEM; | 694 | err = -ENOMEM; |
681 | if (!netpoll) | 695 | if (!netpoll) |
682 | goto out; | 696 | goto out; |
683 | 697 | ||
684 | err = __netpoll_setup(netpoll, real_dev); | 698 | err = __netpoll_setup(netpoll, real_dev, gfp); |
685 | if (err) { | 699 | if (err) { |
686 | kfree(netpoll); | 700 | kfree(netpoll); |
687 | goto out; | 701 | goto out; |
688 | } | 702 | } |
689 | 703 | ||
690 | info->netpoll = netpoll; | 704 | vlan->netpoll = netpoll; |
691 | 705 | ||
692 | out: | 706 | out: |
693 | return err; | 707 | return err; |
@@ -695,19 +709,15 @@ out: | |||
695 | 709 | ||
696 | static void vlan_dev_netpoll_cleanup(struct net_device *dev) | 710 | static void vlan_dev_netpoll_cleanup(struct net_device *dev) |
697 | { | 711 | { |
698 | struct vlan_dev_priv *info = vlan_dev_priv(dev); | 712 | struct vlan_dev_priv *vlan= vlan_dev_priv(dev); |
699 | struct netpoll *netpoll = info->netpoll; | 713 | struct netpoll *netpoll = vlan->netpoll; |
700 | 714 | ||
701 | if (!netpoll) | 715 | if (!netpoll) |
702 | return; | 716 | return; |
703 | 717 | ||
704 | info->netpoll = NULL; | 718 | vlan->netpoll = NULL; |
705 | |||
706 | /* Wait for transmitting packets to finish before freeing. */ | ||
707 | synchronize_rcu_bh(); | ||
708 | 719 | ||
709 | __netpoll_cleanup(netpoll); | 720 | __netpoll_free_rcu(netpoll); |
710 | kfree(netpoll); | ||
711 | } | 721 | } |
712 | #endif /* CONFIG_NET_POLL_CONTROLLER */ | 722 | #endif /* CONFIG_NET_POLL_CONTROLLER */ |
713 | 723 | ||
diff --git a/net/atm/common.c b/net/atm/common.c index b4b44dbed645..0c0ad930a632 100644 --- a/net/atm/common.c +++ b/net/atm/common.c | |||
@@ -812,6 +812,7 @@ int vcc_getsockopt(struct socket *sock, int level, int optname, | |||
812 | 812 | ||
813 | if (!vcc->dev || !test_bit(ATM_VF_ADDR, &vcc->flags)) | 813 | if (!vcc->dev || !test_bit(ATM_VF_ADDR, &vcc->flags)) |
814 | return -ENOTCONN; | 814 | return -ENOTCONN; |
815 | memset(&pvc, 0, sizeof(pvc)); | ||
815 | pvc.sap_family = AF_ATMPVC; | 816 | pvc.sap_family = AF_ATMPVC; |
816 | pvc.sap_addr.itf = vcc->dev->number; | 817 | pvc.sap_addr.itf = vcc->dev->number; |
817 | pvc.sap_addr.vpi = vcc->vpi; | 818 | pvc.sap_addr.vpi = vcc->vpi; |
diff --git a/net/atm/pvc.c b/net/atm/pvc.c index 3a734919c36c..ae0324021407 100644 --- a/net/atm/pvc.c +++ b/net/atm/pvc.c | |||
@@ -95,6 +95,7 @@ static int pvc_getname(struct socket *sock, struct sockaddr *sockaddr, | |||
95 | return -ENOTCONN; | 95 | return -ENOTCONN; |
96 | *sockaddr_len = sizeof(struct sockaddr_atmpvc); | 96 | *sockaddr_len = sizeof(struct sockaddr_atmpvc); |
97 | addr = (struct sockaddr_atmpvc *)sockaddr; | 97 | addr = (struct sockaddr_atmpvc *)sockaddr; |
98 | memset(addr, 0, sizeof(*addr)); | ||
98 | addr->sap_family = AF_ATMPVC; | 99 | addr->sap_family = AF_ATMPVC; |
99 | addr->sap_addr.itf = vcc->dev->number; | 100 | addr->sap_addr.itf = vcc->dev->number; |
100 | addr->sap_addr.vpi = vcc->vpi; | 101 | addr->sap_addr.vpi = vcc->vpi; |
diff --git a/net/batman-adv/gateway_client.c b/net/batman-adv/gateway_client.c index b421cc49d2cd..fc866f2e4528 100644 --- a/net/batman-adv/gateway_client.c +++ b/net/batman-adv/gateway_client.c | |||
@@ -200,11 +200,11 @@ void batadv_gw_election(struct batadv_priv *bat_priv) | |||
200 | if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT) | 200 | if (atomic_read(&bat_priv->gw_mode) != BATADV_GW_MODE_CLIENT) |
201 | goto out; | 201 | goto out; |
202 | 202 | ||
203 | if (!batadv_atomic_dec_not_zero(&bat_priv->gw_reselect)) | ||
204 | goto out; | ||
205 | |||
206 | curr_gw = batadv_gw_get_selected_gw_node(bat_priv); | 203 | curr_gw = batadv_gw_get_selected_gw_node(bat_priv); |
207 | 204 | ||
205 | if (!batadv_atomic_dec_not_zero(&bat_priv->gw_reselect) && curr_gw) | ||
206 | goto out; | ||
207 | |||
208 | next_gw = batadv_gw_get_best_gw_node(bat_priv); | 208 | next_gw = batadv_gw_get_best_gw_node(bat_priv); |
209 | 209 | ||
210 | if (curr_gw == next_gw) | 210 | if (curr_gw == next_gw) |
diff --git a/net/batman-adv/translation-table.c b/net/batman-adv/translation-table.c index a438f4b582fc..99dd8f75b3ff 100644 --- a/net/batman-adv/translation-table.c +++ b/net/batman-adv/translation-table.c | |||
@@ -197,6 +197,7 @@ static void batadv_tt_local_event(struct batadv_priv *bat_priv, | |||
197 | del: | 197 | del: |
198 | list_del(&entry->list); | 198 | list_del(&entry->list); |
199 | kfree(entry); | 199 | kfree(entry); |
200 | kfree(tt_change_node); | ||
200 | event_removed = true; | 201 | event_removed = true; |
201 | goto unlock; | 202 | goto unlock; |
202 | } | 203 | } |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 32e21ad36a68..4fd2cf3bcd05 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -1365,6 +1365,9 @@ static bool hci_resolve_next_name(struct hci_dev *hdev) | |||
1365 | return false; | 1365 | return false; |
1366 | 1366 | ||
1367 | e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); | 1367 | e = hci_inquiry_cache_lookup_resolve(hdev, BDADDR_ANY, NAME_NEEDED); |
1368 | if (!e) | ||
1369 | return false; | ||
1370 | |||
1368 | if (hci_resolve_name(hdev, e) == 0) { | 1371 | if (hci_resolve_name(hdev, e) == 0) { |
1369 | e->name_state = NAME_PENDING; | 1372 | e->name_state = NAME_PENDING; |
1370 | return true; | 1373 | return true; |
@@ -1393,12 +1396,20 @@ static void hci_check_pending_name(struct hci_dev *hdev, struct hci_conn *conn, | |||
1393 | return; | 1396 | return; |
1394 | 1397 | ||
1395 | e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING); | 1398 | e = hci_inquiry_cache_lookup_resolve(hdev, bdaddr, NAME_PENDING); |
1396 | if (e) { | 1399 | /* If the device was not found in a list of found devices names of which |
1400 | * are pending. there is no need to continue resolving a next name as it | ||
1401 | * will be done upon receiving another Remote Name Request Complete | ||
1402 | * Event */ | ||
1403 | if (!e) | ||
1404 | return; | ||
1405 | |||
1406 | list_del(&e->list); | ||
1407 | if (name) { | ||
1397 | e->name_state = NAME_KNOWN; | 1408 | e->name_state = NAME_KNOWN; |
1398 | list_del(&e->list); | 1409 | mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, |
1399 | if (name) | 1410 | e->data.rssi, name, name_len); |
1400 | mgmt_remote_name(hdev, bdaddr, ACL_LINK, 0x00, | 1411 | } else { |
1401 | e->data.rssi, name, name_len); | 1412 | e->name_state = NAME_NOT_KNOWN; |
1402 | } | 1413 | } |
1403 | 1414 | ||
1404 | if (hci_resolve_next_name(hdev)) | 1415 | if (hci_resolve_next_name(hdev)) |
@@ -1749,7 +1760,12 @@ static void hci_conn_complete_evt(struct hci_dev *hdev, struct sk_buff *skb) | |||
1749 | if (conn->type == ACL_LINK) { | 1760 | if (conn->type == ACL_LINK) { |
1750 | conn->state = BT_CONFIG; | 1761 | conn->state = BT_CONFIG; |
1751 | hci_conn_hold(conn); | 1762 | hci_conn_hold(conn); |
1752 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | 1763 | |
1764 | if (!conn->out && !hci_conn_ssp_enabled(conn) && | ||
1765 | !hci_find_link_key(hdev, &ev->bdaddr)) | ||
1766 | conn->disc_timeout = HCI_PAIRING_TIMEOUT; | ||
1767 | else | ||
1768 | conn->disc_timeout = HCI_DISCONN_TIMEOUT; | ||
1753 | } else | 1769 | } else |
1754 | conn->state = BT_CONNECTED; | 1770 | conn->state = BT_CONNECTED; |
1755 | 1771 | ||
diff --git a/net/bluetooth/hci_sock.c b/net/bluetooth/hci_sock.c index 7c3d6c7c6ddb..bb64331db3b7 100644 --- a/net/bluetooth/hci_sock.c +++ b/net/bluetooth/hci_sock.c | |||
@@ -694,6 +694,7 @@ static int hci_sock_getname(struct socket *sock, struct sockaddr *addr, | |||
694 | *addr_len = sizeof(*haddr); | 694 | *addr_len = sizeof(*haddr); |
695 | haddr->hci_family = AF_BLUETOOTH; | 695 | haddr->hci_family = AF_BLUETOOTH; |
696 | haddr->hci_dev = hdev->id; | 696 | haddr->hci_dev = hdev->id; |
697 | haddr->hci_channel= 0; | ||
697 | 698 | ||
698 | release_sock(sk); | 699 | release_sock(sk); |
699 | return 0; | 700 | return 0; |
@@ -1009,6 +1010,7 @@ static int hci_sock_getsockopt(struct socket *sock, int level, int optname, | |||
1009 | { | 1010 | { |
1010 | struct hci_filter *f = &hci_pi(sk)->filter; | 1011 | struct hci_filter *f = &hci_pi(sk)->filter; |
1011 | 1012 | ||
1013 | memset(&uf, 0, sizeof(uf)); | ||
1012 | uf.type_mask = f->type_mask; | 1014 | uf.type_mask = f->type_mask; |
1013 | uf.opcode = f->opcode; | 1015 | uf.opcode = f->opcode; |
1014 | uf.event_mask[0] = *((u32 *) f->event_mask + 0); | 1016 | uf.event_mask[0] = *((u32 *) f->event_mask + 0); |
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c index 9f8b29ef5b68..f0a3ab156ec6 100644 --- a/net/bluetooth/l2cap_core.c +++ b/net/bluetooth/l2cap_core.c | |||
@@ -1198,6 +1198,7 @@ static void l2cap_le_conn_ready(struct l2cap_conn *conn) | |||
1198 | sk = chan->sk; | 1198 | sk = chan->sk; |
1199 | 1199 | ||
1200 | hci_conn_hold(conn->hcon); | 1200 | hci_conn_hold(conn->hcon); |
1201 | conn->hcon->disc_timeout = HCI_DISCONN_TIMEOUT; | ||
1201 | 1202 | ||
1202 | bacpy(&bt_sk(sk)->src, conn->src); | 1203 | bacpy(&bt_sk(sk)->src, conn->src); |
1203 | bacpy(&bt_sk(sk)->dst, conn->dst); | 1204 | bacpy(&bt_sk(sk)->dst, conn->dst); |
diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c index 13f6a9816feb..3a6ce73541d9 100644 --- a/net/bluetooth/l2cap_sock.c +++ b/net/bluetooth/l2cap_sock.c | |||
@@ -249,6 +249,7 @@ static int l2cap_sock_getname(struct socket *sock, struct sockaddr *addr, int *l | |||
249 | 249 | ||
250 | BT_DBG("sock %p, sk %p", sock, sk); | 250 | BT_DBG("sock %p, sk %p", sock, sk); |
251 | 251 | ||
252 | memset(la, 0, sizeof(struct sockaddr_l2)); | ||
252 | addr->sa_family = AF_BLUETOOTH; | 253 | addr->sa_family = AF_BLUETOOTH; |
253 | *len = sizeof(struct sockaddr_l2); | 254 | *len = sizeof(struct sockaddr_l2); |
254 | 255 | ||
@@ -1180,7 +1181,7 @@ static struct sock *l2cap_sock_alloc(struct net *net, struct socket *sock, int p | |||
1180 | 1181 | ||
1181 | chan = l2cap_chan_create(); | 1182 | chan = l2cap_chan_create(); |
1182 | if (!chan) { | 1183 | if (!chan) { |
1183 | l2cap_sock_kill(sk); | 1184 | sk_free(sk); |
1184 | return NULL; | 1185 | return NULL; |
1185 | } | 1186 | } |
1186 | 1187 | ||
diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c index 260821a2d6e7..b3226f3658cf 100644 --- a/net/bluetooth/rfcomm/sock.c +++ b/net/bluetooth/rfcomm/sock.c | |||
@@ -528,6 +528,7 @@ static int rfcomm_sock_getname(struct socket *sock, struct sockaddr *addr, int * | |||
528 | 528 | ||
529 | BT_DBG("sock %p, sk %p", sock, sk); | 529 | BT_DBG("sock %p, sk %p", sock, sk); |
530 | 530 | ||
531 | memset(sa, 0, sizeof(*sa)); | ||
531 | sa->rc_family = AF_BLUETOOTH; | 532 | sa->rc_family = AF_BLUETOOTH; |
532 | sa->rc_channel = rfcomm_pi(sk)->channel; | 533 | sa->rc_channel = rfcomm_pi(sk)->channel; |
533 | if (peer) | 534 | if (peer) |
@@ -822,6 +823,7 @@ static int rfcomm_sock_getsockopt(struct socket *sock, int level, int optname, c | |||
822 | } | 823 | } |
823 | 824 | ||
824 | sec.level = rfcomm_pi(sk)->sec_level; | 825 | sec.level = rfcomm_pi(sk)->sec_level; |
826 | sec.key_size = 0; | ||
825 | 827 | ||
826 | len = min_t(unsigned int, len, sizeof(sec)); | 828 | len = min_t(unsigned int, len, sizeof(sec)); |
827 | if (copy_to_user(optval, (char *) &sec, len)) | 829 | if (copy_to_user(optval, (char *) &sec, len)) |
diff --git a/net/bluetooth/rfcomm/tty.c b/net/bluetooth/rfcomm/tty.c index cb960773c002..56f182393c4c 100644 --- a/net/bluetooth/rfcomm/tty.c +++ b/net/bluetooth/rfcomm/tty.c | |||
@@ -456,7 +456,7 @@ static int rfcomm_get_dev_list(void __user *arg) | |||
456 | 456 | ||
457 | size = sizeof(*dl) + dev_num * sizeof(*di); | 457 | size = sizeof(*dl) + dev_num * sizeof(*di); |
458 | 458 | ||
459 | dl = kmalloc(size, GFP_KERNEL); | 459 | dl = kzalloc(size, GFP_KERNEL); |
460 | if (!dl) | 460 | if (!dl) |
461 | return -ENOMEM; | 461 | return -ENOMEM; |
462 | 462 | ||
diff --git a/net/bluetooth/sco.c b/net/bluetooth/sco.c index caa109df6452..dc42b917aaaf 100644 --- a/net/bluetooth/sco.c +++ b/net/bluetooth/sco.c | |||
@@ -131,6 +131,15 @@ static int sco_conn_del(struct hci_conn *hcon, int err) | |||
131 | sco_sock_clear_timer(sk); | 131 | sco_sock_clear_timer(sk); |
132 | sco_chan_del(sk, err); | 132 | sco_chan_del(sk, err); |
133 | bh_unlock_sock(sk); | 133 | bh_unlock_sock(sk); |
134 | |||
135 | sco_conn_lock(conn); | ||
136 | conn->sk = NULL; | ||
137 | sco_pi(sk)->conn = NULL; | ||
138 | sco_conn_unlock(conn); | ||
139 | |||
140 | if (conn->hcon) | ||
141 | hci_conn_put(conn->hcon); | ||
142 | |||
134 | sco_sock_kill(sk); | 143 | sco_sock_kill(sk); |
135 | } | 144 | } |
136 | 145 | ||
@@ -821,16 +830,6 @@ static void sco_chan_del(struct sock *sk, int err) | |||
821 | 830 | ||
822 | BT_DBG("sk %p, conn %p, err %d", sk, conn, err); | 831 | BT_DBG("sk %p, conn %p, err %d", sk, conn, err); |
823 | 832 | ||
824 | if (conn) { | ||
825 | sco_conn_lock(conn); | ||
826 | conn->sk = NULL; | ||
827 | sco_pi(sk)->conn = NULL; | ||
828 | sco_conn_unlock(conn); | ||
829 | |||
830 | if (conn->hcon) | ||
831 | hci_conn_put(conn->hcon); | ||
832 | } | ||
833 | |||
834 | sk->sk_state = BT_CLOSED; | 833 | sk->sk_state = BT_CLOSED; |
835 | sk->sk_err = err; | 834 | sk->sk_err = err; |
836 | sk->sk_state_change(sk); | 835 | sk->sk_state_change(sk); |
diff --git a/net/bluetooth/smp.c b/net/bluetooth/smp.c index 16ef0dc85a0a..901a616c8083 100644 --- a/net/bluetooth/smp.c +++ b/net/bluetooth/smp.c | |||
@@ -579,8 +579,11 @@ static u8 smp_cmd_pairing_req(struct l2cap_conn *conn, struct sk_buff *skb) | |||
579 | 579 | ||
580 | if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) | 580 | if (!test_and_set_bit(HCI_CONN_LE_SMP_PEND, &conn->hcon->flags)) |
581 | smp = smp_chan_create(conn); | 581 | smp = smp_chan_create(conn); |
582 | else | ||
583 | smp = conn->smp_chan; | ||
582 | 584 | ||
583 | smp = conn->smp_chan; | 585 | if (!smp) |
586 | return SMP_UNSPECIFIED; | ||
584 | 587 | ||
585 | smp->preq[0] = SMP_CMD_PAIRING_REQ; | 588 | smp->preq[0] = SMP_CMD_PAIRING_REQ; |
586 | memcpy(&smp->preq[1], req, sizeof(*req)); | 589 | memcpy(&smp->preq[1], req, sizeof(*req)); |
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 333484537600..070e8a68cfc6 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
@@ -31,9 +31,11 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) | |||
31 | struct net_bridge_mdb_entry *mdst; | 31 | struct net_bridge_mdb_entry *mdst; |
32 | struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats); | 32 | struct br_cpu_netstats *brstats = this_cpu_ptr(br->stats); |
33 | 33 | ||
34 | rcu_read_lock(); | ||
34 | #ifdef CONFIG_BRIDGE_NETFILTER | 35 | #ifdef CONFIG_BRIDGE_NETFILTER |
35 | if (skb->nf_bridge && (skb->nf_bridge->mask & BRNF_BRIDGED_DNAT)) { | 36 | if (skb->nf_bridge && (skb->nf_bridge->mask & BRNF_BRIDGED_DNAT)) { |
36 | br_nf_pre_routing_finish_bridge_slow(skb); | 37 | br_nf_pre_routing_finish_bridge_slow(skb); |
38 | rcu_read_unlock(); | ||
37 | return NETDEV_TX_OK; | 39 | return NETDEV_TX_OK; |
38 | } | 40 | } |
39 | #endif | 41 | #endif |
@@ -48,7 +50,6 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev) | |||
48 | skb_reset_mac_header(skb); | 50 | skb_reset_mac_header(skb); |
49 | skb_pull(skb, ETH_HLEN); | 51 | skb_pull(skb, ETH_HLEN); |
50 | 52 | ||
51 | rcu_read_lock(); | ||
52 | if (is_broadcast_ether_addr(dest)) | 53 | if (is_broadcast_ether_addr(dest)) |
53 | br_flood_deliver(br, skb); | 54 | br_flood_deliver(br, skb); |
54 | else if (is_multicast_ether_addr(dest)) { | 55 | else if (is_multicast_ether_addr(dest)) { |
@@ -206,24 +207,23 @@ static void br_poll_controller(struct net_device *br_dev) | |||
206 | static void br_netpoll_cleanup(struct net_device *dev) | 207 | static void br_netpoll_cleanup(struct net_device *dev) |
207 | { | 208 | { |
208 | struct net_bridge *br = netdev_priv(dev); | 209 | struct net_bridge *br = netdev_priv(dev); |
209 | struct net_bridge_port *p, *n; | 210 | struct net_bridge_port *p; |
210 | 211 | ||
211 | list_for_each_entry_safe(p, n, &br->port_list, list) { | 212 | list_for_each_entry(p, &br->port_list, list) |
212 | br_netpoll_disable(p); | 213 | br_netpoll_disable(p); |
213 | } | ||
214 | } | 214 | } |
215 | 215 | ||
216 | static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni) | 216 | static int br_netpoll_setup(struct net_device *dev, struct netpoll_info *ni, |
217 | gfp_t gfp) | ||
217 | { | 218 | { |
218 | struct net_bridge *br = netdev_priv(dev); | 219 | struct net_bridge *br = netdev_priv(dev); |
219 | struct net_bridge_port *p, *n; | 220 | struct net_bridge_port *p; |
220 | int err = 0; | 221 | int err = 0; |
221 | 222 | ||
222 | list_for_each_entry_safe(p, n, &br->port_list, list) { | 223 | list_for_each_entry(p, &br->port_list, list) { |
223 | if (!p->dev) | 224 | if (!p->dev) |
224 | continue; | 225 | continue; |
225 | 226 | err = br_netpoll_enable(p, gfp); | |
226 | err = br_netpoll_enable(p); | ||
227 | if (err) | 227 | if (err) |
228 | goto fail; | 228 | goto fail; |
229 | } | 229 | } |
@@ -236,17 +236,17 @@ fail: | |||
236 | goto out; | 236 | goto out; |
237 | } | 237 | } |
238 | 238 | ||
239 | int br_netpoll_enable(struct net_bridge_port *p) | 239 | int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp) |
240 | { | 240 | { |
241 | struct netpoll *np; | 241 | struct netpoll *np; |
242 | int err = 0; | 242 | int err = 0; |
243 | 243 | ||
244 | np = kzalloc(sizeof(*p->np), GFP_KERNEL); | 244 | np = kzalloc(sizeof(*p->np), gfp); |
245 | err = -ENOMEM; | 245 | err = -ENOMEM; |
246 | if (!np) | 246 | if (!np) |
247 | goto out; | 247 | goto out; |
248 | 248 | ||
249 | err = __netpoll_setup(np, p->dev); | 249 | err = __netpoll_setup(np, p->dev, gfp); |
250 | if (err) { | 250 | if (err) { |
251 | kfree(np); | 251 | kfree(np); |
252 | goto out; | 252 | goto out; |
@@ -267,11 +267,7 @@ void br_netpoll_disable(struct net_bridge_port *p) | |||
267 | 267 | ||
268 | p->np = NULL; | 268 | p->np = NULL; |
269 | 269 | ||
270 | /* Wait for transmitting packets to finish before freeing. */ | 270 | __netpoll_free_rcu(np); |
271 | synchronize_rcu_bh(); | ||
272 | |||
273 | __netpoll_cleanup(np); | ||
274 | kfree(np); | ||
275 | } | 271 | } |
276 | 272 | ||
277 | #endif | 273 | #endif |
diff --git a/net/bridge/br_forward.c b/net/bridge/br_forward.c index e9466d412707..02015a505d2a 100644 --- a/net/bridge/br_forward.c +++ b/net/bridge/br_forward.c | |||
@@ -65,7 +65,7 @@ static void __br_deliver(const struct net_bridge_port *to, struct sk_buff *skb) | |||
65 | { | 65 | { |
66 | skb->dev = to->dev; | 66 | skb->dev = to->dev; |
67 | 67 | ||
68 | if (unlikely(netpoll_tx_running(to->dev))) { | 68 | if (unlikely(netpoll_tx_running(to->br->dev))) { |
69 | if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb)) | 69 | if (packet_length(skb) > skb->dev->mtu && !skb_is_gso(skb)) |
70 | kfree_skb(skb); | 70 | kfree_skb(skb); |
71 | else { | 71 | else { |
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c index e1144e1617be..1c8fdc3558cd 100644 --- a/net/bridge/br_if.c +++ b/net/bridge/br_if.c | |||
@@ -361,7 +361,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev) | |||
361 | if (err) | 361 | if (err) |
362 | goto err2; | 362 | goto err2; |
363 | 363 | ||
364 | if (br_netpoll_info(br) && ((err = br_netpoll_enable(p)))) | 364 | if (br_netpoll_info(br) && ((err = br_netpoll_enable(p, GFP_KERNEL)))) |
365 | goto err3; | 365 | goto err3; |
366 | 366 | ||
367 | err = netdev_set_master(dev, br->dev); | 367 | err = netdev_set_master(dev, br->dev); |
@@ -427,6 +427,10 @@ int br_del_if(struct net_bridge *br, struct net_device *dev) | |||
427 | if (!p || p->br != br) | 427 | if (!p || p->br != br) |
428 | return -EINVAL; | 428 | return -EINVAL; |
429 | 429 | ||
430 | /* Since more than one interface can be attached to a bridge, | ||
431 | * there still maybe an alternate path for netconsole to use; | ||
432 | * therefore there is no reason for a NETDEV_RELEASE event. | ||
433 | */ | ||
430 | del_nbp(p); | 434 | del_nbp(p); |
431 | 435 | ||
432 | spin_lock_bh(&br->lock); | 436 | spin_lock_bh(&br->lock); |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index a768b2408edf..f507d2af9646 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -316,7 +316,7 @@ static inline void br_netpoll_send_skb(const struct net_bridge_port *p, | |||
316 | netpoll_send_skb(np, skb); | 316 | netpoll_send_skb(np, skb); |
317 | } | 317 | } |
318 | 318 | ||
319 | extern int br_netpoll_enable(struct net_bridge_port *p); | 319 | extern int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp); |
320 | extern void br_netpoll_disable(struct net_bridge_port *p); | 320 | extern void br_netpoll_disable(struct net_bridge_port *p); |
321 | #else | 321 | #else |
322 | static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br) | 322 | static inline struct netpoll_info *br_netpoll_info(struct net_bridge *br) |
@@ -329,7 +329,7 @@ static inline void br_netpoll_send_skb(const struct net_bridge_port *p, | |||
329 | { | 329 | { |
330 | } | 330 | } |
331 | 331 | ||
332 | static inline int br_netpoll_enable(struct net_bridge_port *p) | 332 | static inline int br_netpoll_enable(struct net_bridge_port *p, gfp_t gfp) |
333 | { | 333 | { |
334 | return 0; | 334 | return 0; |
335 | } | 335 | } |
diff --git a/net/caif/chnl_net.c b/net/caif/chnl_net.c index 69771c04ba8f..e597733affb8 100644 --- a/net/caif/chnl_net.c +++ b/net/caif/chnl_net.c | |||
@@ -94,6 +94,10 @@ static int chnl_recv_cb(struct cflayer *layr, struct cfpkt *pkt) | |||
94 | 94 | ||
95 | /* check the version of IP */ | 95 | /* check the version of IP */ |
96 | ip_version = skb_header_pointer(skb, 0, 1, &buf); | 96 | ip_version = skb_header_pointer(skb, 0, 1, &buf); |
97 | if (!ip_version) { | ||
98 | kfree_skb(skb); | ||
99 | return -EINVAL; | ||
100 | } | ||
97 | 101 | ||
98 | switch (*ip_version >> 4) { | 102 | switch (*ip_version >> 4) { |
99 | case 4: | 103 | case 4: |
diff --git a/net/ceph/crypto.c b/net/ceph/crypto.c index b780cb7947dd..9da7fdd3cd8a 100644 --- a/net/ceph/crypto.c +++ b/net/ceph/crypto.c | |||
@@ -466,6 +466,7 @@ void ceph_key_destroy(struct key *key) { | |||
466 | struct ceph_crypto_key *ckey = key->payload.data; | 466 | struct ceph_crypto_key *ckey = key->payload.data; |
467 | 467 | ||
468 | ceph_crypto_key_destroy(ckey); | 468 | ceph_crypto_key_destroy(ckey); |
469 | kfree(ckey); | ||
469 | } | 470 | } |
470 | 471 | ||
471 | struct key_type key_type_ceph = { | 472 | struct key_type key_type_ceph = { |
diff --git a/net/ceph/crypto.h b/net/ceph/crypto.h index 1919d1550d75..3572dc518bc9 100644 --- a/net/ceph/crypto.h +++ b/net/ceph/crypto.h | |||
@@ -16,7 +16,8 @@ struct ceph_crypto_key { | |||
16 | 16 | ||
17 | static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key) | 17 | static inline void ceph_crypto_key_destroy(struct ceph_crypto_key *key) |
18 | { | 18 | { |
19 | kfree(key->key); | 19 | if (key) |
20 | kfree(key->key); | ||
20 | } | 21 | } |
21 | 22 | ||
22 | extern int ceph_crypto_key_clone(struct ceph_crypto_key *dst, | 23 | extern int ceph_crypto_key_clone(struct ceph_crypto_key *dst, |
diff --git a/net/core/dev.c b/net/core/dev.c index ce1bccb08de5..088923fe4066 100644 --- a/net/core/dev.c +++ b/net/core/dev.c | |||
@@ -1055,6 +1055,8 @@ rollback: | |||
1055 | */ | 1055 | */ |
1056 | int dev_set_alias(struct net_device *dev, const char *alias, size_t len) | 1056 | int dev_set_alias(struct net_device *dev, const char *alias, size_t len) |
1057 | { | 1057 | { |
1058 | char *new_ifalias; | ||
1059 | |||
1058 | ASSERT_RTNL(); | 1060 | ASSERT_RTNL(); |
1059 | 1061 | ||
1060 | if (len >= IFALIASZ) | 1062 | if (len >= IFALIASZ) |
@@ -1068,9 +1070,10 @@ int dev_set_alias(struct net_device *dev, const char *alias, size_t len) | |||
1068 | return 0; | 1070 | return 0; |
1069 | } | 1071 | } |
1070 | 1072 | ||
1071 | dev->ifalias = krealloc(dev->ifalias, len + 1, GFP_KERNEL); | 1073 | new_ifalias = krealloc(dev->ifalias, len + 1, GFP_KERNEL); |
1072 | if (!dev->ifalias) | 1074 | if (!new_ifalias) |
1073 | return -ENOMEM; | 1075 | return -ENOMEM; |
1076 | dev->ifalias = new_ifalias; | ||
1074 | 1077 | ||
1075 | strlcpy(dev->ifalias, alias, len+1); | 1078 | strlcpy(dev->ifalias, alias, len+1); |
1076 | return len; | 1079 | return len; |
@@ -1651,6 +1654,19 @@ static inline int deliver_skb(struct sk_buff *skb, | |||
1651 | return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); | 1654 | return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); |
1652 | } | 1655 | } |
1653 | 1656 | ||
1657 | static inline bool skb_loop_sk(struct packet_type *ptype, struct sk_buff *skb) | ||
1658 | { | ||
1659 | if (ptype->af_packet_priv == NULL) | ||
1660 | return false; | ||
1661 | |||
1662 | if (ptype->id_match) | ||
1663 | return ptype->id_match(ptype, skb->sk); | ||
1664 | else if ((struct sock *)ptype->af_packet_priv == skb->sk) | ||
1665 | return true; | ||
1666 | |||
1667 | return false; | ||
1668 | } | ||
1669 | |||
1654 | /* | 1670 | /* |
1655 | * Support routine. Sends outgoing frames to any network | 1671 | * Support routine. Sends outgoing frames to any network |
1656 | * taps currently in use. | 1672 | * taps currently in use. |
@@ -1668,8 +1684,7 @@ static void dev_queue_xmit_nit(struct sk_buff *skb, struct net_device *dev) | |||
1668 | * they originated from - MvS (miquels@drinkel.ow.org) | 1684 | * they originated from - MvS (miquels@drinkel.ow.org) |
1669 | */ | 1685 | */ |
1670 | if ((ptype->dev == dev || !ptype->dev) && | 1686 | if ((ptype->dev == dev || !ptype->dev) && |
1671 | (ptype->af_packet_priv == NULL || | 1687 | (!skb_loop_sk(ptype, skb))) { |
1672 | (struct sock *)ptype->af_packet_priv != skb->sk)) { | ||
1673 | if (pt_prev) { | 1688 | if (pt_prev) { |
1674 | deliver_skb(skb2, pt_prev, skb->dev); | 1689 | deliver_skb(skb2, pt_prev, skb->dev); |
1675 | pt_prev = ptype; | 1690 | pt_prev = ptype; |
@@ -5746,6 +5761,7 @@ EXPORT_SYMBOL(netdev_refcnt_read); | |||
5746 | 5761 | ||
5747 | /** | 5762 | /** |
5748 | * netdev_wait_allrefs - wait until all references are gone. | 5763 | * netdev_wait_allrefs - wait until all references are gone. |
5764 | * @dev: target net_device | ||
5749 | * | 5765 | * |
5750 | * This is called when unregistering network devices. | 5766 | * This is called when unregistering network devices. |
5751 | * | 5767 | * |
diff --git a/net/core/dst.c b/net/core/dst.c index 069d51d29414..56d63612e1e4 100644 --- a/net/core/dst.c +++ b/net/core/dst.c | |||
@@ -149,7 +149,15 @@ int dst_discard(struct sk_buff *skb) | |||
149 | } | 149 | } |
150 | EXPORT_SYMBOL(dst_discard); | 150 | EXPORT_SYMBOL(dst_discard); |
151 | 151 | ||
152 | const u32 dst_default_metrics[RTAX_MAX]; | 152 | const u32 dst_default_metrics[RTAX_MAX + 1] = { |
153 | /* This initializer is needed to force linker to place this variable | ||
154 | * into const section. Otherwise it might end into bss section. | ||
155 | * We really want to avoid false sharing on this variable, and catch | ||
156 | * any writes on it. | ||
157 | */ | ||
158 | [RTAX_MAX] = 0xdeadbeef, | ||
159 | }; | ||
160 | |||
153 | 161 | ||
154 | void *dst_alloc(struct dst_ops *ops, struct net_device *dev, | 162 | void *dst_alloc(struct dst_ops *ops, struct net_device *dev, |
155 | int initial_ref, int initial_obsolete, unsigned short flags) | 163 | int initial_ref, int initial_obsolete, unsigned short flags) |
diff --git a/net/core/netpoll.c b/net/core/netpoll.c index b4c90e42b443..346b1eb83a1f 100644 --- a/net/core/netpoll.c +++ b/net/core/netpoll.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/workqueue.h> | 26 | #include <linux/workqueue.h> |
27 | #include <linux/slab.h> | 27 | #include <linux/slab.h> |
28 | #include <linux/export.h> | 28 | #include <linux/export.h> |
29 | #include <linux/if_vlan.h> | ||
29 | #include <net/tcp.h> | 30 | #include <net/tcp.h> |
30 | #include <net/udp.h> | 31 | #include <net/udp.h> |
31 | #include <asm/unaligned.h> | 32 | #include <asm/unaligned.h> |
@@ -54,7 +55,7 @@ static atomic_t trapped; | |||
54 | MAX_UDP_CHUNK) | 55 | MAX_UDP_CHUNK) |
55 | 56 | ||
56 | static void zap_completion_queue(void); | 57 | static void zap_completion_queue(void); |
57 | static void arp_reply(struct sk_buff *skb); | 58 | static void netpoll_arp_reply(struct sk_buff *skb, struct netpoll_info *npinfo); |
58 | 59 | ||
59 | static unsigned int carrier_timeout = 4; | 60 | static unsigned int carrier_timeout = 4; |
60 | module_param(carrier_timeout, uint, 0644); | 61 | module_param(carrier_timeout, uint, 0644); |
@@ -167,15 +168,24 @@ static void poll_napi(struct net_device *dev) | |||
167 | struct napi_struct *napi; | 168 | struct napi_struct *napi; |
168 | int budget = 16; | 169 | int budget = 16; |
169 | 170 | ||
171 | WARN_ON_ONCE(!irqs_disabled()); | ||
172 | |||
170 | list_for_each_entry(napi, &dev->napi_list, dev_list) { | 173 | list_for_each_entry(napi, &dev->napi_list, dev_list) { |
174 | local_irq_enable(); | ||
171 | if (napi->poll_owner != smp_processor_id() && | 175 | if (napi->poll_owner != smp_processor_id() && |
172 | spin_trylock(&napi->poll_lock)) { | 176 | spin_trylock(&napi->poll_lock)) { |
173 | budget = poll_one_napi(dev->npinfo, napi, budget); | 177 | rcu_read_lock_bh(); |
178 | budget = poll_one_napi(rcu_dereference_bh(dev->npinfo), | ||
179 | napi, budget); | ||
180 | rcu_read_unlock_bh(); | ||
174 | spin_unlock(&napi->poll_lock); | 181 | spin_unlock(&napi->poll_lock); |
175 | 182 | ||
176 | if (!budget) | 183 | if (!budget) { |
184 | local_irq_disable(); | ||
177 | break; | 185 | break; |
186 | } | ||
178 | } | 187 | } |
188 | local_irq_disable(); | ||
179 | } | 189 | } |
180 | } | 190 | } |
181 | 191 | ||
@@ -185,13 +195,14 @@ static void service_arp_queue(struct netpoll_info *npi) | |||
185 | struct sk_buff *skb; | 195 | struct sk_buff *skb; |
186 | 196 | ||
187 | while ((skb = skb_dequeue(&npi->arp_tx))) | 197 | while ((skb = skb_dequeue(&npi->arp_tx))) |
188 | arp_reply(skb); | 198 | netpoll_arp_reply(skb, npi); |
189 | } | 199 | } |
190 | } | 200 | } |
191 | 201 | ||
192 | static void netpoll_poll_dev(struct net_device *dev) | 202 | static void netpoll_poll_dev(struct net_device *dev) |
193 | { | 203 | { |
194 | const struct net_device_ops *ops; | 204 | const struct net_device_ops *ops; |
205 | struct netpoll_info *ni = rcu_dereference_bh(dev->npinfo); | ||
195 | 206 | ||
196 | if (!dev || !netif_running(dev)) | 207 | if (!dev || !netif_running(dev)) |
197 | return; | 208 | return; |
@@ -206,17 +217,18 @@ static void netpoll_poll_dev(struct net_device *dev) | |||
206 | poll_napi(dev); | 217 | poll_napi(dev); |
207 | 218 | ||
208 | if (dev->flags & IFF_SLAVE) { | 219 | if (dev->flags & IFF_SLAVE) { |
209 | if (dev->npinfo) { | 220 | if (ni) { |
210 | struct net_device *bond_dev = dev->master; | 221 | struct net_device *bond_dev = dev->master; |
211 | struct sk_buff *skb; | 222 | struct sk_buff *skb; |
212 | while ((skb = skb_dequeue(&dev->npinfo->arp_tx))) { | 223 | struct netpoll_info *bond_ni = rcu_dereference_bh(bond_dev->npinfo); |
224 | while ((skb = skb_dequeue(&ni->arp_tx))) { | ||
213 | skb->dev = bond_dev; | 225 | skb->dev = bond_dev; |
214 | skb_queue_tail(&bond_dev->npinfo->arp_tx, skb); | 226 | skb_queue_tail(&bond_ni->arp_tx, skb); |
215 | } | 227 | } |
216 | } | 228 | } |
217 | } | 229 | } |
218 | 230 | ||
219 | service_arp_queue(dev->npinfo); | 231 | service_arp_queue(ni); |
220 | 232 | ||
221 | zap_completion_queue(); | 233 | zap_completion_queue(); |
222 | } | 234 | } |
@@ -302,6 +314,7 @@ static int netpoll_owner_active(struct net_device *dev) | |||
302 | return 0; | 314 | return 0; |
303 | } | 315 | } |
304 | 316 | ||
317 | /* call with IRQ disabled */ | ||
305 | void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, | 318 | void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, |
306 | struct net_device *dev) | 319 | struct net_device *dev) |
307 | { | 320 | { |
@@ -309,8 +322,11 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, | |||
309 | unsigned long tries; | 322 | unsigned long tries; |
310 | const struct net_device_ops *ops = dev->netdev_ops; | 323 | const struct net_device_ops *ops = dev->netdev_ops; |
311 | /* It is up to the caller to keep npinfo alive. */ | 324 | /* It is up to the caller to keep npinfo alive. */ |
312 | struct netpoll_info *npinfo = np->dev->npinfo; | 325 | struct netpoll_info *npinfo; |
326 | |||
327 | WARN_ON_ONCE(!irqs_disabled()); | ||
313 | 328 | ||
329 | npinfo = rcu_dereference_bh(np->dev->npinfo); | ||
314 | if (!npinfo || !netif_running(dev) || !netif_device_present(dev)) { | 330 | if (!npinfo || !netif_running(dev) || !netif_device_present(dev)) { |
315 | __kfree_skb(skb); | 331 | __kfree_skb(skb); |
316 | return; | 332 | return; |
@@ -319,16 +335,22 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, | |||
319 | /* don't get messages out of order, and no recursion */ | 335 | /* don't get messages out of order, and no recursion */ |
320 | if (skb_queue_len(&npinfo->txq) == 0 && !netpoll_owner_active(dev)) { | 336 | if (skb_queue_len(&npinfo->txq) == 0 && !netpoll_owner_active(dev)) { |
321 | struct netdev_queue *txq; | 337 | struct netdev_queue *txq; |
322 | unsigned long flags; | ||
323 | 338 | ||
324 | txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); | 339 | txq = netdev_get_tx_queue(dev, skb_get_queue_mapping(skb)); |
325 | 340 | ||
326 | local_irq_save(flags); | ||
327 | /* try until next clock tick */ | 341 | /* try until next clock tick */ |
328 | for (tries = jiffies_to_usecs(1)/USEC_PER_POLL; | 342 | for (tries = jiffies_to_usecs(1)/USEC_PER_POLL; |
329 | tries > 0; --tries) { | 343 | tries > 0; --tries) { |
330 | if (__netif_tx_trylock(txq)) { | 344 | if (__netif_tx_trylock(txq)) { |
331 | if (!netif_xmit_stopped(txq)) { | 345 | if (!netif_xmit_stopped(txq)) { |
346 | if (vlan_tx_tag_present(skb) && | ||
347 | !(netif_skb_features(skb) & NETIF_F_HW_VLAN_TX)) { | ||
348 | skb = __vlan_put_tag(skb, vlan_tx_tag_get(skb)); | ||
349 | if (unlikely(!skb)) | ||
350 | break; | ||
351 | skb->vlan_tci = 0; | ||
352 | } | ||
353 | |||
332 | status = ops->ndo_start_xmit(skb, dev); | 354 | status = ops->ndo_start_xmit(skb, dev); |
333 | if (status == NETDEV_TX_OK) | 355 | if (status == NETDEV_TX_OK) |
334 | txq_trans_update(txq); | 356 | txq_trans_update(txq); |
@@ -347,10 +369,9 @@ void netpoll_send_skb_on_dev(struct netpoll *np, struct sk_buff *skb, | |||
347 | } | 369 | } |
348 | 370 | ||
349 | WARN_ONCE(!irqs_disabled(), | 371 | WARN_ONCE(!irqs_disabled(), |
350 | "netpoll_send_skb(): %s enabled interrupts in poll (%pF)\n", | 372 | "netpoll_send_skb_on_dev(): %s enabled interrupts in poll (%pF)\n", |
351 | dev->name, ops->ndo_start_xmit); | 373 | dev->name, ops->ndo_start_xmit); |
352 | 374 | ||
353 | local_irq_restore(flags); | ||
354 | } | 375 | } |
355 | 376 | ||
356 | if (status != NETDEV_TX_OK) { | 377 | if (status != NETDEV_TX_OK) { |
@@ -423,9 +444,8 @@ void netpoll_send_udp(struct netpoll *np, const char *msg, int len) | |||
423 | } | 444 | } |
424 | EXPORT_SYMBOL(netpoll_send_udp); | 445 | EXPORT_SYMBOL(netpoll_send_udp); |
425 | 446 | ||
426 | static void arp_reply(struct sk_buff *skb) | 447 | static void netpoll_arp_reply(struct sk_buff *skb, struct netpoll_info *npinfo) |
427 | { | 448 | { |
428 | struct netpoll_info *npinfo = skb->dev->npinfo; | ||
429 | struct arphdr *arp; | 449 | struct arphdr *arp; |
430 | unsigned char *arp_ptr; | 450 | unsigned char *arp_ptr; |
431 | int size, type = ARPOP_REPLY, ptype = ETH_P_ARP; | 451 | int size, type = ARPOP_REPLY, ptype = ETH_P_ARP; |
@@ -543,13 +563,12 @@ static void arp_reply(struct sk_buff *skb) | |||
543 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); | 563 | spin_unlock_irqrestore(&npinfo->rx_lock, flags); |
544 | } | 564 | } |
545 | 565 | ||
546 | int __netpoll_rx(struct sk_buff *skb) | 566 | int __netpoll_rx(struct sk_buff *skb, struct netpoll_info *npinfo) |
547 | { | 567 | { |
548 | int proto, len, ulen; | 568 | int proto, len, ulen; |
549 | int hits = 0; | 569 | int hits = 0; |
550 | const struct iphdr *iph; | 570 | const struct iphdr *iph; |
551 | struct udphdr *uh; | 571 | struct udphdr *uh; |
552 | struct netpoll_info *npinfo = skb->dev->npinfo; | ||
553 | struct netpoll *np, *tmp; | 572 | struct netpoll *np, *tmp; |
554 | 573 | ||
555 | if (list_empty(&npinfo->rx_np)) | 574 | if (list_empty(&npinfo->rx_np)) |
@@ -565,6 +584,12 @@ int __netpoll_rx(struct sk_buff *skb) | |||
565 | return 1; | 584 | return 1; |
566 | } | 585 | } |
567 | 586 | ||
587 | if (skb->protocol == cpu_to_be16(ETH_P_8021Q)) { | ||
588 | skb = vlan_untag(skb); | ||
589 | if (unlikely(!skb)) | ||
590 | goto out; | ||
591 | } | ||
592 | |||
568 | proto = ntohs(eth_hdr(skb)->h_proto); | 593 | proto = ntohs(eth_hdr(skb)->h_proto); |
569 | if (proto != ETH_P_IP) | 594 | if (proto != ETH_P_IP) |
570 | goto out; | 595 | goto out; |
@@ -715,7 +740,7 @@ int netpoll_parse_options(struct netpoll *np, char *opt) | |||
715 | } | 740 | } |
716 | EXPORT_SYMBOL(netpoll_parse_options); | 741 | EXPORT_SYMBOL(netpoll_parse_options); |
717 | 742 | ||
718 | int __netpoll_setup(struct netpoll *np, struct net_device *ndev) | 743 | int __netpoll_setup(struct netpoll *np, struct net_device *ndev, gfp_t gfp) |
719 | { | 744 | { |
720 | struct netpoll_info *npinfo; | 745 | struct netpoll_info *npinfo; |
721 | const struct net_device_ops *ops; | 746 | const struct net_device_ops *ops; |
@@ -734,7 +759,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev) | |||
734 | } | 759 | } |
735 | 760 | ||
736 | if (!ndev->npinfo) { | 761 | if (!ndev->npinfo) { |
737 | npinfo = kmalloc(sizeof(*npinfo), GFP_KERNEL); | 762 | npinfo = kmalloc(sizeof(*npinfo), gfp); |
738 | if (!npinfo) { | 763 | if (!npinfo) { |
739 | err = -ENOMEM; | 764 | err = -ENOMEM; |
740 | goto out; | 765 | goto out; |
@@ -752,7 +777,7 @@ int __netpoll_setup(struct netpoll *np, struct net_device *ndev) | |||
752 | 777 | ||
753 | ops = np->dev->netdev_ops; | 778 | ops = np->dev->netdev_ops; |
754 | if (ops->ndo_netpoll_setup) { | 779 | if (ops->ndo_netpoll_setup) { |
755 | err = ops->ndo_netpoll_setup(ndev, npinfo); | 780 | err = ops->ndo_netpoll_setup(ndev, npinfo, gfp); |
756 | if (err) | 781 | if (err) |
757 | goto free_npinfo; | 782 | goto free_npinfo; |
758 | } | 783 | } |
@@ -857,7 +882,7 @@ int netpoll_setup(struct netpoll *np) | |||
857 | refill_skbs(); | 882 | refill_skbs(); |
858 | 883 | ||
859 | rtnl_lock(); | 884 | rtnl_lock(); |
860 | err = __netpoll_setup(np, ndev); | 885 | err = __netpoll_setup(np, ndev, GFP_KERNEL); |
861 | rtnl_unlock(); | 886 | rtnl_unlock(); |
862 | 887 | ||
863 | if (err) | 888 | if (err) |
@@ -878,6 +903,24 @@ static int __init netpoll_init(void) | |||
878 | } | 903 | } |
879 | core_initcall(netpoll_init); | 904 | core_initcall(netpoll_init); |
880 | 905 | ||
906 | static void rcu_cleanup_netpoll_info(struct rcu_head *rcu_head) | ||
907 | { | ||
908 | struct netpoll_info *npinfo = | ||
909 | container_of(rcu_head, struct netpoll_info, rcu); | ||
910 | |||
911 | skb_queue_purge(&npinfo->arp_tx); | ||
912 | skb_queue_purge(&npinfo->txq); | ||
913 | |||
914 | /* we can't call cancel_delayed_work_sync here, as we are in softirq */ | ||
915 | cancel_delayed_work(&npinfo->tx_work); | ||
916 | |||
917 | /* clean after last, unfinished work */ | ||
918 | __skb_queue_purge(&npinfo->txq); | ||
919 | /* now cancel it again */ | ||
920 | cancel_delayed_work(&npinfo->tx_work); | ||
921 | kfree(npinfo); | ||
922 | } | ||
923 | |||
881 | void __netpoll_cleanup(struct netpoll *np) | 924 | void __netpoll_cleanup(struct netpoll *np) |
882 | { | 925 | { |
883 | struct netpoll_info *npinfo; | 926 | struct netpoll_info *npinfo; |
@@ -903,20 +946,24 @@ void __netpoll_cleanup(struct netpoll *np) | |||
903 | ops->ndo_netpoll_cleanup(np->dev); | 946 | ops->ndo_netpoll_cleanup(np->dev); |
904 | 947 | ||
905 | RCU_INIT_POINTER(np->dev->npinfo, NULL); | 948 | RCU_INIT_POINTER(np->dev->npinfo, NULL); |
949 | call_rcu_bh(&npinfo->rcu, rcu_cleanup_netpoll_info); | ||
950 | } | ||
951 | } | ||
952 | EXPORT_SYMBOL_GPL(__netpoll_cleanup); | ||
906 | 953 | ||
907 | /* avoid racing with NAPI reading npinfo */ | 954 | static void rcu_cleanup_netpoll(struct rcu_head *rcu_head) |
908 | synchronize_rcu_bh(); | 955 | { |
956 | struct netpoll *np = container_of(rcu_head, struct netpoll, rcu); | ||
909 | 957 | ||
910 | skb_queue_purge(&npinfo->arp_tx); | 958 | __netpoll_cleanup(np); |
911 | skb_queue_purge(&npinfo->txq); | 959 | kfree(np); |
912 | cancel_delayed_work_sync(&npinfo->tx_work); | 960 | } |
913 | 961 | ||
914 | /* clean after last, unfinished work */ | 962 | void __netpoll_free_rcu(struct netpoll *np) |
915 | __skb_queue_purge(&npinfo->txq); | 963 | { |
916 | kfree(npinfo); | 964 | call_rcu_bh(&np->rcu, rcu_cleanup_netpoll); |
917 | } | ||
918 | } | 965 | } |
919 | EXPORT_SYMBOL_GPL(__netpoll_cleanup); | 966 | EXPORT_SYMBOL_GPL(__netpoll_free_rcu); |
920 | 967 | ||
921 | void netpoll_cleanup(struct netpoll *np) | 968 | void netpoll_cleanup(struct netpoll *np) |
922 | { | 969 | { |
diff --git a/net/core/netprio_cgroup.c b/net/core/netprio_cgroup.c index ed0c0431fcd8..c75e3f9d060f 100644 --- a/net/core/netprio_cgroup.c +++ b/net/core/netprio_cgroup.c | |||
@@ -101,12 +101,10 @@ static int write_update_netdev_table(struct net_device *dev) | |||
101 | u32 max_len; | 101 | u32 max_len; |
102 | struct netprio_map *map; | 102 | struct netprio_map *map; |
103 | 103 | ||
104 | rtnl_lock(); | ||
105 | max_len = atomic_read(&max_prioidx) + 1; | 104 | max_len = atomic_read(&max_prioidx) + 1; |
106 | map = rtnl_dereference(dev->priomap); | 105 | map = rtnl_dereference(dev->priomap); |
107 | if (!map || map->priomap_len < max_len) | 106 | if (!map || map->priomap_len < max_len) |
108 | ret = extend_netdev_table(dev, max_len); | 107 | ret = extend_netdev_table(dev, max_len); |
109 | rtnl_unlock(); | ||
110 | 108 | ||
111 | return ret; | 109 | return ret; |
112 | } | 110 | } |
@@ -256,17 +254,17 @@ static int write_priomap(struct cgroup *cgrp, struct cftype *cft, | |||
256 | if (!dev) | 254 | if (!dev) |
257 | goto out_free_devname; | 255 | goto out_free_devname; |
258 | 256 | ||
257 | rtnl_lock(); | ||
259 | ret = write_update_netdev_table(dev); | 258 | ret = write_update_netdev_table(dev); |
260 | if (ret < 0) | 259 | if (ret < 0) |
261 | goto out_put_dev; | 260 | goto out_put_dev; |
262 | 261 | ||
263 | rcu_read_lock(); | 262 | map = rtnl_dereference(dev->priomap); |
264 | map = rcu_dereference(dev->priomap); | ||
265 | if (map) | 263 | if (map) |
266 | map->priomap[prioidx] = priority; | 264 | map->priomap[prioidx] = priority; |
267 | rcu_read_unlock(); | ||
268 | 265 | ||
269 | out_put_dev: | 266 | out_put_dev: |
267 | rtnl_unlock(); | ||
270 | dev_put(dev); | 268 | dev_put(dev); |
271 | 269 | ||
272 | out_free_devname: | 270 | out_free_devname: |
@@ -277,12 +275,6 @@ out_free_devname: | |||
277 | void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) | 275 | void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) |
278 | { | 276 | { |
279 | struct task_struct *p; | 277 | struct task_struct *p; |
280 | char *tmp = kzalloc(sizeof(char) * PATH_MAX, GFP_KERNEL); | ||
281 | |||
282 | if (!tmp) { | ||
283 | pr_warn("Unable to attach cgrp due to alloc failure!\n"); | ||
284 | return; | ||
285 | } | ||
286 | 278 | ||
287 | cgroup_taskset_for_each(p, cgrp, tset) { | 279 | cgroup_taskset_for_each(p, cgrp, tset) { |
288 | unsigned int fd; | 280 | unsigned int fd; |
@@ -296,32 +288,24 @@ void net_prio_attach(struct cgroup *cgrp, struct cgroup_taskset *tset) | |||
296 | continue; | 288 | continue; |
297 | } | 289 | } |
298 | 290 | ||
299 | rcu_read_lock(); | 291 | spin_lock(&files->file_lock); |
300 | fdt = files_fdtable(files); | 292 | fdt = files_fdtable(files); |
301 | for (fd = 0; fd < fdt->max_fds; fd++) { | 293 | for (fd = 0; fd < fdt->max_fds; fd++) { |
302 | char *path; | ||
303 | struct file *file; | 294 | struct file *file; |
304 | struct socket *sock; | 295 | struct socket *sock; |
305 | unsigned long s; | 296 | int err; |
306 | int rv, err = 0; | ||
307 | 297 | ||
308 | file = fcheck_files(files, fd); | 298 | file = fcheck_files(files, fd); |
309 | if (!file) | 299 | if (!file) |
310 | continue; | 300 | continue; |
311 | 301 | ||
312 | path = d_path(&file->f_path, tmp, PAGE_SIZE); | ||
313 | rv = sscanf(path, "socket:[%lu]", &s); | ||
314 | if (rv <= 0) | ||
315 | continue; | ||
316 | |||
317 | sock = sock_from_file(file, &err); | 302 | sock = sock_from_file(file, &err); |
318 | if (!err) | 303 | if (sock) |
319 | sock_update_netprioidx(sock->sk, p); | 304 | sock_update_netprioidx(sock->sk, p); |
320 | } | 305 | } |
321 | rcu_read_unlock(); | 306 | spin_unlock(&files->file_lock); |
322 | task_unlock(p); | 307 | task_unlock(p); |
323 | } | 308 | } |
324 | kfree(tmp); | ||
325 | } | 309 | } |
326 | 310 | ||
327 | static struct cftype ss_files[] = { | 311 | static struct cftype ss_files[] = { |
diff --git a/net/core/scm.c b/net/core/scm.c index 8f6ccfd68ef4..040cebeed45b 100644 --- a/net/core/scm.c +++ b/net/core/scm.c | |||
@@ -265,6 +265,7 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) | |||
265 | for (i=0, cmfptr=(__force int __user *)CMSG_DATA(cm); i<fdmax; | 265 | for (i=0, cmfptr=(__force int __user *)CMSG_DATA(cm); i<fdmax; |
266 | i++, cmfptr++) | 266 | i++, cmfptr++) |
267 | { | 267 | { |
268 | struct socket *sock; | ||
268 | int new_fd; | 269 | int new_fd; |
269 | err = security_file_receive(fp[i]); | 270 | err = security_file_receive(fp[i]); |
270 | if (err) | 271 | if (err) |
@@ -281,6 +282,9 @@ void scm_detach_fds(struct msghdr *msg, struct scm_cookie *scm) | |||
281 | } | 282 | } |
282 | /* Bump the usage count and install the file. */ | 283 | /* Bump the usage count and install the file. */ |
283 | get_file(fp[i]); | 284 | get_file(fp[i]); |
285 | sock = sock_from_file(fp[i], &err); | ||
286 | if (sock) | ||
287 | sock_update_netprioidx(sock->sk, current); | ||
284 | fd_install(new_fd, fp[i]); | 288 | fd_install(new_fd, fp[i]); |
285 | } | 289 | } |
286 | 290 | ||
diff --git a/net/dccp/ccid.h b/net/dccp/ccid.h index 75c3582a7678..fb85d371a8de 100644 --- a/net/dccp/ccid.h +++ b/net/dccp/ccid.h | |||
@@ -246,7 +246,7 @@ static inline int ccid_hc_rx_getsockopt(struct ccid *ccid, struct sock *sk, | |||
246 | u32 __user *optval, int __user *optlen) | 246 | u32 __user *optval, int __user *optlen) |
247 | { | 247 | { |
248 | int rc = -ENOPROTOOPT; | 248 | int rc = -ENOPROTOOPT; |
249 | if (ccid->ccid_ops->ccid_hc_rx_getsockopt != NULL) | 249 | if (ccid != NULL && ccid->ccid_ops->ccid_hc_rx_getsockopt != NULL) |
250 | rc = ccid->ccid_ops->ccid_hc_rx_getsockopt(sk, optname, len, | 250 | rc = ccid->ccid_ops->ccid_hc_rx_getsockopt(sk, optname, len, |
251 | optval, optlen); | 251 | optval, optlen); |
252 | return rc; | 252 | return rc; |
@@ -257,7 +257,7 @@ static inline int ccid_hc_tx_getsockopt(struct ccid *ccid, struct sock *sk, | |||
257 | u32 __user *optval, int __user *optlen) | 257 | u32 __user *optval, int __user *optlen) |
258 | { | 258 | { |
259 | int rc = -ENOPROTOOPT; | 259 | int rc = -ENOPROTOOPT; |
260 | if (ccid->ccid_ops->ccid_hc_tx_getsockopt != NULL) | 260 | if (ccid != NULL && ccid->ccid_ops->ccid_hc_tx_getsockopt != NULL) |
261 | rc = ccid->ccid_ops->ccid_hc_tx_getsockopt(sk, optname, len, | 261 | rc = ccid->ccid_ops->ccid_hc_tx_getsockopt(sk, optname, len, |
262 | optval, optlen); | 262 | optval, optlen); |
263 | return rc; | 263 | return rc; |
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c index d65e98798eca..119c04317d48 100644 --- a/net/dccp/ccids/ccid3.c +++ b/net/dccp/ccids/ccid3.c | |||
@@ -535,6 +535,7 @@ static int ccid3_hc_tx_getsockopt(struct sock *sk, const int optname, int len, | |||
535 | case DCCP_SOCKOPT_CCID_TX_INFO: | 535 | case DCCP_SOCKOPT_CCID_TX_INFO: |
536 | if (len < sizeof(tfrc)) | 536 | if (len < sizeof(tfrc)) |
537 | return -EINVAL; | 537 | return -EINVAL; |
538 | memset(&tfrc, 0, sizeof(tfrc)); | ||
538 | tfrc.tfrctx_x = hc->tx_x; | 539 | tfrc.tfrctx_x = hc->tx_x; |
539 | tfrc.tfrctx_x_recv = hc->tx_x_recv; | 540 | tfrc.tfrctx_x_recv = hc->tx_x_recv; |
540 | tfrc.tfrctx_x_calc = hc->tx_x_calc; | 541 | tfrc.tfrctx_x_calc = hc->tx_x_calc; |
diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 4587d344046d..3c820dae235e 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c | |||
@@ -367,7 +367,7 @@ static void __leaf_free_rcu(struct rcu_head *head) | |||
367 | 367 | ||
368 | static inline void free_leaf(struct leaf *l) | 368 | static inline void free_leaf(struct leaf *l) |
369 | { | 369 | { |
370 | call_rcu_bh(&l->rcu, __leaf_free_rcu); | 370 | call_rcu(&l->rcu, __leaf_free_rcu); |
371 | } | 371 | } |
372 | 372 | ||
373 | static inline void free_leaf_info(struct leaf_info *leaf) | 373 | static inline void free_leaf_info(struct leaf_info *leaf) |
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index db0cf17c00f7..7f75f21d7b83 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c | |||
@@ -404,12 +404,15 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk, | |||
404 | { | 404 | { |
405 | const struct inet_request_sock *ireq = inet_rsk(req); | 405 | const struct inet_request_sock *ireq = inet_rsk(req); |
406 | struct inet_sock *newinet = inet_sk(newsk); | 406 | struct inet_sock *newinet = inet_sk(newsk); |
407 | struct ip_options_rcu *opt = ireq->opt; | 407 | struct ip_options_rcu *opt; |
408 | struct net *net = sock_net(sk); | 408 | struct net *net = sock_net(sk); |
409 | struct flowi4 *fl4; | 409 | struct flowi4 *fl4; |
410 | struct rtable *rt; | 410 | struct rtable *rt; |
411 | 411 | ||
412 | fl4 = &newinet->cork.fl.u.ip4; | 412 | fl4 = &newinet->cork.fl.u.ip4; |
413 | |||
414 | rcu_read_lock(); | ||
415 | opt = rcu_dereference(newinet->inet_opt); | ||
413 | flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark, | 416 | flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark, |
414 | RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, | 417 | RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE, |
415 | sk->sk_protocol, inet_sk_flowi_flags(sk), | 418 | sk->sk_protocol, inet_sk_flowi_flags(sk), |
@@ -421,11 +424,13 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk, | |||
421 | goto no_route; | 424 | goto no_route; |
422 | if (opt && opt->opt.is_strictroute && rt->rt_gateway) | 425 | if (opt && opt->opt.is_strictroute && rt->rt_gateway) |
423 | goto route_err; | 426 | goto route_err; |
427 | rcu_read_unlock(); | ||
424 | return &rt->dst; | 428 | return &rt->dst; |
425 | 429 | ||
426 | route_err: | 430 | route_err: |
427 | ip_rt_put(rt); | 431 | ip_rt_put(rt); |
428 | no_route: | 432 | no_route: |
433 | rcu_read_unlock(); | ||
429 | IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); | 434 | IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); |
430 | return NULL; | 435 | return NULL; |
431 | } | 436 | } |
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c index ba39a52d18c1..c196d749daf2 100644 --- a/net/ipv4/ip_output.c +++ b/net/ipv4/ip_output.c | |||
@@ -197,7 +197,7 @@ static inline int ip_finish_output2(struct sk_buff *skb) | |||
197 | neigh = __ipv4_neigh_lookup_noref(dev, nexthop); | 197 | neigh = __ipv4_neigh_lookup_noref(dev, nexthop); |
198 | if (unlikely(!neigh)) | 198 | if (unlikely(!neigh)) |
199 | neigh = __neigh_create(&arp_tbl, &nexthop, dev, false); | 199 | neigh = __neigh_create(&arp_tbl, &nexthop, dev, false); |
200 | if (neigh) { | 200 | if (!IS_ERR(neigh)) { |
201 | int res = dst_neigh_output(dst, neigh, skb); | 201 | int res = dst_neigh_output(dst, neigh, skb); |
202 | 202 | ||
203 | rcu_read_unlock_bh(); | 203 | rcu_read_unlock_bh(); |
@@ -1338,10 +1338,10 @@ struct sk_buff *__ip_make_skb(struct sock *sk, | |||
1338 | iph->ihl = 5; | 1338 | iph->ihl = 5; |
1339 | iph->tos = inet->tos; | 1339 | iph->tos = inet->tos; |
1340 | iph->frag_off = df; | 1340 | iph->frag_off = df; |
1341 | ip_select_ident(iph, &rt->dst, sk); | ||
1342 | iph->ttl = ttl; | 1341 | iph->ttl = ttl; |
1343 | iph->protocol = sk->sk_protocol; | 1342 | iph->protocol = sk->sk_protocol; |
1344 | ip_copy_addrs(iph, fl4); | 1343 | ip_copy_addrs(iph, fl4); |
1344 | ip_select_ident(iph, &rt->dst, sk); | ||
1345 | 1345 | ||
1346 | if (opt) { | 1346 | if (opt) { |
1347 | iph->ihl += opt->optlen>>2; | 1347 | iph->ihl += opt->optlen>>2; |
@@ -1366,9 +1366,8 @@ out: | |||
1366 | return skb; | 1366 | return skb; |
1367 | } | 1367 | } |
1368 | 1368 | ||
1369 | int ip_send_skb(struct sk_buff *skb) | 1369 | int ip_send_skb(struct net *net, struct sk_buff *skb) |
1370 | { | 1370 | { |
1371 | struct net *net = sock_net(skb->sk); | ||
1372 | int err; | 1371 | int err; |
1373 | 1372 | ||
1374 | err = ip_local_out(skb); | 1373 | err = ip_local_out(skb); |
@@ -1391,7 +1390,7 @@ int ip_push_pending_frames(struct sock *sk, struct flowi4 *fl4) | |||
1391 | return 0; | 1390 | return 0; |
1392 | 1391 | ||
1393 | /* Netfilter gets whole the not fragmented skb. */ | 1392 | /* Netfilter gets whole the not fragmented skb. */ |
1394 | return ip_send_skb(skb); | 1393 | return ip_send_skb(sock_net(sk), skb); |
1395 | } | 1394 | } |
1396 | 1395 | ||
1397 | /* | 1396 | /* |
@@ -1536,6 +1535,7 @@ void ip_send_unicast_reply(struct net *net, struct sk_buff *skb, __be32 daddr, | |||
1536 | arg->csumoffset) = csum_fold(csum_add(nskb->csum, | 1535 | arg->csumoffset) = csum_fold(csum_add(nskb->csum, |
1537 | arg->csum)); | 1536 | arg->csum)); |
1538 | nskb->ip_summed = CHECKSUM_NONE; | 1537 | nskb->ip_summed = CHECKSUM_NONE; |
1538 | skb_orphan(nskb); | ||
1539 | skb_set_queue_mapping(nskb, skb_get_queue_mapping(skb)); | 1539 | skb_set_queue_mapping(nskb, skb_get_queue_mapping(skb)); |
1540 | ip_push_pending_frames(sk, &fl4); | 1540 | ip_push_pending_frames(sk, &fl4); |
1541 | } | 1541 | } |
diff --git a/net/ipv4/netfilter/nf_nat_sip.c b/net/ipv4/netfilter/nf_nat_sip.c index ea4a23813d26..4ad9cf173992 100644 --- a/net/ipv4/netfilter/nf_nat_sip.c +++ b/net/ipv4/netfilter/nf_nat_sip.c | |||
@@ -148,7 +148,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff, | |||
148 | if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, | 148 | if (ct_sip_parse_header_uri(ct, *dptr, NULL, *datalen, |
149 | hdr, NULL, &matchoff, &matchlen, | 149 | hdr, NULL, &matchoff, &matchlen, |
150 | &addr, &port) > 0) { | 150 | &addr, &port) > 0) { |
151 | unsigned int matchend, poff, plen, buflen, n; | 151 | unsigned int olen, matchend, poff, plen, buflen, n; |
152 | char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")]; | 152 | char buffer[sizeof("nnn.nnn.nnn.nnn:nnnnn")]; |
153 | 153 | ||
154 | /* We're only interested in headers related to this | 154 | /* We're only interested in headers related to this |
@@ -163,17 +163,18 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff, | |||
163 | goto next; | 163 | goto next; |
164 | } | 164 | } |
165 | 165 | ||
166 | olen = *datalen; | ||
166 | if (!map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen, | 167 | if (!map_addr(skb, dataoff, dptr, datalen, matchoff, matchlen, |
167 | &addr, port)) | 168 | &addr, port)) |
168 | return NF_DROP; | 169 | return NF_DROP; |
169 | 170 | ||
170 | matchend = matchoff + matchlen; | 171 | matchend = matchoff + matchlen + *datalen - olen; |
171 | 172 | ||
172 | /* The maddr= parameter (RFC 2361) specifies where to send | 173 | /* The maddr= parameter (RFC 2361) specifies where to send |
173 | * the reply. */ | 174 | * the reply. */ |
174 | if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen, | 175 | if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen, |
175 | "maddr=", &poff, &plen, | 176 | "maddr=", &poff, &plen, |
176 | &addr) > 0 && | 177 | &addr, true) > 0 && |
177 | addr.ip == ct->tuplehash[dir].tuple.src.u3.ip && | 178 | addr.ip == ct->tuplehash[dir].tuple.src.u3.ip && |
178 | addr.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) { | 179 | addr.ip != ct->tuplehash[!dir].tuple.dst.u3.ip) { |
179 | buflen = sprintf(buffer, "%pI4", | 180 | buflen = sprintf(buffer, "%pI4", |
@@ -187,7 +188,7 @@ static unsigned int ip_nat_sip(struct sk_buff *skb, unsigned int dataoff, | |||
187 | * from which the server received the request. */ | 188 | * from which the server received the request. */ |
188 | if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen, | 189 | if (ct_sip_parse_address_param(ct, *dptr, matchend, *datalen, |
189 | "received=", &poff, &plen, | 190 | "received=", &poff, &plen, |
190 | &addr) > 0 && | 191 | &addr, false) > 0 && |
191 | addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip && | 192 | addr.ip == ct->tuplehash[dir].tuple.dst.u3.ip && |
192 | addr.ip != ct->tuplehash[!dir].tuple.src.u3.ip) { | 193 | addr.ip != ct->tuplehash[!dir].tuple.src.u3.ip) { |
193 | buflen = sprintf(buffer, "%pI4", | 194 | buflen = sprintf(buffer, "%pI4", |
diff --git a/net/ipv4/route.c b/net/ipv4/route.c index c58137391a3d..50f6d3adb474 100644 --- a/net/ipv4/route.c +++ b/net/ipv4/route.c | |||
@@ -2031,7 +2031,6 @@ struct rtable *__ip_route_output_key(struct net *net, struct flowi4 *fl4) | |||
2031 | } | 2031 | } |
2032 | dev_out = net->loopback_dev; | 2032 | dev_out = net->loopback_dev; |
2033 | fl4->flowi4_oif = dev_out->ifindex; | 2033 | fl4->flowi4_oif = dev_out->ifindex; |
2034 | res.fi = NULL; | ||
2035 | flags |= RTCF_LOCAL; | 2034 | flags |= RTCF_LOCAL; |
2036 | goto make_route; | 2035 | goto make_route; |
2037 | } | 2036 | } |
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index c423317eb719..bcfccc5cb8d0 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -5396,6 +5396,8 @@ int tcp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
5396 | { | 5396 | { |
5397 | struct tcp_sock *tp = tcp_sk(sk); | 5397 | struct tcp_sock *tp = tcp_sk(sk); |
5398 | 5398 | ||
5399 | if (unlikely(sk->sk_rx_dst == NULL)) | ||
5400 | inet_csk(sk)->icsk_af_ops->sk_rx_dst_set(sk, skb); | ||
5399 | /* | 5401 | /* |
5400 | * Header prediction. | 5402 | * Header prediction. |
5401 | * The code loosely follows the one in the famous | 5403 | * The code loosely follows the one in the famous |
@@ -5609,7 +5611,7 @@ void tcp_finish_connect(struct sock *sk, struct sk_buff *skb) | |||
5609 | tcp_set_state(sk, TCP_ESTABLISHED); | 5611 | tcp_set_state(sk, TCP_ESTABLISHED); |
5610 | 5612 | ||
5611 | if (skb != NULL) { | 5613 | if (skb != NULL) { |
5612 | inet_sk_rx_dst_set(sk, skb); | 5614 | icsk->icsk_af_ops->sk_rx_dst_set(sk, skb); |
5613 | security_inet_conn_established(sk, skb); | 5615 | security_inet_conn_established(sk, skb); |
5614 | } | 5616 | } |
5615 | 5617 | ||
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c index c660d2c19a2b..1e15c5be04e7 100644 --- a/net/ipv4/tcp_ipv4.c +++ b/net/ipv4/tcp_ipv4.c | |||
@@ -417,10 +417,12 @@ void tcp_v4_err(struct sk_buff *icmp_skb, u32 info) | |||
417 | 417 | ||
418 | if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */ | 418 | if (code == ICMP_FRAG_NEEDED) { /* PMTU discovery (RFC1191) */ |
419 | tp->mtu_info = info; | 419 | tp->mtu_info = info; |
420 | if (!sock_owned_by_user(sk)) | 420 | if (!sock_owned_by_user(sk)) { |
421 | tcp_v4_mtu_reduced(sk); | 421 | tcp_v4_mtu_reduced(sk); |
422 | else | 422 | } else { |
423 | set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags); | 423 | if (!test_and_set_bit(TCP_MTU_REDUCED_DEFERRED, &tp->tsq_flags)) |
424 | sock_hold(sk); | ||
425 | } | ||
424 | goto out; | 426 | goto out; |
425 | } | 427 | } |
426 | 428 | ||
@@ -1462,6 +1464,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1462 | goto exit_nonewsk; | 1464 | goto exit_nonewsk; |
1463 | 1465 | ||
1464 | newsk->sk_gso_type = SKB_GSO_TCPV4; | 1466 | newsk->sk_gso_type = SKB_GSO_TCPV4; |
1467 | inet_sk_rx_dst_set(newsk, skb); | ||
1465 | 1468 | ||
1466 | newtp = tcp_sk(newsk); | 1469 | newtp = tcp_sk(newsk); |
1467 | newinet = inet_sk(newsk); | 1470 | newinet = inet_sk(newsk); |
@@ -1627,9 +1630,6 @@ int tcp_v4_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
1627 | sk->sk_rx_dst = NULL; | 1630 | sk->sk_rx_dst = NULL; |
1628 | } | 1631 | } |
1629 | } | 1632 | } |
1630 | if (unlikely(sk->sk_rx_dst == NULL)) | ||
1631 | inet_sk_rx_dst_set(sk, skb); | ||
1632 | |||
1633 | if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) { | 1633 | if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) { |
1634 | rsk = sk; | 1634 | rsk = sk; |
1635 | goto reset; | 1635 | goto reset; |
@@ -1872,10 +1872,21 @@ static struct timewait_sock_ops tcp_timewait_sock_ops = { | |||
1872 | .twsk_destructor= tcp_twsk_destructor, | 1872 | .twsk_destructor= tcp_twsk_destructor, |
1873 | }; | 1873 | }; |
1874 | 1874 | ||
1875 | void inet_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) | ||
1876 | { | ||
1877 | struct dst_entry *dst = skb_dst(skb); | ||
1878 | |||
1879 | dst_hold(dst); | ||
1880 | sk->sk_rx_dst = dst; | ||
1881 | inet_sk(sk)->rx_dst_ifindex = skb->skb_iif; | ||
1882 | } | ||
1883 | EXPORT_SYMBOL(inet_sk_rx_dst_set); | ||
1884 | |||
1875 | const struct inet_connection_sock_af_ops ipv4_specific = { | 1885 | const struct inet_connection_sock_af_ops ipv4_specific = { |
1876 | .queue_xmit = ip_queue_xmit, | 1886 | .queue_xmit = ip_queue_xmit, |
1877 | .send_check = tcp_v4_send_check, | 1887 | .send_check = tcp_v4_send_check, |
1878 | .rebuild_header = inet_sk_rebuild_header, | 1888 | .rebuild_header = inet_sk_rebuild_header, |
1889 | .sk_rx_dst_set = inet_sk_rx_dst_set, | ||
1879 | .conn_request = tcp_v4_conn_request, | 1890 | .conn_request = tcp_v4_conn_request, |
1880 | .syn_recv_sock = tcp_v4_syn_recv_sock, | 1891 | .syn_recv_sock = tcp_v4_syn_recv_sock, |
1881 | .net_header_len = sizeof(struct iphdr), | 1892 | .net_header_len = sizeof(struct iphdr), |
diff --git a/net/ipv4/tcp_metrics.c b/net/ipv4/tcp_metrics.c index 2288a6399e1e..0abe67bb4d3a 100644 --- a/net/ipv4/tcp_metrics.c +++ b/net/ipv4/tcp_metrics.c | |||
@@ -731,6 +731,18 @@ static int __net_init tcp_net_metrics_init(struct net *net) | |||
731 | 731 | ||
732 | static void __net_exit tcp_net_metrics_exit(struct net *net) | 732 | static void __net_exit tcp_net_metrics_exit(struct net *net) |
733 | { | 733 | { |
734 | unsigned int i; | ||
735 | |||
736 | for (i = 0; i < (1U << net->ipv4.tcp_metrics_hash_log) ; i++) { | ||
737 | struct tcp_metrics_block *tm, *next; | ||
738 | |||
739 | tm = rcu_dereference_protected(net->ipv4.tcp_metrics_hash[i].chain, 1); | ||
740 | while (tm) { | ||
741 | next = rcu_dereference_protected(tm->tcpm_next, 1); | ||
742 | kfree(tm); | ||
743 | tm = next; | ||
744 | } | ||
745 | } | ||
734 | kfree(net->ipv4.tcp_metrics_hash); | 746 | kfree(net->ipv4.tcp_metrics_hash); |
735 | } | 747 | } |
736 | 748 | ||
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 232a90c3ec86..6ff7f10dce9d 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c | |||
@@ -387,8 +387,6 @@ struct sock *tcp_create_openreq_child(struct sock *sk, struct request_sock *req, | |||
387 | struct tcp_sock *oldtp = tcp_sk(sk); | 387 | struct tcp_sock *oldtp = tcp_sk(sk); |
388 | struct tcp_cookie_values *oldcvp = oldtp->cookie_values; | 388 | struct tcp_cookie_values *oldcvp = oldtp->cookie_values; |
389 | 389 | ||
390 | inet_sk_rx_dst_set(newsk, skb); | ||
391 | |||
392 | /* TCP Cookie Transactions require space for the cookie pair, | 390 | /* TCP Cookie Transactions require space for the cookie pair, |
393 | * as it differs for each connection. There is no need to | 391 | * as it differs for each connection. There is no need to |
394 | * copy any s_data_payload stored at the original socket. | 392 | * copy any s_data_payload stored at the original socket. |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index a7b3ec9b6c3e..d04632673a9e 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -910,14 +910,18 @@ void tcp_release_cb(struct sock *sk) | |||
910 | if (flags & (1UL << TCP_TSQ_DEFERRED)) | 910 | if (flags & (1UL << TCP_TSQ_DEFERRED)) |
911 | tcp_tsq_handler(sk); | 911 | tcp_tsq_handler(sk); |
912 | 912 | ||
913 | if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) | 913 | if (flags & (1UL << TCP_WRITE_TIMER_DEFERRED)) { |
914 | tcp_write_timer_handler(sk); | 914 | tcp_write_timer_handler(sk); |
915 | 915 | __sock_put(sk); | |
916 | if (flags & (1UL << TCP_DELACK_TIMER_DEFERRED)) | 916 | } |
917 | if (flags & (1UL << TCP_DELACK_TIMER_DEFERRED)) { | ||
917 | tcp_delack_timer_handler(sk); | 918 | tcp_delack_timer_handler(sk); |
918 | 919 | __sock_put(sk); | |
919 | if (flags & (1UL << TCP_MTU_REDUCED_DEFERRED)) | 920 | } |
921 | if (flags & (1UL << TCP_MTU_REDUCED_DEFERRED)) { | ||
920 | sk->sk_prot->mtu_reduced(sk); | 922 | sk->sk_prot->mtu_reduced(sk); |
923 | __sock_put(sk); | ||
924 | } | ||
921 | } | 925 | } |
922 | EXPORT_SYMBOL(tcp_release_cb); | 926 | EXPORT_SYMBOL(tcp_release_cb); |
923 | 927 | ||
@@ -940,7 +944,7 @@ void __init tcp_tasklet_init(void) | |||
940 | * We cant xmit new skbs from this context, as we might already | 944 | * We cant xmit new skbs from this context, as we might already |
941 | * hold qdisc lock. | 945 | * hold qdisc lock. |
942 | */ | 946 | */ |
943 | void tcp_wfree(struct sk_buff *skb) | 947 | static void tcp_wfree(struct sk_buff *skb) |
944 | { | 948 | { |
945 | struct sock *sk = skb->sk; | 949 | struct sock *sk = skb->sk; |
946 | struct tcp_sock *tp = tcp_sk(sk); | 950 | struct tcp_sock *tp = tcp_sk(sk); |
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c index 6df36ad55a38..b774a03bd1dc 100644 --- a/net/ipv4/tcp_timer.c +++ b/net/ipv4/tcp_timer.c | |||
@@ -252,7 +252,8 @@ static void tcp_delack_timer(unsigned long data) | |||
252 | inet_csk(sk)->icsk_ack.blocked = 1; | 252 | inet_csk(sk)->icsk_ack.blocked = 1; |
253 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOCKED); | 253 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_DELAYEDACKLOCKED); |
254 | /* deleguate our work to tcp_release_cb() */ | 254 | /* deleguate our work to tcp_release_cb() */ |
255 | set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags); | 255 | if (!test_and_set_bit(TCP_DELACK_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags)) |
256 | sock_hold(sk); | ||
256 | } | 257 | } |
257 | bh_unlock_sock(sk); | 258 | bh_unlock_sock(sk); |
258 | sock_put(sk); | 259 | sock_put(sk); |
@@ -481,7 +482,8 @@ static void tcp_write_timer(unsigned long data) | |||
481 | tcp_write_timer_handler(sk); | 482 | tcp_write_timer_handler(sk); |
482 | } else { | 483 | } else { |
483 | /* deleguate our work to tcp_release_cb() */ | 484 | /* deleguate our work to tcp_release_cb() */ |
484 | set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags); | 485 | if (!test_and_set_bit(TCP_WRITE_TIMER_DEFERRED, &tcp_sk(sk)->tsq_flags)) |
486 | sock_hold(sk); | ||
485 | } | 487 | } |
486 | bh_unlock_sock(sk); | 488 | bh_unlock_sock(sk); |
487 | sock_put(sk); | 489 | sock_put(sk); |
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index b4c3582a991f..6f6d1aca3c3d 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c | |||
@@ -758,7 +758,7 @@ static int udp_send_skb(struct sk_buff *skb, struct flowi4 *fl4) | |||
758 | uh->check = CSUM_MANGLED_0; | 758 | uh->check = CSUM_MANGLED_0; |
759 | 759 | ||
760 | send: | 760 | send: |
761 | err = ip_send_skb(skb); | 761 | err = ip_send_skb(sock_net(sk), skb); |
762 | if (err) { | 762 | if (err) { |
763 | if (err == -ENOBUFS && !inet->recverr) { | 763 | if (err == -ENOBUFS && !inet->recverr) { |
764 | UDP_INC_STATS_USER(sock_net(sk), | 764 | UDP_INC_STATS_USER(sock_net(sk), |
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 79181819a24f..6bc85f7c31e3 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c | |||
@@ -494,8 +494,7 @@ static void addrconf_forward_change(struct net *net, __s32 newf) | |||
494 | struct net_device *dev; | 494 | struct net_device *dev; |
495 | struct inet6_dev *idev; | 495 | struct inet6_dev *idev; |
496 | 496 | ||
497 | rcu_read_lock(); | 497 | for_each_netdev(net, dev) { |
498 | for_each_netdev_rcu(net, dev) { | ||
499 | idev = __in6_dev_get(dev); | 498 | idev = __in6_dev_get(dev); |
500 | if (idev) { | 499 | if (idev) { |
501 | int changed = (!idev->cnf.forwarding) ^ (!newf); | 500 | int changed = (!idev->cnf.forwarding) ^ (!newf); |
@@ -504,7 +503,6 @@ static void addrconf_forward_change(struct net *net, __s32 newf) | |||
504 | dev_forward_change(idev); | 503 | dev_forward_change(idev); |
505 | } | 504 | } |
506 | } | 505 | } |
507 | rcu_read_unlock(); | ||
508 | } | 506 | } |
509 | 507 | ||
510 | static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf) | 508 | static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int newf) |
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c index da2e92d05c15..745a32042950 100644 --- a/net/ipv6/proc.c +++ b/net/ipv6/proc.c | |||
@@ -307,10 +307,10 @@ static int __net_init ipv6_proc_init_net(struct net *net) | |||
307 | goto proc_dev_snmp6_fail; | 307 | goto proc_dev_snmp6_fail; |
308 | return 0; | 308 | return 0; |
309 | 309 | ||
310 | proc_dev_snmp6_fail: | ||
311 | proc_net_remove(net, "snmp6"); | ||
310 | proc_snmp6_fail: | 312 | proc_snmp6_fail: |
311 | proc_net_remove(net, "sockstat6"); | 313 | proc_net_remove(net, "sockstat6"); |
312 | proc_dev_snmp6_fail: | ||
313 | proc_net_remove(net, "dev_snmp6"); | ||
314 | return -ENOMEM; | 314 | return -ENOMEM; |
315 | } | 315 | } |
316 | 316 | ||
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index aa41b0e6b163..cd49de3678fb 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -94,6 +94,18 @@ static struct tcp_md5sig_key *tcp_v6_md5_do_lookup(struct sock *sk, | |||
94 | } | 94 | } |
95 | #endif | 95 | #endif |
96 | 96 | ||
97 | static void inet6_sk_rx_dst_set(struct sock *sk, const struct sk_buff *skb) | ||
98 | { | ||
99 | struct dst_entry *dst = skb_dst(skb); | ||
100 | const struct rt6_info *rt = (const struct rt6_info *)dst; | ||
101 | |||
102 | dst_hold(dst); | ||
103 | sk->sk_rx_dst = dst; | ||
104 | inet_sk(sk)->rx_dst_ifindex = skb->skb_iif; | ||
105 | if (rt->rt6i_node) | ||
106 | inet6_sk(sk)->rx_dst_cookie = rt->rt6i_node->fn_sernum; | ||
107 | } | ||
108 | |||
97 | static void tcp_v6_hash(struct sock *sk) | 109 | static void tcp_v6_hash(struct sock *sk) |
98 | { | 110 | { |
99 | if (sk->sk_state != TCP_CLOSE) { | 111 | if (sk->sk_state != TCP_CLOSE) { |
@@ -1270,6 +1282,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
1270 | 1282 | ||
1271 | newsk->sk_gso_type = SKB_GSO_TCPV6; | 1283 | newsk->sk_gso_type = SKB_GSO_TCPV6; |
1272 | __ip6_dst_store(newsk, dst, NULL, NULL); | 1284 | __ip6_dst_store(newsk, dst, NULL, NULL); |
1285 | inet6_sk_rx_dst_set(newsk, skb); | ||
1273 | 1286 | ||
1274 | newtcp6sk = (struct tcp6_sock *)newsk; | 1287 | newtcp6sk = (struct tcp6_sock *)newsk; |
1275 | inet_sk(newsk)->pinet6 = &newtcp6sk->inet6; | 1288 | inet_sk(newsk)->pinet6 = &newtcp6sk->inet6; |
@@ -1447,7 +1460,17 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
1447 | opt_skb = skb_clone(skb, sk_gfp_atomic(sk, GFP_ATOMIC)); | 1460 | opt_skb = skb_clone(skb, sk_gfp_atomic(sk, GFP_ATOMIC)); |
1448 | 1461 | ||
1449 | if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ | 1462 | if (sk->sk_state == TCP_ESTABLISHED) { /* Fast path */ |
1463 | struct dst_entry *dst = sk->sk_rx_dst; | ||
1464 | |||
1450 | sock_rps_save_rxhash(sk, skb); | 1465 | sock_rps_save_rxhash(sk, skb); |
1466 | if (dst) { | ||
1467 | if (inet_sk(sk)->rx_dst_ifindex != skb->skb_iif || | ||
1468 | dst->ops->check(dst, np->rx_dst_cookie) == NULL) { | ||
1469 | dst_release(dst); | ||
1470 | sk->sk_rx_dst = NULL; | ||
1471 | } | ||
1472 | } | ||
1473 | |||
1451 | if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) | 1474 | if (tcp_rcv_established(sk, skb, tcp_hdr(skb), skb->len)) |
1452 | goto reset; | 1475 | goto reset; |
1453 | if (opt_skb) | 1476 | if (opt_skb) |
@@ -1705,9 +1728,9 @@ static void tcp_v6_early_demux(struct sk_buff *skb) | |||
1705 | struct dst_entry *dst = sk->sk_rx_dst; | 1728 | struct dst_entry *dst = sk->sk_rx_dst; |
1706 | struct inet_sock *icsk = inet_sk(sk); | 1729 | struct inet_sock *icsk = inet_sk(sk); |
1707 | if (dst) | 1730 | if (dst) |
1708 | dst = dst_check(dst, 0); | 1731 | dst = dst_check(dst, inet6_sk(sk)->rx_dst_cookie); |
1709 | if (dst && | 1732 | if (dst && |
1710 | icsk->rx_dst_ifindex == inet6_iif(skb)) | 1733 | icsk->rx_dst_ifindex == skb->skb_iif) |
1711 | skb_dst_set_noref(skb, dst); | 1734 | skb_dst_set_noref(skb, dst); |
1712 | } | 1735 | } |
1713 | } | 1736 | } |
@@ -1723,6 +1746,7 @@ static const struct inet_connection_sock_af_ops ipv6_specific = { | |||
1723 | .queue_xmit = inet6_csk_xmit, | 1746 | .queue_xmit = inet6_csk_xmit, |
1724 | .send_check = tcp_v6_send_check, | 1747 | .send_check = tcp_v6_send_check, |
1725 | .rebuild_header = inet6_sk_rebuild_header, | 1748 | .rebuild_header = inet6_sk_rebuild_header, |
1749 | .sk_rx_dst_set = inet6_sk_rx_dst_set, | ||
1726 | .conn_request = tcp_v6_conn_request, | 1750 | .conn_request = tcp_v6_conn_request, |
1727 | .syn_recv_sock = tcp_v6_syn_recv_sock, | 1751 | .syn_recv_sock = tcp_v6_syn_recv_sock, |
1728 | .net_header_len = sizeof(struct ipv6hdr), | 1752 | .net_header_len = sizeof(struct ipv6hdr), |
@@ -1754,6 +1778,7 @@ static const struct inet_connection_sock_af_ops ipv6_mapped = { | |||
1754 | .queue_xmit = ip_queue_xmit, | 1778 | .queue_xmit = ip_queue_xmit, |
1755 | .send_check = tcp_v4_send_check, | 1779 | .send_check = tcp_v4_send_check, |
1756 | .rebuild_header = inet_sk_rebuild_header, | 1780 | .rebuild_header = inet_sk_rebuild_header, |
1781 | .sk_rx_dst_set = inet_sk_rx_dst_set, | ||
1757 | .conn_request = tcp_v6_conn_request, | 1782 | .conn_request = tcp_v6_conn_request, |
1758 | .syn_recv_sock = tcp_v6_syn_recv_sock, | 1783 | .syn_recv_sock = tcp_v6_syn_recv_sock, |
1759 | .net_header_len = sizeof(struct iphdr), | 1784 | .net_header_len = sizeof(struct iphdr), |
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c index ef39812107b1..f8c4c08ffb60 100644 --- a/net/ipv6/xfrm6_policy.c +++ b/net/ipv6/xfrm6_policy.c | |||
@@ -73,6 +73,13 @@ static int xfrm6_get_tos(const struct flowi *fl) | |||
73 | return 0; | 73 | return 0; |
74 | } | 74 | } |
75 | 75 | ||
76 | static void xfrm6_init_dst(struct net *net, struct xfrm_dst *xdst) | ||
77 | { | ||
78 | struct rt6_info *rt = (struct rt6_info *)xdst; | ||
79 | |||
80 | rt6_init_peer(rt, net->ipv6.peers); | ||
81 | } | ||
82 | |||
76 | static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst, | 83 | static int xfrm6_init_path(struct xfrm_dst *path, struct dst_entry *dst, |
77 | int nfheader_len) | 84 | int nfheader_len) |
78 | { | 85 | { |
@@ -286,6 +293,7 @@ static struct xfrm_policy_afinfo xfrm6_policy_afinfo = { | |||
286 | .get_saddr = xfrm6_get_saddr, | 293 | .get_saddr = xfrm6_get_saddr, |
287 | .decode_session = _decode_session6, | 294 | .decode_session = _decode_session6, |
288 | .get_tos = xfrm6_get_tos, | 295 | .get_tos = xfrm6_get_tos, |
296 | .init_dst = xfrm6_init_dst, | ||
289 | .init_path = xfrm6_init_path, | 297 | .init_path = xfrm6_init_path, |
290 | .fill_dst = xfrm6_fill_dst, | 298 | .fill_dst = xfrm6_fill_dst, |
291 | .blackhole_route = ip6_blackhole_route, | 299 | .blackhole_route = ip6_blackhole_route, |
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c index 35e1e4bde587..927547171bc7 100644 --- a/net/l2tp/l2tp_ip6.c +++ b/net/l2tp/l2tp_ip6.c | |||
@@ -410,6 +410,7 @@ static int l2tp_ip6_getname(struct socket *sock, struct sockaddr *uaddr, | |||
410 | lsa->l2tp_family = AF_INET6; | 410 | lsa->l2tp_family = AF_INET6; |
411 | lsa->l2tp_flowinfo = 0; | 411 | lsa->l2tp_flowinfo = 0; |
412 | lsa->l2tp_scope_id = 0; | 412 | lsa->l2tp_scope_id = 0; |
413 | lsa->l2tp_unused = 0; | ||
413 | if (peer) { | 414 | if (peer) { |
414 | if (!lsk->peer_conn_id) | 415 | if (!lsk->peer_conn_id) |
415 | return -ENOTCONN; | 416 | return -ENOTCONN; |
diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index f6fe4d400502..c2190005a114 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c | |||
@@ -969,14 +969,13 @@ static int llc_ui_getname(struct socket *sock, struct sockaddr *uaddr, | |||
969 | struct sockaddr_llc sllc; | 969 | struct sockaddr_llc sllc; |
970 | struct sock *sk = sock->sk; | 970 | struct sock *sk = sock->sk; |
971 | struct llc_sock *llc = llc_sk(sk); | 971 | struct llc_sock *llc = llc_sk(sk); |
972 | int rc = 0; | 972 | int rc = -EBADF; |
973 | 973 | ||
974 | memset(&sllc, 0, sizeof(sllc)); | 974 | memset(&sllc, 0, sizeof(sllc)); |
975 | lock_sock(sk); | 975 | lock_sock(sk); |
976 | if (sock_flag(sk, SOCK_ZAPPED)) | 976 | if (sock_flag(sk, SOCK_ZAPPED)) |
977 | goto out; | 977 | goto out; |
978 | *uaddrlen = sizeof(sllc); | 978 | *uaddrlen = sizeof(sllc); |
979 | memset(uaddr, 0, *uaddrlen); | ||
980 | if (peer) { | 979 | if (peer) { |
981 | rc = -ENOTCONN; | 980 | rc = -ENOTCONN; |
982 | if (sk->sk_state != TCP_ESTABLISHED) | 981 | if (sk->sk_state != TCP_ESTABLISHED) |
@@ -1206,7 +1205,7 @@ static int __init llc2_init(void) | |||
1206 | rc = llc_proc_init(); | 1205 | rc = llc_proc_init(); |
1207 | if (rc != 0) { | 1206 | if (rc != 0) { |
1208 | printk(llc_proc_err_msg); | 1207 | printk(llc_proc_err_msg); |
1209 | goto out_unregister_llc_proto; | 1208 | goto out_station; |
1210 | } | 1209 | } |
1211 | rc = llc_sysctl_init(); | 1210 | rc = llc_sysctl_init(); |
1212 | if (rc) { | 1211 | if (rc) { |
@@ -1226,7 +1225,8 @@ out_sysctl: | |||
1226 | llc_sysctl_exit(); | 1225 | llc_sysctl_exit(); |
1227 | out_proc: | 1226 | out_proc: |
1228 | llc_proc_exit(); | 1227 | llc_proc_exit(); |
1229 | out_unregister_llc_proto: | 1228 | out_station: |
1229 | llc_station_exit(); | ||
1230 | proto_unregister(&llc_proto); | 1230 | proto_unregister(&llc_proto); |
1231 | goto out; | 1231 | goto out; |
1232 | } | 1232 | } |
diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c index e32cab44ea95..dd3e83328ad5 100644 --- a/net/llc/llc_input.c +++ b/net/llc/llc_input.c | |||
@@ -42,6 +42,7 @@ static void (*llc_type_handlers[2])(struct llc_sap *sap, | |||
42 | void llc_add_pack(int type, void (*handler)(struct llc_sap *sap, | 42 | void llc_add_pack(int type, void (*handler)(struct llc_sap *sap, |
43 | struct sk_buff *skb)) | 43 | struct sk_buff *skb)) |
44 | { | 44 | { |
45 | smp_wmb(); /* ensure initialisation is complete before it's called */ | ||
45 | if (type == LLC_DEST_SAP || type == LLC_DEST_CONN) | 46 | if (type == LLC_DEST_SAP || type == LLC_DEST_CONN) |
46 | llc_type_handlers[type - 1] = handler; | 47 | llc_type_handlers[type - 1] = handler; |
47 | } | 48 | } |
@@ -50,11 +51,19 @@ void llc_remove_pack(int type) | |||
50 | { | 51 | { |
51 | if (type == LLC_DEST_SAP || type == LLC_DEST_CONN) | 52 | if (type == LLC_DEST_SAP || type == LLC_DEST_CONN) |
52 | llc_type_handlers[type - 1] = NULL; | 53 | llc_type_handlers[type - 1] = NULL; |
54 | synchronize_net(); | ||
53 | } | 55 | } |
54 | 56 | ||
55 | void llc_set_station_handler(void (*handler)(struct sk_buff *skb)) | 57 | void llc_set_station_handler(void (*handler)(struct sk_buff *skb)) |
56 | { | 58 | { |
59 | /* Ensure initialisation is complete before it's called */ | ||
60 | if (handler) | ||
61 | smp_wmb(); | ||
62 | |||
57 | llc_station_handler = handler; | 63 | llc_station_handler = handler; |
64 | |||
65 | if (!handler) | ||
66 | synchronize_net(); | ||
58 | } | 67 | } |
59 | 68 | ||
60 | /** | 69 | /** |
@@ -150,6 +159,8 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, | |||
150 | int dest; | 159 | int dest; |
151 | int (*rcv)(struct sk_buff *, struct net_device *, | 160 | int (*rcv)(struct sk_buff *, struct net_device *, |
152 | struct packet_type *, struct net_device *); | 161 | struct packet_type *, struct net_device *); |
162 | void (*sta_handler)(struct sk_buff *skb); | ||
163 | void (*sap_handler)(struct llc_sap *sap, struct sk_buff *skb); | ||
153 | 164 | ||
154 | if (!net_eq(dev_net(dev), &init_net)) | 165 | if (!net_eq(dev_net(dev), &init_net)) |
155 | goto drop; | 166 | goto drop; |
@@ -182,7 +193,8 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, | |||
182 | */ | 193 | */ |
183 | rcv = rcu_dereference(sap->rcv_func); | 194 | rcv = rcu_dereference(sap->rcv_func); |
184 | dest = llc_pdu_type(skb); | 195 | dest = llc_pdu_type(skb); |
185 | if (unlikely(!dest || !llc_type_handlers[dest - 1])) { | 196 | sap_handler = dest ? ACCESS_ONCE(llc_type_handlers[dest - 1]) : NULL; |
197 | if (unlikely(!sap_handler)) { | ||
186 | if (rcv) | 198 | if (rcv) |
187 | rcv(skb, dev, pt, orig_dev); | 199 | rcv(skb, dev, pt, orig_dev); |
188 | else | 200 | else |
@@ -193,7 +205,7 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev, | |||
193 | if (cskb) | 205 | if (cskb) |
194 | rcv(cskb, dev, pt, orig_dev); | 206 | rcv(cskb, dev, pt, orig_dev); |
195 | } | 207 | } |
196 | llc_type_handlers[dest - 1](sap, skb); | 208 | sap_handler(sap, skb); |
197 | } | 209 | } |
198 | llc_sap_put(sap); | 210 | llc_sap_put(sap); |
199 | out: | 211 | out: |
@@ -202,9 +214,10 @@ drop: | |||
202 | kfree_skb(skb); | 214 | kfree_skb(skb); |
203 | goto out; | 215 | goto out; |
204 | handle_station: | 216 | handle_station: |
205 | if (!llc_station_handler) | 217 | sta_handler = ACCESS_ONCE(llc_station_handler); |
218 | if (!sta_handler) | ||
206 | goto drop; | 219 | goto drop; |
207 | llc_station_handler(skb); | 220 | sta_handler(skb); |
208 | goto out; | 221 | goto out; |
209 | } | 222 | } |
210 | 223 | ||
diff --git a/net/llc/llc_station.c b/net/llc/llc_station.c index 39a8d8924b9c..b2f2bac2c2a2 100644 --- a/net/llc/llc_station.c +++ b/net/llc/llc_station.c | |||
@@ -268,7 +268,7 @@ static int llc_station_ac_send_null_dsap_xid_c(struct sk_buff *skb) | |||
268 | out: | 268 | out: |
269 | return rc; | 269 | return rc; |
270 | free: | 270 | free: |
271 | kfree_skb(skb); | 271 | kfree_skb(nskb); |
272 | goto out; | 272 | goto out; |
273 | } | 273 | } |
274 | 274 | ||
@@ -293,7 +293,7 @@ static int llc_station_ac_send_xid_r(struct sk_buff *skb) | |||
293 | out: | 293 | out: |
294 | return rc; | 294 | return rc; |
295 | free: | 295 | free: |
296 | kfree_skb(skb); | 296 | kfree_skb(nskb); |
297 | goto out; | 297 | goto out; |
298 | } | 298 | } |
299 | 299 | ||
@@ -322,7 +322,7 @@ static int llc_station_ac_send_test_r(struct sk_buff *skb) | |||
322 | out: | 322 | out: |
323 | return rc; | 323 | return rc; |
324 | free: | 324 | free: |
325 | kfree_skb(skb); | 325 | kfree_skb(nskb); |
326 | goto out; | 326 | goto out; |
327 | } | 327 | } |
328 | 328 | ||
@@ -687,12 +687,8 @@ static void llc_station_rcv(struct sk_buff *skb) | |||
687 | llc_station_state_process(skb); | 687 | llc_station_state_process(skb); |
688 | } | 688 | } |
689 | 689 | ||
690 | int __init llc_station_init(void) | 690 | void __init llc_station_init(void) |
691 | { | 691 | { |
692 | int rc = -ENOBUFS; | ||
693 | struct sk_buff *skb; | ||
694 | struct llc_station_state_ev *ev; | ||
695 | |||
696 | skb_queue_head_init(&llc_main_station.mac_pdu_q); | 692 | skb_queue_head_init(&llc_main_station.mac_pdu_q); |
697 | skb_queue_head_init(&llc_main_station.ev_q.list); | 693 | skb_queue_head_init(&llc_main_station.ev_q.list); |
698 | spin_lock_init(&llc_main_station.ev_q.lock); | 694 | spin_lock_init(&llc_main_station.ev_q.lock); |
@@ -700,23 +696,12 @@ int __init llc_station_init(void) | |||
700 | (unsigned long)&llc_main_station); | 696 | (unsigned long)&llc_main_station); |
701 | llc_main_station.ack_timer.expires = jiffies + | 697 | llc_main_station.ack_timer.expires = jiffies + |
702 | sysctl_llc_station_ack_timeout; | 698 | sysctl_llc_station_ack_timeout; |
703 | skb = alloc_skb(0, GFP_ATOMIC); | ||
704 | if (!skb) | ||
705 | goto out; | ||
706 | rc = 0; | ||
707 | llc_set_station_handler(llc_station_rcv); | ||
708 | ev = llc_station_ev(skb); | ||
709 | memset(ev, 0, sizeof(*ev)); | ||
710 | llc_main_station.maximum_retry = 1; | 699 | llc_main_station.maximum_retry = 1; |
711 | llc_main_station.state = LLC_STATION_STATE_DOWN; | 700 | llc_main_station.state = LLC_STATION_STATE_UP; |
712 | ev->type = LLC_STATION_EV_TYPE_SIMPLE; | 701 | llc_set_station_handler(llc_station_rcv); |
713 | ev->prim_type = LLC_STATION_EV_ENABLE_WITHOUT_DUP_ADDR_CHECK; | ||
714 | rc = llc_station_next_state(skb); | ||
715 | out: | ||
716 | return rc; | ||
717 | } | 702 | } |
718 | 703 | ||
719 | void __exit llc_station_exit(void) | 704 | void llc_station_exit(void) |
720 | { | 705 | { |
721 | llc_set_station_handler(NULL); | 706 | llc_set_station_handler(NULL); |
722 | } | 707 | } |
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index 84444dda194b..72bf32a84874 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c | |||
@@ -2759,6 +2759,7 @@ do_ip_vs_get_ctl(struct sock *sk, int cmd, void __user *user, int *len) | |||
2759 | { | 2759 | { |
2760 | struct ip_vs_timeout_user t; | 2760 | struct ip_vs_timeout_user t; |
2761 | 2761 | ||
2762 | memset(&t, 0, sizeof(t)); | ||
2762 | __ip_vs_get_timeouts(net, &t); | 2763 | __ip_vs_get_timeouts(net, &t); |
2763 | if (copy_to_user(user, &t, sizeof(t)) != 0) | 2764 | if (copy_to_user(user, &t, sizeof(t)) != 0) |
2764 | ret = -EFAULT; | 2765 | ret = -EFAULT; |
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c index 45cf602a76bc..527651a53a45 100644 --- a/net/netfilter/nf_conntrack_expect.c +++ b/net/netfilter/nf_conntrack_expect.c | |||
@@ -361,23 +361,6 @@ static void evict_oldest_expect(struct nf_conn *master, | |||
361 | } | 361 | } |
362 | } | 362 | } |
363 | 363 | ||
364 | static inline int refresh_timer(struct nf_conntrack_expect *i) | ||
365 | { | ||
366 | struct nf_conn_help *master_help = nfct_help(i->master); | ||
367 | const struct nf_conntrack_expect_policy *p; | ||
368 | |||
369 | if (!del_timer(&i->timeout)) | ||
370 | return 0; | ||
371 | |||
372 | p = &rcu_dereference_protected( | ||
373 | master_help->helper, | ||
374 | lockdep_is_held(&nf_conntrack_lock) | ||
375 | )->expect_policy[i->class]; | ||
376 | i->timeout.expires = jiffies + p->timeout * HZ; | ||
377 | add_timer(&i->timeout); | ||
378 | return 1; | ||
379 | } | ||
380 | |||
381 | static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) | 364 | static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) |
382 | { | 365 | { |
383 | const struct nf_conntrack_expect_policy *p; | 366 | const struct nf_conntrack_expect_policy *p; |
@@ -386,7 +369,7 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) | |||
386 | struct nf_conn_help *master_help = nfct_help(master); | 369 | struct nf_conn_help *master_help = nfct_help(master); |
387 | struct nf_conntrack_helper *helper; | 370 | struct nf_conntrack_helper *helper; |
388 | struct net *net = nf_ct_exp_net(expect); | 371 | struct net *net = nf_ct_exp_net(expect); |
389 | struct hlist_node *n; | 372 | struct hlist_node *n, *next; |
390 | unsigned int h; | 373 | unsigned int h; |
391 | int ret = 1; | 374 | int ret = 1; |
392 | 375 | ||
@@ -395,12 +378,12 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) | |||
395 | goto out; | 378 | goto out; |
396 | } | 379 | } |
397 | h = nf_ct_expect_dst_hash(&expect->tuple); | 380 | h = nf_ct_expect_dst_hash(&expect->tuple); |
398 | hlist_for_each_entry(i, n, &net->ct.expect_hash[h], hnode) { | 381 | hlist_for_each_entry_safe(i, n, next, &net->ct.expect_hash[h], hnode) { |
399 | if (expect_matches(i, expect)) { | 382 | if (expect_matches(i, expect)) { |
400 | /* Refresh timer: if it's dying, ignore.. */ | 383 | if (del_timer(&i->timeout)) { |
401 | if (refresh_timer(i)) { | 384 | nf_ct_unlink_expect(i); |
402 | ret = 0; | 385 | nf_ct_expect_put(i); |
403 | goto out; | 386 | break; |
404 | } | 387 | } |
405 | } else if (expect_clash(i, expect)) { | 388 | } else if (expect_clash(i, expect)) { |
406 | ret = -EBUSY; | 389 | ret = -EBUSY; |
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c index 14f67a2cbcb5..da4fc37a8578 100644 --- a/net/netfilter/nf_conntrack_netlink.c +++ b/net/netfilter/nf_conntrack_netlink.c | |||
@@ -1896,10 +1896,15 @@ static int | |||
1896 | ctnetlink_nfqueue_parse(const struct nlattr *attr, struct nf_conn *ct) | 1896 | ctnetlink_nfqueue_parse(const struct nlattr *attr, struct nf_conn *ct) |
1897 | { | 1897 | { |
1898 | struct nlattr *cda[CTA_MAX+1]; | 1898 | struct nlattr *cda[CTA_MAX+1]; |
1899 | int ret; | ||
1899 | 1900 | ||
1900 | nla_parse_nested(cda, CTA_MAX, attr, ct_nla_policy); | 1901 | nla_parse_nested(cda, CTA_MAX, attr, ct_nla_policy); |
1901 | 1902 | ||
1902 | return ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct); | 1903 | spin_lock_bh(&nf_conntrack_lock); |
1904 | ret = ctnetlink_nfqueue_parse_ct((const struct nlattr **)cda, ct); | ||
1905 | spin_unlock_bh(&nf_conntrack_lock); | ||
1906 | |||
1907 | return ret; | ||
1903 | } | 1908 | } |
1904 | 1909 | ||
1905 | static struct nfq_ct_hook ctnetlink_nfqueue_hook = { | 1910 | static struct nfq_ct_hook ctnetlink_nfqueue_hook = { |
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c index 758a1bacc126..5c0a112aeee6 100644 --- a/net/netfilter/nf_conntrack_sip.c +++ b/net/netfilter/nf_conntrack_sip.c | |||
@@ -183,12 +183,12 @@ static int media_len(const struct nf_conn *ct, const char *dptr, | |||
183 | return len + digits_len(ct, dptr, limit, shift); | 183 | return len + digits_len(ct, dptr, limit, shift); |
184 | } | 184 | } |
185 | 185 | ||
186 | static int parse_addr(const struct nf_conn *ct, const char *cp, | 186 | static int sip_parse_addr(const struct nf_conn *ct, const char *cp, |
187 | const char **endp, union nf_inet_addr *addr, | 187 | const char **endp, union nf_inet_addr *addr, |
188 | const char *limit) | 188 | const char *limit, bool delim) |
189 | { | 189 | { |
190 | const char *end; | 190 | const char *end; |
191 | int ret = 0; | 191 | int ret; |
192 | 192 | ||
193 | if (!ct) | 193 | if (!ct) |
194 | return 0; | 194 | return 0; |
@@ -197,16 +197,28 @@ static int parse_addr(const struct nf_conn *ct, const char *cp, | |||
197 | switch (nf_ct_l3num(ct)) { | 197 | switch (nf_ct_l3num(ct)) { |
198 | case AF_INET: | 198 | case AF_INET: |
199 | ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end); | 199 | ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end); |
200 | if (ret == 0) | ||
201 | return 0; | ||
200 | break; | 202 | break; |
201 | case AF_INET6: | 203 | case AF_INET6: |
204 | if (cp < limit && *cp == '[') | ||
205 | cp++; | ||
206 | else if (delim) | ||
207 | return 0; | ||
208 | |||
202 | ret = in6_pton(cp, limit - cp, (u8 *)&addr->ip6, -1, &end); | 209 | ret = in6_pton(cp, limit - cp, (u8 *)&addr->ip6, -1, &end); |
210 | if (ret == 0) | ||
211 | return 0; | ||
212 | |||
213 | if (end < limit && *end == ']') | ||
214 | end++; | ||
215 | else if (delim) | ||
216 | return 0; | ||
203 | break; | 217 | break; |
204 | default: | 218 | default: |
205 | BUG(); | 219 | BUG(); |
206 | } | 220 | } |
207 | 221 | ||
208 | if (ret == 0 || end == cp) | ||
209 | return 0; | ||
210 | if (endp) | 222 | if (endp) |
211 | *endp = end; | 223 | *endp = end; |
212 | return 1; | 224 | return 1; |
@@ -219,7 +231,7 @@ static int epaddr_len(const struct nf_conn *ct, const char *dptr, | |||
219 | union nf_inet_addr addr; | 231 | union nf_inet_addr addr; |
220 | const char *aux = dptr; | 232 | const char *aux = dptr; |
221 | 233 | ||
222 | if (!parse_addr(ct, dptr, &dptr, &addr, limit)) { | 234 | if (!sip_parse_addr(ct, dptr, &dptr, &addr, limit, true)) { |
223 | pr_debug("ip: %s parse failed.!\n", dptr); | 235 | pr_debug("ip: %s parse failed.!\n", dptr); |
224 | return 0; | 236 | return 0; |
225 | } | 237 | } |
@@ -296,7 +308,7 @@ int ct_sip_parse_request(const struct nf_conn *ct, | |||
296 | return 0; | 308 | return 0; |
297 | dptr += shift; | 309 | dptr += shift; |
298 | 310 | ||
299 | if (!parse_addr(ct, dptr, &end, addr, limit)) | 311 | if (!sip_parse_addr(ct, dptr, &end, addr, limit, true)) |
300 | return -1; | 312 | return -1; |
301 | if (end < limit && *end == ':') { | 313 | if (end < limit && *end == ':') { |
302 | end++; | 314 | end++; |
@@ -550,7 +562,7 @@ int ct_sip_parse_header_uri(const struct nf_conn *ct, const char *dptr, | |||
550 | if (ret == 0) | 562 | if (ret == 0) |
551 | return ret; | 563 | return ret; |
552 | 564 | ||
553 | if (!parse_addr(ct, dptr + *matchoff, &c, addr, limit)) | 565 | if (!sip_parse_addr(ct, dptr + *matchoff, &c, addr, limit, true)) |
554 | return -1; | 566 | return -1; |
555 | if (*c == ':') { | 567 | if (*c == ':') { |
556 | c++; | 568 | c++; |
@@ -599,7 +611,7 @@ int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr, | |||
599 | unsigned int dataoff, unsigned int datalen, | 611 | unsigned int dataoff, unsigned int datalen, |
600 | const char *name, | 612 | const char *name, |
601 | unsigned int *matchoff, unsigned int *matchlen, | 613 | unsigned int *matchoff, unsigned int *matchlen, |
602 | union nf_inet_addr *addr) | 614 | union nf_inet_addr *addr, bool delim) |
603 | { | 615 | { |
604 | const char *limit = dptr + datalen; | 616 | const char *limit = dptr + datalen; |
605 | const char *start, *end; | 617 | const char *start, *end; |
@@ -613,7 +625,7 @@ int ct_sip_parse_address_param(const struct nf_conn *ct, const char *dptr, | |||
613 | return 0; | 625 | return 0; |
614 | 626 | ||
615 | start += strlen(name); | 627 | start += strlen(name); |
616 | if (!parse_addr(ct, start, &end, addr, limit)) | 628 | if (!sip_parse_addr(ct, start, &end, addr, limit, delim)) |
617 | return 0; | 629 | return 0; |
618 | *matchoff = start - dptr; | 630 | *matchoff = start - dptr; |
619 | *matchlen = end - start; | 631 | *matchlen = end - start; |
@@ -675,6 +687,47 @@ static int ct_sip_parse_transport(struct nf_conn *ct, const char *dptr, | |||
675 | return 1; | 687 | return 1; |
676 | } | 688 | } |
677 | 689 | ||
690 | static int sdp_parse_addr(const struct nf_conn *ct, const char *cp, | ||
691 | const char **endp, union nf_inet_addr *addr, | ||
692 | const char *limit) | ||
693 | { | ||
694 | const char *end; | ||
695 | int ret; | ||
696 | |||
697 | memset(addr, 0, sizeof(*addr)); | ||
698 | switch (nf_ct_l3num(ct)) { | ||
699 | case AF_INET: | ||
700 | ret = in4_pton(cp, limit - cp, (u8 *)&addr->ip, -1, &end); | ||
701 | break; | ||
702 | case AF_INET6: | ||
703 | ret = in6_pton(cp, limit - cp, (u8 *)&addr->ip6, -1, &end); | ||
704 | break; | ||
705 | default: | ||
706 | BUG(); | ||
707 | } | ||
708 | |||
709 | if (ret == 0) | ||
710 | return 0; | ||
711 | if (endp) | ||
712 | *endp = end; | ||
713 | return 1; | ||
714 | } | ||
715 | |||
716 | /* skip ip address. returns its length. */ | ||
717 | static int sdp_addr_len(const struct nf_conn *ct, const char *dptr, | ||
718 | const char *limit, int *shift) | ||
719 | { | ||
720 | union nf_inet_addr addr; | ||
721 | const char *aux = dptr; | ||
722 | |||
723 | if (!sdp_parse_addr(ct, dptr, &dptr, &addr, limit)) { | ||
724 | pr_debug("ip: %s parse failed.!\n", dptr); | ||
725 | return 0; | ||
726 | } | ||
727 | |||
728 | return dptr - aux; | ||
729 | } | ||
730 | |||
678 | /* SDP header parsing: a SDP session description contains an ordered set of | 731 | /* SDP header parsing: a SDP session description contains an ordered set of |
679 | * headers, starting with a section containing general session parameters, | 732 | * headers, starting with a section containing general session parameters, |
680 | * optionally followed by multiple media descriptions. | 733 | * optionally followed by multiple media descriptions. |
@@ -686,10 +739,10 @@ static int ct_sip_parse_transport(struct nf_conn *ct, const char *dptr, | |||
686 | */ | 739 | */ |
687 | static const struct sip_header ct_sdp_hdrs[] = { | 740 | static const struct sip_header ct_sdp_hdrs[] = { |
688 | [SDP_HDR_VERSION] = SDP_HDR("v=", NULL, digits_len), | 741 | [SDP_HDR_VERSION] = SDP_HDR("v=", NULL, digits_len), |
689 | [SDP_HDR_OWNER_IP4] = SDP_HDR("o=", "IN IP4 ", epaddr_len), | 742 | [SDP_HDR_OWNER_IP4] = SDP_HDR("o=", "IN IP4 ", sdp_addr_len), |
690 | [SDP_HDR_CONNECTION_IP4] = SDP_HDR("c=", "IN IP4 ", epaddr_len), | 743 | [SDP_HDR_CONNECTION_IP4] = SDP_HDR("c=", "IN IP4 ", sdp_addr_len), |
691 | [SDP_HDR_OWNER_IP6] = SDP_HDR("o=", "IN IP6 ", epaddr_len), | 744 | [SDP_HDR_OWNER_IP6] = SDP_HDR("o=", "IN IP6 ", sdp_addr_len), |
692 | [SDP_HDR_CONNECTION_IP6] = SDP_HDR("c=", "IN IP6 ", epaddr_len), | 745 | [SDP_HDR_CONNECTION_IP6] = SDP_HDR("c=", "IN IP6 ", sdp_addr_len), |
693 | [SDP_HDR_MEDIA] = SDP_HDR("m=", NULL, media_len), | 746 | [SDP_HDR_MEDIA] = SDP_HDR("m=", NULL, media_len), |
694 | }; | 747 | }; |
695 | 748 | ||
@@ -775,8 +828,8 @@ static int ct_sip_parse_sdp_addr(const struct nf_conn *ct, const char *dptr, | |||
775 | if (ret <= 0) | 828 | if (ret <= 0) |
776 | return ret; | 829 | return ret; |
777 | 830 | ||
778 | if (!parse_addr(ct, dptr + *matchoff, NULL, addr, | 831 | if (!sdp_parse_addr(ct, dptr + *matchoff, NULL, addr, |
779 | dptr + *matchoff + *matchlen)) | 832 | dptr + *matchoff + *matchlen)) |
780 | return -1; | 833 | return -1; |
781 | return 1; | 834 | return 1; |
782 | } | 835 | } |
@@ -1515,7 +1568,6 @@ static int sip_help_udp(struct sk_buff *skb, unsigned int protoff, | |||
1515 | } | 1568 | } |
1516 | 1569 | ||
1517 | static struct nf_conntrack_helper sip[MAX_PORTS][4] __read_mostly; | 1570 | static struct nf_conntrack_helper sip[MAX_PORTS][4] __read_mostly; |
1518 | static char sip_names[MAX_PORTS][4][sizeof("sip-65535")] __read_mostly; | ||
1519 | 1571 | ||
1520 | static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1] = { | 1572 | static const struct nf_conntrack_expect_policy sip_exp_policy[SIP_EXPECT_MAX + 1] = { |
1521 | [SIP_EXPECT_SIGNALLING] = { | 1573 | [SIP_EXPECT_SIGNALLING] = { |
@@ -1585,9 +1637,9 @@ static int __init nf_conntrack_sip_init(void) | |||
1585 | sip[i][j].me = THIS_MODULE; | 1637 | sip[i][j].me = THIS_MODULE; |
1586 | 1638 | ||
1587 | if (ports[i] == SIP_PORT) | 1639 | if (ports[i] == SIP_PORT) |
1588 | sprintf(sip_names[i][j], "sip"); | 1640 | sprintf(sip[i][j].name, "sip"); |
1589 | else | 1641 | else |
1590 | sprintf(sip_names[i][j], "sip-%u", i); | 1642 | sprintf(sip[i][j].name, "sip-%u", i); |
1591 | 1643 | ||
1592 | pr_debug("port #%u: %u\n", i, ports[i]); | 1644 | pr_debug("port #%u: %u\n", i, ports[i]); |
1593 | 1645 | ||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 5463969da45b..1445d73533ed 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1362,7 +1362,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1362 | if (NULL == siocb->scm) | 1362 | if (NULL == siocb->scm) |
1363 | siocb->scm = &scm; | 1363 | siocb->scm = &scm; |
1364 | 1364 | ||
1365 | err = scm_send(sock, msg, siocb->scm); | 1365 | err = scm_send(sock, msg, siocb->scm, true); |
1366 | if (err < 0) | 1366 | if (err < 0) |
1367 | return err; | 1367 | return err; |
1368 | 1368 | ||
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c index 226b2cdfc339..fe0912f161ce 100644 --- a/net/packet/af_packet.c +++ b/net/packet/af_packet.c | |||
@@ -966,7 +966,7 @@ static void *packet_current_rx_frame(struct packet_sock *po, | |||
966 | default: | 966 | default: |
967 | WARN(1, "TPACKET version not supported\n"); | 967 | WARN(1, "TPACKET version not supported\n"); |
968 | BUG(); | 968 | BUG(); |
969 | return 0; | 969 | return NULL; |
970 | } | 970 | } |
971 | } | 971 | } |
972 | 972 | ||
@@ -1161,6 +1161,14 @@ static void __fanout_unlink(struct sock *sk, struct packet_sock *po) | |||
1161 | spin_unlock(&f->lock); | 1161 | spin_unlock(&f->lock); |
1162 | } | 1162 | } |
1163 | 1163 | ||
1164 | bool match_fanout_group(struct packet_type *ptype, struct sock * sk) | ||
1165 | { | ||
1166 | if (ptype->af_packet_priv == (void*)((struct packet_sock *)sk)->fanout) | ||
1167 | return true; | ||
1168 | |||
1169 | return false; | ||
1170 | } | ||
1171 | |||
1164 | static int fanout_add(struct sock *sk, u16 id, u16 type_flags) | 1172 | static int fanout_add(struct sock *sk, u16 id, u16 type_flags) |
1165 | { | 1173 | { |
1166 | struct packet_sock *po = pkt_sk(sk); | 1174 | struct packet_sock *po = pkt_sk(sk); |
@@ -1213,6 +1221,7 @@ static int fanout_add(struct sock *sk, u16 id, u16 type_flags) | |||
1213 | match->prot_hook.dev = po->prot_hook.dev; | 1221 | match->prot_hook.dev = po->prot_hook.dev; |
1214 | match->prot_hook.func = packet_rcv_fanout; | 1222 | match->prot_hook.func = packet_rcv_fanout; |
1215 | match->prot_hook.af_packet_priv = match; | 1223 | match->prot_hook.af_packet_priv = match; |
1224 | match->prot_hook.id_match = match_fanout_group; | ||
1216 | dev_add_pack(&match->prot_hook); | 1225 | dev_add_pack(&match->prot_hook); |
1217 | list_add(&match->list, &fanout_list); | 1226 | list_add(&match->list, &fanout_list); |
1218 | } | 1227 | } |
@@ -1824,7 +1833,6 @@ static void tpacket_destruct_skb(struct sk_buff *skb) | |||
1824 | 1833 | ||
1825 | if (likely(po->tx_ring.pg_vec)) { | 1834 | if (likely(po->tx_ring.pg_vec)) { |
1826 | ph = skb_shinfo(skb)->destructor_arg; | 1835 | ph = skb_shinfo(skb)->destructor_arg; |
1827 | BUG_ON(__packet_get_status(po, ph) != TP_STATUS_SENDING); | ||
1828 | BUG_ON(atomic_read(&po->tx_ring.pending) == 0); | 1836 | BUG_ON(atomic_read(&po->tx_ring.pending) == 0); |
1829 | atomic_dec(&po->tx_ring.pending); | 1837 | atomic_dec(&po->tx_ring.pending); |
1830 | __packet_set_status(po, ph, TP_STATUS_AVAILABLE); | 1838 | __packet_set_status(po, ph, TP_STATUS_AVAILABLE); |
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 60e281ad0f07..58fb3c7aab9e 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c | |||
@@ -185,7 +185,12 @@ err3: | |||
185 | err2: | 185 | err2: |
186 | kfree(tname); | 186 | kfree(tname); |
187 | err1: | 187 | err1: |
188 | kfree(pc); | 188 | if (ret == ACT_P_CREATED) { |
189 | if (est) | ||
190 | gen_kill_estimator(&pc->tcfc_bstats, | ||
191 | &pc->tcfc_rate_est); | ||
192 | kfree_rcu(pc, tcfc_rcu); | ||
193 | } | ||
189 | return err; | 194 | return err; |
190 | } | 195 | } |
191 | 196 | ||
diff --git a/net/sched/act_mirred.c b/net/sched/act_mirred.c index fe81cc18e9e0..9c0fd0c78814 100644 --- a/net/sched/act_mirred.c +++ b/net/sched/act_mirred.c | |||
@@ -200,13 +200,12 @@ static int tcf_mirred(struct sk_buff *skb, const struct tc_action *a, | |||
200 | out: | 200 | out: |
201 | if (err) { | 201 | if (err) { |
202 | m->tcf_qstats.overlimits++; | 202 | m->tcf_qstats.overlimits++; |
203 | /* should we be asking for packet to be dropped? | 203 | if (m->tcfm_eaction != TCA_EGRESS_MIRROR) |
204 | * may make sense for redirect case only | 204 | retval = TC_ACT_SHOT; |
205 | */ | 205 | else |
206 | retval = TC_ACT_SHOT; | 206 | retval = m->tcf_action; |
207 | } else { | 207 | } else |
208 | retval = m->tcf_action; | 208 | retval = m->tcf_action; |
209 | } | ||
210 | spin_unlock(&m->tcf_lock); | 209 | spin_unlock(&m->tcf_lock); |
211 | 210 | ||
212 | return retval; | 211 | return retval; |
diff --git a/net/sched/act_pedit.c b/net/sched/act_pedit.c index 26aa2f6ce257..45c53ab067a6 100644 --- a/net/sched/act_pedit.c +++ b/net/sched/act_pedit.c | |||
@@ -74,7 +74,10 @@ static int tcf_pedit_init(struct nlattr *nla, struct nlattr *est, | |||
74 | p = to_pedit(pc); | 74 | p = to_pedit(pc); |
75 | keys = kmalloc(ksize, GFP_KERNEL); | 75 | keys = kmalloc(ksize, GFP_KERNEL); |
76 | if (keys == NULL) { | 76 | if (keys == NULL) { |
77 | kfree(pc); | 77 | if (est) |
78 | gen_kill_estimator(&pc->tcfc_bstats, | ||
79 | &pc->tcfc_rate_est); | ||
80 | kfree_rcu(pc, tcfc_rcu); | ||
78 | return -ENOMEM; | 81 | return -ENOMEM; |
79 | } | 82 | } |
80 | ret = ACT_P_CREATED; | 83 | ret = ACT_P_CREATED; |
diff --git a/net/sched/act_simple.c b/net/sched/act_simple.c index 3922f2a2821b..3714f60f0b3c 100644 --- a/net/sched/act_simple.c +++ b/net/sched/act_simple.c | |||
@@ -131,7 +131,10 @@ static int tcf_simp_init(struct nlattr *nla, struct nlattr *est, | |||
131 | d = to_defact(pc); | 131 | d = to_defact(pc); |
132 | ret = alloc_defdata(d, defdata); | 132 | ret = alloc_defdata(d, defdata); |
133 | if (ret < 0) { | 133 | if (ret < 0) { |
134 | kfree(pc); | 134 | if (est) |
135 | gen_kill_estimator(&pc->tcfc_bstats, | ||
136 | &pc->tcfc_rate_est); | ||
137 | kfree_rcu(pc, tcfc_rcu); | ||
135 | return ret; | 138 | return ret; |
136 | } | 139 | } |
137 | d->tcf_action = parm->action; | 140 | d->tcf_action = parm->action; |
diff --git a/net/sched/sch_qfq.c b/net/sched/sch_qfq.c index 9af01f3df18c..e4723d31fdd5 100644 --- a/net/sched/sch_qfq.c +++ b/net/sched/sch_qfq.c | |||
@@ -203,6 +203,34 @@ out: | |||
203 | return index; | 203 | return index; |
204 | } | 204 | } |
205 | 205 | ||
206 | /* Length of the next packet (0 if the queue is empty). */ | ||
207 | static unsigned int qdisc_peek_len(struct Qdisc *sch) | ||
208 | { | ||
209 | struct sk_buff *skb; | ||
210 | |||
211 | skb = sch->ops->peek(sch); | ||
212 | return skb ? qdisc_pkt_len(skb) : 0; | ||
213 | } | ||
214 | |||
215 | static void qfq_deactivate_class(struct qfq_sched *, struct qfq_class *); | ||
216 | static void qfq_activate_class(struct qfq_sched *q, struct qfq_class *cl, | ||
217 | unsigned int len); | ||
218 | |||
219 | static void qfq_update_class_params(struct qfq_sched *q, struct qfq_class *cl, | ||
220 | u32 lmax, u32 inv_w, int delta_w) | ||
221 | { | ||
222 | int i; | ||
223 | |||
224 | /* update qfq-specific data */ | ||
225 | cl->lmax = lmax; | ||
226 | cl->inv_w = inv_w; | ||
227 | i = qfq_calc_index(cl->inv_w, cl->lmax); | ||
228 | |||
229 | cl->grp = &q->groups[i]; | ||
230 | |||
231 | q->wsum += delta_w; | ||
232 | } | ||
233 | |||
206 | static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | 234 | static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, |
207 | struct nlattr **tca, unsigned long *arg) | 235 | struct nlattr **tca, unsigned long *arg) |
208 | { | 236 | { |
@@ -250,6 +278,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | |||
250 | lmax = 1UL << QFQ_MTU_SHIFT; | 278 | lmax = 1UL << QFQ_MTU_SHIFT; |
251 | 279 | ||
252 | if (cl != NULL) { | 280 | if (cl != NULL) { |
281 | bool need_reactivation = false; | ||
282 | |||
253 | if (tca[TCA_RATE]) { | 283 | if (tca[TCA_RATE]) { |
254 | err = gen_replace_estimator(&cl->bstats, &cl->rate_est, | 284 | err = gen_replace_estimator(&cl->bstats, &cl->rate_est, |
255 | qdisc_root_sleeping_lock(sch), | 285 | qdisc_root_sleeping_lock(sch), |
@@ -258,12 +288,29 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | |||
258 | return err; | 288 | return err; |
259 | } | 289 | } |
260 | 290 | ||
261 | if (inv_w != cl->inv_w) { | 291 | if (lmax == cl->lmax && inv_w == cl->inv_w) |
262 | sch_tree_lock(sch); | 292 | return 0; /* nothing to update */ |
263 | q->wsum += delta_w; | 293 | |
264 | cl->inv_w = inv_w; | 294 | i = qfq_calc_index(inv_w, lmax); |
265 | sch_tree_unlock(sch); | 295 | sch_tree_lock(sch); |
296 | if (&q->groups[i] != cl->grp && cl->qdisc->q.qlen > 0) { | ||
297 | /* | ||
298 | * shift cl->F back, to not charge the | ||
299 | * class for the not-yet-served head | ||
300 | * packet | ||
301 | */ | ||
302 | cl->F = cl->S; | ||
303 | /* remove class from its slot in the old group */ | ||
304 | qfq_deactivate_class(q, cl); | ||
305 | need_reactivation = true; | ||
266 | } | 306 | } |
307 | |||
308 | qfq_update_class_params(q, cl, lmax, inv_w, delta_w); | ||
309 | |||
310 | if (need_reactivation) /* activate in new group */ | ||
311 | qfq_activate_class(q, cl, qdisc_peek_len(cl->qdisc)); | ||
312 | sch_tree_unlock(sch); | ||
313 | |||
267 | return 0; | 314 | return 0; |
268 | } | 315 | } |
269 | 316 | ||
@@ -273,11 +320,8 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | |||
273 | 320 | ||
274 | cl->refcnt = 1; | 321 | cl->refcnt = 1; |
275 | cl->common.classid = classid; | 322 | cl->common.classid = classid; |
276 | cl->lmax = lmax; | ||
277 | cl->inv_w = inv_w; | ||
278 | i = qfq_calc_index(cl->inv_w, cl->lmax); | ||
279 | 323 | ||
280 | cl->grp = &q->groups[i]; | 324 | qfq_update_class_params(q, cl, lmax, inv_w, delta_w); |
281 | 325 | ||
282 | cl->qdisc = qdisc_create_dflt(sch->dev_queue, | 326 | cl->qdisc = qdisc_create_dflt(sch->dev_queue, |
283 | &pfifo_qdisc_ops, classid); | 327 | &pfifo_qdisc_ops, classid); |
@@ -294,7 +338,6 @@ static int qfq_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | |||
294 | return err; | 338 | return err; |
295 | } | 339 | } |
296 | } | 340 | } |
297 | q->wsum += weight; | ||
298 | 341 | ||
299 | sch_tree_lock(sch); | 342 | sch_tree_lock(sch); |
300 | qdisc_class_hash_insert(&q->clhash, &cl->common); | 343 | qdisc_class_hash_insert(&q->clhash, &cl->common); |
@@ -711,15 +754,6 @@ static void qfq_update_eligible(struct qfq_sched *q, u64 old_V) | |||
711 | } | 754 | } |
712 | } | 755 | } |
713 | 756 | ||
714 | /* What is length of next packet in queue (0 if queue is empty) */ | ||
715 | static unsigned int qdisc_peek_len(struct Qdisc *sch) | ||
716 | { | ||
717 | struct sk_buff *skb; | ||
718 | |||
719 | skb = sch->ops->peek(sch); | ||
720 | return skb ? qdisc_pkt_len(skb) : 0; | ||
721 | } | ||
722 | |||
723 | /* | 757 | /* |
724 | * Updates the class, returns true if also the group needs to be updated. | 758 | * Updates the class, returns true if also the group needs to be updated. |
725 | */ | 759 | */ |
@@ -843,11 +877,8 @@ static void qfq_update_start(struct qfq_sched *q, struct qfq_class *cl) | |||
843 | static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | 877 | static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) |
844 | { | 878 | { |
845 | struct qfq_sched *q = qdisc_priv(sch); | 879 | struct qfq_sched *q = qdisc_priv(sch); |
846 | struct qfq_group *grp; | ||
847 | struct qfq_class *cl; | 880 | struct qfq_class *cl; |
848 | int err; | 881 | int err; |
849 | u64 roundedS; | ||
850 | int s; | ||
851 | 882 | ||
852 | cl = qfq_classify(skb, sch, &err); | 883 | cl = qfq_classify(skb, sch, &err); |
853 | if (cl == NULL) { | 884 | if (cl == NULL) { |
@@ -876,11 +907,25 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
876 | return err; | 907 | return err; |
877 | 908 | ||
878 | /* If reach this point, queue q was idle */ | 909 | /* If reach this point, queue q was idle */ |
879 | grp = cl->grp; | 910 | qfq_activate_class(q, cl, qdisc_pkt_len(skb)); |
911 | |||
912 | return err; | ||
913 | } | ||
914 | |||
915 | /* | ||
916 | * Handle class switch from idle to backlogged. | ||
917 | */ | ||
918 | static void qfq_activate_class(struct qfq_sched *q, struct qfq_class *cl, | ||
919 | unsigned int pkt_len) | ||
920 | { | ||
921 | struct qfq_group *grp = cl->grp; | ||
922 | u64 roundedS; | ||
923 | int s; | ||
924 | |||
880 | qfq_update_start(q, cl); | 925 | qfq_update_start(q, cl); |
881 | 926 | ||
882 | /* compute new finish time and rounded start. */ | 927 | /* compute new finish time and rounded start. */ |
883 | cl->F = cl->S + (u64)qdisc_pkt_len(skb) * cl->inv_w; | 928 | cl->F = cl->S + (u64)pkt_len * cl->inv_w; |
884 | roundedS = qfq_round_down(cl->S, grp->slot_shift); | 929 | roundedS = qfq_round_down(cl->S, grp->slot_shift); |
885 | 930 | ||
886 | /* | 931 | /* |
@@ -917,8 +962,6 @@ static int qfq_enqueue(struct sk_buff *skb, struct Qdisc *sch) | |||
917 | 962 | ||
918 | skip_update: | 963 | skip_update: |
919 | qfq_slot_insert(grp, cl, roundedS); | 964 | qfq_slot_insert(grp, cl, roundedS); |
920 | |||
921 | return err; | ||
922 | } | 965 | } |
923 | 966 | ||
924 | 967 | ||
diff --git a/net/socket.c b/net/socket.c index dfe5b66c97e0..a5471f804d99 100644 --- a/net/socket.c +++ b/net/socket.c | |||
@@ -2657,6 +2657,7 @@ static int dev_ifconf(struct net *net, struct compat_ifconf __user *uifc32) | |||
2657 | if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf))) | 2657 | if (copy_from_user(&ifc32, uifc32, sizeof(struct compat_ifconf))) |
2658 | return -EFAULT; | 2658 | return -EFAULT; |
2659 | 2659 | ||
2660 | memset(&ifc, 0, sizeof(ifc)); | ||
2660 | if (ifc32.ifcbuf == 0) { | 2661 | if (ifc32.ifcbuf == 0) { |
2661 | ifc32.ifc_len = 0; | 2662 | ifc32.ifc_len = 0; |
2662 | ifc.ifc_len = 0; | 2663 | ifc.ifc_len = 0; |
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index e4768c180da2..c5ee4ff61364 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c | |||
@@ -1450,7 +1450,7 @@ static int unix_dgram_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1450 | if (NULL == siocb->scm) | 1450 | if (NULL == siocb->scm) |
1451 | siocb->scm = &tmp_scm; | 1451 | siocb->scm = &tmp_scm; |
1452 | wait_for_unix_gc(); | 1452 | wait_for_unix_gc(); |
1453 | err = scm_send(sock, msg, siocb->scm); | 1453 | err = scm_send(sock, msg, siocb->scm, false); |
1454 | if (err < 0) | 1454 | if (err < 0) |
1455 | return err; | 1455 | return err; |
1456 | 1456 | ||
@@ -1619,7 +1619,7 @@ static int unix_stream_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
1619 | if (NULL == siocb->scm) | 1619 | if (NULL == siocb->scm) |
1620 | siocb->scm = &tmp_scm; | 1620 | siocb->scm = &tmp_scm; |
1621 | wait_for_unix_gc(); | 1621 | wait_for_unix_gc(); |
1622 | err = scm_send(sock, msg, siocb->scm); | 1622 | err = scm_send(sock, msg, siocb->scm, false); |
1623 | if (err < 0) | 1623 | if (err < 0) |
1624 | return err; | 1624 | return err; |
1625 | 1625 | ||
diff --git a/net/wireless/core.c b/net/wireless/core.c index 31b40cc4a9c3..dcd64d5b07aa 100644 --- a/net/wireless/core.c +++ b/net/wireless/core.c | |||
@@ -952,6 +952,11 @@ static int cfg80211_netdev_notifier_call(struct notifier_block *nb, | |||
952 | */ | 952 | */ |
953 | synchronize_rcu(); | 953 | synchronize_rcu(); |
954 | INIT_LIST_HEAD(&wdev->list); | 954 | INIT_LIST_HEAD(&wdev->list); |
955 | /* | ||
956 | * Ensure that all events have been processed and | ||
957 | * freed. | ||
958 | */ | ||
959 | cfg80211_process_wdev_events(wdev); | ||
955 | break; | 960 | break; |
956 | case NETDEV_PRE_UP: | 961 | case NETDEV_PRE_UP: |
957 | if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) | 962 | if (!(wdev->wiphy->interface_modes & BIT(wdev->iftype))) |
diff --git a/net/wireless/core.h b/net/wireless/core.h index 5206c6844fd7..bc7430b54771 100644 --- a/net/wireless/core.h +++ b/net/wireless/core.h | |||
@@ -426,6 +426,7 @@ int cfg80211_change_iface(struct cfg80211_registered_device *rdev, | |||
426 | struct net_device *dev, enum nl80211_iftype ntype, | 426 | struct net_device *dev, enum nl80211_iftype ntype, |
427 | u32 *flags, struct vif_params *params); | 427 | u32 *flags, struct vif_params *params); |
428 | void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); | 428 | void cfg80211_process_rdev_events(struct cfg80211_registered_device *rdev); |
429 | void cfg80211_process_wdev_events(struct wireless_dev *wdev); | ||
429 | 430 | ||
430 | int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, | 431 | int cfg80211_can_use_iftype_chan(struct cfg80211_registered_device *rdev, |
431 | struct wireless_dev *wdev, | 432 | struct wireless_dev *wdev, |
diff --git a/net/wireless/util.c b/net/wireless/util.c index 26f8cd30f712..994e2f0cc7a8 100644 --- a/net/wireless/util.c +++ b/net/wireless/util.c | |||
@@ -735,7 +735,7 @@ void cfg80211_upload_connect_keys(struct wireless_dev *wdev) | |||
735 | wdev->connect_keys = NULL; | 735 | wdev->connect_keys = NULL; |
736 | } | 736 | } |
737 | 737 | ||
738 | static void cfg80211_process_wdev_events(struct wireless_dev *wdev) | 738 | void cfg80211_process_wdev_events(struct wireless_dev *wdev) |
739 | { | 739 | { |
740 | struct cfg80211_event *ev; | 740 | struct cfg80211_event *ev; |
741 | unsigned long flags; | 741 | unsigned long flags; |
diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c index 6405764eaa82..2ed698c190b5 100644 --- a/net/xfrm/xfrm_policy.c +++ b/net/xfrm/xfrm_policy.c | |||
@@ -1358,6 +1358,8 @@ static inline struct xfrm_dst *xfrm_alloc_dst(struct net *net, int family) | |||
1358 | 1358 | ||
1359 | memset(dst + 1, 0, sizeof(*xdst) - sizeof(*dst)); | 1359 | memset(dst + 1, 0, sizeof(*xdst) - sizeof(*dst)); |
1360 | xdst->flo.ops = &xfrm_bundle_fc_ops; | 1360 | xdst->flo.ops = &xfrm_bundle_fc_ops; |
1361 | if (afinfo->init_dst) | ||
1362 | afinfo->init_dst(net, xdst); | ||
1361 | } else | 1363 | } else |
1362 | xdst = ERR_PTR(-ENOBUFS); | 1364 | xdst = ERR_PTR(-ENOBUFS); |
1363 | 1365 | ||
diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index 913d6bdfdda3..ca05ba217f5f 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl | |||
@@ -3016,7 +3016,8 @@ sub process { | |||
3016 | $herectx .= raw_line($linenr, $n) . "\n"; | 3016 | $herectx .= raw_line($linenr, $n) . "\n"; |
3017 | } | 3017 | } |
3018 | 3018 | ||
3019 | if (($stmts =~ tr/;/;/) == 1) { | 3019 | if (($stmts =~ tr/;/;/) == 1 && |
3020 | $stmts !~ /^\s*(if|while|for|switch)\b/) { | ||
3020 | WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", | 3021 | WARN("SINGLE_STATEMENT_DO_WHILE_MACRO", |
3021 | "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); | 3022 | "Single statement macros should not use a do {} while (0) loop\n" . "$herectx"); |
3022 | } | 3023 | } |
diff --git a/scripts/decodecode b/scripts/decodecode index 18ba881c3415..4f8248d5a11f 100755 --- a/scripts/decodecode +++ b/scripts/decodecode | |||
@@ -89,7 +89,7 @@ echo $code >> $T.s | |||
89 | disas $T | 89 | disas $T |
90 | cat $T.dis >> $T.aa | 90 | cat $T.dis >> $T.aa |
91 | 91 | ||
92 | faultline=`cat $T.dis | head -1 | cut -d":" -f2` | 92 | faultline=`cat $T.dis | head -1 | cut -d":" -f2-` |
93 | faultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'` | 93 | faultline=`echo "$faultline" | sed -e 's/\[/\\\[/g; s/\]/\\\]/g'` |
94 | 94 | ||
95 | cat $T.oo | sed -e "s/\($faultline\)/\*\1 <-- trapping instruction/g" | 95 | cat $T.oo | sed -e "s/\($faultline\)/\*\1 <-- trapping instruction/g" |
diff --git a/scripts/kernel-doc b/scripts/kernel-doc index 9b0c0b8b4ab4..8fd107a3fac4 100755 --- a/scripts/kernel-doc +++ b/scripts/kernel-doc | |||
@@ -1786,6 +1786,7 @@ sub dump_function($$) { | |||
1786 | $prototype =~ s/__init +//; | 1786 | $prototype =~ s/__init +//; |
1787 | $prototype =~ s/__init_or_module +//; | 1787 | $prototype =~ s/__init_or_module +//; |
1788 | $prototype =~ s/__must_check +//; | 1788 | $prototype =~ s/__must_check +//; |
1789 | $prototype =~ s/__weak +//; | ||
1789 | $prototype =~ s/^#\s*define\s+//; #ak added | 1790 | $prototype =~ s/^#\s*define\s+//; #ak added |
1790 | $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//; | 1791 | $prototype =~ s/__attribute__\s*\(\([a-z,]*\)\)//; |
1791 | 1792 | ||
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c index 83554ee8a587..0cc99a3ea42d 100644 --- a/security/yama/yama_lsm.c +++ b/security/yama/yama_lsm.c | |||
@@ -279,12 +279,46 @@ static int yama_ptrace_access_check(struct task_struct *child, | |||
279 | } | 279 | } |
280 | 280 | ||
281 | if (rc) { | 281 | if (rc) { |
282 | char name[sizeof(current->comm)]; | ||
283 | printk_ratelimited(KERN_NOTICE | 282 | printk_ratelimited(KERN_NOTICE |
284 | "ptrace of pid %d was attempted by: %s (pid %d)\n", | 283 | "ptrace of pid %d was attempted by: %s (pid %d)\n", |
285 | child->pid, | 284 | child->pid, current->comm, current->pid); |
286 | get_task_comm(name, current), | 285 | } |
287 | current->pid); | 286 | |
287 | return rc; | ||
288 | } | ||
289 | |||
290 | /** | ||
291 | * yama_ptrace_traceme - validate PTRACE_TRACEME calls | ||
292 | * @parent: task that will become the ptracer of the current task | ||
293 | * | ||
294 | * Returns 0 if following the ptrace is allowed, -ve on error. | ||
295 | */ | ||
296 | static int yama_ptrace_traceme(struct task_struct *parent) | ||
297 | { | ||
298 | int rc; | ||
299 | |||
300 | /* If standard caps disallows it, so does Yama. We should | ||
301 | * only tighten restrictions further. | ||
302 | */ | ||
303 | rc = cap_ptrace_traceme(parent); | ||
304 | if (rc) | ||
305 | return rc; | ||
306 | |||
307 | /* Only disallow PTRACE_TRACEME on more aggressive settings. */ | ||
308 | switch (ptrace_scope) { | ||
309 | case YAMA_SCOPE_CAPABILITY: | ||
310 | if (!ns_capable(task_user_ns(parent), CAP_SYS_PTRACE)) | ||
311 | rc = -EPERM; | ||
312 | break; | ||
313 | case YAMA_SCOPE_NO_ATTACH: | ||
314 | rc = -EPERM; | ||
315 | break; | ||
316 | } | ||
317 | |||
318 | if (rc) { | ||
319 | printk_ratelimited(KERN_NOTICE | ||
320 | "ptraceme of pid %d was attempted by: %s (pid %d)\n", | ||
321 | current->pid, parent->comm, parent->pid); | ||
288 | } | 322 | } |
289 | 323 | ||
290 | return rc; | 324 | return rc; |
@@ -294,6 +328,7 @@ static struct security_operations yama_ops = { | |||
294 | .name = "yama", | 328 | .name = "yama", |
295 | 329 | ||
296 | .ptrace_access_check = yama_ptrace_access_check, | 330 | .ptrace_access_check = yama_ptrace_access_check, |
331 | .ptrace_traceme = yama_ptrace_traceme, | ||
297 | .task_prctl = yama_task_prctl, | 332 | .task_prctl = yama_task_prctl, |
298 | .task_free = yama_task_free, | 333 | .task_free = yama_task_free, |
299 | }; | 334 | }; |
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c index 0d7b25e81643..4e1fda75c1c9 100644 --- a/sound/arm/pxa2xx-ac97.c +++ b/sound/arm/pxa2xx-ac97.c | |||
@@ -106,7 +106,7 @@ static struct pxa2xx_pcm_client pxa2xx_ac97_pcm_client = { | |||
106 | .prepare = pxa2xx_ac97_pcm_prepare, | 106 | .prepare = pxa2xx_ac97_pcm_prepare, |
107 | }; | 107 | }; |
108 | 108 | ||
109 | #ifdef CONFIG_PM | 109 | #ifdef CONFIG_PM_SLEEP |
110 | 110 | ||
111 | static int pxa2xx_ac97_do_suspend(struct snd_card *card) | 111 | static int pxa2xx_ac97_do_suspend(struct snd_card *card) |
112 | { | 112 | { |
@@ -243,7 +243,7 @@ static struct platform_driver pxa2xx_ac97_driver = { | |||
243 | .driver = { | 243 | .driver = { |
244 | .name = "pxa2xx-ac97", | 244 | .name = "pxa2xx-ac97", |
245 | .owner = THIS_MODULE, | 245 | .owner = THIS_MODULE, |
246 | #ifdef CONFIG_PM | 246 | #ifdef CONFIG_PM_SLEEP |
247 | .pm = &pxa2xx_ac97_pm_ops, | 247 | .pm = &pxa2xx_ac97_pm_ops, |
248 | #endif | 248 | #endif |
249 | }, | 249 | }, |
diff --git a/sound/atmel/abdac.c b/sound/atmel/abdac.c index eb4ceb71123e..277ebce23a45 100644 --- a/sound/atmel/abdac.c +++ b/sound/atmel/abdac.c | |||
@@ -452,6 +452,7 @@ static int __devinit atmel_abdac_probe(struct platform_device *pdev) | |||
452 | dac->regs = ioremap(regs->start, resource_size(regs)); | 452 | dac->regs = ioremap(regs->start, resource_size(regs)); |
453 | if (!dac->regs) { | 453 | if (!dac->regs) { |
454 | dev_dbg(&pdev->dev, "could not remap register memory\n"); | 454 | dev_dbg(&pdev->dev, "could not remap register memory\n"); |
455 | retval = -ENOMEM; | ||
455 | goto out_free_card; | 456 | goto out_free_card; |
456 | } | 457 | } |
457 | 458 | ||
@@ -534,7 +535,7 @@ out_put_pclk: | |||
534 | return retval; | 535 | return retval; |
535 | } | 536 | } |
536 | 537 | ||
537 | #ifdef CONFIG_PM | 538 | #ifdef CONFIG_PM_SLEEP |
538 | static int atmel_abdac_suspend(struct device *pdev) | 539 | static int atmel_abdac_suspend(struct device *pdev) |
539 | { | 540 | { |
540 | struct snd_card *card = dev_get_drvdata(pdev); | 541 | struct snd_card *card = dev_get_drvdata(pdev); |
diff --git a/sound/atmel/ac97c.c b/sound/atmel/ac97c.c index bf47025bdf45..9052aff37f64 100644 --- a/sound/atmel/ac97c.c +++ b/sound/atmel/ac97c.c | |||
@@ -278,14 +278,9 @@ static int atmel_ac97c_capture_hw_params(struct snd_pcm_substream *substream, | |||
278 | if (retval < 0) | 278 | if (retval < 0) |
279 | return retval; | 279 | return retval; |
280 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ | 280 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ |
281 | if (cpu_is_at32ap7000()) { | 281 | if (cpu_is_at32ap7000() && retval == 1) |
282 | if (retval < 0) | 282 | if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) |
283 | return retval; | 283 | dw_dma_cyclic_free(chip->dma.rx_chan); |
284 | /* snd_pcm_lib_malloc_pages returns 1 if buffer is changed. */ | ||
285 | if (retval == 1) | ||
286 | if (test_and_clear_bit(DMA_RX_READY, &chip->flags)) | ||
287 | dw_dma_cyclic_free(chip->dma.rx_chan); | ||
288 | } | ||
289 | 284 | ||
290 | /* Set restrictions to params. */ | 285 | /* Set restrictions to params. */ |
291 | mutex_lock(&opened_mutex); | 286 | mutex_lock(&opened_mutex); |
@@ -980,6 +975,7 @@ static int __devinit atmel_ac97c_probe(struct platform_device *pdev) | |||
980 | 975 | ||
981 | if (!chip->regs) { | 976 | if (!chip->regs) { |
982 | dev_dbg(&pdev->dev, "could not remap register memory\n"); | 977 | dev_dbg(&pdev->dev, "could not remap register memory\n"); |
978 | retval = -ENOMEM; | ||
983 | goto err_ioremap; | 979 | goto err_ioremap; |
984 | } | 980 | } |
985 | 981 | ||
@@ -1134,7 +1130,7 @@ err_snd_card_new: | |||
1134 | return retval; | 1130 | return retval; |
1135 | } | 1131 | } |
1136 | 1132 | ||
1137 | #ifdef CONFIG_PM | 1133 | #ifdef CONFIG_PM_SLEEP |
1138 | static int atmel_ac97c_suspend(struct device *pdev) | 1134 | static int atmel_ac97c_suspend(struct device *pdev) |
1139 | { | 1135 | { |
1140 | struct snd_card *card = dev_get_drvdata(pdev); | 1136 | struct snd_card *card = dev_get_drvdata(pdev); |
diff --git a/sound/core/sgbuf.c b/sound/core/sgbuf.c index 4e7ec2b49873..d0f00356fc11 100644 --- a/sound/core/sgbuf.c +++ b/sound/core/sgbuf.c | |||
@@ -101,7 +101,7 @@ void *snd_malloc_sgbuf_pages(struct device *device, | |||
101 | if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, device, | 101 | if (snd_dma_alloc_pages_fallback(SNDRV_DMA_TYPE_DEV, device, |
102 | chunk, &tmpb) < 0) { | 102 | chunk, &tmpb) < 0) { |
103 | if (!sgbuf->pages) | 103 | if (!sgbuf->pages) |
104 | return NULL; | 104 | goto _failed; |
105 | if (!res_size) | 105 | if (!res_size) |
106 | goto _failed; | 106 | goto _failed; |
107 | size = sgbuf->pages * PAGE_SIZE; | 107 | size = sgbuf->pages * PAGE_SIZE; |
diff --git a/sound/drivers/aloop.c b/sound/drivers/aloop.c index 1128b35b2b05..5a34355e78e8 100644 --- a/sound/drivers/aloop.c +++ b/sound/drivers/aloop.c | |||
@@ -1176,7 +1176,7 @@ static int __devexit loopback_remove(struct platform_device *devptr) | |||
1176 | return 0; | 1176 | return 0; |
1177 | } | 1177 | } |
1178 | 1178 | ||
1179 | #ifdef CONFIG_PM | 1179 | #ifdef CONFIG_PM_SLEEP |
1180 | static int loopback_suspend(struct device *pdev) | 1180 | static int loopback_suspend(struct device *pdev) |
1181 | { | 1181 | { |
1182 | struct snd_card *card = dev_get_drvdata(pdev); | 1182 | struct snd_card *card = dev_get_drvdata(pdev); |
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c index f7d3bfc6bca8..54bb6644a598 100644 --- a/sound/drivers/dummy.c +++ b/sound/drivers/dummy.c | |||
@@ -1064,7 +1064,7 @@ static int __devexit snd_dummy_remove(struct platform_device *devptr) | |||
1064 | return 0; | 1064 | return 0; |
1065 | } | 1065 | } |
1066 | 1066 | ||
1067 | #ifdef CONFIG_PM | 1067 | #ifdef CONFIG_PM_SLEEP |
1068 | static int snd_dummy_suspend(struct device *pdev) | 1068 | static int snd_dummy_suspend(struct device *pdev) |
1069 | { | 1069 | { |
1070 | struct snd_card *card = dev_get_drvdata(pdev); | 1070 | struct snd_card *card = dev_get_drvdata(pdev); |
diff --git a/sound/drivers/pcsp/pcsp.c b/sound/drivers/pcsp/pcsp.c index 6ca59fc6dcb9..ef171295f6d4 100644 --- a/sound/drivers/pcsp/pcsp.c +++ b/sound/drivers/pcsp/pcsp.c | |||
@@ -199,7 +199,7 @@ static void pcsp_stop_beep(struct snd_pcsp *chip) | |||
199 | pcspkr_stop_sound(); | 199 | pcspkr_stop_sound(); |
200 | } | 200 | } |
201 | 201 | ||
202 | #ifdef CONFIG_PM | 202 | #ifdef CONFIG_PM_SLEEP |
203 | static int pcsp_suspend(struct device *dev) | 203 | static int pcsp_suspend(struct device *dev) |
204 | { | 204 | { |
205 | struct snd_pcsp *chip = dev_get_drvdata(dev); | 205 | struct snd_pcsp *chip = dev_get_drvdata(dev); |
@@ -212,7 +212,7 @@ static SIMPLE_DEV_PM_OPS(pcsp_pm, pcsp_suspend, NULL); | |||
212 | #define PCSP_PM_OPS &pcsp_pm | 212 | #define PCSP_PM_OPS &pcsp_pm |
213 | #else | 213 | #else |
214 | #define PCSP_PM_OPS NULL | 214 | #define PCSP_PM_OPS NULL |
215 | #endif /* CONFIG_PM */ | 215 | #endif /* CONFIG_PM_SLEEP */ |
216 | 216 | ||
217 | static void pcsp_shutdown(struct platform_device *dev) | 217 | static void pcsp_shutdown(struct platform_device *dev) |
218 | { | 218 | { |
diff --git a/sound/isa/als100.c b/sound/isa/als100.c index 2d67c78c9f4b..f7cdaf51512d 100644 --- a/sound/isa/als100.c +++ b/sound/isa/als100.c | |||
@@ -233,7 +233,7 @@ static int __devinit snd_card_als100_probe(int dev, | |||
233 | irq[dev], dma8[dev], dma16[dev]); | 233 | irq[dev], dma8[dev], dma16[dev]); |
234 | } | 234 | } |
235 | 235 | ||
236 | if ((error = snd_sb16dsp_pcm(chip, 0, NULL)) < 0) { | 236 | if ((error = snd_sb16dsp_pcm(chip, 0, &chip->pcm)) < 0) { |
237 | snd_card_free(card); | 237 | snd_card_free(card); |
238 | return error; | 238 | return error; |
239 | } | 239 | } |
diff --git a/sound/oss/sb_audio.c b/sound/oss/sb_audio.c index 733b014ec7d1..b2b3c014221a 100644 --- a/sound/oss/sb_audio.c +++ b/sound/oss/sb_audio.c | |||
@@ -575,13 +575,15 @@ static int jazz16_audio_set_speed(int dev, int speed) | |||
575 | if (speed > 0) | 575 | if (speed > 0) |
576 | { | 576 | { |
577 | int tmp; | 577 | int tmp; |
578 | int s = speed * devc->channels; | 578 | int s; |
579 | 579 | ||
580 | if (speed < 5000) | 580 | if (speed < 5000) |
581 | speed = 5000; | 581 | speed = 5000; |
582 | if (speed > 44100) | 582 | if (speed > 44100) |
583 | speed = 44100; | 583 | speed = 44100; |
584 | 584 | ||
585 | s = speed * devc->channels; | ||
586 | |||
585 | devc->tconst = (256 - ((1000000 + s / 2) / s)) & 0xff; | 587 | devc->tconst = (256 - ((1000000 + s / 2) / s)) & 0xff; |
586 | 588 | ||
587 | tmp = 256 - devc->tconst; | 589 | tmp = 256 - devc->tconst; |
diff --git a/sound/pci/cs46xx/cs46xx_lib.c b/sound/pci/cs46xx/cs46xx_lib.c index f75f5ffdfdfb..a71d1c14a0f6 100644 --- a/sound/pci/cs46xx/cs46xx_lib.c +++ b/sound/pci/cs46xx/cs46xx_lib.c | |||
@@ -94,7 +94,7 @@ static unsigned short snd_cs46xx_codec_read(struct snd_cs46xx *chip, | |||
94 | 94 | ||
95 | if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX && | 95 | if (snd_BUG_ON(codec_index != CS46XX_PRIMARY_CODEC_INDEX && |
96 | codec_index != CS46XX_SECONDARY_CODEC_INDEX)) | 96 | codec_index != CS46XX_SECONDARY_CODEC_INDEX)) |
97 | return -EINVAL; | 97 | return 0xffff; |
98 | 98 | ||
99 | chip->active_ctrl(chip, 1); | 99 | chip->active_ctrl(chip, 1); |
100 | 100 | ||
diff --git a/sound/pci/ctxfi/ctatc.c b/sound/pci/ctxfi/ctatc.c index 8e40262d4117..2f6e9c762d3f 100644 --- a/sound/pci/ctxfi/ctatc.c +++ b/sound/pci/ctxfi/ctatc.c | |||
@@ -1725,8 +1725,10 @@ int __devinit ct_atc_create(struct snd_card *card, struct pci_dev *pci, | |||
1725 | atc_connect_resources(atc); | 1725 | atc_connect_resources(atc); |
1726 | 1726 | ||
1727 | atc->timer = ct_timer_new(atc); | 1727 | atc->timer = ct_timer_new(atc); |
1728 | if (!atc->timer) | 1728 | if (!atc->timer) { |
1729 | err = -ENOMEM; | ||
1729 | goto error1; | 1730 | goto error1; |
1731 | } | ||
1730 | 1732 | ||
1731 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops); | 1733 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, atc, &ops); |
1732 | if (err < 0) | 1734 | if (err < 0) |
diff --git a/sound/pci/emu10k1/memory.c b/sound/pci/emu10k1/memory.c index 4f502a2bdc3c..0a436626182b 100644 --- a/sound/pci/emu10k1/memory.c +++ b/sound/pci/emu10k1/memory.c | |||
@@ -326,7 +326,10 @@ snd_emu10k1_alloc_pages(struct snd_emu10k1 *emu, struct snd_pcm_substream *subst | |||
326 | for (page = blk->first_page; page <= blk->last_page; page++, idx++) { | 326 | for (page = blk->first_page; page <= blk->last_page; page++, idx++) { |
327 | unsigned long ofs = idx << PAGE_SHIFT; | 327 | unsigned long ofs = idx << PAGE_SHIFT; |
328 | dma_addr_t addr; | 328 | dma_addr_t addr; |
329 | addr = snd_pcm_sgbuf_get_addr(substream, ofs); | 329 | if (ofs >= runtime->dma_bytes) |
330 | addr = emu->silent_page.addr; | ||
331 | else | ||
332 | addr = snd_pcm_sgbuf_get_addr(substream, ofs); | ||
330 | if (! is_valid_page(emu, addr)) { | 333 | if (! is_valid_page(emu, addr)) { |
331 | printk(KERN_ERR "emu: failure page = %d\n", idx); | 334 | printk(KERN_ERR "emu: failure page = %d\n", idx); |
332 | mutex_unlock(&hdr->block_mutex); | 335 | mutex_unlock(&hdr->block_mutex); |
diff --git a/sound/pci/hda/hda_auto_parser.c b/sound/pci/hda/hda_auto_parser.c index 647218d69f68..4f7d2dfcef7b 100644 --- a/sound/pci/hda/hda_auto_parser.c +++ b/sound/pci/hda/hda_auto_parser.c | |||
@@ -332,13 +332,12 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, | |||
332 | if (cfg->dig_outs) | 332 | if (cfg->dig_outs) |
333 | snd_printd(" dig-out=0x%x/0x%x\n", | 333 | snd_printd(" dig-out=0x%x/0x%x\n", |
334 | cfg->dig_out_pins[0], cfg->dig_out_pins[1]); | 334 | cfg->dig_out_pins[0], cfg->dig_out_pins[1]); |
335 | snd_printd(" inputs:"); | 335 | snd_printd(" inputs:\n"); |
336 | for (i = 0; i < cfg->num_inputs; i++) { | 336 | for (i = 0; i < cfg->num_inputs; i++) { |
337 | snd_printd(" %s=0x%x", | 337 | snd_printd(" %s=0x%x\n", |
338 | hda_get_autocfg_input_label(codec, cfg, i), | 338 | hda_get_autocfg_input_label(codec, cfg, i), |
339 | cfg->inputs[i].pin); | 339 | cfg->inputs[i].pin); |
340 | } | 340 | } |
341 | snd_printd("\n"); | ||
342 | if (cfg->dig_in_pin) | 341 | if (cfg->dig_in_pin) |
343 | snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin); | 342 | snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin); |
344 | 343 | ||
diff --git a/sound/pci/hda/hda_beep.c b/sound/pci/hda/hda_beep.c index 0bc2315b181d..0849aac449f2 100644 --- a/sound/pci/hda/hda_beep.c +++ b/sound/pci/hda/hda_beep.c | |||
@@ -231,16 +231,22 @@ void snd_hda_detach_beep_device(struct hda_codec *codec) | |||
231 | } | 231 | } |
232 | EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device); | 232 | EXPORT_SYMBOL_HDA(snd_hda_detach_beep_device); |
233 | 233 | ||
234 | static bool ctl_has_mute(struct snd_kcontrol *kcontrol) | ||
235 | { | ||
236 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
237 | return query_amp_caps(codec, get_amp_nid(kcontrol), | ||
238 | get_amp_direction(kcontrol)) & AC_AMPCAP_MUTE; | ||
239 | } | ||
240 | |||
234 | /* get/put callbacks for beep mute mixer switches */ | 241 | /* get/put callbacks for beep mute mixer switches */ |
235 | int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, | 242 | int snd_hda_mixer_amp_switch_get_beep(struct snd_kcontrol *kcontrol, |
236 | struct snd_ctl_elem_value *ucontrol) | 243 | struct snd_ctl_elem_value *ucontrol) |
237 | { | 244 | { |
238 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 245 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
239 | struct hda_beep *beep = codec->beep; | 246 | struct hda_beep *beep = codec->beep; |
240 | if (beep) { | 247 | if (beep && (!beep->enabled || !ctl_has_mute(kcontrol))) { |
241 | ucontrol->value.integer.value[0] = | 248 | ucontrol->value.integer.value[0] = |
242 | ucontrol->value.integer.value[1] = | 249 | ucontrol->value.integer.value[1] = beep->enabled; |
243 | beep->enabled; | ||
244 | return 0; | 250 | return 0; |
245 | } | 251 | } |
246 | return snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); | 252 | return snd_hda_mixer_amp_switch_get(kcontrol, ucontrol); |
@@ -252,9 +258,20 @@ int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol, | |||
252 | { | 258 | { |
253 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 259 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
254 | struct hda_beep *beep = codec->beep; | 260 | struct hda_beep *beep = codec->beep; |
255 | if (beep) | 261 | if (beep) { |
256 | snd_hda_enable_beep_device(codec, | 262 | u8 chs = get_amp_channels(kcontrol); |
257 | *ucontrol->value.integer.value); | 263 | int enable = 0; |
264 | long *valp = ucontrol->value.integer.value; | ||
265 | if (chs & 1) { | ||
266 | enable |= *valp; | ||
267 | valp++; | ||
268 | } | ||
269 | if (chs & 2) | ||
270 | enable |= *valp; | ||
271 | snd_hda_enable_beep_device(codec, enable); | ||
272 | } | ||
273 | if (!ctl_has_mute(kcontrol)) | ||
274 | return 0; | ||
258 | return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | 275 | return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); |
259 | } | 276 | } |
260 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep); | 277 | EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep); |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 88a9c20eb7a2..f560051a949e 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -1386,6 +1386,44 @@ int snd_hda_codec_configure(struct hda_codec *codec) | |||
1386 | } | 1386 | } |
1387 | EXPORT_SYMBOL_HDA(snd_hda_codec_configure); | 1387 | EXPORT_SYMBOL_HDA(snd_hda_codec_configure); |
1388 | 1388 | ||
1389 | /* update the stream-id if changed */ | ||
1390 | static void update_pcm_stream_id(struct hda_codec *codec, | ||
1391 | struct hda_cvt_setup *p, hda_nid_t nid, | ||
1392 | u32 stream_tag, int channel_id) | ||
1393 | { | ||
1394 | unsigned int oldval, newval; | ||
1395 | |||
1396 | if (p->stream_tag != stream_tag || p->channel_id != channel_id) { | ||
1397 | oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | ||
1398 | newval = (stream_tag << 4) | channel_id; | ||
1399 | if (oldval != newval) | ||
1400 | snd_hda_codec_write(codec, nid, 0, | ||
1401 | AC_VERB_SET_CHANNEL_STREAMID, | ||
1402 | newval); | ||
1403 | p->stream_tag = stream_tag; | ||
1404 | p->channel_id = channel_id; | ||
1405 | } | ||
1406 | } | ||
1407 | |||
1408 | /* update the format-id if changed */ | ||
1409 | static void update_pcm_format(struct hda_codec *codec, struct hda_cvt_setup *p, | ||
1410 | hda_nid_t nid, int format) | ||
1411 | { | ||
1412 | unsigned int oldval; | ||
1413 | |||
1414 | if (p->format_id != format) { | ||
1415 | oldval = snd_hda_codec_read(codec, nid, 0, | ||
1416 | AC_VERB_GET_STREAM_FORMAT, 0); | ||
1417 | if (oldval != format) { | ||
1418 | msleep(1); | ||
1419 | snd_hda_codec_write(codec, nid, 0, | ||
1420 | AC_VERB_SET_STREAM_FORMAT, | ||
1421 | format); | ||
1422 | } | ||
1423 | p->format_id = format; | ||
1424 | } | ||
1425 | } | ||
1426 | |||
1389 | /** | 1427 | /** |
1390 | * snd_hda_codec_setup_stream - set up the codec for streaming | 1428 | * snd_hda_codec_setup_stream - set up the codec for streaming |
1391 | * @codec: the CODEC to set up | 1429 | * @codec: the CODEC to set up |
@@ -1400,7 +1438,6 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1400 | { | 1438 | { |
1401 | struct hda_codec *c; | 1439 | struct hda_codec *c; |
1402 | struct hda_cvt_setup *p; | 1440 | struct hda_cvt_setup *p; |
1403 | unsigned int oldval, newval; | ||
1404 | int type; | 1441 | int type; |
1405 | int i; | 1442 | int i; |
1406 | 1443 | ||
@@ -1413,29 +1450,13 @@ void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid, | |||
1413 | p = get_hda_cvt_setup(codec, nid); | 1450 | p = get_hda_cvt_setup(codec, nid); |
1414 | if (!p) | 1451 | if (!p) |
1415 | return; | 1452 | return; |
1416 | /* update the stream-id if changed */ | 1453 | |
1417 | if (p->stream_tag != stream_tag || p->channel_id != channel_id) { | 1454 | if (codec->pcm_format_first) |
1418 | oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | 1455 | update_pcm_format(codec, p, nid, format); |
1419 | newval = (stream_tag << 4) | channel_id; | 1456 | update_pcm_stream_id(codec, p, nid, stream_tag, channel_id); |
1420 | if (oldval != newval) | 1457 | if (!codec->pcm_format_first) |
1421 | snd_hda_codec_write(codec, nid, 0, | 1458 | update_pcm_format(codec, p, nid, format); |
1422 | AC_VERB_SET_CHANNEL_STREAMID, | 1459 | |
1423 | newval); | ||
1424 | p->stream_tag = stream_tag; | ||
1425 | p->channel_id = channel_id; | ||
1426 | } | ||
1427 | /* update the format-id if changed */ | ||
1428 | if (p->format_id != format) { | ||
1429 | oldval = snd_hda_codec_read(codec, nid, 0, | ||
1430 | AC_VERB_GET_STREAM_FORMAT, 0); | ||
1431 | if (oldval != format) { | ||
1432 | msleep(1); | ||
1433 | snd_hda_codec_write(codec, nid, 0, | ||
1434 | AC_VERB_SET_STREAM_FORMAT, | ||
1435 | format); | ||
1436 | } | ||
1437 | p->format_id = format; | ||
1438 | } | ||
1439 | p->active = 1; | 1460 | p->active = 1; |
1440 | p->dirty = 0; | 1461 | p->dirty = 0; |
1441 | 1462 | ||
@@ -3497,7 +3518,7 @@ static bool snd_hda_codec_get_supported_ps(struct hda_codec *codec, hda_nid_t fg | |||
3497 | { | 3518 | { |
3498 | int sup = snd_hda_param_read(codec, fg, AC_PAR_POWER_STATE); | 3519 | int sup = snd_hda_param_read(codec, fg, AC_PAR_POWER_STATE); |
3499 | 3520 | ||
3500 | if (sup < 0) | 3521 | if (sup == -1) |
3501 | return false; | 3522 | return false; |
3502 | if (sup & power_state) | 3523 | if (sup & power_state) |
3503 | return true; | 3524 | return true; |
@@ -4433,6 +4454,8 @@ static void __snd_hda_power_up(struct hda_codec *codec, bool wait_power_down) | |||
4433 | * then there is no need to go through power up here. | 4454 | * then there is no need to go through power up here. |
4434 | */ | 4455 | */ |
4435 | if (codec->power_on) { | 4456 | if (codec->power_on) { |
4457 | if (codec->power_transition < 0) | ||
4458 | codec->power_transition = 0; | ||
4436 | spin_unlock(&codec->power_lock); | 4459 | spin_unlock(&codec->power_lock); |
4437 | return; | 4460 | return; |
4438 | } | 4461 | } |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index c422d330ca54..7fbc1bcaf1a9 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -861,6 +861,7 @@ struct hda_codec { | |||
861 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ | 861 | unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ |
862 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ | 862 | unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ |
863 | unsigned int no_jack_detect:1; /* Machine has no jack-detection */ | 863 | unsigned int no_jack_detect:1; /* Machine has no jack-detection */ |
864 | unsigned int pcm_format_first:1; /* PCM format must be set first */ | ||
864 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 865 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
865 | unsigned int power_on :1; /* current (global) power-state */ | 866 | unsigned int power_on :1; /* current (global) power-state */ |
866 | int power_transition; /* power-state in transition */ | 867 | int power_transition; /* power-state in transition */ |
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index c8aced182fd1..60882c62f180 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -151,6 +151,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | |||
151 | "{Intel, CPT}," | 151 | "{Intel, CPT}," |
152 | "{Intel, PPT}," | 152 | "{Intel, PPT}," |
153 | "{Intel, LPT}," | 153 | "{Intel, LPT}," |
154 | "{Intel, LPT_LP}," | ||
154 | "{Intel, HPT}," | 155 | "{Intel, HPT}," |
155 | "{Intel, PBG}," | 156 | "{Intel, PBG}," |
156 | "{Intel, SCH}," | 157 | "{Intel, SCH}," |
@@ -3270,6 +3271,14 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
3270 | { PCI_DEVICE(0x8086, 0x8c20), | 3271 | { PCI_DEVICE(0x8086, 0x8c20), |
3271 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | 3272 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | |
3272 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, | 3273 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, |
3274 | /* Lynx Point-LP */ | ||
3275 | { PCI_DEVICE(0x8086, 0x9c20), | ||
3276 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | ||
3277 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, | ||
3278 | /* Lynx Point-LP */ | ||
3279 | { PCI_DEVICE(0x8086, 0x9c21), | ||
3280 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP | | ||
3281 | AZX_DCAPS_BUFSIZE | AZX_DCAPS_POSFIX_COMBO }, | ||
3273 | /* Haswell */ | 3282 | /* Haswell */ |
3274 | { PCI_DEVICE(0x8086, 0x0c0c), | 3283 | { PCI_DEVICE(0x8086, 0x0c0c), |
3275 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | | 3284 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP | |
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c index 7e46258fc700..6894ec66258c 100644 --- a/sound/pci/hda/hda_proc.c +++ b/sound/pci/hda/hda_proc.c | |||
@@ -412,7 +412,7 @@ static void print_digital_conv(struct snd_info_buffer *buffer, | |||
412 | if (digi1 & AC_DIG1_EMPHASIS) | 412 | if (digi1 & AC_DIG1_EMPHASIS) |
413 | snd_iprintf(buffer, " Preemphasis"); | 413 | snd_iprintf(buffer, " Preemphasis"); |
414 | if (digi1 & AC_DIG1_COPYRIGHT) | 414 | if (digi1 & AC_DIG1_COPYRIGHT) |
415 | snd_iprintf(buffer, " Copyright"); | 415 | snd_iprintf(buffer, " Non-Copyright"); |
416 | if (digi1 & AC_DIG1_NONAUDIO) | 416 | if (digi1 & AC_DIG1_NONAUDIO) |
417 | snd_iprintf(buffer, " Non-Audio"); | 417 | snd_iprintf(buffer, " Non-Audio"); |
418 | if (digi1 & AC_DIG1_PROFESSIONAL) | 418 | if (digi1 & AC_DIG1_PROFESSIONAL) |
diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index d0d3540e39e7..49750a96d649 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c | |||
@@ -246,7 +246,7 @@ static void init_output(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) | |||
246 | AC_VERB_SET_AMP_GAIN_MUTE, | 246 | AC_VERB_SET_AMP_GAIN_MUTE, |
247 | AMP_OUT_UNMUTE); | 247 | AMP_OUT_UNMUTE); |
248 | } | 248 | } |
249 | if (dac) | 249 | if (dac && (get_wcaps(codec, dac) & AC_WCAP_OUT_AMP)) |
250 | snd_hda_codec_write(codec, dac, 0, | 250 | snd_hda_codec_write(codec, dac, 0, |
251 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); | 251 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO); |
252 | } | 252 | } |
@@ -261,7 +261,7 @@ static void init_input(struct hda_codec *codec, hda_nid_t pin, hda_nid_t adc) | |||
261 | AC_VERB_SET_AMP_GAIN_MUTE, | 261 | AC_VERB_SET_AMP_GAIN_MUTE, |
262 | AMP_IN_UNMUTE(0)); | 262 | AMP_IN_UNMUTE(0)); |
263 | } | 263 | } |
264 | if (adc) | 264 | if (adc && (get_wcaps(codec, adc) & AC_WCAP_IN_AMP)) |
265 | snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 265 | snd_hda_codec_write(codec, adc, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
266 | AMP_IN_UNMUTE(0)); | 266 | AMP_IN_UNMUTE(0)); |
267 | } | 267 | } |
@@ -275,6 +275,10 @@ static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, | |||
275 | int type = dir ? HDA_INPUT : HDA_OUTPUT; | 275 | int type = dir ? HDA_INPUT : HDA_OUTPUT; |
276 | struct snd_kcontrol_new knew = | 276 | struct snd_kcontrol_new knew = |
277 | HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type); | 277 | HDA_CODEC_MUTE_MONO(namestr, nid, chan, 0, type); |
278 | if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_MUTE) == 0) { | ||
279 | snd_printdd("Skipping '%s %s Switch' (no mute on node 0x%x)\n", pfx, dirstr[dir], nid); | ||
280 | return 0; | ||
281 | } | ||
278 | sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); | 282 | sprintf(namestr, "%s %s Switch", pfx, dirstr[dir]); |
279 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); | 283 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); |
280 | } | 284 | } |
@@ -286,6 +290,10 @@ static int _add_volume(struct hda_codec *codec, hda_nid_t nid, const char *pfx, | |||
286 | int type = dir ? HDA_INPUT : HDA_OUTPUT; | 290 | int type = dir ? HDA_INPUT : HDA_OUTPUT; |
287 | struct snd_kcontrol_new knew = | 291 | struct snd_kcontrol_new knew = |
288 | HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); | 292 | HDA_CODEC_VOLUME_MONO(namestr, nid, chan, 0, type); |
293 | if ((query_amp_caps(codec, nid, type) & AC_AMPCAP_NUM_STEPS) == 0) { | ||
294 | snd_printdd("Skipping '%s %s Volume' (no amp on node 0x%x)\n", pfx, dirstr[dir], nid); | ||
295 | return 0; | ||
296 | } | ||
289 | sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); | 297 | sprintf(namestr, "%s %s Volume", pfx, dirstr[dir]); |
290 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); | 298 | return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); |
291 | } | 299 | } |
@@ -464,50 +472,17 @@ exit: | |||
464 | } | 472 | } |
465 | 473 | ||
466 | /* | 474 | /* |
467 | * PCM stuffs | 475 | * PCM callbacks |
468 | */ | 476 | */ |
469 | static void ca0132_setup_stream(struct hda_codec *codec, hda_nid_t nid, | 477 | static int ca0132_playback_pcm_open(struct hda_pcm_stream *hinfo, |
470 | u32 stream_tag, | 478 | struct hda_codec *codec, |
471 | int channel_id, int format) | 479 | struct snd_pcm_substream *substream) |
472 | { | 480 | { |
473 | unsigned int oldval, newval; | 481 | struct ca0132_spec *spec = codec->spec; |
474 | 482 | return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, | |
475 | if (!nid) | 483 | hinfo); |
476 | return; | ||
477 | |||
478 | snd_printdd("ca0132_setup_stream: " | ||
479 | "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n", | ||
480 | nid, stream_tag, channel_id, format); | ||
481 | |||
482 | /* update the format-id if changed */ | ||
483 | oldval = snd_hda_codec_read(codec, nid, 0, | ||
484 | AC_VERB_GET_STREAM_FORMAT, | ||
485 | 0); | ||
486 | if (oldval != format) { | ||
487 | msleep(20); | ||
488 | snd_hda_codec_write(codec, nid, 0, | ||
489 | AC_VERB_SET_STREAM_FORMAT, | ||
490 | format); | ||
491 | } | ||
492 | |||
493 | oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0); | ||
494 | newval = (stream_tag << 4) | channel_id; | ||
495 | if (oldval != newval) { | ||
496 | snd_hda_codec_write(codec, nid, 0, | ||
497 | AC_VERB_SET_CHANNEL_STREAMID, | ||
498 | newval); | ||
499 | } | ||
500 | } | ||
501 | |||
502 | static void ca0132_cleanup_stream(struct hda_codec *codec, hda_nid_t nid) | ||
503 | { | ||
504 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0); | ||
505 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0); | ||
506 | } | 484 | } |
507 | 485 | ||
508 | /* | ||
509 | * PCM callbacks | ||
510 | */ | ||
511 | static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 486 | static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
512 | struct hda_codec *codec, | 487 | struct hda_codec *codec, |
513 | unsigned int stream_tag, | 488 | unsigned int stream_tag, |
@@ -515,10 +490,8 @@ static int ca0132_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
515 | struct snd_pcm_substream *substream) | 490 | struct snd_pcm_substream *substream) |
516 | { | 491 | { |
517 | struct ca0132_spec *spec = codec->spec; | 492 | struct ca0132_spec *spec = codec->spec; |
518 | 493 | return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, | |
519 | ca0132_setup_stream(codec, spec->dacs[0], stream_tag, 0, format); | 494 | stream_tag, format, substream); |
520 | |||
521 | return 0; | ||
522 | } | 495 | } |
523 | 496 | ||
524 | static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 497 | static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
@@ -526,92 +499,45 @@ static int ca0132_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
526 | struct snd_pcm_substream *substream) | 499 | struct snd_pcm_substream *substream) |
527 | { | 500 | { |
528 | struct ca0132_spec *spec = codec->spec; | 501 | struct ca0132_spec *spec = codec->spec; |
529 | 502 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | |
530 | ca0132_cleanup_stream(codec, spec->dacs[0]); | ||
531 | |||
532 | return 0; | ||
533 | } | 503 | } |
534 | 504 | ||
535 | /* | 505 | /* |
536 | * Digital out | 506 | * Digital out |
537 | */ | 507 | */ |
538 | static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | 508 | static int ca0132_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, |
539 | struct hda_codec *codec, | 509 | struct hda_codec *codec, |
540 | unsigned int stream_tag, | 510 | struct snd_pcm_substream *substream) |
541 | unsigned int format, | ||
542 | struct snd_pcm_substream *substream) | ||
543 | { | 511 | { |
544 | struct ca0132_spec *spec = codec->spec; | 512 | struct ca0132_spec *spec = codec->spec; |
545 | 513 | return snd_hda_multi_out_dig_open(codec, &spec->multiout); | |
546 | ca0132_setup_stream(codec, spec->dig_out, stream_tag, 0, format); | ||
547 | |||
548 | return 0; | ||
549 | } | 514 | } |
550 | 515 | ||
551 | static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | 516 | static int ca0132_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, |
552 | struct hda_codec *codec, | ||
553 | struct snd_pcm_substream *substream) | ||
554 | { | ||
555 | struct ca0132_spec *spec = codec->spec; | ||
556 | |||
557 | ca0132_cleanup_stream(codec, spec->dig_out); | ||
558 | |||
559 | return 0; | ||
560 | } | ||
561 | |||
562 | /* | ||
563 | * Analog capture | ||
564 | */ | ||
565 | static int ca0132_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
566 | struct hda_codec *codec, | 517 | struct hda_codec *codec, |
567 | unsigned int stream_tag, | 518 | unsigned int stream_tag, |
568 | unsigned int format, | 519 | unsigned int format, |
569 | struct snd_pcm_substream *substream) | 520 | struct snd_pcm_substream *substream) |
570 | { | 521 | { |
571 | struct ca0132_spec *spec = codec->spec; | 522 | struct ca0132_spec *spec = codec->spec; |
572 | 523 | return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, | |
573 | ca0132_setup_stream(codec, spec->adcs[substream->number], | 524 | stream_tag, format, substream); |
574 | stream_tag, 0, format); | ||
575 | |||
576 | return 0; | ||
577 | } | 525 | } |
578 | 526 | ||
579 | static int ca0132_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | 527 | static int ca0132_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, |
580 | struct hda_codec *codec, | 528 | struct hda_codec *codec, |
581 | struct snd_pcm_substream *substream) | 529 | struct snd_pcm_substream *substream) |
582 | { | 530 | { |
583 | struct ca0132_spec *spec = codec->spec; | 531 | struct ca0132_spec *spec = codec->spec; |
584 | 532 | return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); | |
585 | ca0132_cleanup_stream(codec, spec->adcs[substream->number]); | ||
586 | |||
587 | return 0; | ||
588 | } | 533 | } |
589 | 534 | ||
590 | /* | 535 | static int ca0132_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, |
591 | * Digital capture | 536 | struct hda_codec *codec, |
592 | */ | 537 | struct snd_pcm_substream *substream) |
593 | static int ca0132_dig_capture_pcm_prepare(struct hda_pcm_stream *hinfo, | ||
594 | struct hda_codec *codec, | ||
595 | unsigned int stream_tag, | ||
596 | unsigned int format, | ||
597 | struct snd_pcm_substream *substream) | ||
598 | { | 538 | { |
599 | struct ca0132_spec *spec = codec->spec; | 539 | struct ca0132_spec *spec = codec->spec; |
600 | 540 | return snd_hda_multi_out_dig_close(codec, &spec->multiout); | |
601 | ca0132_setup_stream(codec, spec->dig_in, stream_tag, 0, format); | ||
602 | |||
603 | return 0; | ||
604 | } | ||
605 | |||
606 | static int ca0132_dig_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
607 | struct hda_codec *codec, | ||
608 | struct snd_pcm_substream *substream) | ||
609 | { | ||
610 | struct ca0132_spec *spec = codec->spec; | ||
611 | |||
612 | ca0132_cleanup_stream(codec, spec->dig_in); | ||
613 | |||
614 | return 0; | ||
615 | } | 541 | } |
616 | 542 | ||
617 | /* | 543 | /* |
@@ -621,6 +547,7 @@ static struct hda_pcm_stream ca0132_pcm_analog_playback = { | |||
621 | .channels_min = 2, | 547 | .channels_min = 2, |
622 | .channels_max = 2, | 548 | .channels_max = 2, |
623 | .ops = { | 549 | .ops = { |
550 | .open = ca0132_playback_pcm_open, | ||
624 | .prepare = ca0132_playback_pcm_prepare, | 551 | .prepare = ca0132_playback_pcm_prepare, |
625 | .cleanup = ca0132_playback_pcm_cleanup | 552 | .cleanup = ca0132_playback_pcm_cleanup |
626 | }, | 553 | }, |
@@ -630,10 +557,6 @@ static struct hda_pcm_stream ca0132_pcm_analog_capture = { | |||
630 | .substreams = 1, | 557 | .substreams = 1, |
631 | .channels_min = 2, | 558 | .channels_min = 2, |
632 | .channels_max = 2, | 559 | .channels_max = 2, |
633 | .ops = { | ||
634 | .prepare = ca0132_capture_pcm_prepare, | ||
635 | .cleanup = ca0132_capture_pcm_cleanup | ||
636 | }, | ||
637 | }; | 560 | }; |
638 | 561 | ||
639 | static struct hda_pcm_stream ca0132_pcm_digital_playback = { | 562 | static struct hda_pcm_stream ca0132_pcm_digital_playback = { |
@@ -641,6 +564,8 @@ static struct hda_pcm_stream ca0132_pcm_digital_playback = { | |||
641 | .channels_min = 2, | 564 | .channels_min = 2, |
642 | .channels_max = 2, | 565 | .channels_max = 2, |
643 | .ops = { | 566 | .ops = { |
567 | .open = ca0132_dig_playback_pcm_open, | ||
568 | .close = ca0132_dig_playback_pcm_close, | ||
644 | .prepare = ca0132_dig_playback_pcm_prepare, | 569 | .prepare = ca0132_dig_playback_pcm_prepare, |
645 | .cleanup = ca0132_dig_playback_pcm_cleanup | 570 | .cleanup = ca0132_dig_playback_pcm_cleanup |
646 | }, | 571 | }, |
@@ -650,10 +575,6 @@ static struct hda_pcm_stream ca0132_pcm_digital_capture = { | |||
650 | .substreams = 1, | 575 | .substreams = 1, |
651 | .channels_min = 2, | 576 | .channels_min = 2, |
652 | .channels_max = 2, | 577 | .channels_max = 2, |
653 | .ops = { | ||
654 | .prepare = ca0132_dig_capture_pcm_prepare, | ||
655 | .cleanup = ca0132_dig_capture_pcm_cleanup | ||
656 | }, | ||
657 | }; | 578 | }; |
658 | 579 | ||
659 | static int ca0132_build_pcms(struct hda_codec *codec) | 580 | static int ca0132_build_pcms(struct hda_codec *codec) |
@@ -928,18 +849,16 @@ static int ca0132_build_controls(struct hda_codec *codec) | |||
928 | spec->dig_out); | 849 | spec->dig_out); |
929 | if (err < 0) | 850 | if (err < 0) |
930 | return err; | 851 | return err; |
931 | err = add_out_volume(codec, spec->dig_out, "IEC958"); | 852 | err = snd_hda_create_spdif_share_sw(codec, &spec->multiout); |
932 | if (err < 0) | 853 | if (err < 0) |
933 | return err; | 854 | return err; |
855 | /* spec->multiout.share_spdif = 1; */ | ||
934 | } | 856 | } |
935 | 857 | ||
936 | if (spec->dig_in) { | 858 | if (spec->dig_in) { |
937 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in); | 859 | err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in); |
938 | if (err < 0) | 860 | if (err < 0) |
939 | return err; | 861 | return err; |
940 | err = add_in_volume(codec, spec->dig_in, "IEC958"); | ||
941 | if (err < 0) | ||
942 | return err; | ||
943 | } | 862 | } |
944 | return 0; | 863 | return 0; |
945 | } | 864 | } |
@@ -961,6 +880,9 @@ static void ca0132_config(struct hda_codec *codec) | |||
961 | struct ca0132_spec *spec = codec->spec; | 880 | struct ca0132_spec *spec = codec->spec; |
962 | struct auto_pin_cfg *cfg = &spec->autocfg; | 881 | struct auto_pin_cfg *cfg = &spec->autocfg; |
963 | 882 | ||
883 | codec->pcm_format_first = 1; | ||
884 | codec->no_sticky_stream = 1; | ||
885 | |||
964 | /* line-outs */ | 886 | /* line-outs */ |
965 | cfg->line_outs = 1; | 887 | cfg->line_outs = 1; |
966 | cfg->line_out_pins[0] = 0x0b; /* front */ | 888 | cfg->line_out_pins[0] = 0x0b; /* front */ |
@@ -988,14 +910,24 @@ static void ca0132_config(struct hda_codec *codec) | |||
988 | 910 | ||
989 | /* Mic-in */ | 911 | /* Mic-in */ |
990 | spec->input_pins[0] = 0x12; | 912 | spec->input_pins[0] = 0x12; |
991 | spec->input_labels[0] = "Mic-In"; | 913 | spec->input_labels[0] = "Mic"; |
992 | spec->adcs[0] = 0x07; | 914 | spec->adcs[0] = 0x07; |
993 | 915 | ||
994 | /* Line-In */ | 916 | /* Line-In */ |
995 | spec->input_pins[1] = 0x11; | 917 | spec->input_pins[1] = 0x11; |
996 | spec->input_labels[1] = "Line-In"; | 918 | spec->input_labels[1] = "Line"; |
997 | spec->adcs[1] = 0x08; | 919 | spec->adcs[1] = 0x08; |
998 | spec->num_inputs = 2; | 920 | spec->num_inputs = 2; |
921 | |||
922 | /* SPDIF I/O */ | ||
923 | spec->dig_out = 0x05; | ||
924 | spec->multiout.dig_out_nid = spec->dig_out; | ||
925 | cfg->dig_out_pins[0] = 0x0c; | ||
926 | cfg->dig_outs = 1; | ||
927 | cfg->dig_out_type[0] = HDA_PCM_TYPE_SPDIF; | ||
928 | spec->dig_in = 0x09; | ||
929 | cfg->dig_in_pin = 0x0e; | ||
930 | cfg->dig_in_type = HDA_PCM_TYPE_SPDIF; | ||
999 | } | 931 | } |
1000 | 932 | ||
1001 | static void ca0132_init_chip(struct hda_codec *codec) | 933 | static void ca0132_init_chip(struct hda_codec *codec) |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index 14361184ae1e..5e22a8f43d2e 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -2967,12 +2967,10 @@ static const char * const cxt5066_models[CXT5066_MODELS] = { | |||
2967 | }; | 2967 | }; |
2968 | 2968 | ||
2969 | static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { | 2969 | static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { |
2970 | SND_PCI_QUIRK(0x1025, 0x054c, "Acer Aspire 3830TG", CXT5066_AUTO), | ||
2971 | SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), | 2970 | SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), |
2972 | SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), | 2971 | SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), |
2973 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), | 2972 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), |
2974 | SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO), | 2973 | SND_PCI_QUIRK(0x1028, 0x0401, "Dell Vostro 1014", CXT5066_DELL_VOSTRO), |
2975 | SND_PCI_QUIRK(0x1028, 0x0402, "Dell Vostro", CXT5066_DELL_VOSTRO), | ||
2976 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), | 2974 | SND_PCI_QUIRK(0x1028, 0x0408, "Dell Inspiron One 19T", CXT5066_IDEAPAD), |
2977 | SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD), | 2975 | SND_PCI_QUIRK(0x1028, 0x050f, "Dell Inspiron", CXT5066_IDEAPAD), |
2978 | SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD), | 2976 | SND_PCI_QUIRK(0x1028, 0x0510, "Dell Vostro", CXT5066_IDEAPAD), |
@@ -2988,14 +2986,10 @@ static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
2988 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), | 2986 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400s", CXT5066_THINKPAD), |
2989 | SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), | 2987 | SND_PCI_QUIRK(0x17aa, 0x21c5, "Thinkpad Edge 13", CXT5066_THINKPAD), |
2990 | SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), | 2988 | SND_PCI_QUIRK(0x17aa, 0x21c6, "Thinkpad Edge 13", CXT5066_ASUS), |
2991 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T510", CXT5066_AUTO), | ||
2992 | SND_PCI_QUIRK(0x17aa, 0x21cf, "Lenovo T520 & W520", CXT5066_AUTO), | ||
2993 | SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), | 2989 | SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), |
2994 | SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), | 2990 | SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), |
2995 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), | 2991 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), |
2996 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), | 2992 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), |
2997 | SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO), | ||
2998 | SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO), | ||
2999 | {} | 2993 | {} |
3000 | }; | 2994 | }; |
3001 | 2995 | ||
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 69b928449789..8f23374fa642 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -877,8 +877,6 @@ static int hdmi_pcm_open(struct hda_pcm_stream *hinfo, | |||
877 | struct hdmi_eld *eld; | 877 | struct hdmi_eld *eld; |
878 | struct hdmi_spec_per_cvt *per_cvt = NULL; | 878 | struct hdmi_spec_per_cvt *per_cvt = NULL; |
879 | 879 | ||
880 | hinfo->nid = 0; /* clear the leftover value */ | ||
881 | |||
882 | /* Validate hinfo */ | 880 | /* Validate hinfo */ |
883 | pin_idx = hinfo_to_pin_index(spec, hinfo); | 881 | pin_idx = hinfo_to_pin_index(spec, hinfo); |
884 | if (snd_BUG_ON(pin_idx < 0)) | 882 | if (snd_BUG_ON(pin_idx < 0)) |
@@ -1163,6 +1161,14 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1163 | return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); | 1161 | return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); |
1164 | } | 1162 | } |
1165 | 1163 | ||
1164 | static int generic_hdmi_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
1165 | struct hda_codec *codec, | ||
1166 | struct snd_pcm_substream *substream) | ||
1167 | { | ||
1168 | snd_hda_codec_cleanup_stream(codec, hinfo->nid); | ||
1169 | return 0; | ||
1170 | } | ||
1171 | |||
1166 | static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, | 1172 | static int hdmi_pcm_close(struct hda_pcm_stream *hinfo, |
1167 | struct hda_codec *codec, | 1173 | struct hda_codec *codec, |
1168 | struct snd_pcm_substream *substream) | 1174 | struct snd_pcm_substream *substream) |
@@ -1202,6 +1208,7 @@ static const struct hda_pcm_ops generic_ops = { | |||
1202 | .open = hdmi_pcm_open, | 1208 | .open = hdmi_pcm_open, |
1203 | .close = hdmi_pcm_close, | 1209 | .close = hdmi_pcm_close, |
1204 | .prepare = generic_hdmi_playback_pcm_prepare, | 1210 | .prepare = generic_hdmi_playback_pcm_prepare, |
1211 | .cleanup = generic_hdmi_playback_pcm_cleanup, | ||
1205 | }; | 1212 | }; |
1206 | 1213 | ||
1207 | static int generic_hdmi_build_pcms(struct hda_codec *codec) | 1214 | static int generic_hdmi_build_pcms(struct hda_codec *codec) |
@@ -1220,7 +1227,6 @@ static int generic_hdmi_build_pcms(struct hda_codec *codec) | |||
1220 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; | 1227 | pstr = &info->stream[SNDRV_PCM_STREAM_PLAYBACK]; |
1221 | pstr->substreams = 1; | 1228 | pstr->substreams = 1; |
1222 | pstr->ops = generic_ops; | 1229 | pstr->ops = generic_ops; |
1223 | pstr->nid = 1; /* FIXME: just for avoiding a debug WARNING */ | ||
1224 | /* other pstr fields are set in open */ | 1230 | /* other pstr fields are set in open */ |
1225 | } | 1231 | } |
1226 | 1232 | ||
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 344b221d2102..4f81dd44c837 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -6099,6 +6099,8 @@ static const struct alc_fixup alc269_fixups[] = { | |||
6099 | [ALC269_FIXUP_PCM_44K] = { | 6099 | [ALC269_FIXUP_PCM_44K] = { |
6100 | .type = ALC_FIXUP_FUNC, | 6100 | .type = ALC_FIXUP_FUNC, |
6101 | .v.func = alc269_fixup_pcm_44k, | 6101 | .v.func = alc269_fixup_pcm_44k, |
6102 | .chained = true, | ||
6103 | .chain_id = ALC269_FIXUP_QUANTA_MUTE | ||
6102 | }, | 6104 | }, |
6103 | [ALC269_FIXUP_STEREO_DMIC] = { | 6105 | [ALC269_FIXUP_STEREO_DMIC] = { |
6104 | .type = ALC_FIXUP_FUNC, | 6106 | .type = ALC_FIXUP_FUNC, |
@@ -6206,9 +6208,11 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
6206 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), | 6208 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), |
6207 | SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), | 6209 | SND_PCI_QUIRK(0x17aa, 0x21ca, "Thinkpad L412", ALC269_FIXUP_SKU_IGNORE), |
6208 | SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), | 6210 | SND_PCI_QUIRK(0x17aa, 0x21e9, "Thinkpad Edge 15", ALC269_FIXUP_SKU_IGNORE), |
6211 | SND_PCI_QUIRK(0x17aa, 0x21f6, "Thinkpad T530", ALC269_FIXUP_LENOVO_DOCK), | ||
6212 | SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), | ||
6213 | SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), | ||
6209 | SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), | 6214 | SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), |
6210 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_QUANTA_MUTE), | 6215 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), |
6211 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Lenovo Ideapd", ALC269_FIXUP_PCM_44K), | ||
6212 | SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), | 6216 | SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), |
6213 | 6217 | ||
6214 | #if 0 | 6218 | #if 0 |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 94040ccf8e8f..ea5775a1a7db 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -4272,7 +4272,8 @@ static int stac92xx_init(struct hda_codec *codec) | |||
4272 | unsigned int gpio; | 4272 | unsigned int gpio; |
4273 | int i; | 4273 | int i; |
4274 | 4274 | ||
4275 | snd_hda_sequence_write(codec, spec->init); | 4275 | if (spec->init) |
4276 | snd_hda_sequence_write(codec, spec->init); | ||
4276 | 4277 | ||
4277 | /* power down adcs initially */ | 4278 | /* power down adcs initially */ |
4278 | if (spec->powerdown_adcs) | 4279 | if (spec->powerdown_adcs) |
@@ -5748,7 +5749,6 @@ again: | |||
5748 | /* fallthru */ | 5749 | /* fallthru */ |
5749 | case 0x111d76b4: /* 6 Port without Analog Mixer */ | 5750 | case 0x111d76b4: /* 6 Port without Analog Mixer */ |
5750 | case 0x111d76b5: | 5751 | case 0x111d76b5: |
5751 | spec->init = stac92hd71bxx_core_init; | ||
5752 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 5752 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
5753 | spec->num_dmics = stac92xx_connected_ports(codec, | 5753 | spec->num_dmics = stac92xx_connected_ports(codec, |
5754 | stac92hd71bxx_dmic_nids, | 5754 | stac92hd71bxx_dmic_nids, |
@@ -5773,7 +5773,6 @@ again: | |||
5773 | spec->stream_delay = 40; /* 40 milliseconds */ | 5773 | spec->stream_delay = 40; /* 40 milliseconds */ |
5774 | 5774 | ||
5775 | /* disable VSW */ | 5775 | /* disable VSW */ |
5776 | spec->init = stac92hd71bxx_core_init; | ||
5777 | unmute_init++; | 5776 | unmute_init++; |
5778 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); | 5777 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); |
5779 | snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); | 5778 | snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); |
@@ -5788,7 +5787,6 @@ again: | |||
5788 | 5787 | ||
5789 | /* fallthru */ | 5788 | /* fallthru */ |
5790 | default: | 5789 | default: |
5791 | spec->init = stac92hd71bxx_core_init; | ||
5792 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; | 5790 | codec->slave_dig_outs = stac92hd71bxx_slave_dig_outs; |
5793 | spec->num_dmics = stac92xx_connected_ports(codec, | 5791 | spec->num_dmics = stac92xx_connected_ports(codec, |
5794 | stac92hd71bxx_dmic_nids, | 5792 | stac92hd71bxx_dmic_nids, |
@@ -5796,6 +5794,9 @@ again: | |||
5796 | break; | 5794 | break; |
5797 | } | 5795 | } |
5798 | 5796 | ||
5797 | if (get_wcaps_type(get_wcaps(codec, 0x28)) == AC_WID_VOL_KNB) | ||
5798 | spec->init = stac92hd71bxx_core_init; | ||
5799 | |||
5799 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) | 5800 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) |
5800 | snd_hda_sequence_write_cache(codec, unmute_init); | 5801 | snd_hda_sequence_write_cache(codec, unmute_init); |
5801 | 5802 | ||
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 80d90cb42853..430771776915 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -1752,6 +1752,14 @@ static int via_suspend(struct hda_codec *codec) | |||
1752 | { | 1752 | { |
1753 | struct via_spec *spec = codec->spec; | 1753 | struct via_spec *spec = codec->spec; |
1754 | vt1708_stop_hp_work(spec); | 1754 | vt1708_stop_hp_work(spec); |
1755 | |||
1756 | if (spec->codec_type == VT1802) { | ||
1757 | /* Fix pop noise on headphones */ | ||
1758 | int i; | ||
1759 | for (i = 0; i < spec->autocfg.hp_outs; i++) | ||
1760 | snd_hda_set_pin_ctl(codec, spec->autocfg.hp_pins[i], 0); | ||
1761 | } | ||
1762 | |||
1755 | return 0; | 1763 | return 0; |
1756 | } | 1764 | } |
1757 | #endif | 1765 | #endif |
diff --git a/sound/pci/lx6464es/lx6464es.c b/sound/pci/lx6464es/lx6464es.c index d1ab43706735..5579b08bb35b 100644 --- a/sound/pci/lx6464es/lx6464es.c +++ b/sound/pci/lx6464es/lx6464es.c | |||
@@ -851,6 +851,8 @@ static int __devinit lx_pcm_create(struct lx6464es *chip) | |||
851 | /* hardcoded device name & channel count */ | 851 | /* hardcoded device name & channel count */ |
852 | err = snd_pcm_new(chip->card, (char *)card_name, 0, | 852 | err = snd_pcm_new(chip->card, (char *)card_name, 0, |
853 | 1, 1, &pcm); | 853 | 1, 1, &pcm); |
854 | if (err < 0) | ||
855 | return err; | ||
854 | 856 | ||
855 | pcm->private_data = chip; | 857 | pcm->private_data = chip; |
856 | 858 | ||
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c index b8ac8710f47f..b12308b5ba2a 100644 --- a/sound/pci/rme9652/hdspm.c +++ b/sound/pci/rme9652/hdspm.c | |||
@@ -6585,7 +6585,7 @@ static int __devinit snd_hdspm_create(struct snd_card *card, | |||
6585 | snd_printk(KERN_ERR "HDSPM: " | 6585 | snd_printk(KERN_ERR "HDSPM: " |
6586 | "unable to kmalloc Mixer memory of %d Bytes\n", | 6586 | "unable to kmalloc Mixer memory of %d Bytes\n", |
6587 | (int)sizeof(struct hdspm_mixer)); | 6587 | (int)sizeof(struct hdspm_mixer)); |
6588 | return err; | 6588 | return -ENOMEM; |
6589 | } | 6589 | } |
6590 | 6590 | ||
6591 | hdspm->port_names_in = NULL; | 6591 | hdspm->port_names_in = NULL; |
diff --git a/sound/pci/sis7019.c b/sound/pci/sis7019.c index 512434efcc31..805ab6e9a78f 100644 --- a/sound/pci/sis7019.c +++ b/sound/pci/sis7019.c | |||
@@ -1377,8 +1377,9 @@ static int __devinit sis_chip_create(struct snd_card *card, | |||
1377 | if (rc) | 1377 | if (rc) |
1378 | goto error_out_cleanup; | 1378 | goto error_out_cleanup; |
1379 | 1379 | ||
1380 | if (request_irq(pci->irq, sis_interrupt, IRQF_SHARED, KBUILD_MODNAME, | 1380 | rc = request_irq(pci->irq, sis_interrupt, IRQF_SHARED, KBUILD_MODNAME, |
1381 | sis)) { | 1381 | sis); |
1382 | if (rc) { | ||
1382 | dev_err(&pci->dev, "unable to allocate irq %d\n", sis->irq); | 1383 | dev_err(&pci->dev, "unable to allocate irq %d\n", sis->irq); |
1383 | goto error_out_cleanup; | 1384 | goto error_out_cleanup; |
1384 | } | 1385 | } |
diff --git a/sound/ppc/powermac.c b/sound/ppc/powermac.c index f5ceb6f282de..210cafe04890 100644 --- a/sound/ppc/powermac.c +++ b/sound/ppc/powermac.c | |||
@@ -143,7 +143,7 @@ static int __devexit snd_pmac_remove(struct platform_device *devptr) | |||
143 | return 0; | 143 | return 0; |
144 | } | 144 | } |
145 | 145 | ||
146 | #ifdef CONFIG_PM | 146 | #ifdef CONFIG_PM_SLEEP |
147 | static int snd_pmac_driver_suspend(struct device *dev) | 147 | static int snd_pmac_driver_suspend(struct device *dev) |
148 | { | 148 | { |
149 | struct snd_card *card = dev_get_drvdata(dev); | 149 | struct snd_card *card = dev_get_drvdata(dev); |
diff --git a/sound/ppc/snd_ps3.c b/sound/ppc/snd_ps3.c index 1aa52eff526a..9b18b5243a56 100644 --- a/sound/ppc/snd_ps3.c +++ b/sound/ppc/snd_ps3.c | |||
@@ -1040,6 +1040,7 @@ static int __devinit snd_ps3_driver_probe(struct ps3_system_bus_device *dev) | |||
1040 | GFP_KERNEL); | 1040 | GFP_KERNEL); |
1041 | if (!the_card.null_buffer_start_vaddr) { | 1041 | if (!the_card.null_buffer_start_vaddr) { |
1042 | pr_info("%s: nullbuffer alloc failed\n", __func__); | 1042 | pr_info("%s: nullbuffer alloc failed\n", __func__); |
1043 | ret = -ENOMEM; | ||
1043 | goto clean_preallocate; | 1044 | goto clean_preallocate; |
1044 | } | 1045 | } |
1045 | pr_debug("%s: null vaddr=%p dma=%#llx\n", __func__, | 1046 | pr_debug("%s: null vaddr=%p dma=%#llx\n", __func__, |
diff --git a/sound/soc/blackfin/bf6xx-sport.c b/sound/soc/blackfin/bf6xx-sport.c index 318c5ba5360f..dfb744381c42 100644 --- a/sound/soc/blackfin/bf6xx-sport.c +++ b/sound/soc/blackfin/bf6xx-sport.c | |||
@@ -413,7 +413,14 @@ EXPORT_SYMBOL(sport_create); | |||
413 | 413 | ||
414 | void sport_delete(struct sport_device *sport) | 414 | void sport_delete(struct sport_device *sport) |
415 | { | 415 | { |
416 | if (sport->tx_desc) | ||
417 | dma_free_coherent(NULL, sport->tx_desc_size, | ||
418 | sport->tx_desc, 0); | ||
419 | if (sport->rx_desc) | ||
420 | dma_free_coherent(NULL, sport->rx_desc_size, | ||
421 | sport->rx_desc, 0); | ||
416 | sport_free_resource(sport); | 422 | sport_free_resource(sport); |
423 | kfree(sport); | ||
417 | } | 424 | } |
418 | EXPORT_SYMBOL(sport_delete); | 425 | EXPORT_SYMBOL(sport_delete); |
419 | 426 | ||
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c index 3c795921c5f6..23b40186f9b8 100644 --- a/sound/soc/codecs/ab8500-codec.c +++ b/sound/soc/codecs/ab8500-codec.c | |||
@@ -2406,6 +2406,10 @@ static int ab8500_codec_probe(struct snd_soc_codec *codec) | |||
2406 | 2406 | ||
2407 | /* Setup AB8500 according to board-settings */ | 2407 | /* Setup AB8500 according to board-settings */ |
2408 | pdata = (struct ab8500_platform_data *)dev_get_platdata(dev->parent); | 2408 | pdata = (struct ab8500_platform_data *)dev_get_platdata(dev->parent); |
2409 | |||
2410 | /* Inform SoC Core that we have our own I/O arrangements. */ | ||
2411 | codec->control_data = (void *)true; | ||
2412 | |||
2409 | status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); | 2413 | status = ab8500_audio_setup_mics(codec, &pdata->codec->amics); |
2410 | if (status < 0) { | 2414 | if (status < 0) { |
2411 | pr_err("%s: Failed to setup mics (%d)!\n", __func__, status); | 2415 | pr_err("%s: Failed to setup mics (%d)!\n", __func__, status); |
diff --git a/sound/soc/codecs/ad1980.c b/sound/soc/codecs/ad1980.c index 8c39dddd7d00..11b1b714b8b5 100644 --- a/sound/soc/codecs/ad1980.c +++ b/sound/soc/codecs/ad1980.c | |||
@@ -186,6 +186,7 @@ static int ad1980_soc_probe(struct snd_soc_codec *codec) | |||
186 | 186 | ||
187 | printk(KERN_INFO "AD1980 SoC Audio Codec\n"); | 187 | printk(KERN_INFO "AD1980 SoC Audio Codec\n"); |
188 | 188 | ||
189 | codec->control_data = codec; /* we don't use regmap! */ | ||
189 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | 190 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); |
190 | if (ret < 0) { | 191 | if (ret < 0) { |
191 | printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); | 192 | printk(KERN_ERR "ad1980: failed to register AC97 codec\n"); |
diff --git a/sound/soc/codecs/mc13783.c b/sound/soc/codecs/mc13783.c index 6276e352125f..8f726c063f42 100644 --- a/sound/soc/codecs/mc13783.c +++ b/sound/soc/codecs/mc13783.c | |||
@@ -581,6 +581,8 @@ static int mc13783_probe(struct snd_soc_codec *codec) | |||
581 | { | 581 | { |
582 | struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); | 582 | struct mc13783_priv *priv = snd_soc_codec_get_drvdata(codec); |
583 | 583 | ||
584 | codec->control_data = priv->mc13xxx; | ||
585 | |||
584 | mc13xxx_lock(priv->mc13xxx); | 586 | mc13xxx_lock(priv->mc13xxx); |
585 | 587 | ||
586 | /* these are the reset values */ | 588 | /* these are the reset values */ |
diff --git a/sound/soc/codecs/sgtl5000.c b/sound/soc/codecs/sgtl5000.c index 8af6a5245b18..df2f99d1d428 100644 --- a/sound/soc/codecs/sgtl5000.c +++ b/sound/soc/codecs/sgtl5000.c | |||
@@ -239,6 +239,7 @@ static const struct snd_soc_dapm_route sgtl5000_dapm_routes[] = { | |||
239 | {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */ | 239 | {"Headphone Mux", "DAC", "DAC"}, /* dac --> hp_mux */ |
240 | {"LO", NULL, "DAC"}, /* dac --> line_out */ | 240 | {"LO", NULL, "DAC"}, /* dac --> line_out */ |
241 | 241 | ||
242 | {"LINE_IN", NULL, "VAG_POWER"}, | ||
242 | {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */ | 243 | {"Headphone Mux", "LINE_IN", "LINE_IN"},/* line_in --> hp_mux */ |
243 | {"HP", NULL, "Headphone Mux"}, /* hp_mux --> hp */ | 244 | {"HP", NULL, "Headphone Mux"}, /* hp_mux --> hp */ |
244 | 245 | ||
@@ -1357,8 +1358,6 @@ static int sgtl5000_probe(struct snd_soc_codec *codec) | |||
1357 | if (ret) | 1358 | if (ret) |
1358 | goto err; | 1359 | goto err; |
1359 | 1360 | ||
1360 | snd_soc_dapm_new_widgets(&codec->dapm); | ||
1361 | |||
1362 | return 0; | 1361 | return 0; |
1363 | 1362 | ||
1364 | err: | 1363 | err: |
diff --git a/sound/soc/codecs/stac9766.c b/sound/soc/codecs/stac9766.c index 982e437799a8..33c0f3d39c87 100644 --- a/sound/soc/codecs/stac9766.c +++ b/sound/soc/codecs/stac9766.c | |||
@@ -340,6 +340,7 @@ static int stac9766_codec_probe(struct snd_soc_codec *codec) | |||
340 | 340 | ||
341 | printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION); | 341 | printk(KERN_INFO "STAC9766 SoC Audio Codec %s\n", STAC9766_VERSION); |
342 | 342 | ||
343 | codec->control_data = codec; /* we don't use regmap! */ | ||
343 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | 344 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); |
344 | if (ret < 0) | 345 | if (ret < 0) |
345 | goto codec_err; | 346 | goto codec_err; |
diff --git a/sound/soc/codecs/wm5102.c b/sound/soc/codecs/wm5102.c index 6537f16d383e..e33d327396ad 100644 --- a/sound/soc/codecs/wm5102.c +++ b/sound/soc/codecs/wm5102.c | |||
@@ -128,13 +128,9 @@ SOC_SINGLE_TLV("EQ4 B5 Volume", ARIZONA_EQ4_2, ARIZONA_EQ4_B5_GAIN_SHIFT, | |||
128 | 128 | ||
129 | ARIZONA_MIXER_CONTROLS("DRC1L", ARIZONA_DRC1LMIX_INPUT_1_SOURCE), | 129 | ARIZONA_MIXER_CONTROLS("DRC1L", ARIZONA_DRC1LMIX_INPUT_1_SOURCE), |
130 | ARIZONA_MIXER_CONTROLS("DRC1R", ARIZONA_DRC1RMIX_INPUT_1_SOURCE), | 130 | ARIZONA_MIXER_CONTROLS("DRC1R", ARIZONA_DRC1RMIX_INPUT_1_SOURCE), |
131 | ARIZONA_MIXER_CONTROLS("DRC2L", ARIZONA_DRC2LMIX_INPUT_1_SOURCE), | ||
132 | ARIZONA_MIXER_CONTROLS("DRC2R", ARIZONA_DRC2RMIX_INPUT_1_SOURCE), | ||
133 | 131 | ||
134 | SND_SOC_BYTES_MASK("DRC1", ARIZONA_DRC1_CTRL1, 5, | 132 | SND_SOC_BYTES_MASK("DRC1", ARIZONA_DRC1_CTRL1, 5, |
135 | ARIZONA_DRC1R_ENA | ARIZONA_DRC1L_ENA), | 133 | ARIZONA_DRC1R_ENA | ARIZONA_DRC1L_ENA), |
136 | SND_SOC_BYTES_MASK("DRC2", ARIZONA_DRC2_CTRL1, 5, | ||
137 | ARIZONA_DRC2R_ENA | ARIZONA_DRC2L_ENA), | ||
138 | 134 | ||
139 | ARIZONA_MIXER_CONTROLS("LHPF1", ARIZONA_HPLP1MIX_INPUT_1_SOURCE), | 135 | ARIZONA_MIXER_CONTROLS("LHPF1", ARIZONA_HPLP1MIX_INPUT_1_SOURCE), |
140 | ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE), | 136 | ARIZONA_MIXER_CONTROLS("LHPF2", ARIZONA_HPLP2MIX_INPUT_1_SOURCE), |
@@ -236,8 +232,6 @@ ARIZONA_MIXER_ENUMS(EQ4, ARIZONA_EQ4MIX_INPUT_1_SOURCE); | |||
236 | 232 | ||
237 | ARIZONA_MIXER_ENUMS(DRC1L, ARIZONA_DRC1LMIX_INPUT_1_SOURCE); | 233 | ARIZONA_MIXER_ENUMS(DRC1L, ARIZONA_DRC1LMIX_INPUT_1_SOURCE); |
238 | ARIZONA_MIXER_ENUMS(DRC1R, ARIZONA_DRC1RMIX_INPUT_1_SOURCE); | 234 | ARIZONA_MIXER_ENUMS(DRC1R, ARIZONA_DRC1RMIX_INPUT_1_SOURCE); |
239 | ARIZONA_MIXER_ENUMS(DRC2L, ARIZONA_DRC2LMIX_INPUT_1_SOURCE); | ||
240 | ARIZONA_MIXER_ENUMS(DRC2R, ARIZONA_DRC2RMIX_INPUT_1_SOURCE); | ||
241 | 235 | ||
242 | ARIZONA_MIXER_ENUMS(LHPF1, ARIZONA_HPLP1MIX_INPUT_1_SOURCE); | 236 | ARIZONA_MIXER_ENUMS(LHPF1, ARIZONA_HPLP1MIX_INPUT_1_SOURCE); |
243 | ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE); | 237 | ARIZONA_MIXER_ENUMS(LHPF2, ARIZONA_HPLP2MIX_INPUT_1_SOURCE); |
@@ -349,10 +343,6 @@ SND_SOC_DAPM_PGA("DRC1L", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1L_ENA_SHIFT, 0, | |||
349 | NULL, 0), | 343 | NULL, 0), |
350 | SND_SOC_DAPM_PGA("DRC1R", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1R_ENA_SHIFT, 0, | 344 | SND_SOC_DAPM_PGA("DRC1R", ARIZONA_DRC1_CTRL1, ARIZONA_DRC1R_ENA_SHIFT, 0, |
351 | NULL, 0), | 345 | NULL, 0), |
352 | SND_SOC_DAPM_PGA("DRC2L", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2L_ENA_SHIFT, 0, | ||
353 | NULL, 0), | ||
354 | SND_SOC_DAPM_PGA("DRC2R", ARIZONA_DRC2_CTRL1, ARIZONA_DRC2R_ENA_SHIFT, 0, | ||
355 | NULL, 0), | ||
356 | 346 | ||
357 | SND_SOC_DAPM_PGA("LHPF1", ARIZONA_HPLPF1_1, ARIZONA_LHPF1_ENA_SHIFT, 0, | 347 | SND_SOC_DAPM_PGA("LHPF1", ARIZONA_HPLPF1_1, ARIZONA_LHPF1_ENA_SHIFT, 0, |
358 | NULL, 0), | 348 | NULL, 0), |
@@ -466,8 +456,6 @@ ARIZONA_MIXER_WIDGETS(EQ4, "EQ4"), | |||
466 | 456 | ||
467 | ARIZONA_MIXER_WIDGETS(DRC1L, "DRC1L"), | 457 | ARIZONA_MIXER_WIDGETS(DRC1L, "DRC1L"), |
468 | ARIZONA_MIXER_WIDGETS(DRC1R, "DRC1R"), | 458 | ARIZONA_MIXER_WIDGETS(DRC1R, "DRC1R"), |
469 | ARIZONA_MIXER_WIDGETS(DRC2L, "DRC2L"), | ||
470 | ARIZONA_MIXER_WIDGETS(DRC2R, "DRC2R"), | ||
471 | 459 | ||
472 | ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"), | 460 | ARIZONA_MIXER_WIDGETS(LHPF1, "LHPF1"), |
473 | ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"), | 461 | ARIZONA_MIXER_WIDGETS(LHPF2, "LHPF2"), |
@@ -553,8 +541,6 @@ SND_SOC_DAPM_OUTPUT("SPKDAT1R"), | |||
553 | { name, "EQ4", "EQ4" }, \ | 541 | { name, "EQ4", "EQ4" }, \ |
554 | { name, "DRC1L", "DRC1L" }, \ | 542 | { name, "DRC1L", "DRC1L" }, \ |
555 | { name, "DRC1R", "DRC1R" }, \ | 543 | { name, "DRC1R", "DRC1R" }, \ |
556 | { name, "DRC2L", "DRC2L" }, \ | ||
557 | { name, "DRC2R", "DRC2R" }, \ | ||
558 | { name, "LHPF1", "LHPF1" }, \ | 544 | { name, "LHPF1", "LHPF1" }, \ |
559 | { name, "LHPF2", "LHPF2" }, \ | 545 | { name, "LHPF2", "LHPF2" }, \ |
560 | { name, "LHPF3", "LHPF3" }, \ | 546 | { name, "LHPF3", "LHPF3" }, \ |
@@ -639,6 +625,15 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | |||
639 | { "AIF2 Capture", NULL, "SYSCLK" }, | 625 | { "AIF2 Capture", NULL, "SYSCLK" }, |
640 | { "AIF3 Capture", NULL, "SYSCLK" }, | 626 | { "AIF3 Capture", NULL, "SYSCLK" }, |
641 | 627 | ||
628 | { "IN1L PGA", NULL, "IN1L" }, | ||
629 | { "IN1R PGA", NULL, "IN1R" }, | ||
630 | |||
631 | { "IN2L PGA", NULL, "IN2L" }, | ||
632 | { "IN2R PGA", NULL, "IN2R" }, | ||
633 | |||
634 | { "IN3L PGA", NULL, "IN3L" }, | ||
635 | { "IN3R PGA", NULL, "IN3R" }, | ||
636 | |||
642 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), | 637 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), |
643 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), | 638 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), |
644 | ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), | 639 | ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), |
@@ -675,8 +670,6 @@ static const struct snd_soc_dapm_route wm5102_dapm_routes[] = { | |||
675 | 670 | ||
676 | ARIZONA_MIXER_ROUTES("DRC1L", "DRC1L"), | 671 | ARIZONA_MIXER_ROUTES("DRC1L", "DRC1L"), |
677 | ARIZONA_MIXER_ROUTES("DRC1R", "DRC1R"), | 672 | ARIZONA_MIXER_ROUTES("DRC1R", "DRC1R"), |
678 | ARIZONA_MIXER_ROUTES("DRC2L", "DRC2L"), | ||
679 | ARIZONA_MIXER_ROUTES("DRC2R", "DRC2R"), | ||
680 | 673 | ||
681 | ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"), | 674 | ARIZONA_MIXER_ROUTES("LHPF1", "LHPF1"), |
682 | ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"), | 675 | ARIZONA_MIXER_ROUTES("LHPF2", "LHPF2"), |
diff --git a/sound/soc/codecs/wm5110.c b/sound/soc/codecs/wm5110.c index 8033f7065189..01ebbcc5c6a4 100644 --- a/sound/soc/codecs/wm5110.c +++ b/sound/soc/codecs/wm5110.c | |||
@@ -681,6 +681,18 @@ static const struct snd_soc_dapm_route wm5110_dapm_routes[] = { | |||
681 | { "AIF2 Capture", NULL, "SYSCLK" }, | 681 | { "AIF2 Capture", NULL, "SYSCLK" }, |
682 | { "AIF3 Capture", NULL, "SYSCLK" }, | 682 | { "AIF3 Capture", NULL, "SYSCLK" }, |
683 | 683 | ||
684 | { "IN1L PGA", NULL, "IN1L" }, | ||
685 | { "IN1R PGA", NULL, "IN1R" }, | ||
686 | |||
687 | { "IN2L PGA", NULL, "IN2L" }, | ||
688 | { "IN2R PGA", NULL, "IN2R" }, | ||
689 | |||
690 | { "IN3L PGA", NULL, "IN3L" }, | ||
691 | { "IN3R PGA", NULL, "IN3R" }, | ||
692 | |||
693 | { "IN4L PGA", NULL, "IN4L" }, | ||
694 | { "IN4R PGA", NULL, "IN4R" }, | ||
695 | |||
684 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), | 696 | ARIZONA_MIXER_ROUTES("OUT1L", "HPOUT1L"), |
685 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), | 697 | ARIZONA_MIXER_ROUTES("OUT1R", "HPOUT1R"), |
686 | ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), | 698 | ARIZONA_MIXER_ROUTES("OUT2L", "HPOUT2L"), |
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c index eaf65863ec21..ce6720073798 100644 --- a/sound/soc/codecs/wm8962.c +++ b/sound/soc/codecs/wm8962.c | |||
@@ -2501,6 +2501,9 @@ static int wm8962_set_bias_level(struct snd_soc_codec *codec, | |||
2501 | /* VMID 2*250k */ | 2501 | /* VMID 2*250k */ |
2502 | snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, | 2502 | snd_soc_update_bits(codec, WM8962_PWR_MGMT_1, |
2503 | WM8962_VMID_SEL_MASK, 0x100); | 2503 | WM8962_VMID_SEL_MASK, 0x100); |
2504 | |||
2505 | if (codec->dapm.bias_level == SND_SOC_BIAS_OFF) | ||
2506 | msleep(100); | ||
2504 | break; | 2507 | break; |
2505 | 2508 | ||
2506 | case SND_SOC_BIAS_OFF: | 2509 | case SND_SOC_BIAS_OFF: |
@@ -3730,21 +3733,6 @@ static int wm8962_runtime_resume(struct device *dev) | |||
3730 | 3733 | ||
3731 | regcache_sync(wm8962->regmap); | 3734 | regcache_sync(wm8962->regmap); |
3732 | 3735 | ||
3733 | regmap_update_bits(wm8962->regmap, WM8962_ANTI_POP, | ||
3734 | WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA, | ||
3735 | WM8962_STARTUP_BIAS_ENA | WM8962_VMID_BUF_ENA); | ||
3736 | |||
3737 | /* Bias enable at 2*50k for ramp */ | ||
3738 | regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1, | ||
3739 | WM8962_VMID_SEL_MASK | WM8962_BIAS_ENA, | ||
3740 | WM8962_BIAS_ENA | 0x180); | ||
3741 | |||
3742 | msleep(5); | ||
3743 | |||
3744 | /* VMID back to 2x250k for standby */ | ||
3745 | regmap_update_bits(wm8962->regmap, WM8962_PWR_MGMT_1, | ||
3746 | WM8962_VMID_SEL_MASK, 0x100); | ||
3747 | |||
3748 | return 0; | 3736 | return 0; |
3749 | } | 3737 | } |
3750 | 3738 | ||
diff --git a/sound/soc/codecs/wm8994.c b/sound/soc/codecs/wm8994.c index bb62f4b3d563..6c9eeca85b95 100644 --- a/sound/soc/codecs/wm8994.c +++ b/sound/soc/codecs/wm8994.c | |||
@@ -2649,7 +2649,7 @@ static int wm8994_hw_params(struct snd_pcm_substream *substream, | |||
2649 | return -EINVAL; | 2649 | return -EINVAL; |
2650 | } | 2650 | } |
2651 | 2651 | ||
2652 | bclk_rate = params_rate(params) * 2; | 2652 | bclk_rate = params_rate(params) * 4; |
2653 | switch (params_format(params)) { | 2653 | switch (params_format(params)) { |
2654 | case SNDRV_PCM_FORMAT_S16_LE: | 2654 | case SNDRV_PCM_FORMAT_S16_LE: |
2655 | bclk_rate *= 16; | 2655 | bclk_rate *= 16; |
@@ -3253,10 +3253,13 @@ static void wm8994_mic_work(struct work_struct *work) | |||
3253 | int ret; | 3253 | int ret; |
3254 | int report; | 3254 | int report; |
3255 | 3255 | ||
3256 | pm_runtime_get_sync(dev); | ||
3257 | |||
3256 | ret = regmap_read(regmap, WM8994_INTERRUPT_RAW_STATUS_2, ®); | 3258 | ret = regmap_read(regmap, WM8994_INTERRUPT_RAW_STATUS_2, ®); |
3257 | if (ret < 0) { | 3259 | if (ret < 0) { |
3258 | dev_err(dev, "Failed to read microphone status: %d\n", | 3260 | dev_err(dev, "Failed to read microphone status: %d\n", |
3259 | ret); | 3261 | ret); |
3262 | pm_runtime_put(dev); | ||
3260 | return; | 3263 | return; |
3261 | } | 3264 | } |
3262 | 3265 | ||
@@ -3299,6 +3302,8 @@ static void wm8994_mic_work(struct work_struct *work) | |||
3299 | 3302 | ||
3300 | snd_soc_jack_report(priv->micdet[1].jack, report, | 3303 | snd_soc_jack_report(priv->micdet[1].jack, report, |
3301 | SND_JACK_HEADSET | SND_JACK_BTN_0); | 3304 | SND_JACK_HEADSET | SND_JACK_BTN_0); |
3305 | |||
3306 | pm_runtime_put(dev); | ||
3302 | } | 3307 | } |
3303 | 3308 | ||
3304 | static irqreturn_t wm8994_mic_irq(int irq, void *data) | 3309 | static irqreturn_t wm8994_mic_irq(int irq, void *data) |
@@ -3421,12 +3426,15 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3421 | int reg; | 3426 | int reg; |
3422 | bool present; | 3427 | bool present; |
3423 | 3428 | ||
3429 | pm_runtime_get_sync(codec->dev); | ||
3430 | |||
3424 | mutex_lock(&wm8994->accdet_lock); | 3431 | mutex_lock(&wm8994->accdet_lock); |
3425 | 3432 | ||
3426 | reg = snd_soc_read(codec, WM1811_JACKDET_CTRL); | 3433 | reg = snd_soc_read(codec, WM1811_JACKDET_CTRL); |
3427 | if (reg < 0) { | 3434 | if (reg < 0) { |
3428 | dev_err(codec->dev, "Failed to read jack status: %d\n", reg); | 3435 | dev_err(codec->dev, "Failed to read jack status: %d\n", reg); |
3429 | mutex_unlock(&wm8994->accdet_lock); | 3436 | mutex_unlock(&wm8994->accdet_lock); |
3437 | pm_runtime_put(codec->dev); | ||
3430 | return IRQ_NONE; | 3438 | return IRQ_NONE; |
3431 | } | 3439 | } |
3432 | 3440 | ||
@@ -3491,6 +3499,7 @@ static irqreturn_t wm1811_jackdet_irq(int irq, void *data) | |||
3491 | SND_JACK_MECHANICAL | SND_JACK_HEADSET | | 3499 | SND_JACK_MECHANICAL | SND_JACK_HEADSET | |
3492 | wm8994->btn_mask); | 3500 | wm8994->btn_mask); |
3493 | 3501 | ||
3502 | pm_runtime_put(codec->dev); | ||
3494 | return IRQ_HANDLED; | 3503 | return IRQ_HANDLED; |
3495 | } | 3504 | } |
3496 | 3505 | ||
@@ -3602,6 +3611,8 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3602 | if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) | 3611 | if (!(snd_soc_read(codec, WM8958_MIC_DETECT_1) & WM8958_MICD_ENA)) |
3603 | return IRQ_HANDLED; | 3612 | return IRQ_HANDLED; |
3604 | 3613 | ||
3614 | pm_runtime_get_sync(codec->dev); | ||
3615 | |||
3605 | /* We may occasionally read a detection without an impedence | 3616 | /* We may occasionally read a detection without an impedence |
3606 | * range being provided - if that happens loop again. | 3617 | * range being provided - if that happens loop again. |
3607 | */ | 3618 | */ |
@@ -3612,6 +3623,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3612 | dev_err(codec->dev, | 3623 | dev_err(codec->dev, |
3613 | "Failed to read mic detect status: %d\n", | 3624 | "Failed to read mic detect status: %d\n", |
3614 | reg); | 3625 | reg); |
3626 | pm_runtime_put(codec->dev); | ||
3615 | return IRQ_NONE; | 3627 | return IRQ_NONE; |
3616 | } | 3628 | } |
3617 | 3629 | ||
@@ -3639,6 +3651,7 @@ static irqreturn_t wm8958_mic_irq(int irq, void *data) | |||
3639 | dev_warn(codec->dev, "Accessory detection with no callback\n"); | 3651 | dev_warn(codec->dev, "Accessory detection with no callback\n"); |
3640 | 3652 | ||
3641 | out: | 3653 | out: |
3654 | pm_runtime_put(codec->dev); | ||
3642 | return IRQ_HANDLED; | 3655 | return IRQ_HANDLED; |
3643 | } | 3656 | } |
3644 | 3657 | ||
@@ -4025,6 +4038,8 @@ static int wm8994_codec_probe(struct snd_soc_codec *codec) | |||
4025 | break; | 4038 | break; |
4026 | case WM8958: | 4039 | case WM8958: |
4027 | if (wm8994->revision < 1) { | 4040 | if (wm8994->revision < 1) { |
4041 | snd_soc_dapm_add_routes(dapm, wm8994_intercon, | ||
4042 | ARRAY_SIZE(wm8994_intercon)); | ||
4028 | snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, | 4043 | snd_soc_dapm_add_routes(dapm, wm8994_revd_intercon, |
4029 | ARRAY_SIZE(wm8994_revd_intercon)); | 4044 | ARRAY_SIZE(wm8994_revd_intercon)); |
4030 | snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon, | 4045 | snd_soc_dapm_add_routes(dapm, wm8994_lateclk_revd_intercon, |
diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c index 099e6ec32125..c6d2076a796b 100644 --- a/sound/soc/codecs/wm9712.c +++ b/sound/soc/codecs/wm9712.c | |||
@@ -148,7 +148,7 @@ SOC_SINGLE("Treble Volume", AC97_MASTER_TONE, 0, 15, 1), | |||
148 | 148 | ||
149 | SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1), | 149 | SOC_SINGLE("Capture ADC Switch", AC97_REC_GAIN, 15, 1, 1), |
150 | SOC_ENUM("Capture Volume Steps", wm9712_enum[6]), | 150 | SOC_ENUM("Capture Volume Steps", wm9712_enum[6]), |
151 | SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 1), | 151 | SOC_DOUBLE("Capture Volume", AC97_REC_GAIN, 8, 0, 63, 0), |
152 | SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), | 152 | SOC_SINGLE("Capture ZC Switch", AC97_REC_GAIN, 7, 1, 0), |
153 | 153 | ||
154 | SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv), | 154 | SOC_SINGLE_TLV("Mic 1 Volume", AC97_MIC, 8, 31, 1, main_tlv), |
@@ -272,7 +272,7 @@ SOC_DAPM_ENUM("Route", wm9712_enum[9]); | |||
272 | 272 | ||
273 | /* Mic select */ | 273 | /* Mic select */ |
274 | static const struct snd_kcontrol_new wm9712_mic_src_controls = | 274 | static const struct snd_kcontrol_new wm9712_mic_src_controls = |
275 | SOC_DAPM_ENUM("Route", wm9712_enum[7]); | 275 | SOC_DAPM_ENUM("Mic Source Select", wm9712_enum[7]); |
276 | 276 | ||
277 | /* diff select */ | 277 | /* diff select */ |
278 | static const struct snd_kcontrol_new wm9712_diff_sel_controls = | 278 | static const struct snd_kcontrol_new wm9712_diff_sel_controls = |
@@ -291,7 +291,9 @@ SND_SOC_DAPM_MUX("Left Capture Select", SND_SOC_NOPM, 0, 0, | |||
291 | &wm9712_capture_selectl_controls), | 291 | &wm9712_capture_selectl_controls), |
292 | SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0, | 292 | SND_SOC_DAPM_MUX("Right Capture Select", SND_SOC_NOPM, 0, 0, |
293 | &wm9712_capture_selectr_controls), | 293 | &wm9712_capture_selectr_controls), |
294 | SND_SOC_DAPM_MUX("Mic Select Source", SND_SOC_NOPM, 0, 0, | 294 | SND_SOC_DAPM_MUX("Left Mic Select Source", SND_SOC_NOPM, 0, 0, |
295 | &wm9712_mic_src_controls), | ||
296 | SND_SOC_DAPM_MUX("Right Mic Select Source", SND_SOC_NOPM, 0, 0, | ||
295 | &wm9712_mic_src_controls), | 297 | &wm9712_mic_src_controls), |
296 | SND_SOC_DAPM_MUX("Differential Source", SND_SOC_NOPM, 0, 0, | 298 | SND_SOC_DAPM_MUX("Differential Source", SND_SOC_NOPM, 0, 0, |
297 | &wm9712_diff_sel_controls), | 299 | &wm9712_diff_sel_controls), |
@@ -319,6 +321,7 @@ SND_SOC_DAPM_PGA("Out 3 PGA", AC97_INT_PAGING, 5, 1, NULL, 0), | |||
319 | SND_SOC_DAPM_PGA("Line PGA", AC97_INT_PAGING, 2, 1, NULL, 0), | 321 | SND_SOC_DAPM_PGA("Line PGA", AC97_INT_PAGING, 2, 1, NULL, 0), |
320 | SND_SOC_DAPM_PGA("Phone PGA", AC97_INT_PAGING, 1, 1, NULL, 0), | 322 | SND_SOC_DAPM_PGA("Phone PGA", AC97_INT_PAGING, 1, 1, NULL, 0), |
321 | SND_SOC_DAPM_PGA("Mic PGA", AC97_INT_PAGING, 0, 1, NULL, 0), | 323 | SND_SOC_DAPM_PGA("Mic PGA", AC97_INT_PAGING, 0, 1, NULL, 0), |
324 | SND_SOC_DAPM_PGA("Differential Mic", SND_SOC_NOPM, 0, 0, NULL, 0), | ||
322 | SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_INT_PAGING, 10, 1), | 325 | SND_SOC_DAPM_MICBIAS("Mic Bias", AC97_INT_PAGING, 10, 1), |
323 | SND_SOC_DAPM_OUTPUT("MONOOUT"), | 326 | SND_SOC_DAPM_OUTPUT("MONOOUT"), |
324 | SND_SOC_DAPM_OUTPUT("HPOUTL"), | 327 | SND_SOC_DAPM_OUTPUT("HPOUTL"), |
@@ -379,6 +382,18 @@ static const struct snd_soc_dapm_route wm9712_audio_map[] = { | |||
379 | {"Mic PGA", NULL, "MIC1"}, | 382 | {"Mic PGA", NULL, "MIC1"}, |
380 | {"Mic PGA", NULL, "MIC2"}, | 383 | {"Mic PGA", NULL, "MIC2"}, |
381 | 384 | ||
385 | /* microphones */ | ||
386 | {"Differential Mic", NULL, "MIC1"}, | ||
387 | {"Differential Mic", NULL, "MIC2"}, | ||
388 | {"Left Mic Select Source", "Mic 1", "MIC1"}, | ||
389 | {"Left Mic Select Source", "Mic 2", "MIC2"}, | ||
390 | {"Left Mic Select Source", "Stereo", "MIC1"}, | ||
391 | {"Left Mic Select Source", "Differential", "Differential Mic"}, | ||
392 | {"Right Mic Select Source", "Mic 1", "MIC1"}, | ||
393 | {"Right Mic Select Source", "Mic 2", "MIC2"}, | ||
394 | {"Right Mic Select Source", "Stereo", "MIC2"}, | ||
395 | {"Right Mic Select Source", "Differential", "Differential Mic"}, | ||
396 | |||
382 | /* left capture selector */ | 397 | /* left capture selector */ |
383 | {"Left Capture Select", "Mic", "MIC1"}, | 398 | {"Left Capture Select", "Mic", "MIC1"}, |
384 | {"Left Capture Select", "Speaker Mixer", "Speaker Mixer"}, | 399 | {"Left Capture Select", "Speaker Mixer", "Speaker Mixer"}, |
@@ -619,6 +634,7 @@ static int wm9712_soc_probe(struct snd_soc_codec *codec) | |||
619 | { | 634 | { |
620 | int ret = 0; | 635 | int ret = 0; |
621 | 636 | ||
637 | codec->control_data = codec; /* we don't use regmap! */ | ||
622 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | 638 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); |
623 | if (ret < 0) { | 639 | if (ret < 0) { |
624 | printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); | 640 | printk(KERN_ERR "wm9712: failed to register AC97 codec\n"); |
diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c index 3eb19fb71d17..d0b8a3287a85 100644 --- a/sound/soc/codecs/wm9713.c +++ b/sound/soc/codecs/wm9713.c | |||
@@ -1196,6 +1196,7 @@ static int wm9713_soc_probe(struct snd_soc_codec *codec) | |||
1196 | if (wm9713 == NULL) | 1196 | if (wm9713 == NULL) |
1197 | return -ENOMEM; | 1197 | return -ENOMEM; |
1198 | snd_soc_codec_set_drvdata(codec, wm9713); | 1198 | snd_soc_codec_set_drvdata(codec, wm9713); |
1199 | codec->control_data = wm9713; /* we don't use regmap! */ | ||
1199 | 1200 | ||
1200 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); | 1201 | ret = snd_soc_new_ac97_codec(codec, &soc_ac97_ops, 0); |
1201 | if (ret < 0) | 1202 | if (ret < 0) |
diff --git a/sound/soc/davinci/davinci-mcasp.c b/sound/soc/davinci/davinci-mcasp.c index 95441bfc8190..ce5e5cd254dd 100644 --- a/sound/soc/davinci/davinci-mcasp.c +++ b/sound/soc/davinci/davinci-mcasp.c | |||
@@ -380,14 +380,20 @@ static void mcasp_start_tx(struct davinci_audio_dev *dev) | |||
380 | static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) | 380 | static void davinci_mcasp_start(struct davinci_audio_dev *dev, int stream) |
381 | { | 381 | { |
382 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { | 382 | if (stream == SNDRV_PCM_STREAM_PLAYBACK) { |
383 | if (dev->txnumevt) /* enable FIFO */ | 383 | if (dev->txnumevt) { /* enable FIFO */ |
384 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, | ||
385 | FIFO_ENABLE); | ||
384 | mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, | 386 | mcasp_set_bits(dev->base + DAVINCI_MCASP_WFIFOCTL, |
385 | FIFO_ENABLE); | 387 | FIFO_ENABLE); |
388 | } | ||
386 | mcasp_start_tx(dev); | 389 | mcasp_start_tx(dev); |
387 | } else { | 390 | } else { |
388 | if (dev->rxnumevt) /* enable FIFO */ | 391 | if (dev->rxnumevt) { /* enable FIFO */ |
392 | mcasp_clr_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, | ||
393 | FIFO_ENABLE); | ||
389 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, | 394 | mcasp_set_bits(dev->base + DAVINCI_MCASP_RFIFOCTL, |
390 | FIFO_ENABLE); | 395 | FIFO_ENABLE); |
396 | } | ||
391 | mcasp_start_rx(dev); | 397 | mcasp_start_rx(dev); |
392 | } | 398 | } |
393 | } | 399 | } |
diff --git a/sound/soc/fsl/imx-ssi.c b/sound/soc/fsl/imx-ssi.c index 28dd76c7cb1c..81d7728cf67f 100644 --- a/sound/soc/fsl/imx-ssi.c +++ b/sound/soc/fsl/imx-ssi.c | |||
@@ -380,13 +380,14 @@ static int imx_ssi_dai_probe(struct snd_soc_dai *dai) | |||
380 | static struct snd_soc_dai_driver imx_ssi_dai = { | 380 | static struct snd_soc_dai_driver imx_ssi_dai = { |
381 | .probe = imx_ssi_dai_probe, | 381 | .probe = imx_ssi_dai_probe, |
382 | .playback = { | 382 | .playback = { |
383 | .channels_min = 1, | 383 | /* The SSI does not support monaural audio. */ |
384 | .channels_min = 2, | ||
384 | .channels_max = 2, | 385 | .channels_max = 2, |
385 | .rates = SNDRV_PCM_RATE_8000_96000, | 386 | .rates = SNDRV_PCM_RATE_8000_96000, |
386 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 387 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
387 | }, | 388 | }, |
388 | .capture = { | 389 | .capture = { |
389 | .channels_min = 1, | 390 | .channels_min = 2, |
390 | .channels_max = 2, | 391 | .channels_max = 2, |
391 | .rates = SNDRV_PCM_RATE_8000_96000, | 392 | .rates = SNDRV_PCM_RATE_8000_96000, |
392 | .formats = SNDRV_PCM_FMTBIT_S16_LE, | 393 | .formats = SNDRV_PCM_FMTBIT_S16_LE, |
diff --git a/sound/soc/mxs/Kconfig b/sound/soc/mxs/Kconfig index 99a997f19bb9..b6fa77678d97 100644 --- a/sound/soc/mxs/Kconfig +++ b/sound/soc/mxs/Kconfig | |||
@@ -10,7 +10,7 @@ menuconfig SND_MXS_SOC | |||
10 | if SND_MXS_SOC | 10 | if SND_MXS_SOC |
11 | 11 | ||
12 | config SND_SOC_MXS_SGTL5000 | 12 | config SND_SOC_MXS_SGTL5000 |
13 | tristate "SoC Audio support for i.MX boards with sgtl5000" | 13 | tristate "SoC Audio support for MXS boards with sgtl5000" |
14 | depends on I2C | 14 | depends on I2C |
15 | select SND_SOC_SGTL5000 | 15 | select SND_SOC_SGTL5000 |
16 | help | 16 | help |
diff --git a/sound/soc/mxs/mxs-saif.c b/sound/soc/mxs/mxs-saif.c index aba71bfa33b1..b3030718c228 100644 --- a/sound/soc/mxs/mxs-saif.c +++ b/sound/soc/mxs/mxs-saif.c | |||
@@ -394,9 +394,14 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream, | |||
394 | struct snd_soc_dai *cpu_dai) | 394 | struct snd_soc_dai *cpu_dai) |
395 | { | 395 | { |
396 | struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); | 396 | struct mxs_saif *saif = snd_soc_dai_get_drvdata(cpu_dai); |
397 | struct mxs_saif *master_saif; | ||
397 | u32 scr, stat; | 398 | u32 scr, stat; |
398 | int ret; | 399 | int ret; |
399 | 400 | ||
401 | master_saif = mxs_saif_get_master(saif); | ||
402 | if (!master_saif) | ||
403 | return -EINVAL; | ||
404 | |||
400 | /* mclk should already be set */ | 405 | /* mclk should already be set */ |
401 | if (!saif->mclk && saif->mclk_in_use) { | 406 | if (!saif->mclk && saif->mclk_in_use) { |
402 | dev_err(cpu_dai->dev, "set mclk first\n"); | 407 | dev_err(cpu_dai->dev, "set mclk first\n"); |
@@ -420,6 +425,25 @@ static int mxs_saif_hw_params(struct snd_pcm_substream *substream, | |||
420 | return ret; | 425 | return ret; |
421 | } | 426 | } |
422 | 427 | ||
428 | /* prepare clk in hw_param, enable in trigger */ | ||
429 | clk_prepare(saif->clk); | ||
430 | if (saif != master_saif) { | ||
431 | /* | ||
432 | * Set an initial clock rate for the saif internal logic to work | ||
433 | * properly. This is important when working in EXTMASTER mode | ||
434 | * that uses the other saif's BITCLK&LRCLK but it still needs a | ||
435 | * basic clock which should be fast enough for the internal | ||
436 | * logic. | ||
437 | */ | ||
438 | clk_enable(saif->clk); | ||
439 | ret = clk_set_rate(saif->clk, 24000000); | ||
440 | clk_disable(saif->clk); | ||
441 | if (ret) | ||
442 | return ret; | ||
443 | |||
444 | clk_prepare(master_saif->clk); | ||
445 | } | ||
446 | |||
423 | scr = __raw_readl(saif->base + SAIF_CTRL); | 447 | scr = __raw_readl(saif->base + SAIF_CTRL); |
424 | 448 | ||
425 | scr &= ~BM_SAIF_CTRL_WORD_LENGTH; | 449 | scr &= ~BM_SAIF_CTRL_WORD_LENGTH; |
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c index 34835e8a9160..d33c48baaf71 100644 --- a/sound/soc/omap/mcbsp.c +++ b/sound/soc/omap/mcbsp.c | |||
@@ -745,7 +745,7 @@ int omap_mcbsp_6pin_src_mux(struct omap_mcbsp *mcbsp, u8 mux) | |||
745 | { | 745 | { |
746 | const char *signal, *src; | 746 | const char *signal, *src; |
747 | 747 | ||
748 | if (mcbsp->pdata->mux_signal) | 748 | if (!mcbsp->pdata->mux_signal) |
749 | return -EINVAL; | 749 | return -EINVAL; |
750 | 750 | ||
751 | switch (mux) { | 751 | switch (mux) { |
diff --git a/sound/soc/omap/omap-mcbsp.c b/sound/soc/omap/omap-mcbsp.c index 1046083e90a0..acdd3ef14e08 100644 --- a/sound/soc/omap/omap-mcbsp.c +++ b/sound/soc/omap/omap-mcbsp.c | |||
@@ -820,3 +820,4 @@ module_platform_driver(asoc_mcbsp_driver); | |||
820 | MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); | 820 | MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); |
821 | MODULE_DESCRIPTION("OMAP I2S SoC Interface"); | 821 | MODULE_DESCRIPTION("OMAP I2S SoC Interface"); |
822 | MODULE_LICENSE("GPL"); | 822 | MODULE_LICENSE("GPL"); |
823 | MODULE_ALIAS("platform:omap-mcbsp"); | ||
diff --git a/sound/soc/omap/omap-pcm.c b/sound/soc/omap/omap-pcm.c index 5a649da9122a..f0feb06615f8 100644 --- a/sound/soc/omap/omap-pcm.c +++ b/sound/soc/omap/omap-pcm.c | |||
@@ -441,3 +441,4 @@ module_platform_driver(omap_pcm_driver); | |||
441 | MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); | 441 | MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@bitmer.com>"); |
442 | MODULE_DESCRIPTION("OMAP PCM DMA module"); | 442 | MODULE_DESCRIPTION("OMAP PCM DMA module"); |
443 | MODULE_LICENSE("GPL"); | 443 | MODULE_LICENSE("GPL"); |
444 | MODULE_ALIAS("platform:omap-pcm-audio"); | ||
diff --git a/sound/soc/samsung/pcm.c b/sound/soc/samsung/pcm.c index b7b2a1f91425..89b064650f14 100644 --- a/sound/soc/samsung/pcm.c +++ b/sound/soc/samsung/pcm.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <sound/pcm_params.h> | 20 | #include <sound/pcm_params.h> |
21 | 21 | ||
22 | #include <plat/audio.h> | 22 | #include <plat/audio.h> |
23 | #include <plat/dma.h> | 23 | #include <mach/dma.h> |
24 | 24 | ||
25 | #include "dma.h" | 25 | #include "dma.h" |
26 | #include "pcm.h" | 26 | #include "pcm.h" |
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index f219b2f7ee68..c501af6d8dbe 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c | |||
@@ -826,7 +826,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
826 | } | 826 | } |
827 | 827 | ||
828 | if (!rtd->cpu_dai) { | 828 | if (!rtd->cpu_dai) { |
829 | dev_dbg(card->dev, "CPU DAI %s not registered\n", | 829 | dev_err(card->dev, "CPU DAI %s not registered\n", |
830 | dai_link->cpu_dai_name); | 830 | dai_link->cpu_dai_name); |
831 | return -EPROBE_DEFER; | 831 | return -EPROBE_DEFER; |
832 | } | 832 | } |
@@ -857,14 +857,14 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
857 | } | 857 | } |
858 | 858 | ||
859 | if (!rtd->codec_dai) { | 859 | if (!rtd->codec_dai) { |
860 | dev_dbg(card->dev, "CODEC DAI %s not registered\n", | 860 | dev_err(card->dev, "CODEC DAI %s not registered\n", |
861 | dai_link->codec_dai_name); | 861 | dai_link->codec_dai_name); |
862 | return -EPROBE_DEFER; | 862 | return -EPROBE_DEFER; |
863 | } | 863 | } |
864 | } | 864 | } |
865 | 865 | ||
866 | if (!rtd->codec) { | 866 | if (!rtd->codec) { |
867 | dev_dbg(card->dev, "CODEC %s not registered\n", | 867 | dev_err(card->dev, "CODEC %s not registered\n", |
868 | dai_link->codec_name); | 868 | dai_link->codec_name); |
869 | return -EPROBE_DEFER; | 869 | return -EPROBE_DEFER; |
870 | } | 870 | } |
@@ -888,7 +888,7 @@ static int soc_bind_dai_link(struct snd_soc_card *card, int num) | |||
888 | rtd->platform = platform; | 888 | rtd->platform = platform; |
889 | } | 889 | } |
890 | if (!rtd->platform) { | 890 | if (!rtd->platform) { |
891 | dev_dbg(card->dev, "platform %s not registered\n", | 891 | dev_err(card->dev, "platform %s not registered\n", |
892 | dai_link->platform_name); | 892 | dai_link->platform_name); |
893 | return -EPROBE_DEFER; | 893 | return -EPROBE_DEFER; |
894 | } | 894 | } |
@@ -1096,7 +1096,7 @@ static int soc_probe_codec(struct snd_soc_card *card, | |||
1096 | } | 1096 | } |
1097 | 1097 | ||
1098 | /* If the driver didn't set I/O up try regmap */ | 1098 | /* If the driver didn't set I/O up try regmap */ |
1099 | if (!codec->control_data) | 1099 | if (!codec->write && dev_get_regmap(codec->dev, NULL)) |
1100 | snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); | 1100 | snd_soc_codec_set_cache_io(codec, 0, 0, SND_SOC_REGMAP); |
1101 | 1101 | ||
1102 | if (driver->controls) | 1102 | if (driver->controls) |
@@ -1481,6 +1481,8 @@ static int soc_check_aux_dev(struct snd_soc_card *card, int num) | |||
1481 | return 0; | 1481 | return 0; |
1482 | } | 1482 | } |
1483 | 1483 | ||
1484 | dev_err(card->dev, "%s not registered\n", aux_dev->codec_name); | ||
1485 | |||
1484 | return -EPROBE_DEFER; | 1486 | return -EPROBE_DEFER; |
1485 | } | 1487 | } |
1486 | 1488 | ||
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c index 7f8b3b7428bb..0c172938b82a 100644 --- a/sound/soc/soc-jack.c +++ b/sound/soc/soc-jack.c | |||
@@ -103,7 +103,7 @@ void snd_soc_jack_report(struct snd_soc_jack *jack, int status, int mask) | |||
103 | } | 103 | } |
104 | 104 | ||
105 | /* Report before the DAPM sync to help users updating micbias status */ | 105 | /* Report before the DAPM sync to help users updating micbias status */ |
106 | blocking_notifier_call_chain(&jack->notifier, status, jack); | 106 | blocking_notifier_call_chain(&jack->notifier, jack->status, jack); |
107 | 107 | ||
108 | snd_soc_dapm_sync(dapm); | 108 | snd_soc_dapm_sync(dapm); |
109 | 109 | ||
diff --git a/sound/soc/tegra/tegra_alc5632.c b/sound/soc/tegra/tegra_alc5632.c index d684df294c0c..e463529b38bb 100644 --- a/sound/soc/tegra/tegra_alc5632.c +++ b/sound/soc/tegra/tegra_alc5632.c | |||
@@ -177,7 +177,7 @@ static __devinit int tegra_alc5632_probe(struct platform_device *pdev) | |||
177 | } | 177 | } |
178 | 178 | ||
179 | alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); | 179 | alc5632->gpio_hp_det = of_get_named_gpio(np, "nvidia,hp-det-gpios", 0); |
180 | if (alc5632->gpio_hp_det == -ENODEV) | 180 | if (alc5632->gpio_hp_det == -EPROBE_DEFER) |
181 | return -EPROBE_DEFER; | 181 | return -EPROBE_DEFER; |
182 | 182 | ||
183 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); | 183 | ret = snd_soc_of_parse_card_name(card, "nvidia,model"); |
diff --git a/sound/soc/tegra/tegra_wm8903.c b/sound/soc/tegra/tegra_wm8903.c index 0c5bb33d258e..d4f14e492341 100644 --- a/sound/soc/tegra/tegra_wm8903.c +++ b/sound/soc/tegra/tegra_wm8903.c | |||
@@ -284,27 +284,27 @@ static __devinit int tegra_wm8903_driver_probe(struct platform_device *pdev) | |||
284 | } else if (np) { | 284 | } else if (np) { |
285 | pdata->gpio_spkr_en = of_get_named_gpio(np, | 285 | pdata->gpio_spkr_en = of_get_named_gpio(np, |
286 | "nvidia,spkr-en-gpios", 0); | 286 | "nvidia,spkr-en-gpios", 0); |
287 | if (pdata->gpio_spkr_en == -ENODEV) | 287 | if (pdata->gpio_spkr_en == -EPROBE_DEFER) |
288 | return -EPROBE_DEFER; | 288 | return -EPROBE_DEFER; |
289 | 289 | ||
290 | pdata->gpio_hp_mute = of_get_named_gpio(np, | 290 | pdata->gpio_hp_mute = of_get_named_gpio(np, |
291 | "nvidia,hp-mute-gpios", 0); | 291 | "nvidia,hp-mute-gpios", 0); |
292 | if (pdata->gpio_hp_mute == -ENODEV) | 292 | if (pdata->gpio_hp_mute == -EPROBE_DEFER) |
293 | return -EPROBE_DEFER; | 293 | return -EPROBE_DEFER; |
294 | 294 | ||
295 | pdata->gpio_hp_det = of_get_named_gpio(np, | 295 | pdata->gpio_hp_det = of_get_named_gpio(np, |
296 | "nvidia,hp-det-gpios", 0); | 296 | "nvidia,hp-det-gpios", 0); |
297 | if (pdata->gpio_hp_det == -ENODEV) | 297 | if (pdata->gpio_hp_det == -EPROBE_DEFER) |
298 | return -EPROBE_DEFER; | 298 | return -EPROBE_DEFER; |
299 | 299 | ||
300 | pdata->gpio_int_mic_en = of_get_named_gpio(np, | 300 | pdata->gpio_int_mic_en = of_get_named_gpio(np, |
301 | "nvidia,int-mic-en-gpios", 0); | 301 | "nvidia,int-mic-en-gpios", 0); |
302 | if (pdata->gpio_int_mic_en == -ENODEV) | 302 | if (pdata->gpio_int_mic_en == -EPROBE_DEFER) |
303 | return -EPROBE_DEFER; | 303 | return -EPROBE_DEFER; |
304 | 304 | ||
305 | pdata->gpio_ext_mic_en = of_get_named_gpio(np, | 305 | pdata->gpio_ext_mic_en = of_get_named_gpio(np, |
306 | "nvidia,ext-mic-en-gpios", 0); | 306 | "nvidia,ext-mic-en-gpios", 0); |
307 | if (pdata->gpio_ext_mic_en == -ENODEV) | 307 | if (pdata->gpio_ext_mic_en == -EPROBE_DEFER) |
308 | return -EPROBE_DEFER; | 308 | return -EPROBE_DEFER; |
309 | } | 309 | } |
310 | 310 | ||
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c index 62ac0285bfaf..057e28ef770e 100644 --- a/sound/soc/ux500/ux500_msp_dai.c +++ b/sound/soc/ux500/ux500_msp_dai.c | |||
@@ -21,7 +21,7 @@ | |||
21 | #include <linux/mfd/dbx500-prcmu.h> | 21 | #include <linux/mfd/dbx500-prcmu.h> |
22 | 22 | ||
23 | #include <mach/hardware.h> | 23 | #include <mach/hardware.h> |
24 | #include <mach/board-mop500-msp.h> | 24 | #include <mach/msp.h> |
25 | 25 | ||
26 | #include <sound/soc.h> | 26 | #include <sound/soc.h> |
27 | #include <sound/soc-dai.h> | 27 | #include <sound/soc-dai.h> |
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c index ee14d2dac2f5..5c472f335a64 100644 --- a/sound/soc/ux500/ux500_msp_i2s.c +++ b/sound/soc/ux500/ux500_msp_i2s.c | |||
@@ -19,7 +19,7 @@ | |||
19 | #include <linux/slab.h> | 19 | #include <linux/slab.h> |
20 | 20 | ||
21 | #include <mach/hardware.h> | 21 | #include <mach/hardware.h> |
22 | #include <mach/board-mop500-msp.h> | 22 | #include <mach/msp.h> |
23 | 23 | ||
24 | #include <sound/soc.h> | 24 | #include <sound/soc.h> |
25 | 25 | ||
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h index 7f71b4a0d4bc..2d9136da9865 100644 --- a/sound/soc/ux500/ux500_msp_i2s.h +++ b/sound/soc/ux500/ux500_msp_i2s.h | |||
@@ -17,7 +17,7 @@ | |||
17 | 17 | ||
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | 19 | ||
20 | #include <mach/board-mop500-msp.h> | 20 | #include <mach/msp.h> |
21 | 21 | ||
22 | #define MSP_INPUT_FREQ_APB 48000000 | 22 | #define MSP_INPUT_FREQ_APB 48000000 |
23 | 23 | ||
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index 0f647d22cb4a..c41181202688 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -821,10 +821,6 @@ int snd_usb_endpoint_start(struct snd_usb_endpoint *ep) | |||
821 | if (++ep->use_count != 1) | 821 | if (++ep->use_count != 1) |
822 | return 0; | 822 | return 0; |
823 | 823 | ||
824 | /* just to be sure */ | ||
825 | deactivate_urbs(ep, 0, 1); | ||
826 | wait_clear_urbs(ep); | ||
827 | |||
828 | ep->active_mask = 0; | 824 | ep->active_mask = 0; |
829 | ep->unlink_mask = 0; | 825 | ep->unlink_mask = 0; |
830 | ep->phase = 0; | 826 | ep->phase = 0; |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index a1298f379428..62ec808ed792 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -544,6 +544,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream) | |||
544 | subs->last_frame_number = 0; | 544 | subs->last_frame_number = 0; |
545 | runtime->delay = 0; | 545 | runtime->delay = 0; |
546 | 546 | ||
547 | /* clear the pending deactivation on the target EPs */ | ||
548 | deactivate_endpoints(subs); | ||
549 | |||
547 | /* for playback, submit the URBs now; otherwise, the first hwptr_done | 550 | /* for playback, submit the URBs now; otherwise, the first hwptr_done |
548 | * updates for all URBs would happen at the same time when starting */ | 551 | * updates for all URBs would happen at the same time when starting */ |
549 | if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) | 552 | if (subs->direction == SNDRV_PCM_STREAM_PLAYBACK) |
diff --git a/tools/perf/Makefile b/tools/perf/Makefile index 77f124fe57ad..35655c3a7b7a 100644 --- a/tools/perf/Makefile +++ b/tools/perf/Makefile | |||
@@ -319,6 +319,8 @@ LIB_H += $(ARCH_INCLUDE) | |||
319 | LIB_H += util/cgroup.h | 319 | LIB_H += util/cgroup.h |
320 | LIB_H += $(TRACE_EVENT_DIR)event-parse.h | 320 | LIB_H += $(TRACE_EVENT_DIR)event-parse.h |
321 | LIB_H += util/target.h | 321 | LIB_H += util/target.h |
322 | LIB_H += util/rblist.h | ||
323 | LIB_H += util/intlist.h | ||
322 | 324 | ||
323 | LIB_OBJS += $(OUTPUT)util/abspath.o | 325 | LIB_OBJS += $(OUTPUT)util/abspath.o |
324 | LIB_OBJS += $(OUTPUT)util/alias.o | 326 | LIB_OBJS += $(OUTPUT)util/alias.o |
@@ -383,6 +385,8 @@ LIB_OBJS += $(OUTPUT)util/xyarray.o | |||
383 | LIB_OBJS += $(OUTPUT)util/cpumap.o | 385 | LIB_OBJS += $(OUTPUT)util/cpumap.o |
384 | LIB_OBJS += $(OUTPUT)util/cgroup.o | 386 | LIB_OBJS += $(OUTPUT)util/cgroup.o |
385 | LIB_OBJS += $(OUTPUT)util/target.o | 387 | LIB_OBJS += $(OUTPUT)util/target.o |
388 | LIB_OBJS += $(OUTPUT)util/rblist.o | ||
389 | LIB_OBJS += $(OUTPUT)util/intlist.o | ||
386 | 390 | ||
387 | BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o | 391 | BUILTIN_OBJS += $(OUTPUT)builtin-annotate.o |
388 | 392 | ||
@@ -983,7 +987,8 @@ clean: | |||
983 | $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* | 987 | $(RM) *.spec *.pyc *.pyo */*.pyc */*.pyo $(OUTPUT)common-cmds.h TAGS tags cscope* |
984 | $(MAKE) -C Documentation/ clean | 988 | $(MAKE) -C Documentation/ clean |
985 | $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS | 989 | $(RM) $(OUTPUT)PERF-VERSION-FILE $(OUTPUT)PERF-CFLAGS |
986 | $(RM) $(OUTPUT)util/*-{bison,flex}* | 990 | $(RM) $(OUTPUT)util/*-bison* |
991 | $(RM) $(OUTPUT)util/*-flex* | ||
987 | $(python-clean) | 992 | $(python-clean) |
988 | 993 | ||
989 | .PHONY: all install clean strip $(LIBTRACEEVENT) | 994 | .PHONY: all install clean strip $(LIBTRACEEVENT) |
diff --git a/tools/perf/builtin-record.c b/tools/perf/builtin-record.c index f5a6452931e6..4db6e1ba54e3 100644 --- a/tools/perf/builtin-record.c +++ b/tools/perf/builtin-record.c | |||
@@ -313,7 +313,7 @@ try_again: | |||
313 | } | 313 | } |
314 | } | 314 | } |
315 | 315 | ||
316 | perf_session__update_sample_type(session); | 316 | perf_session__set_id_hdr_size(session); |
317 | } | 317 | } |
318 | 318 | ||
319 | static int process_buildids(struct perf_record *rec) | 319 | static int process_buildids(struct perf_record *rec) |
@@ -844,8 +844,6 @@ int cmd_record(int argc, const char **argv, const char *prefix __used) | |||
844 | struct perf_record *rec = &record; | 844 | struct perf_record *rec = &record; |
845 | char errbuf[BUFSIZ]; | 845 | char errbuf[BUFSIZ]; |
846 | 846 | ||
847 | perf_header__set_cmdline(argc, argv); | ||
848 | |||
849 | evsel_list = perf_evlist__new(NULL, NULL); | 847 | evsel_list = perf_evlist__new(NULL, NULL); |
850 | if (evsel_list == NULL) | 848 | if (evsel_list == NULL) |
851 | return -ENOMEM; | 849 | return -ENOMEM; |
diff --git a/tools/perf/builtin-report.c b/tools/perf/builtin-report.c index 69b1c1185159..7c88a243b5db 100644 --- a/tools/perf/builtin-report.c +++ b/tools/perf/builtin-report.c | |||
@@ -249,8 +249,9 @@ static int process_read_event(struct perf_tool *tool, | |||
249 | static int perf_report__setup_sample_type(struct perf_report *rep) | 249 | static int perf_report__setup_sample_type(struct perf_report *rep) |
250 | { | 250 | { |
251 | struct perf_session *self = rep->session; | 251 | struct perf_session *self = rep->session; |
252 | u64 sample_type = perf_evlist__sample_type(self->evlist); | ||
252 | 253 | ||
253 | if (!self->fd_pipe && !(self->sample_type & PERF_SAMPLE_CALLCHAIN)) { | 254 | if (!self->fd_pipe && !(sample_type & PERF_SAMPLE_CALLCHAIN)) { |
254 | if (sort__has_parent) { | 255 | if (sort__has_parent) { |
255 | ui__error("Selected --sort parent, but no " | 256 | ui__error("Selected --sort parent, but no " |
256 | "callchain data. Did you call " | 257 | "callchain data. Did you call " |
@@ -274,7 +275,7 @@ static int perf_report__setup_sample_type(struct perf_report *rep) | |||
274 | 275 | ||
275 | if (sort__branch_mode == 1) { | 276 | if (sort__branch_mode == 1) { |
276 | if (!self->fd_pipe && | 277 | if (!self->fd_pipe && |
277 | !(self->sample_type & PERF_SAMPLE_BRANCH_STACK)) { | 278 | !(sample_type & PERF_SAMPLE_BRANCH_STACK)) { |
278 | ui__error("Selected -b but no branch data. " | 279 | ui__error("Selected -b but no branch data. " |
279 | "Did you call perf record without -b?\n"); | 280 | "Did you call perf record without -b?\n"); |
280 | return -1; | 281 | return -1; |
diff --git a/tools/perf/builtin-test.c b/tools/perf/builtin-test.c index d909eb74a0eb..1d592f5cbea9 100644 --- a/tools/perf/builtin-test.c +++ b/tools/perf/builtin-test.c | |||
@@ -478,7 +478,6 @@ static int test__basic_mmap(void) | |||
478 | unsigned int nr_events[nsyscalls], | 478 | unsigned int nr_events[nsyscalls], |
479 | expected_nr_events[nsyscalls], i, j; | 479 | expected_nr_events[nsyscalls], i, j; |
480 | struct perf_evsel *evsels[nsyscalls], *evsel; | 480 | struct perf_evsel *evsels[nsyscalls], *evsel; |
481 | int sample_size = __perf_evsel__sample_size(attr.sample_type); | ||
482 | 481 | ||
483 | for (i = 0; i < nsyscalls; ++i) { | 482 | for (i = 0; i < nsyscalls; ++i) { |
484 | char name[64]; | 483 | char name[64]; |
@@ -563,8 +562,7 @@ static int test__basic_mmap(void) | |||
563 | goto out_munmap; | 562 | goto out_munmap; |
564 | } | 563 | } |
565 | 564 | ||
566 | err = perf_event__parse_sample(event, attr.sample_type, sample_size, | 565 | err = perf_evlist__parse_sample(evlist, event, &sample, false); |
567 | false, &sample, false); | ||
568 | if (err) { | 566 | if (err) { |
569 | pr_err("Can't parse sample, err = %d\n", err); | 567 | pr_err("Can't parse sample, err = %d\n", err); |
570 | goto out_munmap; | 568 | goto out_munmap; |
@@ -661,12 +659,12 @@ static int test__PERF_RECORD(void) | |||
661 | const char *cmd = "sleep"; | 659 | const char *cmd = "sleep"; |
662 | const char *argv[] = { cmd, "1", NULL, }; | 660 | const char *argv[] = { cmd, "1", NULL, }; |
663 | char *bname; | 661 | char *bname; |
664 | u64 sample_type, prev_time = 0; | 662 | u64 prev_time = 0; |
665 | bool found_cmd_mmap = false, | 663 | bool found_cmd_mmap = false, |
666 | found_libc_mmap = false, | 664 | found_libc_mmap = false, |
667 | found_vdso_mmap = false, | 665 | found_vdso_mmap = false, |
668 | found_ld_mmap = false; | 666 | found_ld_mmap = false; |
669 | int err = -1, errs = 0, i, wakeups = 0, sample_size; | 667 | int err = -1, errs = 0, i, wakeups = 0; |
670 | u32 cpu; | 668 | u32 cpu; |
671 | int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, }; | 669 | int total_events = 0, nr_events[PERF_RECORD_MAX] = { 0, }; |
672 | 670 | ||
@@ -757,13 +755,6 @@ static int test__PERF_RECORD(void) | |||
757 | } | 755 | } |
758 | 756 | ||
759 | /* | 757 | /* |
760 | * We'll need these two to parse the PERF_SAMPLE_* fields in each | ||
761 | * event. | ||
762 | */ | ||
763 | sample_type = perf_evlist__sample_type(evlist); | ||
764 | sample_size = __perf_evsel__sample_size(sample_type); | ||
765 | |||
766 | /* | ||
767 | * Now that all is properly set up, enable the events, they will | 758 | * Now that all is properly set up, enable the events, they will |
768 | * count just on workload.pid, which will start... | 759 | * count just on workload.pid, which will start... |
769 | */ | 760 | */ |
@@ -788,9 +779,7 @@ static int test__PERF_RECORD(void) | |||
788 | if (type < PERF_RECORD_MAX) | 779 | if (type < PERF_RECORD_MAX) |
789 | nr_events[type]++; | 780 | nr_events[type]++; |
790 | 781 | ||
791 | err = perf_event__parse_sample(event, sample_type, | 782 | err = perf_evlist__parse_sample(evlist, event, &sample, false); |
792 | sample_size, true, | ||
793 | &sample, false); | ||
794 | if (err < 0) { | 783 | if (err < 0) { |
795 | if (verbose) | 784 | if (verbose) |
796 | perf_event__fprintf(event, stderr); | 785 | perf_event__fprintf(event, stderr); |
diff --git a/tools/perf/builtin-top.c b/tools/perf/builtin-top.c index 35e86c6df713..68cd61ef6ac5 100644 --- a/tools/perf/builtin-top.c +++ b/tools/perf/builtin-top.c | |||
@@ -38,6 +38,7 @@ | |||
38 | #include "util/cpumap.h" | 38 | #include "util/cpumap.h" |
39 | #include "util/xyarray.h" | 39 | #include "util/xyarray.h" |
40 | #include "util/sort.h" | 40 | #include "util/sort.h" |
41 | #include "util/intlist.h" | ||
41 | 42 | ||
42 | #include "util/debug.h" | 43 | #include "util/debug.h" |
43 | 44 | ||
@@ -706,8 +707,16 @@ static void perf_event__process_sample(struct perf_tool *tool, | |||
706 | int err; | 707 | int err; |
707 | 708 | ||
708 | if (!machine && perf_guest) { | 709 | if (!machine && perf_guest) { |
709 | pr_err("Can't find guest [%d]'s kernel information\n", | 710 | static struct intlist *seen; |
710 | event->ip.pid); | 711 | |
712 | if (!seen) | ||
713 | seen = intlist__new(); | ||
714 | |||
715 | if (!intlist__has_entry(seen, event->ip.pid)) { | ||
716 | pr_err("Can't find guest [%d]'s kernel information\n", | ||
717 | event->ip.pid); | ||
718 | intlist__add(seen, event->ip.pid); | ||
719 | } | ||
711 | return; | 720 | return; |
712 | } | 721 | } |
713 | 722 | ||
@@ -811,7 +820,7 @@ static void perf_top__mmap_read_idx(struct perf_top *top, int idx) | |||
811 | int ret; | 820 | int ret; |
812 | 821 | ||
813 | while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) { | 822 | while ((event = perf_evlist__mmap_read(top->evlist, idx)) != NULL) { |
814 | ret = perf_session__parse_sample(session, event, &sample); | 823 | ret = perf_evlist__parse_sample(top->evlist, event, &sample, false); |
815 | if (ret) { | 824 | if (ret) { |
816 | pr_err("Can't parse sample, err = %d\n", ret); | 825 | pr_err("Can't parse sample, err = %d\n", ret); |
817 | continue; | 826 | continue; |
@@ -943,8 +952,10 @@ try_again: | |||
943 | * based cpu-clock-tick sw counter, which | 952 | * based cpu-clock-tick sw counter, which |
944 | * is always available even if no PMU support: | 953 | * is always available even if no PMU support: |
945 | */ | 954 | */ |
946 | if (attr->type == PERF_TYPE_HARDWARE && | 955 | if ((err == ENOENT || err == ENXIO) && |
947 | attr->config == PERF_COUNT_HW_CPU_CYCLES) { | 956 | (attr->type == PERF_TYPE_HARDWARE) && |
957 | (attr->config == PERF_COUNT_HW_CPU_CYCLES)) { | ||
958 | |||
948 | if (verbose) | 959 | if (verbose) |
949 | ui__warning("Cycles event not supported,\n" | 960 | ui__warning("Cycles event not supported,\n" |
950 | "trying to fall back to cpu-clock-ticks\n"); | 961 | "trying to fall back to cpu-clock-ticks\n"); |
@@ -1032,7 +1043,7 @@ static int __cmd_top(struct perf_top *top) | |||
1032 | &top->session->host_machine); | 1043 | &top->session->host_machine); |
1033 | perf_top__start_counters(top); | 1044 | perf_top__start_counters(top); |
1034 | top->session->evlist = top->evlist; | 1045 | top->session->evlist = top->evlist; |
1035 | perf_session__update_sample_type(top->session); | 1046 | perf_session__set_id_hdr_size(top->session); |
1036 | 1047 | ||
1037 | /* Wait for a minimal set of events before starting the snapshot */ | 1048 | /* Wait for a minimal set of events before starting the snapshot */ |
1038 | poll(top->evlist->pollfd, top->evlist->nr_fds, 100); | 1049 | poll(top->evlist->pollfd, top->evlist->nr_fds, 100); |
diff --git a/tools/perf/util/event.h b/tools/perf/util/event.h index 1b197280c621..d84870b06426 100644 --- a/tools/perf/util/event.h +++ b/tools/perf/util/event.h | |||
@@ -197,9 +197,6 @@ int perf_event__preprocess_sample(const union perf_event *self, | |||
197 | 197 | ||
198 | const char *perf_event__name(unsigned int id); | 198 | const char *perf_event__name(unsigned int id); |
199 | 199 | ||
200 | int perf_event__parse_sample(const union perf_event *event, u64 type, | ||
201 | int sample_size, bool sample_id_all, | ||
202 | struct perf_sample *sample, bool swapped); | ||
203 | int perf_event__synthesize_sample(union perf_event *event, u64 type, | 200 | int perf_event__synthesize_sample(union perf_event *event, u64 type, |
204 | const struct perf_sample *sample, | 201 | const struct perf_sample *sample, |
205 | bool swapped); | 202 | bool swapped); |
diff --git a/tools/perf/util/evlist.c b/tools/perf/util/evlist.c index 3edfd3483816..9b38681add9e 100644 --- a/tools/perf/util/evlist.c +++ b/tools/perf/util/evlist.c | |||
@@ -881,3 +881,10 @@ int perf_evlist__start_workload(struct perf_evlist *evlist) | |||
881 | 881 | ||
882 | return 0; | 882 | return 0; |
883 | } | 883 | } |
884 | |||
885 | int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event, | ||
886 | struct perf_sample *sample, bool swapped) | ||
887 | { | ||
888 | struct perf_evsel *e = list_entry(evlist->entries.next, struct perf_evsel, node); | ||
889 | return perf_evsel__parse_sample(e, event, sample, swapped); | ||
890 | } | ||
diff --git a/tools/perf/util/evlist.h b/tools/perf/util/evlist.h index 40d4d3cdced0..528c1acd9298 100644 --- a/tools/perf/util/evlist.h +++ b/tools/perf/util/evlist.h | |||
@@ -122,6 +122,9 @@ u64 perf_evlist__sample_type(const struct perf_evlist *evlist); | |||
122 | bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist); | 122 | bool perf_evlist__sample_id_all(const const struct perf_evlist *evlist); |
123 | u16 perf_evlist__id_hdr_size(const struct perf_evlist *evlist); | 123 | u16 perf_evlist__id_hdr_size(const struct perf_evlist *evlist); |
124 | 124 | ||
125 | int perf_evlist__parse_sample(struct perf_evlist *evlist, union perf_event *event, | ||
126 | struct perf_sample *sample, bool swapped); | ||
127 | |||
125 | bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist); | 128 | bool perf_evlist__valid_sample_type(const struct perf_evlist *evlist); |
126 | bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist); | 129 | bool perf_evlist__valid_sample_id_all(const struct perf_evlist *evlist); |
127 | 130 | ||
diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c index e81771364867..2eaae140def2 100644 --- a/tools/perf/util/evsel.c +++ b/tools/perf/util/evsel.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) | 20 | #define FD(e, x, y) (*(int *)xyarray__entry(e->fd, x, y)) |
21 | #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) | 21 | #define GROUP_FD(group_fd, cpu) (*(int *)xyarray__entry(group_fd, cpu, 0)) |
22 | 22 | ||
23 | int __perf_evsel__sample_size(u64 sample_type) | 23 | static int __perf_evsel__sample_size(u64 sample_type) |
24 | { | 24 | { |
25 | u64 mask = sample_type & PERF_SAMPLE_MASK; | 25 | u64 mask = sample_type & PERF_SAMPLE_MASK; |
26 | int size = 0; | 26 | int size = 0; |
@@ -53,6 +53,7 @@ void perf_evsel__init(struct perf_evsel *evsel, | |||
53 | evsel->attr = *attr; | 53 | evsel->attr = *attr; |
54 | INIT_LIST_HEAD(&evsel->node); | 54 | INIT_LIST_HEAD(&evsel->node); |
55 | hists__init(&evsel->hists); | 55 | hists__init(&evsel->hists); |
56 | evsel->sample_size = __perf_evsel__sample_size(attr->sample_type); | ||
56 | } | 57 | } |
57 | 58 | ||
58 | struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx) | 59 | struct perf_evsel *perf_evsel__new(struct perf_event_attr *attr, int idx) |
@@ -728,10 +729,10 @@ static bool sample_overlap(const union perf_event *event, | |||
728 | return false; | 729 | return false; |
729 | } | 730 | } |
730 | 731 | ||
731 | int perf_event__parse_sample(const union perf_event *event, u64 type, | 732 | int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, |
732 | int sample_size, bool sample_id_all, | ||
733 | struct perf_sample *data, bool swapped) | 733 | struct perf_sample *data, bool swapped) |
734 | { | 734 | { |
735 | u64 type = evsel->attr.sample_type; | ||
735 | const u64 *array; | 736 | const u64 *array; |
736 | 737 | ||
737 | /* | 738 | /* |
@@ -746,14 +747,14 @@ int perf_event__parse_sample(const union perf_event *event, u64 type, | |||
746 | data->period = 1; | 747 | data->period = 1; |
747 | 748 | ||
748 | if (event->header.type != PERF_RECORD_SAMPLE) { | 749 | if (event->header.type != PERF_RECORD_SAMPLE) { |
749 | if (!sample_id_all) | 750 | if (!evsel->attr.sample_id_all) |
750 | return 0; | 751 | return 0; |
751 | return perf_event__parse_id_sample(event, type, data, swapped); | 752 | return perf_event__parse_id_sample(event, type, data, swapped); |
752 | } | 753 | } |
753 | 754 | ||
754 | array = event->sample.array; | 755 | array = event->sample.array; |
755 | 756 | ||
756 | if (sample_size + sizeof(event->header) > event->header.size) | 757 | if (evsel->sample_size + sizeof(event->header) > event->header.size) |
757 | return -EFAULT; | 758 | return -EFAULT; |
758 | 759 | ||
759 | if (type & PERF_SAMPLE_IP) { | 760 | if (type & PERF_SAMPLE_IP) { |
@@ -895,7 +896,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, | |||
895 | u.val32[1] = sample->tid; | 896 | u.val32[1] = sample->tid; |
896 | if (swapped) { | 897 | if (swapped) { |
897 | /* | 898 | /* |
898 | * Inverse of what is done in perf_event__parse_sample | 899 | * Inverse of what is done in perf_evsel__parse_sample |
899 | */ | 900 | */ |
900 | u.val32[0] = bswap_32(u.val32[0]); | 901 | u.val32[0] = bswap_32(u.val32[0]); |
901 | u.val32[1] = bswap_32(u.val32[1]); | 902 | u.val32[1] = bswap_32(u.val32[1]); |
@@ -930,7 +931,7 @@ int perf_event__synthesize_sample(union perf_event *event, u64 type, | |||
930 | u.val32[0] = sample->cpu; | 931 | u.val32[0] = sample->cpu; |
931 | if (swapped) { | 932 | if (swapped) { |
932 | /* | 933 | /* |
933 | * Inverse of what is done in perf_event__parse_sample | 934 | * Inverse of what is done in perf_evsel__parse_sample |
934 | */ | 935 | */ |
935 | u.val32[0] = bswap_32(u.val32[0]); | 936 | u.val32[0] = bswap_32(u.val32[0]); |
936 | u.val64 = bswap_64(u.val64); | 937 | u.val64 = bswap_64(u.val64); |
diff --git a/tools/perf/util/evsel.h b/tools/perf/util/evsel.h index 67cc5033d192..b559929983bb 100644 --- a/tools/perf/util/evsel.h +++ b/tools/perf/util/evsel.h | |||
@@ -65,6 +65,7 @@ struct perf_evsel { | |||
65 | void *func; | 65 | void *func; |
66 | void *data; | 66 | void *data; |
67 | } handler; | 67 | } handler; |
68 | unsigned int sample_size; | ||
68 | bool supported; | 69 | bool supported; |
69 | }; | 70 | }; |
70 | 71 | ||
@@ -177,13 +178,8 @@ static inline int perf_evsel__read_scaled(struct perf_evsel *evsel, | |||
177 | return __perf_evsel__read(evsel, ncpus, nthreads, true); | 178 | return __perf_evsel__read(evsel, ncpus, nthreads, true); |
178 | } | 179 | } |
179 | 180 | ||
180 | int __perf_evsel__sample_size(u64 sample_type); | ||
181 | |||
182 | static inline int perf_evsel__sample_size(struct perf_evsel *evsel) | ||
183 | { | ||
184 | return __perf_evsel__sample_size(evsel->attr.sample_type); | ||
185 | } | ||
186 | |||
187 | void hists__init(struct hists *hists); | 181 | void hists__init(struct hists *hists); |
188 | 182 | ||
183 | int perf_evsel__parse_sample(struct perf_evsel *evsel, union perf_event *event, | ||
184 | struct perf_sample *sample, bool swapped); | ||
189 | #endif /* __PERF_EVSEL_H */ | 185 | #endif /* __PERF_EVSEL_H */ |
diff --git a/tools/perf/util/header.c b/tools/perf/util/header.c index 3a6d20443330..74ea3c2f8138 100644 --- a/tools/perf/util/header.c +++ b/tools/perf/util/header.c | |||
@@ -174,6 +174,15 @@ perf_header__set_cmdline(int argc, const char **argv) | |||
174 | { | 174 | { |
175 | int i; | 175 | int i; |
176 | 176 | ||
177 | /* | ||
178 | * If header_argv has already been set, do not override it. | ||
179 | * This allows a command to set the cmdline, parse args and | ||
180 | * then call another builtin function that implements a | ||
181 | * command -- e.g, cmd_kvm calling cmd_record. | ||
182 | */ | ||
183 | if (header_argv) | ||
184 | return 0; | ||
185 | |||
177 | header_argc = (u32)argc; | 186 | header_argc = (u32)argc; |
178 | 187 | ||
179 | /* do not include NULL termination */ | 188 | /* do not include NULL termination */ |
diff --git a/tools/perf/util/intlist.c b/tools/perf/util/intlist.c new file mode 100644 index 000000000000..fd530dced9cb --- /dev/null +++ b/tools/perf/util/intlist.c | |||
@@ -0,0 +1,101 @@ | |||
1 | /* | ||
2 | * Based on intlist.c by: | ||
3 | * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com> | ||
4 | * | ||
5 | * Licensed under the GPLv2. | ||
6 | */ | ||
7 | |||
8 | #include <errno.h> | ||
9 | #include <stdlib.h> | ||
10 | #include <linux/compiler.h> | ||
11 | |||
12 | #include "intlist.h" | ||
13 | |||
14 | static struct rb_node *intlist__node_new(struct rblist *rblist __used, | ||
15 | const void *entry) | ||
16 | { | ||
17 | int i = (int)((long)entry); | ||
18 | struct rb_node *rc = NULL; | ||
19 | struct int_node *node = malloc(sizeof(*node)); | ||
20 | |||
21 | if (node != NULL) { | ||
22 | node->i = i; | ||
23 | rc = &node->rb_node; | ||
24 | } | ||
25 | |||
26 | return rc; | ||
27 | } | ||
28 | |||
29 | static void int_node__delete(struct int_node *ilist) | ||
30 | { | ||
31 | free(ilist); | ||
32 | } | ||
33 | |||
34 | static void intlist__node_delete(struct rblist *rblist __used, | ||
35 | struct rb_node *rb_node) | ||
36 | { | ||
37 | struct int_node *node = container_of(rb_node, struct int_node, rb_node); | ||
38 | |||
39 | int_node__delete(node); | ||
40 | } | ||
41 | |||
42 | static int intlist__node_cmp(struct rb_node *rb_node, const void *entry) | ||
43 | { | ||
44 | int i = (int)((long)entry); | ||
45 | struct int_node *node = container_of(rb_node, struct int_node, rb_node); | ||
46 | |||
47 | return node->i - i; | ||
48 | } | ||
49 | |||
50 | int intlist__add(struct intlist *ilist, int i) | ||
51 | { | ||
52 | return rblist__add_node(&ilist->rblist, (void *)((long)i)); | ||
53 | } | ||
54 | |||
55 | void intlist__remove(struct intlist *ilist __used, struct int_node *node) | ||
56 | { | ||
57 | int_node__delete(node); | ||
58 | } | ||
59 | |||
60 | struct int_node *intlist__find(struct intlist *ilist, int i) | ||
61 | { | ||
62 | struct int_node *node = NULL; | ||
63 | struct rb_node *rb_node = rblist__find(&ilist->rblist, (void *)((long)i)); | ||
64 | |||
65 | if (rb_node) | ||
66 | node = container_of(rb_node, struct int_node, rb_node); | ||
67 | |||
68 | return node; | ||
69 | } | ||
70 | |||
71 | struct intlist *intlist__new(void) | ||
72 | { | ||
73 | struct intlist *ilist = malloc(sizeof(*ilist)); | ||
74 | |||
75 | if (ilist != NULL) { | ||
76 | rblist__init(&ilist->rblist); | ||
77 | ilist->rblist.node_cmp = intlist__node_cmp; | ||
78 | ilist->rblist.node_new = intlist__node_new; | ||
79 | ilist->rblist.node_delete = intlist__node_delete; | ||
80 | } | ||
81 | |||
82 | return ilist; | ||
83 | } | ||
84 | |||
85 | void intlist__delete(struct intlist *ilist) | ||
86 | { | ||
87 | if (ilist != NULL) | ||
88 | rblist__delete(&ilist->rblist); | ||
89 | } | ||
90 | |||
91 | struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx) | ||
92 | { | ||
93 | struct int_node *node = NULL; | ||
94 | struct rb_node *rb_node; | ||
95 | |||
96 | rb_node = rblist__entry(&ilist->rblist, idx); | ||
97 | if (rb_node) | ||
98 | node = container_of(rb_node, struct int_node, rb_node); | ||
99 | |||
100 | return node; | ||
101 | } | ||
diff --git a/tools/perf/util/intlist.h b/tools/perf/util/intlist.h new file mode 100644 index 000000000000..6d63ab90db50 --- /dev/null +++ b/tools/perf/util/intlist.h | |||
@@ -0,0 +1,75 @@ | |||
1 | #ifndef __PERF_INTLIST_H | ||
2 | #define __PERF_INTLIST_H | ||
3 | |||
4 | #include <linux/rbtree.h> | ||
5 | #include <stdbool.h> | ||
6 | |||
7 | #include "rblist.h" | ||
8 | |||
9 | struct int_node { | ||
10 | struct rb_node rb_node; | ||
11 | int i; | ||
12 | }; | ||
13 | |||
14 | struct intlist { | ||
15 | struct rblist rblist; | ||
16 | }; | ||
17 | |||
18 | struct intlist *intlist__new(void); | ||
19 | void intlist__delete(struct intlist *ilist); | ||
20 | |||
21 | void intlist__remove(struct intlist *ilist, struct int_node *in); | ||
22 | int intlist__add(struct intlist *ilist, int i); | ||
23 | |||
24 | struct int_node *intlist__entry(const struct intlist *ilist, unsigned int idx); | ||
25 | struct int_node *intlist__find(struct intlist *ilist, int i); | ||
26 | |||
27 | static inline bool intlist__has_entry(struct intlist *ilist, int i) | ||
28 | { | ||
29 | return intlist__find(ilist, i) != NULL; | ||
30 | } | ||
31 | |||
32 | static inline bool intlist__empty(const struct intlist *ilist) | ||
33 | { | ||
34 | return rblist__empty(&ilist->rblist); | ||
35 | } | ||
36 | |||
37 | static inline unsigned int intlist__nr_entries(const struct intlist *ilist) | ||
38 | { | ||
39 | return rblist__nr_entries(&ilist->rblist); | ||
40 | } | ||
41 | |||
42 | /* For intlist iteration */ | ||
43 | static inline struct int_node *intlist__first(struct intlist *ilist) | ||
44 | { | ||
45 | struct rb_node *rn = rb_first(&ilist->rblist.entries); | ||
46 | return rn ? rb_entry(rn, struct int_node, rb_node) : NULL; | ||
47 | } | ||
48 | static inline struct int_node *intlist__next(struct int_node *in) | ||
49 | { | ||
50 | struct rb_node *rn; | ||
51 | if (!in) | ||
52 | return NULL; | ||
53 | rn = rb_next(&in->rb_node); | ||
54 | return rn ? rb_entry(rn, struct int_node, rb_node) : NULL; | ||
55 | } | ||
56 | |||
57 | /** | ||
58 | * intlist_for_each - iterate over a intlist | ||
59 | * @pos: the &struct int_node to use as a loop cursor. | ||
60 | * @ilist: the &struct intlist for loop. | ||
61 | */ | ||
62 | #define intlist__for_each(pos, ilist) \ | ||
63 | for (pos = intlist__first(ilist); pos; pos = intlist__next(pos)) | ||
64 | |||
65 | /** | ||
66 | * intlist_for_each_safe - iterate over a intlist safe against removal of | ||
67 | * int_node | ||
68 | * @pos: the &struct int_node to use as a loop cursor. | ||
69 | * @n: another &struct int_node to use as temporary storage. | ||
70 | * @ilist: the &struct intlist for loop. | ||
71 | */ | ||
72 | #define intlist__for_each_safe(pos, n, ilist) \ | ||
73 | for (pos = intlist__first(ilist), n = intlist__next(pos); pos;\ | ||
74 | pos = n, n = intlist__next(n)) | ||
75 | #endif /* __PERF_INTLIST_H */ | ||
diff --git a/tools/perf/util/parse-events-test.c b/tools/perf/util/parse-events-test.c index 1b997d2b89ce..127d648cc548 100644 --- a/tools/perf/util/parse-events-test.c +++ b/tools/perf/util/parse-events-test.c | |||
@@ -13,6 +13,9 @@ do { \ | |||
13 | } \ | 13 | } \ |
14 | } while (0) | 14 | } while (0) |
15 | 15 | ||
16 | #define PERF_TP_SAMPLE_TYPE (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | \ | ||
17 | PERF_SAMPLE_CPU | PERF_SAMPLE_PERIOD) | ||
18 | |||
16 | static int test__checkevent_tracepoint(struct perf_evlist *evlist) | 19 | static int test__checkevent_tracepoint(struct perf_evlist *evlist) |
17 | { | 20 | { |
18 | struct perf_evsel *evsel = list_entry(evlist->entries.next, | 21 | struct perf_evsel *evsel = list_entry(evlist->entries.next, |
@@ -21,8 +24,7 @@ static int test__checkevent_tracepoint(struct perf_evlist *evlist) | |||
21 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); | 24 | TEST_ASSERT_VAL("wrong number of entries", 1 == evlist->nr_entries); |
22 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); | 25 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); |
23 | TEST_ASSERT_VAL("wrong sample_type", | 26 | TEST_ASSERT_VAL("wrong sample_type", |
24 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == | 27 | PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); |
25 | evsel->attr.sample_type); | ||
26 | TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); | 28 | TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); |
27 | return 0; | 29 | return 0; |
28 | } | 30 | } |
@@ -37,8 +39,7 @@ static int test__checkevent_tracepoint_multi(struct perf_evlist *evlist) | |||
37 | TEST_ASSERT_VAL("wrong type", | 39 | TEST_ASSERT_VAL("wrong type", |
38 | PERF_TYPE_TRACEPOINT == evsel->attr.type); | 40 | PERF_TYPE_TRACEPOINT == evsel->attr.type); |
39 | TEST_ASSERT_VAL("wrong sample_type", | 41 | TEST_ASSERT_VAL("wrong sample_type", |
40 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) | 42 | PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); |
41 | == evsel->attr.sample_type); | ||
42 | TEST_ASSERT_VAL("wrong sample_period", | 43 | TEST_ASSERT_VAL("wrong sample_period", |
43 | 1 == evsel->attr.sample_period); | 44 | 1 == evsel->attr.sample_period); |
44 | } | 45 | } |
@@ -428,8 +429,7 @@ static int test__checkevent_list(struct perf_evlist *evlist) | |||
428 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); | 429 | evsel = list_entry(evsel->node.next, struct perf_evsel, node); |
429 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); | 430 | TEST_ASSERT_VAL("wrong type", PERF_TYPE_TRACEPOINT == evsel->attr.type); |
430 | TEST_ASSERT_VAL("wrong sample_type", | 431 | TEST_ASSERT_VAL("wrong sample_type", |
431 | (PERF_SAMPLE_RAW | PERF_SAMPLE_TIME | PERF_SAMPLE_CPU) == | 432 | PERF_TP_SAMPLE_TYPE == evsel->attr.sample_type); |
432 | evsel->attr.sample_type); | ||
433 | TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); | 433 | TEST_ASSERT_VAL("wrong sample_period", 1 == evsel->attr.sample_period); |
434 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); | 434 | TEST_ASSERT_VAL("wrong exclude_user", evsel->attr.exclude_user); |
435 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); | 435 | TEST_ASSERT_VAL("wrong exclude_kernel", !evsel->attr.exclude_kernel); |
diff --git a/tools/perf/util/parse-options.c b/tools/perf/util/parse-options.c index 99d02aa57dbf..594f8fad5ecd 100644 --- a/tools/perf/util/parse-options.c +++ b/tools/perf/util/parse-options.c | |||
@@ -1,6 +1,7 @@ | |||
1 | #include "util.h" | 1 | #include "util.h" |
2 | #include "parse-options.h" | 2 | #include "parse-options.h" |
3 | #include "cache.h" | 3 | #include "cache.h" |
4 | #include "header.h" | ||
4 | 5 | ||
5 | #define OPT_SHORT 1 | 6 | #define OPT_SHORT 1 |
6 | #define OPT_UNSET 2 | 7 | #define OPT_UNSET 2 |
@@ -413,6 +414,8 @@ int parse_options(int argc, const char **argv, const struct option *options, | |||
413 | { | 414 | { |
414 | struct parse_opt_ctx_t ctx; | 415 | struct parse_opt_ctx_t ctx; |
415 | 416 | ||
417 | perf_header__set_cmdline(argc, argv); | ||
418 | |||
416 | parse_options_start(&ctx, argc, argv, flags); | 419 | parse_options_start(&ctx, argc, argv, flags); |
417 | switch (parse_options_step(&ctx, options, usagestr)) { | 420 | switch (parse_options_step(&ctx, options, usagestr)) { |
418 | case PARSE_OPT_HELP: | 421 | case PARSE_OPT_HELP: |
diff --git a/tools/perf/util/python.c b/tools/perf/util/python.c index e03b58a48424..0688bfb6d280 100644 --- a/tools/perf/util/python.c +++ b/tools/perf/util/python.c | |||
@@ -797,17 +797,13 @@ static PyObject *pyrf_evlist__read_on_cpu(struct pyrf_evlist *pevlist, | |||
797 | 797 | ||
798 | event = perf_evlist__mmap_read(evlist, cpu); | 798 | event = perf_evlist__mmap_read(evlist, cpu); |
799 | if (event != NULL) { | 799 | if (event != NULL) { |
800 | struct perf_evsel *first; | ||
801 | PyObject *pyevent = pyrf_event__new(event); | 800 | PyObject *pyevent = pyrf_event__new(event); |
802 | struct pyrf_event *pevent = (struct pyrf_event *)pyevent; | 801 | struct pyrf_event *pevent = (struct pyrf_event *)pyevent; |
803 | 802 | ||
804 | if (pyevent == NULL) | 803 | if (pyevent == NULL) |
805 | return PyErr_NoMemory(); | 804 | return PyErr_NoMemory(); |
806 | 805 | ||
807 | first = list_entry(evlist->entries.next, struct perf_evsel, node); | 806 | err = perf_evlist__parse_sample(evlist, event, &pevent->sample, false); |
808 | err = perf_event__parse_sample(event, first->attr.sample_type, | ||
809 | perf_evsel__sample_size(first), | ||
810 | sample_id_all, &pevent->sample, false); | ||
811 | if (err) | 807 | if (err) |
812 | return PyErr_Format(PyExc_OSError, | 808 | return PyErr_Format(PyExc_OSError, |
813 | "perf: can't parse sample, err=%d", err); | 809 | "perf: can't parse sample, err=%d", err); |
diff --git a/tools/perf/util/rblist.c b/tools/perf/util/rblist.c new file mode 100644 index 000000000000..0171fb611004 --- /dev/null +++ b/tools/perf/util/rblist.c | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * Based on strlist.c by: | ||
3 | * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com> | ||
4 | * | ||
5 | * Licensed under the GPLv2. | ||
6 | */ | ||
7 | |||
8 | #include <errno.h> | ||
9 | #include <stdio.h> | ||
10 | #include <stdlib.h> | ||
11 | |||
12 | #include "rblist.h" | ||
13 | |||
14 | int rblist__add_node(struct rblist *rblist, const void *new_entry) | ||
15 | { | ||
16 | struct rb_node **p = &rblist->entries.rb_node; | ||
17 | struct rb_node *parent = NULL, *new_node; | ||
18 | |||
19 | while (*p != NULL) { | ||
20 | int rc; | ||
21 | |||
22 | parent = *p; | ||
23 | |||
24 | rc = rblist->node_cmp(parent, new_entry); | ||
25 | if (rc > 0) | ||
26 | p = &(*p)->rb_left; | ||
27 | else if (rc < 0) | ||
28 | p = &(*p)->rb_right; | ||
29 | else | ||
30 | return -EEXIST; | ||
31 | } | ||
32 | |||
33 | new_node = rblist->node_new(rblist, new_entry); | ||
34 | if (new_node == NULL) | ||
35 | return -ENOMEM; | ||
36 | |||
37 | rb_link_node(new_node, parent, p); | ||
38 | rb_insert_color(new_node, &rblist->entries); | ||
39 | ++rblist->nr_entries; | ||
40 | |||
41 | return 0; | ||
42 | } | ||
43 | |||
44 | void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node) | ||
45 | { | ||
46 | rb_erase(rb_node, &rblist->entries); | ||
47 | rblist->node_delete(rblist, rb_node); | ||
48 | } | ||
49 | |||
50 | struct rb_node *rblist__find(struct rblist *rblist, const void *entry) | ||
51 | { | ||
52 | struct rb_node **p = &rblist->entries.rb_node; | ||
53 | struct rb_node *parent = NULL; | ||
54 | |||
55 | while (*p != NULL) { | ||
56 | int rc; | ||
57 | |||
58 | parent = *p; | ||
59 | |||
60 | rc = rblist->node_cmp(parent, entry); | ||
61 | if (rc > 0) | ||
62 | p = &(*p)->rb_left; | ||
63 | else if (rc < 0) | ||
64 | p = &(*p)->rb_right; | ||
65 | else | ||
66 | return parent; | ||
67 | } | ||
68 | |||
69 | return NULL; | ||
70 | } | ||
71 | |||
72 | void rblist__init(struct rblist *rblist) | ||
73 | { | ||
74 | if (rblist != NULL) { | ||
75 | rblist->entries = RB_ROOT; | ||
76 | rblist->nr_entries = 0; | ||
77 | } | ||
78 | |||
79 | return; | ||
80 | } | ||
81 | |||
82 | void rblist__delete(struct rblist *rblist) | ||
83 | { | ||
84 | if (rblist != NULL) { | ||
85 | struct rb_node *pos, *next = rb_first(&rblist->entries); | ||
86 | |||
87 | while (next) { | ||
88 | pos = next; | ||
89 | next = rb_next(pos); | ||
90 | rb_erase(pos, &rblist->entries); | ||
91 | rblist->node_delete(rblist, pos); | ||
92 | } | ||
93 | free(rblist); | ||
94 | } | ||
95 | } | ||
96 | |||
97 | struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx) | ||
98 | { | ||
99 | struct rb_node *node; | ||
100 | |||
101 | for (node = rb_first(&rblist->entries); node; node = rb_next(node)) { | ||
102 | if (!idx--) | ||
103 | return node; | ||
104 | } | ||
105 | |||
106 | return NULL; | ||
107 | } | ||
diff --git a/tools/perf/util/rblist.h b/tools/perf/util/rblist.h new file mode 100644 index 000000000000..6d0cae5ae83d --- /dev/null +++ b/tools/perf/util/rblist.h | |||
@@ -0,0 +1,47 @@ | |||
1 | #ifndef __PERF_RBLIST_H | ||
2 | #define __PERF_RBLIST_H | ||
3 | |||
4 | #include <linux/rbtree.h> | ||
5 | #include <stdbool.h> | ||
6 | |||
7 | /* | ||
8 | * create node structs of the form: | ||
9 | * struct my_node { | ||
10 | * struct rb_node rb_node; | ||
11 | * ... my data ... | ||
12 | * }; | ||
13 | * | ||
14 | * create list structs of the form: | ||
15 | * struct mylist { | ||
16 | * struct rblist rblist; | ||
17 | * ... my data ... | ||
18 | * }; | ||
19 | */ | ||
20 | |||
21 | struct rblist { | ||
22 | struct rb_root entries; | ||
23 | unsigned int nr_entries; | ||
24 | |||
25 | int (*node_cmp)(struct rb_node *rbn, const void *entry); | ||
26 | struct rb_node *(*node_new)(struct rblist *rlist, const void *new_entry); | ||
27 | void (*node_delete)(struct rblist *rblist, struct rb_node *rb_node); | ||
28 | }; | ||
29 | |||
30 | void rblist__init(struct rblist *rblist); | ||
31 | void rblist__delete(struct rblist *rblist); | ||
32 | int rblist__add_node(struct rblist *rblist, const void *new_entry); | ||
33 | void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node); | ||
34 | struct rb_node *rblist__find(struct rblist *rblist, const void *entry); | ||
35 | struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx); | ||
36 | |||
37 | static inline bool rblist__empty(const struct rblist *rblist) | ||
38 | { | ||
39 | return rblist->nr_entries == 0; | ||
40 | } | ||
41 | |||
42 | static inline unsigned int rblist__nr_entries(const struct rblist *rblist) | ||
43 | { | ||
44 | return rblist->nr_entries; | ||
45 | } | ||
46 | |||
47 | #endif /* __PERF_RBLIST_H */ | ||
diff --git a/tools/perf/util/session.c b/tools/perf/util/session.c index 8e4f0755d2aa..2437fb0b463a 100644 --- a/tools/perf/util/session.c +++ b/tools/perf/util/session.c | |||
@@ -80,14 +80,12 @@ out_close: | |||
80 | return -1; | 80 | return -1; |
81 | } | 81 | } |
82 | 82 | ||
83 | void perf_session__update_sample_type(struct perf_session *self) | 83 | void perf_session__set_id_hdr_size(struct perf_session *session) |
84 | { | 84 | { |
85 | self->sample_type = perf_evlist__sample_type(self->evlist); | 85 | u16 id_hdr_size = perf_evlist__id_hdr_size(session->evlist); |
86 | self->sample_size = __perf_evsel__sample_size(self->sample_type); | 86 | |
87 | self->sample_id_all = perf_evlist__sample_id_all(self->evlist); | 87 | session->host_machine.id_hdr_size = id_hdr_size; |
88 | self->id_hdr_size = perf_evlist__id_hdr_size(self->evlist); | 88 | machines__set_id_hdr_size(&session->machines, id_hdr_size); |
89 | self->host_machine.id_hdr_size = self->id_hdr_size; | ||
90 | machines__set_id_hdr_size(&self->machines, self->id_hdr_size); | ||
91 | } | 89 | } |
92 | 90 | ||
93 | int perf_session__create_kernel_maps(struct perf_session *self) | 91 | int perf_session__create_kernel_maps(struct perf_session *self) |
@@ -147,7 +145,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, | |||
147 | if (mode == O_RDONLY) { | 145 | if (mode == O_RDONLY) { |
148 | if (perf_session__open(self, force) < 0) | 146 | if (perf_session__open(self, force) < 0) |
149 | goto out_delete; | 147 | goto out_delete; |
150 | perf_session__update_sample_type(self); | 148 | perf_session__set_id_hdr_size(self); |
151 | } else if (mode == O_WRONLY) { | 149 | } else if (mode == O_WRONLY) { |
152 | /* | 150 | /* |
153 | * In O_RDONLY mode this will be performed when reading the | 151 | * In O_RDONLY mode this will be performed when reading the |
@@ -158,7 +156,7 @@ struct perf_session *perf_session__new(const char *filename, int mode, | |||
158 | } | 156 | } |
159 | 157 | ||
160 | if (tool && tool->ordering_requires_timestamps && | 158 | if (tool && tool->ordering_requires_timestamps && |
161 | tool->ordered_samples && !self->sample_id_all) { | 159 | tool->ordered_samples && !perf_evlist__sample_id_all(self->evlist)) { |
162 | dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); | 160 | dump_printf("WARNING: No sample_id_all support, falling back to unordered processing\n"); |
163 | tool->ordered_samples = false; | 161 | tool->ordered_samples = false; |
164 | } | 162 | } |
@@ -673,7 +671,8 @@ static void flush_sample_queue(struct perf_session *s, | |||
673 | if (iter->timestamp > limit) | 671 | if (iter->timestamp > limit) |
674 | break; | 672 | break; |
675 | 673 | ||
676 | ret = perf_session__parse_sample(s, iter->event, &sample); | 674 | ret = perf_evlist__parse_sample(s->evlist, iter->event, &sample, |
675 | s->header.needs_swap); | ||
677 | if (ret) | 676 | if (ret) |
678 | pr_err("Can't parse sample, err = %d\n", ret); | 677 | pr_err("Can't parse sample, err = %d\n", ret); |
679 | else | 678 | else |
@@ -865,16 +864,18 @@ static void perf_session__print_tstamp(struct perf_session *session, | |||
865 | union perf_event *event, | 864 | union perf_event *event, |
866 | struct perf_sample *sample) | 865 | struct perf_sample *sample) |
867 | { | 866 | { |
867 | u64 sample_type = perf_evlist__sample_type(session->evlist); | ||
868 | |||
868 | if (event->header.type != PERF_RECORD_SAMPLE && | 869 | if (event->header.type != PERF_RECORD_SAMPLE && |
869 | !session->sample_id_all) { | 870 | !perf_evlist__sample_id_all(session->evlist)) { |
870 | fputs("-1 -1 ", stdout); | 871 | fputs("-1 -1 ", stdout); |
871 | return; | 872 | return; |
872 | } | 873 | } |
873 | 874 | ||
874 | if ((session->sample_type & PERF_SAMPLE_CPU)) | 875 | if ((sample_type & PERF_SAMPLE_CPU)) |
875 | printf("%u ", sample->cpu); | 876 | printf("%u ", sample->cpu); |
876 | 877 | ||
877 | if (session->sample_type & PERF_SAMPLE_TIME) | 878 | if (sample_type & PERF_SAMPLE_TIME) |
878 | printf("%" PRIu64 " ", sample->time); | 879 | printf("%" PRIu64 " ", sample->time); |
879 | } | 880 | } |
880 | 881 | ||
@@ -899,6 +900,8 @@ static void dump_event(struct perf_session *session, union perf_event *event, | |||
899 | static void dump_sample(struct perf_session *session, union perf_event *event, | 900 | static void dump_sample(struct perf_session *session, union perf_event *event, |
900 | struct perf_sample *sample) | 901 | struct perf_sample *sample) |
901 | { | 902 | { |
903 | u64 sample_type; | ||
904 | |||
902 | if (!dump_trace) | 905 | if (!dump_trace) |
903 | return; | 906 | return; |
904 | 907 | ||
@@ -906,10 +909,12 @@ static void dump_sample(struct perf_session *session, union perf_event *event, | |||
906 | event->header.misc, sample->pid, sample->tid, sample->ip, | 909 | event->header.misc, sample->pid, sample->tid, sample->ip, |
907 | sample->period, sample->addr); | 910 | sample->period, sample->addr); |
908 | 911 | ||
909 | if (session->sample_type & PERF_SAMPLE_CALLCHAIN) | 912 | sample_type = perf_evlist__sample_type(session->evlist); |
913 | |||
914 | if (sample_type & PERF_SAMPLE_CALLCHAIN) | ||
910 | callchain__printf(sample); | 915 | callchain__printf(sample); |
911 | 916 | ||
912 | if (session->sample_type & PERF_SAMPLE_BRANCH_STACK) | 917 | if (sample_type & PERF_SAMPLE_BRANCH_STACK) |
913 | branch_stack__printf(sample); | 918 | branch_stack__printf(sample); |
914 | } | 919 | } |
915 | 920 | ||
@@ -1006,7 +1011,7 @@ static int perf_session__preprocess_sample(struct perf_session *session, | |||
1006 | union perf_event *event, struct perf_sample *sample) | 1011 | union perf_event *event, struct perf_sample *sample) |
1007 | { | 1012 | { |
1008 | if (event->header.type != PERF_RECORD_SAMPLE || | 1013 | if (event->header.type != PERF_RECORD_SAMPLE || |
1009 | !(session->sample_type & PERF_SAMPLE_CALLCHAIN)) | 1014 | !(perf_evlist__sample_type(session->evlist) & PERF_SAMPLE_CALLCHAIN)) |
1010 | return 0; | 1015 | return 0; |
1011 | 1016 | ||
1012 | if (!ip_callchain__valid(sample->callchain, event)) { | 1017 | if (!ip_callchain__valid(sample->callchain, event)) { |
@@ -1030,7 +1035,7 @@ static int perf_session__process_user_event(struct perf_session *session, union | |||
1030 | case PERF_RECORD_HEADER_ATTR: | 1035 | case PERF_RECORD_HEADER_ATTR: |
1031 | err = tool->attr(event, &session->evlist); | 1036 | err = tool->attr(event, &session->evlist); |
1032 | if (err == 0) | 1037 | if (err == 0) |
1033 | perf_session__update_sample_type(session); | 1038 | perf_session__set_id_hdr_size(session); |
1034 | return err; | 1039 | return err; |
1035 | case PERF_RECORD_HEADER_EVENT_TYPE: | 1040 | case PERF_RECORD_HEADER_EVENT_TYPE: |
1036 | return tool->event_type(tool, event); | 1041 | return tool->event_type(tool, event); |
@@ -1065,7 +1070,7 @@ static int perf_session__process_event(struct perf_session *session, | |||
1065 | int ret; | 1070 | int ret; |
1066 | 1071 | ||
1067 | if (session->header.needs_swap) | 1072 | if (session->header.needs_swap) |
1068 | event_swap(event, session->sample_id_all); | 1073 | event_swap(event, perf_evlist__sample_id_all(session->evlist)); |
1069 | 1074 | ||
1070 | if (event->header.type >= PERF_RECORD_HEADER_MAX) | 1075 | if (event->header.type >= PERF_RECORD_HEADER_MAX) |
1071 | return -EINVAL; | 1076 | return -EINVAL; |
@@ -1078,7 +1083,8 @@ static int perf_session__process_event(struct perf_session *session, | |||
1078 | /* | 1083 | /* |
1079 | * For all kernel events we get the sample data | 1084 | * For all kernel events we get the sample data |
1080 | */ | 1085 | */ |
1081 | ret = perf_session__parse_sample(session, event, &sample); | 1086 | ret = perf_evlist__parse_sample(session->evlist, event, &sample, |
1087 | session->header.needs_swap); | ||
1082 | if (ret) | 1088 | if (ret) |
1083 | return ret; | 1089 | return ret; |
1084 | 1090 | ||
@@ -1389,9 +1395,9 @@ int perf_session__process_events(struct perf_session *self, | |||
1389 | return err; | 1395 | return err; |
1390 | } | 1396 | } |
1391 | 1397 | ||
1392 | bool perf_session__has_traces(struct perf_session *self, const char *msg) | 1398 | bool perf_session__has_traces(struct perf_session *session, const char *msg) |
1393 | { | 1399 | { |
1394 | if (!(self->sample_type & PERF_SAMPLE_RAW)) { | 1400 | if (!(perf_evlist__sample_type(session->evlist) & PERF_SAMPLE_RAW)) { |
1395 | pr_err("No trace sample to read. Did you call 'perf %s'?\n", msg); | 1401 | pr_err("No trace sample to read. Did you call 'perf %s'?\n", msg); |
1396 | return false; | 1402 | return false; |
1397 | } | 1403 | } |
diff --git a/tools/perf/util/session.h b/tools/perf/util/session.h index 7c435bde6eb0..1f7ec87db7d7 100644 --- a/tools/perf/util/session.h +++ b/tools/perf/util/session.h | |||
@@ -41,13 +41,9 @@ struct perf_session { | |||
41 | * perf.data file. | 41 | * perf.data file. |
42 | */ | 42 | */ |
43 | struct hists hists; | 43 | struct hists hists; |
44 | u64 sample_type; | ||
45 | int sample_size; | ||
46 | int fd; | 44 | int fd; |
47 | bool fd_pipe; | 45 | bool fd_pipe; |
48 | bool repipe; | 46 | bool repipe; |
49 | bool sample_id_all; | ||
50 | u16 id_hdr_size; | ||
51 | int cwdlen; | 47 | int cwdlen; |
52 | char *cwd; | 48 | char *cwd; |
53 | struct ordered_samples ordered_samples; | 49 | struct ordered_samples ordered_samples; |
@@ -86,7 +82,7 @@ void perf_event__attr_swap(struct perf_event_attr *attr); | |||
86 | 82 | ||
87 | int perf_session__create_kernel_maps(struct perf_session *self); | 83 | int perf_session__create_kernel_maps(struct perf_session *self); |
88 | 84 | ||
89 | void perf_session__update_sample_type(struct perf_session *self); | 85 | void perf_session__set_id_hdr_size(struct perf_session *session); |
90 | void perf_session__remove_thread(struct perf_session *self, struct thread *th); | 86 | void perf_session__remove_thread(struct perf_session *self, struct thread *th); |
91 | 87 | ||
92 | static inline | 88 | static inline |
@@ -130,24 +126,6 @@ size_t perf_session__fprintf_dsos_buildid(struct perf_session *self, | |||
130 | 126 | ||
131 | size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp); | 127 | size_t perf_session__fprintf_nr_events(struct perf_session *session, FILE *fp); |
132 | 128 | ||
133 | static inline int perf_session__parse_sample(struct perf_session *session, | ||
134 | const union perf_event *event, | ||
135 | struct perf_sample *sample) | ||
136 | { | ||
137 | return perf_event__parse_sample(event, session->sample_type, | ||
138 | session->sample_size, | ||
139 | session->sample_id_all, sample, | ||
140 | session->header.needs_swap); | ||
141 | } | ||
142 | |||
143 | static inline int perf_session__synthesize_sample(struct perf_session *session, | ||
144 | union perf_event *event, | ||
145 | const struct perf_sample *sample) | ||
146 | { | ||
147 | return perf_event__synthesize_sample(event, session->sample_type, | ||
148 | sample, session->header.needs_swap); | ||
149 | } | ||
150 | |||
151 | struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, | 129 | struct perf_evsel *perf_session__find_first_evtype(struct perf_session *session, |
152 | unsigned int type); | 130 | unsigned int type); |
153 | 131 | ||
diff --git a/tools/perf/util/strlist.c b/tools/perf/util/strlist.c index 6783a2043555..95856ff3dda4 100644 --- a/tools/perf/util/strlist.c +++ b/tools/perf/util/strlist.c | |||
@@ -10,23 +10,28 @@ | |||
10 | #include <stdlib.h> | 10 | #include <stdlib.h> |
11 | #include <string.h> | 11 | #include <string.h> |
12 | 12 | ||
13 | static struct str_node *str_node__new(const char *s, bool dupstr) | 13 | static |
14 | struct rb_node *strlist__node_new(struct rblist *rblist, const void *entry) | ||
14 | { | 15 | { |
15 | struct str_node *self = malloc(sizeof(*self)); | 16 | const char *s = entry; |
17 | struct rb_node *rc = NULL; | ||
18 | struct strlist *strlist = container_of(rblist, struct strlist, rblist); | ||
19 | struct str_node *snode = malloc(sizeof(*snode)); | ||
16 | 20 | ||
17 | if (self != NULL) { | 21 | if (snode != NULL) { |
18 | if (dupstr) { | 22 | if (strlist->dupstr) { |
19 | s = strdup(s); | 23 | s = strdup(s); |
20 | if (s == NULL) | 24 | if (s == NULL) |
21 | goto out_delete; | 25 | goto out_delete; |
22 | } | 26 | } |
23 | self->s = s; | 27 | snode->s = s; |
28 | rc = &snode->rb_node; | ||
24 | } | 29 | } |
25 | 30 | ||
26 | return self; | 31 | return rc; |
27 | 32 | ||
28 | out_delete: | 33 | out_delete: |
29 | free(self); | 34 | free(snode); |
30 | return NULL; | 35 | return NULL; |
31 | } | 36 | } |
32 | 37 | ||
@@ -37,36 +42,26 @@ static void str_node__delete(struct str_node *self, bool dupstr) | |||
37 | free(self); | 42 | free(self); |
38 | } | 43 | } |
39 | 44 | ||
40 | int strlist__add(struct strlist *self, const char *new_entry) | 45 | static |
46 | void strlist__node_delete(struct rblist *rblist, struct rb_node *rb_node) | ||
41 | { | 47 | { |
42 | struct rb_node **p = &self->entries.rb_node; | 48 | struct strlist *slist = container_of(rblist, struct strlist, rblist); |
43 | struct rb_node *parent = NULL; | 49 | struct str_node *snode = container_of(rb_node, struct str_node, rb_node); |
44 | struct str_node *sn; | ||
45 | |||
46 | while (*p != NULL) { | ||
47 | int rc; | ||
48 | |||
49 | parent = *p; | ||
50 | sn = rb_entry(parent, struct str_node, rb_node); | ||
51 | rc = strcmp(sn->s, new_entry); | ||
52 | |||
53 | if (rc > 0) | ||
54 | p = &(*p)->rb_left; | ||
55 | else if (rc < 0) | ||
56 | p = &(*p)->rb_right; | ||
57 | else | ||
58 | return -EEXIST; | ||
59 | } | ||
60 | 50 | ||
61 | sn = str_node__new(new_entry, self->dupstr); | 51 | str_node__delete(snode, slist->dupstr); |
62 | if (sn == NULL) | 52 | } |
63 | return -ENOMEM; | ||
64 | 53 | ||
65 | rb_link_node(&sn->rb_node, parent, p); | 54 | static int strlist__node_cmp(struct rb_node *rb_node, const void *entry) |
66 | rb_insert_color(&sn->rb_node, &self->entries); | 55 | { |
67 | ++self->nr_entries; | 56 | const char *str = entry; |
57 | struct str_node *snode = container_of(rb_node, struct str_node, rb_node); | ||
58 | |||
59 | return strcmp(snode->s, str); | ||
60 | } | ||
68 | 61 | ||
69 | return 0; | 62 | int strlist__add(struct strlist *self, const char *new_entry) |
63 | { | ||
64 | return rblist__add_node(&self->rblist, new_entry); | ||
70 | } | 65 | } |
71 | 66 | ||
72 | int strlist__load(struct strlist *self, const char *filename) | 67 | int strlist__load(struct strlist *self, const char *filename) |
@@ -96,34 +91,20 @@ out: | |||
96 | return err; | 91 | return err; |
97 | } | 92 | } |
98 | 93 | ||
99 | void strlist__remove(struct strlist *self, struct str_node *sn) | 94 | void strlist__remove(struct strlist *slist, struct str_node *snode) |
100 | { | 95 | { |
101 | rb_erase(&sn->rb_node, &self->entries); | 96 | str_node__delete(snode, slist->dupstr); |
102 | str_node__delete(sn, self->dupstr); | ||
103 | } | 97 | } |
104 | 98 | ||
105 | struct str_node *strlist__find(struct strlist *self, const char *entry) | 99 | struct str_node *strlist__find(struct strlist *slist, const char *entry) |
106 | { | 100 | { |
107 | struct rb_node **p = &self->entries.rb_node; | 101 | struct str_node *snode = NULL; |
108 | struct rb_node *parent = NULL; | 102 | struct rb_node *rb_node = rblist__find(&slist->rblist, entry); |
109 | |||
110 | while (*p != NULL) { | ||
111 | struct str_node *sn; | ||
112 | int rc; | ||
113 | |||
114 | parent = *p; | ||
115 | sn = rb_entry(parent, struct str_node, rb_node); | ||
116 | rc = strcmp(sn->s, entry); | ||
117 | |||
118 | if (rc > 0) | ||
119 | p = &(*p)->rb_left; | ||
120 | else if (rc < 0) | ||
121 | p = &(*p)->rb_right; | ||
122 | else | ||
123 | return sn; | ||
124 | } | ||
125 | 103 | ||
126 | return NULL; | 104 | if (rb_node) |
105 | snode = container_of(rb_node, struct str_node, rb_node); | ||
106 | |||
107 | return snode; | ||
127 | } | 108 | } |
128 | 109 | ||
129 | static int strlist__parse_list_entry(struct strlist *self, const char *s) | 110 | static int strlist__parse_list_entry(struct strlist *self, const char *s) |
@@ -156,9 +137,12 @@ struct strlist *strlist__new(bool dupstr, const char *slist) | |||
156 | struct strlist *self = malloc(sizeof(*self)); | 137 | struct strlist *self = malloc(sizeof(*self)); |
157 | 138 | ||
158 | if (self != NULL) { | 139 | if (self != NULL) { |
159 | self->entries = RB_ROOT; | 140 | rblist__init(&self->rblist); |
141 | self->rblist.node_cmp = strlist__node_cmp; | ||
142 | self->rblist.node_new = strlist__node_new; | ||
143 | self->rblist.node_delete = strlist__node_delete; | ||
144 | |||
160 | self->dupstr = dupstr; | 145 | self->dupstr = dupstr; |
161 | self->nr_entries = 0; | ||
162 | if (slist && strlist__parse_list(self, slist) != 0) | 146 | if (slist && strlist__parse_list(self, slist) != 0) |
163 | goto out_error; | 147 | goto out_error; |
164 | } | 148 | } |
@@ -171,30 +155,18 @@ out_error: | |||
171 | 155 | ||
172 | void strlist__delete(struct strlist *self) | 156 | void strlist__delete(struct strlist *self) |
173 | { | 157 | { |
174 | if (self != NULL) { | 158 | if (self != NULL) |
175 | struct str_node *pos; | 159 | rblist__delete(&self->rblist); |
176 | struct rb_node *next = rb_first(&self->entries); | ||
177 | |||
178 | while (next) { | ||
179 | pos = rb_entry(next, struct str_node, rb_node); | ||
180 | next = rb_next(&pos->rb_node); | ||
181 | strlist__remove(self, pos); | ||
182 | } | ||
183 | self->entries = RB_ROOT; | ||
184 | free(self); | ||
185 | } | ||
186 | } | 160 | } |
187 | 161 | ||
188 | struct str_node *strlist__entry(const struct strlist *self, unsigned int idx) | 162 | struct str_node *strlist__entry(const struct strlist *slist, unsigned int idx) |
189 | { | 163 | { |
190 | struct rb_node *nd; | 164 | struct str_node *snode = NULL; |
165 | struct rb_node *rb_node; | ||
191 | 166 | ||
192 | for (nd = rb_first(&self->entries); nd; nd = rb_next(nd)) { | 167 | rb_node = rblist__entry(&slist->rblist, idx); |
193 | struct str_node *pos = rb_entry(nd, struct str_node, rb_node); | 168 | if (rb_node) |
169 | snode = container_of(rb_node, struct str_node, rb_node); | ||
194 | 170 | ||
195 | if (!idx--) | 171 | return snode; |
196 | return pos; | ||
197 | } | ||
198 | |||
199 | return NULL; | ||
200 | } | 172 | } |
diff --git a/tools/perf/util/strlist.h b/tools/perf/util/strlist.h index 3ba839007d2c..dd9f922ec67c 100644 --- a/tools/perf/util/strlist.h +++ b/tools/perf/util/strlist.h | |||
@@ -4,14 +4,15 @@ | |||
4 | #include <linux/rbtree.h> | 4 | #include <linux/rbtree.h> |
5 | #include <stdbool.h> | 5 | #include <stdbool.h> |
6 | 6 | ||
7 | #include "rblist.h" | ||
8 | |||
7 | struct str_node { | 9 | struct str_node { |
8 | struct rb_node rb_node; | 10 | struct rb_node rb_node; |
9 | const char *s; | 11 | const char *s; |
10 | }; | 12 | }; |
11 | 13 | ||
12 | struct strlist { | 14 | struct strlist { |
13 | struct rb_root entries; | 15 | struct rblist rblist; |
14 | unsigned int nr_entries; | ||
15 | bool dupstr; | 16 | bool dupstr; |
16 | }; | 17 | }; |
17 | 18 | ||
@@ -32,18 +33,18 @@ static inline bool strlist__has_entry(struct strlist *self, const char *entry) | |||
32 | 33 | ||
33 | static inline bool strlist__empty(const struct strlist *self) | 34 | static inline bool strlist__empty(const struct strlist *self) |
34 | { | 35 | { |
35 | return self->nr_entries == 0; | 36 | return rblist__empty(&self->rblist); |
36 | } | 37 | } |
37 | 38 | ||
38 | static inline unsigned int strlist__nr_entries(const struct strlist *self) | 39 | static inline unsigned int strlist__nr_entries(const struct strlist *self) |
39 | { | 40 | { |
40 | return self->nr_entries; | 41 | return rblist__nr_entries(&self->rblist); |
41 | } | 42 | } |
42 | 43 | ||
43 | /* For strlist iteration */ | 44 | /* For strlist iteration */ |
44 | static inline struct str_node *strlist__first(struct strlist *self) | 45 | static inline struct str_node *strlist__first(struct strlist *self) |
45 | { | 46 | { |
46 | struct rb_node *rn = rb_first(&self->entries); | 47 | struct rb_node *rn = rb_first(&self->rblist.entries); |
47 | return rn ? rb_entry(rn, struct str_node, rb_node) : NULL; | 48 | return rn ? rb_entry(rn, struct str_node, rb_node) : NULL; |
48 | } | 49 | } |
49 | static inline struct str_node *strlist__next(struct str_node *sn) | 50 | static inline struct str_node *strlist__next(struct str_node *sn) |
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c index fdad4eeeb429..8b63b678e127 100644 --- a/tools/perf/util/symbol.c +++ b/tools/perf/util/symbol.c | |||
@@ -64,7 +64,7 @@ static enum dso_binary_type binary_type_symtab[] = { | |||
64 | DSO_BINARY_TYPE__NOT_FOUND, | 64 | DSO_BINARY_TYPE__NOT_FOUND, |
65 | }; | 65 | }; |
66 | 66 | ||
67 | #define DSO_BINARY_TYPE__SYMTAB_CNT sizeof(binary_type_symtab) | 67 | #define DSO_BINARY_TYPE__SYMTAB_CNT ARRAY_SIZE(binary_type_symtab) |
68 | 68 | ||
69 | static enum dso_binary_type binary_type_data[] = { | 69 | static enum dso_binary_type binary_type_data[] = { |
70 | DSO_BINARY_TYPE__BUILD_ID_CACHE, | 70 | DSO_BINARY_TYPE__BUILD_ID_CACHE, |
@@ -72,7 +72,7 @@ static enum dso_binary_type binary_type_data[] = { | |||
72 | DSO_BINARY_TYPE__NOT_FOUND, | 72 | DSO_BINARY_TYPE__NOT_FOUND, |
73 | }; | 73 | }; |
74 | 74 | ||
75 | #define DSO_BINARY_TYPE__DATA_CNT sizeof(binary_type_data) | 75 | #define DSO_BINARY_TYPE__DATA_CNT ARRAY_SIZE(binary_type_data) |
76 | 76 | ||
77 | int dso__name_len(const struct dso *dso) | 77 | int dso__name_len(const struct dso *dso) |
78 | { | 78 | { |
@@ -2875,6 +2875,7 @@ int machines__create_guest_kernel_maps(struct rb_root *machines) | |||
2875 | int i, items = 0; | 2875 | int i, items = 0; |
2876 | char path[PATH_MAX]; | 2876 | char path[PATH_MAX]; |
2877 | pid_t pid; | 2877 | pid_t pid; |
2878 | char *endp; | ||
2878 | 2879 | ||
2879 | if (symbol_conf.default_guest_vmlinux_name || | 2880 | if (symbol_conf.default_guest_vmlinux_name || |
2880 | symbol_conf.default_guest_modules || | 2881 | symbol_conf.default_guest_modules || |
@@ -2891,7 +2892,14 @@ int machines__create_guest_kernel_maps(struct rb_root *machines) | |||
2891 | /* Filter out . and .. */ | 2892 | /* Filter out . and .. */ |
2892 | continue; | 2893 | continue; |
2893 | } | 2894 | } |
2894 | pid = atoi(namelist[i]->d_name); | 2895 | pid = (pid_t)strtol(namelist[i]->d_name, &endp, 10); |
2896 | if ((*endp != '\0') || | ||
2897 | (endp == namelist[i]->d_name) || | ||
2898 | (errno == ERANGE)) { | ||
2899 | pr_debug("invalid directory (%s). Skipping.\n", | ||
2900 | namelist[i]->d_name); | ||
2901 | continue; | ||
2902 | } | ||
2895 | sprintf(path, "%s/%s/proc/kallsyms", | 2903 | sprintf(path, "%s/%s/proc/kallsyms", |
2896 | symbol_conf.guestmount, | 2904 | symbol_conf.guestmount, |
2897 | namelist[i]->d_name); | 2905 | namelist[i]->d_name); |
diff --git a/tools/perf/util/target.c b/tools/perf/util/target.c index 3f59c496e64c..051eaa68095e 100644 --- a/tools/perf/util/target.c +++ b/tools/perf/util/target.c | |||
@@ -110,7 +110,7 @@ int perf_target__strerror(struct perf_target *target, int errnum, | |||
110 | int idx; | 110 | int idx; |
111 | const char *msg; | 111 | const char *msg; |
112 | 112 | ||
113 | BUG_ON(buflen > 0); | 113 | BUG_ON(buflen == 0); |
114 | 114 | ||
115 | if (errnum >= 0) { | 115 | if (errnum >= 0) { |
116 | const char *err = strerror_r(errnum, buf, buflen); | 116 | const char *err = strerror_r(errnum, buf, buflen); |