diff options
468 files changed, 5746 insertions, 4223 deletions
diff --git a/Documentation/devicetree/bindings/arm/vexpress-sysreg.txt b/Documentation/devicetree/bindings/arm/vexpress-sysreg.txt index 5580e9c4bd85..00318d083c9e 100644 --- a/Documentation/devicetree/bindings/arm/vexpress-sysreg.txt +++ b/Documentation/devicetree/bindings/arm/vexpress-sysreg.txt | |||
@@ -8,6 +8,8 @@ interrupt generation, MMC and NOR Flash control etc. | |||
8 | Required node properties: | 8 | Required node properties: |
9 | - compatible value : = "arm,vexpress,sysreg"; | 9 | - compatible value : = "arm,vexpress,sysreg"; |
10 | - reg : physical base address and the size of the registers window | 10 | - reg : physical base address and the size of the registers window |
11 | |||
12 | Deprecated properties, replaced by GPIO subnodes (see below): | ||
11 | - gpio-controller : specifies that the node is a GPIO controller | 13 | - gpio-controller : specifies that the node is a GPIO controller |
12 | - #gpio-cells : size of the GPIO specifier, should be 2: | 14 | - #gpio-cells : size of the GPIO specifier, should be 2: |
13 | - first cell is the pseudo-GPIO line number: | 15 | - first cell is the pseudo-GPIO line number: |
@@ -16,35 +18,86 @@ Required node properties: | |||
16 | 2 - NOR FLASH WPn | 18 | 2 - NOR FLASH WPn |
17 | - second cell can take standard GPIO flags (currently ignored). | 19 | - second cell can take standard GPIO flags (currently ignored). |
18 | 20 | ||
21 | Control registers providing pseudo-GPIO lines must be represented | ||
22 | by subnodes, each of them requiring the following properties: | ||
23 | - compatible value : one of | ||
24 | "arm,vexpress-sysreg,sys_led" | ||
25 | "arm,vexpress-sysreg,sys_mci" | ||
26 | "arm,vexpress-sysreg,sys_flash" | ||
27 | - gpio-controller : makes the node a GPIO controller | ||
28 | - #gpio-cells : size of the GPIO specifier, must be 2: | ||
29 | - first cell is the function number: | ||
30 | - for sys_led : 0..7 = LED 0..7 | ||
31 | - for sys_mci : 0 = MMC CARDIN, 1 = MMC WPROT | ||
32 | - for sys_flash : 0 = NOR FLASH WPn | ||
33 | - second cell can take standard GPIO flags (currently ignored). | ||
34 | |||
19 | Example: | 35 | Example: |
20 | v2m_sysreg: sysreg@10000000 { | 36 | v2m_sysreg: sysreg@10000000 { |
21 | compatible = "arm,vexpress-sysreg"; | 37 | compatible = "arm,vexpress-sysreg"; |
22 | reg = <0x10000000 0x1000>; | 38 | reg = <0x10000000 0x1000>; |
23 | gpio-controller; | 39 | |
24 | #gpio-cells = <2>; | 40 | v2m_led_gpios: sys_led@08 { |
41 | compatible = "arm,vexpress-sysreg,sys_led"; | ||
42 | gpio-controller; | ||
43 | #gpio-cells = <2>; | ||
44 | }; | ||
45 | |||
46 | v2m_mmc_gpios: sys_mci@48 { | ||
47 | compatible = "arm,vexpress-sysreg,sys_mci"; | ||
48 | gpio-controller; | ||
49 | #gpio-cells = <2>; | ||
50 | }; | ||
51 | |||
52 | v2m_flash_gpios: sys_flash@4c { | ||
53 | compatible = "arm,vexpress-sysreg,sys_flash"; | ||
54 | gpio-controller; | ||
55 | #gpio-cells = <2>; | ||
56 | }; | ||
25 | }; | 57 | }; |
26 | 58 | ||
27 | This block also can also act a bridge to the platform's configuration | 59 | This block also can also act a bridge to the platform's configuration |
28 | bus via "system control" interface, addressing devices with site number, | 60 | bus via "system control" interface, addressing devices with site number, |
29 | position in the board stack, config controller, function and device | 61 | position in the board stack, config controller, function and device |
30 | numbers - see motherboard's TRM for more details. | 62 | numbers - see motherboard's TRM for more details. All configuration |
31 | 63 | controller accessible via this interface must reference the sysreg | |
32 | The node describing a config device must refer to the sysreg node via | 64 | node via "arm,vexpress,config-bridge" phandle and define appropriate |
33 | "arm,vexpress,config-bridge" phandle (can be also defined in the node's | 65 | topology properties - see main vexpress node documentation for more |
34 | parent) and relies on the board topology properties - see main vexpress | 66 | details. Each child of such node describes one function and must |
35 | node documentation for more details. It must also define the following | 67 | define the following properties: |
36 | property: | 68 | - compatible value : must be one of (corresponding to the TRM): |
37 | - arm,vexpress-sysreg,func : must contain two cells: | 69 | "arm,vexpress-amp" |
38 | - first cell defines function number (eg. 1 for clock generator, | 70 | "arm,vexpress-dvimode" |
39 | 2 for voltage regulators etc.) | 71 | "arm,vexpress-energy" |
40 | - device number (eg. osc 0, osc 1 etc.) | 72 | "arm,vexpress-muxfpga" |
73 | "arm,vexpress-osc" | ||
74 | "arm,vexpress-power" | ||
75 | "arm,vexpress-reboot" | ||
76 | "arm,vexpress-reset" | ||
77 | "arm,vexpress-scc" | ||
78 | "arm,vexpress-shutdown" | ||
79 | "arm,vexpress-temp" | ||
80 | "arm,vexpress-volt" | ||
81 | - arm,vexpress-sysreg,func : must contain a set of two cells long groups: | ||
82 | - first cell of each group defines the function number | ||
83 | (eg. 1 for clock generator, 2 for voltage regulators etc.) | ||
84 | - second cell of each group defines device number (eg. osc 0, | ||
85 | osc 1 etc.) | ||
86 | - some functions (eg. energy meter, with its 64 bit long counter) | ||
87 | are using more than one function/device number pair | ||
41 | 88 | ||
42 | Example: | 89 | Example: |
43 | mcc { | 90 | mcc { |
91 | compatible = "arm,vexpress,config-bus"; | ||
44 | arm,vexpress,config-bridge = <&v2m_sysreg>; | 92 | arm,vexpress,config-bridge = <&v2m_sysreg>; |
45 | 93 | ||
46 | osc@0 { | 94 | osc@0 { |
47 | compatible = "arm,vexpress-osc"; | 95 | compatible = "arm,vexpress-osc"; |
48 | arm,vexpress-sysreg,func = <1 0>; | 96 | arm,vexpress-sysreg,func = <1 0>; |
49 | }; | 97 | }; |
98 | |||
99 | energy@0 { | ||
100 | compatible = "arm,vexpress-energy"; | ||
101 | arm,vexpress-sysreg,func = <13 0>, <13 1>; | ||
102 | }; | ||
50 | }; | 103 | }; |
diff --git a/Documentation/devicetree/bindings/arm/vexpress.txt b/Documentation/devicetree/bindings/arm/vexpress.txt index ae49161e478a..39844cd0bcce 100644 --- a/Documentation/devicetree/bindings/arm/vexpress.txt +++ b/Documentation/devicetree/bindings/arm/vexpress.txt | |||
@@ -80,12 +80,17 @@ but also control clock generators, voltage regulators, gather | |||
80 | environmental data like temperature, power consumption etc. Even | 80 | environmental data like temperature, power consumption etc. Even |
81 | the video output switch (FPGA) is controlled that way. | 81 | the video output switch (FPGA) is controlled that way. |
82 | 82 | ||
83 | Nodes describing devices controlled by this infrastructure should | 83 | The controllers are not mapped into normal memory address space |
84 | point at the bridge device node: | 84 | and must be accessed through bridges - other devices capable |
85 | of generating transactions on the configuration bus. | ||
86 | |||
87 | The nodes describing configuration controllers must define | ||
88 | the following properties: | ||
89 | - compatible value: | ||
90 | compatible = "arm,vexpress,config-bus"; | ||
85 | - bridge phandle: | 91 | - bridge phandle: |
86 | arm,vexpress,config-bridge = <phandle>; | 92 | arm,vexpress,config-bridge = <phandle>; |
87 | This property can be also defined in a parent node (eg. for a DCC) | 93 | and children describing available functions. |
88 | and is effective for all children. | ||
89 | 94 | ||
90 | 95 | ||
91 | Platform topology | 96 | Platform topology |
@@ -197,7 +202,7 @@ Example of a VE tile description (simplified) | |||
197 | }; | 202 | }; |
198 | 203 | ||
199 | dcc { | 204 | dcc { |
200 | compatible = "simple-bus"; | 205 | compatible = "arm,vexpress,config-bus"; |
201 | arm,vexpress,config-bridge = <&v2m_sysreg>; | 206 | arm,vexpress,config-bridge = <&v2m_sysreg>; |
202 | 207 | ||
203 | osc@0 { | 208 | osc@0 { |
diff --git a/Documentation/devicetree/bindings/net/arc_emac.txt b/Documentation/devicetree/bindings/net/arc_emac.txt index 7fbb027218a1..a1d71eb43b20 100644 --- a/Documentation/devicetree/bindings/net/arc_emac.txt +++ b/Documentation/devicetree/bindings/net/arc_emac.txt | |||
@@ -4,11 +4,15 @@ Required properties: | |||
4 | - compatible: Should be "snps,arc-emac" | 4 | - compatible: Should be "snps,arc-emac" |
5 | - reg: Address and length of the register set for the device | 5 | - reg: Address and length of the register set for the device |
6 | - interrupts: Should contain the EMAC interrupts | 6 | - interrupts: Should contain the EMAC interrupts |
7 | - clock-frequency: CPU frequency. It is needed to calculate and set polling | ||
8 | period of EMAC. | ||
9 | - max-speed: see ethernet.txt file in the same directory. | 7 | - max-speed: see ethernet.txt file in the same directory. |
10 | - phy: see ethernet.txt file in the same directory. | 8 | - phy: see ethernet.txt file in the same directory. |
11 | 9 | ||
10 | Clock handling: | ||
11 | The clock frequency is needed to calculate and set polling period of EMAC. | ||
12 | It must be provided by one of: | ||
13 | - clock-frequency: CPU frequency. | ||
14 | - clocks: reference to the clock supplying the EMAC. | ||
15 | |||
12 | Child nodes of the driver are the individual PHY devices connected to the | 16 | Child nodes of the driver are the individual PHY devices connected to the |
13 | MDIO bus. They must have a "reg" property given the PHY address on the MDIO bus. | 17 | MDIO bus. They must have a "reg" property given the PHY address on the MDIO bus. |
14 | 18 | ||
@@ -19,7 +23,11 @@ Examples: | |||
19 | reg = <0xc0fc2000 0x3c>; | 23 | reg = <0xc0fc2000 0x3c>; |
20 | interrupts = <6>; | 24 | interrupts = <6>; |
21 | mac-address = [ 00 11 22 33 44 55 ]; | 25 | mac-address = [ 00 11 22 33 44 55 ]; |
26 | |||
22 | clock-frequency = <80000000>; | 27 | clock-frequency = <80000000>; |
28 | /* or */ | ||
29 | clocks = <&emac_clock>; | ||
30 | |||
23 | max-speed = <100>; | 31 | max-speed = <100>; |
24 | phy = <&phy0>; | 32 | phy = <&phy0>; |
25 | 33 | ||
diff --git a/Documentation/input/elantech.txt b/Documentation/input/elantech.txt index 5602eb71ad5d..e1ae127ed099 100644 --- a/Documentation/input/elantech.txt +++ b/Documentation/input/elantech.txt | |||
@@ -504,9 +504,12 @@ byte 5: | |||
504 | * reg_10 | 504 | * reg_10 |
505 | 505 | ||
506 | bit 7 6 5 4 3 2 1 0 | 506 | bit 7 6 5 4 3 2 1 0 |
507 | 0 0 0 0 0 0 0 A | 507 | 0 0 0 0 R F T A |
508 | 508 | ||
509 | A: 1 = enable absolute tracking | 509 | A: 1 = enable absolute tracking |
510 | T: 1 = enable two finger mode auto correct | ||
511 | F: 1 = disable ABS Position Filter | ||
512 | R: 1 = enable real hardware resolution | ||
510 | 513 | ||
511 | 6.2 Native absolute mode 6 byte packet format | 514 | 6.2 Native absolute mode 6 byte packet format |
512 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | 515 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
diff --git a/Documentation/networking/scaling.txt b/Documentation/networking/scaling.txt index ca6977f5b2ed..99ca40e8e810 100644 --- a/Documentation/networking/scaling.txt +++ b/Documentation/networking/scaling.txt | |||
@@ -429,7 +429,7 @@ RPS and RFS were introduced in kernel 2.6.35. XPS was incorporated into | |||
429 | (therbert@google.com) | 429 | (therbert@google.com) |
430 | 430 | ||
431 | Accelerated RFS was introduced in 2.6.35. Original patches were | 431 | Accelerated RFS was introduced in 2.6.35. Original patches were |
432 | submitted by Ben Hutchings (bhutchings@solarflare.com) | 432 | submitted by Ben Hutchings (bwh@kernel.org) |
433 | 433 | ||
434 | Authors: | 434 | Authors: |
435 | Tom Herbert (therbert@google.com) | 435 | Tom Herbert (therbert@google.com) |
diff --git a/MAINTAINERS b/MAINTAINERS index 106626442124..51ebb779c5f3 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -7288,7 +7288,6 @@ F: drivers/video/aty/aty128fb.c | |||
7288 | RALINK RT2X00 WIRELESS LAN DRIVER | 7288 | RALINK RT2X00 WIRELESS LAN DRIVER |
7289 | P: rt2x00 project | 7289 | P: rt2x00 project |
7290 | M: Ivo van Doorn <IvDoorn@gmail.com> | 7290 | M: Ivo van Doorn <IvDoorn@gmail.com> |
7291 | M: Gertjan van Wingerde <gwingerde@gmail.com> | ||
7292 | M: Helmut Schaa <helmut.schaa@googlemail.com> | 7291 | M: Helmut Schaa <helmut.schaa@googlemail.com> |
7293 | L: linux-wireless@vger.kernel.org | 7292 | L: linux-wireless@vger.kernel.org |
7294 | L: users@rt2x00.serialmonkey.com (moderated for non-subscribers) | 7293 | L: users@rt2x00.serialmonkey.com (moderated for non-subscribers) |
@@ -7304,7 +7303,7 @@ F: Documentation/blockdev/ramdisk.txt | |||
7304 | F: drivers/block/brd.c | 7303 | F: drivers/block/brd.c |
7305 | 7304 | ||
7306 | RANDOM NUMBER DRIVER | 7305 | RANDOM NUMBER DRIVER |
7307 | M: Theodore Ts'o" <tytso@mit.edu> | 7306 | M: "Theodore Ts'o" <tytso@mit.edu> |
7308 | S: Maintained | 7307 | S: Maintained |
7309 | F: drivers/char/random.c | 7308 | F: drivers/char/random.c |
7310 | 7309 | ||
@@ -7685,7 +7684,6 @@ F: drivers/clk/samsung/ | |||
7685 | SAMSUNG SXGBE DRIVERS | 7684 | SAMSUNG SXGBE DRIVERS |
7686 | M: Byungho An <bh74.an@samsung.com> | 7685 | M: Byungho An <bh74.an@samsung.com> |
7687 | M: Girish K S <ks.giri@samsung.com> | 7686 | M: Girish K S <ks.giri@samsung.com> |
7688 | M: Siva Reddy Kallam <siva.kallam@samsung.com> | ||
7689 | M: Vipul Pandya <vipul.pandya@samsung.com> | 7687 | M: Vipul Pandya <vipul.pandya@samsung.com> |
7690 | S: Supported | 7688 | S: Supported |
7691 | L: netdev@vger.kernel.org | 7689 | L: netdev@vger.kernel.org |
@@ -9962,7 +9960,7 @@ F: drivers/net/hamradio/*scc.c | |||
9962 | F: drivers/net/hamradio/z8530.h | 9960 | F: drivers/net/hamradio/z8530.h |
9963 | 9961 | ||
9964 | ZBUD COMPRESSED PAGE ALLOCATOR | 9962 | ZBUD COMPRESSED PAGE ALLOCATOR |
9965 | M: Seth Jennings <sjenning@linux.vnet.ibm.com> | 9963 | M: Seth Jennings <sjennings@variantweb.net> |
9966 | L: linux-mm@kvack.org | 9964 | L: linux-mm@kvack.org |
9967 | S: Maintained | 9965 | S: Maintained |
9968 | F: mm/zbud.c | 9966 | F: mm/zbud.c |
@@ -10007,7 +10005,7 @@ F: mm/zsmalloc.c | |||
10007 | F: include/linux/zsmalloc.h | 10005 | F: include/linux/zsmalloc.h |
10008 | 10006 | ||
10009 | ZSWAP COMPRESSED SWAP CACHING | 10007 | ZSWAP COMPRESSED SWAP CACHING |
10010 | M: Seth Jennings <sjenning@linux.vnet.ibm.com> | 10008 | M: Seth Jennings <sjennings@variantweb.net> |
10011 | L: linux-mm@kvack.org | 10009 | L: linux-mm@kvack.org |
10012 | S: Maintained | 10010 | S: Maintained |
10013 | F: mm/zswap.c | 10011 | F: mm/zswap.c |
@@ -1,7 +1,7 @@ | |||
1 | VERSION = 3 | 1 | VERSION = 3 |
2 | PATCHLEVEL = 15 | 2 | PATCHLEVEL = 15 |
3 | SUBLEVEL = 0 | 3 | SUBLEVEL = 0 |
4 | EXTRAVERSION = -rc4 | 4 | EXTRAVERSION = -rc5 |
5 | NAME = Shuffling Zombie Juror | 5 | NAME = Shuffling Zombie Juror |
6 | 6 | ||
7 | # *DOCUMENTATION* | 7 | # *DOCUMENTATION* |
diff --git a/arch/arm/boot/dts/atlas6.dtsi b/arch/arm/boot/dts/atlas6.dtsi index 9d72674049d6..317bc590a4d0 100644 --- a/arch/arm/boot/dts/atlas6.dtsi +++ b/arch/arm/boot/dts/atlas6.dtsi | |||
@@ -195,6 +195,7 @@ | |||
195 | compatible = "sirf,prima2-tick"; | 195 | compatible = "sirf,prima2-tick"; |
196 | reg = <0xb0020000 0x1000>; | 196 | reg = <0xb0020000 0x1000>; |
197 | interrupts = <0>; | 197 | interrupts = <0>; |
198 | clocks = <&clks 11>; | ||
198 | }; | 199 | }; |
199 | 200 | ||
200 | nand@b0030000 { | 201 | nand@b0030000 { |
diff --git a/arch/arm/boot/dts/prima2.dtsi b/arch/arm/boot/dts/prima2.dtsi index 1e82571d6823..7e7d8843abaf 100644 --- a/arch/arm/boot/dts/prima2.dtsi +++ b/arch/arm/boot/dts/prima2.dtsi | |||
@@ -201,6 +201,7 @@ | |||
201 | compatible = "sirf,prima2-tick"; | 201 | compatible = "sirf,prima2-tick"; |
202 | reg = <0xb0020000 0x1000>; | 202 | reg = <0xb0020000 0x1000>; |
203 | interrupts = <0>; | 203 | interrupts = <0>; |
204 | clocks = <&clks 11>; | ||
204 | }; | 205 | }; |
205 | 206 | ||
206 | nand@b0030000 { | 207 | nand@b0030000 { |
diff --git a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi index ac870fb3fa0d..756c986995a3 100644 --- a/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi +++ b/arch/arm/boot/dts/vexpress-v2m-rs1.dtsi | |||
@@ -74,8 +74,24 @@ | |||
74 | v2m_sysreg: sysreg@010000 { | 74 | v2m_sysreg: sysreg@010000 { |
75 | compatible = "arm,vexpress-sysreg"; | 75 | compatible = "arm,vexpress-sysreg"; |
76 | reg = <0x010000 0x1000>; | 76 | reg = <0x010000 0x1000>; |
77 | gpio-controller; | 77 | |
78 | #gpio-cells = <2>; | 78 | v2m_led_gpios: sys_led@08 { |
79 | compatible = "arm,vexpress-sysreg,sys_led"; | ||
80 | gpio-controller; | ||
81 | #gpio-cells = <2>; | ||
82 | }; | ||
83 | |||
84 | v2m_mmc_gpios: sys_mci@48 { | ||
85 | compatible = "arm,vexpress-sysreg,sys_mci"; | ||
86 | gpio-controller; | ||
87 | #gpio-cells = <2>; | ||
88 | }; | ||
89 | |||
90 | v2m_flash_gpios: sys_flash@4c { | ||
91 | compatible = "arm,vexpress-sysreg,sys_flash"; | ||
92 | gpio-controller; | ||
93 | #gpio-cells = <2>; | ||
94 | }; | ||
79 | }; | 95 | }; |
80 | 96 | ||
81 | v2m_sysctl: sysctl@020000 { | 97 | v2m_sysctl: sysctl@020000 { |
@@ -113,8 +129,8 @@ | |||
113 | compatible = "arm,pl180", "arm,primecell"; | 129 | compatible = "arm,pl180", "arm,primecell"; |
114 | reg = <0x050000 0x1000>; | 130 | reg = <0x050000 0x1000>; |
115 | interrupts = <9 10>; | 131 | interrupts = <9 10>; |
116 | cd-gpios = <&v2m_sysreg 0 0>; | 132 | cd-gpios = <&v2m_mmc_gpios 0 0>; |
117 | wp-gpios = <&v2m_sysreg 1 0>; | 133 | wp-gpios = <&v2m_mmc_gpios 1 0>; |
118 | max-frequency = <12000000>; | 134 | max-frequency = <12000000>; |
119 | vmmc-supply = <&v2m_fixed_3v3>; | 135 | vmmc-supply = <&v2m_fixed_3v3>; |
120 | clocks = <&v2m_clk24mhz>, <&smbclk>; | 136 | clocks = <&v2m_clk24mhz>, <&smbclk>; |
@@ -265,6 +281,58 @@ | |||
265 | clock-output-names = "v2m:refclk32khz"; | 281 | clock-output-names = "v2m:refclk32khz"; |
266 | }; | 282 | }; |
267 | 283 | ||
284 | leds { | ||
285 | compatible = "gpio-leds"; | ||
286 | |||
287 | user@1 { | ||
288 | label = "v2m:green:user1"; | ||
289 | gpios = <&v2m_led_gpios 0 0>; | ||
290 | linux,default-trigger = "heartbeat"; | ||
291 | }; | ||
292 | |||
293 | user@2 { | ||
294 | label = "v2m:green:user2"; | ||
295 | gpios = <&v2m_led_gpios 1 0>; | ||
296 | linux,default-trigger = "mmc0"; | ||
297 | }; | ||
298 | |||
299 | user@3 { | ||
300 | label = "v2m:green:user3"; | ||
301 | gpios = <&v2m_led_gpios 2 0>; | ||
302 | linux,default-trigger = "cpu0"; | ||
303 | }; | ||
304 | |||
305 | user@4 { | ||
306 | label = "v2m:green:user4"; | ||
307 | gpios = <&v2m_led_gpios 3 0>; | ||
308 | linux,default-trigger = "cpu1"; | ||
309 | }; | ||
310 | |||
311 | user@5 { | ||
312 | label = "v2m:green:user5"; | ||
313 | gpios = <&v2m_led_gpios 4 0>; | ||
314 | linux,default-trigger = "cpu2"; | ||
315 | }; | ||
316 | |||
317 | user@6 { | ||
318 | label = "v2m:green:user6"; | ||
319 | gpios = <&v2m_led_gpios 5 0>; | ||
320 | linux,default-trigger = "cpu3"; | ||
321 | }; | ||
322 | |||
323 | user@7 { | ||
324 | label = "v2m:green:user7"; | ||
325 | gpios = <&v2m_led_gpios 6 0>; | ||
326 | linux,default-trigger = "cpu4"; | ||
327 | }; | ||
328 | |||
329 | user@8 { | ||
330 | label = "v2m:green:user8"; | ||
331 | gpios = <&v2m_led_gpios 7 0>; | ||
332 | linux,default-trigger = "cpu5"; | ||
333 | }; | ||
334 | }; | ||
335 | |||
268 | mcc { | 336 | mcc { |
269 | compatible = "arm,vexpress,config-bus"; | 337 | compatible = "arm,vexpress,config-bus"; |
270 | arm,vexpress,config-bridge = <&v2m_sysreg>; | 338 | arm,vexpress,config-bridge = <&v2m_sysreg>; |
diff --git a/arch/arm/boot/dts/vexpress-v2m.dtsi b/arch/arm/boot/dts/vexpress-v2m.dtsi index f1420368355b..ba856d604fb7 100644 --- a/arch/arm/boot/dts/vexpress-v2m.dtsi +++ b/arch/arm/boot/dts/vexpress-v2m.dtsi | |||
@@ -73,8 +73,24 @@ | |||
73 | v2m_sysreg: sysreg@00000 { | 73 | v2m_sysreg: sysreg@00000 { |
74 | compatible = "arm,vexpress-sysreg"; | 74 | compatible = "arm,vexpress-sysreg"; |
75 | reg = <0x00000 0x1000>; | 75 | reg = <0x00000 0x1000>; |
76 | gpio-controller; | 76 | |
77 | #gpio-cells = <2>; | 77 | v2m_led_gpios: sys_led@08 { |
78 | compatible = "arm,vexpress-sysreg,sys_led"; | ||
79 | gpio-controller; | ||
80 | #gpio-cells = <2>; | ||
81 | }; | ||
82 | |||
83 | v2m_mmc_gpios: sys_mci@48 { | ||
84 | compatible = "arm,vexpress-sysreg,sys_mci"; | ||
85 | gpio-controller; | ||
86 | #gpio-cells = <2>; | ||
87 | }; | ||
88 | |||
89 | v2m_flash_gpios: sys_flash@4c { | ||
90 | compatible = "arm,vexpress-sysreg,sys_flash"; | ||
91 | gpio-controller; | ||
92 | #gpio-cells = <2>; | ||
93 | }; | ||
78 | }; | 94 | }; |
79 | 95 | ||
80 | v2m_sysctl: sysctl@01000 { | 96 | v2m_sysctl: sysctl@01000 { |
@@ -112,8 +128,8 @@ | |||
112 | compatible = "arm,pl180", "arm,primecell"; | 128 | compatible = "arm,pl180", "arm,primecell"; |
113 | reg = <0x05000 0x1000>; | 129 | reg = <0x05000 0x1000>; |
114 | interrupts = <9 10>; | 130 | interrupts = <9 10>; |
115 | cd-gpios = <&v2m_sysreg 0 0>; | 131 | cd-gpios = <&v2m_mmc_gpios 0 0>; |
116 | wp-gpios = <&v2m_sysreg 1 0>; | 132 | wp-gpios = <&v2m_mmc_gpios 1 0>; |
117 | max-frequency = <12000000>; | 133 | max-frequency = <12000000>; |
118 | vmmc-supply = <&v2m_fixed_3v3>; | 134 | vmmc-supply = <&v2m_fixed_3v3>; |
119 | clocks = <&v2m_clk24mhz>, <&smbclk>; | 135 | clocks = <&v2m_clk24mhz>, <&smbclk>; |
@@ -264,6 +280,58 @@ | |||
264 | clock-output-names = "v2m:refclk32khz"; | 280 | clock-output-names = "v2m:refclk32khz"; |
265 | }; | 281 | }; |
266 | 282 | ||
283 | leds { | ||
284 | compatible = "gpio-leds"; | ||
285 | |||
286 | user@1 { | ||
287 | label = "v2m:green:user1"; | ||
288 | gpios = <&v2m_led_gpios 0 0>; | ||
289 | linux,default-trigger = "heartbeat"; | ||
290 | }; | ||
291 | |||
292 | user@2 { | ||
293 | label = "v2m:green:user2"; | ||
294 | gpios = <&v2m_led_gpios 1 0>; | ||
295 | linux,default-trigger = "mmc0"; | ||
296 | }; | ||
297 | |||
298 | user@3 { | ||
299 | label = "v2m:green:user3"; | ||
300 | gpios = <&v2m_led_gpios 2 0>; | ||
301 | linux,default-trigger = "cpu0"; | ||
302 | }; | ||
303 | |||
304 | user@4 { | ||
305 | label = "v2m:green:user4"; | ||
306 | gpios = <&v2m_led_gpios 3 0>; | ||
307 | linux,default-trigger = "cpu1"; | ||
308 | }; | ||
309 | |||
310 | user@5 { | ||
311 | label = "v2m:green:user5"; | ||
312 | gpios = <&v2m_led_gpios 4 0>; | ||
313 | linux,default-trigger = "cpu2"; | ||
314 | }; | ||
315 | |||
316 | user@6 { | ||
317 | label = "v2m:green:user6"; | ||
318 | gpios = <&v2m_led_gpios 5 0>; | ||
319 | linux,default-trigger = "cpu3"; | ||
320 | }; | ||
321 | |||
322 | user@7 { | ||
323 | label = "v2m:green:user7"; | ||
324 | gpios = <&v2m_led_gpios 6 0>; | ||
325 | linux,default-trigger = "cpu4"; | ||
326 | }; | ||
327 | |||
328 | user@8 { | ||
329 | label = "v2m:green:user8"; | ||
330 | gpios = <&v2m_led_gpios 7 0>; | ||
331 | linux,default-trigger = "cpu5"; | ||
332 | }; | ||
333 | }; | ||
334 | |||
267 | mcc { | 335 | mcc { |
268 | compatible = "arm,vexpress,config-bus"; | 336 | compatible = "arm,vexpress,config-bus"; |
269 | arm,vexpress,config-bridge = <&v2m_sysreg>; | 337 | arm,vexpress,config-bridge = <&v2m_sysreg>; |
diff --git a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts index 15f98cbcb75a..a25c262326dc 100644 --- a/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts +++ b/arch/arm/boot/dts/vexpress-v2p-ca15_a7.dts | |||
@@ -312,6 +312,7 @@ | |||
312 | arm,vexpress-sysreg,func = <12 0>; | 312 | arm,vexpress-sysreg,func = <12 0>; |
313 | label = "A15 Pcore"; | 313 | label = "A15 Pcore"; |
314 | }; | 314 | }; |
315 | |||
315 | power@1 { | 316 | power@1 { |
316 | /* Total power for the three A7 cores */ | 317 | /* Total power for the three A7 cores */ |
317 | compatible = "arm,vexpress-power"; | 318 | compatible = "arm,vexpress-power"; |
@@ -322,14 +323,14 @@ | |||
322 | energy@0 { | 323 | energy@0 { |
323 | /* Total energy for the two A15 cores */ | 324 | /* Total energy for the two A15 cores */ |
324 | compatible = "arm,vexpress-energy"; | 325 | compatible = "arm,vexpress-energy"; |
325 | arm,vexpress-sysreg,func = <13 0>; | 326 | arm,vexpress-sysreg,func = <13 0>, <13 1>; |
326 | label = "A15 Jcore"; | 327 | label = "A15 Jcore"; |
327 | }; | 328 | }; |
328 | 329 | ||
329 | energy@2 { | 330 | energy@2 { |
330 | /* Total energy for the three A7 cores */ | 331 | /* Total energy for the three A7 cores */ |
331 | compatible = "arm,vexpress-energy"; | 332 | compatible = "arm,vexpress-energy"; |
332 | arm,vexpress-sysreg,func = <13 2>; | 333 | arm,vexpress-sysreg,func = <13 2>, <13 3>; |
333 | label = "A7 Jcore"; | 334 | label = "A7 Jcore"; |
334 | }; | 335 | }; |
335 | }; | 336 | }; |
diff --git a/arch/arm/configs/realview-smp_defconfig b/arch/arm/configs/realview-smp_defconfig index abe61bf379d2..1da5d9e48224 100644 --- a/arch/arm/configs/realview-smp_defconfig +++ b/arch/arm/configs/realview-smp_defconfig | |||
@@ -76,8 +76,10 @@ CONFIG_MMC=y | |||
76 | CONFIG_MMC_ARMMMCI=y | 76 | CONFIG_MMC_ARMMMCI=y |
77 | CONFIG_NEW_LEDS=y | 77 | CONFIG_NEW_LEDS=y |
78 | CONFIG_LEDS_CLASS=y | 78 | CONFIG_LEDS_CLASS=y |
79 | CONFIG_LEDS_VERSATILE=y | ||
79 | CONFIG_LEDS_TRIGGERS=y | 80 | CONFIG_LEDS_TRIGGERS=y |
80 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | 81 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y |
82 | CONFIG_LEDS_TRIGGER_CPU=y | ||
81 | CONFIG_RTC_CLASS=y | 83 | CONFIG_RTC_CLASS=y |
82 | CONFIG_RTC_DRV_DS1307=y | 84 | CONFIG_RTC_DRV_DS1307=y |
83 | CONFIG_RTC_DRV_PL031=y | 85 | CONFIG_RTC_DRV_PL031=y |
diff --git a/arch/arm/configs/realview_defconfig b/arch/arm/configs/realview_defconfig index 7079cbe898a8..d02e9d911bb7 100644 --- a/arch/arm/configs/realview_defconfig +++ b/arch/arm/configs/realview_defconfig | |||
@@ -75,8 +75,10 @@ CONFIG_MMC=y | |||
75 | CONFIG_MMC_ARMMMCI=y | 75 | CONFIG_MMC_ARMMMCI=y |
76 | CONFIG_NEW_LEDS=y | 76 | CONFIG_NEW_LEDS=y |
77 | CONFIG_LEDS_CLASS=y | 77 | CONFIG_LEDS_CLASS=y |
78 | CONFIG_LEDS_VERSATILE=y | ||
78 | CONFIG_LEDS_TRIGGERS=y | 79 | CONFIG_LEDS_TRIGGERS=y |
79 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | 80 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y |
81 | CONFIG_LEDS_TRIGGER_CPU=y | ||
80 | CONFIG_RTC_CLASS=y | 82 | CONFIG_RTC_CLASS=y |
81 | CONFIG_RTC_DRV_DS1307=y | 83 | CONFIG_RTC_DRV_DS1307=y |
82 | CONFIG_RTC_DRV_PL031=y | 84 | CONFIG_RTC_DRV_PL031=y |
diff --git a/arch/arm/configs/versatile_defconfig b/arch/arm/configs/versatile_defconfig index 073541a50e23..d52b4ffe2012 100644 --- a/arch/arm/configs/versatile_defconfig +++ b/arch/arm/configs/versatile_defconfig | |||
@@ -61,6 +61,9 @@ CONFIG_SND_ARMAACI=m | |||
61 | CONFIG_MMC=y | 61 | CONFIG_MMC=y |
62 | CONFIG_MMC_ARMMMCI=m | 62 | CONFIG_MMC_ARMMMCI=m |
63 | CONFIG_NEW_LEDS=y | 63 | CONFIG_NEW_LEDS=y |
64 | CONFIG_LEDS_CLASS=y | ||
65 | CONFIG_LEDS_VERSATILE=y | ||
66 | CONFIG_LEDS_TRIGGERS=y | ||
64 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y | 67 | CONFIG_LEDS_TRIGGER_HEARTBEAT=y |
65 | CONFIG_LEDS_TRIGGER_CPU=y | 68 | CONFIG_LEDS_TRIGGER_CPU=y |
66 | CONFIG_EXT2_FS=y | 69 | CONFIG_EXT2_FS=y |
diff --git a/arch/arm/mach-bcm/Kconfig b/arch/arm/mach-bcm/Kconfig index 49c914cd9c7a..b8cc9e8992f1 100644 --- a/arch/arm/mach-bcm/Kconfig +++ b/arch/arm/mach-bcm/Kconfig | |||
@@ -10,22 +10,51 @@ if ARCH_BCM | |||
10 | menu "Broadcom SoC Selection" | 10 | menu "Broadcom SoC Selection" |
11 | 11 | ||
12 | config ARCH_BCM_MOBILE | 12 | config ARCH_BCM_MOBILE |
13 | bool "Broadcom Mobile SoC" if ARCH_MULTI_V7 | 13 | bool "Broadcom Mobile SoC Support" if ARCH_MULTI_V7 |
14 | depends on MMU | ||
15 | select ARCH_REQUIRE_GPIOLIB | 14 | select ARCH_REQUIRE_GPIOLIB |
16 | select ARM_ERRATA_754322 | 15 | select ARM_ERRATA_754322 |
17 | select ARM_ERRATA_764369 if SMP | 16 | select ARM_ERRATA_764369 if SMP |
18 | select ARM_GIC | 17 | select ARM_GIC |
19 | select GPIO_BCM_KONA | 18 | select GPIO_BCM_KONA |
20 | select TICK_ONESHOT | 19 | select TICK_ONESHOT |
21 | select CACHE_L2X0 | ||
22 | select HAVE_ARM_ARCH_TIMER | 20 | select HAVE_ARM_ARCH_TIMER |
23 | select PINCTRL | 21 | select PINCTRL |
24 | help | 22 | help |
25 | This enables support for systems based on Broadcom mobile SoCs. | 23 | This enables support for systems based on Broadcom mobile SoCs. |
26 | It currently supports the 'BCM281XX' family, which includes | 24 | |
27 | BCM11130, BCM11140, BCM11351, BCM28145 and | 25 | if ARCH_BCM_MOBILE |
28 | BCM28155 variants. | 26 | |
27 | menu "Broadcom Mobile SoC Selection" | ||
28 | |||
29 | config ARCH_BCM_281XX | ||
30 | bool "Broadcom BCM281XX SoC family" | ||
31 | default y | ||
32 | help | ||
33 | Enable support for the the BCM281XX family, which includes | ||
34 | BCM11130, BCM11140, BCM11351, BCM28145 and BCM28155 | ||
35 | variants. | ||
36 | |||
37 | config ARCH_BCM_21664 | ||
38 | bool "Broadcom BCM21664 SoC family" | ||
39 | default y | ||
40 | help | ||
41 | Enable support for the the BCM21664 family, which includes | ||
42 | BCM21663 and BCM21664 variants. | ||
43 | |||
44 | config ARCH_BCM_MOBILE_L2_CACHE | ||
45 | bool "Broadcom mobile SoC level 2 cache support" | ||
46 | depends on (ARCH_BCM_281XX || ARCH_BCM_21664) | ||
47 | default y | ||
48 | select CACHE_L2X0 | ||
49 | select ARCH_BCM_MOBILE_SMC | ||
50 | |||
51 | config ARCH_BCM_MOBILE_SMC | ||
52 | bool | ||
53 | depends on ARCH_BCM_281XX || ARCH_BCM_21664 | ||
54 | |||
55 | endmenu | ||
56 | |||
57 | endif | ||
29 | 58 | ||
30 | config ARCH_BCM2835 | 59 | config ARCH_BCM2835 |
31 | bool "Broadcom BCM2835 family" if ARCH_MULTI_V6 | 60 | bool "Broadcom BCM2835 family" if ARCH_MULTI_V6 |
@@ -33,10 +62,7 @@ config ARCH_BCM2835 | |||
33 | select ARM_AMBA | 62 | select ARM_AMBA |
34 | select ARM_ERRATA_411920 | 63 | select ARM_ERRATA_411920 |
35 | select ARM_TIMER_SP804 | 64 | select ARM_TIMER_SP804 |
36 | select CLKDEV_LOOKUP | ||
37 | select CLKSRC_OF | 65 | select CLKSRC_OF |
38 | select CPU_V6 | ||
39 | select GENERIC_CLOCKEVENTS | ||
40 | select PINCTRL | 66 | select PINCTRL |
41 | select PINCTRL_BCM2835 | 67 | select PINCTRL_BCM2835 |
42 | help | 68 | help |
@@ -45,14 +71,10 @@ config ARCH_BCM2835 | |||
45 | 71 | ||
46 | config ARCH_BCM_5301X | 72 | config ARCH_BCM_5301X |
47 | bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7 | 73 | bool "Broadcom BCM470X / BCM5301X ARM SoC" if ARCH_MULTI_V7 |
48 | depends on MMU | ||
49 | select ARM_GIC | 74 | select ARM_GIC |
50 | select CACHE_L2X0 | 75 | select CACHE_L2X0 |
51 | select HAVE_ARM_SCU if SMP | 76 | select HAVE_ARM_SCU if SMP |
52 | select HAVE_ARM_TWD if SMP | 77 | select HAVE_ARM_TWD if SMP |
53 | select HAVE_SMP | ||
54 | select COMMON_CLK | ||
55 | select GENERIC_CLOCKEVENTS | ||
56 | select ARM_GLOBAL_TIMER | 78 | select ARM_GLOBAL_TIMER |
57 | select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK | 79 | select CLKSRC_ARM_GLOBAL_TIMER_SCHED_CLOCK |
58 | select MIGHT_HAVE_PCI | 80 | select MIGHT_HAVE_PCI |
diff --git a/arch/arm/mach-bcm/Makefile b/arch/arm/mach-bcm/Makefile index a326b28c4406..731292114975 100644 --- a/arch/arm/mach-bcm/Makefile +++ b/arch/arm/mach-bcm/Makefile | |||
@@ -10,10 +10,23 @@ | |||
10 | # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 | # of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 | # GNU General Public License for more details. | 11 | # GNU General Public License for more details. |
12 | 12 | ||
13 | obj-$(CONFIG_ARCH_BCM_MOBILE) := board_bcm281xx.o board_bcm21664.o \ | 13 | # BCM281XX |
14 | bcm_kona_smc.o bcm_kona_smc_asm.o kona.o | 14 | obj-$(CONFIG_ARCH_BCM_281XX) += board_bcm281xx.o |
15 | |||
16 | # BCM21664 | ||
17 | obj-$(CONFIG_ARCH_BCM_21664) += board_bcm21664.o | ||
18 | |||
19 | # BCM281XX and BCM21664 L2 cache control | ||
20 | obj-$(CONFIG_ARCH_BCM_MOBILE_L2_CACHE) += kona_l2_cache.o | ||
21 | |||
22 | # Support for secure monitor traps | ||
23 | obj-$(CONFIG_ARCH_BCM_MOBILE_SMC) += bcm_kona_smc.o | ||
24 | ifeq ($(call as-instr,.arch_extension sec,as_has_sec),as_has_sec) | ||
25 | CFLAGS_bcm_kona_smc.o += -Wa,-march=armv7-a+sec -DREQUIRES_SEC | ||
26 | endif | ||
27 | |||
28 | # BCM2835 | ||
15 | obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o | 29 | obj-$(CONFIG_ARCH_BCM2835) += board_bcm2835.o |
16 | 30 | ||
17 | plus_sec := $(call as-instr,.arch_extension sec,+sec) | 31 | # BCM5301X |
18 | AFLAGS_bcm_kona_smc_asm.o :=-Wa,-march=armv7-a$(plus_sec) | ||
19 | obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o | 32 | obj-$(CONFIG_ARCH_BCM_5301X) += bcm_5301x.o |
diff --git a/arch/arm/mach-bcm/bcm_kona_smc.c b/arch/arm/mach-bcm/bcm_kona_smc.c index 5e31e918f325..a55a7ecf146a 100644 --- a/arch/arm/mach-bcm/bcm_kona_smc.c +++ b/arch/arm/mach-bcm/bcm_kona_smc.c | |||
@@ -21,11 +21,8 @@ | |||
21 | 21 | ||
22 | #include "bcm_kona_smc.h" | 22 | #include "bcm_kona_smc.h" |
23 | 23 | ||
24 | struct secure_bridge_data { | 24 | static u32 bcm_smc_buffer_phys; /* physical address */ |
25 | void __iomem *bounce; /* virtual address */ | 25 | static void __iomem *bcm_smc_buffer; /* virtual address */ |
26 | u32 __iomem buffer_addr; /* physical address */ | ||
27 | int initialized; | ||
28 | } bridge_data; | ||
29 | 26 | ||
30 | struct bcm_kona_smc_data { | 27 | struct bcm_kona_smc_data { |
31 | unsigned service_id; | 28 | unsigned service_id; |
@@ -33,6 +30,7 @@ struct bcm_kona_smc_data { | |||
33 | unsigned arg1; | 30 | unsigned arg1; |
34 | unsigned arg2; | 31 | unsigned arg2; |
35 | unsigned arg3; | 32 | unsigned arg3; |
33 | unsigned result; | ||
36 | }; | 34 | }; |
37 | 35 | ||
38 | static const struct of_device_id bcm_kona_smc_ids[] __initconst = { | 36 | static const struct of_device_id bcm_kona_smc_ids[] __initconst = { |
@@ -41,59 +39,125 @@ static const struct of_device_id bcm_kona_smc_ids[] __initconst = { | |||
41 | {}, | 39 | {}, |
42 | }; | 40 | }; |
43 | 41 | ||
44 | /* Map in the bounce area */ | 42 | /* Map in the args buffer area */ |
45 | int __init bcm_kona_smc_init(void) | 43 | int __init bcm_kona_smc_init(void) |
46 | { | 44 | { |
47 | struct device_node *node; | 45 | struct device_node *node; |
46 | const __be32 *prop_val; | ||
47 | u64 prop_size = 0; | ||
48 | unsigned long buffer_size; | ||
49 | u32 buffer_phys; | ||
48 | 50 | ||
49 | /* Read buffer addr and size from the device tree node */ | 51 | /* Read buffer addr and size from the device tree node */ |
50 | node = of_find_matching_node(NULL, bcm_kona_smc_ids); | 52 | node = of_find_matching_node(NULL, bcm_kona_smc_ids); |
51 | if (!node) | 53 | if (!node) |
52 | return -ENODEV; | 54 | return -ENODEV; |
53 | 55 | ||
54 | /* Don't care about size or flags of the DT node */ | 56 | prop_val = of_get_address(node, 0, &prop_size, NULL); |
55 | bridge_data.buffer_addr = | 57 | if (!prop_val) |
56 | be32_to_cpu(*of_get_address(node, 0, NULL, NULL)); | 58 | return -EINVAL; |
57 | BUG_ON(!bridge_data.buffer_addr); | ||
58 | 59 | ||
59 | bridge_data.bounce = of_iomap(node, 0); | 60 | /* We assume space for four 32-bit arguments */ |
60 | BUG_ON(!bridge_data.bounce); | 61 | if (prop_size < 4 * sizeof(u32) || prop_size > (u64)ULONG_MAX) |
62 | return -EINVAL; | ||
63 | buffer_size = (unsigned long)prop_size; | ||
61 | 64 | ||
62 | bridge_data.initialized = 1; | 65 | buffer_phys = be32_to_cpup(prop_val); |
66 | if (!buffer_phys) | ||
67 | return -EINVAL; | ||
68 | |||
69 | bcm_smc_buffer = ioremap(buffer_phys, buffer_size); | ||
70 | if (!bcm_smc_buffer) | ||
71 | return -ENOMEM; | ||
72 | bcm_smc_buffer_phys = buffer_phys; | ||
63 | 73 | ||
64 | pr_info("Kona Secure API initialized\n"); | 74 | pr_info("Kona Secure API initialized\n"); |
65 | 75 | ||
66 | return 0; | 76 | return 0; |
67 | } | 77 | } |
68 | 78 | ||
79 | /* | ||
80 | * int bcm_kona_do_smc(u32 service_id, u32 buffer_addr) | ||
81 | * | ||
82 | * Only core 0 can run the secure monitor code. If an "smc" request | ||
83 | * is initiated on a different core it must be redirected to core 0 | ||
84 | * for execution. We rely on the caller to handle this. | ||
85 | * | ||
86 | * Each "smc" request supplies a service id and the address of a | ||
87 | * buffer containing parameters related to the service to be | ||
88 | * performed. A flags value defines the behavior of the level 2 | ||
89 | * cache and interrupt handling while the secure monitor executes. | ||
90 | * | ||
91 | * Parameters to the "smc" request are passed in r4-r6 as follows: | ||
92 | * r4 service id | ||
93 | * r5 flags (SEC_ROM_*) | ||
94 | * r6 physical address of buffer with other parameters | ||
95 | * | ||
96 | * Execution of an "smc" request produces two distinct results. | ||
97 | * | ||
98 | * First, the secure monitor call itself (regardless of the specific | ||
99 | * service request) can succeed, or can produce an error. When an | ||
100 | * "smc" request completes this value is found in r12; it should | ||
101 | * always be SEC_EXIT_NORMAL. | ||
102 | * | ||
103 | * In addition, the particular service performed produces a result. | ||
104 | * The values that should be expected depend on the service. We | ||
105 | * therefore return this value to the caller, so it can handle the | ||
106 | * request result appropriately. This result value is found in r0 | ||
107 | * when the "smc" request completes. | ||
108 | */ | ||
109 | static int bcm_kona_do_smc(u32 service_id, u32 buffer_phys) | ||
110 | { | ||
111 | register u32 ip asm("ip"); /* Also called r12 */ | ||
112 | register u32 r0 asm("r0"); | ||
113 | register u32 r4 asm("r4"); | ||
114 | register u32 r5 asm("r5"); | ||
115 | register u32 r6 asm("r6"); | ||
116 | |||
117 | r4 = service_id; | ||
118 | r5 = 0x3; /* Keep IRQ and FIQ off in SM */ | ||
119 | r6 = buffer_phys; | ||
120 | |||
121 | asm volatile ( | ||
122 | /* Make sure we got the registers we want */ | ||
123 | __asmeq("%0", "ip") | ||
124 | __asmeq("%1", "r0") | ||
125 | __asmeq("%2", "r4") | ||
126 | __asmeq("%3", "r5") | ||
127 | __asmeq("%4", "r6") | ||
128 | #ifdef REQUIRES_SEC | ||
129 | ".arch_extension sec\n" | ||
130 | #endif | ||
131 | " smc #0\n" | ||
132 | : "=r" (ip), "=r" (r0) | ||
133 | : "r" (r4), "r" (r5), "r" (r6) | ||
134 | : "r1", "r2", "r3", "r7", "lr"); | ||
135 | |||
136 | BUG_ON(ip != SEC_EXIT_NORMAL); | ||
137 | |||
138 | return r0; | ||
139 | } | ||
140 | |||
69 | /* __bcm_kona_smc() should only run on CPU 0, with pre-emption disabled */ | 141 | /* __bcm_kona_smc() should only run on CPU 0, with pre-emption disabled */ |
70 | static void __bcm_kona_smc(void *info) | 142 | static void __bcm_kona_smc(void *info) |
71 | { | 143 | { |
72 | struct bcm_kona_smc_data *data = info; | 144 | struct bcm_kona_smc_data *data = info; |
73 | u32 *args = bridge_data.bounce; | 145 | u32 *args = bcm_smc_buffer; |
74 | int rc = 0; | ||
75 | 146 | ||
76 | /* Must run on CPU 0 */ | ||
77 | BUG_ON(smp_processor_id() != 0); | 147 | BUG_ON(smp_processor_id() != 0); |
148 | BUG_ON(!args); | ||
78 | 149 | ||
79 | /* Check map in the bounce area */ | 150 | /* Copy the four 32 bit argument values into the bounce area */ |
80 | BUG_ON(!bridge_data.initialized); | 151 | writel_relaxed(data->arg0, args++); |
81 | 152 | writel_relaxed(data->arg1, args++); | |
82 | /* Copy one 32 bit word into the bounce area */ | 153 | writel_relaxed(data->arg2, args++); |
83 | args[0] = data->arg0; | 154 | writel(data->arg3, args); |
84 | args[1] = data->arg1; | ||
85 | args[2] = data->arg2; | ||
86 | args[3] = data->arg3; | ||
87 | 155 | ||
88 | /* Flush caches for input data passed to Secure Monitor */ | 156 | /* Flush caches for input data passed to Secure Monitor */ |
89 | if (data->service_id != SSAPI_BRCM_START_VC_CORE) | 157 | flush_cache_all(); |
90 | flush_cache_all(); | ||
91 | |||
92 | /* Trap into Secure Monitor */ | ||
93 | rc = bcm_kona_smc_asm(data->service_id, bridge_data.buffer_addr); | ||
94 | 158 | ||
95 | if (rc != SEC_ROM_RET_OK) | 159 | /* Trap into Secure Monitor and record the request result */ |
96 | pr_err("Secure Monitor call failed (0x%x)!\n", rc); | 160 | data->result = bcm_kona_do_smc(data->service_id, bcm_smc_buffer_phys); |
97 | } | 161 | } |
98 | 162 | ||
99 | unsigned bcm_kona_smc(unsigned service_id, unsigned arg0, unsigned arg1, | 163 | unsigned bcm_kona_smc(unsigned service_id, unsigned arg0, unsigned arg1, |
@@ -106,17 +170,13 @@ unsigned bcm_kona_smc(unsigned service_id, unsigned arg0, unsigned arg1, | |||
106 | data.arg1 = arg1; | 170 | data.arg1 = arg1; |
107 | data.arg2 = arg2; | 171 | data.arg2 = arg2; |
108 | data.arg3 = arg3; | 172 | data.arg3 = arg3; |
173 | data.result = 0; | ||
109 | 174 | ||
110 | /* | 175 | /* |
111 | * Due to a limitation of the secure monitor, we must use the SMP | 176 | * Due to a limitation of the secure monitor, we must use the SMP |
112 | * infrastructure to forward all secure monitor calls to Core 0. | 177 | * infrastructure to forward all secure monitor calls to Core 0. |
113 | */ | 178 | */ |
114 | if (get_cpu() != 0) | 179 | smp_call_function_single(0, __bcm_kona_smc, &data, 1); |
115 | smp_call_function_single(0, __bcm_kona_smc, (void *)&data, 1); | ||
116 | else | ||
117 | __bcm_kona_smc(&data); | ||
118 | 180 | ||
119 | put_cpu(); | 181 | return data.result; |
120 | |||
121 | return 0; | ||
122 | } | 182 | } |
diff --git a/arch/arm/mach-bcm/bcm_kona_smc.h b/arch/arm/mach-bcm/bcm_kona_smc.h index d098a7e76744..2e29ec67e414 100644 --- a/arch/arm/mach-bcm/bcm_kona_smc.h +++ b/arch/arm/mach-bcm/bcm_kona_smc.h | |||
@@ -15,55 +15,12 @@ | |||
15 | #define BCM_KONA_SMC_H | 15 | #define BCM_KONA_SMC_H |
16 | 16 | ||
17 | #include <linux/types.h> | 17 | #include <linux/types.h> |
18 | #define FLAGS (SEC_ROM_ICACHE_ENABLE_MASK | SEC_ROM_DCACHE_ENABLE_MASK | \ | ||
19 | SEC_ROM_IRQ_ENABLE_MASK | SEC_ROM_FIQ_ENABLE_MASK) | ||
20 | 18 | ||
21 | /*! | 19 | /* Broadcom Secure Service API service IDs, return codes, and exit codes */ |
22 | * Definitions for IRQ & FIQ Mask for ARM | 20 | #define SSAPI_ENABLE_L2_CACHE 0x01000002 |
23 | */ | ||
24 | |||
25 | #define FIQ_IRQ_MASK 0xC0 | ||
26 | #define FIQ_MASK 0x40 | ||
27 | #define IRQ_MASK 0x80 | ||
28 | |||
29 | /*! | ||
30 | * Secure Mode FLAGs | ||
31 | */ | ||
32 | |||
33 | /* When set, enables ICache within the secure mode */ | ||
34 | #define SEC_ROM_ICACHE_ENABLE_MASK 0x00000001 | ||
35 | |||
36 | /* When set, enables DCache within the secure mode */ | ||
37 | #define SEC_ROM_DCACHE_ENABLE_MASK 0x00000002 | ||
38 | |||
39 | /* When set, enables IRQ within the secure mode */ | ||
40 | #define SEC_ROM_IRQ_ENABLE_MASK 0x00000004 | ||
41 | |||
42 | /* When set, enables FIQ within the secure mode */ | ||
43 | #define SEC_ROM_FIQ_ENABLE_MASK 0x00000008 | ||
44 | |||
45 | /* When set, enables Unified L2 cache within the secure mode */ | ||
46 | #define SEC_ROM_UL2_CACHE_ENABLE_MASK 0x00000010 | ||
47 | |||
48 | /* Broadcom Secure Service API Service IDs */ | ||
49 | #define SSAPI_DORMANT_ENTRY_SERV 0x01000000 | ||
50 | #define SSAPI_PUBLIC_OTP_SERV 0x01000001 | ||
51 | #define SSAPI_ENABLE_L2_CACHE 0x01000002 | ||
52 | #define SSAPI_DISABLE_L2_CACHE 0x01000003 | ||
53 | #define SSAPI_WRITE_SCU_STATUS 0x01000004 | ||
54 | #define SSAPI_WRITE_PWR_GATE 0x01000005 | ||
55 | |||
56 | /* Broadcom Secure Service API Return Codes */ | ||
57 | #define SEC_ROM_RET_OK 0x00000001 | 21 | #define SEC_ROM_RET_OK 0x00000001 |
58 | #define SEC_ROM_RET_FAIL 0x00000009 | ||
59 | |||
60 | #define SSAPI_RET_FROM_INT_SERV 0x4 | ||
61 | #define SEC_EXIT_NORMAL 0x1 | 22 | #define SEC_EXIT_NORMAL 0x1 |
62 | 23 | ||
63 | #define SSAPI_ROW_AES 0x0E000006 | ||
64 | #define SSAPI_BRCM_START_VC_CORE 0x0E000008 | ||
65 | |||
66 | #ifndef __ASSEMBLY__ | ||
67 | extern int __init bcm_kona_smc_init(void); | 24 | extern int __init bcm_kona_smc_init(void); |
68 | 25 | ||
69 | extern unsigned bcm_kona_smc(unsigned service_id, | 26 | extern unsigned bcm_kona_smc(unsigned service_id, |
@@ -72,9 +29,4 @@ extern unsigned bcm_kona_smc(unsigned service_id, | |||
72 | unsigned arg2, | 29 | unsigned arg2, |
73 | unsigned arg3); | 30 | unsigned arg3); |
74 | 31 | ||
75 | extern int bcm_kona_smc_asm(u32 service_id, | ||
76 | u32 buffer_addr); | ||
77 | |||
78 | #endif /* __ASSEMBLY__ */ | ||
79 | |||
80 | #endif /* BCM_KONA_SMC_H */ | 32 | #endif /* BCM_KONA_SMC_H */ |
diff --git a/arch/arm/mach-bcm/bcm_kona_smc_asm.S b/arch/arm/mach-bcm/bcm_kona_smc_asm.S deleted file mode 100644 index a1608480d60d..000000000000 --- a/arch/arm/mach-bcm/bcm_kona_smc_asm.S +++ /dev/null | |||
@@ -1,41 +0,0 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2013 Broadcom Corporation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or | ||
5 | * modify it under the terms of the GNU General Public License as | ||
6 | * published by the Free Software Foundation version 2. | ||
7 | * | ||
8 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any | ||
9 | * kind, whether express or implied; without even the implied warranty | ||
10 | * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
11 | * GNU General Public License for more details. | ||
12 | */ | ||
13 | |||
14 | #include <linux/linkage.h> | ||
15 | #include "bcm_kona_smc.h" | ||
16 | |||
17 | /* | ||
18 | * int bcm_kona_smc_asm(u32 service_id, u32 buffer_addr) | ||
19 | */ | ||
20 | |||
21 | ENTRY(bcm_kona_smc_asm) | ||
22 | stmfd sp!, {r4-r12, lr} | ||
23 | mov r4, r0 @ service_id | ||
24 | mov r5, #3 @ Keep IRQ and FIQ off in SM | ||
25 | /* | ||
26 | * Since interrupts are disabled in the open mode, we must keep | ||
27 | * interrupts disabled in secure mode by setting R5=0x3. If interrupts | ||
28 | * are enabled in open mode, we can set R5=0x0 to allow interrupts in | ||
29 | * secure mode. If we did this, the secure monitor would return back | ||
30 | * control to the open mode to handle the interrupt prior to completing | ||
31 | * the secure service. If this happened, R12 would not be | ||
32 | * SEC_EXIT_NORMAL and we would need to call SMC again after resetting | ||
33 | * R5 (it gets clobbered by the secure monitor) and setting R4 to | ||
34 | * SSAPI_RET_FROM_INT_SERV to indicate that we want the secure monitor | ||
35 | * to finish up the previous uncompleted secure service. | ||
36 | */ | ||
37 | mov r6, r1 @ buffer_addr | ||
38 | smc #0 | ||
39 | /* Check r12 for SEC_EXIT_NORMAL here if interrupts are enabled */ | ||
40 | ldmfd sp!, {r4-r12, pc} | ||
41 | ENDPROC(bcm_kona_smc_asm) | ||
diff --git a/arch/arm/mach-bcm/board_bcm21664.c b/arch/arm/mach-bcm/board_bcm21664.c index acc1573fd005..f0521cc0640d 100644 --- a/arch/arm/mach-bcm/board_bcm21664.c +++ b/arch/arm/mach-bcm/board_bcm21664.c | |||
@@ -11,14 +11,13 @@ | |||
11 | * GNU General Public License for more details. | 11 | * GNU General Public License for more details. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/clocksource.h> | ||
15 | #include <linux/of_address.h> | 14 | #include <linux/of_address.h> |
16 | #include <linux/of_platform.h> | 15 | #include <linux/of_platform.h> |
16 | #include <linux/io.h> | ||
17 | 17 | ||
18 | #include <asm/mach/arch.h> | 18 | #include <asm/mach/arch.h> |
19 | 19 | ||
20 | #include "bcm_kona_smc.h" | 20 | #include "kona_l2_cache.h" |
21 | #include "kona.h" | ||
22 | 21 | ||
23 | #define RSTMGR_DT_STRING "brcm,bcm21664-resetmgr" | 22 | #define RSTMGR_DT_STRING "brcm,bcm21664-resetmgr" |
24 | 23 | ||
diff --git a/arch/arm/mach-bcm/board_bcm281xx.c b/arch/arm/mach-bcm/board_bcm281xx.c index 6be54c10f8cb..1ac59fc0cb15 100644 --- a/arch/arm/mach-bcm/board_bcm281xx.c +++ b/arch/arm/mach-bcm/board_bcm281xx.c | |||
@@ -17,7 +17,7 @@ | |||
17 | 17 | ||
18 | #include <asm/mach/arch.h> | 18 | #include <asm/mach/arch.h> |
19 | 19 | ||
20 | #include "kona.h" | 20 | #include "kona_l2_cache.h" |
21 | 21 | ||
22 | #define SECWDOG_OFFSET 0x00000000 | 22 | #define SECWDOG_OFFSET 0x00000000 |
23 | #define SECWDOG_RESERVED_MASK 0xe2000000 | 23 | #define SECWDOG_RESERVED_MASK 0xe2000000 |
diff --git a/arch/arm/mach-bcm/kona.c b/arch/arm/mach-bcm/kona_l2_cache.c index 768bc2837bf5..b31970377c20 100644 --- a/arch/arm/mach-bcm/kona.c +++ b/arch/arm/mach-bcm/kona_l2_cache.c | |||
@@ -11,19 +11,18 @@ | |||
11 | * GNU General Public License for more details. | 11 | * GNU General Public License for more details. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/of_platform.h> | 14 | |
15 | #include <linux/init.h> | ||
16 | #include <linux/printk.h> | ||
15 | #include <asm/hardware/cache-l2x0.h> | 17 | #include <asm/hardware/cache-l2x0.h> |
16 | 18 | ||
17 | #include "bcm_kona_smc.h" | 19 | #include "bcm_kona_smc.h" |
18 | #include "kona.h" | ||
19 | 20 | ||
20 | void __init kona_l2_cache_init(void) | 21 | void __init kona_l2_cache_init(void) |
21 | { | 22 | { |
23 | unsigned int result; | ||
22 | int ret; | 24 | int ret; |
23 | 25 | ||
24 | if (!IS_ENABLED(CONFIG_CACHE_L2X0)) | ||
25 | return; | ||
26 | |||
27 | ret = bcm_kona_smc_init(); | 26 | ret = bcm_kona_smc_init(); |
28 | if (ret) { | 27 | if (ret) { |
29 | pr_info("Secure API not available (%d). Skipping L2 init.\n", | 28 | pr_info("Secure API not available (%d). Skipping L2 init.\n", |
@@ -31,7 +30,12 @@ void __init kona_l2_cache_init(void) | |||
31 | return; | 30 | return; |
32 | } | 31 | } |
33 | 32 | ||
34 | bcm_kona_smc(SSAPI_ENABLE_L2_CACHE, 0, 0, 0, 0); | 33 | result = bcm_kona_smc(SSAPI_ENABLE_L2_CACHE, 0, 0, 0, 0); |
34 | if (result != SEC_ROM_RET_OK) { | ||
35 | pr_err("Secure Monitor call failed (%u)! Skipping L2 init.\n", | ||
36 | result); | ||
37 | return; | ||
38 | } | ||
35 | 39 | ||
36 | /* | 40 | /* |
37 | * The aux_val and aux_mask have no effect since L2 cache is already | 41 | * The aux_val and aux_mask have no effect since L2 cache is already |
diff --git a/arch/arm/mach-bcm/kona.h b/arch/arm/mach-bcm/kona_l2_cache.h index 3a7a017c29cd..46f84a95ab1c 100644 --- a/arch/arm/mach-bcm/kona.h +++ b/arch/arm/mach-bcm/kona_l2_cache.h | |||
@@ -11,4 +11,8 @@ | |||
11 | * GNU General Public License for more details. | 11 | * GNU General Public License for more details. |
12 | */ | 12 | */ |
13 | 13 | ||
14 | void __init kona_l2_cache_init(void); | 14 | #ifdef CONFIG_ARCH_BCM_MOBILE_L2_CACHE |
15 | void kona_l2_cache_init(void); | ||
16 | #else | ||
17 | #define kona_l2_cache_init() ((void)0) | ||
18 | #endif | ||
diff --git a/arch/arm/mach-mvebu/Kconfig b/arch/arm/mach-mvebu/Kconfig index 3f73eecbcfb0..bfc5af18e483 100644 --- a/arch/arm/mach-mvebu/Kconfig +++ b/arch/arm/mach-mvebu/Kconfig | |||
@@ -3,7 +3,6 @@ config ARCH_MVEBU | |||
3 | select ARCH_SUPPORTS_BIG_ENDIAN | 3 | select ARCH_SUPPORTS_BIG_ENDIAN |
4 | select CLKSRC_MMIO | 4 | select CLKSRC_MMIO |
5 | select GENERIC_IRQ_CHIP | 5 | select GENERIC_IRQ_CHIP |
6 | select IRQ_DOMAIN | ||
7 | select PINCTRL | 6 | select PINCTRL |
8 | select PLAT_ORION | 7 | select PLAT_ORION |
9 | select MVEBU_MBUS | 8 | select MVEBU_MBUS |
@@ -11,7 +10,6 @@ config ARCH_MVEBU | |||
11 | select ARCH_REQUIRE_GPIOLIB | 10 | select ARCH_REQUIRE_GPIOLIB |
12 | select MIGHT_HAVE_PCI | 11 | select MIGHT_HAVE_PCI |
13 | select PCI_QUIRKS if PCI | 12 | select PCI_QUIRKS if PCI |
14 | select OF_ADDRESS_PCI | ||
15 | 13 | ||
16 | if ARCH_MVEBU | 14 | if ARCH_MVEBU |
17 | 15 | ||
@@ -38,7 +36,6 @@ config MACH_ARMADA_375 | |||
38 | select ARM_ERRATA_753970 | 36 | select ARM_ERRATA_753970 |
39 | select ARM_GIC | 37 | select ARM_GIC |
40 | select ARMADA_375_CLK | 38 | select ARMADA_375_CLK |
41 | select CPU_V7 | ||
42 | select MACH_MVEBU_V7 | 39 | select MACH_MVEBU_V7 |
43 | select PINCTRL_ARMADA_375 | 40 | select PINCTRL_ARMADA_375 |
44 | help | 41 | help |
@@ -51,7 +48,6 @@ config MACH_ARMADA_38X | |||
51 | select ARM_ERRATA_753970 | 48 | select ARM_ERRATA_753970 |
52 | select ARM_GIC | 49 | select ARM_GIC |
53 | select ARMADA_38X_CLK | 50 | select ARMADA_38X_CLK |
54 | select CPU_V7 | ||
55 | select MACH_MVEBU_V7 | 51 | select MACH_MVEBU_V7 |
56 | select PINCTRL_ARMADA_38X | 52 | select PINCTRL_ARMADA_38X |
57 | help | 53 | help |
@@ -86,13 +82,11 @@ config MACH_KIRKWOOD | |||
86 | select ARCH_REQUIRE_GPIOLIB | 82 | select ARCH_REQUIRE_GPIOLIB |
87 | select CPU_FEROCEON | 83 | select CPU_FEROCEON |
88 | select KIRKWOOD_CLK | 84 | select KIRKWOOD_CLK |
89 | select OF_IRQ | ||
90 | select ORION_IRQCHIP | 85 | select ORION_IRQCHIP |
91 | select ORION_TIMER | 86 | select ORION_TIMER |
92 | select PCI | 87 | select PCI |
93 | select PCI_QUIRKS | 88 | select PCI_QUIRKS |
94 | select PINCTRL_KIRKWOOD | 89 | select PINCTRL_KIRKWOOD |
95 | select USE_OF | ||
96 | help | 90 | help |
97 | Say 'Y' here if you want your kernel to support boards based | 91 | Say 'Y' here if you want your kernel to support boards based |
98 | on the Marvell Kirkwood device tree. | 92 | on the Marvell Kirkwood device tree. |
diff --git a/arch/arm/mach-omap2/board-flash.c b/arch/arm/mach-omap2/board-flash.c index ac82512b9c8c..84cc1482e584 100644 --- a/arch/arm/mach-omap2/board-flash.c +++ b/arch/arm/mach-omap2/board-flash.c | |||
@@ -160,13 +160,13 @@ static u8 get_gpmc0_type(void) | |||
160 | if (!fpga_map_addr) | 160 | if (!fpga_map_addr) |
161 | return -ENOMEM; | 161 | return -ENOMEM; |
162 | 162 | ||
163 | if (!(__raw_readw(fpga_map_addr + REG_FPGA_REV))) | 163 | if (!(readw_relaxed(fpga_map_addr + REG_FPGA_REV))) |
164 | /* we dont have an DEBUG FPGA??? */ | 164 | /* we dont have an DEBUG FPGA??? */ |
165 | /* Depend on #defines!! default to strata boot return param */ | 165 | /* Depend on #defines!! default to strata boot return param */ |
166 | goto unmap; | 166 | goto unmap; |
167 | 167 | ||
168 | /* S8-DIP-OFF = 1, S8-DIP-ON = 0 */ | 168 | /* S8-DIP-OFF = 1, S8-DIP-ON = 0 */ |
169 | cs = __raw_readw(fpga_map_addr + REG_FPGA_DIP_SWITCH_INPUT2) & 0xf; | 169 | cs = readw_relaxed(fpga_map_addr + REG_FPGA_DIP_SWITCH_INPUT2) & 0xf; |
170 | 170 | ||
171 | /* ES2.0 SDP's onwards 4 dip switches are provided for CS */ | 171 | /* ES2.0 SDP's onwards 4 dip switches are provided for CS */ |
172 | if (omap_rev() >= OMAP3430_REV_ES1_0) | 172 | if (omap_rev() >= OMAP3430_REV_ES1_0) |
diff --git a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c index 3ff32543493c..59cf310bc1e9 100644 --- a/arch/arm/mach-omap2/clkt2xxx_dpllcore.c +++ b/arch/arm/mach-omap2/clkt2xxx_dpllcore.c | |||
@@ -138,7 +138,7 @@ int omap2_reprogram_dpllcore(struct clk_hw *hw, unsigned long rate, | |||
138 | if (!dd) | 138 | if (!dd) |
139 | return -EINVAL; | 139 | return -EINVAL; |
140 | 140 | ||
141 | tmpset.cm_clksel1_pll = __raw_readl(dd->mult_div1_reg); | 141 | tmpset.cm_clksel1_pll = readl_relaxed(dd->mult_div1_reg); |
142 | tmpset.cm_clksel1_pll &= ~(dd->mult_mask | | 142 | tmpset.cm_clksel1_pll &= ~(dd->mult_mask | |
143 | dd->div1_mask); | 143 | dd->div1_mask); |
144 | div = ((curr_prcm_set->xtal_speed / 1000000) - 1); | 144 | div = ((curr_prcm_set->xtal_speed / 1000000) - 1); |
diff --git a/arch/arm/mach-omap2/clkt2xxx_osc.c b/arch/arm/mach-omap2/clkt2xxx_osc.c index 19f54d433490..0717dff1bc04 100644 --- a/arch/arm/mach-omap2/clkt2xxx_osc.c +++ b/arch/arm/mach-omap2/clkt2xxx_osc.c | |||
@@ -39,9 +39,9 @@ int omap2_enable_osc_ck(struct clk_hw *clk) | |||
39 | { | 39 | { |
40 | u32 pcc; | 40 | u32 pcc; |
41 | 41 | ||
42 | pcc = __raw_readl(prcm_clksrc_ctrl); | 42 | pcc = readl_relaxed(prcm_clksrc_ctrl); |
43 | 43 | ||
44 | __raw_writel(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl); | 44 | writel_relaxed(pcc & ~OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl); |
45 | 45 | ||
46 | return 0; | 46 | return 0; |
47 | } | 47 | } |
@@ -57,9 +57,9 @@ void omap2_disable_osc_ck(struct clk_hw *clk) | |||
57 | { | 57 | { |
58 | u32 pcc; | 58 | u32 pcc; |
59 | 59 | ||
60 | pcc = __raw_readl(prcm_clksrc_ctrl); | 60 | pcc = readl_relaxed(prcm_clksrc_ctrl); |
61 | 61 | ||
62 | __raw_writel(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl); | 62 | writel_relaxed(pcc | OMAP_AUTOEXTCLKMODE_MASK, prcm_clksrc_ctrl); |
63 | } | 63 | } |
64 | 64 | ||
65 | unsigned long omap2_osc_clk_recalc(struct clk_hw *clk, | 65 | unsigned long omap2_osc_clk_recalc(struct clk_hw *clk, |
diff --git a/arch/arm/mach-omap2/clkt2xxx_sys.c b/arch/arm/mach-omap2/clkt2xxx_sys.c index f467d072cd02..58dd3a9b726c 100644 --- a/arch/arm/mach-omap2/clkt2xxx_sys.c +++ b/arch/arm/mach-omap2/clkt2xxx_sys.c | |||
@@ -33,7 +33,7 @@ u32 omap2xxx_get_sysclkdiv(void) | |||
33 | { | 33 | { |
34 | u32 div; | 34 | u32 div; |
35 | 35 | ||
36 | div = __raw_readl(prcm_clksrc_ctrl); | 36 | div = readl_relaxed(prcm_clksrc_ctrl); |
37 | div &= OMAP_SYSCLKDIV_MASK; | 37 | div &= OMAP_SYSCLKDIV_MASK; |
38 | div >>= OMAP_SYSCLKDIV_SHIFT; | 38 | div >>= OMAP_SYSCLKDIV_SHIFT; |
39 | 39 | ||
diff --git a/arch/arm/mach-omap2/clockdomain.h b/arch/arm/mach-omap2/clockdomain.h index f17f00697cc0..82c37b1becc4 100644 --- a/arch/arm/mach-omap2/clockdomain.h +++ b/arch/arm/mach-omap2/clockdomain.h | |||
@@ -18,7 +18,6 @@ | |||
18 | 18 | ||
19 | #include "powerdomain.h" | 19 | #include "powerdomain.h" |
20 | #include "clock.h" | 20 | #include "clock.h" |
21 | #include "omap_hwmod.h" | ||
22 | 21 | ||
23 | /* | 22 | /* |
24 | * Clockdomain flags | 23 | * Clockdomain flags |
@@ -98,6 +97,8 @@ struct clkdm_dep { | |||
98 | /* Possible flags for struct clockdomain._flags */ | 97 | /* Possible flags for struct clockdomain._flags */ |
99 | #define _CLKDM_FLAG_HWSUP_ENABLED BIT(0) | 98 | #define _CLKDM_FLAG_HWSUP_ENABLED BIT(0) |
100 | 99 | ||
100 | struct omap_hwmod; | ||
101 | |||
101 | /** | 102 | /** |
102 | * struct clockdomain - OMAP clockdomain | 103 | * struct clockdomain - OMAP clockdomain |
103 | * @name: clockdomain name | 104 | * @name: clockdomain name |
diff --git a/arch/arm/mach-omap2/cm2xxx.c b/arch/arm/mach-omap2/cm2xxx.c index ce25abbcffae..8be6ea50c092 100644 --- a/arch/arm/mach-omap2/cm2xxx.c +++ b/arch/arm/mach-omap2/cm2xxx.c | |||
@@ -18,9 +18,6 @@ | |||
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | 20 | ||
21 | #include "soc.h" | ||
22 | #include "iomap.h" | ||
23 | #include "common.h" | ||
24 | #include "prm2xxx.h" | 21 | #include "prm2xxx.h" |
25 | #include "cm.h" | 22 | #include "cm.h" |
26 | #include "cm2xxx.h" | 23 | #include "cm2xxx.h" |
@@ -390,7 +387,7 @@ void omap2xxx_cm_set_mod_dividers(u32 mpu, u32 dsp, u32 gfx, u32 core, u32 mdm) | |||
390 | tmp = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & | 387 | tmp = omap2_cm_read_mod_reg(CORE_MOD, CM_CLKSEL1) & |
391 | OMAP24XX_CLKSEL_DSS2_MASK; | 388 | OMAP24XX_CLKSEL_DSS2_MASK; |
392 | omap2_cm_write_mod_reg(core | tmp, CORE_MOD, CM_CLKSEL1); | 389 | omap2_cm_write_mod_reg(core | tmp, CORE_MOD, CM_CLKSEL1); |
393 | if (cpu_is_omap2430()) | 390 | if (mdm) |
394 | omap2_cm_write_mod_reg(mdm, OMAP2430_MDM_MOD, CM_CLKSEL); | 391 | omap2_cm_write_mod_reg(mdm, OMAP2430_MDM_MOD, CM_CLKSEL); |
395 | } | 392 | } |
396 | 393 | ||
@@ -405,19 +402,11 @@ static struct cm_ll_data omap2xxx_cm_ll_data = { | |||
405 | 402 | ||
406 | int __init omap2xxx_cm_init(void) | 403 | int __init omap2xxx_cm_init(void) |
407 | { | 404 | { |
408 | if (!cpu_is_omap24xx()) | ||
409 | return 0; | ||
410 | |||
411 | return cm_register(&omap2xxx_cm_ll_data); | 405 | return cm_register(&omap2xxx_cm_ll_data); |
412 | } | 406 | } |
413 | 407 | ||
414 | static void __exit omap2xxx_cm_exit(void) | 408 | static void __exit omap2xxx_cm_exit(void) |
415 | { | 409 | { |
416 | if (!cpu_is_omap24xx()) | 410 | cm_unregister(&omap2xxx_cm_ll_data); |
417 | return; | ||
418 | |||
419 | /* Should never happen */ | ||
420 | WARN(cm_unregister(&omap2xxx_cm_ll_data), | ||
421 | "%s: cm_ll_data function pointer mismatch\n", __func__); | ||
422 | } | 411 | } |
423 | __exitcall(omap2xxx_cm_exit); | 412 | __exitcall(omap2xxx_cm_exit); |
diff --git a/arch/arm/mach-omap2/cm2xxx_3xxx.h b/arch/arm/mach-omap2/cm2xxx_3xxx.h index bfbd16fe9151..72928a3ce2aa 100644 --- a/arch/arm/mach-omap2/cm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/cm2xxx_3xxx.h | |||
@@ -52,12 +52,12 @@ | |||
52 | 52 | ||
53 | static inline u32 omap2_cm_read_mod_reg(s16 module, u16 idx) | 53 | static inline u32 omap2_cm_read_mod_reg(s16 module, u16 idx) |
54 | { | 54 | { |
55 | return __raw_readl(cm_base + module + idx); | 55 | return readl_relaxed(cm_base + module + idx); |
56 | } | 56 | } |
57 | 57 | ||
58 | static inline void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx) | 58 | static inline void omap2_cm_write_mod_reg(u32 val, s16 module, u16 idx) |
59 | { | 59 | { |
60 | __raw_writel(val, cm_base + module + idx); | 60 | writel_relaxed(val, cm_base + module + idx); |
61 | } | 61 | } |
62 | 62 | ||
63 | /* Read-modify-write a register in a CM module. Caller must lock */ | 63 | /* Read-modify-write a register in a CM module. Caller must lock */ |
diff --git a/arch/arm/mach-omap2/cm33xx.c b/arch/arm/mach-omap2/cm33xx.c index 40a22e5649ae..b3f99e93def0 100644 --- a/arch/arm/mach-omap2/cm33xx.c +++ b/arch/arm/mach-omap2/cm33xx.c | |||
@@ -50,13 +50,13 @@ | |||
50 | /* Read a register in a CM instance */ | 50 | /* Read a register in a CM instance */ |
51 | static inline u32 am33xx_cm_read_reg(u16 inst, u16 idx) | 51 | static inline u32 am33xx_cm_read_reg(u16 inst, u16 idx) |
52 | { | 52 | { |
53 | return __raw_readl(cm_base + inst + idx); | 53 | return readl_relaxed(cm_base + inst + idx); |
54 | } | 54 | } |
55 | 55 | ||
56 | /* Write into a register in a CM */ | 56 | /* Write into a register in a CM */ |
57 | static inline void am33xx_cm_write_reg(u32 val, u16 inst, u16 idx) | 57 | static inline void am33xx_cm_write_reg(u32 val, u16 inst, u16 idx) |
58 | { | 58 | { |
59 | __raw_writel(val, cm_base + inst + idx); | 59 | writel_relaxed(val, cm_base + inst + idx); |
60 | } | 60 | } |
61 | 61 | ||
62 | /* Read-modify-write a register in CM */ | 62 | /* Read-modify-write a register in CM */ |
diff --git a/arch/arm/mach-omap2/cm33xx.h b/arch/arm/mach-omap2/cm33xx.h index cfb8891b0c0e..15a778ce7707 100644 --- a/arch/arm/mach-omap2/cm33xx.h +++ b/arch/arm/mach-omap2/cm33xx.h | |||
@@ -17,11 +17,8 @@ | |||
17 | #ifndef __ARCH_ARM_MACH_OMAP2_CM_33XX_H | 17 | #ifndef __ARCH_ARM_MACH_OMAP2_CM_33XX_H |
18 | #define __ARCH_ARM_MACH_OMAP2_CM_33XX_H | 18 | #define __ARCH_ARM_MACH_OMAP2_CM_33XX_H |
19 | 19 | ||
20 | #include "common.h" | ||
21 | |||
22 | #include "cm.h" | 20 | #include "cm.h" |
23 | #include "cm-regbits-33xx.h" | 21 | #include "cm-regbits-33xx.h" |
24 | #include "iomap.h" | ||
25 | 22 | ||
26 | /* CM base address */ | 23 | /* CM base address */ |
27 | #define AM33XX_CM_BASE 0x44e00000 | 24 | #define AM33XX_CM_BASE 0x44e00000 |
diff --git a/arch/arm/mach-omap2/cm3xxx.c b/arch/arm/mach-omap2/cm3xxx.c index f6f028867bfe..129a4e7f6ef5 100644 --- a/arch/arm/mach-omap2/cm3xxx.c +++ b/arch/arm/mach-omap2/cm3xxx.c | |||
@@ -18,9 +18,6 @@ | |||
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | 20 | ||
21 | #include "soc.h" | ||
22 | #include "iomap.h" | ||
23 | #include "common.h" | ||
24 | #include "prm2xxx_3xxx.h" | 21 | #include "prm2xxx_3xxx.h" |
25 | #include "cm.h" | 22 | #include "cm.h" |
26 | #include "cm3xxx.h" | 23 | #include "cm3xxx.h" |
@@ -388,7 +385,8 @@ void omap3_cm_save_context(void) | |||
388 | omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1); | 385 | omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL1); |
389 | cm_context.iva2_cm_clksel2 = | 386 | cm_context.iva2_cm_clksel2 = |
390 | omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL2); | 387 | omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_CLKSEL2); |
391 | cm_context.cm_sysconfig = __raw_readl(OMAP3430_CM_SYSCONFIG); | 388 | cm_context.cm_sysconfig = |
389 | omap2_cm_read_mod_reg(OCP_MOD, OMAP3430_CM_SYSCONFIG); | ||
392 | cm_context.sgx_cm_clksel = | 390 | cm_context.sgx_cm_clksel = |
393 | omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL); | 391 | omap2_cm_read_mod_reg(OMAP3430ES2_SGX_MOD, CM_CLKSEL); |
394 | cm_context.dss_cm_clksel = | 392 | cm_context.dss_cm_clksel = |
@@ -418,7 +416,8 @@ void omap3_cm_save_context(void) | |||
418 | omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5); | 416 | omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKSEL5); |
419 | cm_context.pll_cm_clken2 = | 417 | cm_context.pll_cm_clken2 = |
420 | omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2); | 418 | omap2_cm_read_mod_reg(PLL_MOD, OMAP3430ES2_CM_CLKEN2); |
421 | cm_context.cm_polctrl = __raw_readl(OMAP3430_CM_POLCTRL); | 419 | cm_context.cm_polctrl = |
420 | omap2_cm_read_mod_reg(OCP_MOD, OMAP3430_CM_POLCTRL); | ||
422 | cm_context.iva2_cm_fclken = | 421 | cm_context.iva2_cm_fclken = |
423 | omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_FCLKEN); | 422 | omap2_cm_read_mod_reg(OMAP3430_IVA2_MOD, CM_FCLKEN); |
424 | cm_context.iva2_cm_clken_pll = | 423 | cm_context.iva2_cm_clken_pll = |
@@ -519,7 +518,8 @@ void omap3_cm_restore_context(void) | |||
519 | CM_CLKSEL1); | 518 | CM_CLKSEL1); |
520 | omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel2, OMAP3430_IVA2_MOD, | 519 | omap2_cm_write_mod_reg(cm_context.iva2_cm_clksel2, OMAP3430_IVA2_MOD, |
521 | CM_CLKSEL2); | 520 | CM_CLKSEL2); |
522 | __raw_writel(cm_context.cm_sysconfig, OMAP3430_CM_SYSCONFIG); | 521 | omap2_cm_write_mod_reg(cm_context.cm_sysconfig, OCP_MOD, |
522 | OMAP3430_CM_SYSCONFIG); | ||
523 | omap2_cm_write_mod_reg(cm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD, | 523 | omap2_cm_write_mod_reg(cm_context.sgx_cm_clksel, OMAP3430ES2_SGX_MOD, |
524 | CM_CLKSEL); | 524 | CM_CLKSEL); |
525 | omap2_cm_write_mod_reg(cm_context.dss_cm_clksel, OMAP3430_DSS_MOD, | 525 | omap2_cm_write_mod_reg(cm_context.dss_cm_clksel, OMAP3430_DSS_MOD, |
@@ -547,7 +547,8 @@ void omap3_cm_restore_context(void) | |||
547 | OMAP3430ES2_CM_CLKSEL5); | 547 | OMAP3430ES2_CM_CLKSEL5); |
548 | omap2_cm_write_mod_reg(cm_context.pll_cm_clken2, PLL_MOD, | 548 | omap2_cm_write_mod_reg(cm_context.pll_cm_clken2, PLL_MOD, |
549 | OMAP3430ES2_CM_CLKEN2); | 549 | OMAP3430ES2_CM_CLKEN2); |
550 | __raw_writel(cm_context.cm_polctrl, OMAP3430_CM_POLCTRL); | 550 | omap2_cm_write_mod_reg(cm_context.cm_polctrl, OCP_MOD, |
551 | OMAP3430_CM_POLCTRL); | ||
551 | omap2_cm_write_mod_reg(cm_context.iva2_cm_fclken, OMAP3430_IVA2_MOD, | 552 | omap2_cm_write_mod_reg(cm_context.iva2_cm_fclken, OMAP3430_IVA2_MOD, |
552 | CM_FCLKEN); | 553 | CM_FCLKEN); |
553 | omap2_cm_write_mod_reg(cm_context.iva2_cm_clken_pll, OMAP3430_IVA2_MOD, | 554 | omap2_cm_write_mod_reg(cm_context.iva2_cm_clken_pll, OMAP3430_IVA2_MOD, |
@@ -669,19 +670,11 @@ static struct cm_ll_data omap3xxx_cm_ll_data = { | |||
669 | 670 | ||
670 | int __init omap3xxx_cm_init(void) | 671 | int __init omap3xxx_cm_init(void) |
671 | { | 672 | { |
672 | if (!cpu_is_omap34xx()) | ||
673 | return 0; | ||
674 | |||
675 | return cm_register(&omap3xxx_cm_ll_data); | 673 | return cm_register(&omap3xxx_cm_ll_data); |
676 | } | 674 | } |
677 | 675 | ||
678 | static void __exit omap3xxx_cm_exit(void) | 676 | static void __exit omap3xxx_cm_exit(void) |
679 | { | 677 | { |
680 | if (!cpu_is_omap34xx()) | 678 | cm_unregister(&omap3xxx_cm_ll_data); |
681 | return; | ||
682 | |||
683 | /* Should never happen */ | ||
684 | WARN(cm_unregister(&omap3xxx_cm_ll_data), | ||
685 | "%s: cm_ll_data function pointer mismatch\n", __func__); | ||
686 | } | 679 | } |
687 | __exitcall(omap3xxx_cm_exit); | 680 | __exitcall(omap3xxx_cm_exit); |
diff --git a/arch/arm/mach-omap2/cm3xxx.h b/arch/arm/mach-omap2/cm3xxx.h index 8224c91b4d7a..7a16b5598127 100644 --- a/arch/arm/mach-omap2/cm3xxx.h +++ b/arch/arm/mach-omap2/cm3xxx.h | |||
@@ -29,9 +29,8 @@ | |||
29 | * These registers appear once per CM module. | 29 | * These registers appear once per CM module. |
30 | */ | 30 | */ |
31 | 31 | ||
32 | #define OMAP3430_CM_REVISION OMAP34XX_CM_REGADDR(OCP_MOD, 0x0000) | 32 | #define OMAP3430_CM_SYSCONFIG 0x0010 |
33 | #define OMAP3430_CM_SYSCONFIG OMAP34XX_CM_REGADDR(OCP_MOD, 0x0010) | 33 | #define OMAP3430_CM_POLCTRL 0x009c |
34 | #define OMAP3430_CM_POLCTRL OMAP34XX_CM_REGADDR(OCP_MOD, 0x009c) | ||
35 | 34 | ||
36 | #define OMAP3_CM_CLKOUT_CTRL_OFFSET 0x0070 | 35 | #define OMAP3_CM_CLKOUT_CTRL_OFFSET 0x0070 |
37 | #define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070) | 36 | #define OMAP3430_CM_CLKOUT_CTRL OMAP_CM_REGADDR(OMAP3430_CCR_MOD, 0x0070) |
diff --git a/arch/arm/mach-omap2/cm44xx.c b/arch/arm/mach-omap2/cm44xx.c index 535d66e2822c..fe5cc7bae489 100644 --- a/arch/arm/mach-omap2/cm44xx.c +++ b/arch/arm/mach-omap2/cm44xx.c | |||
@@ -18,35 +18,32 @@ | |||
18 | #include <linux/err.h> | 18 | #include <linux/err.h> |
19 | #include <linux/io.h> | 19 | #include <linux/io.h> |
20 | 20 | ||
21 | #include "iomap.h" | ||
22 | #include "common.h" | ||
23 | #include "cm.h" | 21 | #include "cm.h" |
24 | #include "cm1_44xx.h" | 22 | #include "cm1_44xx.h" |
25 | #include "cm2_44xx.h" | 23 | #include "cm2_44xx.h" |
26 | #include "cm-regbits-44xx.h" | ||
27 | 24 | ||
28 | /* CM1 hardware module low-level functions */ | 25 | /* CM1 hardware module low-level functions */ |
29 | 26 | ||
30 | /* Read a register in CM1 */ | 27 | /* Read a register in CM1 */ |
31 | u32 omap4_cm1_read_inst_reg(s16 inst, u16 reg) | 28 | u32 omap4_cm1_read_inst_reg(s16 inst, u16 reg) |
32 | { | 29 | { |
33 | return __raw_readl(OMAP44XX_CM1_REGADDR(inst, reg)); | 30 | return readl_relaxed(cm_base + inst + reg); |
34 | } | 31 | } |
35 | 32 | ||
36 | /* Write into a register in CM1 */ | 33 | /* Write into a register in CM1 */ |
37 | void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 reg) | 34 | void omap4_cm1_write_inst_reg(u32 val, s16 inst, u16 reg) |
38 | { | 35 | { |
39 | __raw_writel(val, OMAP44XX_CM1_REGADDR(inst, reg)); | 36 | writel_relaxed(val, cm_base + inst + reg); |
40 | } | 37 | } |
41 | 38 | ||
42 | /* Read a register in CM2 */ | 39 | /* Read a register in CM2 */ |
43 | u32 omap4_cm2_read_inst_reg(s16 inst, u16 reg) | 40 | u32 omap4_cm2_read_inst_reg(s16 inst, u16 reg) |
44 | { | 41 | { |
45 | return __raw_readl(OMAP44XX_CM2_REGADDR(inst, reg)); | 42 | return readl_relaxed(cm2_base + inst + reg); |
46 | } | 43 | } |
47 | 44 | ||
48 | /* Write into a register in CM2 */ | 45 | /* Write into a register in CM2 */ |
49 | void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg) | 46 | void omap4_cm2_write_inst_reg(u32 val, s16 inst, u16 reg) |
50 | { | 47 | { |
51 | __raw_writel(val, OMAP44XX_CM2_REGADDR(inst, reg)); | 48 | writel_relaxed(val, cm2_base + inst + reg); |
52 | } | 49 | } |
diff --git a/arch/arm/mach-omap2/cm_common.c b/arch/arm/mach-omap2/cm_common.c index 40b3b5a84458..8f6c4710877e 100644 --- a/arch/arm/mach-omap2/cm_common.c +++ b/arch/arm/mach-omap2/cm_common.c | |||
@@ -14,11 +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/errno.h> | 16 | #include <linux/errno.h> |
17 | #include <linux/bug.h> | ||
17 | 18 | ||
18 | #include "cm2xxx.h" | 19 | #include "cm2xxx.h" |
19 | #include "cm3xxx.h" | 20 | #include "cm3xxx.h" |
20 | #include "cm44xx.h" | 21 | #include "cm44xx.h" |
21 | #include "common.h" | ||
22 | 22 | ||
23 | /* | 23 | /* |
24 | * cm_ll_data: function pointers to SoC-specific implementations of | 24 | * cm_ll_data: function pointers to SoC-specific implementations of |
diff --git a/arch/arm/mach-omap2/cminst44xx.c b/arch/arm/mach-omap2/cminst44xx.c index f5c4731b6f06..12aca56942c0 100644 --- a/arch/arm/mach-omap2/cminst44xx.c +++ b/arch/arm/mach-omap2/cminst44xx.c | |||
@@ -21,8 +21,6 @@ | |||
21 | #include <linux/err.h> | 21 | #include <linux/err.h> |
22 | #include <linux/io.h> | 22 | #include <linux/io.h> |
23 | 23 | ||
24 | #include "iomap.h" | ||
25 | #include "common.h" | ||
26 | #include "clockdomain.h" | 24 | #include "clockdomain.h" |
27 | #include "cm.h" | 25 | #include "cm.h" |
28 | #include "cm1_44xx.h" | 26 | #include "cm1_44xx.h" |
@@ -30,12 +28,18 @@ | |||
30 | #include "cm44xx.h" | 28 | #include "cm44xx.h" |
31 | #include "cminst44xx.h" | 29 | #include "cminst44xx.h" |
32 | #include "cm-regbits-34xx.h" | 30 | #include "cm-regbits-34xx.h" |
33 | #include "cm-regbits-44xx.h" | ||
34 | #include "prcm44xx.h" | 31 | #include "prcm44xx.h" |
35 | #include "prm44xx.h" | 32 | #include "prm44xx.h" |
36 | #include "prcm_mpu44xx.h" | 33 | #include "prcm_mpu44xx.h" |
37 | #include "prcm-common.h" | 34 | #include "prcm-common.h" |
38 | 35 | ||
36 | #define OMAP4430_IDLEST_SHIFT 16 | ||
37 | #define OMAP4430_IDLEST_MASK (0x3 << 16) | ||
38 | #define OMAP4430_CLKTRCTRL_SHIFT 0 | ||
39 | #define OMAP4430_CLKTRCTRL_MASK (0x3 << 0) | ||
40 | #define OMAP4430_MODULEMODE_SHIFT 0 | ||
41 | #define OMAP4430_MODULEMODE_MASK (0x3 << 0) | ||
42 | |||
39 | /* | 43 | /* |
40 | * CLKCTRL_IDLEST_*: possible values for the CM_*_CLKCTRL.IDLEST bitfield: | 44 | * CLKCTRL_IDLEST_*: possible values for the CM_*_CLKCTRL.IDLEST bitfield: |
41 | * | 45 | * |
@@ -116,7 +120,7 @@ u32 omap4_cminst_read_inst_reg(u8 part, u16 inst, u16 idx) | |||
116 | BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || | 120 | BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || |
117 | part == OMAP4430_INVALID_PRCM_PARTITION || | 121 | part == OMAP4430_INVALID_PRCM_PARTITION || |
118 | !_cm_bases[part]); | 122 | !_cm_bases[part]); |
119 | return __raw_readl(_cm_bases[part] + inst + idx); | 123 | return readl_relaxed(_cm_bases[part] + inst + idx); |
120 | } | 124 | } |
121 | 125 | ||
122 | /* Write into a register in a CM instance */ | 126 | /* Write into a register in a CM instance */ |
@@ -125,7 +129,7 @@ void omap4_cminst_write_inst_reg(u32 val, u8 part, u16 inst, u16 idx) | |||
125 | BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || | 129 | BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || |
126 | part == OMAP4430_INVALID_PRCM_PARTITION || | 130 | part == OMAP4430_INVALID_PRCM_PARTITION || |
127 | !_cm_bases[part]); | 131 | !_cm_bases[part]); |
128 | __raw_writel(val, _cm_bases[part] + inst + idx); | 132 | writel_relaxed(val, _cm_bases[part] + inst + idx); |
129 | } | 133 | } |
130 | 134 | ||
131 | /* Read-modify-write a register in CM1. Caller must lock */ | 135 | /* Read-modify-write a register in CM1. Caller must lock */ |
diff --git a/arch/arm/mach-omap2/control.c b/arch/arm/mach-omap2/control.c index 44bb4d544dcf..751f3549bf6f 100644 --- a/arch/arm/mach-omap2/control.c +++ b/arch/arm/mach-omap2/control.c | |||
@@ -151,32 +151,32 @@ void __iomem *omap_ctrl_base_get(void) | |||
151 | 151 | ||
152 | u8 omap_ctrl_readb(u16 offset) | 152 | u8 omap_ctrl_readb(u16 offset) |
153 | { | 153 | { |
154 | return __raw_readb(OMAP_CTRL_REGADDR(offset)); | 154 | return readb_relaxed(OMAP_CTRL_REGADDR(offset)); |
155 | } | 155 | } |
156 | 156 | ||
157 | u16 omap_ctrl_readw(u16 offset) | 157 | u16 omap_ctrl_readw(u16 offset) |
158 | { | 158 | { |
159 | return __raw_readw(OMAP_CTRL_REGADDR(offset)); | 159 | return readw_relaxed(OMAP_CTRL_REGADDR(offset)); |
160 | } | 160 | } |
161 | 161 | ||
162 | u32 omap_ctrl_readl(u16 offset) | 162 | u32 omap_ctrl_readl(u16 offset) |
163 | { | 163 | { |
164 | return __raw_readl(OMAP_CTRL_REGADDR(offset)); | 164 | return readl_relaxed(OMAP_CTRL_REGADDR(offset)); |
165 | } | 165 | } |
166 | 166 | ||
167 | void omap_ctrl_writeb(u8 val, u16 offset) | 167 | void omap_ctrl_writeb(u8 val, u16 offset) |
168 | { | 168 | { |
169 | __raw_writeb(val, OMAP_CTRL_REGADDR(offset)); | 169 | writeb_relaxed(val, OMAP_CTRL_REGADDR(offset)); |
170 | } | 170 | } |
171 | 171 | ||
172 | void omap_ctrl_writew(u16 val, u16 offset) | 172 | void omap_ctrl_writew(u16 val, u16 offset) |
173 | { | 173 | { |
174 | __raw_writew(val, OMAP_CTRL_REGADDR(offset)); | 174 | writew_relaxed(val, OMAP_CTRL_REGADDR(offset)); |
175 | } | 175 | } |
176 | 176 | ||
177 | void omap_ctrl_writel(u32 val, u16 offset) | 177 | void omap_ctrl_writel(u32 val, u16 offset) |
178 | { | 178 | { |
179 | __raw_writel(val, OMAP_CTRL_REGADDR(offset)); | 179 | writel_relaxed(val, OMAP_CTRL_REGADDR(offset)); |
180 | } | 180 | } |
181 | 181 | ||
182 | /* | 182 | /* |
@@ -188,12 +188,12 @@ void omap_ctrl_writel(u32 val, u16 offset) | |||
188 | 188 | ||
189 | u32 omap4_ctrl_pad_readl(u16 offset) | 189 | u32 omap4_ctrl_pad_readl(u16 offset) |
190 | { | 190 | { |
191 | return __raw_readl(OMAP4_CTRL_PAD_REGADDR(offset)); | 191 | return readl_relaxed(OMAP4_CTRL_PAD_REGADDR(offset)); |
192 | } | 192 | } |
193 | 193 | ||
194 | void omap4_ctrl_pad_writel(u32 val, u16 offset) | 194 | void omap4_ctrl_pad_writel(u32 val, u16 offset) |
195 | { | 195 | { |
196 | __raw_writel(val, OMAP4_CTRL_PAD_REGADDR(offset)); | 196 | writel_relaxed(val, OMAP4_CTRL_PAD_REGADDR(offset)); |
197 | } | 197 | } |
198 | 198 | ||
199 | #ifdef CONFIG_ARCH_OMAP3 | 199 | #ifdef CONFIG_ARCH_OMAP3 |
@@ -222,7 +222,7 @@ void omap3_ctrl_write_boot_mode(u8 bootmode) | |||
222 | * | 222 | * |
223 | * XXX This should use some omap_ctrl_writel()-type function | 223 | * XXX This should use some omap_ctrl_writel()-type function |
224 | */ | 224 | */ |
225 | __raw_writel(l, OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD + 4)); | 225 | writel_relaxed(l, OMAP2_L4_IO_ADDRESS(OMAP343X_SCRATCHPAD + 4)); |
226 | } | 226 | } |
227 | 227 | ||
228 | #endif | 228 | #endif |
@@ -285,7 +285,7 @@ void omap3_clear_scratchpad_contents(void) | |||
285 | if (omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) & | 285 | if (omap2_prm_read_mod_reg(OMAP3430_GR_MOD, OMAP3_PRM_RSTST_OFFSET) & |
286 | OMAP3430_GLOBAL_COLD_RST_MASK) { | 286 | OMAP3430_GLOBAL_COLD_RST_MASK) { |
287 | for ( ; offset <= max_offset; offset += 0x4) | 287 | for ( ; offset <= max_offset; offset += 0x4) |
288 | __raw_writel(0x0, (v_addr + offset)); | 288 | writel_relaxed(0x0, (v_addr + offset)); |
289 | omap2_prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST_MASK, | 289 | omap2_prm_set_mod_reg_bits(OMAP3430_GLOBAL_COLD_RST_MASK, |
290 | OMAP3430_GR_MOD, | 290 | OMAP3430_GR_MOD, |
291 | OMAP3_PRM_RSTST_OFFSET); | 291 | OMAP3_PRM_RSTST_OFFSET); |
diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c index 5689c88d986d..a6d2cf1f8d02 100644 --- a/arch/arm/mach-omap2/dma.c +++ b/arch/arm/mach-omap2/dma.c | |||
@@ -91,7 +91,7 @@ static inline void dma_write(u32 val, int reg, int lch) | |||
91 | addr += reg_map[reg].offset; | 91 | addr += reg_map[reg].offset; |
92 | addr += reg_map[reg].stride * lch; | 92 | addr += reg_map[reg].stride * lch; |
93 | 93 | ||
94 | __raw_writel(val, addr); | 94 | writel_relaxed(val, addr); |
95 | } | 95 | } |
96 | 96 | ||
97 | static inline u32 dma_read(int reg, int lch) | 97 | static inline u32 dma_read(int reg, int lch) |
@@ -101,7 +101,7 @@ static inline u32 dma_read(int reg, int lch) | |||
101 | addr += reg_map[reg].offset; | 101 | addr += reg_map[reg].offset; |
102 | addr += reg_map[reg].stride * lch; | 102 | addr += reg_map[reg].stride * lch; |
103 | 103 | ||
104 | return __raw_readl(addr); | 104 | return readl_relaxed(addr); |
105 | } | 105 | } |
106 | 106 | ||
107 | static void omap2_clear_dma(int lch) | 107 | static void omap2_clear_dma(int lch) |
diff --git a/arch/arm/mach-omap2/gpmc.c b/arch/arm/mach-omap2/gpmc.c index 9fe8c949305c..852b19a367f0 100644 --- a/arch/arm/mach-omap2/gpmc.c +++ b/arch/arm/mach-omap2/gpmc.c | |||
@@ -170,12 +170,12 @@ static irqreturn_t gpmc_handle_irq(int irq, void *dev); | |||
170 | 170 | ||
171 | static void gpmc_write_reg(int idx, u32 val) | 171 | static void gpmc_write_reg(int idx, u32 val) |
172 | { | 172 | { |
173 | __raw_writel(val, gpmc_base + idx); | 173 | writel_relaxed(val, gpmc_base + idx); |
174 | } | 174 | } |
175 | 175 | ||
176 | static u32 gpmc_read_reg(int idx) | 176 | static u32 gpmc_read_reg(int idx) |
177 | { | 177 | { |
178 | return __raw_readl(gpmc_base + idx); | 178 | return readl_relaxed(gpmc_base + idx); |
179 | } | 179 | } |
180 | 180 | ||
181 | void gpmc_cs_write_reg(int cs, int idx, u32 val) | 181 | void gpmc_cs_write_reg(int cs, int idx, u32 val) |
@@ -183,7 +183,7 @@ void gpmc_cs_write_reg(int cs, int idx, u32 val) | |||
183 | void __iomem *reg_addr; | 183 | void __iomem *reg_addr; |
184 | 184 | ||
185 | reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; | 185 | reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; |
186 | __raw_writel(val, reg_addr); | 186 | writel_relaxed(val, reg_addr); |
187 | } | 187 | } |
188 | 188 | ||
189 | static u32 gpmc_cs_read_reg(int cs, int idx) | 189 | static u32 gpmc_cs_read_reg(int cs, int idx) |
@@ -191,7 +191,7 @@ static u32 gpmc_cs_read_reg(int cs, int idx) | |||
191 | void __iomem *reg_addr; | 191 | void __iomem *reg_addr; |
192 | 192 | ||
193 | reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; | 193 | reg_addr = gpmc_base + GPMC_CS0_OFFSET + (cs * GPMC_CS_SIZE) + idx; |
194 | return __raw_readl(reg_addr); | 194 | return readl_relaxed(reg_addr); |
195 | } | 195 | } |
196 | 196 | ||
197 | /* TODO: Add support for gpmc_fck to clock framework and use it */ | 197 | /* TODO: Add support for gpmc_fck to clock framework and use it */ |
diff --git a/arch/arm/mach-omap2/id.c b/arch/arm/mach-omap2/id.c index 157412e4273a..f61f1bf68df4 100644 --- a/arch/arm/mach-omap2/id.c +++ b/arch/arm/mach-omap2/id.c | |||
@@ -94,7 +94,7 @@ EXPORT_SYMBOL(omap_type); | |||
94 | #define OMAP_TAP_DIE_ID_44XX_2 0x020c | 94 | #define OMAP_TAP_DIE_ID_44XX_2 0x020c |
95 | #define OMAP_TAP_DIE_ID_44XX_3 0x0210 | 95 | #define OMAP_TAP_DIE_ID_44XX_3 0x0210 |
96 | 96 | ||
97 | #define read_tap_reg(reg) __raw_readl(tap_base + (reg)) | 97 | #define read_tap_reg(reg) readl_relaxed(tap_base + (reg)) |
98 | 98 | ||
99 | struct omap_id { | 99 | struct omap_id { |
100 | u16 hawkeye; /* Silicon type (Hawkeye id) */ | 100 | u16 hawkeye; /* Silicon type (Hawkeye id) */ |
diff --git a/arch/arm/mach-omap2/irq.c b/arch/arm/mach-omap2/irq.c index 6037a9a01ed5..35b8590c322e 100644 --- a/arch/arm/mach-omap2/irq.c +++ b/arch/arm/mach-omap2/irq.c | |||
@@ -83,12 +83,12 @@ struct omap3_intc_regs { | |||
83 | 83 | ||
84 | static void intc_bank_write_reg(u32 val, struct omap_irq_bank *bank, u16 reg) | 84 | static void intc_bank_write_reg(u32 val, struct omap_irq_bank *bank, u16 reg) |
85 | { | 85 | { |
86 | __raw_writel(val, bank->base_reg + reg); | 86 | writel_relaxed(val, bank->base_reg + reg); |
87 | } | 87 | } |
88 | 88 | ||
89 | static u32 intc_bank_read_reg(struct omap_irq_bank *bank, u16 reg) | 89 | static u32 intc_bank_read_reg(struct omap_irq_bank *bank, u16 reg) |
90 | { | 90 | { |
91 | return __raw_readl(bank->base_reg + reg); | 91 | return readl_relaxed(bank->base_reg + reg); |
92 | } | 92 | } |
93 | 93 | ||
94 | /* XXX: FIQ and additional INTC support (only MPU at the moment) */ | 94 | /* XXX: FIQ and additional INTC support (only MPU at the moment) */ |
diff --git a/arch/arm/mach-omap2/mux.c b/arch/arm/mach-omap2/mux.c index 48094b58c88f..fd88edeb027f 100644 --- a/arch/arm/mach-omap2/mux.c +++ b/arch/arm/mach-omap2/mux.c | |||
@@ -70,18 +70,18 @@ struct omap_mux_partition *omap_mux_get(const char *name) | |||
70 | u16 omap_mux_read(struct omap_mux_partition *partition, u16 reg) | 70 | u16 omap_mux_read(struct omap_mux_partition *partition, u16 reg) |
71 | { | 71 | { |
72 | if (partition->flags & OMAP_MUX_REG_8BIT) | 72 | if (partition->flags & OMAP_MUX_REG_8BIT) |
73 | return __raw_readb(partition->base + reg); | 73 | return readb_relaxed(partition->base + reg); |
74 | else | 74 | else |
75 | return __raw_readw(partition->base + reg); | 75 | return readw_relaxed(partition->base + reg); |
76 | } | 76 | } |
77 | 77 | ||
78 | void omap_mux_write(struct omap_mux_partition *partition, u16 val, | 78 | void omap_mux_write(struct omap_mux_partition *partition, u16 val, |
79 | u16 reg) | 79 | u16 reg) |
80 | { | 80 | { |
81 | if (partition->flags & OMAP_MUX_REG_8BIT) | 81 | if (partition->flags & OMAP_MUX_REG_8BIT) |
82 | __raw_writeb(val, partition->base + reg); | 82 | writeb_relaxed(val, partition->base + reg); |
83 | else | 83 | else |
84 | __raw_writew(val, partition->base + reg); | 84 | writew_relaxed(val, partition->base + reg); |
85 | } | 85 | } |
86 | 86 | ||
87 | void omap_mux_write_array(struct omap_mux_partition *partition, | 87 | void omap_mux_write_array(struct omap_mux_partition *partition, |
diff --git a/arch/arm/mach-omap2/omap-hotplug.c b/arch/arm/mach-omap2/omap-hotplug.c index 458f72f9dc8f..971791fe9a3f 100644 --- a/arch/arm/mach-omap2/omap-hotplug.c +++ b/arch/arm/mach-omap2/omap-hotplug.c | |||
@@ -39,7 +39,7 @@ void __ref omap4_cpu_die(unsigned int cpu) | |||
39 | if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0) | 39 | if (omap_modify_auxcoreboot0(0x0, 0x200) != 0x0) |
40 | pr_err("Secure clear status failed\n"); | 40 | pr_err("Secure clear status failed\n"); |
41 | } else { | 41 | } else { |
42 | __raw_writel(0, base + OMAP_AUX_CORE_BOOT_0); | 42 | writel_relaxed(0, base + OMAP_AUX_CORE_BOOT_0); |
43 | } | 43 | } |
44 | 44 | ||
45 | 45 | ||
@@ -53,7 +53,7 @@ void __ref omap4_cpu_die(unsigned int cpu) | |||
53 | boot_cpu = omap_read_auxcoreboot0(); | 53 | boot_cpu = omap_read_auxcoreboot0(); |
54 | else | 54 | else |
55 | boot_cpu = | 55 | boot_cpu = |
56 | __raw_readl(base + OMAP_AUX_CORE_BOOT_0) >> 5; | 56 | readl_relaxed(base + OMAP_AUX_CORE_BOOT_0) >> 5; |
57 | 57 | ||
58 | if (boot_cpu == smp_processor_id()) { | 58 | if (boot_cpu == smp_processor_id()) { |
59 | /* | 59 | /* |
diff --git a/arch/arm/mach-omap2/omap-mpuss-lowpower.c b/arch/arm/mach-omap2/omap-mpuss-lowpower.c index 667915d236f3..eb76e47091ad 100644 --- a/arch/arm/mach-omap2/omap-mpuss-lowpower.c +++ b/arch/arm/mach-omap2/omap-mpuss-lowpower.c | |||
@@ -116,7 +116,7 @@ static inline void set_cpu_wakeup_addr(unsigned int cpu_id, u32 addr) | |||
116 | { | 116 | { |
117 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); | 117 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); |
118 | 118 | ||
119 | __raw_writel(addr, pm_info->wkup_sar_addr); | 119 | writel_relaxed(addr, pm_info->wkup_sar_addr); |
120 | } | 120 | } |
121 | 121 | ||
122 | /* | 122 | /* |
@@ -141,7 +141,7 @@ static void scu_pwrst_prepare(unsigned int cpu_id, unsigned int cpu_state) | |||
141 | break; | 141 | break; |
142 | } | 142 | } |
143 | 143 | ||
144 | __raw_writel(scu_pwr_st, pm_info->scu_sar_addr); | 144 | writel_relaxed(scu_pwr_st, pm_info->scu_sar_addr); |
145 | } | 145 | } |
146 | 146 | ||
147 | /* Helper functions for MPUSS OSWR */ | 147 | /* Helper functions for MPUSS OSWR */ |
@@ -179,7 +179,7 @@ static void l2x0_pwrst_prepare(unsigned int cpu_id, unsigned int save_state) | |||
179 | { | 179 | { |
180 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); | 180 | struct omap4_cpu_pm_info *pm_info = &per_cpu(omap4_pm_info, cpu_id); |
181 | 181 | ||
182 | __raw_writel(save_state, pm_info->l2x0_sar_addr); | 182 | writel_relaxed(save_state, pm_info->l2x0_sar_addr); |
183 | } | 183 | } |
184 | 184 | ||
185 | /* | 185 | /* |
@@ -192,10 +192,10 @@ static void save_l2x0_context(void) | |||
192 | u32 val; | 192 | u32 val; |
193 | void __iomem *l2x0_base = omap4_get_l2cache_base(); | 193 | void __iomem *l2x0_base = omap4_get_l2cache_base(); |
194 | if (l2x0_base) { | 194 | if (l2x0_base) { |
195 | val = __raw_readl(l2x0_base + L2X0_AUX_CTRL); | 195 | val = readl_relaxed(l2x0_base + L2X0_AUX_CTRL); |
196 | __raw_writel(val, sar_base + L2X0_AUXCTRL_OFFSET); | 196 | writel_relaxed(val, sar_base + L2X0_AUXCTRL_OFFSET); |
197 | val = __raw_readl(l2x0_base + L2X0_PREFETCH_CTRL); | 197 | val = readl_relaxed(l2x0_base + L2X0_PREFETCH_CTRL); |
198 | __raw_writel(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET); | 198 | writel_relaxed(val, sar_base + L2X0_PREFETCH_CTRL_OFFSET); |
199 | } | 199 | } |
200 | } | 200 | } |
201 | #else | 201 | #else |
@@ -386,9 +386,9 @@ int __init omap4_mpuss_init(void) | |||
386 | 386 | ||
387 | /* Save device type on scratchpad for low level code to use */ | 387 | /* Save device type on scratchpad for low level code to use */ |
388 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) | 388 | if (omap_type() != OMAP2_DEVICE_TYPE_GP) |
389 | __raw_writel(1, sar_base + OMAP_TYPE_OFFSET); | 389 | writel_relaxed(1, sar_base + OMAP_TYPE_OFFSET); |
390 | else | 390 | else |
391 | __raw_writel(0, sar_base + OMAP_TYPE_OFFSET); | 391 | writel_relaxed(0, sar_base + OMAP_TYPE_OFFSET); |
392 | 392 | ||
393 | save_l2x0_context(); | 393 | save_l2x0_context(); |
394 | 394 | ||
diff --git a/arch/arm/mach-omap2/omap-smp.c b/arch/arm/mach-omap2/omap-smp.c index 17550aa39d0f..256e84ef0f67 100644 --- a/arch/arm/mach-omap2/omap-smp.c +++ b/arch/arm/mach-omap2/omap-smp.c | |||
@@ -99,7 +99,7 @@ static int omap4_boot_secondary(unsigned int cpu, struct task_struct *idle) | |||
99 | if (omap_secure_apis_support()) | 99 | if (omap_secure_apis_support()) |
100 | omap_modify_auxcoreboot0(0x200, 0xfffffdff); | 100 | omap_modify_auxcoreboot0(0x200, 0xfffffdff); |
101 | else | 101 | else |
102 | __raw_writel(0x20, base + OMAP_AUX_CORE_BOOT_0); | 102 | writel_relaxed(0x20, base + OMAP_AUX_CORE_BOOT_0); |
103 | 103 | ||
104 | if (!cpu1_clkdm && !cpu1_pwrdm) { | 104 | if (!cpu1_clkdm && !cpu1_pwrdm) { |
105 | cpu1_clkdm = clkdm_lookup("mpu1_clkdm"); | 105 | cpu1_clkdm = clkdm_lookup("mpu1_clkdm"); |
@@ -227,8 +227,8 @@ static void __init omap4_smp_prepare_cpus(unsigned int max_cpus) | |||
227 | if (omap_secure_apis_support()) | 227 | if (omap_secure_apis_support()) |
228 | omap_auxcoreboot_addr(virt_to_phys(startup_addr)); | 228 | omap_auxcoreboot_addr(virt_to_phys(startup_addr)); |
229 | else | 229 | else |
230 | __raw_writel(virt_to_phys(omap5_secondary_startup), | 230 | writel_relaxed(virt_to_phys(omap5_secondary_startup), |
231 | base + OMAP_AUX_CORE_BOOT_1); | 231 | base + OMAP_AUX_CORE_BOOT_1); |
232 | 232 | ||
233 | } | 233 | } |
234 | 234 | ||
diff --git a/arch/arm/mach-omap2/omap-wakeupgen.c b/arch/arm/mach-omap2/omap-wakeupgen.c index 693fe486e917..37843a7d3639 100644 --- a/arch/arm/mach-omap2/omap-wakeupgen.c +++ b/arch/arm/mach-omap2/omap-wakeupgen.c | |||
@@ -60,19 +60,19 @@ static unsigned int omap_secure_apis; | |||
60 | */ | 60 | */ |
61 | static inline u32 wakeupgen_readl(u8 idx, u32 cpu) | 61 | static inline u32 wakeupgen_readl(u8 idx, u32 cpu) |
62 | { | 62 | { |
63 | return __raw_readl(wakeupgen_base + OMAP_WKG_ENB_A_0 + | 63 | return readl_relaxed(wakeupgen_base + OMAP_WKG_ENB_A_0 + |
64 | (cpu * CPU_ENA_OFFSET) + (idx * 4)); | 64 | (cpu * CPU_ENA_OFFSET) + (idx * 4)); |
65 | } | 65 | } |
66 | 66 | ||
67 | static inline void wakeupgen_writel(u32 val, u8 idx, u32 cpu) | 67 | static inline void wakeupgen_writel(u32 val, u8 idx, u32 cpu) |
68 | { | 68 | { |
69 | __raw_writel(val, wakeupgen_base + OMAP_WKG_ENB_A_0 + | 69 | writel_relaxed(val, wakeupgen_base + OMAP_WKG_ENB_A_0 + |
70 | (cpu * CPU_ENA_OFFSET) + (idx * 4)); | 70 | (cpu * CPU_ENA_OFFSET) + (idx * 4)); |
71 | } | 71 | } |
72 | 72 | ||
73 | static inline void sar_writel(u32 val, u32 offset, u8 idx) | 73 | static inline void sar_writel(u32 val, u32 offset, u8 idx) |
74 | { | 74 | { |
75 | __raw_writel(val, sar_base + offset + (idx * 4)); | 75 | writel_relaxed(val, sar_base + offset + (idx * 4)); |
76 | } | 76 | } |
77 | 77 | ||
78 | static inline int _wakeupgen_get_irq_info(u32 irq, u32 *bit_posn, u8 *reg_index) | 78 | static inline int _wakeupgen_get_irq_info(u32 irq, u32 *bit_posn, u8 *reg_index) |
@@ -231,21 +231,21 @@ static inline void omap4_irq_save_context(void) | |||
231 | } | 231 | } |
232 | 232 | ||
233 | /* Save AuxBoot* registers */ | 233 | /* Save AuxBoot* registers */ |
234 | val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); | 234 | val = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); |
235 | __raw_writel(val, sar_base + AUXCOREBOOT0_OFFSET); | 235 | writel_relaxed(val, sar_base + AUXCOREBOOT0_OFFSET); |
236 | val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_1); | 236 | val = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_1); |
237 | __raw_writel(val, sar_base + AUXCOREBOOT1_OFFSET); | 237 | writel_relaxed(val, sar_base + AUXCOREBOOT1_OFFSET); |
238 | 238 | ||
239 | /* Save SyncReq generation logic */ | 239 | /* Save SyncReq generation logic */ |
240 | val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_MASK); | 240 | val = readl_relaxed(wakeupgen_base + OMAP_PTMSYNCREQ_MASK); |
241 | __raw_writel(val, sar_base + PTMSYNCREQ_MASK_OFFSET); | 241 | writel_relaxed(val, sar_base + PTMSYNCREQ_MASK_OFFSET); |
242 | val = __raw_readl(wakeupgen_base + OMAP_PTMSYNCREQ_EN); | 242 | val = readl_relaxed(wakeupgen_base + OMAP_PTMSYNCREQ_EN); |
243 | __raw_writel(val, sar_base + PTMSYNCREQ_EN_OFFSET); | 243 | writel_relaxed(val, sar_base + PTMSYNCREQ_EN_OFFSET); |
244 | 244 | ||
245 | /* Set the Backup Bit Mask status */ | 245 | /* Set the Backup Bit Mask status */ |
246 | val = __raw_readl(sar_base + SAR_BACKUP_STATUS_OFFSET); | 246 | val = readl_relaxed(sar_base + SAR_BACKUP_STATUS_OFFSET); |
247 | val |= SAR_BACKUP_STATUS_WAKEUPGEN; | 247 | val |= SAR_BACKUP_STATUS_WAKEUPGEN; |
248 | __raw_writel(val, sar_base + SAR_BACKUP_STATUS_OFFSET); | 248 | writel_relaxed(val, sar_base + SAR_BACKUP_STATUS_OFFSET); |
249 | 249 | ||
250 | } | 250 | } |
251 | 251 | ||
@@ -264,15 +264,15 @@ static inline void omap5_irq_save_context(void) | |||
264 | } | 264 | } |
265 | 265 | ||
266 | /* Save AuxBoot* registers */ | 266 | /* Save AuxBoot* registers */ |
267 | val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); | 267 | val = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); |
268 | __raw_writel(val, sar_base + OMAP5_AUXCOREBOOT0_OFFSET); | 268 | writel_relaxed(val, sar_base + OMAP5_AUXCOREBOOT0_OFFSET); |
269 | val = __raw_readl(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); | 269 | val = readl_relaxed(wakeupgen_base + OMAP_AUX_CORE_BOOT_0); |
270 | __raw_writel(val, sar_base + OMAP5_AUXCOREBOOT1_OFFSET); | 270 | writel_relaxed(val, sar_base + OMAP5_AUXCOREBOOT1_OFFSET); |
271 | 271 | ||
272 | /* Set the Backup Bit Mask status */ | 272 | /* Set the Backup Bit Mask status */ |
273 | val = __raw_readl(sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET); | 273 | val = readl_relaxed(sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET); |
274 | val |= SAR_BACKUP_STATUS_WAKEUPGEN; | 274 | val |= SAR_BACKUP_STATUS_WAKEUPGEN; |
275 | __raw_writel(val, sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET); | 275 | writel_relaxed(val, sar_base + OMAP5_SAR_BACKUP_STATUS_OFFSET); |
276 | 276 | ||
277 | } | 277 | } |
278 | 278 | ||
@@ -306,9 +306,9 @@ static void irq_sar_clear(void) | |||
306 | if (soc_is_omap54xx()) | 306 | if (soc_is_omap54xx()) |
307 | offset = OMAP5_SAR_BACKUP_STATUS_OFFSET; | 307 | offset = OMAP5_SAR_BACKUP_STATUS_OFFSET; |
308 | 308 | ||
309 | val = __raw_readl(sar_base + offset); | 309 | val = readl_relaxed(sar_base + offset); |
310 | val &= ~SAR_BACKUP_STATUS_WAKEUPGEN; | 310 | val &= ~SAR_BACKUP_STATUS_WAKEUPGEN; |
311 | __raw_writel(val, sar_base + offset); | 311 | writel_relaxed(val, sar_base + offset); |
312 | } | 312 | } |
313 | 313 | ||
314 | /* | 314 | /* |
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c index 95e171a055f3..99b0154493a4 100644 --- a/arch/arm/mach-omap2/omap4-common.c +++ b/arch/arm/mach-omap2/omap4-common.c | |||
@@ -125,25 +125,25 @@ void __init gic_init_irq(void) | |||
125 | void gic_dist_disable(void) | 125 | void gic_dist_disable(void) |
126 | { | 126 | { |
127 | if (gic_dist_base_addr) | 127 | if (gic_dist_base_addr) |
128 | __raw_writel(0x0, gic_dist_base_addr + GIC_DIST_CTRL); | 128 | writel_relaxed(0x0, gic_dist_base_addr + GIC_DIST_CTRL); |
129 | } | 129 | } |
130 | 130 | ||
131 | void gic_dist_enable(void) | 131 | void gic_dist_enable(void) |
132 | { | 132 | { |
133 | if (gic_dist_base_addr) | 133 | if (gic_dist_base_addr) |
134 | __raw_writel(0x1, gic_dist_base_addr + GIC_DIST_CTRL); | 134 | writel_relaxed(0x1, gic_dist_base_addr + GIC_DIST_CTRL); |
135 | } | 135 | } |
136 | 136 | ||
137 | bool gic_dist_disabled(void) | 137 | bool gic_dist_disabled(void) |
138 | { | 138 | { |
139 | return !(__raw_readl(gic_dist_base_addr + GIC_DIST_CTRL) & 0x1); | 139 | return !(readl_relaxed(gic_dist_base_addr + GIC_DIST_CTRL) & 0x1); |
140 | } | 140 | } |
141 | 141 | ||
142 | void gic_timer_retrigger(void) | 142 | void gic_timer_retrigger(void) |
143 | { | 143 | { |
144 | u32 twd_int = __raw_readl(twd_base + TWD_TIMER_INTSTAT); | 144 | u32 twd_int = readl_relaxed(twd_base + TWD_TIMER_INTSTAT); |
145 | u32 gic_int = __raw_readl(gic_dist_base_addr + GIC_DIST_PENDING_SET); | 145 | u32 gic_int = readl_relaxed(gic_dist_base_addr + GIC_DIST_PENDING_SET); |
146 | u32 twd_ctrl = __raw_readl(twd_base + TWD_TIMER_CONTROL); | 146 | u32 twd_ctrl = readl_relaxed(twd_base + TWD_TIMER_CONTROL); |
147 | 147 | ||
148 | if (twd_int && !(gic_int & BIT(IRQ_LOCALTIMER))) { | 148 | if (twd_int && !(gic_int & BIT(IRQ_LOCALTIMER))) { |
149 | /* | 149 | /* |
@@ -151,11 +151,11 @@ void gic_timer_retrigger(void) | |||
151 | * disabled. Ack the pending interrupt, and retrigger it. | 151 | * disabled. Ack the pending interrupt, and retrigger it. |
152 | */ | 152 | */ |
153 | pr_warn("%s: lost localtimer interrupt\n", __func__); | 153 | pr_warn("%s: lost localtimer interrupt\n", __func__); |
154 | __raw_writel(1, twd_base + TWD_TIMER_INTSTAT); | 154 | writel_relaxed(1, twd_base + TWD_TIMER_INTSTAT); |
155 | if (!(twd_ctrl & TWD_TIMER_CONTROL_PERIODIC)) { | 155 | if (!(twd_ctrl & TWD_TIMER_CONTROL_PERIODIC)) { |
156 | __raw_writel(1, twd_base + TWD_TIMER_COUNTER); | 156 | writel_relaxed(1, twd_base + TWD_TIMER_COUNTER); |
157 | twd_ctrl |= TWD_TIMER_CONTROL_ENABLE; | 157 | twd_ctrl |= TWD_TIMER_CONTROL_ENABLE; |
158 | __raw_writel(twd_ctrl, twd_base + TWD_TIMER_CONTROL); | 158 | writel_relaxed(twd_ctrl, twd_base + TWD_TIMER_CONTROL); |
159 | } | 159 | } |
160 | } | 160 | } |
161 | } | 161 | } |
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c index 66c60fe1104c..f7bb435bb543 100644 --- a/arch/arm/mach-omap2/omap_hwmod.c +++ b/arch/arm/mach-omap2/omap_hwmod.c | |||
@@ -72,7 +72,7 @@ | |||
72 | * | (../mach-omap2/omap_hwmod*) | | 72 | * | (../mach-omap2/omap_hwmod*) | |
73 | * +-------------------------------+ | 73 | * +-------------------------------+ |
74 | * | OMAP clock/PRCM/register fns | | 74 | * | OMAP clock/PRCM/register fns | |
75 | * | (__raw_{read,write}l, clk*) | | 75 | * | ({read,write}l_relaxed, clk*) | |
76 | * +-------------------------------+ | 76 | * +-------------------------------+ |
77 | * | 77 | * |
78 | * Device drivers should not contain any OMAP-specific code or data in | 78 | * Device drivers should not contain any OMAP-specific code or data in |
@@ -3230,17 +3230,17 @@ static int _am33xx_is_hardreset_asserted(struct omap_hwmod *oh, | |||
3230 | u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs) | 3230 | u32 omap_hwmod_read(struct omap_hwmod *oh, u16 reg_offs) |
3231 | { | 3231 | { |
3232 | if (oh->flags & HWMOD_16BIT_REG) | 3232 | if (oh->flags & HWMOD_16BIT_REG) |
3233 | return __raw_readw(oh->_mpu_rt_va + reg_offs); | 3233 | return readw_relaxed(oh->_mpu_rt_va + reg_offs); |
3234 | else | 3234 | else |
3235 | return __raw_readl(oh->_mpu_rt_va + reg_offs); | 3235 | return readl_relaxed(oh->_mpu_rt_va + reg_offs); |
3236 | } | 3236 | } |
3237 | 3237 | ||
3238 | void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs) | 3238 | void omap_hwmod_write(u32 v, struct omap_hwmod *oh, u16 reg_offs) |
3239 | { | 3239 | { |
3240 | if (oh->flags & HWMOD_16BIT_REG) | 3240 | if (oh->flags & HWMOD_16BIT_REG) |
3241 | __raw_writew(v, oh->_mpu_rt_va + reg_offs); | 3241 | writew_relaxed(v, oh->_mpu_rt_va + reg_offs); |
3242 | else | 3242 | else |
3243 | __raw_writel(v, oh->_mpu_rt_va + reg_offs); | 3243 | writel_relaxed(v, oh->_mpu_rt_va + reg_offs); |
3244 | } | 3244 | } |
3245 | 3245 | ||
3246 | /** | 3246 | /** |
diff --git a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c index 0f178623e7da..a579b89ce9b7 100644 --- a/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c +++ b/arch/arm/mach-omap2/omap_hwmod_33xx_43xx_ipblock_data.c | |||
@@ -24,6 +24,7 @@ | |||
24 | #include "prm33xx.h" | 24 | #include "prm33xx.h" |
25 | #include "omap_hwmod_33xx_43xx_common_data.h" | 25 | #include "omap_hwmod_33xx_43xx_common_data.h" |
26 | #include "prcm43xx.h" | 26 | #include "prcm43xx.h" |
27 | #include "common.h" | ||
27 | 28 | ||
28 | #define CLKCTRL(oh, clkctrl) ((oh).prcm.omap4.clkctrl_offs = (clkctrl)) | 29 | #define CLKCTRL(oh, clkctrl) ((oh).prcm.omap4.clkctrl_offs = (clkctrl)) |
29 | #define RSTCTRL(oh, rstctrl) ((oh).prcm.omap4.rstctrl_offs = (rstctrl)) | 30 | #define RSTCTRL(oh, rstctrl) ((oh).prcm.omap4.rstctrl_offs = (rstctrl)) |
diff --git a/arch/arm/mach-omap2/omap_phy_internal.c b/arch/arm/mach-omap2/omap_phy_internal.c index eb8a25de67ed..50640b38f0bf 100644 --- a/arch/arm/mach-omap2/omap_phy_internal.c +++ b/arch/arm/mach-omap2/omap_phy_internal.c | |||
@@ -57,7 +57,7 @@ static int __init omap4430_phy_power_down(void) | |||
57 | } | 57 | } |
58 | 58 | ||
59 | /* Power down the phy */ | 59 | /* Power down the phy */ |
60 | __raw_writel(PHY_PD, ctrl_base + CONTROL_DEV_CONF); | 60 | writel_relaxed(PHY_PD, ctrl_base + CONTROL_DEV_CONF); |
61 | 61 | ||
62 | iounmap(ctrl_base); | 62 | iounmap(ctrl_base); |
63 | 63 | ||
@@ -162,7 +162,7 @@ void ti81xx_musb_phy_power(u8 on) | |||
162 | return; | 162 | return; |
163 | } | 163 | } |
164 | 164 | ||
165 | usbphycfg = __raw_readl(scm_base + USBCTRL0); | 165 | usbphycfg = readl_relaxed(scm_base + USBCTRL0); |
166 | 166 | ||
167 | if (on) { | 167 | if (on) { |
168 | if (cpu_is_ti816x()) { | 168 | if (cpu_is_ti816x()) { |
@@ -181,7 +181,7 @@ void ti81xx_musb_phy_power(u8 on) | |||
181 | usbphycfg |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN; | 181 | usbphycfg |= USBPHY_CM_PWRDN | USBPHY_OTG_PWRDN; |
182 | 182 | ||
183 | } | 183 | } |
184 | __raw_writel(usbphycfg, scm_base + USBCTRL0); | 184 | writel_relaxed(usbphycfg, scm_base + USBCTRL0); |
185 | 185 | ||
186 | iounmap(scm_base); | 186 | iounmap(scm_base); |
187 | } | 187 | } |
diff --git a/arch/arm/mach-omap2/powerdomain-common.c b/arch/arm/mach-omap2/powerdomain-common.c index c0aeabfcf009..c40e5f009826 100644 --- a/arch/arm/mach-omap2/powerdomain-common.c +++ b/arch/arm/mach-omap2/powerdomain-common.c | |||
@@ -17,7 +17,6 @@ | |||
17 | #include "pm.h" | 17 | #include "pm.h" |
18 | #include "cm.h" | 18 | #include "cm.h" |
19 | #include "cm-regbits-34xx.h" | 19 | #include "cm-regbits-34xx.h" |
20 | #include "cm-regbits-44xx.h" | ||
21 | #include "prm-regbits-34xx.h" | 20 | #include "prm-regbits-34xx.h" |
22 | #include "prm-regbits-44xx.h" | 21 | #include "prm-regbits-44xx.h" |
23 | 22 | ||
diff --git a/arch/arm/mach-omap2/powerdomain.c b/arch/arm/mach-omap2/powerdomain.c index 93a2a6e4260f..faebd5f076af 100644 --- a/arch/arm/mach-omap2/powerdomain.c +++ b/arch/arm/mach-omap2/powerdomain.c | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #include "powerdomain.h" | 33 | #include "powerdomain.h" |
34 | #include "clockdomain.h" | 34 | #include "clockdomain.h" |
35 | #include "voltage.h" | ||
35 | 36 | ||
36 | #include "soc.h" | 37 | #include "soc.h" |
37 | #include "pm.h" | 38 | #include "pm.h" |
diff --git a/arch/arm/mach-omap2/powerdomain.h b/arch/arm/mach-omap2/powerdomain.h index da5a59ae77b6..f4727117f6cc 100644 --- a/arch/arm/mach-omap2/powerdomain.h +++ b/arch/arm/mach-omap2/powerdomain.h | |||
@@ -21,8 +21,6 @@ | |||
21 | #include <linux/list.h> | 21 | #include <linux/list.h> |
22 | #include <linux/spinlock.h> | 22 | #include <linux/spinlock.h> |
23 | 23 | ||
24 | #include "voltage.h" | ||
25 | |||
26 | /* Powerdomain basic power states */ | 24 | /* Powerdomain basic power states */ |
27 | #define PWRDM_POWER_OFF 0x0 | 25 | #define PWRDM_POWER_OFF 0x0 |
28 | #define PWRDM_POWER_RET 0x1 | 26 | #define PWRDM_POWER_RET 0x1 |
@@ -75,6 +73,7 @@ | |||
75 | 73 | ||
76 | struct clockdomain; | 74 | struct clockdomain; |
77 | struct powerdomain; | 75 | struct powerdomain; |
76 | struct voltagedomain; | ||
78 | 77 | ||
79 | /** | 78 | /** |
80 | * struct powerdomain - OMAP powerdomain | 79 | * struct powerdomain - OMAP powerdomain |
diff --git a/arch/arm/mach-omap2/prcm-common.h b/arch/arm/mach-omap2/prcm-common.h index 0e841fd9498a..a8e4b582c527 100644 --- a/arch/arm/mach-omap2/prcm-common.h +++ b/arch/arm/mach-omap2/prcm-common.h | |||
@@ -428,6 +428,28 @@ | |||
428 | #define MAX_IOPAD_LATCH_TIME 100 | 428 | #define MAX_IOPAD_LATCH_TIME 100 |
429 | # ifndef __ASSEMBLER__ | 429 | # ifndef __ASSEMBLER__ |
430 | 430 | ||
431 | #include <linux/delay.h> | ||
432 | |||
433 | /** | ||
434 | * omap_test_timeout - busy-loop, testing a condition | ||
435 | * @cond: condition to test until it evaluates to true | ||
436 | * @timeout: maximum number of microseconds in the timeout | ||
437 | * @index: loop index (integer) | ||
438 | * | ||
439 | * Loop waiting for @cond to become true or until at least @timeout | ||
440 | * microseconds have passed. To use, define some integer @index in the | ||
441 | * calling code. After running, if @index == @timeout, then the loop has | ||
442 | * timed out. | ||
443 | */ | ||
444 | #define omap_test_timeout(cond, timeout, index) \ | ||
445 | ({ \ | ||
446 | for (index = 0; index < timeout; index++) { \ | ||
447 | if (cond) \ | ||
448 | break; \ | ||
449 | udelay(1); \ | ||
450 | } \ | ||
451 | }) | ||
452 | |||
431 | /** | 453 | /** |
432 | * struct omap_prcm_irq - describes a PRCM interrupt bit | 454 | * struct omap_prcm_irq - describes a PRCM interrupt bit |
433 | * @name: a short name describing the interrupt type, e.g. "wkup" or "io" | 455 | * @name: a short name describing the interrupt type, e.g. "wkup" or "io" |
@@ -458,6 +480,7 @@ struct omap_prcm_irq { | |||
458 | * @ocp_barrier: fn ptr to force buffered PRM writes to complete | 480 | * @ocp_barrier: fn ptr to force buffered PRM writes to complete |
459 | * @save_and_clear_irqen: fn ptr to save and clear IRQENABLE regs | 481 | * @save_and_clear_irqen: fn ptr to save and clear IRQENABLE regs |
460 | * @restore_irqen: fn ptr to save and clear IRQENABLE regs | 482 | * @restore_irqen: fn ptr to save and clear IRQENABLE regs |
483 | * @reconfigure_io_chain: fn ptr to reconfigure IO chain | ||
461 | * @saved_mask: IRQENABLE regs are saved here during suspend | 484 | * @saved_mask: IRQENABLE regs are saved here during suspend |
462 | * @priority_mask: 1 bit per IRQ, set to 1 if omap_prcm_irq.priority = true | 485 | * @priority_mask: 1 bit per IRQ, set to 1 if omap_prcm_irq.priority = true |
463 | * @base_irq: base dynamic IRQ number, returned from irq_alloc_descs() in init | 486 | * @base_irq: base dynamic IRQ number, returned from irq_alloc_descs() in init |
@@ -479,6 +502,7 @@ struct omap_prcm_irq_setup { | |||
479 | void (*ocp_barrier)(void); | 502 | void (*ocp_barrier)(void); |
480 | void (*save_and_clear_irqen)(u32 *saved_mask); | 503 | void (*save_and_clear_irqen)(u32 *saved_mask); |
481 | void (*restore_irqen)(u32 *saved_mask); | 504 | void (*restore_irqen)(u32 *saved_mask); |
505 | void (*reconfigure_io_chain)(void); | ||
482 | u32 *saved_mask; | 506 | u32 *saved_mask; |
483 | u32 *priority_mask; | 507 | u32 *priority_mask; |
484 | int base_irq; | 508 | int base_irq; |
diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.c b/arch/arm/mach-omap2/prcm_mpu44xx.c index c30e44a7fab0..cdbee6326d29 100644 --- a/arch/arm/mach-omap2/prcm_mpu44xx.c +++ b/arch/arm/mach-omap2/prcm_mpu44xx.c | |||
@@ -30,12 +30,12 @@ void __iomem *prcm_mpu_base; | |||
30 | 30 | ||
31 | u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 reg) | 31 | u32 omap4_prcm_mpu_read_inst_reg(s16 inst, u16 reg) |
32 | { | 32 | { |
33 | return __raw_readl(OMAP44XX_PRCM_MPU_REGADDR(inst, reg)); | 33 | return readl_relaxed(OMAP44XX_PRCM_MPU_REGADDR(inst, reg)); |
34 | } | 34 | } |
35 | 35 | ||
36 | void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 reg) | 36 | void omap4_prcm_mpu_write_inst_reg(u32 val, s16 inst, u16 reg) |
37 | { | 37 | { |
38 | __raw_writel(val, OMAP44XX_PRCM_MPU_REGADDR(inst, reg)); | 38 | writel_relaxed(val, OMAP44XX_PRCM_MPU_REGADDR(inst, reg)); |
39 | } | 39 | } |
40 | 40 | ||
41 | u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg) | 41 | u32 omap4_prcm_mpu_rmw_inst_reg_bits(u32 mask, u32 bits, s16 inst, s16 reg) |
diff --git a/arch/arm/mach-omap2/prcm_mpu44xx.h b/arch/arm/mach-omap2/prcm_mpu44xx.h index 059bd4f49035..ac9cb4550239 100644 --- a/arch/arm/mach-omap2/prcm_mpu44xx.h +++ b/arch/arm/mach-omap2/prcm_mpu44xx.h | |||
@@ -26,7 +26,6 @@ | |||
26 | #define __ARCH_ARM_MACH_OMAP2_PRCM_MPU44XX_H | 26 | #define __ARCH_ARM_MACH_OMAP2_PRCM_MPU44XX_H |
27 | 27 | ||
28 | #include "prcm_mpu_44xx_54xx.h" | 28 | #include "prcm_mpu_44xx_54xx.h" |
29 | #include "common.h" | ||
30 | 29 | ||
31 | #define OMAP4430_PRCM_MPU_BASE 0x48243000 | 30 | #define OMAP4430_PRCM_MPU_BASE 0x48243000 |
32 | 31 | ||
diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index 623db40fdbbd..48480d557b61 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h | |||
@@ -17,10 +17,18 @@ | |||
17 | 17 | ||
18 | # ifndef __ASSEMBLER__ | 18 | # ifndef __ASSEMBLER__ |
19 | extern void __iomem *prm_base; | 19 | extern void __iomem *prm_base; |
20 | extern u16 prm_features; | ||
20 | extern void omap2_set_globals_prm(void __iomem *prm); | 21 | extern void omap2_set_globals_prm(void __iomem *prm); |
21 | int of_prcm_init(void); | 22 | int of_prcm_init(void); |
22 | # endif | 23 | # endif |
23 | 24 | ||
25 | /* | ||
26 | * prm_features flag values | ||
27 | * | ||
28 | * PRM_HAS_IO_WAKEUP: has IO wakeup capability | ||
29 | * PRM_HAS_VOLTAGE: has voltage domains | ||
30 | */ | ||
31 | #define PRM_HAS_IO_WAKEUP (1 << 0) | ||
24 | 32 | ||
25 | /* | 33 | /* |
26 | * MAX_MODULE_SOFTRESET_WAIT: Maximum microseconds to wait for OMAP | 34 | * MAX_MODULE_SOFTRESET_WAIT: Maximum microseconds to wait for OMAP |
@@ -118,6 +126,7 @@ struct prm_reset_src_map { | |||
118 | * @read_reset_sources: ptr to the SoC PRM-specific get_reset_source impl | 126 | * @read_reset_sources: ptr to the SoC PRM-specific get_reset_source impl |
119 | * @was_any_context_lost_old: ptr to the SoC PRM context loss test fn | 127 | * @was_any_context_lost_old: ptr to the SoC PRM context loss test fn |
120 | * @clear_context_loss_flags_old: ptr to the SoC PRM context loss flag clear fn | 128 | * @clear_context_loss_flags_old: ptr to the SoC PRM context loss flag clear fn |
129 | * @late_init: ptr to the late init function | ||
121 | * | 130 | * |
122 | * XXX @was_any_context_lost_old and @clear_context_loss_flags_old are | 131 | * XXX @was_any_context_lost_old and @clear_context_loss_flags_old are |
123 | * deprecated. | 132 | * deprecated. |
@@ -126,6 +135,7 @@ struct prm_ll_data { | |||
126 | u32 (*read_reset_sources)(void); | 135 | u32 (*read_reset_sources)(void); |
127 | bool (*was_any_context_lost_old)(u8 part, s16 inst, u16 idx); | 136 | bool (*was_any_context_lost_old)(u8 part, s16 inst, u16 idx); |
128 | void (*clear_context_loss_flags_old)(u8 part, s16 inst, u16 idx); | 137 | void (*clear_context_loss_flags_old)(u8 part, s16 inst, u16 idx); |
138 | int (*late_init)(void); | ||
129 | }; | 139 | }; |
130 | 140 | ||
131 | extern int prm_register(struct prm_ll_data *pld); | 141 | extern int prm_register(struct prm_ll_data *pld); |
diff --git a/arch/arm/mach-omap2/prm2xxx.c b/arch/arm/mach-omap2/prm2xxx.c index 418de9c3b319..a3a3cca2bcc4 100644 --- a/arch/arm/mach-omap2/prm2xxx.c +++ b/arch/arm/mach-omap2/prm2xxx.c | |||
@@ -18,9 +18,6 @@ | |||
18 | #include <linux/io.h> | 18 | #include <linux/io.h> |
19 | #include <linux/irq.h> | 19 | #include <linux/irq.h> |
20 | 20 | ||
21 | #include "soc.h" | ||
22 | #include "common.h" | ||
23 | #include "vp.h" | ||
24 | #include "powerdomain.h" | 21 | #include "powerdomain.h" |
25 | #include "clockdomain.h" | 22 | #include "clockdomain.h" |
26 | #include "prm2xxx.h" | 23 | #include "prm2xxx.h" |
@@ -201,19 +198,11 @@ static struct prm_ll_data omap2xxx_prm_ll_data = { | |||
201 | 198 | ||
202 | int __init omap2xxx_prm_init(void) | 199 | int __init omap2xxx_prm_init(void) |
203 | { | 200 | { |
204 | if (!cpu_is_omap24xx()) | ||
205 | return 0; | ||
206 | |||
207 | return prm_register(&omap2xxx_prm_ll_data); | 201 | return prm_register(&omap2xxx_prm_ll_data); |
208 | } | 202 | } |
209 | 203 | ||
210 | static void __exit omap2xxx_prm_exit(void) | 204 | static void __exit omap2xxx_prm_exit(void) |
211 | { | 205 | { |
212 | if (!cpu_is_omap24xx()) | 206 | prm_unregister(&omap2xxx_prm_ll_data); |
213 | return; | ||
214 | |||
215 | /* Should never happen */ | ||
216 | WARN(prm_unregister(&omap2xxx_prm_ll_data), | ||
217 | "%s: prm_ll_data function pointer mismatch\n", __func__); | ||
218 | } | 207 | } |
219 | __exitcall(omap2xxx_prm_exit); | 208 | __exitcall(omap2xxx_prm_exit); |
diff --git a/arch/arm/mach-omap2/prm2xxx.h b/arch/arm/mach-omap2/prm2xxx.h index 3194dd87e0e4..d2cb6365716f 100644 --- a/arch/arm/mach-omap2/prm2xxx.h +++ b/arch/arm/mach-omap2/prm2xxx.h | |||
@@ -27,7 +27,7 @@ | |||
27 | 27 | ||
28 | /* | 28 | /* |
29 | * OMAP2-specific global PRM registers | 29 | * OMAP2-specific global PRM registers |
30 | * Use __raw_{read,write}l() with these registers. | 30 | * Use {read,write}l_relaxed() with these registers. |
31 | * | 31 | * |
32 | * With a few exceptions, these are the register names beginning with | 32 | * With a few exceptions, these are the register names beginning with |
33 | * PRCM_* on 24xx. (The exceptions are the IRQSTATUS and IRQENABLE | 33 | * PRCM_* on 24xx. (The exceptions are the IRQSTATUS and IRQENABLE |
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.c b/arch/arm/mach-omap2/prm2xxx_3xxx.c index 947f6adfed0c..c13b4e293ffa 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.c +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | #include <linux/io.h> | 17 | #include <linux/io.h> |
18 | 18 | ||
19 | #include "common.h" | ||
20 | #include "powerdomain.h" | 19 | #include "powerdomain.h" |
21 | #include "prm2xxx_3xxx.h" | 20 | #include "prm2xxx_3xxx.h" |
22 | #include "prm-regbits-24xx.h" | 21 | #include "prm-regbits-24xx.h" |
diff --git a/arch/arm/mach-omap2/prm2xxx_3xxx.h b/arch/arm/mach-omap2/prm2xxx_3xxx.h index 9624b40836d4..1a3a96392b97 100644 --- a/arch/arm/mach-omap2/prm2xxx_3xxx.h +++ b/arch/arm/mach-omap2/prm2xxx_3xxx.h | |||
@@ -55,12 +55,12 @@ | |||
55 | /* Power/reset management domain register get/set */ | 55 | /* Power/reset management domain register get/set */ |
56 | static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx) | 56 | static inline u32 omap2_prm_read_mod_reg(s16 module, u16 idx) |
57 | { | 57 | { |
58 | return __raw_readl(prm_base + module + idx); | 58 | return readl_relaxed(prm_base + module + idx); |
59 | } | 59 | } |
60 | 60 | ||
61 | static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx) | 61 | static inline void omap2_prm_write_mod_reg(u32 val, s16 module, u16 idx) |
62 | { | 62 | { |
63 | __raw_writel(val, prm_base + module + idx); | 63 | writel_relaxed(val, prm_base + module + idx); |
64 | } | 64 | } |
65 | 65 | ||
66 | /* Read-modify-write a register in a PRM module. Caller must lock */ | 66 | /* Read-modify-write a register in a PRM module. Caller must lock */ |
diff --git a/arch/arm/mach-omap2/prm33xx.c b/arch/arm/mach-omap2/prm33xx.c index 720440737744..62709cd2f9c5 100644 --- a/arch/arm/mach-omap2/prm33xx.c +++ b/arch/arm/mach-omap2/prm33xx.c | |||
@@ -19,7 +19,6 @@ | |||
19 | #include <linux/err.h> | 19 | #include <linux/err.h> |
20 | #include <linux/io.h> | 20 | #include <linux/io.h> |
21 | 21 | ||
22 | #include "common.h" | ||
23 | #include "powerdomain.h" | 22 | #include "powerdomain.h" |
24 | #include "prm33xx.h" | 23 | #include "prm33xx.h" |
25 | #include "prm-regbits-33xx.h" | 24 | #include "prm-regbits-33xx.h" |
@@ -27,13 +26,13 @@ | |||
27 | /* Read a register in a PRM instance */ | 26 | /* Read a register in a PRM instance */ |
28 | u32 am33xx_prm_read_reg(s16 inst, u16 idx) | 27 | u32 am33xx_prm_read_reg(s16 inst, u16 idx) |
29 | { | 28 | { |
30 | return __raw_readl(prm_base + inst + idx); | 29 | return readl_relaxed(prm_base + inst + idx); |
31 | } | 30 | } |
32 | 31 | ||
33 | /* Write into a register in a PRM instance */ | 32 | /* Write into a register in a PRM instance */ |
34 | void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx) | 33 | void am33xx_prm_write_reg(u32 val, s16 inst, u16 idx) |
35 | { | 34 | { |
36 | __raw_writel(val, prm_base + inst + idx); | 35 | writel_relaxed(val, prm_base + inst + idx); |
37 | } | 36 | } |
38 | 37 | ||
39 | /* Read-modify-write a register in PRM. Caller must lock */ | 38 | /* Read-modify-write a register in PRM. Caller must lock */ |
diff --git a/arch/arm/mach-omap2/prm3xxx.c b/arch/arm/mach-omap2/prm3xxx.c index 7721990d2006..4bd7a2dca8af 100644 --- a/arch/arm/mach-omap2/prm3xxx.c +++ b/arch/arm/mach-omap2/prm3xxx.c | |||
@@ -43,6 +43,7 @@ static struct omap_prcm_irq_setup omap3_prcm_irq_setup = { | |||
43 | .ocp_barrier = &omap3xxx_prm_ocp_barrier, | 43 | .ocp_barrier = &omap3xxx_prm_ocp_barrier, |
44 | .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen, | 44 | .save_and_clear_irqen = &omap3xxx_prm_save_and_clear_irqen, |
45 | .restore_irqen = &omap3xxx_prm_restore_irqen, | 45 | .restore_irqen = &omap3xxx_prm_restore_irqen, |
46 | .reconfigure_io_chain = &omap3xxx_prm_reconfigure_io_chain, | ||
46 | }; | 47 | }; |
47 | 48 | ||
48 | /* | 49 | /* |
@@ -246,7 +247,7 @@ void omap3xxx_prm_reconfigure_io_chain(void) | |||
246 | */ | 247 | */ |
247 | static void __init omap3xxx_prm_enable_io_wakeup(void) | 248 | static void __init omap3xxx_prm_enable_io_wakeup(void) |
248 | { | 249 | { |
249 | if (omap3_has_io_wakeup()) | 250 | if (prm_features & PRM_HAS_IO_WAKEUP) |
250 | omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, | 251 | omap2_prm_set_mod_reg_bits(OMAP3430_EN_IO_MASK, WKUP_MOD, |
251 | PM_WKEN); | 252 | PM_WKEN); |
252 | } | 253 | } |
@@ -400,23 +401,26 @@ struct pwrdm_ops omap3_pwrdm_operations = { | |||
400 | * | 401 | * |
401 | */ | 402 | */ |
402 | 403 | ||
404 | static int omap3xxx_prm_late_init(void); | ||
405 | |||
403 | static struct prm_ll_data omap3xxx_prm_ll_data = { | 406 | static struct prm_ll_data omap3xxx_prm_ll_data = { |
404 | .read_reset_sources = &omap3xxx_prm_read_reset_sources, | 407 | .read_reset_sources = &omap3xxx_prm_read_reset_sources, |
408 | .late_init = &omap3xxx_prm_late_init, | ||
405 | }; | 409 | }; |
406 | 410 | ||
407 | int __init omap3xxx_prm_init(void) | 411 | int __init omap3xxx_prm_init(void) |
408 | { | 412 | { |
409 | if (!cpu_is_omap34xx()) | 413 | if (omap3_has_io_wakeup()) |
410 | return 0; | 414 | prm_features |= PRM_HAS_IO_WAKEUP; |
411 | 415 | ||
412 | return prm_register(&omap3xxx_prm_ll_data); | 416 | return prm_register(&omap3xxx_prm_ll_data); |
413 | } | 417 | } |
414 | 418 | ||
415 | static int __init omap3xxx_prm_late_init(void) | 419 | static int omap3xxx_prm_late_init(void) |
416 | { | 420 | { |
417 | int ret; | 421 | int ret; |
418 | 422 | ||
419 | if (!cpu_is_omap34xx()) | 423 | if (!(prm_features & PRM_HAS_IO_WAKEUP)) |
420 | return 0; | 424 | return 0; |
421 | 425 | ||
422 | omap3xxx_prm_enable_io_wakeup(); | 426 | omap3xxx_prm_enable_io_wakeup(); |
@@ -427,15 +431,9 @@ static int __init omap3xxx_prm_late_init(void) | |||
427 | 431 | ||
428 | return ret; | 432 | return ret; |
429 | } | 433 | } |
430 | omap_subsys_initcall(omap3xxx_prm_late_init); | ||
431 | 434 | ||
432 | static void __exit omap3xxx_prm_exit(void) | 435 | static void __exit omap3xxx_prm_exit(void) |
433 | { | 436 | { |
434 | if (!cpu_is_omap34xx()) | 437 | prm_unregister(&omap3xxx_prm_ll_data); |
435 | return; | ||
436 | |||
437 | /* Should never happen */ | ||
438 | WARN(prm_unregister(&omap3xxx_prm_ll_data), | ||
439 | "%s: prm_ll_data function pointer mismatch\n", __func__); | ||
440 | } | 438 | } |
441 | __exitcall(omap3xxx_prm_exit); | 439 | __exitcall(omap3xxx_prm_exit); |
diff --git a/arch/arm/mach-omap2/prm3xxx.h b/arch/arm/mach-omap2/prm3xxx.h index f8eb83323b1a..1dacfc5b1959 100644 --- a/arch/arm/mach-omap2/prm3xxx.h +++ b/arch/arm/mach-omap2/prm3xxx.h | |||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | /* | 27 | /* |
28 | * OMAP3-specific global PRM registers | 28 | * OMAP3-specific global PRM registers |
29 | * Use __raw_{read,write}l() with these registers. | 29 | * Use {read,write}l_relaxed() with these registers. |
30 | * | 30 | * |
31 | * With a few exceptions, these are the register names beginning with | 31 | * With a few exceptions, these are the register names beginning with |
32 | * PRM_* on 34xx. (The exceptions are the IRQSTATUS and IRQENABLE | 32 | * PRM_* on 34xx. (The exceptions are the IRQSTATUS and IRQENABLE |
diff --git a/arch/arm/mach-omap2/prm44xx.c b/arch/arm/mach-omap2/prm44xx.c index 03a603476cfc..a7f6ea27180a 100644 --- a/arch/arm/mach-omap2/prm44xx.c +++ b/arch/arm/mach-omap2/prm44xx.c | |||
@@ -47,6 +47,7 @@ static struct omap_prcm_irq_setup omap4_prcm_irq_setup = { | |||
47 | .ocp_barrier = &omap44xx_prm_ocp_barrier, | 47 | .ocp_barrier = &omap44xx_prm_ocp_barrier, |
48 | .save_and_clear_irqen = &omap44xx_prm_save_and_clear_irqen, | 48 | .save_and_clear_irqen = &omap44xx_prm_save_and_clear_irqen, |
49 | .restore_irqen = &omap44xx_prm_restore_irqen, | 49 | .restore_irqen = &omap44xx_prm_restore_irqen, |
50 | .reconfigure_io_chain = &omap44xx_prm_reconfigure_io_chain, | ||
50 | }; | 51 | }; |
51 | 52 | ||
52 | /* | 53 | /* |
@@ -81,13 +82,13 @@ static struct prm_reset_src_map omap44xx_prm_reset_src_map[] = { | |||
81 | /* Read a register in a CM/PRM instance in the PRM module */ | 82 | /* Read a register in a CM/PRM instance in the PRM module */ |
82 | u32 omap4_prm_read_inst_reg(s16 inst, u16 reg) | 83 | u32 omap4_prm_read_inst_reg(s16 inst, u16 reg) |
83 | { | 84 | { |
84 | return __raw_readl(prm_base + inst + reg); | 85 | return readl_relaxed(prm_base + inst + reg); |
85 | } | 86 | } |
86 | 87 | ||
87 | /* Write into a register in a CM/PRM instance in the PRM module */ | 88 | /* Write into a register in a CM/PRM instance in the PRM module */ |
88 | void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg) | 89 | void omap4_prm_write_inst_reg(u32 val, s16 inst, u16 reg) |
89 | { | 90 | { |
90 | __raw_writel(val, prm_base + inst + reg); | 91 | writel_relaxed(val, prm_base + inst + reg); |
91 | } | 92 | } |
92 | 93 | ||
93 | /* Read-modify-write a register in a PRM module. Caller must lock */ | 94 | /* Read-modify-write a register in a PRM module. Caller must lock */ |
@@ -649,6 +650,8 @@ struct pwrdm_ops omap4_pwrdm_operations = { | |||
649 | .pwrdm_has_voltdm = omap4_check_vcvp, | 650 | .pwrdm_has_voltdm = omap4_check_vcvp, |
650 | }; | 651 | }; |
651 | 652 | ||
653 | static int omap44xx_prm_late_init(void); | ||
654 | |||
652 | /* | 655 | /* |
653 | * XXX document | 656 | * XXX document |
654 | */ | 657 | */ |
@@ -656,34 +659,29 @@ static struct prm_ll_data omap44xx_prm_ll_data = { | |||
656 | .read_reset_sources = &omap44xx_prm_read_reset_sources, | 659 | .read_reset_sources = &omap44xx_prm_read_reset_sources, |
657 | .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old, | 660 | .was_any_context_lost_old = &omap44xx_prm_was_any_context_lost_old, |
658 | .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old, | 661 | .clear_context_loss_flags_old = &omap44xx_prm_clear_context_loss_flags_old, |
662 | .late_init = &omap44xx_prm_late_init, | ||
659 | }; | 663 | }; |
660 | 664 | ||
661 | int __init omap44xx_prm_init(void) | 665 | int __init omap44xx_prm_init(void) |
662 | { | 666 | { |
663 | if (!cpu_is_omap44xx() && !soc_is_omap54xx() && !soc_is_dra7xx()) | 667 | if (cpu_is_omap44xx()) |
664 | return 0; | 668 | prm_features |= PRM_HAS_IO_WAKEUP; |
665 | 669 | ||
666 | return prm_register(&omap44xx_prm_ll_data); | 670 | return prm_register(&omap44xx_prm_ll_data); |
667 | } | 671 | } |
668 | 672 | ||
669 | static int __init omap44xx_prm_late_init(void) | 673 | static int omap44xx_prm_late_init(void) |
670 | { | 674 | { |
671 | if (!cpu_is_omap44xx()) | 675 | if (!(prm_features & PRM_HAS_IO_WAKEUP)) |
672 | return 0; | 676 | return 0; |
673 | 677 | ||
674 | omap44xx_prm_enable_io_wakeup(); | 678 | omap44xx_prm_enable_io_wakeup(); |
675 | 679 | ||
676 | return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); | 680 | return omap_prcm_register_chain_handler(&omap4_prcm_irq_setup); |
677 | } | 681 | } |
678 | omap_subsys_initcall(omap44xx_prm_late_init); | ||
679 | 682 | ||
680 | static void __exit omap44xx_prm_exit(void) | 683 | static void __exit omap44xx_prm_exit(void) |
681 | { | 684 | { |
682 | if (!cpu_is_omap44xx()) | 685 | prm_unregister(&omap44xx_prm_ll_data); |
683 | return; | ||
684 | |||
685 | /* Should never happen */ | ||
686 | WARN(prm_unregister(&omap44xx_prm_ll_data), | ||
687 | "%s: prm_ll_data function pointer mismatch\n", __func__); | ||
688 | } | 686 | } |
689 | __exitcall(omap44xx_prm_exit); | 687 | __exitcall(omap44xx_prm_exit); |
diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index b4c4ab9c8044..25e8b8232115 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c | |||
@@ -62,6 +62,8 @@ static struct omap_prcm_irq_setup *prcm_irq_setup; | |||
62 | /* prm_base: base virtual address of the PRM IP block */ | 62 | /* prm_base: base virtual address of the PRM IP block */ |
63 | void __iomem *prm_base; | 63 | void __iomem *prm_base; |
64 | 64 | ||
65 | u16 prm_features; | ||
66 | |||
65 | /* | 67 | /* |
66 | * prm_ll_data: function pointers to SoC-specific implementations of | 68 | * prm_ll_data: function pointers to SoC-specific implementations of |
67 | * common PRM functions | 69 | * common PRM functions |
@@ -330,12 +332,7 @@ int omap_prcm_register_chain_handler(struct omap_prcm_irq_setup *irq_setup) | |||
330 | 332 | ||
331 | if (of_have_populated_dt()) { | 333 | if (of_have_populated_dt()) { |
332 | int irq = omap_prcm_event_to_irq("io"); | 334 | int irq = omap_prcm_event_to_irq("io"); |
333 | if (cpu_is_omap34xx()) | 335 | omap_pcs_legacy_init(irq, irq_setup->reconfigure_io_chain); |
334 | omap_pcs_legacy_init(irq, | ||
335 | omap3xxx_prm_reconfigure_io_chain); | ||
336 | else | ||
337 | omap_pcs_legacy_init(irq, | ||
338 | omap44xx_prm_reconfigure_io_chain); | ||
339 | } | 336 | } |
340 | 337 | ||
341 | return 0; | 338 | return 0; |
@@ -530,3 +527,11 @@ int __init of_prcm_init(void) | |||
530 | 527 | ||
531 | return 0; | 528 | return 0; |
532 | } | 529 | } |
530 | |||
531 | static int __init prm_late_init(void) | ||
532 | { | ||
533 | if (prm_ll_data->late_init) | ||
534 | return prm_ll_data->late_init(); | ||
535 | return 0; | ||
536 | } | ||
537 | subsys_initcall(prm_late_init); | ||
diff --git a/arch/arm/mach-omap2/prminst44xx.c b/arch/arm/mach-omap2/prminst44xx.c index 05fcf6de44ee..69f0dd08629c 100644 --- a/arch/arm/mach-omap2/prminst44xx.c +++ b/arch/arm/mach-omap2/prminst44xx.c | |||
@@ -49,7 +49,7 @@ u32 omap4_prminst_read_inst_reg(u8 part, s16 inst, u16 idx) | |||
49 | BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || | 49 | BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || |
50 | part == OMAP4430_INVALID_PRCM_PARTITION || | 50 | part == OMAP4430_INVALID_PRCM_PARTITION || |
51 | !_prm_bases[part]); | 51 | !_prm_bases[part]); |
52 | return __raw_readl(_prm_bases[part] + inst + idx); | 52 | return readl_relaxed(_prm_bases[part] + inst + idx); |
53 | } | 53 | } |
54 | 54 | ||
55 | /* Write into a register in a PRM instance */ | 55 | /* Write into a register in a PRM instance */ |
@@ -58,7 +58,7 @@ void omap4_prminst_write_inst_reg(u32 val, u8 part, s16 inst, u16 idx) | |||
58 | BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || | 58 | BUG_ON(part >= OMAP4_MAX_PRCM_PARTITIONS || |
59 | part == OMAP4430_INVALID_PRCM_PARTITION || | 59 | part == OMAP4430_INVALID_PRCM_PARTITION || |
60 | !_prm_bases[part]); | 60 | !_prm_bases[part]); |
61 | __raw_writel(val, _prm_bases[part] + inst + idx); | 61 | writel_relaxed(val, _prm_bases[part] + inst + idx); |
62 | } | 62 | } |
63 | 63 | ||
64 | /* Read-modify-write a register in PRM. Caller must lock */ | 64 | /* Read-modify-write a register in PRM. Caller must lock */ |
diff --git a/arch/arm/mach-omap2/sdrc.h b/arch/arm/mach-omap2/sdrc.h index 446aa13511fd..645a2a46b213 100644 --- a/arch/arm/mach-omap2/sdrc.h +++ b/arch/arm/mach-omap2/sdrc.h | |||
@@ -31,24 +31,24 @@ extern void __iomem *omap2_sms_base; | |||
31 | 31 | ||
32 | static inline void sdrc_write_reg(u32 val, u16 reg) | 32 | static inline void sdrc_write_reg(u32 val, u16 reg) |
33 | { | 33 | { |
34 | __raw_writel(val, OMAP_SDRC_REGADDR(reg)); | 34 | writel_relaxed(val, OMAP_SDRC_REGADDR(reg)); |
35 | } | 35 | } |
36 | 36 | ||
37 | static inline u32 sdrc_read_reg(u16 reg) | 37 | static inline u32 sdrc_read_reg(u16 reg) |
38 | { | 38 | { |
39 | return __raw_readl(OMAP_SDRC_REGADDR(reg)); | 39 | return readl_relaxed(OMAP_SDRC_REGADDR(reg)); |
40 | } | 40 | } |
41 | 41 | ||
42 | /* SMS global register get/set */ | 42 | /* SMS global register get/set */ |
43 | 43 | ||
44 | static inline void sms_write_reg(u32 val, u16 reg) | 44 | static inline void sms_write_reg(u32 val, u16 reg) |
45 | { | 45 | { |
46 | __raw_writel(val, OMAP_SMS_REGADDR(reg)); | 46 | writel_relaxed(val, OMAP_SMS_REGADDR(reg)); |
47 | } | 47 | } |
48 | 48 | ||
49 | static inline u32 sms_read_reg(u16 reg) | 49 | static inline u32 sms_read_reg(u16 reg) |
50 | { | 50 | { |
51 | return __raw_readl(OMAP_SMS_REGADDR(reg)); | 51 | return readl_relaxed(OMAP_SMS_REGADDR(reg)); |
52 | } | 52 | } |
53 | 53 | ||
54 | extern void omap2_set_globals_sdrc(void __iomem *sdrc, void __iomem *sms); | 54 | extern void omap2_set_globals_sdrc(void __iomem *sdrc, void __iomem *sms); |
diff --git a/arch/arm/mach-omap2/sdrc2xxx.c b/arch/arm/mach-omap2/sdrc2xxx.c index 907291714643..ae3f1553158d 100644 --- a/arch/arm/mach-omap2/sdrc2xxx.c +++ b/arch/arm/mach-omap2/sdrc2xxx.c | |||
@@ -103,9 +103,9 @@ u32 omap2xxx_sdrc_reprogram(u32 level, u32 force) | |||
103 | * prm2xxx.c function | 103 | * prm2xxx.c function |
104 | */ | 104 | */ |
105 | if (cpu_is_omap2420()) | 105 | if (cpu_is_omap2420()) |
106 | __raw_writel(0xffff, OMAP2420_PRCM_VOLTSETUP); | 106 | writel_relaxed(0xffff, OMAP2420_PRCM_VOLTSETUP); |
107 | else | 107 | else |
108 | __raw_writel(0xffff, OMAP2430_PRCM_VOLTSETUP); | 108 | writel_relaxed(0xffff, OMAP2430_PRCM_VOLTSETUP); |
109 | omap2_sram_reprogram_sdrc(level, dll_ctrl, m_type); | 109 | omap2_sram_reprogram_sdrc(level, dll_ctrl, m_type); |
110 | curr_perf_level = level; | 110 | curr_perf_level = level; |
111 | local_irq_restore(flags); | 111 | local_irq_restore(flags); |
diff --git a/arch/arm/mach-omap2/sr_device.c b/arch/arm/mach-omap2/sr_device.c index d7bc33f15344..1b91ef0c182a 100644 --- a/arch/arm/mach-omap2/sr_device.c +++ b/arch/arm/mach-omap2/sr_device.c | |||
@@ -57,7 +57,7 @@ static void __init sr_set_nvalues(struct omap_volt_data *volt_data, | |||
57 | 57 | ||
58 | /* | 58 | /* |
59 | * In OMAP4 the efuse registers are 24 bit aligned. | 59 | * In OMAP4 the efuse registers are 24 bit aligned. |
60 | * A __raw_readl will fail for non-32 bit aligned address | 60 | * A readl_relaxed will fail for non-32 bit aligned address |
61 | * and hence the 8-bit read and shift. | 61 | * and hence the 8-bit read and shift. |
62 | */ | 62 | */ |
63 | if (cpu_is_omap44xx()) { | 63 | if (cpu_is_omap44xx()) { |
diff --git a/arch/arm/mach-omap2/sram.c b/arch/arm/mach-omap2/sram.c index 4bd096836235..ddf1818af228 100644 --- a/arch/arm/mach-omap2/sram.c +++ b/arch/arm/mach-omap2/sram.c | |||
@@ -70,16 +70,16 @@ static int is_sram_locked(void) | |||
70 | if (OMAP2_DEVICE_TYPE_GP == omap_type()) { | 70 | if (OMAP2_DEVICE_TYPE_GP == omap_type()) { |
71 | /* RAMFW: R/W access to all initiators for all qualifier sets */ | 71 | /* RAMFW: R/W access to all initiators for all qualifier sets */ |
72 | if (cpu_is_omap242x()) { | 72 | if (cpu_is_omap242x()) { |
73 | __raw_writel(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */ | 73 | writel_relaxed(0xFF, OMAP24XX_VA_REQINFOPERM0); /* all q-vects */ |
74 | __raw_writel(0xCFDE, OMAP24XX_VA_READPERM0); /* all i-read */ | 74 | writel_relaxed(0xCFDE, OMAP24XX_VA_READPERM0); /* all i-read */ |
75 | __raw_writel(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */ | 75 | writel_relaxed(0xCFDE, OMAP24XX_VA_WRITEPERM0); /* all i-write */ |
76 | } | 76 | } |
77 | if (cpu_is_omap34xx()) { | 77 | if (cpu_is_omap34xx()) { |
78 | __raw_writel(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */ | 78 | writel_relaxed(0xFFFF, OMAP34XX_VA_REQINFOPERM0); /* all q-vects */ |
79 | __raw_writel(0xFFFF, OMAP34XX_VA_READPERM0); /* all i-read */ | 79 | writel_relaxed(0xFFFF, OMAP34XX_VA_READPERM0); /* all i-read */ |
80 | __raw_writel(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */ | 80 | writel_relaxed(0xFFFF, OMAP34XX_VA_WRITEPERM0); /* all i-write */ |
81 | __raw_writel(0x0, OMAP34XX_VA_ADDR_MATCH2); | 81 | writel_relaxed(0x0, OMAP34XX_VA_ADDR_MATCH2); |
82 | __raw_writel(0xFFFFFFFF, OMAP34XX_VA_SMS_RG_ATT0); | 82 | writel_relaxed(0xFFFFFFFF, OMAP34XX_VA_SMS_RG_ATT0); |
83 | } | 83 | } |
84 | return 0; | 84 | return 0; |
85 | } else | 85 | } else |
diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index b62de9f9d05c..a8ec16787170 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c | |||
@@ -546,15 +546,15 @@ static void __init realtime_counter_init(void) | |||
546 | } | 546 | } |
547 | 547 | ||
548 | /* Program numerator and denumerator registers */ | 548 | /* Program numerator and denumerator registers */ |
549 | reg = __raw_readl(base + INCREMENTER_NUMERATOR_OFFSET) & | 549 | reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) & |
550 | NUMERATOR_DENUMERATOR_MASK; | 550 | NUMERATOR_DENUMERATOR_MASK; |
551 | reg |= num; | 551 | reg |= num; |
552 | __raw_writel(reg, base + INCREMENTER_NUMERATOR_OFFSET); | 552 | writel_relaxed(reg, base + INCREMENTER_NUMERATOR_OFFSET); |
553 | 553 | ||
554 | reg = __raw_readl(base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET) & | 554 | reg = readl_relaxed(base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET) & |
555 | NUMERATOR_DENUMERATOR_MASK; | 555 | NUMERATOR_DENUMERATOR_MASK; |
556 | reg |= den; | 556 | reg |= den; |
557 | __raw_writel(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET); | 557 | writel_relaxed(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET); |
558 | 558 | ||
559 | arch_timer_freq = (rate / den) * num; | 559 | arch_timer_freq = (rate / den) * num; |
560 | set_cntfreq(); | 560 | set_cntfreq(); |
diff --git a/arch/arm/mach-omap2/vc.c b/arch/arm/mach-omap2/vc.c index 49ac7977e03e..267f204559c3 100644 --- a/arch/arm/mach-omap2/vc.c +++ b/arch/arm/mach-omap2/vc.c | |||
@@ -462,7 +462,7 @@ static void omap4_set_timings(struct voltagedomain *voltdm, bool off_mode) | |||
462 | val |= omap4_usec_to_val_scrm(tshut, OMAP4_DOWNTIME_SHIFT, | 462 | val |= omap4_usec_to_val_scrm(tshut, OMAP4_DOWNTIME_SHIFT, |
463 | OMAP4_DOWNTIME_MASK); | 463 | OMAP4_DOWNTIME_MASK); |
464 | 464 | ||
465 | __raw_writel(val, OMAP4_SCRM_CLKSETUPTIME); | 465 | writel_relaxed(val, OMAP4_SCRM_CLKSETUPTIME); |
466 | } | 466 | } |
467 | 467 | ||
468 | /* OMAP4 specific voltage init functions */ | 468 | /* OMAP4 specific voltage init functions */ |
@@ -584,7 +584,7 @@ static void __init omap4_vc_i2c_timing_init(struct voltagedomain *voltdm) | |||
584 | val = i2c_data->loadbits << 25 | i2c_data->loadbits << 29; | 584 | val = i2c_data->loadbits << 25 | i2c_data->loadbits << 29; |
585 | 585 | ||
586 | /* Write to SYSCTRL_PADCONF_WKUP_CTRL_I2C_2 to setup I2C pull */ | 586 | /* Write to SYSCTRL_PADCONF_WKUP_CTRL_I2C_2 to setup I2C pull */ |
587 | __raw_writel(val, OMAP2_L4_IO_ADDRESS(OMAP4_CTRL_MODULE_PAD_WKUP + | 587 | writel_relaxed(val, OMAP2_L4_IO_ADDRESS(OMAP4_CTRL_MODULE_PAD_WKUP + |
588 | OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_I2C_2)); | 588 | OMAP4_CTRL_MODULE_PAD_WKUP_CONTROL_I2C_2)); |
589 | 589 | ||
590 | /* HSSCLH can always be zero */ | 590 | /* HSSCLH can always be zero */ |
diff --git a/arch/arm/mach-omap2/wd_timer.c b/arch/arm/mach-omap2/wd_timer.c index d15c7bbab8e2..97d6607d447a 100644 --- a/arch/arm/mach-omap2/wd_timer.c +++ b/arch/arm/mach-omap2/wd_timer.c | |||
@@ -49,12 +49,12 @@ int omap2_wd_timer_disable(struct omap_hwmod *oh) | |||
49 | } | 49 | } |
50 | 50 | ||
51 | /* sequence required to disable watchdog */ | 51 | /* sequence required to disable watchdog */ |
52 | __raw_writel(0xAAAA, base + OMAP_WDT_SPR); | 52 | writel_relaxed(0xAAAA, base + OMAP_WDT_SPR); |
53 | while (__raw_readl(base + OMAP_WDT_WPS) & 0x10) | 53 | while (readl_relaxed(base + OMAP_WDT_WPS) & 0x10) |
54 | cpu_relax(); | 54 | cpu_relax(); |
55 | 55 | ||
56 | __raw_writel(0x5555, base + OMAP_WDT_SPR); | 56 | writel_relaxed(0x5555, base + OMAP_WDT_SPR); |
57 | while (__raw_readl(base + OMAP_WDT_WPS) & 0x10) | 57 | while (readl_relaxed(base + OMAP_WDT_WPS) & 0x10) |
58 | cpu_relax(); | 58 | cpu_relax(); |
59 | 59 | ||
60 | return 0; | 60 | return 0; |
diff --git a/arch/arm/mach-prima2/rstc.c b/arch/arm/mach-prima2/rstc.c index 4887a2a4c698..3dffcb2d714e 100644 --- a/arch/arm/mach-prima2/rstc.c +++ b/arch/arm/mach-prima2/rstc.c | |||
@@ -36,27 +36,33 @@ static int sirfsoc_reset_module(struct reset_controller_dev *rcdev, | |||
36 | 36 | ||
37 | if (of_device_is_compatible(rcdev->of_node, "sirf,prima2-rstc")) { | 37 | if (of_device_is_compatible(rcdev->of_node, "sirf,prima2-rstc")) { |
38 | /* | 38 | /* |
39 | * Writing 1 to this bit resets corresponding block. Writing 0 to this | 39 | * Writing 1 to this bit resets corresponding block. |
40 | * bit de-asserts reset signal of the corresponding block. | 40 | * Writing 0 to this bit de-asserts reset signal of the |
41 | * datasheet doesn't require explicit delay between the set and clear | 41 | * corresponding block. datasheet doesn't require explicit |
42 | * of reset bit. it could be shorter if tests pass. | 42 | * delay between the set and clear of reset bit. it could |
43 | * be shorter if tests pass. | ||
43 | */ | 44 | */ |
44 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) | (1 << reset_bit), | 45 | writel(readl(sirfsoc_rstc_base + |
46 | (reset_bit / 32) * 4) | (1 << reset_bit), | ||
45 | sirfsoc_rstc_base + (reset_bit / 32) * 4); | 47 | sirfsoc_rstc_base + (reset_bit / 32) * 4); |
46 | msleep(10); | 48 | msleep(20); |
47 | writel(readl(sirfsoc_rstc_base + (reset_bit / 32) * 4) & ~(1 << reset_bit), | 49 | writel(readl(sirfsoc_rstc_base + |
50 | (reset_bit / 32) * 4) & ~(1 << reset_bit), | ||
48 | sirfsoc_rstc_base + (reset_bit / 32) * 4); | 51 | sirfsoc_rstc_base + (reset_bit / 32) * 4); |
49 | } else { | 52 | } else { |
50 | /* | 53 | /* |
51 | * For MARCO and POLO | 54 | * For MARCO and POLO |
52 | * Writing 1 to SET register resets corresponding block. Writing 1 to CLEAR | 55 | * Writing 1 to SET register resets corresponding block. |
53 | * register de-asserts reset signal of the corresponding block. | 56 | * Writing 1 to CLEAR register de-asserts reset signal of the |
54 | * datasheet doesn't require explicit delay between the set and clear | 57 | * corresponding block. |
55 | * of reset bit. it could be shorter if tests pass. | 58 | * datasheet doesn't require explicit delay between the set and |
59 | * clear of reset bit. it could be shorter if tests pass. | ||
56 | */ | 60 | */ |
57 | writel(1 << reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8); | 61 | writel(1 << reset_bit, |
58 | msleep(10); | 62 | sirfsoc_rstc_base + (reset_bit / 32) * 8); |
59 | writel(1 << reset_bit, sirfsoc_rstc_base + (reset_bit / 32) * 8 + 4); | 63 | msleep(20); |
64 | writel(1 << reset_bit, | ||
65 | sirfsoc_rstc_base + (reset_bit / 32) * 8 + 4); | ||
60 | } | 66 | } |
61 | 67 | ||
62 | mutex_unlock(&rstc_lock); | 68 | mutex_unlock(&rstc_lock); |
diff --git a/arch/arm/mach-qcom/Kconfig b/arch/arm/mach-qcom/Kconfig index a028be234334..6aa22147cace 100644 --- a/arch/arm/mach-qcom/Kconfig +++ b/arch/arm/mach-qcom/Kconfig | |||
@@ -3,8 +3,6 @@ config ARCH_QCOM | |||
3 | select ARCH_REQUIRE_GPIOLIB | 3 | select ARCH_REQUIRE_GPIOLIB |
4 | select ARM_GIC | 4 | select ARM_GIC |
5 | select CLKSRC_OF | 5 | select CLKSRC_OF |
6 | select GENERIC_CLOCKEVENTS | ||
7 | select HAVE_SMP | ||
8 | select QCOM_SCM if SMP | 6 | select QCOM_SCM if SMP |
9 | help | 7 | help |
10 | Support for Qualcomm's devicetree based systems. | 8 | Support for Qualcomm's devicetree based systems. |
diff --git a/arch/arm/mach-realview/core.c b/arch/arm/mach-realview/core.c index 1d5ee5c9a1dc..960b8dd78c44 100644 --- a/arch/arm/mach-realview/core.c +++ b/arch/arm/mach-realview/core.c | |||
@@ -148,6 +148,21 @@ struct platform_device realview_cf_device = { | |||
148 | }, | 148 | }, |
149 | }; | 149 | }; |
150 | 150 | ||
151 | static struct resource realview_leds_resources[] = { | ||
152 | { | ||
153 | .start = REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET, | ||
154 | .end = REALVIEW_SYS_BASE + REALVIEW_SYS_LED_OFFSET + 4, | ||
155 | .flags = IORESOURCE_MEM, | ||
156 | }, | ||
157 | }; | ||
158 | |||
159 | struct platform_device realview_leds_device = { | ||
160 | .name = "versatile-leds", | ||
161 | .id = -1, | ||
162 | .num_resources = ARRAY_SIZE(realview_leds_resources), | ||
163 | .resource = realview_leds_resources, | ||
164 | }; | ||
165 | |||
151 | static struct resource realview_i2c_resource = { | 166 | static struct resource realview_i2c_resource = { |
152 | .start = REALVIEW_I2C_BASE, | 167 | .start = REALVIEW_I2C_BASE, |
153 | .end = REALVIEW_I2C_BASE + SZ_4K - 1, | 168 | .end = REALVIEW_I2C_BASE + SZ_4K - 1, |
diff --git a/arch/arm/mach-realview/core.h b/arch/arm/mach-realview/core.h index 602ca5ec52c5..13dc830ef469 100644 --- a/arch/arm/mach-realview/core.h +++ b/arch/arm/mach-realview/core.h | |||
@@ -37,6 +37,7 @@ struct machine_desc; | |||
37 | 37 | ||
38 | extern struct platform_device realview_flash_device; | 38 | extern struct platform_device realview_flash_device; |
39 | extern struct platform_device realview_cf_device; | 39 | extern struct platform_device realview_cf_device; |
40 | extern struct platform_device realview_leds_device; | ||
40 | extern struct platform_device realview_i2c_device; | 41 | extern struct platform_device realview_i2c_device; |
41 | extern struct mmci_platform_data realview_mmc0_plat_data; | 42 | extern struct mmci_platform_data realview_mmc0_plat_data; |
42 | extern struct mmci_platform_data realview_mmc1_plat_data; | 43 | extern struct mmci_platform_data realview_mmc1_plat_data; |
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c index c85ddb2a0ad0..6bb070e80128 100644 --- a/arch/arm/mach-realview/realview_eb.c +++ b/arch/arm/mach-realview/realview_eb.c | |||
@@ -452,6 +452,7 @@ static void __init realview_eb_init(void) | |||
452 | realview_flash_register(&realview_eb_flash_resource, 1); | 452 | realview_flash_register(&realview_eb_flash_resource, 1); |
453 | platform_device_register(&realview_i2c_device); | 453 | platform_device_register(&realview_i2c_device); |
454 | platform_device_register(&char_lcd_device); | 454 | platform_device_register(&char_lcd_device); |
455 | platform_device_register(&realview_leds_device); | ||
455 | eth_device_register(); | 456 | eth_device_register(); |
456 | realview_usb_register(realview_eb_isp1761_resources); | 457 | realview_usb_register(realview_eb_isp1761_resources); |
457 | 458 | ||
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c index c5eade76461b..173f2c15de49 100644 --- a/arch/arm/mach-realview/realview_pb1176.c +++ b/arch/arm/mach-realview/realview_pb1176.c | |||
@@ -367,6 +367,7 @@ static void __init realview_pb1176_init(void) | |||
367 | realview_usb_register(realview_pb1176_isp1761_resources); | 367 | realview_usb_register(realview_pb1176_isp1761_resources); |
368 | platform_device_register(&pmu_device); | 368 | platform_device_register(&pmu_device); |
369 | platform_device_register(&char_lcd_device); | 369 | platform_device_register(&char_lcd_device); |
370 | platform_device_register(&realview_leds_device); | ||
370 | 371 | ||
371 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { | 372 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { |
372 | struct amba_device *d = amba_devs[i]; | 373 | struct amba_device *d = amba_devs[i]; |
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c index f4b0962578fe..bde7e6b1fd44 100644 --- a/arch/arm/mach-realview/realview_pb11mp.c +++ b/arch/arm/mach-realview/realview_pb11mp.c | |||
@@ -347,6 +347,7 @@ static void __init realview_pb11mp_init(void) | |||
347 | realview_eth_register(NULL, realview_pb11mp_smsc911x_resources); | 347 | realview_eth_register(NULL, realview_pb11mp_smsc911x_resources); |
348 | platform_device_register(&realview_i2c_device); | 348 | platform_device_register(&realview_i2c_device); |
349 | platform_device_register(&realview_cf_device); | 349 | platform_device_register(&realview_cf_device); |
350 | platform_device_register(&realview_leds_device); | ||
350 | realview_usb_register(realview_pb11mp_isp1761_resources); | 351 | realview_usb_register(realview_pb11mp_isp1761_resources); |
351 | platform_device_register(&pmu_device); | 352 | platform_device_register(&pmu_device); |
352 | 353 | ||
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c index 10a3e1d76891..4e57a8599265 100644 --- a/arch/arm/mach-realview/realview_pba8.c +++ b/arch/arm/mach-realview/realview_pba8.c | |||
@@ -289,6 +289,7 @@ static void __init realview_pba8_init(void) | |||
289 | realview_eth_register(NULL, realview_pba8_smsc911x_resources); | 289 | realview_eth_register(NULL, realview_pba8_smsc911x_resources); |
290 | platform_device_register(&realview_i2c_device); | 290 | platform_device_register(&realview_i2c_device); |
291 | platform_device_register(&realview_cf_device); | 291 | platform_device_register(&realview_cf_device); |
292 | platform_device_register(&realview_leds_device); | ||
292 | realview_usb_register(realview_pba8_isp1761_resources); | 293 | realview_usb_register(realview_pba8_isp1761_resources); |
293 | platform_device_register(&pmu_device); | 294 | platform_device_register(&pmu_device); |
294 | 295 | ||
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c index 9d75493e3f0c..72c96caebefa 100644 --- a/arch/arm/mach-realview/realview_pbx.c +++ b/arch/arm/mach-realview/realview_pbx.c | |||
@@ -385,6 +385,7 @@ static void __init realview_pbx_init(void) | |||
385 | realview_eth_register(NULL, realview_pbx_smsc911x_resources); | 385 | realview_eth_register(NULL, realview_pbx_smsc911x_resources); |
386 | platform_device_register(&realview_i2c_device); | 386 | platform_device_register(&realview_i2c_device); |
387 | platform_device_register(&realview_cf_device); | 387 | platform_device_register(&realview_cf_device); |
388 | platform_device_register(&realview_leds_device); | ||
388 | realview_usb_register(realview_pbx_isp1761_resources); | 389 | realview_usb_register(realview_pbx_isp1761_resources); |
389 | 390 | ||
390 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { | 391 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { |
diff --git a/arch/arm/mach-shmobile/Kconfig b/arch/arm/mach-shmobile/Kconfig index 0f92ba8e7884..edb1a914deb3 100644 --- a/arch/arm/mach-shmobile/Kconfig +++ b/arch/arm/mach-shmobile/Kconfig | |||
@@ -205,8 +205,8 @@ config MACH_ARMADILLO800EVA_REFERENCE | |||
205 | select SND_SOC_WM8978 if SND_SIMPLE_CARD | 205 | select SND_SOC_WM8978 if SND_SIMPLE_CARD |
206 | select USE_OF | 206 | select USE_OF |
207 | ---help--- | 207 | ---help--- |
208 | Use reference implementation of Aramdillo800 EVA board support | 208 | Use reference implementation of Armadillo800 EVA board support |
209 | which makes a greater use of device tree at the expense | 209 | which makes greater use of device tree at the expense |
210 | of not supporting a number of devices. | 210 | of not supporting a number of devices. |
211 | 211 | ||
212 | This is intended to aid developers | 212 | This is intended to aid developers |
diff --git a/arch/arm/mach-shmobile/setup-r8a7740.c b/arch/arm/mach-shmobile/setup-r8a7740.c index 8f3c68101d59..a177a7b3bdbd 100644 --- a/arch/arm/mach-shmobile/setup-r8a7740.c +++ b/arch/arm/mach-shmobile/setup-r8a7740.c | |||
@@ -765,7 +765,7 @@ static struct platform_device *r8a7740_late_devices[] __initdata = { | |||
765 | * "Media RAM (MERAM)" on r8a7740 documentation | 765 | * "Media RAM (MERAM)" on r8a7740 documentation |
766 | */ | 766 | */ |
767 | #define MEBUFCNTR 0xFE950098 | 767 | #define MEBUFCNTR 0xFE950098 |
768 | void r8a7740_meram_workaround(void) | 768 | void __init r8a7740_meram_workaround(void) |
769 | { | 769 | { |
770 | void __iomem *reg; | 770 | void __iomem *reg; |
771 | 771 | ||
@@ -869,17 +869,6 @@ void __init r8a7740_add_early_devices(void) | |||
869 | 869 | ||
870 | #ifdef CONFIG_USE_OF | 870 | #ifdef CONFIG_USE_OF |
871 | 871 | ||
872 | void __init r8a7740_add_early_devices_dt(void) | ||
873 | { | ||
874 | shmobile_setup_delay(800, 1, 3); /* Cortex-A9 @ 800MHz */ | ||
875 | |||
876 | early_platform_add_devices(r8a7740_early_devices, | ||
877 | ARRAY_SIZE(r8a7740_early_devices)); | ||
878 | |||
879 | /* setup early console here as well */ | ||
880 | shmobile_setup_console(); | ||
881 | } | ||
882 | |||
883 | void __init r8a7740_add_standard_devices_dt(void) | 872 | void __init r8a7740_add_standard_devices_dt(void) |
884 | { | 873 | { |
885 | platform_add_devices(r8a7740_devices_dt, | 874 | platform_add_devices(r8a7740_devices_dt, |
diff --git a/arch/arm/mach-shmobile/setup-sh7372.c b/arch/arm/mach-shmobile/setup-sh7372.c index 27301278c208..f8176b051be4 100644 --- a/arch/arm/mach-shmobile/setup-sh7372.c +++ b/arch/arm/mach-shmobile/setup-sh7372.c | |||
@@ -1037,11 +1037,7 @@ void __init sh7372_add_early_devices_dt(void) | |||
1037 | { | 1037 | { |
1038 | shmobile_setup_delay(800, 1, 3); /* Cortex-A8 @ 800MHz */ | 1038 | shmobile_setup_delay(800, 1, 3); /* Cortex-A8 @ 800MHz */ |
1039 | 1039 | ||
1040 | early_platform_add_devices(sh7372_early_devices, | 1040 | sh7372_add_early_devices(); |
1041 | ARRAY_SIZE(sh7372_early_devices)); | ||
1042 | |||
1043 | /* setup early console here as well */ | ||
1044 | shmobile_setup_console(); | ||
1045 | } | 1041 | } |
1046 | 1042 | ||
1047 | void __init sh7372_add_standard_devices_dt(void) | 1043 | void __init sh7372_add_standard_devices_dt(void) |
diff --git a/arch/arm/mach-versatile/core.c b/arch/arm/mach-versatile/core.c index f2c89fb8fca9..be83ba25f81b 100644 --- a/arch/arm/mach-versatile/core.c +++ b/arch/arm/mach-versatile/core.c | |||
@@ -310,6 +310,21 @@ static struct platform_device char_lcd_device = { | |||
310 | .resource = char_lcd_resources, | 310 | .resource = char_lcd_resources, |
311 | }; | 311 | }; |
312 | 312 | ||
313 | static struct resource leds_resources[] = { | ||
314 | { | ||
315 | .start = VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET, | ||
316 | .end = VERSATILE_SYS_BASE + VERSATILE_SYS_LED_OFFSET + 4, | ||
317 | .flags = IORESOURCE_MEM, | ||
318 | }, | ||
319 | }; | ||
320 | |||
321 | static struct platform_device leds_device = { | ||
322 | .name = "versatile-leds", | ||
323 | .id = -1, | ||
324 | .num_resources = ARRAY_SIZE(leds_resources), | ||
325 | .resource = leds_resources, | ||
326 | }; | ||
327 | |||
313 | /* | 328 | /* |
314 | * Clock handling | 329 | * Clock handling |
315 | */ | 330 | */ |
@@ -795,6 +810,7 @@ void __init versatile_init(void) | |||
795 | platform_device_register(&versatile_i2c_device); | 810 | platform_device_register(&versatile_i2c_device); |
796 | platform_device_register(&smc91x_device); | 811 | platform_device_register(&smc91x_device); |
797 | platform_device_register(&char_lcd_device); | 812 | platform_device_register(&char_lcd_device); |
813 | platform_device_register(&leds_device); | ||
798 | 814 | ||
799 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { | 815 | for (i = 0; i < ARRAY_SIZE(amba_devs); i++) { |
800 | struct amba_device *d = amba_devs[i]; | 816 | struct amba_device *d = amba_devs[i]; |
diff --git a/arch/arm/mach-vexpress/Kconfig b/arch/arm/mach-vexpress/Kconfig index 657d52d0391f..b8ac752fd24b 100644 --- a/arch/arm/mach-vexpress/Kconfig +++ b/arch/arm/mach-vexpress/Kconfig | |||
@@ -18,6 +18,8 @@ config ARCH_VEXPRESS | |||
18 | select POWER_SUPPLY | 18 | select POWER_SUPPLY |
19 | select REGULATOR_FIXED_VOLTAGE if REGULATOR | 19 | select REGULATOR_FIXED_VOLTAGE if REGULATOR |
20 | select VEXPRESS_CONFIG | 20 | select VEXPRESS_CONFIG |
21 | select VEXPRESS_SYSCFG | ||
22 | select MFD_VEXPRESS_SYSREG | ||
21 | help | 23 | help |
22 | This option enables support for systems using Cortex processor based | 24 | This option enables support for systems using Cortex processor based |
23 | ARM core and logic (FPGA) tiles on the Versatile Express motherboard, | 25 | ARM core and logic (FPGA) tiles on the Versatile Express motherboard, |
diff --git a/arch/arm/mach-vexpress/core.h b/arch/arm/mach-vexpress/core.h index bde4374ab6d5..152fad91b3ae 100644 --- a/arch/arm/mach-vexpress/core.h +++ b/arch/arm/mach-vexpress/core.h | |||
@@ -4,10 +4,9 @@ | |||
4 | /* Tile's peripherals static mappings should start here */ | 4 | /* Tile's peripherals static mappings should start here */ |
5 | #define V2T_PERIPH 0xf8200000 | 5 | #define V2T_PERIPH 0xf8200000 |
6 | 6 | ||
7 | void vexpress_dt_smp_map_io(void); | ||
8 | |||
9 | bool vexpress_smp_init_ops(void); | 7 | bool vexpress_smp_init_ops(void); |
10 | 8 | ||
11 | extern struct smp_operations vexpress_smp_ops; | 9 | extern struct smp_operations vexpress_smp_ops; |
10 | extern struct smp_operations vexpress_smp_dt_ops; | ||
12 | 11 | ||
13 | extern void vexpress_cpu_die(unsigned int cpu); | 12 | extern void vexpress_cpu_die(unsigned int cpu); |
diff --git a/arch/arm/mach-vexpress/ct-ca9x4.c b/arch/arm/mach-vexpress/ct-ca9x4.c index 6f34497a4245..494d70bfddad 100644 --- a/arch/arm/mach-vexpress/ct-ca9x4.c +++ b/arch/arm/mach-vexpress/ct-ca9x4.c | |||
@@ -128,6 +128,10 @@ static struct platform_device pmu_device = { | |||
128 | .resource = pmu_resources, | 128 | .resource = pmu_resources, |
129 | }; | 129 | }; |
130 | 130 | ||
131 | static struct clk_lookup osc1_lookup = { | ||
132 | .dev_id = "ct:clcd", | ||
133 | }; | ||
134 | |||
131 | static struct platform_device osc1_device = { | 135 | static struct platform_device osc1_device = { |
132 | .name = "vexpress-osc", | 136 | .name = "vexpress-osc", |
133 | .id = 1, | 137 | .id = 1, |
@@ -135,6 +139,7 @@ static struct platform_device osc1_device = { | |||
135 | .resource = (struct resource []) { | 139 | .resource = (struct resource []) { |
136 | VEXPRESS_RES_FUNC(0xf, 1), | 140 | VEXPRESS_RES_FUNC(0xf, 1), |
137 | }, | 141 | }, |
142 | .dev.platform_data = &osc1_lookup, | ||
138 | }; | 143 | }; |
139 | 144 | ||
140 | static void __init ct_ca9x4_init(void) | 145 | static void __init ct_ca9x4_init(void) |
@@ -155,10 +160,7 @@ static void __init ct_ca9x4_init(void) | |||
155 | amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource); | 160 | amba_device_register(ct_ca9x4_amba_devs[i], &iomem_resource); |
156 | 161 | ||
157 | platform_device_register(&pmu_device); | 162 | platform_device_register(&pmu_device); |
158 | platform_device_register(&osc1_device); | 163 | vexpress_syscfg_device_register(&osc1_device); |
159 | |||
160 | WARN_ON(clk_register_clkdev(vexpress_osc_setup(&osc1_device.dev), | ||
161 | NULL, "ct:clcd")); | ||
162 | } | 164 | } |
163 | 165 | ||
164 | #ifdef CONFIG_SMP | 166 | #ifdef CONFIG_SMP |
diff --git a/arch/arm/mach-vexpress/platsmp.c b/arch/arm/mach-vexpress/platsmp.c index 993c9ae5dc5e..a1f3804fd5a5 100644 --- a/arch/arm/mach-vexpress/platsmp.c +++ b/arch/arm/mach-vexpress/platsmp.c | |||
@@ -12,8 +12,7 @@ | |||
12 | #include <linux/errno.h> | 12 | #include <linux/errno.h> |
13 | #include <linux/smp.h> | 13 | #include <linux/smp.h> |
14 | #include <linux/io.h> | 14 | #include <linux/io.h> |
15 | #include <linux/of.h> | 15 | #include <linux/of_address.h> |
16 | #include <linux/of_fdt.h> | ||
17 | #include <linux/vexpress.h> | 16 | #include <linux/vexpress.h> |
18 | 17 | ||
19 | #include <asm/mcpm.h> | 18 | #include <asm/mcpm.h> |
@@ -26,154 +25,13 @@ | |||
26 | 25 | ||
27 | #include "core.h" | 26 | #include "core.h" |
28 | 27 | ||
29 | #if defined(CONFIG_OF) | ||
30 | |||
31 | static enum { | ||
32 | GENERIC_SCU, | ||
33 | CORTEX_A9_SCU, | ||
34 | } vexpress_dt_scu __initdata = GENERIC_SCU; | ||
35 | |||
36 | static struct map_desc vexpress_dt_cortex_a9_scu_map __initdata = { | ||
37 | .virtual = V2T_PERIPH, | ||
38 | /* .pfn set in vexpress_dt_init_cortex_a9_scu() */ | ||
39 | .length = SZ_128, | ||
40 | .type = MT_DEVICE, | ||
41 | }; | ||
42 | |||
43 | static void *vexpress_dt_cortex_a9_scu_base __initdata; | ||
44 | |||
45 | const static char *vexpress_dt_cortex_a9_match[] __initconst = { | ||
46 | "arm,cortex-a5-scu", | ||
47 | "arm,cortex-a9-scu", | ||
48 | NULL | ||
49 | }; | ||
50 | |||
51 | static int __init vexpress_dt_find_scu(unsigned long node, | ||
52 | const char *uname, int depth, void *data) | ||
53 | { | ||
54 | if (of_flat_dt_match(node, vexpress_dt_cortex_a9_match)) { | ||
55 | phys_addr_t phys_addr; | ||
56 | __be32 *reg = of_get_flat_dt_prop(node, "reg", NULL); | ||
57 | |||
58 | if (WARN_ON(!reg)) | ||
59 | return -EINVAL; | ||
60 | |||
61 | phys_addr = be32_to_cpup(reg); | ||
62 | vexpress_dt_scu = CORTEX_A9_SCU; | ||
63 | |||
64 | vexpress_dt_cortex_a9_scu_map.pfn = __phys_to_pfn(phys_addr); | ||
65 | iotable_init(&vexpress_dt_cortex_a9_scu_map, 1); | ||
66 | vexpress_dt_cortex_a9_scu_base = ioremap(phys_addr, SZ_256); | ||
67 | if (WARN_ON(!vexpress_dt_cortex_a9_scu_base)) | ||
68 | return -EFAULT; | ||
69 | } | ||
70 | |||
71 | return 0; | ||
72 | } | ||
73 | |||
74 | void __init vexpress_dt_smp_map_io(void) | ||
75 | { | ||
76 | if (initial_boot_params) | ||
77 | WARN_ON(of_scan_flat_dt(vexpress_dt_find_scu, NULL)); | ||
78 | } | ||
79 | |||
80 | static int __init vexpress_dt_cpus_num(unsigned long node, const char *uname, | ||
81 | int depth, void *data) | ||
82 | { | ||
83 | static int prev_depth = -1; | ||
84 | static int nr_cpus = -1; | ||
85 | |||
86 | if (prev_depth > depth && nr_cpus > 0) | ||
87 | return nr_cpus; | ||
88 | |||
89 | if (nr_cpus < 0 && strcmp(uname, "cpus") == 0) | ||
90 | nr_cpus = 0; | ||
91 | |||
92 | if (nr_cpus >= 0) { | ||
93 | const char *device_type = of_get_flat_dt_prop(node, | ||
94 | "device_type", NULL); | ||
95 | |||
96 | if (device_type && strcmp(device_type, "cpu") == 0) | ||
97 | nr_cpus++; | ||
98 | } | ||
99 | |||
100 | prev_depth = depth; | ||
101 | |||
102 | return 0; | ||
103 | } | ||
104 | |||
105 | static void __init vexpress_dt_smp_init_cpus(void) | ||
106 | { | ||
107 | int ncores = 0, i; | ||
108 | |||
109 | switch (vexpress_dt_scu) { | ||
110 | case GENERIC_SCU: | ||
111 | ncores = of_scan_flat_dt(vexpress_dt_cpus_num, NULL); | ||
112 | break; | ||
113 | case CORTEX_A9_SCU: | ||
114 | ncores = scu_get_core_count(vexpress_dt_cortex_a9_scu_base); | ||
115 | break; | ||
116 | default: | ||
117 | WARN_ON(1); | ||
118 | break; | ||
119 | } | ||
120 | |||
121 | if (ncores < 2) | ||
122 | return; | ||
123 | |||
124 | if (ncores > nr_cpu_ids) { | ||
125 | pr_warn("SMP: %u cores greater than maximum (%u), clipping\n", | ||
126 | ncores, nr_cpu_ids); | ||
127 | ncores = nr_cpu_ids; | ||
128 | } | ||
129 | |||
130 | for (i = 0; i < ncores; ++i) | ||
131 | set_cpu_possible(i, true); | ||
132 | } | ||
133 | |||
134 | static void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus) | ||
135 | { | ||
136 | int i; | ||
137 | |||
138 | switch (vexpress_dt_scu) { | ||
139 | case GENERIC_SCU: | ||
140 | for (i = 0; i < max_cpus; i++) | ||
141 | set_cpu_present(i, true); | ||
142 | break; | ||
143 | case CORTEX_A9_SCU: | ||
144 | scu_enable(vexpress_dt_cortex_a9_scu_base); | ||
145 | break; | ||
146 | default: | ||
147 | WARN_ON(1); | ||
148 | break; | ||
149 | } | ||
150 | } | ||
151 | |||
152 | #else | ||
153 | |||
154 | static void __init vexpress_dt_smp_init_cpus(void) | ||
155 | { | ||
156 | WARN_ON(1); | ||
157 | } | ||
158 | |||
159 | void __init vexpress_dt_smp_prepare_cpus(unsigned int max_cpus) | ||
160 | { | ||
161 | WARN_ON(1); | ||
162 | } | ||
163 | |||
164 | #endif | ||
165 | |||
166 | /* | 28 | /* |
167 | * Initialise the CPU possible map early - this describes the CPUs | 29 | * Initialise the CPU possible map early - this describes the CPUs |
168 | * which may be present or become present in the system. | 30 | * which may be present or become present in the system. |
169 | */ | 31 | */ |
170 | static void __init vexpress_smp_init_cpus(void) | 32 | static void __init vexpress_smp_init_cpus(void) |
171 | { | 33 | { |
172 | if (ct_desc) | 34 | ct_desc->init_cpu_map(); |
173 | ct_desc->init_cpu_map(); | ||
174 | else | ||
175 | vexpress_dt_smp_init_cpus(); | ||
176 | |||
177 | } | 35 | } |
178 | 36 | ||
179 | static void __init vexpress_smp_prepare_cpus(unsigned int max_cpus) | 37 | static void __init vexpress_smp_prepare_cpus(unsigned int max_cpus) |
@@ -182,10 +40,7 @@ static void __init vexpress_smp_prepare_cpus(unsigned int max_cpus) | |||
182 | * Initialise the present map, which describes the set of CPUs | 40 | * Initialise the present map, which describes the set of CPUs |
183 | * actually populated at the present time. | 41 | * actually populated at the present time. |
184 | */ | 42 | */ |
185 | if (ct_desc) | 43 | ct_desc->smp_enable(max_cpus); |
186 | ct_desc->smp_enable(max_cpus); | ||
187 | else | ||
188 | vexpress_dt_smp_prepare_cpus(max_cpus); | ||
189 | 44 | ||
190 | /* | 45 | /* |
191 | * Write the address of secondary startup into the | 46 | * Write the address of secondary startup into the |
@@ -223,3 +78,39 @@ bool __init vexpress_smp_init_ops(void) | |||
223 | #endif | 78 | #endif |
224 | return false; | 79 | return false; |
225 | } | 80 | } |
81 | |||
82 | #if defined(CONFIG_OF) | ||
83 | |||
84 | static const struct of_device_id vexpress_smp_dt_scu_match[] __initconst = { | ||
85 | { .compatible = "arm,cortex-a5-scu", }, | ||
86 | { .compatible = "arm,cortex-a9-scu", }, | ||
87 | {} | ||
88 | }; | ||
89 | |||
90 | static void __init vexpress_smp_dt_prepare_cpus(unsigned int max_cpus) | ||
91 | { | ||
92 | struct device_node *scu = of_find_matching_node(NULL, | ||
93 | vexpress_smp_dt_scu_match); | ||
94 | |||
95 | if (scu) | ||
96 | scu_enable(of_iomap(scu, 0)); | ||
97 | |||
98 | /* | ||
99 | * Write the address of secondary startup into the | ||
100 | * system-wide flags register. The boot monitor waits | ||
101 | * until it receives a soft interrupt, and then the | ||
102 | * secondary CPU branches to this address. | ||
103 | */ | ||
104 | vexpress_flags_set(virt_to_phys(versatile_secondary_startup)); | ||
105 | } | ||
106 | |||
107 | struct smp_operations __initdata vexpress_smp_dt_ops = { | ||
108 | .smp_prepare_cpus = vexpress_smp_dt_prepare_cpus, | ||
109 | .smp_secondary_init = versatile_secondary_init, | ||
110 | .smp_boot_secondary = versatile_boot_secondary, | ||
111 | #ifdef CONFIG_HOTPLUG_CPU | ||
112 | .cpu_die = vexpress_cpu_die, | ||
113 | #endif | ||
114 | }; | ||
115 | |||
116 | #endif | ||
diff --git a/arch/arm/mach-vexpress/v2m.c b/arch/arm/mach-vexpress/v2m.c index 4f8b8cb17ff5..38f4f6f37770 100644 --- a/arch/arm/mach-vexpress/v2m.c +++ b/arch/arm/mach-vexpress/v2m.c | |||
@@ -201,8 +201,9 @@ static struct platform_device v2m_cf_device = { | |||
201 | 201 | ||
202 | static struct mmci_platform_data v2m_mmci_data = { | 202 | static struct mmci_platform_data v2m_mmci_data = { |
203 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, | 203 | .ocr_mask = MMC_VDD_32_33|MMC_VDD_33_34, |
204 | .gpio_wp = VEXPRESS_GPIO_MMC_WPROT, | 204 | .status = vexpress_get_mci_cardin, |
205 | .gpio_cd = VEXPRESS_GPIO_MMC_CARDIN, | 205 | .gpio_cd = -1, |
206 | .gpio_wp = -1, | ||
206 | }; | 207 | }; |
207 | 208 | ||
208 | static struct resource v2m_sysreg_resources[] = { | 209 | static struct resource v2m_sysreg_resources[] = { |
@@ -340,11 +341,6 @@ static void __init v2m_init(void) | |||
340 | regulator_register_fixed(0, v2m_eth_supplies, | 341 | regulator_register_fixed(0, v2m_eth_supplies, |
341 | ARRAY_SIZE(v2m_eth_supplies)); | 342 | ARRAY_SIZE(v2m_eth_supplies)); |
342 | 343 | ||
343 | platform_device_register(&v2m_muxfpga_device); | ||
344 | platform_device_register(&v2m_shutdown_device); | ||
345 | platform_device_register(&v2m_reboot_device); | ||
346 | platform_device_register(&v2m_dvimode_device); | ||
347 | |||
348 | platform_device_register(&v2m_sysreg_device); | 344 | platform_device_register(&v2m_sysreg_device); |
349 | platform_device_register(&v2m_pcie_i2c_device); | 345 | platform_device_register(&v2m_pcie_i2c_device); |
350 | platform_device_register(&v2m_ddc_i2c_device); | 346 | platform_device_register(&v2m_ddc_i2c_device); |
@@ -356,6 +352,11 @@ static void __init v2m_init(void) | |||
356 | for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++) | 352 | for (i = 0; i < ARRAY_SIZE(v2m_amba_devs); i++) |
357 | amba_device_register(v2m_amba_devs[i], &iomem_resource); | 353 | amba_device_register(v2m_amba_devs[i], &iomem_resource); |
358 | 354 | ||
355 | vexpress_syscfg_device_register(&v2m_muxfpga_device); | ||
356 | vexpress_syscfg_device_register(&v2m_shutdown_device); | ||
357 | vexpress_syscfg_device_register(&v2m_reboot_device); | ||
358 | vexpress_syscfg_device_register(&v2m_dvimode_device); | ||
359 | |||
359 | ct_desc->init_tile(); | 360 | ct_desc->init_tile(); |
360 | } | 361 | } |
361 | 362 | ||
@@ -369,71 +370,10 @@ MACHINE_START(VEXPRESS, "ARM-Versatile Express") | |||
369 | .init_machine = v2m_init, | 370 | .init_machine = v2m_init, |
370 | MACHINE_END | 371 | MACHINE_END |
371 | 372 | ||
372 | static struct map_desc v2m_rs1_io_desc __initdata = { | ||
373 | .virtual = V2M_PERIPH, | ||
374 | .pfn = __phys_to_pfn(0x1c000000), | ||
375 | .length = SZ_2M, | ||
376 | .type = MT_DEVICE, | ||
377 | }; | ||
378 | |||
379 | static int __init v2m_dt_scan_memory_map(unsigned long node, const char *uname, | ||
380 | int depth, void *data) | ||
381 | { | ||
382 | const char **map = data; | ||
383 | |||
384 | if (strcmp(uname, "motherboard") != 0) | ||
385 | return 0; | ||
386 | |||
387 | *map = of_get_flat_dt_prop(node, "arm,v2m-memory-map", NULL); | ||
388 | |||
389 | return 1; | ||
390 | } | ||
391 | |||
392 | void __init v2m_dt_map_io(void) | ||
393 | { | ||
394 | const char *map = NULL; | ||
395 | |||
396 | of_scan_flat_dt(v2m_dt_scan_memory_map, &map); | ||
397 | |||
398 | if (map && strcmp(map, "rs1") == 0) | ||
399 | iotable_init(&v2m_rs1_io_desc, 1); | ||
400 | else | ||
401 | iotable_init(v2m_io_desc, ARRAY_SIZE(v2m_io_desc)); | ||
402 | |||
403 | #if defined(CONFIG_SMP) | ||
404 | vexpress_dt_smp_map_io(); | ||
405 | #endif | ||
406 | } | ||
407 | |||
408 | void __init v2m_dt_init_early(void) | ||
409 | { | ||
410 | u32 dt_hbi; | ||
411 | |||
412 | vexpress_sysreg_of_early_init(); | ||
413 | |||
414 | /* Confirm board type against DT property, if available */ | ||
415 | if (of_property_read_u32(of_allnodes, "arm,hbi", &dt_hbi) == 0) { | ||
416 | u32 hbi = vexpress_get_hbi(VEXPRESS_SITE_MASTER); | ||
417 | |||
418 | if (WARN_ON(dt_hbi != hbi)) | ||
419 | pr_warning("vexpress: DT HBI (%x) is not matching " | ||
420 | "hardware (%x)!\n", dt_hbi, hbi); | ||
421 | } | ||
422 | |||
423 | versatile_sched_clock_init(vexpress_get_24mhz_clock_base(), 24000000); | ||
424 | } | ||
425 | |||
426 | static const struct of_device_id v2m_dt_bus_match[] __initconst = { | ||
427 | { .compatible = "simple-bus", }, | ||
428 | { .compatible = "arm,amba-bus", }, | ||
429 | { .compatible = "arm,vexpress,config-bus", }, | ||
430 | {} | ||
431 | }; | ||
432 | |||
433 | static void __init v2m_dt_init(void) | 373 | static void __init v2m_dt_init(void) |
434 | { | 374 | { |
435 | l2x0_of_init(0x00400000, 0xfe0fffff); | 375 | l2x0_of_init(0x00400000, 0xfe0fffff); |
436 | of_platform_populate(NULL, v2m_dt_bus_match, NULL, NULL); | 376 | of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL); |
437 | } | 377 | } |
438 | 378 | ||
439 | static const char * const v2m_dt_match[] __initconst = { | 379 | static const char * const v2m_dt_match[] __initconst = { |
@@ -443,9 +383,7 @@ static const char * const v2m_dt_match[] __initconst = { | |||
443 | 383 | ||
444 | DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express") | 384 | DT_MACHINE_START(VEXPRESS_DT, "ARM-Versatile Express") |
445 | .dt_compat = v2m_dt_match, | 385 | .dt_compat = v2m_dt_match, |
446 | .smp = smp_ops(vexpress_smp_ops), | 386 | .smp = smp_ops(vexpress_smp_dt_ops), |
447 | .smp_init = smp_init_ops(vexpress_smp_init_ops), | 387 | .smp_init = smp_init_ops(vexpress_smp_init_ops), |
448 | .map_io = v2m_dt_map_io, | ||
449 | .init_early = v2m_dt_init_early, | ||
450 | .init_machine = v2m_dt_init, | 388 | .init_machine = v2m_dt_init, |
451 | MACHINE_END | 389 | MACHINE_END |
diff --git a/arch/arm/plat-omap/counter_32k.c b/arch/arm/plat-omap/counter_32k.c index 384a776d8eb2..61b4d705c267 100644 --- a/arch/arm/plat-omap/counter_32k.c +++ b/arch/arm/plat-omap/counter_32k.c | |||
@@ -40,7 +40,7 @@ static void __iomem *sync32k_cnt_reg; | |||
40 | 40 | ||
41 | static u64 notrace omap_32k_read_sched_clock(void) | 41 | static u64 notrace omap_32k_read_sched_clock(void) |
42 | { | 42 | { |
43 | return sync32k_cnt_reg ? __raw_readl(sync32k_cnt_reg) : 0; | 43 | return sync32k_cnt_reg ? readl_relaxed(sync32k_cnt_reg) : 0; |
44 | } | 44 | } |
45 | 45 | ||
46 | /** | 46 | /** |
@@ -64,7 +64,7 @@ static void omap_read_persistent_clock(struct timespec *ts) | |||
64 | spin_lock_irqsave(&read_persistent_clock_lock, flags); | 64 | spin_lock_irqsave(&read_persistent_clock_lock, flags); |
65 | 65 | ||
66 | last_cycles = cycles; | 66 | last_cycles = cycles; |
67 | cycles = sync32k_cnt_reg ? __raw_readl(sync32k_cnt_reg) : 0; | 67 | cycles = sync32k_cnt_reg ? readl_relaxed(sync32k_cnt_reg) : 0; |
68 | 68 | ||
69 | nsecs = clocksource_cyc2ns(cycles - last_cycles, | 69 | nsecs = clocksource_cyc2ns(cycles - last_cycles, |
70 | persistent_mult, persistent_shift); | 70 | persistent_mult, persistent_shift); |
@@ -95,7 +95,7 @@ int __init omap_init_clocksource_32k(void __iomem *vbase) | |||
95 | * The 'SCHEME' bits(30-31) of the revision register is used | 95 | * The 'SCHEME' bits(30-31) of the revision register is used |
96 | * to identify the version. | 96 | * to identify the version. |
97 | */ | 97 | */ |
98 | if (__raw_readl(vbase + OMAP2_32KSYNCNT_REV_OFF) & | 98 | if (readl_relaxed(vbase + OMAP2_32KSYNCNT_REV_OFF) & |
99 | OMAP2_32KSYNCNT_REV_SCHEME) | 99 | OMAP2_32KSYNCNT_REV_SCHEME) |
100 | sync32k_cnt_reg = vbase + OMAP2_32KSYNCNT_CR_OFF_HIGH; | 100 | sync32k_cnt_reg = vbase + OMAP2_32KSYNCNT_CR_OFF_HIGH; |
101 | else | 101 | else |
diff --git a/arch/arm/plat-omap/debug-leds.c b/arch/arm/plat-omap/debug-leds.c index aa7ebc6bcd65..48b69de89a5d 100644 --- a/arch/arm/plat-omap/debug-leds.c +++ b/arch/arm/plat-omap/debug-leds.c | |||
@@ -85,12 +85,12 @@ static void dbg_led_set(struct led_classdev *cdev, | |||
85 | struct dbg_led *led = container_of(cdev, struct dbg_led, cdev); | 85 | struct dbg_led *led = container_of(cdev, struct dbg_led, cdev); |
86 | u16 reg; | 86 | u16 reg; |
87 | 87 | ||
88 | reg = __raw_readw(&fpga->leds); | 88 | reg = readw_relaxed(&fpga->leds); |
89 | if (b != LED_OFF) | 89 | if (b != LED_OFF) |
90 | reg |= led->mask; | 90 | reg |= led->mask; |
91 | else | 91 | else |
92 | reg &= ~led->mask; | 92 | reg &= ~led->mask; |
93 | __raw_writew(reg, &fpga->leds); | 93 | writew_relaxed(reg, &fpga->leds); |
94 | } | 94 | } |
95 | 95 | ||
96 | static enum led_brightness dbg_led_get(struct led_classdev *cdev) | 96 | static enum led_brightness dbg_led_get(struct led_classdev *cdev) |
@@ -98,7 +98,7 @@ static enum led_brightness dbg_led_get(struct led_classdev *cdev) | |||
98 | struct dbg_led *led = container_of(cdev, struct dbg_led, cdev); | 98 | struct dbg_led *led = container_of(cdev, struct dbg_led, cdev); |
99 | u16 reg; | 99 | u16 reg; |
100 | 100 | ||
101 | reg = __raw_readw(&fpga->leds); | 101 | reg = readw_relaxed(&fpga->leds); |
102 | return (reg & led->mask) ? LED_FULL : LED_OFF; | 102 | return (reg & led->mask) ? LED_FULL : LED_OFF; |
103 | } | 103 | } |
104 | 104 | ||
@@ -112,7 +112,7 @@ static int fpga_probe(struct platform_device *pdev) | |||
112 | return -ENODEV; | 112 | return -ENODEV; |
113 | 113 | ||
114 | fpga = ioremap(iomem->start, resource_size(iomem)); | 114 | fpga = ioremap(iomem->start, resource_size(iomem)); |
115 | __raw_writew(0xff, &fpga->leds); | 115 | writew_relaxed(0xff, &fpga->leds); |
116 | 116 | ||
117 | for (i = 0; i < ARRAY_SIZE(dbg_leds); i++) { | 117 | for (i = 0; i < ARRAY_SIZE(dbg_leds); i++) { |
118 | struct dbg_led *led; | 118 | struct dbg_led *led; |
@@ -138,15 +138,15 @@ static int fpga_probe(struct platform_device *pdev) | |||
138 | 138 | ||
139 | static int fpga_suspend_noirq(struct device *dev) | 139 | static int fpga_suspend_noirq(struct device *dev) |
140 | { | 140 | { |
141 | fpga_led_state = __raw_readw(&fpga->leds); | 141 | fpga_led_state = readw_relaxed(&fpga->leds); |
142 | __raw_writew(0xff, &fpga->leds); | 142 | writew_relaxed(0xff, &fpga->leds); |
143 | 143 | ||
144 | return 0; | 144 | return 0; |
145 | } | 145 | } |
146 | 146 | ||
147 | static int fpga_resume_noirq(struct device *dev) | 147 | static int fpga_resume_noirq(struct device *dev) |
148 | { | 148 | { |
149 | __raw_writew(~fpga_led_state, &fpga->leds); | 149 | writew_relaxed(~fpga_led_state, &fpga->leds); |
150 | return 0; | 150 | return 0; |
151 | } | 151 | } |
152 | 152 | ||
diff --git a/arch/arm/plat-omap/dmtimer.c b/arch/arm/plat-omap/dmtimer.c index 869254cebf84..db10169a08de 100644 --- a/arch/arm/plat-omap/dmtimer.c +++ b/arch/arm/plat-omap/dmtimer.c | |||
@@ -103,7 +103,7 @@ static void omap_timer_restore_context(struct omap_dm_timer *timer) | |||
103 | timer->context.tmar); | 103 | timer->context.tmar); |
104 | omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, | 104 | omap_dm_timer_write_reg(timer, OMAP_TIMER_IF_CTRL_REG, |
105 | timer->context.tsicr); | 105 | timer->context.tsicr); |
106 | __raw_writel(timer->context.tier, timer->irq_ena); | 106 | writel_relaxed(timer->context.tier, timer->irq_ena); |
107 | omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, | 107 | omap_dm_timer_write_reg(timer, OMAP_TIMER_CTRL_REG, |
108 | timer->context.tclr); | 108 | timer->context.tclr); |
109 | } | 109 | } |
@@ -699,9 +699,9 @@ int omap_dm_timer_set_int_disable(struct omap_dm_timer *timer, u32 mask) | |||
699 | omap_dm_timer_enable(timer); | 699 | omap_dm_timer_enable(timer); |
700 | 700 | ||
701 | if (timer->revision == 1) | 701 | if (timer->revision == 1) |
702 | l = __raw_readl(timer->irq_ena) & ~mask; | 702 | l = readl_relaxed(timer->irq_ena) & ~mask; |
703 | 703 | ||
704 | __raw_writel(l, timer->irq_dis); | 704 | writel_relaxed(l, timer->irq_dis); |
705 | l = omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask; | 705 | l = omap_dm_timer_read_reg(timer, OMAP_TIMER_WAKEUP_EN_REG) & ~mask; |
706 | omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l); | 706 | omap_dm_timer_write_reg(timer, OMAP_TIMER_WAKEUP_EN_REG, l); |
707 | 707 | ||
@@ -722,7 +722,7 @@ unsigned int omap_dm_timer_read_status(struct omap_dm_timer *timer) | |||
722 | return 0; | 722 | return 0; |
723 | } | 723 | } |
724 | 724 | ||
725 | l = __raw_readl(timer->irq_stat); | 725 | l = readl_relaxed(timer->irq_stat); |
726 | 726 | ||
727 | return l; | 727 | return l; |
728 | } | 728 | } |
diff --git a/arch/arm/plat-omap/include/plat/dmtimer.h b/arch/arm/plat-omap/include/plat/dmtimer.h index 2861b155485a..dd79f3005cdf 100644 --- a/arch/arm/plat-omap/include/plat/dmtimer.h +++ b/arch/arm/plat-omap/include/plat/dmtimer.h | |||
@@ -280,20 +280,20 @@ static inline u32 __omap_dm_timer_read(struct omap_dm_timer *timer, u32 reg, | |||
280 | int posted) | 280 | int posted) |
281 | { | 281 | { |
282 | if (posted) | 282 | if (posted) |
283 | while (__raw_readl(timer->pend) & (reg >> WPSHIFT)) | 283 | while (readl_relaxed(timer->pend) & (reg >> WPSHIFT)) |
284 | cpu_relax(); | 284 | cpu_relax(); |
285 | 285 | ||
286 | return __raw_readl(timer->func_base + (reg & 0xff)); | 286 | return readl_relaxed(timer->func_base + (reg & 0xff)); |
287 | } | 287 | } |
288 | 288 | ||
289 | static inline void __omap_dm_timer_write(struct omap_dm_timer *timer, | 289 | static inline void __omap_dm_timer_write(struct omap_dm_timer *timer, |
290 | u32 reg, u32 val, int posted) | 290 | u32 reg, u32 val, int posted) |
291 | { | 291 | { |
292 | if (posted) | 292 | if (posted) |
293 | while (__raw_readl(timer->pend) & (reg >> WPSHIFT)) | 293 | while (readl_relaxed(timer->pend) & (reg >> WPSHIFT)) |
294 | cpu_relax(); | 294 | cpu_relax(); |
295 | 295 | ||
296 | __raw_writel(val, timer->func_base + (reg & 0xff)); | 296 | writel_relaxed(val, timer->func_base + (reg & 0xff)); |
297 | } | 297 | } |
298 | 298 | ||
299 | static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer) | 299 | static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer) |
@@ -301,7 +301,7 @@ static inline void __omap_dm_timer_init_regs(struct omap_dm_timer *timer) | |||
301 | u32 tidr; | 301 | u32 tidr; |
302 | 302 | ||
303 | /* Assume v1 ip if bits [31:16] are zero */ | 303 | /* Assume v1 ip if bits [31:16] are zero */ |
304 | tidr = __raw_readl(timer->io_base); | 304 | tidr = readl_relaxed(timer->io_base); |
305 | if (!(tidr >> 16)) { | 305 | if (!(tidr >> 16)) { |
306 | timer->revision = 1; | 306 | timer->revision = 1; |
307 | timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET; | 307 | timer->irq_stat = timer->io_base + OMAP_TIMER_V1_STAT_OFFSET; |
@@ -385,7 +385,7 @@ static inline void __omap_dm_timer_stop(struct omap_dm_timer *timer, | |||
385 | } | 385 | } |
386 | 386 | ||
387 | /* Ack possibly pending interrupt */ | 387 | /* Ack possibly pending interrupt */ |
388 | __raw_writel(OMAP_TIMER_INT_OVERFLOW, timer->irq_stat); | 388 | writel_relaxed(OMAP_TIMER_INT_OVERFLOW, timer->irq_stat); |
389 | } | 389 | } |
390 | 390 | ||
391 | static inline void __omap_dm_timer_load_start(struct omap_dm_timer *timer, | 391 | static inline void __omap_dm_timer_load_start(struct omap_dm_timer *timer, |
@@ -399,7 +399,7 @@ static inline void __omap_dm_timer_load_start(struct omap_dm_timer *timer, | |||
399 | static inline void __omap_dm_timer_int_enable(struct omap_dm_timer *timer, | 399 | static inline void __omap_dm_timer_int_enable(struct omap_dm_timer *timer, |
400 | unsigned int value) | 400 | unsigned int value) |
401 | { | 401 | { |
402 | __raw_writel(value, timer->irq_ena); | 402 | writel_relaxed(value, timer->irq_ena); |
403 | __omap_dm_timer_write(timer, OMAP_TIMER_WAKEUP_EN_REG, value, 0); | 403 | __omap_dm_timer_write(timer, OMAP_TIMER_WAKEUP_EN_REG, value, 0); |
404 | } | 404 | } |
405 | 405 | ||
@@ -412,7 +412,7 @@ __omap_dm_timer_read_counter(struct omap_dm_timer *timer, int posted) | |||
412 | static inline void __omap_dm_timer_write_status(struct omap_dm_timer *timer, | 412 | static inline void __omap_dm_timer_write_status(struct omap_dm_timer *timer, |
413 | unsigned int value) | 413 | unsigned int value) |
414 | { | 414 | { |
415 | __raw_writel(value, timer->irq_stat); | 415 | writel_relaxed(value, timer->irq_stat); |
416 | } | 416 | } |
417 | 417 | ||
418 | #endif /* __ASM_ARCH_DMTIMER_H */ | 418 | #endif /* __ASM_ARCH_DMTIMER_H */ |
diff --git a/arch/arm/plat-versatile/Kconfig b/arch/arm/plat-versatile/Kconfig index 2c4332b9f948..fce41e93b6a4 100644 --- a/arch/arm/plat-versatile/Kconfig +++ b/arch/arm/plat-versatile/Kconfig | |||
@@ -6,12 +6,6 @@ config PLAT_VERSATILE_CLOCK | |||
6 | config PLAT_VERSATILE_CLCD | 6 | config PLAT_VERSATILE_CLCD |
7 | bool | 7 | bool |
8 | 8 | ||
9 | config PLAT_VERSATILE_LEDS | ||
10 | def_bool y if NEW_LEDS | ||
11 | depends on ARCH_REALVIEW || ARCH_VERSATILE | ||
12 | select LEDS_CLASS | ||
13 | select LEDS_TRIGGERS | ||
14 | |||
15 | config PLAT_VERSATILE_SCHED_CLOCK | 9 | config PLAT_VERSATILE_SCHED_CLOCK |
16 | def_bool y | 10 | def_bool y |
17 | 11 | ||
diff --git a/arch/arm/plat-versatile/Makefile b/arch/arm/plat-versatile/Makefile index f88d448b629c..2e0c472958ae 100644 --- a/arch/arm/plat-versatile/Makefile +++ b/arch/arm/plat-versatile/Makefile | |||
@@ -2,6 +2,5 @@ ccflags-$(CONFIG_ARCH_MULTIPLATFORM) := -I$(srctree)/$(src)/include | |||
2 | 2 | ||
3 | obj-$(CONFIG_PLAT_VERSATILE_CLOCK) += clock.o | 3 | obj-$(CONFIG_PLAT_VERSATILE_CLOCK) += clock.o |
4 | obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o | 4 | obj-$(CONFIG_PLAT_VERSATILE_CLCD) += clcd.o |
5 | obj-$(CONFIG_PLAT_VERSATILE_LEDS) += leds.o | ||
6 | obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o | 5 | obj-$(CONFIG_PLAT_VERSATILE_SCHED_CLOCK) += sched-clock.o |
7 | obj-$(CONFIG_SMP) += headsmp.o platsmp.o | 6 | obj-$(CONFIG_SMP) += headsmp.o platsmp.o |
diff --git a/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi b/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi index 2f2ecd217363..ac2cb2418025 100644 --- a/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi +++ b/arch/arm64/boot/dts/rtsm_ve-motherboard.dtsi | |||
@@ -200,7 +200,7 @@ | |||
200 | }; | 200 | }; |
201 | 201 | ||
202 | mcc { | 202 | mcc { |
203 | compatible = "arm,vexpress,config-bus", "simple-bus"; | 203 | compatible = "arm,vexpress,config-bus"; |
204 | arm,vexpress,config-bridge = <&v2m_sysreg>; | 204 | arm,vexpress,config-bridge = <&v2m_sysreg>; |
205 | 205 | ||
206 | v2m_oscclk1: osc@1 { | 206 | v2m_oscclk1: osc@1 { |
diff --git a/arch/sparc/include/asm/pgtable_64.h b/arch/sparc/include/asm/pgtable_64.h index 0f9e94537eee..fde5abaac0cc 100644 --- a/arch/sparc/include/asm/pgtable_64.h +++ b/arch/sparc/include/asm/pgtable_64.h | |||
@@ -71,6 +71,23 @@ | |||
71 | 71 | ||
72 | #include <linux/sched.h> | 72 | #include <linux/sched.h> |
73 | 73 | ||
74 | extern unsigned long sparc64_valid_addr_bitmap[]; | ||
75 | |||
76 | /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ | ||
77 | static inline bool __kern_addr_valid(unsigned long paddr) | ||
78 | { | ||
79 | if ((paddr >> MAX_PHYS_ADDRESS_BITS) != 0UL) | ||
80 | return false; | ||
81 | return test_bit(paddr >> ILOG2_4MB, sparc64_valid_addr_bitmap); | ||
82 | } | ||
83 | |||
84 | static inline bool kern_addr_valid(unsigned long addr) | ||
85 | { | ||
86 | unsigned long paddr = __pa(addr); | ||
87 | |||
88 | return __kern_addr_valid(paddr); | ||
89 | } | ||
90 | |||
74 | /* Entries per page directory level. */ | 91 | /* Entries per page directory level. */ |
75 | #define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3)) | 92 | #define PTRS_PER_PTE (1UL << (PAGE_SHIFT-3)) |
76 | #define PTRS_PER_PMD (1UL << PMD_BITS) | 93 | #define PTRS_PER_PMD (1UL << PMD_BITS) |
@@ -79,9 +96,12 @@ | |||
79 | /* Kernel has a separate 44bit address space. */ | 96 | /* Kernel has a separate 44bit address space. */ |
80 | #define FIRST_USER_ADDRESS 0 | 97 | #define FIRST_USER_ADDRESS 0 |
81 | 98 | ||
82 | #define pte_ERROR(e) __builtin_trap() | 99 | #define pmd_ERROR(e) \ |
83 | #define pmd_ERROR(e) __builtin_trap() | 100 | pr_err("%s:%d: bad pmd %p(%016lx) seen at (%pS)\n", \ |
84 | #define pgd_ERROR(e) __builtin_trap() | 101 | __FILE__, __LINE__, &(e), pmd_val(e), __builtin_return_address(0)) |
102 | #define pgd_ERROR(e) \ | ||
103 | pr_err("%s:%d: bad pgd %p(%016lx) seen at (%pS)\n", \ | ||
104 | __FILE__, __LINE__, &(e), pgd_val(e), __builtin_return_address(0)) | ||
85 | 105 | ||
86 | #endif /* !(__ASSEMBLY__) */ | 106 | #endif /* !(__ASSEMBLY__) */ |
87 | 107 | ||
@@ -258,8 +278,8 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot) | |||
258 | { | 278 | { |
259 | unsigned long mask, tmp; | 279 | unsigned long mask, tmp; |
260 | 280 | ||
261 | /* SUN4U: 0x600307ffffffecb8 (negated == 0x9ffcf80000001347) | 281 | /* SUN4U: 0x630107ffffffec38 (negated == 0x9cfef800000013c7) |
262 | * SUN4V: 0x30ffffffffffee17 (negated == 0xcf000000000011e8) | 282 | * SUN4V: 0x33ffffffffffee07 (negated == 0xcc000000000011f8) |
263 | * | 283 | * |
264 | * Even if we use negation tricks the result is still a 6 | 284 | * Even if we use negation tricks the result is still a 6 |
265 | * instruction sequence, so don't try to play fancy and just | 285 | * instruction sequence, so don't try to play fancy and just |
@@ -289,10 +309,10 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t prot) | |||
289 | " .previous\n" | 309 | " .previous\n" |
290 | : "=r" (mask), "=r" (tmp) | 310 | : "=r" (mask), "=r" (tmp) |
291 | : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U | | 311 | : "i" (_PAGE_PADDR_4U | _PAGE_MODIFIED_4U | _PAGE_ACCESSED_4U | |
292 | _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | _PAGE_PRESENT_4U | | 312 | _PAGE_CP_4U | _PAGE_CV_4U | _PAGE_E_4U | |
293 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U), | 313 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4U), |
294 | "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | | 314 | "i" (_PAGE_PADDR_4V | _PAGE_MODIFIED_4V | _PAGE_ACCESSED_4V | |
295 | _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | _PAGE_PRESENT_4V | | 315 | _PAGE_CP_4V | _PAGE_CV_4V | _PAGE_E_4V | |
296 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V)); | 316 | _PAGE_SPECIAL | _PAGE_PMD_HUGE | _PAGE_SZALL_4V)); |
297 | 317 | ||
298 | return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask)); | 318 | return __pte((pte_val(pte) & mask) | (pgprot_val(prot) & ~mask)); |
@@ -633,7 +653,7 @@ static inline unsigned long pmd_large(pmd_t pmd) | |||
633 | { | 653 | { |
634 | pte_t pte = __pte(pmd_val(pmd)); | 654 | pte_t pte = __pte(pmd_val(pmd)); |
635 | 655 | ||
636 | return (pte_val(pte) & _PAGE_PMD_HUGE) && pte_present(pte); | 656 | return pte_val(pte) & _PAGE_PMD_HUGE; |
637 | } | 657 | } |
638 | 658 | ||
639 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 659 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
@@ -719,20 +739,6 @@ static inline pmd_t pmd_mkwrite(pmd_t pmd) | |||
719 | return __pmd(pte_val(pte)); | 739 | return __pmd(pte_val(pte)); |
720 | } | 740 | } |
721 | 741 | ||
722 | static inline pmd_t pmd_mknotpresent(pmd_t pmd) | ||
723 | { | ||
724 | unsigned long mask; | ||
725 | |||
726 | if (tlb_type == hypervisor) | ||
727 | mask = _PAGE_PRESENT_4V; | ||
728 | else | ||
729 | mask = _PAGE_PRESENT_4U; | ||
730 | |||
731 | pmd_val(pmd) &= ~mask; | ||
732 | |||
733 | return pmd; | ||
734 | } | ||
735 | |||
736 | static inline pmd_t pmd_mksplitting(pmd_t pmd) | 742 | static inline pmd_t pmd_mksplitting(pmd_t pmd) |
737 | { | 743 | { |
738 | pte_t pte = __pte(pmd_val(pmd)); | 744 | pte_t pte = __pte(pmd_val(pmd)); |
@@ -757,6 +763,20 @@ static inline int pmd_present(pmd_t pmd) | |||
757 | 763 | ||
758 | #define pmd_none(pmd) (!pmd_val(pmd)) | 764 | #define pmd_none(pmd) (!pmd_val(pmd)) |
759 | 765 | ||
766 | /* pmd_bad() is only called on non-trans-huge PMDs. Our encoding is | ||
767 | * very simple, it's just the physical address. PTE tables are of | ||
768 | * size PAGE_SIZE so make sure the sub-PAGE_SIZE bits are clear and | ||
769 | * the top bits outside of the range of any physical address size we | ||
770 | * support are clear as well. We also validate the physical itself. | ||
771 | */ | ||
772 | #define pmd_bad(pmd) ((pmd_val(pmd) & ~PAGE_MASK) || \ | ||
773 | !__kern_addr_valid(pmd_val(pmd))) | ||
774 | |||
775 | #define pud_none(pud) (!pud_val(pud)) | ||
776 | |||
777 | #define pud_bad(pud) ((pud_val(pud) & ~PAGE_MASK) || \ | ||
778 | !__kern_addr_valid(pud_val(pud))) | ||
779 | |||
760 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 780 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
761 | extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, | 781 | extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, |
762 | pmd_t *pmdp, pmd_t pmd); | 782 | pmd_t *pmdp, pmd_t pmd); |
@@ -790,10 +810,7 @@ static inline unsigned long __pmd_page(pmd_t pmd) | |||
790 | #define pud_page_vaddr(pud) \ | 810 | #define pud_page_vaddr(pud) \ |
791 | ((unsigned long) __va(pud_val(pud))) | 811 | ((unsigned long) __va(pud_val(pud))) |
792 | #define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud)) | 812 | #define pud_page(pud) virt_to_page((void *)pud_page_vaddr(pud)) |
793 | #define pmd_bad(pmd) (0) | ||
794 | #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL) | 813 | #define pmd_clear(pmdp) (pmd_val(*(pmdp)) = 0UL) |
795 | #define pud_none(pud) (!pud_val(pud)) | ||
796 | #define pud_bad(pud) (0) | ||
797 | #define pud_present(pud) (pud_val(pud) != 0U) | 814 | #define pud_present(pud) (pud_val(pud) != 0U) |
798 | #define pud_clear(pudp) (pud_val(*(pudp)) = 0UL) | 815 | #define pud_clear(pudp) (pud_val(*(pudp)) = 0UL) |
799 | 816 | ||
@@ -893,6 +910,10 @@ extern void update_mmu_cache(struct vm_area_struct *, unsigned long, pte_t *); | |||
893 | extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, | 910 | extern void update_mmu_cache_pmd(struct vm_area_struct *vma, unsigned long addr, |
894 | pmd_t *pmd); | 911 | pmd_t *pmd); |
895 | 912 | ||
913 | #define __HAVE_ARCH_PMDP_INVALIDATE | ||
914 | extern void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | ||
915 | pmd_t *pmdp); | ||
916 | |||
896 | #define __HAVE_ARCH_PGTABLE_DEPOSIT | 917 | #define __HAVE_ARCH_PGTABLE_DEPOSIT |
897 | extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, | 918 | extern void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, |
898 | pgtable_t pgtable); | 919 | pgtable_t pgtable); |
@@ -919,18 +940,6 @@ extern unsigned long pte_file(pte_t); | |||
919 | extern pte_t pgoff_to_pte(unsigned long); | 940 | extern pte_t pgoff_to_pte(unsigned long); |
920 | #define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL) | 941 | #define PTE_FILE_MAX_BITS (64UL - PAGE_SHIFT - 1UL) |
921 | 942 | ||
922 | extern unsigned long sparc64_valid_addr_bitmap[]; | ||
923 | |||
924 | /* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ | ||
925 | static inline bool kern_addr_valid(unsigned long addr) | ||
926 | { | ||
927 | unsigned long paddr = __pa(addr); | ||
928 | |||
929 | if ((paddr >> 41UL) != 0UL) | ||
930 | return false; | ||
931 | return test_bit(paddr >> 22, sparc64_valid_addr_bitmap); | ||
932 | } | ||
933 | |||
934 | extern int page_in_phys_avail(unsigned long paddr); | 943 | extern int page_in_phys_avail(unsigned long paddr); |
935 | 944 | ||
936 | /* | 945 | /* |
diff --git a/arch/sparc/include/asm/tsb.h b/arch/sparc/include/asm/tsb.h index 2230f80d9fe3..90916f955cac 100644 --- a/arch/sparc/include/asm/tsb.h +++ b/arch/sparc/include/asm/tsb.h | |||
@@ -171,7 +171,8 @@ extern struct tsb_phys_patch_entry __tsb_phys_patch, __tsb_phys_patch_end; | |||
171 | andcc REG1, REG2, %g0; \ | 171 | andcc REG1, REG2, %g0; \ |
172 | be,pt %xcc, 700f; \ | 172 | be,pt %xcc, 700f; \ |
173 | sethi %hi(4 * 1024 * 1024), REG2; \ | 173 | sethi %hi(4 * 1024 * 1024), REG2; \ |
174 | andn REG1, REG2, REG1; \ | 174 | brgez,pn REG1, FAIL_LABEL; \ |
175 | andn REG1, REG2, REG1; \ | ||
175 | and VADDR, REG2, REG2; \ | 176 | and VADDR, REG2, REG2; \ |
176 | brlz,pt REG1, PTE_LABEL; \ | 177 | brlz,pt REG1, PTE_LABEL; \ |
177 | or REG1, REG2, REG1; \ | 178 | or REG1, REG2, REG1; \ |
diff --git a/arch/sparc/kernel/head_64.S b/arch/sparc/kernel/head_64.S index 26b706a1867d..452f04fe8da6 100644 --- a/arch/sparc/kernel/head_64.S +++ b/arch/sparc/kernel/head_64.S | |||
@@ -282,8 +282,8 @@ sun4v_chip_type: | |||
282 | stx %l2, [%l4 + 0x0] | 282 | stx %l2, [%l4 + 0x0] |
283 | ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low | 283 | ldx [%sp + 2047 + 128 + 0x50], %l3 ! physaddr low |
284 | /* 4MB align */ | 284 | /* 4MB align */ |
285 | srlx %l3, 22, %l3 | 285 | srlx %l3, ILOG2_4MB, %l3 |
286 | sllx %l3, 22, %l3 | 286 | sllx %l3, ILOG2_4MB, %l3 |
287 | stx %l3, [%l4 + 0x8] | 287 | stx %l3, [%l4 + 0x8] |
288 | 288 | ||
289 | /* Leave service as-is, "call-method" */ | 289 | /* Leave service as-is, "call-method" */ |
diff --git a/arch/sparc/kernel/ktlb.S b/arch/sparc/kernel/ktlb.S index 542e96ac4d39..605d49204580 100644 --- a/arch/sparc/kernel/ktlb.S +++ b/arch/sparc/kernel/ktlb.S | |||
@@ -277,7 +277,7 @@ kvmap_dtlb_load: | |||
277 | #ifdef CONFIG_SPARSEMEM_VMEMMAP | 277 | #ifdef CONFIG_SPARSEMEM_VMEMMAP |
278 | kvmap_vmemmap: | 278 | kvmap_vmemmap: |
279 | sub %g4, %g5, %g5 | 279 | sub %g4, %g5, %g5 |
280 | srlx %g5, 22, %g5 | 280 | srlx %g5, ILOG2_4MB, %g5 |
281 | sethi %hi(vmemmap_table), %g1 | 281 | sethi %hi(vmemmap_table), %g1 |
282 | sllx %g5, 3, %g5 | 282 | sllx %g5, 3, %g5 |
283 | or %g1, %lo(vmemmap_table), %g1 | 283 | or %g1, %lo(vmemmap_table), %g1 |
diff --git a/arch/sparc/kernel/nmi.c b/arch/sparc/kernel/nmi.c index 6479256fd5a4..337094556916 100644 --- a/arch/sparc/kernel/nmi.c +++ b/arch/sparc/kernel/nmi.c | |||
@@ -68,27 +68,16 @@ EXPORT_SYMBOL(touch_nmi_watchdog); | |||
68 | 68 | ||
69 | static void die_nmi(const char *str, struct pt_regs *regs, int do_panic) | 69 | static void die_nmi(const char *str, struct pt_regs *regs, int do_panic) |
70 | { | 70 | { |
71 | int this_cpu = smp_processor_id(); | ||
72 | |||
71 | if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, | 73 | if (notify_die(DIE_NMIWATCHDOG, str, regs, 0, |
72 | pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) | 74 | pt_regs_trap_type(regs), SIGINT) == NOTIFY_STOP) |
73 | return; | 75 | return; |
74 | 76 | ||
75 | console_verbose(); | ||
76 | bust_spinlocks(1); | ||
77 | |||
78 | printk(KERN_EMERG "%s", str); | ||
79 | printk(" on CPU%d, ip %08lx, registers:\n", | ||
80 | smp_processor_id(), regs->tpc); | ||
81 | show_regs(regs); | ||
82 | dump_stack(); | ||
83 | |||
84 | bust_spinlocks(0); | ||
85 | |||
86 | if (do_panic || panic_on_oops) | 77 | if (do_panic || panic_on_oops) |
87 | panic("Non maskable interrupt"); | 78 | panic("Watchdog detected hard LOCKUP on cpu %d", this_cpu); |
88 | 79 | else | |
89 | nmi_exit(); | 80 | WARN(1, "Watchdog detected hard LOCKUP on cpu %d", this_cpu); |
90 | local_irq_enable(); | ||
91 | do_exit(SIGBUS); | ||
92 | } | 81 | } |
93 | 82 | ||
94 | notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) | 83 | notrace __kprobes void perfctr_irq(int irq, struct pt_regs *regs) |
diff --git a/arch/sparc/kernel/smp_64.c b/arch/sparc/kernel/smp_64.c index 9781048161ab..745a3633ce14 100644 --- a/arch/sparc/kernel/smp_64.c +++ b/arch/sparc/kernel/smp_64.c | |||
@@ -149,7 +149,7 @@ void cpu_panic(void) | |||
149 | #define NUM_ROUNDS 64 /* magic value */ | 149 | #define NUM_ROUNDS 64 /* magic value */ |
150 | #define NUM_ITERS 5 /* likewise */ | 150 | #define NUM_ITERS 5 /* likewise */ |
151 | 151 | ||
152 | static DEFINE_SPINLOCK(itc_sync_lock); | 152 | static DEFINE_RAW_SPINLOCK(itc_sync_lock); |
153 | static unsigned long go[SLAVE + 1]; | 153 | static unsigned long go[SLAVE + 1]; |
154 | 154 | ||
155 | #define DEBUG_TICK_SYNC 0 | 155 | #define DEBUG_TICK_SYNC 0 |
@@ -257,7 +257,7 @@ static void smp_synchronize_one_tick(int cpu) | |||
257 | go[MASTER] = 0; | 257 | go[MASTER] = 0; |
258 | membar_safe("#StoreLoad"); | 258 | membar_safe("#StoreLoad"); |
259 | 259 | ||
260 | spin_lock_irqsave(&itc_sync_lock, flags); | 260 | raw_spin_lock_irqsave(&itc_sync_lock, flags); |
261 | { | 261 | { |
262 | for (i = 0; i < NUM_ROUNDS*NUM_ITERS; i++) { | 262 | for (i = 0; i < NUM_ROUNDS*NUM_ITERS; i++) { |
263 | while (!go[MASTER]) | 263 | while (!go[MASTER]) |
@@ -268,7 +268,7 @@ static void smp_synchronize_one_tick(int cpu) | |||
268 | membar_safe("#StoreLoad"); | 268 | membar_safe("#StoreLoad"); |
269 | } | 269 | } |
270 | } | 270 | } |
271 | spin_unlock_irqrestore(&itc_sync_lock, flags); | 271 | raw_spin_unlock_irqrestore(&itc_sync_lock, flags); |
272 | } | 272 | } |
273 | 273 | ||
274 | #if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU) | 274 | #if defined(CONFIG_SUN_LDOMS) && defined(CONFIG_HOTPLUG_CPU) |
diff --git a/arch/sparc/kernel/sys32.S b/arch/sparc/kernel/sys32.S index f7c72b6efc27..d066eb18650c 100644 --- a/arch/sparc/kernel/sys32.S +++ b/arch/sparc/kernel/sys32.S | |||
@@ -44,7 +44,7 @@ SIGN1(sys32_timer_settime, compat_sys_timer_settime, %o1) | |||
44 | SIGN1(sys32_io_submit, compat_sys_io_submit, %o1) | 44 | SIGN1(sys32_io_submit, compat_sys_io_submit, %o1) |
45 | SIGN1(sys32_mq_open, compat_sys_mq_open, %o1) | 45 | SIGN1(sys32_mq_open, compat_sys_mq_open, %o1) |
46 | SIGN1(sys32_select, compat_sys_select, %o0) | 46 | SIGN1(sys32_select, compat_sys_select, %o0) |
47 | SIGN3(sys32_futex, compat_sys_futex, %o1, %o2, %o5) | 47 | SIGN1(sys32_futex, compat_sys_futex, %o1) |
48 | SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0) | 48 | SIGN1(sys32_recvfrom, compat_sys_recvfrom, %o0) |
49 | SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0) | 49 | SIGN1(sys32_recvmsg, compat_sys_recvmsg, %o0) |
50 | SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0) | 50 | SIGN1(sys32_sendmsg, compat_sys_sendmsg, %o0) |
diff --git a/arch/sparc/kernel/unaligned_64.c b/arch/sparc/kernel/unaligned_64.c index 3c1a7cb31579..35ab8b60d256 100644 --- a/arch/sparc/kernel/unaligned_64.c +++ b/arch/sparc/kernel/unaligned_64.c | |||
@@ -166,17 +166,23 @@ static unsigned long *fetch_reg_addr(unsigned int reg, struct pt_regs *regs) | |||
166 | unsigned long compute_effective_address(struct pt_regs *regs, | 166 | unsigned long compute_effective_address(struct pt_regs *regs, |
167 | unsigned int insn, unsigned int rd) | 167 | unsigned int insn, unsigned int rd) |
168 | { | 168 | { |
169 | int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; | ||
169 | unsigned int rs1 = (insn >> 14) & 0x1f; | 170 | unsigned int rs1 = (insn >> 14) & 0x1f; |
170 | unsigned int rs2 = insn & 0x1f; | 171 | unsigned int rs2 = insn & 0x1f; |
171 | int from_kernel = (regs->tstate & TSTATE_PRIV) != 0; | 172 | unsigned long addr; |
172 | 173 | ||
173 | if (insn & 0x2000) { | 174 | if (insn & 0x2000) { |
174 | maybe_flush_windows(rs1, 0, rd, from_kernel); | 175 | maybe_flush_windows(rs1, 0, rd, from_kernel); |
175 | return (fetch_reg(rs1, regs) + sign_extend_imm13(insn)); | 176 | addr = (fetch_reg(rs1, regs) + sign_extend_imm13(insn)); |
176 | } else { | 177 | } else { |
177 | maybe_flush_windows(rs1, rs2, rd, from_kernel); | 178 | maybe_flush_windows(rs1, rs2, rd, from_kernel); |
178 | return (fetch_reg(rs1, regs) + fetch_reg(rs2, regs)); | 179 | addr = (fetch_reg(rs1, regs) + fetch_reg(rs2, regs)); |
179 | } | 180 | } |
181 | |||
182 | if (!from_kernel && test_thread_flag(TIF_32BIT)) | ||
183 | addr &= 0xffffffff; | ||
184 | |||
185 | return addr; | ||
180 | } | 186 | } |
181 | 187 | ||
182 | /* This is just to make gcc think die_if_kernel does return... */ | 188 | /* This is just to make gcc think die_if_kernel does return... */ |
diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c index 69bb818fdd79..a8ff0d1a3b69 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c | |||
@@ -96,38 +96,51 @@ static unsigned int get_user_insn(unsigned long tpc) | |||
96 | pte_t *ptep, pte; | 96 | pte_t *ptep, pte; |
97 | unsigned long pa; | 97 | unsigned long pa; |
98 | u32 insn = 0; | 98 | u32 insn = 0; |
99 | unsigned long pstate; | ||
100 | 99 | ||
101 | if (pgd_none(*pgdp)) | 100 | if (pgd_none(*pgdp) || unlikely(pgd_bad(*pgdp))) |
102 | goto outret; | 101 | goto out; |
103 | pudp = pud_offset(pgdp, tpc); | 102 | pudp = pud_offset(pgdp, tpc); |
104 | if (pud_none(*pudp)) | 103 | if (pud_none(*pudp) || unlikely(pud_bad(*pudp))) |
105 | goto outret; | 104 | goto out; |
106 | pmdp = pmd_offset(pudp, tpc); | ||
107 | if (pmd_none(*pmdp)) | ||
108 | goto outret; | ||
109 | 105 | ||
110 | /* This disables preemption for us as well. */ | 106 | /* This disables preemption for us as well. */ |
111 | __asm__ __volatile__("rdpr %%pstate, %0" : "=r" (pstate)); | 107 | local_irq_disable(); |
112 | __asm__ __volatile__("wrpr %0, %1, %%pstate" | ||
113 | : : "r" (pstate), "i" (PSTATE_IE)); | ||
114 | ptep = pte_offset_map(pmdp, tpc); | ||
115 | pte = *ptep; | ||
116 | if (!pte_present(pte)) | ||
117 | goto out; | ||
118 | 108 | ||
119 | pa = (pte_pfn(pte) << PAGE_SHIFT); | 109 | pmdp = pmd_offset(pudp, tpc); |
120 | pa += (tpc & ~PAGE_MASK); | 110 | if (pmd_none(*pmdp) || unlikely(pmd_bad(*pmdp))) |
111 | goto out_irq_enable; | ||
112 | |||
113 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
114 | if (pmd_trans_huge(*pmdp)) { | ||
115 | if (pmd_trans_splitting(*pmdp)) | ||
116 | goto out_irq_enable; | ||
121 | 117 | ||
122 | /* Use phys bypass so we don't pollute dtlb/dcache. */ | 118 | pa = pmd_pfn(*pmdp) << PAGE_SHIFT; |
123 | __asm__ __volatile__("lduwa [%1] %2, %0" | 119 | pa += tpc & ~HPAGE_MASK; |
124 | : "=r" (insn) | ||
125 | : "r" (pa), "i" (ASI_PHYS_USE_EC)); | ||
126 | 120 | ||
121 | /* Use phys bypass so we don't pollute dtlb/dcache. */ | ||
122 | __asm__ __volatile__("lduwa [%1] %2, %0" | ||
123 | : "=r" (insn) | ||
124 | : "r" (pa), "i" (ASI_PHYS_USE_EC)); | ||
125 | } else | ||
126 | #endif | ||
127 | { | ||
128 | ptep = pte_offset_map(pmdp, tpc); | ||
129 | pte = *ptep; | ||
130 | if (pte_present(pte)) { | ||
131 | pa = (pte_pfn(pte) << PAGE_SHIFT); | ||
132 | pa += (tpc & ~PAGE_MASK); | ||
133 | |||
134 | /* Use phys bypass so we don't pollute dtlb/dcache. */ | ||
135 | __asm__ __volatile__("lduwa [%1] %2, %0" | ||
136 | : "=r" (insn) | ||
137 | : "r" (pa), "i" (ASI_PHYS_USE_EC)); | ||
138 | } | ||
139 | pte_unmap(ptep); | ||
140 | } | ||
141 | out_irq_enable: | ||
142 | local_irq_enable(); | ||
127 | out: | 143 | out: |
128 | pte_unmap(ptep); | ||
129 | __asm__ __volatile__("wrpr %0, 0x0, %%pstate" : : "r" (pstate)); | ||
130 | outret: | ||
131 | return insn; | 144 | return insn; |
132 | } | 145 | } |
133 | 146 | ||
@@ -153,7 +166,8 @@ show_signal_msg(struct pt_regs *regs, int sig, int code, | |||
153 | } | 166 | } |
154 | 167 | ||
155 | static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, | 168 | static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, |
156 | unsigned int insn, int fault_code) | 169 | unsigned long fault_addr, unsigned int insn, |
170 | int fault_code) | ||
157 | { | 171 | { |
158 | unsigned long addr; | 172 | unsigned long addr; |
159 | siginfo_t info; | 173 | siginfo_t info; |
@@ -161,10 +175,18 @@ static void do_fault_siginfo(int code, int sig, struct pt_regs *regs, | |||
161 | info.si_code = code; | 175 | info.si_code = code; |
162 | info.si_signo = sig; | 176 | info.si_signo = sig; |
163 | info.si_errno = 0; | 177 | info.si_errno = 0; |
164 | if (fault_code & FAULT_CODE_ITLB) | 178 | if (fault_code & FAULT_CODE_ITLB) { |
165 | addr = regs->tpc; | 179 | addr = regs->tpc; |
166 | else | 180 | } else { |
167 | addr = compute_effective_address(regs, insn, 0); | 181 | /* If we were able to probe the faulting instruction, use it |
182 | * to compute a precise fault address. Otherwise use the fault | ||
183 | * time provided address which may only have page granularity. | ||
184 | */ | ||
185 | if (insn) | ||
186 | addr = compute_effective_address(regs, insn, 0); | ||
187 | else | ||
188 | addr = fault_addr; | ||
189 | } | ||
168 | info.si_addr = (void __user *) addr; | 190 | info.si_addr = (void __user *) addr; |
169 | info.si_trapno = 0; | 191 | info.si_trapno = 0; |
170 | 192 | ||
@@ -239,7 +261,7 @@ static void __kprobes do_kernel_fault(struct pt_regs *regs, int si_code, | |||
239 | /* The si_code was set to make clear whether | 261 | /* The si_code was set to make clear whether |
240 | * this was a SEGV_MAPERR or SEGV_ACCERR fault. | 262 | * this was a SEGV_MAPERR or SEGV_ACCERR fault. |
241 | */ | 263 | */ |
242 | do_fault_siginfo(si_code, SIGSEGV, regs, insn, fault_code); | 264 | do_fault_siginfo(si_code, SIGSEGV, regs, address, insn, fault_code); |
243 | return; | 265 | return; |
244 | } | 266 | } |
245 | 267 | ||
@@ -525,7 +547,7 @@ do_sigbus: | |||
525 | * Send a sigbus, regardless of whether we were in kernel | 547 | * Send a sigbus, regardless of whether we were in kernel |
526 | * or user mode. | 548 | * or user mode. |
527 | */ | 549 | */ |
528 | do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, insn, fault_code); | 550 | do_fault_siginfo(BUS_ADRERR, SIGBUS, regs, address, insn, fault_code); |
529 | 551 | ||
530 | /* Kernel mode? Handle exceptions or die */ | 552 | /* Kernel mode? Handle exceptions or die */ |
531 | if (regs->tstate & TSTATE_PRIV) | 553 | if (regs->tstate & TSTATE_PRIV) |
diff --git a/arch/sparc/mm/gup.c b/arch/sparc/mm/gup.c index c4d3da68b800..1aed0432c64b 100644 --- a/arch/sparc/mm/gup.c +++ b/arch/sparc/mm/gup.c | |||
@@ -73,7 +73,7 @@ static int gup_huge_pmd(pmd_t *pmdp, pmd_t pmd, unsigned long addr, | |||
73 | struct page *head, *page, *tail; | 73 | struct page *head, *page, *tail; |
74 | int refs; | 74 | int refs; |
75 | 75 | ||
76 | if (!pmd_large(pmd)) | 76 | if (!(pmd_val(pmd) & _PAGE_VALID)) |
77 | return 0; | 77 | return 0; |
78 | 78 | ||
79 | if (write && !pmd_write(pmd)) | 79 | if (write && !pmd_write(pmd)) |
diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index eafbc65c9c47..ed3c969a5f4c 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c | |||
@@ -588,7 +588,7 @@ static void __init remap_kernel(void) | |||
588 | int i, tlb_ent = sparc64_highest_locked_tlbent(); | 588 | int i, tlb_ent = sparc64_highest_locked_tlbent(); |
589 | 589 | ||
590 | tte_vaddr = (unsigned long) KERNBASE; | 590 | tte_vaddr = (unsigned long) KERNBASE; |
591 | phys_page = (prom_boot_mapping_phys_low >> 22UL) << 22UL; | 591 | phys_page = (prom_boot_mapping_phys_low >> ILOG2_4MB) << ILOG2_4MB; |
592 | tte_data = kern_large_tte(phys_page); | 592 | tte_data = kern_large_tte(phys_page); |
593 | 593 | ||
594 | kern_locked_tte_data = tte_data; | 594 | kern_locked_tte_data = tte_data; |
@@ -1881,7 +1881,7 @@ void __init paging_init(void) | |||
1881 | 1881 | ||
1882 | BUILD_BUG_ON(NR_CPUS > 4096); | 1882 | BUILD_BUG_ON(NR_CPUS > 4096); |
1883 | 1883 | ||
1884 | kern_base = (prom_boot_mapping_phys_low >> 22UL) << 22UL; | 1884 | kern_base = (prom_boot_mapping_phys_low >> ILOG2_4MB) << ILOG2_4MB; |
1885 | kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; | 1885 | kern_size = (unsigned long)&_end - (unsigned long)KERNBASE; |
1886 | 1886 | ||
1887 | /* Invalidate both kernel TSBs. */ | 1887 | /* Invalidate both kernel TSBs. */ |
@@ -1937,7 +1937,7 @@ void __init paging_init(void) | |||
1937 | shift = kern_base + PAGE_OFFSET - ((unsigned long)KERNBASE); | 1937 | shift = kern_base + PAGE_OFFSET - ((unsigned long)KERNBASE); |
1938 | 1938 | ||
1939 | real_end = (unsigned long)_end; | 1939 | real_end = (unsigned long)_end; |
1940 | num_kernel_image_mappings = DIV_ROUND_UP(real_end - KERNBASE, 1 << 22); | 1940 | num_kernel_image_mappings = DIV_ROUND_UP(real_end - KERNBASE, 1 << ILOG2_4MB); |
1941 | printk("Kernel: Using %d locked TLB entries for main kernel image.\n", | 1941 | printk("Kernel: Using %d locked TLB entries for main kernel image.\n", |
1942 | num_kernel_image_mappings); | 1942 | num_kernel_image_mappings); |
1943 | 1943 | ||
@@ -2094,7 +2094,7 @@ static void __init setup_valid_addr_bitmap_from_pavail(unsigned long *bitmap) | |||
2094 | 2094 | ||
2095 | if (new_start <= old_start && | 2095 | if (new_start <= old_start && |
2096 | new_end >= (old_start + PAGE_SIZE)) { | 2096 | new_end >= (old_start + PAGE_SIZE)) { |
2097 | set_bit(old_start >> 22, bitmap); | 2097 | set_bit(old_start >> ILOG2_4MB, bitmap); |
2098 | goto do_next_page; | 2098 | goto do_next_page; |
2099 | } | 2099 | } |
2100 | } | 2100 | } |
@@ -2143,7 +2143,7 @@ void __init mem_init(void) | |||
2143 | addr = PAGE_OFFSET + kern_base; | 2143 | addr = PAGE_OFFSET + kern_base; |
2144 | last = PAGE_ALIGN(kern_size) + addr; | 2144 | last = PAGE_ALIGN(kern_size) + addr; |
2145 | while (addr < last) { | 2145 | while (addr < last) { |
2146 | set_bit(__pa(addr) >> 22, sparc64_valid_addr_bitmap); | 2146 | set_bit(__pa(addr) >> ILOG2_4MB, sparc64_valid_addr_bitmap); |
2147 | addr += PAGE_SIZE; | 2147 | addr += PAGE_SIZE; |
2148 | } | 2148 | } |
2149 | 2149 | ||
@@ -2267,7 +2267,7 @@ int __meminit vmemmap_populate(unsigned long vstart, unsigned long vend, | |||
2267 | void *block; | 2267 | void *block; |
2268 | 2268 | ||
2269 | if (!(*vmem_pp & _PAGE_VALID)) { | 2269 | if (!(*vmem_pp & _PAGE_VALID)) { |
2270 | block = vmemmap_alloc_block(1UL << 22, node); | 2270 | block = vmemmap_alloc_block(1UL << ILOG2_4MB, node); |
2271 | if (!block) | 2271 | if (!block) |
2272 | return -ENOMEM; | 2272 | return -ENOMEM; |
2273 | 2273 | ||
diff --git a/arch/sparc/mm/tlb.c b/arch/sparc/mm/tlb.c index b12cb5e72812..b89aba217e3b 100644 --- a/arch/sparc/mm/tlb.c +++ b/arch/sparc/mm/tlb.c | |||
@@ -134,7 +134,7 @@ no_cache_flush: | |||
134 | 134 | ||
135 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 135 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
136 | static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr, | 136 | static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr, |
137 | pmd_t pmd, bool exec) | 137 | pmd_t pmd) |
138 | { | 138 | { |
139 | unsigned long end; | 139 | unsigned long end; |
140 | pte_t *pte; | 140 | pte_t *pte; |
@@ -142,8 +142,11 @@ static void tlb_batch_pmd_scan(struct mm_struct *mm, unsigned long vaddr, | |||
142 | pte = pte_offset_map(&pmd, vaddr); | 142 | pte = pte_offset_map(&pmd, vaddr); |
143 | end = vaddr + HPAGE_SIZE; | 143 | end = vaddr + HPAGE_SIZE; |
144 | while (vaddr < end) { | 144 | while (vaddr < end) { |
145 | if (pte_val(*pte) & _PAGE_VALID) | 145 | if (pte_val(*pte) & _PAGE_VALID) { |
146 | bool exec = pte_exec(*pte); | ||
147 | |||
146 | tlb_batch_add_one(mm, vaddr, exec); | 148 | tlb_batch_add_one(mm, vaddr, exec); |
149 | } | ||
147 | pte++; | 150 | pte++; |
148 | vaddr += PAGE_SIZE; | 151 | vaddr += PAGE_SIZE; |
149 | } | 152 | } |
@@ -177,19 +180,30 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, | |||
177 | } | 180 | } |
178 | 181 | ||
179 | if (!pmd_none(orig)) { | 182 | if (!pmd_none(orig)) { |
180 | pte_t orig_pte = __pte(pmd_val(orig)); | ||
181 | bool exec = pte_exec(orig_pte); | ||
182 | |||
183 | addr &= HPAGE_MASK; | 183 | addr &= HPAGE_MASK; |
184 | if (pmd_trans_huge(orig)) { | 184 | if (pmd_trans_huge(orig)) { |
185 | pte_t orig_pte = __pte(pmd_val(orig)); | ||
186 | bool exec = pte_exec(orig_pte); | ||
187 | |||
185 | tlb_batch_add_one(mm, addr, exec); | 188 | tlb_batch_add_one(mm, addr, exec); |
186 | tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec); | 189 | tlb_batch_add_one(mm, addr + REAL_HPAGE_SIZE, exec); |
187 | } else { | 190 | } else { |
188 | tlb_batch_pmd_scan(mm, addr, orig, exec); | 191 | tlb_batch_pmd_scan(mm, addr, orig); |
189 | } | 192 | } |
190 | } | 193 | } |
191 | } | 194 | } |
192 | 195 | ||
196 | void pmdp_invalidate(struct vm_area_struct *vma, unsigned long address, | ||
197 | pmd_t *pmdp) | ||
198 | { | ||
199 | pmd_t entry = *pmdp; | ||
200 | |||
201 | pmd_val(entry) &= ~_PAGE_VALID; | ||
202 | |||
203 | set_pmd_at(vma->vm_mm, address, pmdp, entry); | ||
204 | flush_tlb_range(vma, address, address + HPAGE_PMD_SIZE); | ||
205 | } | ||
206 | |||
193 | void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, | 207 | void pgtable_trans_huge_deposit(struct mm_struct *mm, pmd_t *pmdp, |
194 | pgtable_t pgtable) | 208 | pgtable_t pgtable) |
195 | { | 209 | { |
diff --git a/arch/x86/Makefile b/arch/x86/Makefile index ce6ad7e6a7d7..33f71b01fd22 100644 --- a/arch/x86/Makefile +++ b/arch/x86/Makefile | |||
@@ -79,6 +79,7 @@ else | |||
79 | UTS_MACHINE := x86_64 | 79 | UTS_MACHINE := x86_64 |
80 | CHECKFLAGS += -D__x86_64__ -m64 | 80 | CHECKFLAGS += -D__x86_64__ -m64 |
81 | 81 | ||
82 | biarch := -m64 | ||
82 | KBUILD_AFLAGS += -m64 | 83 | KBUILD_AFLAGS += -m64 |
83 | KBUILD_CFLAGS += -m64 | 84 | KBUILD_CFLAGS += -m64 |
84 | 85 | ||
diff --git a/arch/x86/boot/Makefile b/arch/x86/boot/Makefile index abb9eba61b50..dbe8dd2fe247 100644 --- a/arch/x86/boot/Makefile +++ b/arch/x86/boot/Makefile | |||
@@ -71,7 +71,7 @@ $(obj)/vmlinux.bin: $(obj)/compressed/vmlinux FORCE | |||
71 | 71 | ||
72 | SETUP_OBJS = $(addprefix $(obj)/,$(setup-y)) | 72 | SETUP_OBJS = $(addprefix $(obj)/,$(setup-y)) |
73 | 73 | ||
74 | sed-voffset := -e 's/^\([0-9a-fA-F]*\) . \(_text\|_end\)$$/\#define VO_\2 0x\1/p' | 74 | sed-voffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(_text\|_end\)$$/\#define VO_\2 0x\1/p' |
75 | 75 | ||
76 | quiet_cmd_voffset = VOFFSET $@ | 76 | quiet_cmd_voffset = VOFFSET $@ |
77 | cmd_voffset = $(NM) $< | sed -n $(sed-voffset) > $@ | 77 | cmd_voffset = $(NM) $< | sed -n $(sed-voffset) > $@ |
@@ -80,7 +80,7 @@ targets += voffset.h | |||
80 | $(obj)/voffset.h: vmlinux FORCE | 80 | $(obj)/voffset.h: vmlinux FORCE |
81 | $(call if_changed,voffset) | 81 | $(call if_changed,voffset) |
82 | 82 | ||
83 | sed-zoffset := -e 's/^\([0-9a-fA-F]*\) . \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p' | 83 | sed-zoffset := -e 's/^\([0-9a-fA-F]*\) [ABCDGRSTVW] \(startup_32\|startup_64\|efi32_stub_entry\|efi64_stub_entry\|efi_pe_entry\|input_data\|_end\|z_.*\)$$/\#define ZO_\2 0x\1/p' |
84 | 84 | ||
85 | quiet_cmd_zoffset = ZOFFSET $@ | 85 | quiet_cmd_zoffset = ZOFFSET $@ |
86 | cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@ | 86 | cmd_zoffset = $(NM) $< | sed -n $(sed-zoffset) > $@ |
diff --git a/arch/x86/boot/compressed/misc.c b/arch/x86/boot/compressed/misc.c index 17684615374b..57ab74df7eea 100644 --- a/arch/x86/boot/compressed/misc.c +++ b/arch/x86/boot/compressed/misc.c | |||
@@ -354,7 +354,7 @@ static void parse_elf(void *output) | |||
354 | free(phdrs); | 354 | free(phdrs); |
355 | } | 355 | } |
356 | 356 | ||
357 | asmlinkage void *decompress_kernel(void *rmode, memptr heap, | 357 | asmlinkage __visible void *decompress_kernel(void *rmode, memptr heap, |
358 | unsigned char *input_data, | 358 | unsigned char *input_data, |
359 | unsigned long input_len, | 359 | unsigned long input_len, |
360 | unsigned char *output, | 360 | unsigned char *output, |
diff --git a/arch/x86/include/asm/hpet.h b/arch/x86/include/asm/hpet.h index b18df579c0e9..36f7125945e3 100644 --- a/arch/x86/include/asm/hpet.h +++ b/arch/x86/include/asm/hpet.h | |||
@@ -63,6 +63,7 @@ | |||
63 | /* hpet memory map physical address */ | 63 | /* hpet memory map physical address */ |
64 | extern unsigned long hpet_address; | 64 | extern unsigned long hpet_address; |
65 | extern unsigned long force_hpet_address; | 65 | extern unsigned long force_hpet_address; |
66 | extern int boot_hpet_disable; | ||
66 | extern u8 hpet_blockid; | 67 | extern u8 hpet_blockid; |
67 | extern int hpet_force_user; | 68 | extern int hpet_force_user; |
68 | extern u8 hpet_msi_disable; | 69 | extern u8 hpet_msi_disable; |
diff --git a/arch/x86/include/uapi/asm/msr-index.h b/arch/x86/include/uapi/asm/msr-index.h index c827ace3121b..fcf2b3ae1bf0 100644 --- a/arch/x86/include/uapi/asm/msr-index.h +++ b/arch/x86/include/uapi/asm/msr-index.h | |||
@@ -384,7 +384,7 @@ | |||
384 | #define MSR_IA32_MISC_ENABLE_MWAIT_BIT 18 | 384 | #define MSR_IA32_MISC_ENABLE_MWAIT_BIT 18 |
385 | #define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << MSR_IA32_MISC_ENABLE_MWAIT_BIT) | 385 | #define MSR_IA32_MISC_ENABLE_MWAIT (1ULL << MSR_IA32_MISC_ENABLE_MWAIT_BIT) |
386 | #define MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT 22 | 386 | #define MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT 22 |
387 | #define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT); | 387 | #define MSR_IA32_MISC_ENABLE_LIMIT_CPUID (1ULL << MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT) |
388 | #define MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT 23 | 388 | #define MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT 23 |
389 | #define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT) | 389 | #define MSR_IA32_MISC_ENABLE_XTPR_DISABLE (1ULL << MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT) |
390 | #define MSR_IA32_MISC_ENABLE_XD_DISABLE_BIT 34 | 390 | #define MSR_IA32_MISC_ENABLE_XD_DISABLE_BIT 34 |
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 3a2ae4c88948..31368207837c 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
@@ -31,7 +31,7 @@ static char temp_stack[4096]; | |||
31 | * | 31 | * |
32 | * Wrapper around acpi_enter_sleep_state() to be called by assmebly. | 32 | * Wrapper around acpi_enter_sleep_state() to be called by assmebly. |
33 | */ | 33 | */ |
34 | acpi_status asmlinkage x86_acpi_enter_sleep_state(u8 state) | 34 | acpi_status asmlinkage __visible x86_acpi_enter_sleep_state(u8 state) |
35 | { | 35 | { |
36 | return acpi_enter_sleep_state(state); | 36 | return acpi_enter_sleep_state(state); |
37 | } | 37 | } |
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c index d23aa82e7a7b..992060e09897 100644 --- a/arch/x86/kernel/apic/io_apic.c +++ b/arch/x86/kernel/apic/io_apic.c | |||
@@ -2189,7 +2189,7 @@ void send_cleanup_vector(struct irq_cfg *cfg) | |||
2189 | cfg->move_in_progress = 0; | 2189 | cfg->move_in_progress = 0; |
2190 | } | 2190 | } |
2191 | 2191 | ||
2192 | asmlinkage void smp_irq_move_cleanup_interrupt(void) | 2192 | asmlinkage __visible void smp_irq_move_cleanup_interrupt(void) |
2193 | { | 2193 | { |
2194 | unsigned vector, me; | 2194 | unsigned vector, me; |
2195 | 2195 | ||
diff --git a/arch/x86/kernel/cpu/mcheck/therm_throt.c b/arch/x86/kernel/cpu/mcheck/therm_throt.c index d921b7ee6595..36a1bb6d1ee0 100644 --- a/arch/x86/kernel/cpu/mcheck/therm_throt.c +++ b/arch/x86/kernel/cpu/mcheck/therm_throt.c | |||
@@ -429,14 +429,14 @@ static inline void __smp_thermal_interrupt(void) | |||
429 | smp_thermal_vector(); | 429 | smp_thermal_vector(); |
430 | } | 430 | } |
431 | 431 | ||
432 | asmlinkage void smp_thermal_interrupt(struct pt_regs *regs) | 432 | asmlinkage __visible void smp_thermal_interrupt(struct pt_regs *regs) |
433 | { | 433 | { |
434 | entering_irq(); | 434 | entering_irq(); |
435 | __smp_thermal_interrupt(); | 435 | __smp_thermal_interrupt(); |
436 | exiting_ack_irq(); | 436 | exiting_ack_irq(); |
437 | } | 437 | } |
438 | 438 | ||
439 | asmlinkage void smp_trace_thermal_interrupt(struct pt_regs *regs) | 439 | asmlinkage __visible void smp_trace_thermal_interrupt(struct pt_regs *regs) |
440 | { | 440 | { |
441 | entering_irq(); | 441 | entering_irq(); |
442 | trace_thermal_apic_entry(THERMAL_APIC_VECTOR); | 442 | trace_thermal_apic_entry(THERMAL_APIC_VECTOR); |
diff --git a/arch/x86/kernel/cpu/mcheck/threshold.c b/arch/x86/kernel/cpu/mcheck/threshold.c index fe6b1c86645b..7245980186ee 100644 --- a/arch/x86/kernel/cpu/mcheck/threshold.c +++ b/arch/x86/kernel/cpu/mcheck/threshold.c | |||
@@ -24,14 +24,14 @@ static inline void __smp_threshold_interrupt(void) | |||
24 | mce_threshold_vector(); | 24 | mce_threshold_vector(); |
25 | } | 25 | } |
26 | 26 | ||
27 | asmlinkage void smp_threshold_interrupt(void) | 27 | asmlinkage __visible void smp_threshold_interrupt(void) |
28 | { | 28 | { |
29 | entering_irq(); | 29 | entering_irq(); |
30 | __smp_threshold_interrupt(); | 30 | __smp_threshold_interrupt(); |
31 | exiting_ack_irq(); | 31 | exiting_ack_irq(); |
32 | } | 32 | } |
33 | 33 | ||
34 | asmlinkage void smp_trace_threshold_interrupt(void) | 34 | asmlinkage __visible void smp_trace_threshold_interrupt(void) |
35 | { | 35 | { |
36 | entering_irq(); | 36 | entering_irq(); |
37 | trace_threshold_apic_entry(THRESHOLD_APIC_VECTOR); | 37 | trace_threshold_apic_entry(THRESHOLD_APIC_VECTOR); |
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c index 6e2537c32190..6cda0baeac9d 100644 --- a/arch/x86/kernel/early-quirks.c +++ b/arch/x86/kernel/early-quirks.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <asm/dma.h> | 17 | #include <asm/dma.h> |
18 | #include <asm/io_apic.h> | 18 | #include <asm/io_apic.h> |
19 | #include <asm/apic.h> | 19 | #include <asm/apic.h> |
20 | #include <asm/hpet.h> | ||
20 | #include <asm/iommu.h> | 21 | #include <asm/iommu.h> |
21 | #include <asm/gart.h> | 22 | #include <asm/gart.h> |
22 | #include <asm/irq_remapping.h> | 23 | #include <asm/irq_remapping.h> |
@@ -530,6 +531,15 @@ static void __init intel_graphics_stolen(int num, int slot, int func) | |||
530 | } | 531 | } |
531 | } | 532 | } |
532 | 533 | ||
534 | static void __init force_disable_hpet(int num, int slot, int func) | ||
535 | { | ||
536 | #ifdef CONFIG_HPET_TIMER | ||
537 | boot_hpet_disable = 1; | ||
538 | pr_info("x86/hpet: Will disable the HPET for this platform because it's not reliable\n"); | ||
539 | #endif | ||
540 | } | ||
541 | |||
542 | |||
533 | #define QFLAG_APPLY_ONCE 0x1 | 543 | #define QFLAG_APPLY_ONCE 0x1 |
534 | #define QFLAG_APPLIED 0x2 | 544 | #define QFLAG_APPLIED 0x2 |
535 | #define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED) | 545 | #define QFLAG_DONE (QFLAG_APPLY_ONCE|QFLAG_APPLIED) |
@@ -567,6 +577,12 @@ static struct chipset early_qrk[] __initdata = { | |||
567 | PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check }, | 577 | PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check }, |
568 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA, PCI_ANY_ID, | 578 | { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA, PCI_ANY_ID, |
569 | QFLAG_APPLY_ONCE, intel_graphics_stolen }, | 579 | QFLAG_APPLY_ONCE, intel_graphics_stolen }, |
580 | /* | ||
581 | * HPET on current version of Baytrail platform has accuracy | ||
582 | * problems, disable it for now: | ||
583 | */ | ||
584 | { PCI_VENDOR_ID_INTEL, 0x0f00, | ||
585 | PCI_CLASS_BRIDGE_HOST, PCI_ANY_ID, 0, force_disable_hpet}, | ||
570 | {} | 586 | {} |
571 | }; | 587 | }; |
572 | 588 | ||
diff --git a/arch/x86/kernel/head32.c b/arch/x86/kernel/head32.c index c61a14a4a310..d6c1b9836995 100644 --- a/arch/x86/kernel/head32.c +++ b/arch/x86/kernel/head32.c | |||
@@ -29,7 +29,7 @@ static void __init i386_default_early_setup(void) | |||
29 | reserve_ebda_region(); | 29 | reserve_ebda_region(); |
30 | } | 30 | } |
31 | 31 | ||
32 | asmlinkage void __init i386_start_kernel(void) | 32 | asmlinkage __visible void __init i386_start_kernel(void) |
33 | { | 33 | { |
34 | sanitize_boot_params(&boot_params); | 34 | sanitize_boot_params(&boot_params); |
35 | 35 | ||
diff --git a/arch/x86/kernel/head64.c b/arch/x86/kernel/head64.c index 85126ccbdf6b..068054f4bf20 100644 --- a/arch/x86/kernel/head64.c +++ b/arch/x86/kernel/head64.c | |||
@@ -137,7 +137,7 @@ static void __init copy_bootdata(char *real_mode_data) | |||
137 | } | 137 | } |
138 | } | 138 | } |
139 | 139 | ||
140 | asmlinkage void __init x86_64_start_kernel(char * real_mode_data) | 140 | asmlinkage __visible void __init x86_64_start_kernel(char * real_mode_data) |
141 | { | 141 | { |
142 | int i; | 142 | int i; |
143 | 143 | ||
diff --git a/arch/x86/kernel/hpet.c b/arch/x86/kernel/hpet.c index 8d80ae011603..4177bfbc80b0 100644 --- a/arch/x86/kernel/hpet.c +++ b/arch/x86/kernel/hpet.c | |||
@@ -88,7 +88,7 @@ static inline void hpet_clear_mapping(void) | |||
88 | /* | 88 | /* |
89 | * HPET command line enable / disable | 89 | * HPET command line enable / disable |
90 | */ | 90 | */ |
91 | static int boot_hpet_disable; | 91 | int boot_hpet_disable; |
92 | int hpet_force_user; | 92 | int hpet_force_user; |
93 | static int hpet_verbose; | 93 | static int hpet_verbose; |
94 | 94 | ||
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c index 9c0280f93d05..898d077617a9 100644 --- a/arch/x86/kernel/process_64.c +++ b/arch/x86/kernel/process_64.c | |||
@@ -52,7 +52,7 @@ | |||
52 | 52 | ||
53 | asmlinkage extern void ret_from_fork(void); | 53 | asmlinkage extern void ret_from_fork(void); |
54 | 54 | ||
55 | asmlinkage DEFINE_PER_CPU(unsigned long, old_rsp); | 55 | __visible DEFINE_PER_CPU(unsigned long, old_rsp); |
56 | 56 | ||
57 | /* Prints also some state that isn't saved in the pt_regs */ | 57 | /* Prints also some state that isn't saved in the pt_regs */ |
58 | void __show_regs(struct pt_regs *regs, int all) | 58 | void __show_regs(struct pt_regs *regs, int all) |
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c index 3399d3a99730..52b1157c53eb 100644 --- a/arch/x86/kernel/reboot.c +++ b/arch/x86/kernel/reboot.c | |||
@@ -191,6 +191,16 @@ static struct dmi_system_id __initdata reboot_dmi_table[] = { | |||
191 | }, | 191 | }, |
192 | }, | 192 | }, |
193 | 193 | ||
194 | /* Certec */ | ||
195 | { /* Handle problems with rebooting on Certec BPC600 */ | ||
196 | .callback = set_pci_reboot, | ||
197 | .ident = "Certec BPC600", | ||
198 | .matches = { | ||
199 | DMI_MATCH(DMI_SYS_VENDOR, "Certec"), | ||
200 | DMI_MATCH(DMI_PRODUCT_NAME, "BPC600"), | ||
201 | }, | ||
202 | }, | ||
203 | |||
194 | /* Dell */ | 204 | /* Dell */ |
195 | { /* Handle problems with rebooting on Dell DXP061 */ | 205 | { /* Handle problems with rebooting on Dell DXP061 */ |
196 | .callback = set_bios_reboot, | 206 | .callback = set_bios_reboot, |
diff --git a/arch/x86/kernel/smp.c b/arch/x86/kernel/smp.c index 7c3a5a61f2e4..be8e1bde07aa 100644 --- a/arch/x86/kernel/smp.c +++ b/arch/x86/kernel/smp.c | |||
@@ -168,7 +168,7 @@ static int smp_stop_nmi_callback(unsigned int val, struct pt_regs *regs) | |||
168 | * this function calls the 'stop' function on all other CPUs in the system. | 168 | * this function calls the 'stop' function on all other CPUs in the system. |
169 | */ | 169 | */ |
170 | 170 | ||
171 | asmlinkage void smp_reboot_interrupt(void) | 171 | asmlinkage __visible void smp_reboot_interrupt(void) |
172 | { | 172 | { |
173 | ack_APIC_irq(); | 173 | ack_APIC_irq(); |
174 | irq_enter(); | 174 | irq_enter(); |
diff --git a/arch/x86/kernel/traps.c b/arch/x86/kernel/traps.c index 57409f6b8c62..f73b5d435bdc 100644 --- a/arch/x86/kernel/traps.c +++ b/arch/x86/kernel/traps.c | |||
@@ -357,7 +357,7 @@ exit: | |||
357 | * for scheduling or signal handling. The actual stack switch is done in | 357 | * for scheduling or signal handling. The actual stack switch is done in |
358 | * entry.S | 358 | * entry.S |
359 | */ | 359 | */ |
360 | asmlinkage __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) | 360 | asmlinkage __visible __kprobes struct pt_regs *sync_regs(struct pt_regs *eregs) |
361 | { | 361 | { |
362 | struct pt_regs *regs = eregs; | 362 | struct pt_regs *regs = eregs; |
363 | /* Did already sync */ | 363 | /* Did already sync */ |
@@ -601,11 +601,11 @@ do_spurious_interrupt_bug(struct pt_regs *regs, long error_code) | |||
601 | #endif | 601 | #endif |
602 | } | 602 | } |
603 | 603 | ||
604 | asmlinkage void __attribute__((weak)) smp_thermal_interrupt(void) | 604 | asmlinkage __visible void __attribute__((weak)) smp_thermal_interrupt(void) |
605 | { | 605 | { |
606 | } | 606 | } |
607 | 607 | ||
608 | asmlinkage void __attribute__((weak)) smp_threshold_interrupt(void) | 608 | asmlinkage __visible void __attribute__((weak)) smp_threshold_interrupt(void) |
609 | { | 609 | { |
610 | } | 610 | } |
611 | 611 | ||
diff --git a/arch/x86/kernel/vsmp_64.c b/arch/x86/kernel/vsmp_64.c index 5edc34b5b951..b99b9ad8540c 100644 --- a/arch/x86/kernel/vsmp_64.c +++ b/arch/x86/kernel/vsmp_64.c | |||
@@ -36,7 +36,7 @@ static int irq_routing_comply = 1; | |||
36 | * and vice versa. | 36 | * and vice versa. |
37 | */ | 37 | */ |
38 | 38 | ||
39 | asmlinkage unsigned long vsmp_save_fl(void) | 39 | asmlinkage __visible unsigned long vsmp_save_fl(void) |
40 | { | 40 | { |
41 | unsigned long flags = native_save_fl(); | 41 | unsigned long flags = native_save_fl(); |
42 | 42 | ||
@@ -56,7 +56,7 @@ __visible void vsmp_restore_fl(unsigned long flags) | |||
56 | } | 56 | } |
57 | PV_CALLEE_SAVE_REGS_THUNK(vsmp_restore_fl); | 57 | PV_CALLEE_SAVE_REGS_THUNK(vsmp_restore_fl); |
58 | 58 | ||
59 | asmlinkage void vsmp_irq_disable(void) | 59 | asmlinkage __visible void vsmp_irq_disable(void) |
60 | { | 60 | { |
61 | unsigned long flags = native_save_fl(); | 61 | unsigned long flags = native_save_fl(); |
62 | 62 | ||
@@ -64,7 +64,7 @@ asmlinkage void vsmp_irq_disable(void) | |||
64 | } | 64 | } |
65 | PV_CALLEE_SAVE_REGS_THUNK(vsmp_irq_disable); | 65 | PV_CALLEE_SAVE_REGS_THUNK(vsmp_irq_disable); |
66 | 66 | ||
67 | asmlinkage void vsmp_irq_enable(void) | 67 | asmlinkage __visible void vsmp_irq_enable(void) |
68 | { | 68 | { |
69 | unsigned long flags = native_save_fl(); | 69 | unsigned long flags = native_save_fl(); |
70 | 70 | ||
diff --git a/arch/x86/kernel/vsyscall_gtod.c b/arch/x86/kernel/vsyscall_gtod.c index f9c6e56e14b5..9531fbb123ba 100644 --- a/arch/x86/kernel/vsyscall_gtod.c +++ b/arch/x86/kernel/vsyscall_gtod.c | |||
@@ -43,7 +43,7 @@ void update_vsyscall(struct timekeeper *tk) | |||
43 | vdata->monotonic_time_sec = tk->xtime_sec | 43 | vdata->monotonic_time_sec = tk->xtime_sec |
44 | + tk->wall_to_monotonic.tv_sec; | 44 | + tk->wall_to_monotonic.tv_sec; |
45 | vdata->monotonic_time_snsec = tk->xtime_nsec | 45 | vdata->monotonic_time_snsec = tk->xtime_nsec |
46 | + (tk->wall_to_monotonic.tv_nsec | 46 | + ((u64)tk->wall_to_monotonic.tv_nsec |
47 | << tk->shift); | 47 | << tk->shift); |
48 | while (vdata->monotonic_time_snsec >= | 48 | while (vdata->monotonic_time_snsec >= |
49 | (((u64)NSEC_PER_SEC) << tk->shift)) { | 49 | (((u64)NSEC_PER_SEC) << tk->shift)) { |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 8b8fc0b792ba..b6c0bacca9bd 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -280,7 +280,7 @@ int kvm_set_apic_base(struct kvm_vcpu *vcpu, struct msr_data *msr_info) | |||
280 | } | 280 | } |
281 | EXPORT_SYMBOL_GPL(kvm_set_apic_base); | 281 | EXPORT_SYMBOL_GPL(kvm_set_apic_base); |
282 | 282 | ||
283 | asmlinkage void kvm_spurious_fault(void) | 283 | asmlinkage __visible void kvm_spurious_fault(void) |
284 | { | 284 | { |
285 | /* Fault while not rebooting. We want the trace. */ | 285 | /* Fault while not rebooting. We want the trace. */ |
286 | BUG(); | 286 | BUG(); |
diff --git a/arch/x86/lguest/boot.c b/arch/x86/lguest/boot.c index ad1fb5f53925..aae94132bc24 100644 --- a/arch/x86/lguest/boot.c +++ b/arch/x86/lguest/boot.c | |||
@@ -233,13 +233,13 @@ static void lguest_end_context_switch(struct task_struct *next) | |||
233 | * flags word contains all kind of stuff, but in practice Linux only cares | 233 | * flags word contains all kind of stuff, but in practice Linux only cares |
234 | * about the interrupt flag. Our "save_flags()" just returns that. | 234 | * about the interrupt flag. Our "save_flags()" just returns that. |
235 | */ | 235 | */ |
236 | asmlinkage unsigned long lguest_save_fl(void) | 236 | asmlinkage __visible unsigned long lguest_save_fl(void) |
237 | { | 237 | { |
238 | return lguest_data.irq_enabled; | 238 | return lguest_data.irq_enabled; |
239 | } | 239 | } |
240 | 240 | ||
241 | /* Interrupts go off... */ | 241 | /* Interrupts go off... */ |
242 | asmlinkage void lguest_irq_disable(void) | 242 | asmlinkage __visible void lguest_irq_disable(void) |
243 | { | 243 | { |
244 | lguest_data.irq_enabled = 0; | 244 | lguest_data.irq_enabled = 0; |
245 | } | 245 | } |
diff --git a/arch/x86/lib/msr.c b/arch/x86/lib/msr.c index db9db446b71a..43623739c7cf 100644 --- a/arch/x86/lib/msr.c +++ b/arch/x86/lib/msr.c | |||
@@ -76,7 +76,7 @@ static inline int __flip_bit(u32 msr, u8 bit, bool set) | |||
76 | if (m1.q == m.q) | 76 | if (m1.q == m.q) |
77 | return 0; | 77 | return 0; |
78 | 78 | ||
79 | err = msr_write(msr, &m); | 79 | err = msr_write(msr, &m1); |
80 | if (err) | 80 | if (err) |
81 | return err; | 81 | return err; |
82 | 82 | ||
diff --git a/arch/x86/math-emu/errors.c b/arch/x86/math-emu/errors.c index a5449089cd9f..9e6545f269e5 100644 --- a/arch/x86/math-emu/errors.c +++ b/arch/x86/math-emu/errors.c | |||
@@ -302,7 +302,7 @@ static struct { | |||
302 | 0x242 in div_Xsig.S | 302 | 0x242 in div_Xsig.S |
303 | */ | 303 | */ |
304 | 304 | ||
305 | asmlinkage void FPU_exception(int n) | 305 | asmlinkage __visible void FPU_exception(int n) |
306 | { | 306 | { |
307 | int i, int_type; | 307 | int i, int_type; |
308 | 308 | ||
@@ -492,7 +492,7 @@ int real_2op_NaN(FPU_REG const *b, u_char tagb, | |||
492 | 492 | ||
493 | /* Invalid arith operation on Valid registers */ | 493 | /* Invalid arith operation on Valid registers */ |
494 | /* Returns < 0 if the exception is unmasked */ | 494 | /* Returns < 0 if the exception is unmasked */ |
495 | asmlinkage int arith_invalid(int deststnr) | 495 | asmlinkage __visible int arith_invalid(int deststnr) |
496 | { | 496 | { |
497 | 497 | ||
498 | EXCEPTION(EX_Invalid); | 498 | EXCEPTION(EX_Invalid); |
@@ -507,7 +507,7 @@ asmlinkage int arith_invalid(int deststnr) | |||
507 | } | 507 | } |
508 | 508 | ||
509 | /* Divide a finite number by zero */ | 509 | /* Divide a finite number by zero */ |
510 | asmlinkage int FPU_divide_by_zero(int deststnr, u_char sign) | 510 | asmlinkage __visible int FPU_divide_by_zero(int deststnr, u_char sign) |
511 | { | 511 | { |
512 | FPU_REG *dest = &st(deststnr); | 512 | FPU_REG *dest = &st(deststnr); |
513 | int tag = TAG_Valid; | 513 | int tag = TAG_Valid; |
@@ -539,7 +539,7 @@ int set_precision_flag(int flags) | |||
539 | } | 539 | } |
540 | 540 | ||
541 | /* This may be called often, so keep it lean */ | 541 | /* This may be called often, so keep it lean */ |
542 | asmlinkage void set_precision_flag_up(void) | 542 | asmlinkage __visible void set_precision_flag_up(void) |
543 | { | 543 | { |
544 | if (control_word & CW_Precision) | 544 | if (control_word & CW_Precision) |
545 | partial_status |= (SW_Precision | SW_C1); /* The masked response */ | 545 | partial_status |= (SW_Precision | SW_C1); /* The masked response */ |
@@ -548,7 +548,7 @@ asmlinkage void set_precision_flag_up(void) | |||
548 | } | 548 | } |
549 | 549 | ||
550 | /* This may be called often, so keep it lean */ | 550 | /* This may be called often, so keep it lean */ |
551 | asmlinkage void set_precision_flag_down(void) | 551 | asmlinkage __visible void set_precision_flag_down(void) |
552 | { | 552 | { |
553 | if (control_word & CW_Precision) { /* The masked response */ | 553 | if (control_word & CW_Precision) { /* The masked response */ |
554 | partial_status &= ~SW_C1; | 554 | partial_status &= ~SW_C1; |
@@ -557,7 +557,7 @@ asmlinkage void set_precision_flag_down(void) | |||
557 | EXCEPTION(EX_Precision); | 557 | EXCEPTION(EX_Precision); |
558 | } | 558 | } |
559 | 559 | ||
560 | asmlinkage int denormal_operand(void) | 560 | asmlinkage __visible int denormal_operand(void) |
561 | { | 561 | { |
562 | if (control_word & CW_Denormal) { /* The masked response */ | 562 | if (control_word & CW_Denormal) { /* The masked response */ |
563 | partial_status |= SW_Denorm_Op; | 563 | partial_status |= SW_Denorm_Op; |
@@ -568,7 +568,7 @@ asmlinkage int denormal_operand(void) | |||
568 | } | 568 | } |
569 | } | 569 | } |
570 | 570 | ||
571 | asmlinkage int arith_overflow(FPU_REG *dest) | 571 | asmlinkage __visible int arith_overflow(FPU_REG *dest) |
572 | { | 572 | { |
573 | int tag = TAG_Valid; | 573 | int tag = TAG_Valid; |
574 | 574 | ||
@@ -596,7 +596,7 @@ asmlinkage int arith_overflow(FPU_REG *dest) | |||
596 | 596 | ||
597 | } | 597 | } |
598 | 598 | ||
599 | asmlinkage int arith_underflow(FPU_REG *dest) | 599 | asmlinkage __visible int arith_underflow(FPU_REG *dest) |
600 | { | 600 | { |
601 | int tag = TAG_Valid; | 601 | int tag = TAG_Valid; |
602 | 602 | ||
diff --git a/arch/x86/platform/efi/early_printk.c b/arch/x86/platform/efi/early_printk.c index 81b506d5befd..524142117296 100644 --- a/arch/x86/platform/efi/early_printk.c +++ b/arch/x86/platform/efi/early_printk.c | |||
@@ -14,48 +14,92 @@ | |||
14 | 14 | ||
15 | static const struct font_desc *font; | 15 | static const struct font_desc *font; |
16 | static u32 efi_x, efi_y; | 16 | static u32 efi_x, efi_y; |
17 | static void *efi_fb; | ||
18 | static bool early_efi_keep; | ||
17 | 19 | ||
18 | static __init void early_efi_clear_scanline(unsigned int y) | 20 | /* |
21 | * efi earlyprintk need use early_ioremap to map the framebuffer. | ||
22 | * But early_ioremap is not usable for earlyprintk=efi,keep, ioremap should | ||
23 | * be used instead. ioremap will be available after paging_init() which is | ||
24 | * earlier than initcall callbacks. Thus adding this early initcall function | ||
25 | * early_efi_map_fb to map the whole efi framebuffer. | ||
26 | */ | ||
27 | static __init int early_efi_map_fb(void) | ||
19 | { | 28 | { |
20 | unsigned long base, *dst; | 29 | unsigned long base, size; |
21 | u16 len; | 30 | |
31 | if (!early_efi_keep) | ||
32 | return 0; | ||
22 | 33 | ||
23 | base = boot_params.screen_info.lfb_base; | 34 | base = boot_params.screen_info.lfb_base; |
24 | len = boot_params.screen_info.lfb_linelength; | 35 | size = boot_params.screen_info.lfb_size; |
36 | efi_fb = ioremap(base, size); | ||
37 | |||
38 | return efi_fb ? 0 : -ENOMEM; | ||
39 | } | ||
40 | early_initcall(early_efi_map_fb); | ||
41 | |||
42 | /* | ||
43 | * early_efi_map maps efi framebuffer region [start, start + len -1] | ||
44 | * In case earlyprintk=efi,keep we have the whole framebuffer mapped already | ||
45 | * so just return the offset efi_fb + start. | ||
46 | */ | ||
47 | static __init_refok void *early_efi_map(unsigned long start, unsigned long len) | ||
48 | { | ||
49 | unsigned long base; | ||
50 | |||
51 | base = boot_params.screen_info.lfb_base; | ||
52 | |||
53 | if (efi_fb) | ||
54 | return (efi_fb + start); | ||
55 | else | ||
56 | return early_ioremap(base + start, len); | ||
57 | } | ||
25 | 58 | ||
26 | dst = early_ioremap(base + y*len, len); | 59 | static __init_refok void early_efi_unmap(void *addr, unsigned long len) |
60 | { | ||
61 | if (!efi_fb) | ||
62 | early_iounmap(addr, len); | ||
63 | } | ||
64 | |||
65 | static void early_efi_clear_scanline(unsigned int y) | ||
66 | { | ||
67 | unsigned long *dst; | ||
68 | u16 len; | ||
69 | |||
70 | len = boot_params.screen_info.lfb_linelength; | ||
71 | dst = early_efi_map(y*len, len); | ||
27 | if (!dst) | 72 | if (!dst) |
28 | return; | 73 | return; |
29 | 74 | ||
30 | memset(dst, 0, len); | 75 | memset(dst, 0, len); |
31 | early_iounmap(dst, len); | 76 | early_efi_unmap(dst, len); |
32 | } | 77 | } |
33 | 78 | ||
34 | static __init void early_efi_scroll_up(void) | 79 | static void early_efi_scroll_up(void) |
35 | { | 80 | { |
36 | unsigned long base, *dst, *src; | 81 | unsigned long *dst, *src; |
37 | u16 len; | 82 | u16 len; |
38 | u32 i, height; | 83 | u32 i, height; |
39 | 84 | ||
40 | base = boot_params.screen_info.lfb_base; | ||
41 | len = boot_params.screen_info.lfb_linelength; | 85 | len = boot_params.screen_info.lfb_linelength; |
42 | height = boot_params.screen_info.lfb_height; | 86 | height = boot_params.screen_info.lfb_height; |
43 | 87 | ||
44 | for (i = 0; i < height - font->height; i++) { | 88 | for (i = 0; i < height - font->height; i++) { |
45 | dst = early_ioremap(base + i*len, len); | 89 | dst = early_efi_map(i*len, len); |
46 | if (!dst) | 90 | if (!dst) |
47 | return; | 91 | return; |
48 | 92 | ||
49 | src = early_ioremap(base + (i + font->height) * len, len); | 93 | src = early_efi_map((i + font->height) * len, len); |
50 | if (!src) { | 94 | if (!src) { |
51 | early_iounmap(dst, len); | 95 | early_efi_unmap(dst, len); |
52 | return; | 96 | return; |
53 | } | 97 | } |
54 | 98 | ||
55 | memmove(dst, src, len); | 99 | memmove(dst, src, len); |
56 | 100 | ||
57 | early_iounmap(src, len); | 101 | early_efi_unmap(src, len); |
58 | early_iounmap(dst, len); | 102 | early_efi_unmap(dst, len); |
59 | } | 103 | } |
60 | } | 104 | } |
61 | 105 | ||
@@ -79,16 +123,14 @@ static void early_efi_write_char(u32 *dst, unsigned char c, unsigned int h) | |||
79 | } | 123 | } |
80 | } | 124 | } |
81 | 125 | ||
82 | static __init void | 126 | static void |
83 | early_efi_write(struct console *con, const char *str, unsigned int num) | 127 | early_efi_write(struct console *con, const char *str, unsigned int num) |
84 | { | 128 | { |
85 | struct screen_info *si; | 129 | struct screen_info *si; |
86 | unsigned long base; | ||
87 | unsigned int len; | 130 | unsigned int len; |
88 | const char *s; | 131 | const char *s; |
89 | void *dst; | 132 | void *dst; |
90 | 133 | ||
91 | base = boot_params.screen_info.lfb_base; | ||
92 | si = &boot_params.screen_info; | 134 | si = &boot_params.screen_info; |
93 | len = si->lfb_linelength; | 135 | len = si->lfb_linelength; |
94 | 136 | ||
@@ -109,7 +151,7 @@ early_efi_write(struct console *con, const char *str, unsigned int num) | |||
109 | for (h = 0; h < font->height; h++) { | 151 | for (h = 0; h < font->height; h++) { |
110 | unsigned int n, x; | 152 | unsigned int n, x; |
111 | 153 | ||
112 | dst = early_ioremap(base + (efi_y + h) * len, len); | 154 | dst = early_efi_map((efi_y + h) * len, len); |
113 | if (!dst) | 155 | if (!dst) |
114 | return; | 156 | return; |
115 | 157 | ||
@@ -123,7 +165,7 @@ early_efi_write(struct console *con, const char *str, unsigned int num) | |||
123 | s++; | 165 | s++; |
124 | } | 166 | } |
125 | 167 | ||
126 | early_iounmap(dst, len); | 168 | early_efi_unmap(dst, len); |
127 | } | 169 | } |
128 | 170 | ||
129 | num -= count; | 171 | num -= count; |
@@ -179,6 +221,9 @@ static __init int early_efi_setup(struct console *con, char *options) | |||
179 | for (i = 0; i < (yres - efi_y) / font->height; i++) | 221 | for (i = 0; i < (yres - efi_y) / font->height; i++) |
180 | early_efi_scroll_up(); | 222 | early_efi_scroll_up(); |
181 | 223 | ||
224 | /* early_console_register will unset CON_BOOT in case ,keep */ | ||
225 | if (!(con->flags & CON_BOOT)) | ||
226 | early_efi_keep = true; | ||
182 | return 0; | 227 | return 0; |
183 | } | 228 | } |
184 | 229 | ||
diff --git a/arch/x86/platform/olpc/olpc-xo1-pm.c b/arch/x86/platform/olpc/olpc-xo1-pm.c index ff0174dda810..a9acde72d4ed 100644 --- a/arch/x86/platform/olpc/olpc-xo1-pm.c +++ b/arch/x86/platform/olpc/olpc-xo1-pm.c | |||
@@ -75,7 +75,7 @@ static int xo1_power_state_enter(suspend_state_t pm_state) | |||
75 | return 0; | 75 | return 0; |
76 | } | 76 | } |
77 | 77 | ||
78 | asmlinkage int xo1_do_sleep(u8 sleep_state) | 78 | asmlinkage __visible int xo1_do_sleep(u8 sleep_state) |
79 | { | 79 | { |
80 | void *pgd_addr = __va(read_cr3()); | 80 | void *pgd_addr = __va(read_cr3()); |
81 | 81 | ||
diff --git a/arch/x86/power/hibernate_64.c b/arch/x86/power/hibernate_64.c index 304fca20d96e..35e2bb6c0f37 100644 --- a/arch/x86/power/hibernate_64.c +++ b/arch/x86/power/hibernate_64.c | |||
@@ -23,7 +23,7 @@ | |||
23 | extern __visible const void __nosave_begin, __nosave_end; | 23 | extern __visible const void __nosave_begin, __nosave_end; |
24 | 24 | ||
25 | /* Defined in hibernate_asm_64.S */ | 25 | /* Defined in hibernate_asm_64.S */ |
26 | extern asmlinkage int restore_image(void); | 26 | extern asmlinkage __visible int restore_image(void); |
27 | 27 | ||
28 | /* | 28 | /* |
29 | * Address to jump to in the last phase of restore in order to get to the image | 29 | * Address to jump to in the last phase of restore in order to get to the image |
diff --git a/arch/x86/xen/enlighten.c b/arch/x86/xen/enlighten.c index 201d09a7c46b..c34bfc4bbe7f 100644 --- a/arch/x86/xen/enlighten.c +++ b/arch/x86/xen/enlighten.c | |||
@@ -1515,7 +1515,7 @@ static void __init xen_pvh_early_guest_init(void) | |||
1515 | } | 1515 | } |
1516 | 1516 | ||
1517 | /* First C function to be called on Xen boot */ | 1517 | /* First C function to be called on Xen boot */ |
1518 | asmlinkage void __init xen_start_kernel(void) | 1518 | asmlinkage __visible void __init xen_start_kernel(void) |
1519 | { | 1519 | { |
1520 | struct physdev_set_iopl set_iopl; | 1520 | struct physdev_set_iopl set_iopl; |
1521 | int rc; | 1521 | int rc; |
diff --git a/arch/x86/xen/irq.c b/arch/x86/xen/irq.c index 08f763de26fe..a1207cb6472a 100644 --- a/arch/x86/xen/irq.c +++ b/arch/x86/xen/irq.c | |||
@@ -23,7 +23,7 @@ void xen_force_evtchn_callback(void) | |||
23 | (void)HYPERVISOR_xen_version(0, NULL); | 23 | (void)HYPERVISOR_xen_version(0, NULL); |
24 | } | 24 | } |
25 | 25 | ||
26 | asmlinkage unsigned long xen_save_fl(void) | 26 | asmlinkage __visible unsigned long xen_save_fl(void) |
27 | { | 27 | { |
28 | struct vcpu_info *vcpu; | 28 | struct vcpu_info *vcpu; |
29 | unsigned long flags; | 29 | unsigned long flags; |
@@ -63,7 +63,7 @@ __visible void xen_restore_fl(unsigned long flags) | |||
63 | } | 63 | } |
64 | PV_CALLEE_SAVE_REGS_THUNK(xen_restore_fl); | 64 | PV_CALLEE_SAVE_REGS_THUNK(xen_restore_fl); |
65 | 65 | ||
66 | asmlinkage void xen_irq_disable(void) | 66 | asmlinkage __visible void xen_irq_disable(void) |
67 | { | 67 | { |
68 | /* There's a one instruction preempt window here. We need to | 68 | /* There's a one instruction preempt window here. We need to |
69 | make sure we're don't switch CPUs between getting the vcpu | 69 | make sure we're don't switch CPUs between getting the vcpu |
@@ -74,7 +74,7 @@ asmlinkage void xen_irq_disable(void) | |||
74 | } | 74 | } |
75 | PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable); | 75 | PV_CALLEE_SAVE_REGS_THUNK(xen_irq_disable); |
76 | 76 | ||
77 | asmlinkage void xen_irq_enable(void) | 77 | asmlinkage __visible void xen_irq_enable(void) |
78 | { | 78 | { |
79 | struct vcpu_info *vcpu; | 79 | struct vcpu_info *vcpu; |
80 | 80 | ||
diff --git a/arch/xtensa/Kconfig b/arch/xtensa/Kconfig index 02d6d29a63c1..3a617af60d46 100644 --- a/arch/xtensa/Kconfig +++ b/arch/xtensa/Kconfig | |||
@@ -14,6 +14,7 @@ config XTENSA | |||
14 | select GENERIC_PCI_IOMAP | 14 | select GENERIC_PCI_IOMAP |
15 | select ARCH_WANT_IPC_PARSE_VERSION | 15 | select ARCH_WANT_IPC_PARSE_VERSION |
16 | select ARCH_WANT_OPTIONAL_GPIOLIB | 16 | select ARCH_WANT_OPTIONAL_GPIOLIB |
17 | select BUILDTIME_EXTABLE_SORT | ||
17 | select CLONE_BACKWARDS | 18 | select CLONE_BACKWARDS |
18 | select IRQ_DOMAIN | 19 | select IRQ_DOMAIN |
19 | select HAVE_OPROFILE | 20 | select HAVE_OPROFILE |
@@ -189,6 +190,24 @@ config INITIALIZE_XTENSA_MMU_INSIDE_VMLINUX | |||
189 | 190 | ||
190 | If in doubt, say Y. | 191 | If in doubt, say Y. |
191 | 192 | ||
193 | config HIGHMEM | ||
194 | bool "High Memory Support" | ||
195 | help | ||
196 | Linux can use the full amount of RAM in the system by | ||
197 | default. However, the default MMUv2 setup only maps the | ||
198 | lowermost 128 MB of memory linearly to the areas starting | ||
199 | at 0xd0000000 (cached) and 0xd8000000 (uncached). | ||
200 | When there are more than 128 MB memory in the system not | ||
201 | all of it can be "permanently mapped" by the kernel. | ||
202 | The physical memory that's not permanently mapped is called | ||
203 | "high memory". | ||
204 | |||
205 | If you are compiling a kernel which will never run on a | ||
206 | machine with more than 128 MB total physical RAM, answer | ||
207 | N here. | ||
208 | |||
209 | If unsure, say Y. | ||
210 | |||
192 | endmenu | 211 | endmenu |
193 | 212 | ||
194 | config XTENSA_CALIBRATE_CCOUNT | 213 | config XTENSA_CALIBRATE_CCOUNT |
@@ -224,7 +243,6 @@ choice | |||
224 | 243 | ||
225 | config XTENSA_PLATFORM_ISS | 244 | config XTENSA_PLATFORM_ISS |
226 | bool "ISS" | 245 | bool "ISS" |
227 | depends on TTY | ||
228 | select XTENSA_CALIBRATE_CCOUNT | 246 | select XTENSA_CALIBRATE_CCOUNT |
229 | select SERIAL_CONSOLE | 247 | select SERIAL_CONSOLE |
230 | help | 248 | help |
diff --git a/arch/xtensa/boot/dts/kc705.dts b/arch/xtensa/boot/dts/kc705.dts new file mode 100644 index 000000000000..742a347be67a --- /dev/null +++ b/arch/xtensa/boot/dts/kc705.dts | |||
@@ -0,0 +1,11 @@ | |||
1 | /dts-v1/; | ||
2 | /include/ "xtfpga.dtsi" | ||
3 | /include/ "xtfpga-flash-128m.dtsi" | ||
4 | |||
5 | / { | ||
6 | compatible = "cdns,xtensa-kc705"; | ||
7 | memory@0 { | ||
8 | device_type = "memory"; | ||
9 | reg = <0x00000000 0x08000000>; | ||
10 | }; | ||
11 | }; | ||
diff --git a/arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi new file mode 100644 index 000000000000..d3a88e029873 --- /dev/null +++ b/arch/xtensa/boot/dts/xtfpga-flash-128m.dtsi | |||
@@ -0,0 +1,28 @@ | |||
1 | / { | ||
2 | soc { | ||
3 | flash: flash@00000000 { | ||
4 | #address-cells = <1>; | ||
5 | #size-cells = <1>; | ||
6 | compatible = "cfi-flash"; | ||
7 | reg = <0x00000000 0x08000000>; | ||
8 | bank-width = <2>; | ||
9 | device-width = <2>; | ||
10 | partition@0x0 { | ||
11 | label = "data"; | ||
12 | reg = <0x00000000 0x06000000>; | ||
13 | }; | ||
14 | partition@0x6000000 { | ||
15 | label = "boot loader area"; | ||
16 | reg = <0x06000000 0x00800000>; | ||
17 | }; | ||
18 | partition@0x6800000 { | ||
19 | label = "kernel image"; | ||
20 | reg = <0x06800000 0x017e0000>; | ||
21 | }; | ||
22 | partition@0x7fe0000 { | ||
23 | label = "boot environment"; | ||
24 | reg = <0x07fe0000 0x00020000>; | ||
25 | }; | ||
26 | }; | ||
27 | }; | ||
28 | }; | ||
diff --git a/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi index e5703c7beeb6..1d97203c18e7 100644 --- a/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi +++ b/arch/xtensa/boot/dts/xtfpga-flash-16m.dtsi | |||
@@ -1,26 +1,28 @@ | |||
1 | / { | 1 | / { |
2 | flash: flash@f8000000 { | 2 | soc { |
3 | #address-cells = <1>; | 3 | flash: flash@08000000 { |
4 | #size-cells = <1>; | 4 | #address-cells = <1>; |
5 | compatible = "cfi-flash"; | 5 | #size-cells = <1>; |
6 | reg = <0xf8000000 0x01000000>; | 6 | compatible = "cfi-flash"; |
7 | bank-width = <2>; | 7 | reg = <0x08000000 0x01000000>; |
8 | device-width = <2>; | 8 | bank-width = <2>; |
9 | partition@0x0 { | 9 | device-width = <2>; |
10 | label = "boot loader area"; | 10 | partition@0x0 { |
11 | reg = <0x00000000 0x00400000>; | 11 | label = "boot loader area"; |
12 | reg = <0x00000000 0x00400000>; | ||
13 | }; | ||
14 | partition@0x400000 { | ||
15 | label = "kernel image"; | ||
16 | reg = <0x00400000 0x00600000>; | ||
17 | }; | ||
18 | partition@0xa00000 { | ||
19 | label = "data"; | ||
20 | reg = <0x00a00000 0x005e0000>; | ||
21 | }; | ||
22 | partition@0xfe0000 { | ||
23 | label = "boot environment"; | ||
24 | reg = <0x00fe0000 0x00020000>; | ||
25 | }; | ||
12 | }; | 26 | }; |
13 | partition@0x400000 { | 27 | }; |
14 | label = "kernel image"; | ||
15 | reg = <0x00400000 0x00600000>; | ||
16 | }; | ||
17 | partition@0xa00000 { | ||
18 | label = "data"; | ||
19 | reg = <0x00a00000 0x005e0000>; | ||
20 | }; | ||
21 | partition@0xfe0000 { | ||
22 | label = "boot environment"; | ||
23 | reg = <0x00fe0000 0x00020000>; | ||
24 | }; | ||
25 | }; | ||
26 | }; | 28 | }; |
diff --git a/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi b/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi index 6f9c10d6b689..d1c621ca8be1 100644 --- a/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi +++ b/arch/xtensa/boot/dts/xtfpga-flash-4m.dtsi | |||
@@ -1,18 +1,20 @@ | |||
1 | / { | 1 | / { |
2 | flash: flash@f8000000 { | 2 | soc { |
3 | #address-cells = <1>; | 3 | flash: flash@08000000 { |
4 | #size-cells = <1>; | 4 | #address-cells = <1>; |
5 | compatible = "cfi-flash"; | 5 | #size-cells = <1>; |
6 | reg = <0xf8000000 0x00400000>; | 6 | compatible = "cfi-flash"; |
7 | bank-width = <2>; | 7 | reg = <0x08000000 0x00400000>; |
8 | device-width = <2>; | 8 | bank-width = <2>; |
9 | partition@0x0 { | 9 | device-width = <2>; |
10 | label = "boot loader area"; | 10 | partition@0x0 { |
11 | reg = <0x00000000 0x003f0000>; | 11 | label = "boot loader area"; |
12 | reg = <0x00000000 0x003f0000>; | ||
13 | }; | ||
14 | partition@0x3f0000 { | ||
15 | label = "boot environment"; | ||
16 | reg = <0x003f0000 0x00010000>; | ||
17 | }; | ||
12 | }; | 18 | }; |
13 | partition@0x3f0000 { | 19 | }; |
14 | label = "boot environment"; | ||
15 | reg = <0x003f0000 0x00010000>; | ||
16 | }; | ||
17 | }; | ||
18 | }; | 20 | }; |
diff --git a/arch/xtensa/boot/dts/xtfpga.dtsi b/arch/xtensa/boot/dts/xtfpga.dtsi index e7370b11348e..dec9178840f6 100644 --- a/arch/xtensa/boot/dts/xtfpga.dtsi +++ b/arch/xtensa/boot/dts/xtfpga.dtsi | |||
@@ -42,21 +42,28 @@ | |||
42 | }; | 42 | }; |
43 | }; | 43 | }; |
44 | 44 | ||
45 | serial0: serial@fd050020 { | 45 | soc { |
46 | device_type = "serial"; | 46 | #address-cells = <1>; |
47 | compatible = "ns16550a"; | 47 | #size-cells = <1>; |
48 | no-loopback-test; | 48 | compatible = "simple-bus"; |
49 | reg = <0xfd050020 0x20>; | 49 | ranges = <0x00000000 0xf0000000 0x10000000>; |
50 | reg-shift = <2>; | ||
51 | interrupts = <0 1>; /* external irq 0 */ | ||
52 | clocks = <&osc>; | ||
53 | }; | ||
54 | 50 | ||
55 | enet0: ethoc@fd030000 { | 51 | serial0: serial@0d050020 { |
56 | compatible = "opencores,ethoc"; | 52 | device_type = "serial"; |
57 | reg = <0xfd030000 0x4000 0xfd800000 0x4000>; | 53 | compatible = "ns16550a"; |
58 | interrupts = <1 1>; /* external irq 1 */ | 54 | no-loopback-test; |
59 | local-mac-address = [00 50 c2 13 6f 00]; | 55 | reg = <0x0d050020 0x20>; |
60 | clocks = <&osc>; | 56 | reg-shift = <2>; |
57 | interrupts = <0 1>; /* external irq 0 */ | ||
58 | clocks = <&osc>; | ||
59 | }; | ||
60 | |||
61 | enet0: ethoc@0d030000 { | ||
62 | compatible = "opencores,ethoc"; | ||
63 | reg = <0x0d030000 0x4000 0x0d800000 0x4000>; | ||
64 | interrupts = <1 1>; /* external irq 1 */ | ||
65 | local-mac-address = [00 50 c2 13 6f 00]; | ||
66 | clocks = <&osc>; | ||
67 | }; | ||
61 | }; | 68 | }; |
62 | }; | 69 | }; |
diff --git a/arch/xtensa/include/asm/bootparam.h b/arch/xtensa/include/asm/bootparam.h index 23392c5630ce..892aab399ac8 100644 --- a/arch/xtensa/include/asm/bootparam.h +++ b/arch/xtensa/include/asm/bootparam.h | |||
@@ -37,23 +37,14 @@ typedef struct bp_tag { | |||
37 | unsigned long data[0]; /* data */ | 37 | unsigned long data[0]; /* data */ |
38 | } bp_tag_t; | 38 | } bp_tag_t; |
39 | 39 | ||
40 | typedef struct meminfo { | 40 | struct bp_meminfo { |
41 | unsigned long type; | 41 | unsigned long type; |
42 | unsigned long start; | 42 | unsigned long start; |
43 | unsigned long end; | 43 | unsigned long end; |
44 | } meminfo_t; | 44 | }; |
45 | |||
46 | #define SYSMEM_BANKS_MAX 5 | ||
47 | 45 | ||
48 | #define MEMORY_TYPE_CONVENTIONAL 0x1000 | 46 | #define MEMORY_TYPE_CONVENTIONAL 0x1000 |
49 | #define MEMORY_TYPE_NONE 0x2000 | 47 | #define MEMORY_TYPE_NONE 0x2000 |
50 | 48 | ||
51 | typedef struct sysmem_info { | ||
52 | int nr_banks; | ||
53 | meminfo_t bank[SYSMEM_BANKS_MAX]; | ||
54 | } sysmem_info_t; | ||
55 | |||
56 | extern sysmem_info_t sysmem; | ||
57 | |||
58 | #endif | 49 | #endif |
59 | #endif | 50 | #endif |
diff --git a/arch/xtensa/include/asm/fixmap.h b/arch/xtensa/include/asm/fixmap.h new file mode 100644 index 000000000000..9f6c33d0428a --- /dev/null +++ b/arch/xtensa/include/asm/fixmap.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * fixmap.h: compile-time virtual memory allocation | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 1998 Ingo Molnar | ||
9 | * | ||
10 | * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 | ||
11 | */ | ||
12 | |||
13 | #ifndef _ASM_FIXMAP_H | ||
14 | #define _ASM_FIXMAP_H | ||
15 | |||
16 | #include <asm/pgtable.h> | ||
17 | #ifdef CONFIG_HIGHMEM | ||
18 | #include <linux/threads.h> | ||
19 | #include <asm/kmap_types.h> | ||
20 | #endif | ||
21 | |||
22 | /* | ||
23 | * Here we define all the compile-time 'special' virtual | ||
24 | * addresses. The point is to have a constant address at | ||
25 | * compile time, but to set the physical address only | ||
26 | * in the boot process. We allocate these special addresses | ||
27 | * from the end of the consistent memory region backwards. | ||
28 | * Also this lets us do fail-safe vmalloc(), we | ||
29 | * can guarantee that these special addresses and | ||
30 | * vmalloc()-ed addresses never overlap. | ||
31 | * | ||
32 | * these 'compile-time allocated' memory buffers are | ||
33 | * fixed-size 4k pages. (or larger if used with an increment | ||
34 | * higher than 1) use fixmap_set(idx,phys) to associate | ||
35 | * physical memory with fixmap indices. | ||
36 | */ | ||
37 | enum fixed_addresses { | ||
38 | #ifdef CONFIG_HIGHMEM | ||
39 | /* reserved pte's for temporary kernel mappings */ | ||
40 | FIX_KMAP_BEGIN, | ||
41 | FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS) - 1, | ||
42 | #endif | ||
43 | __end_of_fixed_addresses | ||
44 | }; | ||
45 | |||
46 | #define FIXADDR_TOP (VMALLOC_START - PAGE_SIZE) | ||
47 | #define FIXADDR_SIZE (__end_of_fixed_addresses << PAGE_SHIFT) | ||
48 | #define FIXADDR_START ((FIXADDR_TOP - FIXADDR_SIZE) & PMD_MASK) | ||
49 | |||
50 | #include <asm-generic/fixmap.h> | ||
51 | |||
52 | #define kmap_get_fixmap_pte(vaddr) \ | ||
53 | pte_offset_kernel( \ | ||
54 | pmd_offset(pud_offset(pgd_offset_k(vaddr), (vaddr)), (vaddr)), \ | ||
55 | (vaddr) \ | ||
56 | ) | ||
57 | |||
58 | #endif | ||
diff --git a/arch/xtensa/include/asm/highmem.h b/arch/xtensa/include/asm/highmem.h index 80be15124697..2653ef5d55f1 100644 --- a/arch/xtensa/include/asm/highmem.h +++ b/arch/xtensa/include/asm/highmem.h | |||
@@ -6,11 +6,54 @@ | |||
6 | * this archive for more details. | 6 | * this archive for more details. |
7 | * | 7 | * |
8 | * Copyright (C) 2003 - 2005 Tensilica Inc. | 8 | * Copyright (C) 2003 - 2005 Tensilica Inc. |
9 | * Copyright (C) 2014 Cadence Design Systems Inc. | ||
9 | */ | 10 | */ |
10 | 11 | ||
11 | #ifndef _XTENSA_HIGHMEM_H | 12 | #ifndef _XTENSA_HIGHMEM_H |
12 | #define _XTENSA_HIGHMEM_H | 13 | #define _XTENSA_HIGHMEM_H |
13 | 14 | ||
14 | extern void flush_cache_kmaps(void); | 15 | #include <asm/cacheflush.h> |
16 | #include <asm/fixmap.h> | ||
17 | #include <asm/kmap_types.h> | ||
18 | #include <asm/pgtable.h> | ||
19 | |||
20 | #define PKMAP_BASE (FIXADDR_START - PMD_SIZE) | ||
21 | #define LAST_PKMAP PTRS_PER_PTE | ||
22 | #define LAST_PKMAP_MASK (LAST_PKMAP - 1) | ||
23 | #define PKMAP_NR(virt) (((virt) - PKMAP_BASE) >> PAGE_SHIFT) | ||
24 | #define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) | ||
25 | |||
26 | #define kmap_prot PAGE_KERNEL | ||
27 | |||
28 | extern pte_t *pkmap_page_table; | ||
29 | |||
30 | void *kmap_high(struct page *page); | ||
31 | void kunmap_high(struct page *page); | ||
32 | |||
33 | static inline void *kmap(struct page *page) | ||
34 | { | ||
35 | BUG_ON(in_interrupt()); | ||
36 | if (!PageHighMem(page)) | ||
37 | return page_address(page); | ||
38 | return kmap_high(page); | ||
39 | } | ||
40 | |||
41 | static inline void kunmap(struct page *page) | ||
42 | { | ||
43 | BUG_ON(in_interrupt()); | ||
44 | if (!PageHighMem(page)) | ||
45 | return; | ||
46 | kunmap_high(page); | ||
47 | } | ||
48 | |||
49 | static inline void flush_cache_kmaps(void) | ||
50 | { | ||
51 | flush_cache_all(); | ||
52 | } | ||
53 | |||
54 | void *kmap_atomic(struct page *page); | ||
55 | void __kunmap_atomic(void *kvaddr); | ||
56 | |||
57 | void kmap_init(void); | ||
15 | 58 | ||
16 | #endif | 59 | #endif |
diff --git a/arch/xtensa/include/asm/pgtable.h b/arch/xtensa/include/asm/pgtable.h index 216446295ada..4b0ca35a93b1 100644 --- a/arch/xtensa/include/asm/pgtable.h +++ b/arch/xtensa/include/asm/pgtable.h | |||
@@ -310,6 +310,10 @@ set_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pteval) | |||
310 | update_pte(ptep, pteval); | 310 | update_pte(ptep, pteval); |
311 | } | 311 | } |
312 | 312 | ||
313 | static inline void set_pte(pte_t *ptep, pte_t pteval) | ||
314 | { | ||
315 | update_pte(ptep, pteval); | ||
316 | } | ||
313 | 317 | ||
314 | static inline void | 318 | static inline void |
315 | set_pmd(pmd_t *pmdp, pmd_t pmdval) | 319 | set_pmd(pmd_t *pmdp, pmd_t pmdval) |
diff --git a/arch/xtensa/include/asm/sysmem.h b/arch/xtensa/include/asm/sysmem.h new file mode 100644 index 000000000000..c015c5c8e3f7 --- /dev/null +++ b/arch/xtensa/include/asm/sysmem.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * sysmem-related prototypes. | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2014 Cadence Design Systems Inc. | ||
9 | */ | ||
10 | |||
11 | #ifndef _XTENSA_SYSMEM_H | ||
12 | #define _XTENSA_SYSMEM_H | ||
13 | |||
14 | #define SYSMEM_BANKS_MAX 31 | ||
15 | |||
16 | struct meminfo { | ||
17 | unsigned long start; | ||
18 | unsigned long end; | ||
19 | }; | ||
20 | |||
21 | /* | ||
22 | * Bank array is sorted by .start. | ||
23 | * Banks don't overlap and there's at least one page gap | ||
24 | * between adjacent bank entries. | ||
25 | */ | ||
26 | struct sysmem_info { | ||
27 | int nr_banks; | ||
28 | struct meminfo bank[SYSMEM_BANKS_MAX]; | ||
29 | }; | ||
30 | |||
31 | extern struct sysmem_info sysmem; | ||
32 | |||
33 | int add_sysmem_bank(unsigned long start, unsigned long end); | ||
34 | int mem_reserve(unsigned long, unsigned long, int); | ||
35 | void bootmem_init(void); | ||
36 | void zones_init(void); | ||
37 | |||
38 | #endif /* _XTENSA_SYSMEM_H */ | ||
diff --git a/arch/xtensa/include/asm/tlbflush.h b/arch/xtensa/include/asm/tlbflush.h index fc34274ce41b..06875feb27c2 100644 --- a/arch/xtensa/include/asm/tlbflush.h +++ b/arch/xtensa/include/asm/tlbflush.h | |||
@@ -36,6 +36,7 @@ void local_flush_tlb_page(struct vm_area_struct *vma, | |||
36 | unsigned long page); | 36 | unsigned long page); |
37 | void local_flush_tlb_range(struct vm_area_struct *vma, | 37 | void local_flush_tlb_range(struct vm_area_struct *vma, |
38 | unsigned long start, unsigned long end); | 38 | unsigned long start, unsigned long end); |
39 | void local_flush_tlb_kernel_range(unsigned long start, unsigned long end); | ||
39 | 40 | ||
40 | #ifdef CONFIG_SMP | 41 | #ifdef CONFIG_SMP |
41 | 42 | ||
@@ -44,12 +45,7 @@ void flush_tlb_mm(struct mm_struct *); | |||
44 | void flush_tlb_page(struct vm_area_struct *, unsigned long); | 45 | void flush_tlb_page(struct vm_area_struct *, unsigned long); |
45 | void flush_tlb_range(struct vm_area_struct *, unsigned long, | 46 | void flush_tlb_range(struct vm_area_struct *, unsigned long, |
46 | unsigned long); | 47 | unsigned long); |
47 | 48 | void flush_tlb_kernel_range(unsigned long start, unsigned long end); | |
48 | static inline void flush_tlb_kernel_range(unsigned long start, | ||
49 | unsigned long end) | ||
50 | { | ||
51 | flush_tlb_all(); | ||
52 | } | ||
53 | 49 | ||
54 | #else /* !CONFIG_SMP */ | 50 | #else /* !CONFIG_SMP */ |
55 | 51 | ||
@@ -58,7 +54,8 @@ static inline void flush_tlb_kernel_range(unsigned long start, | |||
58 | #define flush_tlb_page(vma, page) local_flush_tlb_page(vma, page) | 54 | #define flush_tlb_page(vma, page) local_flush_tlb_page(vma, page) |
59 | #define flush_tlb_range(vma, vmaddr, end) local_flush_tlb_range(vma, vmaddr, \ | 55 | #define flush_tlb_range(vma, vmaddr, end) local_flush_tlb_range(vma, vmaddr, \ |
60 | end) | 56 | end) |
61 | #define flush_tlb_kernel_range(start, end) local_flush_tlb_all() | 57 | #define flush_tlb_kernel_range(start, end) local_flush_tlb_kernel_range(start, \ |
58 | end) | ||
62 | 59 | ||
63 | #endif /* CONFIG_SMP */ | 60 | #endif /* CONFIG_SMP */ |
64 | 61 | ||
diff --git a/arch/xtensa/kernel/setup.c b/arch/xtensa/kernel/setup.c index 84fe931bb60e..9757bb74e532 100644 --- a/arch/xtensa/kernel/setup.c +++ b/arch/xtensa/kernel/setup.c | |||
@@ -50,6 +50,7 @@ | |||
50 | #include <asm/param.h> | 50 | #include <asm/param.h> |
51 | #include <asm/traps.h> | 51 | #include <asm/traps.h> |
52 | #include <asm/smp.h> | 52 | #include <asm/smp.h> |
53 | #include <asm/sysmem.h> | ||
53 | 54 | ||
54 | #include <platform/hardware.h> | 55 | #include <platform/hardware.h> |
55 | 56 | ||
@@ -88,12 +89,6 @@ static char __initdata command_line[COMMAND_LINE_SIZE]; | |||
88 | static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; | 89 | static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; |
89 | #endif | 90 | #endif |
90 | 91 | ||
91 | sysmem_info_t __initdata sysmem; | ||
92 | |||
93 | extern int mem_reserve(unsigned long, unsigned long, int); | ||
94 | extern void bootmem_init(void); | ||
95 | extern void zones_init(void); | ||
96 | |||
97 | /* | 92 | /* |
98 | * Boot parameter parsing. | 93 | * Boot parameter parsing. |
99 | * | 94 | * |
@@ -113,31 +108,14 @@ typedef struct tagtable { | |||
113 | 108 | ||
114 | /* parse current tag */ | 109 | /* parse current tag */ |
115 | 110 | ||
116 | static int __init add_sysmem_bank(unsigned long type, unsigned long start, | ||
117 | unsigned long end) | ||
118 | { | ||
119 | if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) { | ||
120 | printk(KERN_WARNING | ||
121 | "Ignoring memory bank 0x%08lx size %ldKB\n", | ||
122 | start, end - start); | ||
123 | return -EINVAL; | ||
124 | } | ||
125 | sysmem.bank[sysmem.nr_banks].type = type; | ||
126 | sysmem.bank[sysmem.nr_banks].start = PAGE_ALIGN(start); | ||
127 | sysmem.bank[sysmem.nr_banks].end = end & PAGE_MASK; | ||
128 | sysmem.nr_banks++; | ||
129 | |||
130 | return 0; | ||
131 | } | ||
132 | |||
133 | static int __init parse_tag_mem(const bp_tag_t *tag) | 111 | static int __init parse_tag_mem(const bp_tag_t *tag) |
134 | { | 112 | { |
135 | meminfo_t *mi = (meminfo_t *)(tag->data); | 113 | struct bp_meminfo *mi = (struct bp_meminfo *)(tag->data); |
136 | 114 | ||
137 | if (mi->type != MEMORY_TYPE_CONVENTIONAL) | 115 | if (mi->type != MEMORY_TYPE_CONVENTIONAL) |
138 | return -1; | 116 | return -1; |
139 | 117 | ||
140 | return add_sysmem_bank(mi->type, mi->start, mi->end); | 118 | return add_sysmem_bank(mi->start, mi->end); |
141 | } | 119 | } |
142 | 120 | ||
143 | __tagtable(BP_TAG_MEMORY, parse_tag_mem); | 121 | __tagtable(BP_TAG_MEMORY, parse_tag_mem); |
@@ -146,8 +124,8 @@ __tagtable(BP_TAG_MEMORY, parse_tag_mem); | |||
146 | 124 | ||
147 | static int __init parse_tag_initrd(const bp_tag_t* tag) | 125 | static int __init parse_tag_initrd(const bp_tag_t* tag) |
148 | { | 126 | { |
149 | meminfo_t* mi; | 127 | struct bp_meminfo *mi = (struct bp_meminfo *)(tag->data); |
150 | mi = (meminfo_t*)(tag->data); | 128 | |
151 | initrd_start = (unsigned long)__va(mi->start); | 129 | initrd_start = (unsigned long)__va(mi->start); |
152 | initrd_end = (unsigned long)__va(mi->end); | 130 | initrd_end = (unsigned long)__va(mi->end); |
153 | 131 | ||
@@ -255,7 +233,7 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) | |||
255 | return; | 233 | return; |
256 | 234 | ||
257 | size &= PAGE_MASK; | 235 | size &= PAGE_MASK; |
258 | add_sysmem_bank(MEMORY_TYPE_CONVENTIONAL, base, base + size); | 236 | add_sysmem_bank(base, base + size); |
259 | } | 237 | } |
260 | 238 | ||
261 | void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) | 239 | void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) |
@@ -292,8 +270,6 @@ device_initcall(xtensa_device_probe); | |||
292 | 270 | ||
293 | void __init init_arch(bp_tag_t *bp_start) | 271 | void __init init_arch(bp_tag_t *bp_start) |
294 | { | 272 | { |
295 | sysmem.nr_banks = 0; | ||
296 | |||
297 | /* Parse boot parameters */ | 273 | /* Parse boot parameters */ |
298 | 274 | ||
299 | if (bp_start) | 275 | if (bp_start) |
@@ -304,10 +280,9 @@ void __init init_arch(bp_tag_t *bp_start) | |||
304 | #endif | 280 | #endif |
305 | 281 | ||
306 | if (sysmem.nr_banks == 0) { | 282 | if (sysmem.nr_banks == 0) { |
307 | sysmem.nr_banks = 1; | 283 | add_sysmem_bank(PLATFORM_DEFAULT_MEM_START, |
308 | sysmem.bank[0].start = PLATFORM_DEFAULT_MEM_START; | 284 | PLATFORM_DEFAULT_MEM_START + |
309 | sysmem.bank[0].end = PLATFORM_DEFAULT_MEM_START | 285 | PLATFORM_DEFAULT_MEM_SIZE); |
310 | + PLATFORM_DEFAULT_MEM_SIZE; | ||
311 | } | 286 | } |
312 | 287 | ||
313 | #ifdef CONFIG_CMDLINE_BOOL | 288 | #ifdef CONFIG_CMDLINE_BOOL |
@@ -487,7 +462,7 @@ void __init setup_arch(char **cmdline_p) | |||
487 | #ifdef CONFIG_BLK_DEV_INITRD | 462 | #ifdef CONFIG_BLK_DEV_INITRD |
488 | if (initrd_start < initrd_end) { | 463 | if (initrd_start < initrd_end) { |
489 | initrd_is_mapped = mem_reserve(__pa(initrd_start), | 464 | initrd_is_mapped = mem_reserve(__pa(initrd_start), |
490 | __pa(initrd_end), 0); | 465 | __pa(initrd_end), 0) == 0; |
491 | initrd_below_start_ok = 1; | 466 | initrd_below_start_ok = 1; |
492 | } else { | 467 | } else { |
493 | initrd_start = 0; | 468 | initrd_start = 0; |
@@ -532,6 +507,7 @@ void __init setup_arch(char **cmdline_p) | |||
532 | __pa(&_Level6InterruptVector_text_end), 0); | 507 | __pa(&_Level6InterruptVector_text_end), 0); |
533 | #endif | 508 | #endif |
534 | 509 | ||
510 | parse_early_param(); | ||
535 | bootmem_init(); | 511 | bootmem_init(); |
536 | 512 | ||
537 | unflatten_and_copy_device_tree(); | 513 | unflatten_and_copy_device_tree(); |
diff --git a/arch/xtensa/kernel/smp.c b/arch/xtensa/kernel/smp.c index aa8bd8717927..40b5a3771fb0 100644 --- a/arch/xtensa/kernel/smp.c +++ b/arch/xtensa/kernel/smp.c | |||
@@ -496,6 +496,21 @@ void flush_tlb_range(struct vm_area_struct *vma, | |||
496 | on_each_cpu(ipi_flush_tlb_range, &fd, 1); | 496 | on_each_cpu(ipi_flush_tlb_range, &fd, 1); |
497 | } | 497 | } |
498 | 498 | ||
499 | static void ipi_flush_tlb_kernel_range(void *arg) | ||
500 | { | ||
501 | struct flush_data *fd = arg; | ||
502 | local_flush_tlb_kernel_range(fd->addr1, fd->addr2); | ||
503 | } | ||
504 | |||
505 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) | ||
506 | { | ||
507 | struct flush_data fd = { | ||
508 | .addr1 = start, | ||
509 | .addr2 = end, | ||
510 | }; | ||
511 | on_each_cpu(ipi_flush_tlb_kernel_range, &fd, 1); | ||
512 | } | ||
513 | |||
499 | /* Cache flush functions */ | 514 | /* Cache flush functions */ |
500 | 515 | ||
501 | static void ipi_flush_cache_all(void *arg) | 516 | static void ipi_flush_cache_all(void *arg) |
diff --git a/arch/xtensa/kernel/xtensa_ksyms.c b/arch/xtensa/kernel/xtensa_ksyms.c index 80b33ed51f31..4d2872fd9bb5 100644 --- a/arch/xtensa/kernel/xtensa_ksyms.c +++ b/arch/xtensa/kernel/xtensa_ksyms.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/in6.h> | 20 | #include <linux/in6.h> |
21 | 21 | ||
22 | #include <asm/uaccess.h> | 22 | #include <asm/uaccess.h> |
23 | #include <asm/cacheflush.h> | ||
23 | #include <asm/checksum.h> | 24 | #include <asm/checksum.h> |
24 | #include <asm/dma.h> | 25 | #include <asm/dma.h> |
25 | #include <asm/io.h> | 26 | #include <asm/io.h> |
@@ -105,6 +106,7 @@ EXPORT_SYMBOL(csum_partial_copy_generic); | |||
105 | * Architecture-specific symbols | 106 | * Architecture-specific symbols |
106 | */ | 107 | */ |
107 | EXPORT_SYMBOL(__xtensa_copy_user); | 108 | EXPORT_SYMBOL(__xtensa_copy_user); |
109 | EXPORT_SYMBOL(__invalidate_icache_range); | ||
108 | 110 | ||
109 | /* | 111 | /* |
110 | * Kernel hacking ... | 112 | * Kernel hacking ... |
@@ -127,3 +129,8 @@ EXPORT_SYMBOL(common_exception_return); | |||
127 | #ifdef CONFIG_FUNCTION_TRACER | 129 | #ifdef CONFIG_FUNCTION_TRACER |
128 | EXPORT_SYMBOL(_mcount); | 130 | EXPORT_SYMBOL(_mcount); |
129 | #endif | 131 | #endif |
132 | |||
133 | EXPORT_SYMBOL(__invalidate_dcache_range); | ||
134 | #if XCHAL_DCACHE_IS_WRITEBACK | ||
135 | EXPORT_SYMBOL(__flush_dcache_range); | ||
136 | #endif | ||
diff --git a/arch/xtensa/mm/Makefile b/arch/xtensa/mm/Makefile index f0b646d2f843..f54f78e24d7b 100644 --- a/arch/xtensa/mm/Makefile +++ b/arch/xtensa/mm/Makefile | |||
@@ -4,3 +4,4 @@ | |||
4 | 4 | ||
5 | obj-y := init.o cache.o misc.o | 5 | obj-y := init.o cache.o misc.o |
6 | obj-$(CONFIG_MMU) += fault.o mmu.o tlb.o | 6 | obj-$(CONFIG_MMU) += fault.o mmu.o tlb.o |
7 | obj-$(CONFIG_HIGHMEM) += highmem.o | ||
diff --git a/arch/xtensa/mm/cache.c b/arch/xtensa/mm/cache.c index ba4c47f291b1..63cbb867dadd 100644 --- a/arch/xtensa/mm/cache.c +++ b/arch/xtensa/mm/cache.c | |||
@@ -59,6 +59,10 @@ | |||
59 | * | 59 | * |
60 | */ | 60 | */ |
61 | 61 | ||
62 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) && defined(CONFIG_HIGHMEM) | ||
63 | #error "HIGHMEM is not supported on cores with aliasing cache." | ||
64 | #endif | ||
65 | |||
62 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK | 66 | #if (DCACHE_WAY_SIZE > PAGE_SIZE) && XCHAL_DCACHE_IS_WRITEBACK |
63 | 67 | ||
64 | /* | 68 | /* |
@@ -179,10 +183,11 @@ update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t *ptep) | |||
179 | #else | 183 | #else |
180 | if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags) | 184 | if (!PageReserved(page) && !test_bit(PG_arch_1, &page->flags) |
181 | && (vma->vm_flags & VM_EXEC) != 0) { | 185 | && (vma->vm_flags & VM_EXEC) != 0) { |
182 | unsigned long paddr = (unsigned long) page_address(page); | 186 | unsigned long paddr = (unsigned long)kmap_atomic(page); |
183 | __flush_dcache_page(paddr); | 187 | __flush_dcache_page(paddr); |
184 | __invalidate_icache_page(paddr); | 188 | __invalidate_icache_page(paddr); |
185 | set_bit(PG_arch_1, &page->flags); | 189 | set_bit(PG_arch_1, &page->flags); |
190 | kunmap_atomic((void *)paddr); | ||
186 | } | 191 | } |
187 | #endif | 192 | #endif |
188 | } | 193 | } |
diff --git a/arch/xtensa/mm/highmem.c b/arch/xtensa/mm/highmem.c new file mode 100644 index 000000000000..17a8c0d6fd17 --- /dev/null +++ b/arch/xtensa/mm/highmem.c | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * High memory support for Xtensa architecture | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General | ||
5 | * Public License. See the file "COPYING" in the main directory of | ||
6 | * this archive for more details. | ||
7 | * | ||
8 | * Copyright (C) 2014 Cadence Design Systems Inc. | ||
9 | */ | ||
10 | |||
11 | #include <linux/export.h> | ||
12 | #include <linux/highmem.h> | ||
13 | #include <asm/tlbflush.h> | ||
14 | |||
15 | static pte_t *kmap_pte; | ||
16 | |||
17 | void *kmap_atomic(struct page *page) | ||
18 | { | ||
19 | enum fixed_addresses idx; | ||
20 | unsigned long vaddr; | ||
21 | int type; | ||
22 | |||
23 | pagefault_disable(); | ||
24 | if (!PageHighMem(page)) | ||
25 | return page_address(page); | ||
26 | |||
27 | type = kmap_atomic_idx_push(); | ||
28 | idx = type + KM_TYPE_NR * smp_processor_id(); | ||
29 | vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); | ||
30 | #ifdef CONFIG_DEBUG_HIGHMEM | ||
31 | BUG_ON(!pte_none(*(kmap_pte - idx))); | ||
32 | #endif | ||
33 | set_pte(kmap_pte - idx, mk_pte(page, PAGE_KERNEL_EXEC)); | ||
34 | |||
35 | return (void *)vaddr; | ||
36 | } | ||
37 | EXPORT_SYMBOL(kmap_atomic); | ||
38 | |||
39 | void __kunmap_atomic(void *kvaddr) | ||
40 | { | ||
41 | int idx, type; | ||
42 | |||
43 | if (kvaddr >= (void *)FIXADDR_START && | ||
44 | kvaddr < (void *)FIXADDR_TOP) { | ||
45 | type = kmap_atomic_idx(); | ||
46 | idx = type + KM_TYPE_NR * smp_processor_id(); | ||
47 | |||
48 | /* | ||
49 | * Force other mappings to Oops if they'll try to access this | ||
50 | * pte without first remap it. Keeping stale mappings around | ||
51 | * is a bad idea also, in case the page changes cacheability | ||
52 | * attributes or becomes a protected page in a hypervisor. | ||
53 | */ | ||
54 | pte_clear(&init_mm, kvaddr, kmap_pte - idx); | ||
55 | local_flush_tlb_kernel_range((unsigned long)kvaddr, | ||
56 | (unsigned long)kvaddr + PAGE_SIZE); | ||
57 | |||
58 | kmap_atomic_idx_pop(); | ||
59 | } | ||
60 | |||
61 | pagefault_enable(); | ||
62 | } | ||
63 | EXPORT_SYMBOL(__kunmap_atomic); | ||
64 | |||
65 | void __init kmap_init(void) | ||
66 | { | ||
67 | unsigned long kmap_vstart; | ||
68 | |||
69 | /* cache the first kmap pte */ | ||
70 | kmap_vstart = __fix_to_virt(FIX_KMAP_BEGIN); | ||
71 | kmap_pte = kmap_get_fixmap_pte(kmap_vstart); | ||
72 | } | ||
diff --git a/arch/xtensa/mm/init.c b/arch/xtensa/mm/init.c index aff108df92d3..4224256bb215 100644 --- a/arch/xtensa/mm/init.c +++ b/arch/xtensa/mm/init.c | |||
@@ -8,6 +8,7 @@ | |||
8 | * for more details. | 8 | * for more details. |
9 | * | 9 | * |
10 | * Copyright (C) 2001 - 2005 Tensilica Inc. | 10 | * Copyright (C) 2001 - 2005 Tensilica Inc. |
11 | * Copyright (C) 2014 Cadence Design Systems Inc. | ||
11 | * | 12 | * |
12 | * Chris Zankel <chris@zankel.net> | 13 | * Chris Zankel <chris@zankel.net> |
13 | * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> | 14 | * Joe Taylor <joe@tensilica.com, joetylr@yahoo.com> |
@@ -19,6 +20,7 @@ | |||
19 | #include <linux/errno.h> | 20 | #include <linux/errno.h> |
20 | #include <linux/bootmem.h> | 21 | #include <linux/bootmem.h> |
21 | #include <linux/gfp.h> | 22 | #include <linux/gfp.h> |
23 | #include <linux/highmem.h> | ||
22 | #include <linux/swap.h> | 24 | #include <linux/swap.h> |
23 | #include <linux/mman.h> | 25 | #include <linux/mman.h> |
24 | #include <linux/nodemask.h> | 26 | #include <linux/nodemask.h> |
@@ -27,11 +29,133 @@ | |||
27 | #include <asm/bootparam.h> | 29 | #include <asm/bootparam.h> |
28 | #include <asm/page.h> | 30 | #include <asm/page.h> |
29 | #include <asm/sections.h> | 31 | #include <asm/sections.h> |
32 | #include <asm/sysmem.h> | ||
33 | |||
34 | struct sysmem_info sysmem __initdata; | ||
35 | |||
36 | static void __init sysmem_dump(void) | ||
37 | { | ||
38 | unsigned i; | ||
39 | |||
40 | pr_debug("Sysmem:\n"); | ||
41 | for (i = 0; i < sysmem.nr_banks; ++i) | ||
42 | pr_debug(" 0x%08lx - 0x%08lx (%ldK)\n", | ||
43 | sysmem.bank[i].start, sysmem.bank[i].end, | ||
44 | (sysmem.bank[i].end - sysmem.bank[i].start) >> 10); | ||
45 | } | ||
46 | |||
47 | /* | ||
48 | * Find bank with maximal .start such that bank.start <= start | ||
49 | */ | ||
50 | static inline struct meminfo * __init find_bank(unsigned long start) | ||
51 | { | ||
52 | unsigned i; | ||
53 | struct meminfo *it = NULL; | ||
54 | |||
55 | for (i = 0; i < sysmem.nr_banks; ++i) | ||
56 | if (sysmem.bank[i].start <= start) | ||
57 | it = sysmem.bank + i; | ||
58 | else | ||
59 | break; | ||
60 | return it; | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * Move all memory banks starting at 'from' to a new place at 'to', | ||
65 | * adjust nr_banks accordingly. | ||
66 | * Both 'from' and 'to' must be inside the sysmem.bank. | ||
67 | * | ||
68 | * Returns: 0 (success), -ENOMEM (not enough space in the sysmem.bank). | ||
69 | */ | ||
70 | static int __init move_banks(struct meminfo *to, struct meminfo *from) | ||
71 | { | ||
72 | unsigned n = sysmem.nr_banks - (from - sysmem.bank); | ||
73 | |||
74 | if (to > from && to - from + sysmem.nr_banks > SYSMEM_BANKS_MAX) | ||
75 | return -ENOMEM; | ||
76 | if (to != from) | ||
77 | memmove(to, from, n * sizeof(struct meminfo)); | ||
78 | sysmem.nr_banks += to - from; | ||
79 | return 0; | ||
80 | } | ||
81 | |||
82 | /* | ||
83 | * Add new bank to sysmem. Resulting sysmem is the union of bytes of the | ||
84 | * original sysmem and the new bank. | ||
85 | * | ||
86 | * Returns: 0 (success), < 0 (error) | ||
87 | */ | ||
88 | int __init add_sysmem_bank(unsigned long start, unsigned long end) | ||
89 | { | ||
90 | unsigned i; | ||
91 | struct meminfo *it = NULL; | ||
92 | unsigned long sz; | ||
93 | unsigned long bank_sz = 0; | ||
94 | |||
95 | if (start == end || | ||
96 | (start < end) != (PAGE_ALIGN(start) < (end & PAGE_MASK))) { | ||
97 | pr_warn("Ignoring small memory bank 0x%08lx size: %ld bytes\n", | ||
98 | start, end - start); | ||
99 | return -EINVAL; | ||
100 | } | ||
101 | |||
102 | start = PAGE_ALIGN(start); | ||
103 | end &= PAGE_MASK; | ||
104 | sz = end - start; | ||
105 | |||
106 | it = find_bank(start); | ||
107 | |||
108 | if (it) | ||
109 | bank_sz = it->end - it->start; | ||
110 | |||
111 | if (it && bank_sz >= start - it->start) { | ||
112 | if (end - it->start > bank_sz) | ||
113 | it->end = end; | ||
114 | else | ||
115 | return 0; | ||
116 | } else { | ||
117 | if (!it) | ||
118 | it = sysmem.bank; | ||
119 | else | ||
120 | ++it; | ||
121 | |||
122 | if (it - sysmem.bank < sysmem.nr_banks && | ||
123 | it->start - start <= sz) { | ||
124 | it->start = start; | ||
125 | if (it->end - it->start < sz) | ||
126 | it->end = end; | ||
127 | else | ||
128 | return 0; | ||
129 | } else { | ||
130 | if (move_banks(it + 1, it) < 0) { | ||
131 | pr_warn("Ignoring memory bank 0x%08lx size %ld bytes\n", | ||
132 | start, end - start); | ||
133 | return -EINVAL; | ||
134 | } | ||
135 | it->start = start; | ||
136 | it->end = end; | ||
137 | return 0; | ||
138 | } | ||
139 | } | ||
140 | sz = it->end - it->start; | ||
141 | for (i = it + 1 - sysmem.bank; i < sysmem.nr_banks; ++i) | ||
142 | if (sysmem.bank[i].start - it->start <= sz) { | ||
143 | if (sz < sysmem.bank[i].end - it->start) | ||
144 | it->end = sysmem.bank[i].end; | ||
145 | } else { | ||
146 | break; | ||
147 | } | ||
148 | |||
149 | move_banks(it + 1, sysmem.bank + i); | ||
150 | return 0; | ||
151 | } | ||
30 | 152 | ||
31 | /* | 153 | /* |
32 | * mem_reserve(start, end, must_exist) | 154 | * mem_reserve(start, end, must_exist) |
33 | * | 155 | * |
34 | * Reserve some memory from the memory pool. | 156 | * Reserve some memory from the memory pool. |
157 | * If must_exist is set and a part of the region being reserved does not exist | ||
158 | * memory map is not altered. | ||
35 | * | 159 | * |
36 | * Parameters: | 160 | * Parameters: |
37 | * start Start of region, | 161 | * start Start of region, |
@@ -39,53 +163,69 @@ | |||
39 | * must_exist Must exist in memory pool. | 163 | * must_exist Must exist in memory pool. |
40 | * | 164 | * |
41 | * Returns: | 165 | * Returns: |
42 | * 0 (memory area couldn't be mapped) | 166 | * 0 (success) |
43 | * -1 (success) | 167 | * < 0 (error) |
44 | */ | 168 | */ |
45 | 169 | ||
46 | int __init mem_reserve(unsigned long start, unsigned long end, int must_exist) | 170 | int __init mem_reserve(unsigned long start, unsigned long end, int must_exist) |
47 | { | 171 | { |
48 | int i; | 172 | struct meminfo *it; |
49 | 173 | struct meminfo *rm = NULL; | |
50 | if (start == end) | 174 | unsigned long sz; |
51 | return 0; | 175 | unsigned long bank_sz = 0; |
52 | 176 | ||
53 | start = start & PAGE_MASK; | 177 | start = start & PAGE_MASK; |
54 | end = PAGE_ALIGN(end); | 178 | end = PAGE_ALIGN(end); |
179 | sz = end - start; | ||
180 | if (!sz) | ||
181 | return -EINVAL; | ||
55 | 182 | ||
56 | for (i = 0; i < sysmem.nr_banks; i++) | 183 | it = find_bank(start); |
57 | if (start < sysmem.bank[i].end | 184 | |
58 | && end >= sysmem.bank[i].start) | 185 | if (it) |
59 | break; | 186 | bank_sz = it->end - it->start; |
60 | 187 | ||
61 | if (i == sysmem.nr_banks) { | 188 | if ((!it || end - it->start > bank_sz) && must_exist) { |
62 | if (must_exist) | 189 | pr_warn("mem_reserve: [0x%0lx, 0x%0lx) not in any region!\n", |
63 | printk (KERN_WARNING "mem_reserve: [0x%0lx, 0x%0lx) " | 190 | start, end); |
64 | "not in any region!\n", start, end); | 191 | return -EINVAL; |
65 | return 0; | ||
66 | } | 192 | } |
67 | 193 | ||
68 | if (start > sysmem.bank[i].start) { | 194 | if (it && start - it->start < bank_sz) { |
69 | if (end < sysmem.bank[i].end) { | 195 | if (start == it->start) { |
70 | /* split entry */ | 196 | if (end - it->start < bank_sz) { |
71 | if (sysmem.nr_banks >= SYSMEM_BANKS_MAX) | 197 | it->start = end; |
72 | panic("meminfo overflow\n"); | 198 | return 0; |
73 | sysmem.bank[sysmem.nr_banks].start = end; | 199 | } else { |
74 | sysmem.bank[sysmem.nr_banks].end = sysmem.bank[i].end; | 200 | rm = it; |
75 | sysmem.nr_banks++; | 201 | } |
202 | } else { | ||
203 | it->end = start; | ||
204 | if (end - it->start < bank_sz) | ||
205 | return add_sysmem_bank(end, | ||
206 | it->start + bank_sz); | ||
207 | ++it; | ||
76 | } | 208 | } |
77 | sysmem.bank[i].end = start; | 209 | } |
78 | 210 | ||
79 | } else if (end < sysmem.bank[i].end) { | 211 | if (!it) |
80 | sysmem.bank[i].start = end; | 212 | it = sysmem.bank; |
81 | 213 | ||
82 | } else { | 214 | for (; it < sysmem.bank + sysmem.nr_banks; ++it) { |
83 | /* remove entry */ | 215 | if (it->end - start <= sz) { |
84 | sysmem.nr_banks--; | 216 | if (!rm) |
85 | sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start; | 217 | rm = it; |
86 | sysmem.bank[i].end = sysmem.bank[sysmem.nr_banks].end; | 218 | } else { |
219 | if (it->start - start < sz) | ||
220 | it->start = end; | ||
221 | break; | ||
222 | } | ||
87 | } | 223 | } |
88 | return -1; | 224 | |
225 | if (rm) | ||
226 | move_banks(rm, it); | ||
227 | |||
228 | return 0; | ||
89 | } | 229 | } |
90 | 230 | ||
91 | 231 | ||
@@ -99,6 +239,7 @@ void __init bootmem_init(void) | |||
99 | unsigned long bootmap_start, bootmap_size; | 239 | unsigned long bootmap_start, bootmap_size; |
100 | int i; | 240 | int i; |
101 | 241 | ||
242 | sysmem_dump(); | ||
102 | max_low_pfn = max_pfn = 0; | 243 | max_low_pfn = max_pfn = 0; |
103 | min_low_pfn = ~0; | 244 | min_low_pfn = ~0; |
104 | 245 | ||
@@ -156,19 +297,13 @@ void __init bootmem_init(void) | |||
156 | 297 | ||
157 | void __init zones_init(void) | 298 | void __init zones_init(void) |
158 | { | 299 | { |
159 | unsigned long zones_size[MAX_NR_ZONES]; | ||
160 | int i; | ||
161 | |||
162 | /* All pages are DMA-able, so we put them all in the DMA zone. */ | 300 | /* All pages are DMA-able, so we put them all in the DMA zone. */ |
163 | 301 | unsigned long zones_size[MAX_NR_ZONES] = { | |
164 | zones_size[ZONE_DMA] = max_low_pfn - ARCH_PFN_OFFSET; | 302 | [ZONE_DMA] = max_low_pfn - ARCH_PFN_OFFSET, |
165 | for (i = 1; i < MAX_NR_ZONES; i++) | ||
166 | zones_size[i] = 0; | ||
167 | |||
168 | #ifdef CONFIG_HIGHMEM | 303 | #ifdef CONFIG_HIGHMEM |
169 | zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn; | 304 | [ZONE_HIGHMEM] = max_pfn - max_low_pfn, |
170 | #endif | 305 | #endif |
171 | 306 | }; | |
172 | free_area_init_node(0, zones_size, ARCH_PFN_OFFSET, NULL); | 307 | free_area_init_node(0, zones_size, ARCH_PFN_OFFSET, NULL); |
173 | } | 308 | } |
174 | 309 | ||
@@ -178,16 +313,38 @@ void __init zones_init(void) | |||
178 | 313 | ||
179 | void __init mem_init(void) | 314 | void __init mem_init(void) |
180 | { | 315 | { |
181 | max_mapnr = max_low_pfn - ARCH_PFN_OFFSET; | ||
182 | high_memory = (void *) __va(max_low_pfn << PAGE_SHIFT); | ||
183 | |||
184 | #ifdef CONFIG_HIGHMEM | 316 | #ifdef CONFIG_HIGHMEM |
185 | #error HIGHGMEM not implemented in init.c | 317 | unsigned long tmp; |
318 | |||
319 | reset_all_zones_managed_pages(); | ||
320 | for (tmp = max_low_pfn; tmp < max_pfn; tmp++) | ||
321 | free_highmem_page(pfn_to_page(tmp)); | ||
186 | #endif | 322 | #endif |
187 | 323 | ||
324 | max_mapnr = max_pfn - ARCH_PFN_OFFSET; | ||
325 | high_memory = (void *)__va(max_low_pfn << PAGE_SHIFT); | ||
326 | |||
188 | free_all_bootmem(); | 327 | free_all_bootmem(); |
189 | 328 | ||
190 | mem_init_print_info(NULL); | 329 | mem_init_print_info(NULL); |
330 | pr_info("virtual kernel memory layout:\n" | ||
331 | #ifdef CONFIG_HIGHMEM | ||
332 | " pkmap : 0x%08lx - 0x%08lx (%5lu kB)\n" | ||
333 | " fixmap : 0x%08lx - 0x%08lx (%5lu kB)\n" | ||
334 | #endif | ||
335 | " vmalloc : 0x%08x - 0x%08x (%5u MB)\n" | ||
336 | " lowmem : 0x%08x - 0x%08lx (%5lu MB)\n", | ||
337 | #ifdef CONFIG_HIGHMEM | ||
338 | PKMAP_BASE, PKMAP_BASE + LAST_PKMAP * PAGE_SIZE, | ||
339 | (LAST_PKMAP*PAGE_SIZE) >> 10, | ||
340 | FIXADDR_START, FIXADDR_TOP, | ||
341 | (FIXADDR_TOP - FIXADDR_START) >> 10, | ||
342 | #endif | ||
343 | VMALLOC_START, VMALLOC_END, | ||
344 | (VMALLOC_END - VMALLOC_START) >> 20, | ||
345 | PAGE_OFFSET, PAGE_OFFSET + | ||
346 | (max_low_pfn - min_low_pfn) * PAGE_SIZE, | ||
347 | ((max_low_pfn - min_low_pfn) * PAGE_SIZE) >> 20); | ||
191 | } | 348 | } |
192 | 349 | ||
193 | #ifdef CONFIG_BLK_DEV_INITRD | 350 | #ifdef CONFIG_BLK_DEV_INITRD |
@@ -204,3 +361,53 @@ void free_initmem(void) | |||
204 | { | 361 | { |
205 | free_initmem_default(-1); | 362 | free_initmem_default(-1); |
206 | } | 363 | } |
364 | |||
365 | static void __init parse_memmap_one(char *p) | ||
366 | { | ||
367 | char *oldp; | ||
368 | unsigned long start_at, mem_size; | ||
369 | |||
370 | if (!p) | ||
371 | return; | ||
372 | |||
373 | oldp = p; | ||
374 | mem_size = memparse(p, &p); | ||
375 | if (p == oldp) | ||
376 | return; | ||
377 | |||
378 | switch (*p) { | ||
379 | case '@': | ||
380 | start_at = memparse(p + 1, &p); | ||
381 | add_sysmem_bank(start_at, start_at + mem_size); | ||
382 | break; | ||
383 | |||
384 | case '$': | ||
385 | start_at = memparse(p + 1, &p); | ||
386 | mem_reserve(start_at, start_at + mem_size, 0); | ||
387 | break; | ||
388 | |||
389 | case 0: | ||
390 | mem_reserve(mem_size, 0, 0); | ||
391 | break; | ||
392 | |||
393 | default: | ||
394 | pr_warn("Unrecognized memmap syntax: %s\n", p); | ||
395 | break; | ||
396 | } | ||
397 | } | ||
398 | |||
399 | static int __init parse_memmap_opt(char *str) | ||
400 | { | ||
401 | while (str) { | ||
402 | char *k = strchr(str, ','); | ||
403 | |||
404 | if (k) | ||
405 | *k++ = 0; | ||
406 | |||
407 | parse_memmap_one(str); | ||
408 | str = k; | ||
409 | } | ||
410 | |||
411 | return 0; | ||
412 | } | ||
413 | early_param("memmap", parse_memmap_opt); | ||
diff --git a/arch/xtensa/mm/mmu.c b/arch/xtensa/mm/mmu.c index 861203e958da..3429b483d9f8 100644 --- a/arch/xtensa/mm/mmu.c +++ b/arch/xtensa/mm/mmu.c | |||
@@ -3,6 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Extracted from init.c | 4 | * Extracted from init.c |
5 | */ | 5 | */ |
6 | #include <linux/bootmem.h> | ||
6 | #include <linux/percpu.h> | 7 | #include <linux/percpu.h> |
7 | #include <linux/init.h> | 8 | #include <linux/init.h> |
8 | #include <linux/string.h> | 9 | #include <linux/string.h> |
@@ -16,9 +17,44 @@ | |||
16 | #include <asm/initialize_mmu.h> | 17 | #include <asm/initialize_mmu.h> |
17 | #include <asm/io.h> | 18 | #include <asm/io.h> |
18 | 19 | ||
20 | #if defined(CONFIG_HIGHMEM) | ||
21 | static void * __init init_pmd(unsigned long vaddr) | ||
22 | { | ||
23 | pgd_t *pgd = pgd_offset_k(vaddr); | ||
24 | pmd_t *pmd = pmd_offset(pgd, vaddr); | ||
25 | |||
26 | if (pmd_none(*pmd)) { | ||
27 | unsigned i; | ||
28 | pte_t *pte = alloc_bootmem_low_pages(PAGE_SIZE); | ||
29 | |||
30 | for (i = 0; i < 1024; i++) | ||
31 | pte_clear(NULL, 0, pte + i); | ||
32 | |||
33 | set_pmd(pmd, __pmd(((unsigned long)pte) & PAGE_MASK)); | ||
34 | BUG_ON(pte != pte_offset_kernel(pmd, 0)); | ||
35 | pr_debug("%s: vaddr: 0x%08lx, pmd: 0x%p, pte: 0x%p\n", | ||
36 | __func__, vaddr, pmd, pte); | ||
37 | return pte; | ||
38 | } else { | ||
39 | return pte_offset_kernel(pmd, 0); | ||
40 | } | ||
41 | } | ||
42 | |||
43 | static void __init fixedrange_init(void) | ||
44 | { | ||
45 | BUILD_BUG_ON(FIXADDR_SIZE > PMD_SIZE); | ||
46 | init_pmd(__fix_to_virt(__end_of_fixed_addresses - 1) & PMD_MASK); | ||
47 | } | ||
48 | #endif | ||
49 | |||
19 | void __init paging_init(void) | 50 | void __init paging_init(void) |
20 | { | 51 | { |
21 | memset(swapper_pg_dir, 0, PAGE_SIZE); | 52 | memset(swapper_pg_dir, 0, PAGE_SIZE); |
53 | #ifdef CONFIG_HIGHMEM | ||
54 | fixedrange_init(); | ||
55 | pkmap_page_table = init_pmd(PKMAP_BASE); | ||
56 | kmap_init(); | ||
57 | #endif | ||
22 | } | 58 | } |
23 | 59 | ||
24 | /* | 60 | /* |
diff --git a/arch/xtensa/mm/tlb.c b/arch/xtensa/mm/tlb.c index ade623826788..5ece856c5725 100644 --- a/arch/xtensa/mm/tlb.c +++ b/arch/xtensa/mm/tlb.c | |||
@@ -149,6 +149,21 @@ void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page) | |||
149 | local_irq_restore(flags); | 149 | local_irq_restore(flags); |
150 | } | 150 | } |
151 | 151 | ||
152 | void local_flush_tlb_kernel_range(unsigned long start, unsigned long end) | ||
153 | { | ||
154 | if (end > start && start >= TASK_SIZE && end <= PAGE_OFFSET && | ||
155 | end - start < _TLB_ENTRIES << PAGE_SHIFT) { | ||
156 | start &= PAGE_MASK; | ||
157 | while (start < end) { | ||
158 | invalidate_itlb_mapping(start); | ||
159 | invalidate_dtlb_mapping(start); | ||
160 | start += PAGE_SIZE; | ||
161 | } | ||
162 | } else { | ||
163 | local_flush_tlb_all(); | ||
164 | } | ||
165 | } | ||
166 | |||
152 | #ifdef CONFIG_DEBUG_TLB_SANITY | 167 | #ifdef CONFIG_DEBUG_TLB_SANITY |
153 | 168 | ||
154 | static unsigned get_pte_for_vaddr(unsigned vaddr) | 169 | static unsigned get_pte_for_vaddr(unsigned vaddr) |
diff --git a/arch/xtensa/platforms/iss/Makefile b/arch/xtensa/platforms/iss/Makefile index d2369b799c50..b3e89291cfba 100644 --- a/arch/xtensa/platforms/iss/Makefile +++ b/arch/xtensa/platforms/iss/Makefile | |||
@@ -4,6 +4,7 @@ | |||
4 | # "prom monitor" library routines under Linux. | 4 | # "prom monitor" library routines under Linux. |
5 | # | 5 | # |
6 | 6 | ||
7 | obj-y = console.o setup.o | 7 | obj-y = setup.o |
8 | obj-$(CONFIG_TTY) += console.o | ||
8 | obj-$(CONFIG_NET) += network.o | 9 | obj-$(CONFIG_NET) += network.o |
9 | obj-$(CONFIG_BLK_DEV_SIMDISK) += simdisk.o | 10 | obj-$(CONFIG_BLK_DEV_SIMDISK) += simdisk.o |
diff --git a/arch/xtensa/platforms/xt2000/setup.c b/arch/xtensa/platforms/xt2000/setup.c index f9bc87966290..b90555cb8089 100644 --- a/arch/xtensa/platforms/xt2000/setup.c +++ b/arch/xtensa/platforms/xt2000/setup.c | |||
@@ -92,18 +92,8 @@ void __init platform_setup(char** cmdline) | |||
92 | 92 | ||
93 | /* early initialization */ | 93 | /* early initialization */ |
94 | 94 | ||
95 | extern sysmem_info_t __initdata sysmem; | 95 | void __init platform_init(bp_tag_t *first) |
96 | |||
97 | void platform_init(bp_tag_t* first) | ||
98 | { | 96 | { |
99 | /* Set default memory block if not provided by the bootloader. */ | ||
100 | |||
101 | if (sysmem.nr_banks == 0) { | ||
102 | sysmem.nr_banks = 1; | ||
103 | sysmem.bank[0].start = PLATFORM_DEFAULT_MEM_START; | ||
104 | sysmem.bank[0].end = PLATFORM_DEFAULT_MEM_START | ||
105 | + PLATFORM_DEFAULT_MEM_SIZE; | ||
106 | } | ||
107 | } | 97 | } |
108 | 98 | ||
109 | /* Heartbeat. Let the LED blink. */ | 99 | /* Heartbeat. Let the LED blink. */ |
diff --git a/crypto/crypto_user.c b/crypto/crypto_user.c index 1512e41cd93d..43665d0d0905 100644 --- a/crypto/crypto_user.c +++ b/crypto/crypto_user.c | |||
@@ -466,7 +466,7 @@ static int crypto_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
466 | type -= CRYPTO_MSG_BASE; | 466 | type -= CRYPTO_MSG_BASE; |
467 | link = &crypto_dispatch[type]; | 467 | link = &crypto_dispatch[type]; |
468 | 468 | ||
469 | if (!capable(CAP_NET_ADMIN)) | 469 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
470 | return -EPERM; | 470 | return -EPERM; |
471 | 471 | ||
472 | if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) && | 472 | if ((type == (CRYPTO_MSG_GETALG - CRYPTO_MSG_BASE) && |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 8f5565bf34cd..fa9bb742df6e 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c | |||
@@ -3067,7 +3067,10 @@ static int raw_cmd_copyout(int cmd, void __user *param, | |||
3067 | int ret; | 3067 | int ret; |
3068 | 3068 | ||
3069 | while (ptr) { | 3069 | while (ptr) { |
3070 | ret = copy_to_user(param, ptr, sizeof(*ptr)); | 3070 | struct floppy_raw_cmd cmd = *ptr; |
3071 | cmd.next = NULL; | ||
3072 | cmd.kernel_data = NULL; | ||
3073 | ret = copy_to_user(param, &cmd, sizeof(cmd)); | ||
3071 | if (ret) | 3074 | if (ret) |
3072 | return -EFAULT; | 3075 | return -EFAULT; |
3073 | param += sizeof(struct floppy_raw_cmd); | 3076 | param += sizeof(struct floppy_raw_cmd); |
@@ -3121,10 +3124,11 @@ loop: | |||
3121 | return -ENOMEM; | 3124 | return -ENOMEM; |
3122 | *rcmd = ptr; | 3125 | *rcmd = ptr; |
3123 | ret = copy_from_user(ptr, param, sizeof(*ptr)); | 3126 | ret = copy_from_user(ptr, param, sizeof(*ptr)); |
3124 | if (ret) | ||
3125 | return -EFAULT; | ||
3126 | ptr->next = NULL; | 3127 | ptr->next = NULL; |
3127 | ptr->buffer_length = 0; | 3128 | ptr->buffer_length = 0; |
3129 | ptr->kernel_data = NULL; | ||
3130 | if (ret) | ||
3131 | return -EFAULT; | ||
3128 | param += sizeof(struct floppy_raw_cmd); | 3132 | param += sizeof(struct floppy_raw_cmd); |
3129 | if (ptr->cmd_count > 33) | 3133 | if (ptr->cmd_count > 33) |
3130 | /* the command may now also take up the space | 3134 | /* the command may now also take up the space |
@@ -3140,7 +3144,6 @@ loop: | |||
3140 | for (i = 0; i < 16; i++) | 3144 | for (i = 0; i < 16; i++) |
3141 | ptr->reply[i] = 0; | 3145 | ptr->reply[i] = 0; |
3142 | ptr->resultcode = 0; | 3146 | ptr->resultcode = 0; |
3143 | ptr->kernel_data = NULL; | ||
3144 | 3147 | ||
3145 | if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) { | 3148 | if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) { |
3146 | if (ptr->length <= 0) | 3149 | if (ptr->length <= 0) |
diff --git a/drivers/bluetooth/ath3k.c b/drivers/bluetooth/ath3k.c index be571fef185d..a83b57e57b63 100644 --- a/drivers/bluetooth/ath3k.c +++ b/drivers/bluetooth/ath3k.c | |||
@@ -82,6 +82,7 @@ static const struct usb_device_id ath3k_table[] = { | |||
82 | { USB_DEVICE(0x04CA, 0x3004) }, | 82 | { USB_DEVICE(0x04CA, 0x3004) }, |
83 | { USB_DEVICE(0x04CA, 0x3005) }, | 83 | { USB_DEVICE(0x04CA, 0x3005) }, |
84 | { USB_DEVICE(0x04CA, 0x3006) }, | 84 | { USB_DEVICE(0x04CA, 0x3006) }, |
85 | { USB_DEVICE(0x04CA, 0x3007) }, | ||
85 | { USB_DEVICE(0x04CA, 0x3008) }, | 86 | { USB_DEVICE(0x04CA, 0x3008) }, |
86 | { USB_DEVICE(0x04CA, 0x300b) }, | 87 | { USB_DEVICE(0x04CA, 0x300b) }, |
87 | { USB_DEVICE(0x0930, 0x0219) }, | 88 | { USB_DEVICE(0x0930, 0x0219) }, |
@@ -131,6 +132,7 @@ static const struct usb_device_id ath3k_blist_tbl[] = { | |||
131 | { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, | 132 | { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, |
132 | { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, | 133 | { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, |
133 | { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, | 134 | { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, |
135 | { USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 }, | ||
134 | { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, | 136 | { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, |
135 | { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, | 137 | { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, |
136 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, | 138 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, |
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c index f338b0c5a8de..a7dfbf9a3afb 100644 --- a/drivers/bluetooth/btusb.c +++ b/drivers/bluetooth/btusb.c | |||
@@ -152,6 +152,7 @@ static const struct usb_device_id blacklist_table[] = { | |||
152 | { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, | 152 | { USB_DEVICE(0x04ca, 0x3004), .driver_info = BTUSB_ATH3012 }, |
153 | { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, | 153 | { USB_DEVICE(0x04ca, 0x3005), .driver_info = BTUSB_ATH3012 }, |
154 | { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, | 154 | { USB_DEVICE(0x04ca, 0x3006), .driver_info = BTUSB_ATH3012 }, |
155 | { USB_DEVICE(0x04ca, 0x3007), .driver_info = BTUSB_ATH3012 }, | ||
155 | { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, | 156 | { USB_DEVICE(0x04ca, 0x3008), .driver_info = BTUSB_ATH3012 }, |
156 | { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, | 157 | { USB_DEVICE(0x04ca, 0x300b), .driver_info = BTUSB_ATH3012 }, |
157 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, | 158 | { USB_DEVICE(0x0930, 0x0219), .driver_info = BTUSB_ATH3012 }, |
@@ -1485,10 +1486,8 @@ static int btusb_probe(struct usb_interface *intf, | |||
1485 | if (id->driver_info & BTUSB_BCM92035) | 1486 | if (id->driver_info & BTUSB_BCM92035) |
1486 | hdev->setup = btusb_setup_bcm92035; | 1487 | hdev->setup = btusb_setup_bcm92035; |
1487 | 1488 | ||
1488 | if (id->driver_info & BTUSB_INTEL) { | 1489 | if (id->driver_info & BTUSB_INTEL) |
1489 | usb_enable_autosuspend(data->udev); | ||
1490 | hdev->setup = btusb_setup_intel; | 1490 | hdev->setup = btusb_setup_intel; |
1491 | } | ||
1492 | 1491 | ||
1493 | /* Interface numbers are hardcoded in the specification */ | 1492 | /* Interface numbers are hardcoded in the specification */ |
1494 | data->isoc = usb_ifnum_to_if(data->udev, 1); | 1493 | data->isoc = usb_ifnum_to_if(data->udev, 1); |
diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index 552373c4e362..286342778884 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig | |||
@@ -41,4 +41,14 @@ config ARM_CCI | |||
41 | help | 41 | help |
42 | Driver supporting the CCI cache coherent interconnect for ARM | 42 | Driver supporting the CCI cache coherent interconnect for ARM |
43 | platforms. | 43 | platforms. |
44 | |||
45 | config VEXPRESS_CONFIG | ||
46 | bool "Versatile Express configuration bus" | ||
47 | default y if ARCH_VEXPRESS | ||
48 | depends on ARM || ARM64 | ||
49 | depends on OF | ||
50 | select REGMAP | ||
51 | help | ||
52 | Platform configuration infrastructure for the ARM Ltd. | ||
53 | Versatile Express. | ||
44 | endmenu | 54 | endmenu |
diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile index 8947bdd0de8b..f095aa771de9 100644 --- a/drivers/bus/Makefile +++ b/drivers/bus/Makefile | |||
@@ -10,3 +10,5 @@ obj-$(CONFIG_OMAP_OCP2SCP) += omap-ocp2scp.o | |||
10 | obj-$(CONFIG_OMAP_INTERCONNECT) += omap_l3_smx.o omap_l3_noc.o | 10 | obj-$(CONFIG_OMAP_INTERCONNECT) += omap_l3_smx.o omap_l3_noc.o |
11 | # CCI cache coherent interconnect for ARM platforms | 11 | # CCI cache coherent interconnect for ARM platforms |
12 | obj-$(CONFIG_ARM_CCI) += arm-cci.o | 12 | obj-$(CONFIG_ARM_CCI) += arm-cci.o |
13 | |||
14 | obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o | ||
diff --git a/drivers/bus/vexpress-config.c b/drivers/bus/vexpress-config.c new file mode 100644 index 000000000000..a64763b6b5fd --- /dev/null +++ b/drivers/bus/vexpress-config.c | |||
@@ -0,0 +1,202 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License version 2 as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * Copyright (C) 2014 ARM Limited | ||
12 | */ | ||
13 | |||
14 | #include <linux/err.h> | ||
15 | #include <linux/init.h> | ||
16 | #include <linux/of.h> | ||
17 | #include <linux/of_device.h> | ||
18 | #include <linux/vexpress.h> | ||
19 | |||
20 | |||
21 | struct vexpress_config_bridge { | ||
22 | struct vexpress_config_bridge_ops *ops; | ||
23 | void *context; | ||
24 | }; | ||
25 | |||
26 | |||
27 | static DEFINE_MUTEX(vexpress_config_mutex); | ||
28 | static struct class *vexpress_config_class; | ||
29 | static u32 vexpress_config_site_master = VEXPRESS_SITE_MASTER; | ||
30 | |||
31 | |||
32 | void vexpress_config_set_master(u32 site) | ||
33 | { | ||
34 | vexpress_config_site_master = site; | ||
35 | } | ||
36 | |||
37 | u32 vexpress_config_get_master(void) | ||
38 | { | ||
39 | return vexpress_config_site_master; | ||
40 | } | ||
41 | |||
42 | void vexpress_config_lock(void *arg) | ||
43 | { | ||
44 | mutex_lock(&vexpress_config_mutex); | ||
45 | } | ||
46 | |||
47 | void vexpress_config_unlock(void *arg) | ||
48 | { | ||
49 | mutex_unlock(&vexpress_config_mutex); | ||
50 | } | ||
51 | |||
52 | |||
53 | static void vexpress_config_find_prop(struct device_node *node, | ||
54 | const char *name, u32 *val) | ||
55 | { | ||
56 | /* Default value */ | ||
57 | *val = 0; | ||
58 | |||
59 | of_node_get(node); | ||
60 | while (node) { | ||
61 | if (of_property_read_u32(node, name, val) == 0) { | ||
62 | of_node_put(node); | ||
63 | return; | ||
64 | } | ||
65 | node = of_get_next_parent(node); | ||
66 | } | ||
67 | } | ||
68 | |||
69 | int vexpress_config_get_topo(struct device_node *node, u32 *site, | ||
70 | u32 *position, u32 *dcc) | ||
71 | { | ||
72 | vexpress_config_find_prop(node, "arm,vexpress,site", site); | ||
73 | if (*site == VEXPRESS_SITE_MASTER) | ||
74 | *site = vexpress_config_site_master; | ||
75 | if (WARN_ON(vexpress_config_site_master == VEXPRESS_SITE_MASTER)) | ||
76 | return -EINVAL; | ||
77 | vexpress_config_find_prop(node, "arm,vexpress,position", position); | ||
78 | vexpress_config_find_prop(node, "arm,vexpress,dcc", dcc); | ||
79 | |||
80 | return 0; | ||
81 | } | ||
82 | |||
83 | |||
84 | static void vexpress_config_devres_release(struct device *dev, void *res) | ||
85 | { | ||
86 | struct vexpress_config_bridge *bridge = dev_get_drvdata(dev->parent); | ||
87 | struct regmap *regmap = res; | ||
88 | |||
89 | bridge->ops->regmap_exit(regmap, bridge->context); | ||
90 | } | ||
91 | |||
92 | struct regmap *devm_regmap_init_vexpress_config(struct device *dev) | ||
93 | { | ||
94 | struct vexpress_config_bridge *bridge; | ||
95 | struct regmap *regmap; | ||
96 | struct regmap **res; | ||
97 | |||
98 | if (WARN_ON(dev->parent->class != vexpress_config_class)) | ||
99 | return ERR_PTR(-ENODEV); | ||
100 | |||
101 | bridge = dev_get_drvdata(dev->parent); | ||
102 | if (WARN_ON(!bridge)) | ||
103 | return ERR_PTR(-EINVAL); | ||
104 | |||
105 | res = devres_alloc(vexpress_config_devres_release, sizeof(*res), | ||
106 | GFP_KERNEL); | ||
107 | if (!res) | ||
108 | return ERR_PTR(-ENOMEM); | ||
109 | |||
110 | regmap = bridge->ops->regmap_init(dev, bridge->context); | ||
111 | if (IS_ERR(regmap)) { | ||
112 | devres_free(res); | ||
113 | return regmap; | ||
114 | } | ||
115 | |||
116 | *res = regmap; | ||
117 | devres_add(dev, res); | ||
118 | |||
119 | return regmap; | ||
120 | } | ||
121 | EXPORT_SYMBOL_GPL(devm_regmap_init_vexpress_config); | ||
122 | |||
123 | struct device *vexpress_config_bridge_register(struct device *parent, | ||
124 | struct vexpress_config_bridge_ops *ops, void *context) | ||
125 | { | ||
126 | struct device *dev; | ||
127 | struct vexpress_config_bridge *bridge; | ||
128 | |||
129 | if (!vexpress_config_class) { | ||
130 | vexpress_config_class = class_create(THIS_MODULE, | ||
131 | "vexpress-config"); | ||
132 | if (IS_ERR(vexpress_config_class)) | ||
133 | return (void *)vexpress_config_class; | ||
134 | } | ||
135 | |||
136 | dev = device_create(vexpress_config_class, parent, 0, | ||
137 | NULL, "%s.bridge", dev_name(parent)); | ||
138 | |||
139 | if (IS_ERR(dev)) | ||
140 | return dev; | ||
141 | |||
142 | bridge = devm_kmalloc(dev, sizeof(*bridge), GFP_KERNEL); | ||
143 | if (!bridge) { | ||
144 | put_device(dev); | ||
145 | device_unregister(dev); | ||
146 | return ERR_PTR(-ENOMEM); | ||
147 | } | ||
148 | bridge->ops = ops; | ||
149 | bridge->context = context; | ||
150 | |||
151 | dev_set_drvdata(dev, bridge); | ||
152 | |||
153 | dev_dbg(parent, "Registered bridge '%s', parent node %p\n", | ||
154 | dev_name(dev), parent->of_node); | ||
155 | |||
156 | return dev; | ||
157 | } | ||
158 | |||
159 | |||
160 | static int vexpress_config_node_match(struct device *dev, const void *data) | ||
161 | { | ||
162 | const struct device_node *node = data; | ||
163 | |||
164 | dev_dbg(dev, "Parent node %p, looking for %p\n", | ||
165 | dev->parent->of_node, node); | ||
166 | |||
167 | return dev->parent->of_node == node; | ||
168 | } | ||
169 | |||
170 | static int vexpress_config_populate(struct device_node *node) | ||
171 | { | ||
172 | struct device_node *bridge; | ||
173 | struct device *parent; | ||
174 | |||
175 | bridge = of_parse_phandle(node, "arm,vexpress,config-bridge", 0); | ||
176 | if (!bridge) | ||
177 | return -EINVAL; | ||
178 | |||
179 | parent = class_find_device(vexpress_config_class, NULL, bridge, | ||
180 | vexpress_config_node_match); | ||
181 | if (WARN_ON(!parent)) | ||
182 | return -ENODEV; | ||
183 | |||
184 | return of_platform_populate(node, NULL, NULL, parent); | ||
185 | } | ||
186 | |||
187 | static int __init vexpress_config_init(void) | ||
188 | { | ||
189 | int err = 0; | ||
190 | struct device_node *node; | ||
191 | |||
192 | /* Need the config devices early, before the "normal" devices... */ | ||
193 | for_each_compatible_node(node, NULL, "arm,vexpress,config-bus") { | ||
194 | err = vexpress_config_populate(node); | ||
195 | if (err) | ||
196 | break; | ||
197 | } | ||
198 | |||
199 | return err; | ||
200 | } | ||
201 | postcore_initcall(vexpress_config_init); | ||
202 | |||
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c index 8121b4c70ede..b29703324e94 100644 --- a/drivers/char/agp/frontend.c +++ b/drivers/char/agp/frontend.c | |||
@@ -730,6 +730,7 @@ static int agpioc_info_wrap(struct agp_file_private *priv, void __user *arg) | |||
730 | 730 | ||
731 | agp_copy_info(agp_bridge, &kerninfo); | 731 | agp_copy_info(agp_bridge, &kerninfo); |
732 | 732 | ||
733 | memset(&userinfo, 0, sizeof(userinfo)); | ||
733 | userinfo.version.major = kerninfo.version.major; | 734 | userinfo.version.major = kerninfo.version.major; |
734 | userinfo.version.minor = kerninfo.version.minor; | 735 | userinfo.version.minor = kerninfo.version.minor; |
735 | userinfo.bridge_id = kerninfo.device->vendor | | 736 | userinfo.bridge_id = kerninfo.device->vendor | |
diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 6f56d3a4f010..4fdfd6c70bd3 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig | |||
@@ -30,14 +30,7 @@ config COMMON_CLK_WM831X | |||
30 | Supports the clocking subsystem of the WM831x/2x series of | 30 | Supports the clocking subsystem of the WM831x/2x series of |
31 | PMICs from Wolfson Microlectronics. | 31 | PMICs from Wolfson Microlectronics. |
32 | 32 | ||
33 | config COMMON_CLK_VERSATILE | 33 | source "drivers/clk/versatile/Kconfig" |
34 | bool "Clock driver for ARM Reference designs" | ||
35 | depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS || ARM64 | ||
36 | ---help--- | ||
37 | Supports clocking on ARM Reference designs: | ||
38 | - Integrator/AP and Integrator/CP | ||
39 | - RealView PB1176, EB, PB11MP and PBX | ||
40 | - Versatile Express | ||
41 | 34 | ||
42 | config COMMON_CLK_MAX77686 | 35 | config COMMON_CLK_MAX77686 |
43 | tristate "Clock driver for Maxim 77686 MFD" | 36 | tristate "Clock driver for Maxim 77686 MFD" |
diff --git a/drivers/clk/samsung/clk-s3c2410-dclk.c b/drivers/clk/samsung/clk-s3c2410-dclk.c index 8d8dff005c10..0449cc0458ed 100644 --- a/drivers/clk/samsung/clk-s3c2410-dclk.c +++ b/drivers/clk/samsung/clk-s3c2410-dclk.c | |||
@@ -135,26 +135,26 @@ struct s3c24xx_dclk { | |||
135 | #define to_s3c24xx_dclk1(x) \ | 135 | #define to_s3c24xx_dclk1(x) \ |
136 | container_of(x, struct s3c24xx_dclk, dclk1_div_change_nb) | 136 | container_of(x, struct s3c24xx_dclk, dclk1_div_change_nb) |
137 | 137 | ||
138 | PNAME(dclk_s3c2410_p) = { "pclk", "uclk" }; | 138 | static const char *dclk_s3c2410_p[] = { "pclk", "uclk" }; |
139 | PNAME(clkout0_s3c2410_p) = { "mpll", "upll", "fclk", "hclk", "pclk", | 139 | static const char *clkout0_s3c2410_p[] = { "mpll", "upll", "fclk", "hclk", "pclk", |
140 | "gate_dclk0" }; | 140 | "gate_dclk0" }; |
141 | PNAME(clkout1_s3c2410_p) = { "mpll", "upll", "fclk", "hclk", "pclk", | 141 | static const char *clkout1_s3c2410_p[] = { "mpll", "upll", "fclk", "hclk", "pclk", |
142 | "gate_dclk1" }; | 142 | "gate_dclk1" }; |
143 | 143 | ||
144 | PNAME(clkout0_s3c2412_p) = { "mpll", "upll", "rtc_clkout", | 144 | static const char *clkout0_s3c2412_p[] = { "mpll", "upll", "rtc_clkout", |
145 | "hclk", "pclk", "gate_dclk0" }; | 145 | "hclk", "pclk", "gate_dclk0" }; |
146 | PNAME(clkout1_s3c2412_p) = { "xti", "upll", "fclk", "hclk", "pclk", | 146 | static const char *clkout1_s3c2412_p[] = { "xti", "upll", "fclk", "hclk", "pclk", |
147 | "gate_dclk1" }; | 147 | "gate_dclk1" }; |
148 | 148 | ||
149 | PNAME(clkout0_s3c2440_p) = { "xti", "upll", "fclk", "hclk", "pclk", | 149 | static const char *clkout0_s3c2440_p[] = { "xti", "upll", "fclk", "hclk", "pclk", |
150 | "gate_dclk0" }; | 150 | "gate_dclk0" }; |
151 | PNAME(clkout1_s3c2440_p) = { "mpll", "upll", "rtc_clkout", | 151 | static const char *clkout1_s3c2440_p[] = { "mpll", "upll", "rtc_clkout", |
152 | "hclk", "pclk", "gate_dclk1" }; | 152 | "hclk", "pclk", "gate_dclk1" }; |
153 | 153 | ||
154 | PNAME(dclk_s3c2443_p) = { "pclk", "epll" }; | 154 | static const char *dclk_s3c2443_p[] = { "pclk", "epll" }; |
155 | PNAME(clkout0_s3c2443_p) = { "xti", "epll", "armclk", "hclk", "pclk", | 155 | static const char *clkout0_s3c2443_p[] = { "xti", "epll", "armclk", "hclk", "pclk", |
156 | "gate_dclk0" }; | 156 | "gate_dclk0" }; |
157 | PNAME(clkout1_s3c2443_p) = { "dummy", "epll", "rtc_clkout", | 157 | static const char *clkout1_s3c2443_p[] = { "dummy", "epll", "rtc_clkout", |
158 | "hclk", "pclk", "gate_dclk1" }; | 158 | "hclk", "pclk", "gate_dclk1" }; |
159 | 159 | ||
160 | #define DCLKCON_DCLK_DIV_MASK 0xf | 160 | #define DCLKCON_DCLK_DIV_MASK 0xf |
diff --git a/drivers/clk/versatile/Kconfig b/drivers/clk/versatile/Kconfig new file mode 100644 index 000000000000..1530c9352a76 --- /dev/null +++ b/drivers/clk/versatile/Kconfig | |||
@@ -0,0 +1,26 @@ | |||
1 | config COMMON_CLK_VERSATILE | ||
2 | bool "Clock driver for ARM Reference designs" | ||
3 | depends on ARCH_INTEGRATOR || ARCH_REALVIEW || ARCH_VEXPRESS || ARM64 | ||
4 | ---help--- | ||
5 | Supports clocking on ARM Reference designs: | ||
6 | - Integrator/AP and Integrator/CP | ||
7 | - RealView PB1176, EB, PB11MP and PBX | ||
8 | - Versatile Express | ||
9 | |||
10 | config CLK_SP810 | ||
11 | bool "Clock driver for ARM SP810 System Controller" | ||
12 | depends on COMMON_CLK_VERSATILE | ||
13 | default y if ARCH_VEXPRESS | ||
14 | ---help--- | ||
15 | Supports clock muxing (REFCLK/TIMCLK to TIMERCLKEN0-3) capabilities | ||
16 | of the ARM SP810 System Controller cell. | ||
17 | |||
18 | config CLK_VEXPRESS_OSC | ||
19 | bool "Clock driver for Versatile Express OSC clock generators" | ||
20 | depends on COMMON_CLK_VERSATILE | ||
21 | depends on VEXPRESS_CONFIG | ||
22 | default y if ARCH_VEXPRESS | ||
23 | ---help--- | ||
24 | Simple regmap-based driver driving clock generators on Versatile | ||
25 | Express platforms hidden behind its configuration infrastructure, | ||
26 | commonly known as OSCs. | ||
diff --git a/drivers/clk/versatile/Makefile b/drivers/clk/versatile/Makefile index c16ca787170a..fd449f9b006d 100644 --- a/drivers/clk/versatile/Makefile +++ b/drivers/clk/versatile/Makefile | |||
@@ -3,5 +3,6 @@ obj-$(CONFIG_ICST) += clk-icst.o | |||
3 | obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o | 3 | obj-$(CONFIG_ARCH_INTEGRATOR) += clk-integrator.o |
4 | obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o | 4 | obj-$(CONFIG_INTEGRATOR_IMPD1) += clk-impd1.o |
5 | obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o | 5 | obj-$(CONFIG_ARCH_REALVIEW) += clk-realview.o |
6 | obj-$(CONFIG_ARCH_VEXPRESS) += clk-vexpress.o clk-sp810.o | 6 | obj-$(CONFIG_ARCH_VEXPRESS) += clk-vexpress.o |
7 | obj-$(CONFIG_VEXPRESS_CONFIG) += clk-vexpress-osc.o | 7 | obj-$(CONFIG_CLK_SP810) += clk-sp810.o |
8 | obj-$(CONFIG_CLK_VEXPRESS_OSC) += clk-vexpress-osc.o | ||
diff --git a/drivers/clk/versatile/clk-vexpress-osc.c b/drivers/clk/versatile/clk-vexpress-osc.c index 422391242b39..529a59c0fbfa 100644 --- a/drivers/clk/versatile/clk-vexpress-osc.c +++ b/drivers/clk/versatile/clk-vexpress-osc.c | |||
@@ -11,8 +11,6 @@ | |||
11 | * Copyright (C) 2012 ARM Limited | 11 | * Copyright (C) 2012 ARM Limited |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #define pr_fmt(fmt) "vexpress-osc: " fmt | ||
15 | |||
16 | #include <linux/clkdev.h> | 14 | #include <linux/clkdev.h> |
17 | #include <linux/clk-provider.h> | 15 | #include <linux/clk-provider.h> |
18 | #include <linux/err.h> | 16 | #include <linux/err.h> |
@@ -22,7 +20,7 @@ | |||
22 | #include <linux/vexpress.h> | 20 | #include <linux/vexpress.h> |
23 | 21 | ||
24 | struct vexpress_osc { | 22 | struct vexpress_osc { |
25 | struct vexpress_config_func *func; | 23 | struct regmap *reg; |
26 | struct clk_hw hw; | 24 | struct clk_hw hw; |
27 | unsigned long rate_min; | 25 | unsigned long rate_min; |
28 | unsigned long rate_max; | 26 | unsigned long rate_max; |
@@ -36,7 +34,7 @@ static unsigned long vexpress_osc_recalc_rate(struct clk_hw *hw, | |||
36 | struct vexpress_osc *osc = to_vexpress_osc(hw); | 34 | struct vexpress_osc *osc = to_vexpress_osc(hw); |
37 | u32 rate; | 35 | u32 rate; |
38 | 36 | ||
39 | vexpress_config_read(osc->func, 0, &rate); | 37 | regmap_read(osc->reg, 0, &rate); |
40 | 38 | ||
41 | return rate; | 39 | return rate; |
42 | } | 40 | } |
@@ -60,7 +58,7 @@ static int vexpress_osc_set_rate(struct clk_hw *hw, unsigned long rate, | |||
60 | { | 58 | { |
61 | struct vexpress_osc *osc = to_vexpress_osc(hw); | 59 | struct vexpress_osc *osc = to_vexpress_osc(hw); |
62 | 60 | ||
63 | return vexpress_config_write(osc->func, 0, rate); | 61 | return regmap_write(osc->reg, 0, rate); |
64 | } | 62 | } |
65 | 63 | ||
66 | static struct clk_ops vexpress_osc_ops = { | 64 | static struct clk_ops vexpress_osc_ops = { |
@@ -70,58 +68,31 @@ static struct clk_ops vexpress_osc_ops = { | |||
70 | }; | 68 | }; |
71 | 69 | ||
72 | 70 | ||
73 | struct clk * __init vexpress_osc_setup(struct device *dev) | 71 | static int vexpress_osc_probe(struct platform_device *pdev) |
74 | { | ||
75 | struct clk_init_data init; | ||
76 | struct vexpress_osc *osc = kzalloc(sizeof(*osc), GFP_KERNEL); | ||
77 | |||
78 | if (!osc) | ||
79 | return NULL; | ||
80 | |||
81 | osc->func = vexpress_config_func_get_by_dev(dev); | ||
82 | if (!osc->func) { | ||
83 | kfree(osc); | ||
84 | return NULL; | ||
85 | } | ||
86 | |||
87 | init.name = dev_name(dev); | ||
88 | init.ops = &vexpress_osc_ops; | ||
89 | init.flags = CLK_IS_ROOT; | ||
90 | init.num_parents = 0; | ||
91 | osc->hw.init = &init; | ||
92 | |||
93 | return clk_register(NULL, &osc->hw); | ||
94 | } | ||
95 | |||
96 | void __init vexpress_osc_of_setup(struct device_node *node) | ||
97 | { | 72 | { |
73 | struct clk_lookup *cl = pdev->dev.platform_data; /* Non-DT lookup */ | ||
98 | struct clk_init_data init; | 74 | struct clk_init_data init; |
99 | struct vexpress_osc *osc; | 75 | struct vexpress_osc *osc; |
100 | struct clk *clk; | 76 | struct clk *clk; |
101 | u32 range[2]; | 77 | u32 range[2]; |
102 | 78 | ||
103 | vexpress_sysreg_of_early_init(); | 79 | osc = devm_kzalloc(&pdev->dev, sizeof(*osc), GFP_KERNEL); |
104 | |||
105 | osc = kzalloc(sizeof(*osc), GFP_KERNEL); | ||
106 | if (!osc) | 80 | if (!osc) |
107 | return; | 81 | return -ENOMEM; |
108 | 82 | ||
109 | osc->func = vexpress_config_func_get_by_node(node); | 83 | osc->reg = devm_regmap_init_vexpress_config(&pdev->dev); |
110 | if (!osc->func) { | 84 | if (IS_ERR(osc->reg)) |
111 | pr_err("Failed to obtain config func for node '%s'!\n", | 85 | return PTR_ERR(osc->reg); |
112 | node->full_name); | ||
113 | goto error; | ||
114 | } | ||
115 | 86 | ||
116 | if (of_property_read_u32_array(node, "freq-range", range, | 87 | if (of_property_read_u32_array(pdev->dev.of_node, "freq-range", range, |
117 | ARRAY_SIZE(range)) == 0) { | 88 | ARRAY_SIZE(range)) == 0) { |
118 | osc->rate_min = range[0]; | 89 | osc->rate_min = range[0]; |
119 | osc->rate_max = range[1]; | 90 | osc->rate_max = range[1]; |
120 | } | 91 | } |
121 | 92 | ||
122 | of_property_read_string(node, "clock-output-names", &init.name); | 93 | if (of_property_read_string(pdev->dev.of_node, "clock-output-names", |
123 | if (!init.name) | 94 | &init.name) != 0) |
124 | init.name = node->full_name; | 95 | init.name = dev_name(&pdev->dev); |
125 | 96 | ||
126 | init.ops = &vexpress_osc_ops; | 97 | init.ops = &vexpress_osc_ops; |
127 | init.flags = CLK_IS_ROOT; | 98 | init.flags = CLK_IS_ROOT; |
@@ -130,20 +101,37 @@ void __init vexpress_osc_of_setup(struct device_node *node) | |||
130 | osc->hw.init = &init; | 101 | osc->hw.init = &init; |
131 | 102 | ||
132 | clk = clk_register(NULL, &osc->hw); | 103 | clk = clk_register(NULL, &osc->hw); |
133 | if (IS_ERR(clk)) { | 104 | if (IS_ERR(clk)) |
134 | pr_err("Failed to register clock '%s'!\n", init.name); | 105 | return PTR_ERR(clk); |
135 | goto error; | 106 | |
107 | of_clk_add_provider(pdev->dev.of_node, of_clk_src_simple_get, clk); | ||
108 | |||
109 | /* Only happens for non-DT cases */ | ||
110 | if (cl) { | ||
111 | cl->clk = clk; | ||
112 | clkdev_add(cl); | ||
136 | } | 113 | } |
137 | 114 | ||
138 | of_clk_add_provider(node, of_clk_src_simple_get, clk); | 115 | dev_dbg(&pdev->dev, "Registered clock '%s'\n", init.name); |
116 | |||
117 | return 0; | ||
118 | } | ||
139 | 119 | ||
140 | pr_debug("Registered clock '%s'\n", init.name); | 120 | static struct of_device_id vexpress_osc_of_match[] = { |
121 | { .compatible = "arm,vexpress-osc", }, | ||
122 | {} | ||
123 | }; | ||
141 | 124 | ||
142 | return; | 125 | static struct platform_driver vexpress_osc_driver = { |
126 | .driver = { | ||
127 | .name = "vexpress-osc", | ||
128 | .of_match_table = vexpress_osc_of_match, | ||
129 | }, | ||
130 | .probe = vexpress_osc_probe, | ||
131 | }; | ||
143 | 132 | ||
144 | error: | 133 | static int __init vexpress_osc_init(void) |
145 | if (osc->func) | 134 | { |
146 | vexpress_config_func_put(osc->func); | 135 | return platform_driver_register(&vexpress_osc_driver); |
147 | kfree(osc); | ||
148 | } | 136 | } |
149 | CLK_OF_DECLARE(vexpress_soc, "arm,vexpress-osc", vexpress_osc_of_setup); | 137 | core_initcall(vexpress_osc_init); |
diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 96918e1f26a3..43f1acf0d1d2 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig | |||
@@ -191,3 +191,14 @@ config EM_TIMER_STI | |||
191 | 191 | ||
192 | config CLKSRC_QCOM | 192 | config CLKSRC_QCOM |
193 | bool | 193 | bool |
194 | |||
195 | config CLKSRC_VERSATILE | ||
196 | bool "ARM Versatile (Express) reference platforms clock source" | ||
197 | depends on GENERIC_SCHED_CLOCK && !ARCH_USES_GETTIMEOFFSET | ||
198 | select CLKSRC_OF | ||
199 | default y if MFD_VEXPRESS_SYSREG | ||
200 | help | ||
201 | This option enables clock source based on free running | ||
202 | counter available in the "System Registers" block of | ||
203 | ARM Versatile, RealView and Versatile Express reference | ||
204 | platforms. | ||
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 98cb6c51aa87..6f25bdffc176 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
@@ -39,3 +39,4 @@ obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o | |||
39 | obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o | 39 | obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o |
40 | obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o | 40 | obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o |
41 | obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o | 41 | obj-$(CONFIG_ARCH_KEYSTONE) += timer-keystone.o |
42 | obj-$(CONFIG_CLKSRC_VERSATILE) += versatile.o | ||
diff --git a/drivers/clocksource/timer-marco.c b/drivers/clocksource/timer-marco.c index b52e1c078b99..571d10974139 100644 --- a/drivers/clocksource/timer-marco.c +++ b/drivers/clocksource/timer-marco.c | |||
@@ -252,15 +252,13 @@ static void __init sirfsoc_clockevent_init(void) | |||
252 | } | 252 | } |
253 | 253 | ||
254 | /* initialize the kernel jiffy timer source */ | 254 | /* initialize the kernel jiffy timer source */ |
255 | static void __init sirfsoc_marco_timer_init(void) | 255 | static void __init sirfsoc_marco_timer_init(struct device_node *np) |
256 | { | 256 | { |
257 | unsigned long rate; | 257 | unsigned long rate; |
258 | u32 timer_div; | 258 | u32 timer_div; |
259 | struct clk *clk; | 259 | struct clk *clk; |
260 | 260 | ||
261 | /* timer's input clock is io clock */ | 261 | clk = of_clk_get(np, 0); |
262 | clk = clk_get_sys("io", NULL); | ||
263 | |||
264 | BUG_ON(IS_ERR(clk)); | 262 | BUG_ON(IS_ERR(clk)); |
265 | rate = clk_get_rate(clk); | 263 | rate = clk_get_rate(clk); |
266 | 264 | ||
@@ -303,6 +301,6 @@ static void __init sirfsoc_of_timer_init(struct device_node *np) | |||
303 | if (!sirfsoc_timer1_irq.irq) | 301 | if (!sirfsoc_timer1_irq.irq) |
304 | panic("No irq passed for timer1 via DT\n"); | 302 | panic("No irq passed for timer1 via DT\n"); |
305 | 303 | ||
306 | sirfsoc_marco_timer_init(); | 304 | sirfsoc_marco_timer_init(np); |
307 | } | 305 | } |
308 | CLOCKSOURCE_OF_DECLARE(sirfsoc_marco_timer, "sirf,marco-tick", sirfsoc_of_timer_init ); | 306 | CLOCKSOURCE_OF_DECLARE(sirfsoc_marco_timer, "sirf,marco-tick", sirfsoc_of_timer_init ); |
diff --git a/drivers/clocksource/timer-prima2.c b/drivers/clocksource/timer-prima2.c index 1a6b2d6356d6..a722aac7ac02 100644 --- a/drivers/clocksource/timer-prima2.c +++ b/drivers/clocksource/timer-prima2.c | |||
@@ -61,7 +61,8 @@ static irqreturn_t sirfsoc_timer_interrupt(int irq, void *dev_id) | |||
61 | { | 61 | { |
62 | struct clock_event_device *ce = dev_id; | 62 | struct clock_event_device *ce = dev_id; |
63 | 63 | ||
64 | WARN_ON(!(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_STATUS) & BIT(0))); | 64 | WARN_ON(!(readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_STATUS) & |
65 | BIT(0))); | ||
65 | 66 | ||
66 | /* clear timer0 interrupt */ | 67 | /* clear timer0 interrupt */ |
67 | writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS); | 68 | writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS); |
@@ -77,9 +78,11 @@ static cycle_t sirfsoc_timer_read(struct clocksource *cs) | |||
77 | u64 cycles; | 78 | u64 cycles; |
78 | 79 | ||
79 | /* latch the 64-bit timer counter */ | 80 | /* latch the 64-bit timer counter */ |
80 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | 81 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, |
82 | sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | ||
81 | cycles = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_HI); | 83 | cycles = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_HI); |
82 | cycles = (cycles << 32) | readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO); | 84 | cycles = (cycles << 32) | |
85 | readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO); | ||
83 | 86 | ||
84 | return cycles; | 87 | return cycles; |
85 | } | 88 | } |
@@ -89,11 +92,13 @@ static int sirfsoc_timer_set_next_event(unsigned long delta, | |||
89 | { | 92 | { |
90 | unsigned long now, next; | 93 | unsigned long now, next; |
91 | 94 | ||
92 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | 95 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, |
96 | sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | ||
93 | now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO); | 97 | now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO); |
94 | next = now + delta; | 98 | next = now + delta; |
95 | writel_relaxed(next, sirfsoc_timer_base + SIRFSOC_TIMER_MATCH_0); | 99 | writel_relaxed(next, sirfsoc_timer_base + SIRFSOC_TIMER_MATCH_0); |
96 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | 100 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, |
101 | sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | ||
97 | now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO); | 102 | now = readl_relaxed(sirfsoc_timer_base + SIRFSOC_TIMER_LATCHED_LO); |
98 | 103 | ||
99 | return next - now > delta ? -ETIME : 0; | 104 | return next - now > delta ? -ETIME : 0; |
@@ -108,10 +113,12 @@ static void sirfsoc_timer_set_mode(enum clock_event_mode mode, | |||
108 | WARN_ON(1); | 113 | WARN_ON(1); |
109 | break; | 114 | break; |
110 | case CLOCK_EVT_MODE_ONESHOT: | 115 | case CLOCK_EVT_MODE_ONESHOT: |
111 | writel_relaxed(val | BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN); | 116 | writel_relaxed(val | BIT(0), |
117 | sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN); | ||
112 | break; | 118 | break; |
113 | case CLOCK_EVT_MODE_SHUTDOWN: | 119 | case CLOCK_EVT_MODE_SHUTDOWN: |
114 | writel_relaxed(val & ~BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN); | 120 | writel_relaxed(val & ~BIT(0), |
121 | sirfsoc_timer_base + SIRFSOC_TIMER_INT_EN); | ||
115 | break; | 122 | break; |
116 | case CLOCK_EVT_MODE_UNUSED: | 123 | case CLOCK_EVT_MODE_UNUSED: |
117 | case CLOCK_EVT_MODE_RESUME: | 124 | case CLOCK_EVT_MODE_RESUME: |
@@ -123,10 +130,13 @@ static void sirfsoc_clocksource_suspend(struct clocksource *cs) | |||
123 | { | 130 | { |
124 | int i; | 131 | int i; |
125 | 132 | ||
126 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | 133 | writel_relaxed(SIRFSOC_TIMER_LATCH_BIT, |
134 | sirfsoc_timer_base + SIRFSOC_TIMER_LATCH); | ||
127 | 135 | ||
128 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++) | 136 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT; i++) |
129 | sirfsoc_timer_reg_val[i] = readl_relaxed(sirfsoc_timer_base + sirfsoc_timer_reg_list[i]); | 137 | sirfsoc_timer_reg_val[i] = |
138 | readl_relaxed(sirfsoc_timer_base + | ||
139 | sirfsoc_timer_reg_list[i]); | ||
130 | } | 140 | } |
131 | 141 | ||
132 | static void sirfsoc_clocksource_resume(struct clocksource *cs) | 142 | static void sirfsoc_clocksource_resume(struct clocksource *cs) |
@@ -134,10 +144,13 @@ static void sirfsoc_clocksource_resume(struct clocksource *cs) | |||
134 | int i; | 144 | int i; |
135 | 145 | ||
136 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT - 2; i++) | 146 | for (i = 0; i < SIRFSOC_TIMER_REG_CNT - 2; i++) |
137 | writel_relaxed(sirfsoc_timer_reg_val[i], sirfsoc_timer_base + sirfsoc_timer_reg_list[i]); | 147 | writel_relaxed(sirfsoc_timer_reg_val[i], |
148 | sirfsoc_timer_base + sirfsoc_timer_reg_list[i]); | ||
138 | 149 | ||
139 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 2], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); | 150 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 2], |
140 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 1], sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); | 151 | sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); |
152 | writel_relaxed(sirfsoc_timer_reg_val[SIRFSOC_TIMER_REG_CNT - 1], | ||
153 | sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); | ||
141 | } | 154 | } |
142 | 155 | ||
143 | static struct clock_event_device sirfsoc_clockevent = { | 156 | static struct clock_event_device sirfsoc_clockevent = { |
@@ -185,11 +198,8 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np) | |||
185 | unsigned long rate; | 198 | unsigned long rate; |
186 | struct clk *clk; | 199 | struct clk *clk; |
187 | 200 | ||
188 | /* timer's input clock is io clock */ | 201 | clk = of_clk_get(np, 0); |
189 | clk = clk_get_sys("io", NULL); | ||
190 | |||
191 | BUG_ON(IS_ERR(clk)); | 202 | BUG_ON(IS_ERR(clk)); |
192 | |||
193 | rate = clk_get_rate(clk); | 203 | rate = clk_get_rate(clk); |
194 | 204 | ||
195 | BUG_ON(rate < PRIMA2_CLOCK_FREQ); | 205 | BUG_ON(rate < PRIMA2_CLOCK_FREQ); |
@@ -202,7 +212,7 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np) | |||
202 | sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0); | 212 | sirfsoc_timer_irq.irq = irq_of_parse_and_map(np, 0); |
203 | 213 | ||
204 | writel_relaxed(rate / PRIMA2_CLOCK_FREQ / 2 - 1, | 214 | writel_relaxed(rate / PRIMA2_CLOCK_FREQ / 2 - 1, |
205 | sirfsoc_timer_base + SIRFSOC_TIMER_DIV); | 215 | sirfsoc_timer_base + SIRFSOC_TIMER_DIV); |
206 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); | 216 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_LO); |
207 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); | 217 | writel_relaxed(0, sirfsoc_timer_base + SIRFSOC_TIMER_COUNTER_HI); |
208 | writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS); | 218 | writel_relaxed(BIT(0), sirfsoc_timer_base + SIRFSOC_TIMER_STATUS); |
@@ -216,4 +226,5 @@ static void __init sirfsoc_prima2_timer_init(struct device_node *np) | |||
216 | 226 | ||
217 | sirfsoc_clockevent_init(); | 227 | sirfsoc_clockevent_init(); |
218 | } | 228 | } |
219 | CLOCKSOURCE_OF_DECLARE(sirfsoc_prima2_timer, "sirf,prima2-tick", sirfsoc_prima2_timer_init); | 229 | CLOCKSOURCE_OF_DECLARE(sirfsoc_prima2_timer, |
230 | "sirf,prima2-tick", sirfsoc_prima2_timer_init); | ||
diff --git a/drivers/clocksource/versatile.c b/drivers/clocksource/versatile.c new file mode 100644 index 000000000000..e4c50ad2f9d9 --- /dev/null +++ b/drivers/clocksource/versatile.c | |||
@@ -0,0 +1,40 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License version 2 as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * Copyright (C) 2014 ARM Limited | ||
12 | */ | ||
13 | |||
14 | #include <linux/clocksource.h> | ||
15 | #include <linux/io.h> | ||
16 | #include <linux/of_address.h> | ||
17 | #include <linux/sched_clock.h> | ||
18 | |||
19 | #define SYS_24MHZ 0x05c | ||
20 | |||
21 | static void __iomem *versatile_sys_24mhz; | ||
22 | |||
23 | static u32 notrace versatile_sys_24mhz_read(void) | ||
24 | { | ||
25 | return readl(versatile_sys_24mhz); | ||
26 | } | ||
27 | |||
28 | static void __init versatile_sched_clock_init(struct device_node *node) | ||
29 | { | ||
30 | void __iomem *base = of_iomap(node, 0); | ||
31 | |||
32 | if (!base) | ||
33 | return; | ||
34 | |||
35 | versatile_sys_24mhz = base + SYS_24MHZ; | ||
36 | |||
37 | setup_sched_clock(versatile_sys_24mhz_read, 32, 24000000); | ||
38 | } | ||
39 | CLOCKSOURCE_OF_DECLARE(versatile, "arm,vexpress-sysreg", | ||
40 | versatile_sched_clock_init); | ||
diff --git a/drivers/connector/cn_proc.c b/drivers/connector/cn_proc.c index 148d707a1d43..ccdd4c7e748b 100644 --- a/drivers/connector/cn_proc.c +++ b/drivers/connector/cn_proc.c | |||
@@ -369,7 +369,7 @@ static void cn_proc_mcast_ctl(struct cn_msg *msg, | |||
369 | return; | 369 | return; |
370 | 370 | ||
371 | /* Can only change if privileged. */ | 371 | /* Can only change if privileged. */ |
372 | if (!capable(CAP_NET_ADMIN)) { | 372 | if (!__netlink_ns_capable(nsp, &init_user_ns, CAP_NET_ADMIN)) { |
373 | err = EPERM; | 373 | err = EPERM; |
374 | goto out; | 374 | goto out; |
375 | } | 375 | } |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index ec82f6bff122..108e1ec2fa4b 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1954,6 +1954,9 @@ struct drm_i915_cmd_table { | |||
1954 | #define IS_ULT(dev) (IS_HSW_ULT(dev) || IS_BDW_ULT(dev)) | 1954 | #define IS_ULT(dev) (IS_HSW_ULT(dev) || IS_BDW_ULT(dev)) |
1955 | #define IS_HSW_GT3(dev) (IS_HASWELL(dev) && \ | 1955 | #define IS_HSW_GT3(dev) (IS_HASWELL(dev) && \ |
1956 | ((dev)->pdev->device & 0x00F0) == 0x0020) | 1956 | ((dev)->pdev->device & 0x00F0) == 0x0020) |
1957 | /* ULX machines are also considered ULT. */ | ||
1958 | #define IS_HSW_ULX(dev) ((dev)->pdev->device == 0x0A0E || \ | ||
1959 | (dev)->pdev->device == 0x0A1E) | ||
1957 | #define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary) | 1960 | #define IS_PRELIMINARY_HW(intel_info) ((intel_info)->is_preliminary) |
1958 | 1961 | ||
1959 | /* | 1962 | /* |
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 62a5c3627b90..154b0f8bb88d 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -34,25 +34,35 @@ static void gen8_setup_private_ppat(struct drm_i915_private *dev_priv); | |||
34 | 34 | ||
35 | bool intel_enable_ppgtt(struct drm_device *dev, bool full) | 35 | bool intel_enable_ppgtt(struct drm_device *dev, bool full) |
36 | { | 36 | { |
37 | if (i915.enable_ppgtt == 0 || !HAS_ALIASING_PPGTT(dev)) | 37 | if (i915.enable_ppgtt == 0) |
38 | return false; | 38 | return false; |
39 | 39 | ||
40 | if (i915.enable_ppgtt == 1 && full) | 40 | if (i915.enable_ppgtt == 1 && full) |
41 | return false; | 41 | return false; |
42 | 42 | ||
43 | return true; | ||
44 | } | ||
45 | |||
46 | static int sanitize_enable_ppgtt(struct drm_device *dev, int enable_ppgtt) | ||
47 | { | ||
48 | if (enable_ppgtt == 0 || !HAS_ALIASING_PPGTT(dev)) | ||
49 | return 0; | ||
50 | |||
51 | if (enable_ppgtt == 1) | ||
52 | return 1; | ||
53 | |||
54 | if (enable_ppgtt == 2 && HAS_PPGTT(dev)) | ||
55 | return 2; | ||
56 | |||
43 | #ifdef CONFIG_INTEL_IOMMU | 57 | #ifdef CONFIG_INTEL_IOMMU |
44 | /* Disable ppgtt on SNB if VT-d is on. */ | 58 | /* Disable ppgtt on SNB if VT-d is on. */ |
45 | if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) { | 59 | if (INTEL_INFO(dev)->gen == 6 && intel_iommu_gfx_mapped) { |
46 | DRM_INFO("Disabling PPGTT because VT-d is on\n"); | 60 | DRM_INFO("Disabling PPGTT because VT-d is on\n"); |
47 | return false; | 61 | return 0; |
48 | } | 62 | } |
49 | #endif | 63 | #endif |
50 | 64 | ||
51 | /* Full ppgtt disabled by default for now due to issues. */ | 65 | return HAS_ALIASING_PPGTT(dev) ? 1 : 0; |
52 | if (full) | ||
53 | return HAS_PPGTT(dev) && (i915.enable_ppgtt == 2); | ||
54 | else | ||
55 | return HAS_ALIASING_PPGTT(dev); | ||
56 | } | 66 | } |
57 | 67 | ||
58 | #define GEN6_PPGTT_PD_ENTRIES 512 | 68 | #define GEN6_PPGTT_PD_ENTRIES 512 |
@@ -2031,6 +2041,14 @@ int i915_gem_gtt_init(struct drm_device *dev) | |||
2031 | gtt->base.total >> 20); | 2041 | gtt->base.total >> 20); |
2032 | DRM_DEBUG_DRIVER("GMADR size = %ldM\n", gtt->mappable_end >> 20); | 2042 | DRM_DEBUG_DRIVER("GMADR size = %ldM\n", gtt->mappable_end >> 20); |
2033 | DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", gtt->stolen_size >> 20); | 2043 | DRM_DEBUG_DRIVER("GTT stolen size = %zdM\n", gtt->stolen_size >> 20); |
2044 | /* | ||
2045 | * i915.enable_ppgtt is read-only, so do an early pass to validate the | ||
2046 | * user's requested state against the hardware/driver capabilities. We | ||
2047 | * do this now so that we can print out any log messages once rather | ||
2048 | * than every time we check intel_enable_ppgtt(). | ||
2049 | */ | ||
2050 | i915.enable_ppgtt = sanitize_enable_ppgtt(dev, i915.enable_ppgtt); | ||
2051 | DRM_DEBUG_DRIVER("ppgtt mode: %i\n", i915.enable_ppgtt); | ||
2034 | 2052 | ||
2035 | return 0; | 2053 | return 0; |
2036 | } | 2054 | } |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index 69bcc42a0e44..48aa516a1ac0 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -11395,15 +11395,6 @@ void intel_modeset_init(struct drm_device *dev) | |||
11395 | } | 11395 | } |
11396 | } | 11396 | } |
11397 | 11397 | ||
11398 | static void | ||
11399 | intel_connector_break_all_links(struct intel_connector *connector) | ||
11400 | { | ||
11401 | connector->base.dpms = DRM_MODE_DPMS_OFF; | ||
11402 | connector->base.encoder = NULL; | ||
11403 | connector->encoder->connectors_active = false; | ||
11404 | connector->encoder->base.crtc = NULL; | ||
11405 | } | ||
11406 | |||
11407 | static void intel_enable_pipe_a(struct drm_device *dev) | 11398 | static void intel_enable_pipe_a(struct drm_device *dev) |
11408 | { | 11399 | { |
11409 | struct intel_connector *connector; | 11400 | struct intel_connector *connector; |
@@ -11485,8 +11476,17 @@ static void intel_sanitize_crtc(struct intel_crtc *crtc) | |||
11485 | if (connector->encoder->base.crtc != &crtc->base) | 11476 | if (connector->encoder->base.crtc != &crtc->base) |
11486 | continue; | 11477 | continue; |
11487 | 11478 | ||
11488 | intel_connector_break_all_links(connector); | 11479 | connector->base.dpms = DRM_MODE_DPMS_OFF; |
11480 | connector->base.encoder = NULL; | ||
11489 | } | 11481 | } |
11482 | /* multiple connectors may have the same encoder: | ||
11483 | * handle them and break crtc link separately */ | ||
11484 | list_for_each_entry(connector, &dev->mode_config.connector_list, | ||
11485 | base.head) | ||
11486 | if (connector->encoder->base.crtc == &crtc->base) { | ||
11487 | connector->encoder->base.crtc = NULL; | ||
11488 | connector->encoder->connectors_active = false; | ||
11489 | } | ||
11490 | 11490 | ||
11491 | WARN_ON(crtc->active); | 11491 | WARN_ON(crtc->active); |
11492 | crtc->base.enabled = false; | 11492 | crtc->base.enabled = false; |
@@ -11568,6 +11568,8 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) | |||
11568 | drm_get_encoder_name(&encoder->base)); | 11568 | drm_get_encoder_name(&encoder->base)); |
11569 | encoder->disable(encoder); | 11569 | encoder->disable(encoder); |
11570 | } | 11570 | } |
11571 | encoder->base.crtc = NULL; | ||
11572 | encoder->connectors_active = false; | ||
11571 | 11573 | ||
11572 | /* Inconsistent output/port/pipe state happens presumably due to | 11574 | /* Inconsistent output/port/pipe state happens presumably due to |
11573 | * a bug in one of the get_hw_state functions. Or someplace else | 11575 | * a bug in one of the get_hw_state functions. Or someplace else |
@@ -11578,8 +11580,8 @@ static void intel_sanitize_encoder(struct intel_encoder *encoder) | |||
11578 | base.head) { | 11580 | base.head) { |
11579 | if (connector->encoder != encoder) | 11581 | if (connector->encoder != encoder) |
11580 | continue; | 11582 | continue; |
11581 | 11583 | connector->base.dpms = DRM_MODE_DPMS_OFF; | |
11582 | intel_connector_break_all_links(connector); | 11584 | connector->base.encoder = NULL; |
11583 | } | 11585 | } |
11584 | } | 11586 | } |
11585 | /* Enabled encoders without active connectors will be fixed in | 11587 | /* Enabled encoders without active connectors will be fixed in |
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c index dfa85289f28f..5ca68aa9f237 100644 --- a/drivers/gpu/drm/i915/intel_dp.c +++ b/drivers/gpu/drm/i915/intel_dp.c | |||
@@ -105,7 +105,8 @@ intel_dp_max_link_bw(struct intel_dp *intel_dp) | |||
105 | case DP_LINK_BW_2_7: | 105 | case DP_LINK_BW_2_7: |
106 | break; | 106 | break; |
107 | case DP_LINK_BW_5_4: /* 1.2 capable displays may advertise higher bw */ | 107 | case DP_LINK_BW_5_4: /* 1.2 capable displays may advertise higher bw */ |
108 | if ((IS_HASWELL(dev) || INTEL_INFO(dev)->gen >= 8) && | 108 | if (((IS_HASWELL(dev) && !IS_HSW_ULX(dev)) || |
109 | INTEL_INFO(dev)->gen >= 8) && | ||
109 | intel_dp->dpcd[DP_DPCD_REV] >= 0x12) | 110 | intel_dp->dpcd[DP_DPCD_REV] >= 0x12) |
110 | max_link_bw = DP_LINK_BW_5_4; | 111 | max_link_bw = DP_LINK_BW_5_4; |
111 | else | 112 | else |
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c index 1dc37b1ddbfa..b0d0fb2f4d08 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxgm107.c | |||
@@ -863,7 +863,7 @@ gm107_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) | |||
863 | { | 863 | { |
864 | mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); | 864 | mmio_data(0x003000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); |
865 | mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); | 865 | mmio_data(0x008000, 0x0100, NV_MEM_ACCESS_RW | NV_MEM_ACCESS_SYS); |
866 | mmio_data(0x060000, 0x1000, NV_MEM_ACCESS_RW); | 866 | mmio_data(0x200000, 0x1000, NV_MEM_ACCESS_RW); |
867 | 867 | ||
868 | mmio_list(0x40800c, 0x00000000, 8, 1); | 868 | mmio_list(0x40800c, 0x00000000, 8, 1); |
869 | mmio_list(0x408010, 0x80000000, 0, 0); | 869 | mmio_list(0x408010, 0x80000000, 0, 0); |
@@ -877,6 +877,8 @@ gm107_grctx_generate_mods(struct nvc0_graph_priv *priv, struct nvc0_grctx *info) | |||
877 | mmio_list(0x418e24, 0x00000000, 8, 0); | 877 | mmio_list(0x418e24, 0x00000000, 8, 0); |
878 | mmio_list(0x418e28, 0x80000030, 0, 0); | 878 | mmio_list(0x418e28, 0x80000030, 0, 0); |
879 | 879 | ||
880 | mmio_list(0x4064c8, 0x018002c0, 0, 0); | ||
881 | |||
880 | mmio_list(0x418810, 0x80000000, 12, 2); | 882 | mmio_list(0x418810, 0x80000000, 12, 2); |
881 | mmio_list(0x419848, 0x10000000, 12, 2); | 883 | mmio_list(0x419848, 0x10000000, 12, 2); |
882 | mmio_list(0x419c2c, 0x10000000, 12, 2); | 884 | mmio_list(0x419c2c, 0x10000000, 12, 2); |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c index fb0b6b2d1427..222e8ebb669d 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c | |||
@@ -168,7 +168,8 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios) | |||
168 | */ | 168 | */ |
169 | i = 16; | 169 | i = 16; |
170 | do { | 170 | do { |
171 | if ((nv_rd32(bios, 0x300000) & 0xffff) == 0xaa55) | 171 | u32 data = le32_to_cpu(nv_rd32(bios, 0x300000)) & 0xffff; |
172 | if (data == 0xaa55) | ||
172 | break; | 173 | break; |
173 | } while (i--); | 174 | } while (i--); |
174 | 175 | ||
@@ -176,14 +177,15 @@ nouveau_bios_shadow_prom(struct nouveau_bios *bios) | |||
176 | goto out; | 177 | goto out; |
177 | 178 | ||
178 | /* read entire bios image to system memory */ | 179 | /* read entire bios image to system memory */ |
179 | bios->size = ((nv_rd32(bios, 0x300000) >> 16) & 0xff) * 512; | 180 | bios->size = (le32_to_cpu(nv_rd32(bios, 0x300000)) >> 16) & 0xff; |
181 | bios->size = bios->size * 512; | ||
180 | if (!bios->size) | 182 | if (!bios->size) |
181 | goto out; | 183 | goto out; |
182 | 184 | ||
183 | bios->data = kmalloc(bios->size, GFP_KERNEL); | 185 | bios->data = kmalloc(bios->size, GFP_KERNEL); |
184 | if (bios->data) { | 186 | if (bios->data) { |
185 | for (i = 0; i < bios->size; i+=4) | 187 | for (i = 0; i < bios->size; i += 4) |
186 | nv_wo32(bios, i, nv_rd32(bios, 0x300000 + i)); | 188 | ((u32 *)bios->data)[i/4] = nv_rd32(bios, 0x300000 + i); |
187 | } | 189 | } |
188 | 190 | ||
189 | /* check the PCI record header */ | 191 | /* check the PCI record header */ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 83face3f608f..279206997e5c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c | |||
@@ -389,9 +389,6 @@ bool nouveau_acpi_rom_supported(struct pci_dev *pdev) | |||
389 | acpi_status status; | 389 | acpi_status status; |
390 | acpi_handle dhandle, rom_handle; | 390 | acpi_handle dhandle, rom_handle; |
391 | 391 | ||
392 | if (!nouveau_dsm_priv.dsm_detected && !nouveau_dsm_priv.optimus_detected) | ||
393 | return false; | ||
394 | |||
395 | dhandle = ACPI_HANDLE(&pdev->dev); | 392 | dhandle = ACPI_HANDLE(&pdev->dev); |
396 | if (!dhandle) | 393 | if (!dhandle) |
397 | return false; | 394 | return false; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 3ff030dc1ee3..da764a4ed958 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -764,9 +764,9 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, | |||
764 | } | 764 | } |
765 | 765 | ||
766 | ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); | 766 | ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); |
767 | mutex_unlock(&chan->cli->mutex); | ||
768 | if (ret) | 767 | if (ret) |
769 | goto fail_unreserve; | 768 | goto fail_unreserve; |
769 | mutex_unlock(&chan->cli->mutex); | ||
770 | 770 | ||
771 | /* Update the crtc struct and cleanup */ | 771 | /* Update the crtc struct and cleanup */ |
772 | crtc->primary->fb = fb; | 772 | crtc->primary->fb = fb; |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index fb187c78978f..c31c12b4e666 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -1177,27 +1177,43 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
1177 | 1177 | ||
1178 | /* Set NUM_BANKS. */ | 1178 | /* Set NUM_BANKS. */ |
1179 | if (rdev->family >= CHIP_TAHITI) { | 1179 | if (rdev->family >= CHIP_TAHITI) { |
1180 | unsigned tileb, index, num_banks, tile_split_bytes; | 1180 | unsigned index, num_banks; |
1181 | 1181 | ||
1182 | /* Calculate the macrotile mode index. */ | 1182 | if (rdev->family >= CHIP_BONAIRE) { |
1183 | tile_split_bytes = 64 << tile_split; | 1183 | unsigned tileb, tile_split_bytes; |
1184 | tileb = 8 * 8 * target_fb->bits_per_pixel / 8; | ||
1185 | tileb = min(tile_split_bytes, tileb); | ||
1186 | 1184 | ||
1187 | for (index = 0; tileb > 64; index++) { | 1185 | /* Calculate the macrotile mode index. */ |
1188 | tileb >>= 1; | 1186 | tile_split_bytes = 64 << tile_split; |
1189 | } | 1187 | tileb = 8 * 8 * target_fb->bits_per_pixel / 8; |
1188 | tileb = min(tile_split_bytes, tileb); | ||
1190 | 1189 | ||
1191 | if (index >= 16) { | 1190 | for (index = 0; tileb > 64; index++) |
1192 | DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n", | 1191 | tileb >>= 1; |
1193 | target_fb->bits_per_pixel, tile_split); | 1192 | |
1194 | return -EINVAL; | 1193 | if (index >= 16) { |
1195 | } | 1194 | DRM_ERROR("Wrong screen bpp (%u) or tile split (%u)\n", |
1195 | target_fb->bits_per_pixel, tile_split); | ||
1196 | return -EINVAL; | ||
1197 | } | ||
1196 | 1198 | ||
1197 | if (rdev->family >= CHIP_BONAIRE) | ||
1198 | num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3; | 1199 | num_banks = (rdev->config.cik.macrotile_mode_array[index] >> 6) & 0x3; |
1199 | else | 1200 | } else { |
1201 | switch (target_fb->bits_per_pixel) { | ||
1202 | case 8: | ||
1203 | index = 10; | ||
1204 | break; | ||
1205 | case 16: | ||
1206 | index = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP; | ||
1207 | break; | ||
1208 | default: | ||
1209 | case 32: | ||
1210 | index = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP; | ||
1211 | break; | ||
1212 | } | ||
1213 | |||
1200 | num_banks = (rdev->config.si.tile_mode_array[index] >> 20) & 0x3; | 1214 | num_banks = (rdev->config.si.tile_mode_array[index] >> 20) & 0x3; |
1215 | } | ||
1216 | |||
1201 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks); | 1217 | fb_format |= EVERGREEN_GRPH_NUM_BANKS(num_banks); |
1202 | } else { | 1218 | } else { |
1203 | /* NI and older. */ | 1219 | /* NI and older. */ |
@@ -1720,8 +1736,9 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1720 | } | 1736 | } |
1721 | /* otherwise, pick one of the plls */ | 1737 | /* otherwise, pick one of the plls */ |
1722 | if ((rdev->family == CHIP_KAVERI) || | 1738 | if ((rdev->family == CHIP_KAVERI) || |
1723 | (rdev->family == CHIP_KABINI)) { | 1739 | (rdev->family == CHIP_KABINI) || |
1724 | /* KB/KV has PPLL1 and PPLL2 */ | 1740 | (rdev->family == CHIP_MULLINS)) { |
1741 | /* KB/KV/ML has PPLL1 and PPLL2 */ | ||
1725 | pll_in_use = radeon_get_pll_use_mask(crtc); | 1742 | pll_in_use = radeon_get_pll_use_mask(crtc); |
1726 | if (!(pll_in_use & (1 << ATOM_PPLL2))) | 1743 | if (!(pll_in_use & (1 << ATOM_PPLL2))) |
1727 | return ATOM_PPLL2; | 1744 | return ATOM_PPLL2; |
@@ -1885,6 +1902,9 @@ int atombios_crtc_mode_set(struct drm_crtc *crtc, | |||
1885 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) | 1902 | (ATOM_DEVICE_TV_SUPPORT | ATOM_DEVICE_CV_SUPPORT)) |
1886 | is_tvcv = true; | 1903 | is_tvcv = true; |
1887 | 1904 | ||
1905 | if (!radeon_crtc->adjusted_clock) | ||
1906 | return -EINVAL; | ||
1907 | |||
1888 | atombios_crtc_set_pll(crtc, adjusted_mode); | 1908 | atombios_crtc_set_pll(crtc, adjusted_mode); |
1889 | 1909 | ||
1890 | if (ASIC_IS_DCE4(rdev)) | 1910 | if (ASIC_IS_DCE4(rdev)) |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index bc0119fb6c12..54e4f52549af 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -366,11 +366,11 @@ static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector) | |||
366 | if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) | 366 | if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT)) |
367 | return; | 367 | return; |
368 | 368 | ||
369 | if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3)) | 369 | if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3) == 3) |
370 | DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", | 370 | DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n", |
371 | buf[0], buf[1], buf[2]); | 371 | buf[0], buf[1], buf[2]); |
372 | 372 | ||
373 | if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3)) | 373 | if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3) == 3) |
374 | DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", | 374 | DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n", |
375 | buf[0], buf[1], buf[2]); | 375 | buf[0], buf[1], buf[2]); |
376 | } | 376 | } |
@@ -419,21 +419,23 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder, | |||
419 | 419 | ||
420 | if (dp_bridge != ENCODER_OBJECT_ID_NONE) { | 420 | if (dp_bridge != ENCODER_OBJECT_ID_NONE) { |
421 | /* DP bridge chips */ | 421 | /* DP bridge chips */ |
422 | drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, | 422 | if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, |
423 | DP_EDP_CONFIGURATION_CAP, &tmp); | 423 | DP_EDP_CONFIGURATION_CAP, &tmp) == 1) { |
424 | if (tmp & 1) | 424 | if (tmp & 1) |
425 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 425 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
426 | else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || | 426 | else if ((dp_bridge == ENCODER_OBJECT_ID_NUTMEG) || |
427 | (dp_bridge == ENCODER_OBJECT_ID_TRAVIS)) | 427 | (dp_bridge == ENCODER_OBJECT_ID_TRAVIS)) |
428 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; | 428 | panel_mode = DP_PANEL_MODE_INTERNAL_DP1_MODE; |
429 | else | 429 | else |
430 | panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; | 430 | panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE; |
431 | } | ||
431 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { | 432 | } else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) { |
432 | /* eDP */ | 433 | /* eDP */ |
433 | drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, | 434 | if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, |
434 | DP_EDP_CONFIGURATION_CAP, &tmp); | 435 | DP_EDP_CONFIGURATION_CAP, &tmp) == 1) { |
435 | if (tmp & 1) | 436 | if (tmp & 1) |
436 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; | 437 | panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE; |
438 | } | ||
437 | } | 439 | } |
438 | 440 | ||
439 | return panel_mode; | 441 | return panel_mode; |
@@ -809,11 +811,15 @@ void radeon_dp_link_train(struct drm_encoder *encoder, | |||
809 | else | 811 | else |
810 | dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A; | 812 | dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A; |
811 | 813 | ||
812 | drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp); | 814 | if (drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp) |
813 | if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED)) | 815 | == 1) { |
814 | dp_info.tp3_supported = true; | 816 | if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED)) |
815 | else | 817 | dp_info.tp3_supported = true; |
818 | else | ||
819 | dp_info.tp3_supported = false; | ||
820 | } else { | ||
816 | dp_info.tp3_supported = false; | 821 | dp_info.tp3_supported = false; |
822 | } | ||
817 | 823 | ||
818 | memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE); | 824 | memcpy(dp_info.dpcd, dig_connector->dpcd, DP_RECEIVER_CAP_SIZE); |
819 | dp_info.rdev = rdev; | 825 | dp_info.rdev = rdev; |
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c index 199eb194716f..d2fd98968085 100644 --- a/drivers/gpu/drm/radeon/cik.c +++ b/drivers/gpu/drm/radeon/cik.c | |||
@@ -63,6 +63,12 @@ MODULE_FIRMWARE("radeon/KABINI_ce.bin"); | |||
63 | MODULE_FIRMWARE("radeon/KABINI_mec.bin"); | 63 | MODULE_FIRMWARE("radeon/KABINI_mec.bin"); |
64 | MODULE_FIRMWARE("radeon/KABINI_rlc.bin"); | 64 | MODULE_FIRMWARE("radeon/KABINI_rlc.bin"); |
65 | MODULE_FIRMWARE("radeon/KABINI_sdma.bin"); | 65 | MODULE_FIRMWARE("radeon/KABINI_sdma.bin"); |
66 | MODULE_FIRMWARE("radeon/MULLINS_pfp.bin"); | ||
67 | MODULE_FIRMWARE("radeon/MULLINS_me.bin"); | ||
68 | MODULE_FIRMWARE("radeon/MULLINS_ce.bin"); | ||
69 | MODULE_FIRMWARE("radeon/MULLINS_mec.bin"); | ||
70 | MODULE_FIRMWARE("radeon/MULLINS_rlc.bin"); | ||
71 | MODULE_FIRMWARE("radeon/MULLINS_sdma.bin"); | ||
66 | 72 | ||
67 | extern int r600_ih_ring_alloc(struct radeon_device *rdev); | 73 | extern int r600_ih_ring_alloc(struct radeon_device *rdev); |
68 | extern void r600_ih_ring_fini(struct radeon_device *rdev); | 74 | extern void r600_ih_ring_fini(struct radeon_device *rdev); |
@@ -1473,6 +1479,43 @@ static const u32 hawaii_mgcg_cgcg_init[] = | |||
1473 | 0xd80c, 0xff000ff0, 0x00000100 | 1479 | 0xd80c, 0xff000ff0, 0x00000100 |
1474 | }; | 1480 | }; |
1475 | 1481 | ||
1482 | static const u32 godavari_golden_registers[] = | ||
1483 | { | ||
1484 | 0x55e4, 0xff607fff, 0xfc000100, | ||
1485 | 0x6ed8, 0x00010101, 0x00010000, | ||
1486 | 0x9830, 0xffffffff, 0x00000000, | ||
1487 | 0x98302, 0xf00fffff, 0x00000400, | ||
1488 | 0x6130, 0xffffffff, 0x00010000, | ||
1489 | 0x5bb0, 0x000000f0, 0x00000070, | ||
1490 | 0x5bc0, 0xf0311fff, 0x80300000, | ||
1491 | 0x98f8, 0x73773777, 0x12010001, | ||
1492 | 0x98fc, 0xffffffff, 0x00000010, | ||
1493 | 0x8030, 0x00001f0f, 0x0000100a, | ||
1494 | 0x2f48, 0x73773777, 0x12010001, | ||
1495 | 0x2408, 0x000fffff, 0x000c007f, | ||
1496 | 0x8a14, 0xf000003f, 0x00000007, | ||
1497 | 0x8b24, 0xffffffff, 0x00ff0fff, | ||
1498 | 0x30a04, 0x0000ff0f, 0x00000000, | ||
1499 | 0x28a4c, 0x07ffffff, 0x06000000, | ||
1500 | 0x4d8, 0x00000fff, 0x00000100, | ||
1501 | 0xd014, 0x00010000, 0x00810001, | ||
1502 | 0xd814, 0x00010000, 0x00810001, | ||
1503 | 0x3e78, 0x00000001, 0x00000002, | ||
1504 | 0xc768, 0x00000008, 0x00000008, | ||
1505 | 0xc770, 0x00000f00, 0x00000800, | ||
1506 | 0xc774, 0x00000f00, 0x00000800, | ||
1507 | 0xc798, 0x00ffffff, 0x00ff7fbf, | ||
1508 | 0xc79c, 0x00ffffff, 0x00ff7faf, | ||
1509 | 0x8c00, 0x000000ff, 0x00000001, | ||
1510 | 0x214f8, 0x01ff01ff, 0x00000002, | ||
1511 | 0x21498, 0x007ff800, 0x00200000, | ||
1512 | 0x2015c, 0xffffffff, 0x00000f40, | ||
1513 | 0x88c4, 0x001f3ae3, 0x00000082, | ||
1514 | 0x88d4, 0x0000001f, 0x00000010, | ||
1515 | 0x30934, 0xffffffff, 0x00000000 | ||
1516 | }; | ||
1517 | |||
1518 | |||
1476 | static void cik_init_golden_registers(struct radeon_device *rdev) | 1519 | static void cik_init_golden_registers(struct radeon_device *rdev) |
1477 | { | 1520 | { |
1478 | switch (rdev->family) { | 1521 | switch (rdev->family) { |
@@ -1504,6 +1547,20 @@ static void cik_init_golden_registers(struct radeon_device *rdev) | |||
1504 | kalindi_golden_spm_registers, | 1547 | kalindi_golden_spm_registers, |
1505 | (const u32)ARRAY_SIZE(kalindi_golden_spm_registers)); | 1548 | (const u32)ARRAY_SIZE(kalindi_golden_spm_registers)); |
1506 | break; | 1549 | break; |
1550 | case CHIP_MULLINS: | ||
1551 | radeon_program_register_sequence(rdev, | ||
1552 | kalindi_mgcg_cgcg_init, | ||
1553 | (const u32)ARRAY_SIZE(kalindi_mgcg_cgcg_init)); | ||
1554 | radeon_program_register_sequence(rdev, | ||
1555 | godavari_golden_registers, | ||
1556 | (const u32)ARRAY_SIZE(godavari_golden_registers)); | ||
1557 | radeon_program_register_sequence(rdev, | ||
1558 | kalindi_golden_common_registers, | ||
1559 | (const u32)ARRAY_SIZE(kalindi_golden_common_registers)); | ||
1560 | radeon_program_register_sequence(rdev, | ||
1561 | kalindi_golden_spm_registers, | ||
1562 | (const u32)ARRAY_SIZE(kalindi_golden_spm_registers)); | ||
1563 | break; | ||
1507 | case CHIP_KAVERI: | 1564 | case CHIP_KAVERI: |
1508 | radeon_program_register_sequence(rdev, | 1565 | radeon_program_register_sequence(rdev, |
1509 | spectre_mgcg_cgcg_init, | 1566 | spectre_mgcg_cgcg_init, |
@@ -1834,6 +1891,15 @@ static int cik_init_microcode(struct radeon_device *rdev) | |||
1834 | rlc_req_size = KB_RLC_UCODE_SIZE * 4; | 1891 | rlc_req_size = KB_RLC_UCODE_SIZE * 4; |
1835 | sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; | 1892 | sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; |
1836 | break; | 1893 | break; |
1894 | case CHIP_MULLINS: | ||
1895 | chip_name = "MULLINS"; | ||
1896 | pfp_req_size = CIK_PFP_UCODE_SIZE * 4; | ||
1897 | me_req_size = CIK_ME_UCODE_SIZE * 4; | ||
1898 | ce_req_size = CIK_CE_UCODE_SIZE * 4; | ||
1899 | mec_req_size = CIK_MEC_UCODE_SIZE * 4; | ||
1900 | rlc_req_size = ML_RLC_UCODE_SIZE * 4; | ||
1901 | sdma_req_size = CIK_SDMA_UCODE_SIZE * 4; | ||
1902 | break; | ||
1837 | default: BUG(); | 1903 | default: BUG(); |
1838 | } | 1904 | } |
1839 | 1905 | ||
@@ -3272,6 +3338,7 @@ static void cik_gpu_init(struct radeon_device *rdev) | |||
3272 | gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN; | 3338 | gb_addr_config = BONAIRE_GB_ADDR_CONFIG_GOLDEN; |
3273 | break; | 3339 | break; |
3274 | case CHIP_KABINI: | 3340 | case CHIP_KABINI: |
3341 | case CHIP_MULLINS: | ||
3275 | default: | 3342 | default: |
3276 | rdev->config.cik.max_shader_engines = 1; | 3343 | rdev->config.cik.max_shader_engines = 1; |
3277 | rdev->config.cik.max_tile_pipes = 2; | 3344 | rdev->config.cik.max_tile_pipes = 2; |
@@ -3702,6 +3769,7 @@ int cik_copy_cpdma(struct radeon_device *rdev, | |||
3702 | r = radeon_fence_emit(rdev, fence, ring->idx); | 3769 | r = radeon_fence_emit(rdev, fence, ring->idx); |
3703 | if (r) { | 3770 | if (r) { |
3704 | radeon_ring_unlock_undo(rdev, ring); | 3771 | radeon_ring_unlock_undo(rdev, ring); |
3772 | radeon_semaphore_free(rdev, &sem, NULL); | ||
3705 | return r; | 3773 | return r; |
3706 | } | 3774 | } |
3707 | 3775 | ||
@@ -5800,6 +5868,9 @@ static int cik_rlc_resume(struct radeon_device *rdev) | |||
5800 | case CHIP_KABINI: | 5868 | case CHIP_KABINI: |
5801 | size = KB_RLC_UCODE_SIZE; | 5869 | size = KB_RLC_UCODE_SIZE; |
5802 | break; | 5870 | break; |
5871 | case CHIP_MULLINS: | ||
5872 | size = ML_RLC_UCODE_SIZE; | ||
5873 | break; | ||
5803 | } | 5874 | } |
5804 | 5875 | ||
5805 | cik_rlc_stop(rdev); | 5876 | cik_rlc_stop(rdev); |
@@ -6548,6 +6619,7 @@ void cik_get_csb_buffer(struct radeon_device *rdev, volatile u32 *buffer) | |||
6548 | buffer[count++] = cpu_to_le32(0x00000000); | 6619 | buffer[count++] = cpu_to_le32(0x00000000); |
6549 | break; | 6620 | break; |
6550 | case CHIP_KABINI: | 6621 | case CHIP_KABINI: |
6622 | case CHIP_MULLINS: | ||
6551 | buffer[count++] = cpu_to_le32(0x00000000); /* XXX */ | 6623 | buffer[count++] = cpu_to_le32(0x00000000); /* XXX */ |
6552 | buffer[count++] = cpu_to_le32(0x00000000); | 6624 | buffer[count++] = cpu_to_le32(0x00000000); |
6553 | break; | 6625 | break; |
@@ -6693,6 +6765,19 @@ static void cik_disable_interrupt_state(struct radeon_device *rdev) | |||
6693 | WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | 6765 | WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); |
6694 | WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | 6766 | WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); |
6695 | } | 6767 | } |
6768 | /* pflip */ | ||
6769 | if (rdev->num_crtc >= 2) { | ||
6770 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, 0); | ||
6771 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, 0); | ||
6772 | } | ||
6773 | if (rdev->num_crtc >= 4) { | ||
6774 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, 0); | ||
6775 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, 0); | ||
6776 | } | ||
6777 | if (rdev->num_crtc >= 6) { | ||
6778 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, 0); | ||
6779 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, 0); | ||
6780 | } | ||
6696 | 6781 | ||
6697 | /* dac hotplug */ | 6782 | /* dac hotplug */ |
6698 | WREG32(DAC_AUTODETECT_INT_CONTROL, 0); | 6783 | WREG32(DAC_AUTODETECT_INT_CONTROL, 0); |
@@ -7049,6 +7134,25 @@ int cik_irq_set(struct radeon_device *rdev) | |||
7049 | WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); | 7134 | WREG32(LB_INTERRUPT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); |
7050 | } | 7135 | } |
7051 | 7136 | ||
7137 | if (rdev->num_crtc >= 2) { | ||
7138 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, | ||
7139 | GRPH_PFLIP_INT_MASK); | ||
7140 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, | ||
7141 | GRPH_PFLIP_INT_MASK); | ||
7142 | } | ||
7143 | if (rdev->num_crtc >= 4) { | ||
7144 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, | ||
7145 | GRPH_PFLIP_INT_MASK); | ||
7146 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, | ||
7147 | GRPH_PFLIP_INT_MASK); | ||
7148 | } | ||
7149 | if (rdev->num_crtc >= 6) { | ||
7150 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, | ||
7151 | GRPH_PFLIP_INT_MASK); | ||
7152 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, | ||
7153 | GRPH_PFLIP_INT_MASK); | ||
7154 | } | ||
7155 | |||
7052 | WREG32(DC_HPD1_INT_CONTROL, hpd1); | 7156 | WREG32(DC_HPD1_INT_CONTROL, hpd1); |
7053 | WREG32(DC_HPD2_INT_CONTROL, hpd2); | 7157 | WREG32(DC_HPD2_INT_CONTROL, hpd2); |
7054 | WREG32(DC_HPD3_INT_CONTROL, hpd3); | 7158 | WREG32(DC_HPD3_INT_CONTROL, hpd3); |
@@ -7085,6 +7189,29 @@ static inline void cik_irq_ack(struct radeon_device *rdev) | |||
7085 | rdev->irq.stat_regs.cik.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); | 7189 | rdev->irq.stat_regs.cik.disp_int_cont5 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE5); |
7086 | rdev->irq.stat_regs.cik.disp_int_cont6 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE6); | 7190 | rdev->irq.stat_regs.cik.disp_int_cont6 = RREG32(DISP_INTERRUPT_STATUS_CONTINUE6); |
7087 | 7191 | ||
7192 | rdev->irq.stat_regs.cik.d1grph_int = RREG32(GRPH_INT_STATUS + | ||
7193 | EVERGREEN_CRTC0_REGISTER_OFFSET); | ||
7194 | rdev->irq.stat_regs.cik.d2grph_int = RREG32(GRPH_INT_STATUS + | ||
7195 | EVERGREEN_CRTC1_REGISTER_OFFSET); | ||
7196 | if (rdev->num_crtc >= 4) { | ||
7197 | rdev->irq.stat_regs.cik.d3grph_int = RREG32(GRPH_INT_STATUS + | ||
7198 | EVERGREEN_CRTC2_REGISTER_OFFSET); | ||
7199 | rdev->irq.stat_regs.cik.d4grph_int = RREG32(GRPH_INT_STATUS + | ||
7200 | EVERGREEN_CRTC3_REGISTER_OFFSET); | ||
7201 | } | ||
7202 | if (rdev->num_crtc >= 6) { | ||
7203 | rdev->irq.stat_regs.cik.d5grph_int = RREG32(GRPH_INT_STATUS + | ||
7204 | EVERGREEN_CRTC4_REGISTER_OFFSET); | ||
7205 | rdev->irq.stat_regs.cik.d6grph_int = RREG32(GRPH_INT_STATUS + | ||
7206 | EVERGREEN_CRTC5_REGISTER_OFFSET); | ||
7207 | } | ||
7208 | |||
7209 | if (rdev->irq.stat_regs.cik.d1grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
7210 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, | ||
7211 | GRPH_PFLIP_INT_CLEAR); | ||
7212 | if (rdev->irq.stat_regs.cik.d2grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
7213 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, | ||
7214 | GRPH_PFLIP_INT_CLEAR); | ||
7088 | if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT) | 7215 | if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VBLANK_INTERRUPT) |
7089 | WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK); | 7216 | WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC0_REGISTER_OFFSET, VBLANK_ACK); |
7090 | if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT) | 7217 | if (rdev->irq.stat_regs.cik.disp_int & LB_D1_VLINE_INTERRUPT) |
@@ -7095,6 +7222,12 @@ static inline void cik_irq_ack(struct radeon_device *rdev) | |||
7095 | WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK); | 7222 | WREG32(LB_VLINE_STATUS + EVERGREEN_CRTC1_REGISTER_OFFSET, VLINE_ACK); |
7096 | 7223 | ||
7097 | if (rdev->num_crtc >= 4) { | 7224 | if (rdev->num_crtc >= 4) { |
7225 | if (rdev->irq.stat_regs.cik.d3grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
7226 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, | ||
7227 | GRPH_PFLIP_INT_CLEAR); | ||
7228 | if (rdev->irq.stat_regs.cik.d4grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
7229 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC3_REGISTER_OFFSET, | ||
7230 | GRPH_PFLIP_INT_CLEAR); | ||
7098 | if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) | 7231 | if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VBLANK_INTERRUPT) |
7099 | WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); | 7232 | WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC2_REGISTER_OFFSET, VBLANK_ACK); |
7100 | if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) | 7233 | if (rdev->irq.stat_regs.cik.disp_int_cont2 & LB_D3_VLINE_INTERRUPT) |
@@ -7106,6 +7239,12 @@ static inline void cik_irq_ack(struct radeon_device *rdev) | |||
7106 | } | 7239 | } |
7107 | 7240 | ||
7108 | if (rdev->num_crtc >= 6) { | 7241 | if (rdev->num_crtc >= 6) { |
7242 | if (rdev->irq.stat_regs.cik.d5grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
7243 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, | ||
7244 | GRPH_PFLIP_INT_CLEAR); | ||
7245 | if (rdev->irq.stat_regs.cik.d6grph_int & GRPH_PFLIP_INT_OCCURRED) | ||
7246 | WREG32(GRPH_INT_STATUS + EVERGREEN_CRTC5_REGISTER_OFFSET, | ||
7247 | GRPH_PFLIP_INT_CLEAR); | ||
7109 | if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) | 7248 | if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VBLANK_INTERRUPT) |
7110 | WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); | 7249 | WREG32(LB_VBLANK_STATUS + EVERGREEN_CRTC4_REGISTER_OFFSET, VBLANK_ACK); |
7111 | if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) | 7250 | if (rdev->irq.stat_regs.cik.disp_int_cont4 & LB_D5_VLINE_INTERRUPT) |
@@ -7457,6 +7596,15 @@ restart_ih: | |||
7457 | break; | 7596 | break; |
7458 | } | 7597 | } |
7459 | break; | 7598 | break; |
7599 | case 8: /* D1 page flip */ | ||
7600 | case 10: /* D2 page flip */ | ||
7601 | case 12: /* D3 page flip */ | ||
7602 | case 14: /* D4 page flip */ | ||
7603 | case 16: /* D5 page flip */ | ||
7604 | case 18: /* D6 page flip */ | ||
7605 | DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1); | ||
7606 | radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1); | ||
7607 | break; | ||
7460 | case 42: /* HPD hotplug */ | 7608 | case 42: /* HPD hotplug */ |
7461 | switch (src_data) { | 7609 | switch (src_data) { |
7462 | case 0: | 7610 | case 0: |
diff --git a/drivers/gpu/drm/radeon/cik_sdma.c b/drivers/gpu/drm/radeon/cik_sdma.c index f7e46cf682af..72e464c79a88 100644 --- a/drivers/gpu/drm/radeon/cik_sdma.c +++ b/drivers/gpu/drm/radeon/cik_sdma.c | |||
@@ -562,6 +562,7 @@ int cik_copy_dma(struct radeon_device *rdev, | |||
562 | r = radeon_fence_emit(rdev, fence, ring->idx); | 562 | r = radeon_fence_emit(rdev, fence, ring->idx); |
563 | if (r) { | 563 | if (r) { |
564 | radeon_ring_unlock_undo(rdev, ring); | 564 | radeon_ring_unlock_undo(rdev, ring); |
565 | radeon_semaphore_free(rdev, &sem, NULL); | ||
565 | return r; | 566 | return r; |
566 | } | 567 | } |
567 | 568 | ||
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index 213873270d5f..dd7926394a8f 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h | |||
@@ -888,6 +888,15 @@ | |||
888 | # define DC_HPD6_RX_INTERRUPT (1 << 18) | 888 | # define DC_HPD6_RX_INTERRUPT (1 << 18) |
889 | #define DISP_INTERRUPT_STATUS_CONTINUE6 0x6780 | 889 | #define DISP_INTERRUPT_STATUS_CONTINUE6 0x6780 |
890 | 890 | ||
891 | /* 0x6858, 0x7458, 0x10058, 0x10c58, 0x11858, 0x12458 */ | ||
892 | #define GRPH_INT_STATUS 0x6858 | ||
893 | # define GRPH_PFLIP_INT_OCCURRED (1 << 0) | ||
894 | # define GRPH_PFLIP_INT_CLEAR (1 << 8) | ||
895 | /* 0x685c, 0x745c, 0x1005c, 0x10c5c, 0x1185c, 0x1245c */ | ||
896 | #define GRPH_INT_CONTROL 0x685c | ||
897 | # define GRPH_PFLIP_INT_MASK (1 << 0) | ||
898 | # define GRPH_PFLIP_INT_TYPE (1 << 8) | ||
899 | |||
891 | #define DAC_AUTODETECT_INT_CONTROL 0x67c8 | 900 | #define DAC_AUTODETECT_INT_CONTROL 0x67c8 |
892 | 901 | ||
893 | #define DC_HPD1_INT_STATUS 0x601c | 902 | #define DC_HPD1_INT_STATUS 0x601c |
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index b406546440da..0f7a51a3694f 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -4371,7 +4371,6 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
4371 | u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; | 4371 | u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; |
4372 | u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; | 4372 | u32 hpd1, hpd2, hpd3, hpd4, hpd5, hpd6; |
4373 | u32 grbm_int_cntl = 0; | 4373 | u32 grbm_int_cntl = 0; |
4374 | u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; | ||
4375 | u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0; | 4374 | u32 afmt1 = 0, afmt2 = 0, afmt3 = 0, afmt4 = 0, afmt5 = 0, afmt6 = 0; |
4376 | u32 dma_cntl, dma_cntl1 = 0; | 4375 | u32 dma_cntl, dma_cntl1 = 0; |
4377 | u32 thermal_int = 0; | 4376 | u32 thermal_int = 0; |
@@ -4554,15 +4553,21 @@ int evergreen_irq_set(struct radeon_device *rdev) | |||
4554 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); | 4553 | WREG32(INT_MASK + EVERGREEN_CRTC5_REGISTER_OFFSET, crtc6); |
4555 | } | 4554 | } |
4556 | 4555 | ||
4557 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); | 4556 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, |
4558 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); | 4557 | GRPH_PFLIP_INT_MASK); |
4558 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, | ||
4559 | GRPH_PFLIP_INT_MASK); | ||
4559 | if (rdev->num_crtc >= 4) { | 4560 | if (rdev->num_crtc >= 4) { |
4560 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); | 4561 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, |
4561 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); | 4562 | GRPH_PFLIP_INT_MASK); |
4563 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, | ||
4564 | GRPH_PFLIP_INT_MASK); | ||
4562 | } | 4565 | } |
4563 | if (rdev->num_crtc >= 6) { | 4566 | if (rdev->num_crtc >= 6) { |
4564 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5); | 4567 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, |
4565 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); | 4568 | GRPH_PFLIP_INT_MASK); |
4569 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, | ||
4570 | GRPH_PFLIP_INT_MASK); | ||
4566 | } | 4571 | } |
4567 | 4572 | ||
4568 | WREG32(DC_HPD1_INT_CONTROL, hpd1); | 4573 | WREG32(DC_HPD1_INT_CONTROL, hpd1); |
@@ -4951,6 +4956,15 @@ restart_ih: | |||
4951 | break; | 4956 | break; |
4952 | } | 4957 | } |
4953 | break; | 4958 | break; |
4959 | case 8: /* D1 page flip */ | ||
4960 | case 10: /* D2 page flip */ | ||
4961 | case 12: /* D3 page flip */ | ||
4962 | case 14: /* D4 page flip */ | ||
4963 | case 16: /* D5 page flip */ | ||
4964 | case 18: /* D6 page flip */ | ||
4965 | DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1); | ||
4966 | radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1); | ||
4967 | break; | ||
4954 | case 42: /* HPD hotplug */ | 4968 | case 42: /* HPD hotplug */ |
4955 | switch (src_data) { | 4969 | switch (src_data) { |
4956 | case 0: | 4970 | case 0: |
diff --git a/drivers/gpu/drm/radeon/evergreen_dma.c b/drivers/gpu/drm/radeon/evergreen_dma.c index 287fe966d7de..478caefe0fef 100644 --- a/drivers/gpu/drm/radeon/evergreen_dma.c +++ b/drivers/gpu/drm/radeon/evergreen_dma.c | |||
@@ -151,6 +151,7 @@ int evergreen_copy_dma(struct radeon_device *rdev, | |||
151 | r = radeon_fence_emit(rdev, fence, ring->idx); | 151 | r = radeon_fence_emit(rdev, fence, ring->idx); |
152 | if (r) { | 152 | if (r) { |
153 | radeon_ring_unlock_undo(rdev, ring); | 153 | radeon_ring_unlock_undo(rdev, ring); |
154 | radeon_semaphore_free(rdev, &sem, NULL); | ||
154 | return r; | 155 | return r; |
155 | } | 156 | } |
156 | 157 | ||
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index 16ec9d56a234..3f6e817d97ee 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c | |||
@@ -546,6 +546,52 @@ static int kv_set_divider_value(struct radeon_device *rdev, | |||
546 | return 0; | 546 | return 0; |
547 | } | 547 | } |
548 | 548 | ||
549 | static u32 kv_convert_vid2_to_vid7(struct radeon_device *rdev, | ||
550 | struct sumo_vid_mapping_table *vid_mapping_table, | ||
551 | u32 vid_2bit) | ||
552 | { | ||
553 | struct radeon_clock_voltage_dependency_table *vddc_sclk_table = | ||
554 | &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk; | ||
555 | u32 i; | ||
556 | |||
557 | if (vddc_sclk_table && vddc_sclk_table->count) { | ||
558 | if (vid_2bit < vddc_sclk_table->count) | ||
559 | return vddc_sclk_table->entries[vid_2bit].v; | ||
560 | else | ||
561 | return vddc_sclk_table->entries[vddc_sclk_table->count - 1].v; | ||
562 | } else { | ||
563 | for (i = 0; i < vid_mapping_table->num_entries; i++) { | ||
564 | if (vid_mapping_table->entries[i].vid_2bit == vid_2bit) | ||
565 | return vid_mapping_table->entries[i].vid_7bit; | ||
566 | } | ||
567 | return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_7bit; | ||
568 | } | ||
569 | } | ||
570 | |||
571 | static u32 kv_convert_vid7_to_vid2(struct radeon_device *rdev, | ||
572 | struct sumo_vid_mapping_table *vid_mapping_table, | ||
573 | u32 vid_7bit) | ||
574 | { | ||
575 | struct radeon_clock_voltage_dependency_table *vddc_sclk_table = | ||
576 | &rdev->pm.dpm.dyn_state.vddc_dependency_on_sclk; | ||
577 | u32 i; | ||
578 | |||
579 | if (vddc_sclk_table && vddc_sclk_table->count) { | ||
580 | for (i = 0; i < vddc_sclk_table->count; i++) { | ||
581 | if (vddc_sclk_table->entries[i].v == vid_7bit) | ||
582 | return i; | ||
583 | } | ||
584 | return vddc_sclk_table->count - 1; | ||
585 | } else { | ||
586 | for (i = 0; i < vid_mapping_table->num_entries; i++) { | ||
587 | if (vid_mapping_table->entries[i].vid_7bit == vid_7bit) | ||
588 | return vid_mapping_table->entries[i].vid_2bit; | ||
589 | } | ||
590 | |||
591 | return vid_mapping_table->entries[vid_mapping_table->num_entries - 1].vid_2bit; | ||
592 | } | ||
593 | } | ||
594 | |||
549 | static u16 kv_convert_8bit_index_to_voltage(struct radeon_device *rdev, | 595 | static u16 kv_convert_8bit_index_to_voltage(struct radeon_device *rdev, |
550 | u16 voltage) | 596 | u16 voltage) |
551 | { | 597 | { |
@@ -556,9 +602,9 @@ static u16 kv_convert_2bit_index_to_voltage(struct radeon_device *rdev, | |||
556 | u32 vid_2bit) | 602 | u32 vid_2bit) |
557 | { | 603 | { |
558 | struct kv_power_info *pi = kv_get_pi(rdev); | 604 | struct kv_power_info *pi = kv_get_pi(rdev); |
559 | u32 vid_8bit = sumo_convert_vid2_to_vid7(rdev, | 605 | u32 vid_8bit = kv_convert_vid2_to_vid7(rdev, |
560 | &pi->sys_info.vid_mapping_table, | 606 | &pi->sys_info.vid_mapping_table, |
561 | vid_2bit); | 607 | vid_2bit); |
562 | 608 | ||
563 | return kv_convert_8bit_index_to_voltage(rdev, (u16)vid_8bit); | 609 | return kv_convert_8bit_index_to_voltage(rdev, (u16)vid_8bit); |
564 | } | 610 | } |
@@ -639,7 +685,7 @@ static int kv_force_lowest_valid(struct radeon_device *rdev) | |||
639 | 685 | ||
640 | static int kv_unforce_levels(struct radeon_device *rdev) | 686 | static int kv_unforce_levels(struct radeon_device *rdev) |
641 | { | 687 | { |
642 | if (rdev->family == CHIP_KABINI) | 688 | if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) |
643 | return kv_notify_message_to_smu(rdev, PPSMC_MSG_NoForcedLevel); | 689 | return kv_notify_message_to_smu(rdev, PPSMC_MSG_NoForcedLevel); |
644 | else | 690 | else |
645 | return kv_set_enabled_levels(rdev); | 691 | return kv_set_enabled_levels(rdev); |
@@ -1362,13 +1408,20 @@ static int kv_update_uvd_dpm(struct radeon_device *rdev, bool gate) | |||
1362 | struct radeon_uvd_clock_voltage_dependency_table *table = | 1408 | struct radeon_uvd_clock_voltage_dependency_table *table = |
1363 | &rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table; | 1409 | &rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table; |
1364 | int ret; | 1410 | int ret; |
1411 | u32 mask; | ||
1365 | 1412 | ||
1366 | if (!gate) { | 1413 | if (!gate) { |
1367 | if (!pi->caps_uvd_dpm || table->count || pi->caps_stable_p_state) | 1414 | if (table->count) |
1368 | pi->uvd_boot_level = table->count - 1; | 1415 | pi->uvd_boot_level = table->count - 1; |
1369 | else | 1416 | else |
1370 | pi->uvd_boot_level = 0; | 1417 | pi->uvd_boot_level = 0; |
1371 | 1418 | ||
1419 | if (!pi->caps_uvd_dpm || pi->caps_stable_p_state) { | ||
1420 | mask = 1 << pi->uvd_boot_level; | ||
1421 | } else { | ||
1422 | mask = 0x1f; | ||
1423 | } | ||
1424 | |||
1372 | ret = kv_copy_bytes_to_smc(rdev, | 1425 | ret = kv_copy_bytes_to_smc(rdev, |
1373 | pi->dpm_table_start + | 1426 | pi->dpm_table_start + |
1374 | offsetof(SMU7_Fusion_DpmTable, UvdBootLevel), | 1427 | offsetof(SMU7_Fusion_DpmTable, UvdBootLevel), |
@@ -1377,11 +1430,9 @@ static int kv_update_uvd_dpm(struct radeon_device *rdev, bool gate) | |||
1377 | if (ret) | 1430 | if (ret) |
1378 | return ret; | 1431 | return ret; |
1379 | 1432 | ||
1380 | if (!pi->caps_uvd_dpm || | 1433 | kv_send_msg_to_smc_with_parameter(rdev, |
1381 | pi->caps_stable_p_state) | 1434 | PPSMC_MSG_UVDDPM_SetEnabledMask, |
1382 | kv_send_msg_to_smc_with_parameter(rdev, | 1435 | mask); |
1383 | PPSMC_MSG_UVDDPM_SetEnabledMask, | ||
1384 | (1 << pi->uvd_boot_level)); | ||
1385 | } | 1436 | } |
1386 | 1437 | ||
1387 | return kv_enable_uvd_dpm(rdev, !gate); | 1438 | return kv_enable_uvd_dpm(rdev, !gate); |
@@ -1617,7 +1668,7 @@ static void kv_dpm_powergate_acp(struct radeon_device *rdev, bool gate) | |||
1617 | if (pi->acp_power_gated == gate) | 1668 | if (pi->acp_power_gated == gate) |
1618 | return; | 1669 | return; |
1619 | 1670 | ||
1620 | if (rdev->family == CHIP_KABINI) | 1671 | if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) |
1621 | return; | 1672 | return; |
1622 | 1673 | ||
1623 | pi->acp_power_gated = gate; | 1674 | pi->acp_power_gated = gate; |
@@ -1786,7 +1837,7 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) | |||
1786 | } | 1837 | } |
1787 | } | 1838 | } |
1788 | 1839 | ||
1789 | if (rdev->family == CHIP_KABINI) { | 1840 | if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) { |
1790 | if (pi->enable_dpm) { | 1841 | if (pi->enable_dpm) { |
1791 | kv_set_valid_clock_range(rdev, new_ps); | 1842 | kv_set_valid_clock_range(rdev, new_ps); |
1792 | kv_update_dfs_bypass_settings(rdev, new_ps); | 1843 | kv_update_dfs_bypass_settings(rdev, new_ps); |
@@ -1812,6 +1863,8 @@ int kv_dpm_set_power_state(struct radeon_device *rdev) | |||
1812 | return ret; | 1863 | return ret; |
1813 | } | 1864 | } |
1814 | kv_update_sclk_t(rdev); | 1865 | kv_update_sclk_t(rdev); |
1866 | if (rdev->family == CHIP_MULLINS) | ||
1867 | kv_enable_nb_dpm(rdev); | ||
1815 | } | 1868 | } |
1816 | } else { | 1869 | } else { |
1817 | if (pi->enable_dpm) { | 1870 | if (pi->enable_dpm) { |
@@ -1862,7 +1915,7 @@ void kv_dpm_reset_asic(struct radeon_device *rdev) | |||
1862 | { | 1915 | { |
1863 | struct kv_power_info *pi = kv_get_pi(rdev); | 1916 | struct kv_power_info *pi = kv_get_pi(rdev); |
1864 | 1917 | ||
1865 | if (rdev->family == CHIP_KABINI) { | 1918 | if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) { |
1866 | kv_force_lowest_valid(rdev); | 1919 | kv_force_lowest_valid(rdev); |
1867 | kv_init_graphics_levels(rdev); | 1920 | kv_init_graphics_levels(rdev); |
1868 | kv_program_bootup_state(rdev); | 1921 | kv_program_bootup_state(rdev); |
@@ -1901,14 +1954,41 @@ static void kv_construct_max_power_limits_table(struct radeon_device *rdev, | |||
1901 | static void kv_patch_voltage_values(struct radeon_device *rdev) | 1954 | static void kv_patch_voltage_values(struct radeon_device *rdev) |
1902 | { | 1955 | { |
1903 | int i; | 1956 | int i; |
1904 | struct radeon_uvd_clock_voltage_dependency_table *table = | 1957 | struct radeon_uvd_clock_voltage_dependency_table *uvd_table = |
1905 | &rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table; | 1958 | &rdev->pm.dpm.dyn_state.uvd_clock_voltage_dependency_table; |
1959 | struct radeon_vce_clock_voltage_dependency_table *vce_table = | ||
1960 | &rdev->pm.dpm.dyn_state.vce_clock_voltage_dependency_table; | ||
1961 | struct radeon_clock_voltage_dependency_table *samu_table = | ||
1962 | &rdev->pm.dpm.dyn_state.samu_clock_voltage_dependency_table; | ||
1963 | struct radeon_clock_voltage_dependency_table *acp_table = | ||
1964 | &rdev->pm.dpm.dyn_state.acp_clock_voltage_dependency_table; | ||
1906 | 1965 | ||
1907 | if (table->count) { | 1966 | if (uvd_table->count) { |
1908 | for (i = 0; i < table->count; i++) | 1967 | for (i = 0; i < uvd_table->count; i++) |
1909 | table->entries[i].v = | 1968 | uvd_table->entries[i].v = |
1910 | kv_convert_8bit_index_to_voltage(rdev, | 1969 | kv_convert_8bit_index_to_voltage(rdev, |
1911 | table->entries[i].v); | 1970 | uvd_table->entries[i].v); |
1971 | } | ||
1972 | |||
1973 | if (vce_table->count) { | ||
1974 | for (i = 0; i < vce_table->count; i++) | ||
1975 | vce_table->entries[i].v = | ||
1976 | kv_convert_8bit_index_to_voltage(rdev, | ||
1977 | vce_table->entries[i].v); | ||
1978 | } | ||
1979 | |||
1980 | if (samu_table->count) { | ||
1981 | for (i = 0; i < samu_table->count; i++) | ||
1982 | samu_table->entries[i].v = | ||
1983 | kv_convert_8bit_index_to_voltage(rdev, | ||
1984 | samu_table->entries[i].v); | ||
1985 | } | ||
1986 | |||
1987 | if (acp_table->count) { | ||
1988 | for (i = 0; i < acp_table->count; i++) | ||
1989 | acp_table->entries[i].v = | ||
1990 | kv_convert_8bit_index_to_voltage(rdev, | ||
1991 | acp_table->entries[i].v); | ||
1912 | } | 1992 | } |
1913 | 1993 | ||
1914 | } | 1994 | } |
@@ -1941,7 +2021,7 @@ static int kv_force_dpm_highest(struct radeon_device *rdev) | |||
1941 | break; | 2021 | break; |
1942 | } | 2022 | } |
1943 | 2023 | ||
1944 | if (rdev->family == CHIP_KABINI) | 2024 | if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) |
1945 | return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i); | 2025 | return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i); |
1946 | else | 2026 | else |
1947 | return kv_set_enabled_level(rdev, i); | 2027 | return kv_set_enabled_level(rdev, i); |
@@ -1961,7 +2041,7 @@ static int kv_force_dpm_lowest(struct radeon_device *rdev) | |||
1961 | break; | 2041 | break; |
1962 | } | 2042 | } |
1963 | 2043 | ||
1964 | if (rdev->family == CHIP_KABINI) | 2044 | if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) |
1965 | return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i); | 2045 | return kv_send_msg_to_smc_with_parameter(rdev, PPSMC_MSG_DPM_ForceState, i); |
1966 | else | 2046 | else |
1967 | return kv_set_enabled_level(rdev, i); | 2047 | return kv_set_enabled_level(rdev, i); |
@@ -2118,7 +2198,7 @@ static void kv_apply_state_adjust_rules(struct radeon_device *rdev, | |||
2118 | else | 2198 | else |
2119 | pi->battery_state = false; | 2199 | pi->battery_state = false; |
2120 | 2200 | ||
2121 | if (rdev->family == CHIP_KABINI) { | 2201 | if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) { |
2122 | ps->dpm0_pg_nb_ps_lo = 0x1; | 2202 | ps->dpm0_pg_nb_ps_lo = 0x1; |
2123 | ps->dpm0_pg_nb_ps_hi = 0x0; | 2203 | ps->dpm0_pg_nb_ps_hi = 0x0; |
2124 | ps->dpmx_nb_ps_lo = 0x1; | 2204 | ps->dpmx_nb_ps_lo = 0x1; |
@@ -2179,7 +2259,7 @@ static int kv_calculate_nbps_level_settings(struct radeon_device *rdev) | |||
2179 | if (pi->lowest_valid > pi->highest_valid) | 2259 | if (pi->lowest_valid > pi->highest_valid) |
2180 | return -EINVAL; | 2260 | return -EINVAL; |
2181 | 2261 | ||
2182 | if (rdev->family == CHIP_KABINI) { | 2262 | if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) { |
2183 | for (i = pi->lowest_valid; i <= pi->highest_valid; i++) { | 2263 | for (i = pi->lowest_valid; i <= pi->highest_valid; i++) { |
2184 | pi->graphics_level[i].GnbSlow = 1; | 2264 | pi->graphics_level[i].GnbSlow = 1; |
2185 | pi->graphics_level[i].ForceNbPs1 = 0; | 2265 | pi->graphics_level[i].ForceNbPs1 = 0; |
@@ -2253,9 +2333,9 @@ static void kv_init_graphics_levels(struct radeon_device *rdev) | |||
2253 | break; | 2333 | break; |
2254 | 2334 | ||
2255 | kv_set_divider_value(rdev, i, table->entries[i].clk); | 2335 | kv_set_divider_value(rdev, i, table->entries[i].clk); |
2256 | vid_2bit = sumo_convert_vid7_to_vid2(rdev, | 2336 | vid_2bit = kv_convert_vid7_to_vid2(rdev, |
2257 | &pi->sys_info.vid_mapping_table, | 2337 | &pi->sys_info.vid_mapping_table, |
2258 | table->entries[i].v); | 2338 | table->entries[i].v); |
2259 | kv_set_vid(rdev, i, vid_2bit); | 2339 | kv_set_vid(rdev, i, vid_2bit); |
2260 | kv_set_at(rdev, i, pi->at[i]); | 2340 | kv_set_at(rdev, i, pi->at[i]); |
2261 | kv_dpm_power_level_enabled_for_throttle(rdev, i, true); | 2341 | kv_dpm_power_level_enabled_for_throttle(rdev, i, true); |
@@ -2324,7 +2404,7 @@ static void kv_program_nbps_index_settings(struct radeon_device *rdev, | |||
2324 | struct kv_power_info *pi = kv_get_pi(rdev); | 2404 | struct kv_power_info *pi = kv_get_pi(rdev); |
2325 | u32 nbdpmconfig1; | 2405 | u32 nbdpmconfig1; |
2326 | 2406 | ||
2327 | if (rdev->family == CHIP_KABINI) | 2407 | if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) |
2328 | return; | 2408 | return; |
2329 | 2409 | ||
2330 | if (pi->sys_info.nb_dpm_enable) { | 2410 | if (pi->sys_info.nb_dpm_enable) { |
@@ -2631,9 +2711,6 @@ int kv_dpm_init(struct radeon_device *rdev) | |||
2631 | 2711 | ||
2632 | pi->sram_end = SMC_RAM_END; | 2712 | pi->sram_end = SMC_RAM_END; |
2633 | 2713 | ||
2634 | if (rdev->family == CHIP_KABINI) | ||
2635 | pi->high_voltage_t = 4001; | ||
2636 | |||
2637 | pi->enable_nb_dpm = true; | 2714 | pi->enable_nb_dpm = true; |
2638 | 2715 | ||
2639 | pi->caps_power_containment = true; | 2716 | pi->caps_power_containment = true; |
diff --git a/drivers/gpu/drm/radeon/r600.c b/drivers/gpu/drm/radeon/r600.c index 6e887d004eba..bbc189fd3ddc 100644 --- a/drivers/gpu/drm/radeon/r600.c +++ b/drivers/gpu/drm/radeon/r600.c | |||
@@ -2839,6 +2839,7 @@ int r600_copy_cpdma(struct radeon_device *rdev, | |||
2839 | r = radeon_fence_emit(rdev, fence, ring->idx); | 2839 | r = radeon_fence_emit(rdev, fence, ring->idx); |
2840 | if (r) { | 2840 | if (r) { |
2841 | radeon_ring_unlock_undo(rdev, ring); | 2841 | radeon_ring_unlock_undo(rdev, ring); |
2842 | radeon_semaphore_free(rdev, &sem, NULL); | ||
2842 | return r; | 2843 | return r; |
2843 | } | 2844 | } |
2844 | 2845 | ||
@@ -3505,7 +3506,6 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3505 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; | 3506 | u32 hpd1, hpd2, hpd3, hpd4 = 0, hpd5 = 0, hpd6 = 0; |
3506 | u32 grbm_int_cntl = 0; | 3507 | u32 grbm_int_cntl = 0; |
3507 | u32 hdmi0, hdmi1; | 3508 | u32 hdmi0, hdmi1; |
3508 | u32 d1grph = 0, d2grph = 0; | ||
3509 | u32 dma_cntl; | 3509 | u32 dma_cntl; |
3510 | u32 thermal_int = 0; | 3510 | u32 thermal_int = 0; |
3511 | 3511 | ||
@@ -3614,8 +3614,8 @@ int r600_irq_set(struct radeon_device *rdev) | |||
3614 | WREG32(CP_INT_CNTL, cp_int_cntl); | 3614 | WREG32(CP_INT_CNTL, cp_int_cntl); |
3615 | WREG32(DMA_CNTL, dma_cntl); | 3615 | WREG32(DMA_CNTL, dma_cntl); |
3616 | WREG32(DxMODE_INT_MASK, mode_int); | 3616 | WREG32(DxMODE_INT_MASK, mode_int); |
3617 | WREG32(D1GRPH_INTERRUPT_CONTROL, d1grph); | 3617 | WREG32(D1GRPH_INTERRUPT_CONTROL, DxGRPH_PFLIP_INT_MASK); |
3618 | WREG32(D2GRPH_INTERRUPT_CONTROL, d2grph); | 3618 | WREG32(D2GRPH_INTERRUPT_CONTROL, DxGRPH_PFLIP_INT_MASK); |
3619 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); | 3619 | WREG32(GRBM_INT_CNTL, grbm_int_cntl); |
3620 | if (ASIC_IS_DCE3(rdev)) { | 3620 | if (ASIC_IS_DCE3(rdev)) { |
3621 | WREG32(DC_HPD1_INT_CONTROL, hpd1); | 3621 | WREG32(DC_HPD1_INT_CONTROL, hpd1); |
@@ -3918,6 +3918,14 @@ restart_ih: | |||
3918 | break; | 3918 | break; |
3919 | } | 3919 | } |
3920 | break; | 3920 | break; |
3921 | case 9: /* D1 pflip */ | ||
3922 | DRM_DEBUG("IH: D1 flip\n"); | ||
3923 | radeon_crtc_handle_flip(rdev, 0); | ||
3924 | break; | ||
3925 | case 11: /* D2 pflip */ | ||
3926 | DRM_DEBUG("IH: D2 flip\n"); | ||
3927 | radeon_crtc_handle_flip(rdev, 1); | ||
3928 | break; | ||
3921 | case 19: /* HPD/DAC hotplug */ | 3929 | case 19: /* HPD/DAC hotplug */ |
3922 | switch (src_data) { | 3930 | switch (src_data) { |
3923 | case 0: | 3931 | case 0: |
diff --git a/drivers/gpu/drm/radeon/r600_dma.c b/drivers/gpu/drm/radeon/r600_dma.c index 53fcb28f5578..4969cef44a19 100644 --- a/drivers/gpu/drm/radeon/r600_dma.c +++ b/drivers/gpu/drm/radeon/r600_dma.c | |||
@@ -489,6 +489,7 @@ int r600_copy_dma(struct radeon_device *rdev, | |||
489 | r = radeon_fence_emit(rdev, fence, ring->idx); | 489 | r = radeon_fence_emit(rdev, fence, ring->idx); |
490 | if (r) { | 490 | if (r) { |
491 | radeon_ring_unlock_undo(rdev, ring); | 491 | radeon_ring_unlock_undo(rdev, ring); |
492 | radeon_semaphore_free(rdev, &sem, NULL); | ||
492 | return r; | 493 | return r; |
493 | } | 494 | } |
494 | 495 | ||
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index b58e1afdda76..68528619834a 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -730,6 +730,12 @@ struct cik_irq_stat_regs { | |||
730 | u32 disp_int_cont4; | 730 | u32 disp_int_cont4; |
731 | u32 disp_int_cont5; | 731 | u32 disp_int_cont5; |
732 | u32 disp_int_cont6; | 732 | u32 disp_int_cont6; |
733 | u32 d1grph_int; | ||
734 | u32 d2grph_int; | ||
735 | u32 d3grph_int; | ||
736 | u32 d4grph_int; | ||
737 | u32 d5grph_int; | ||
738 | u32 d6grph_int; | ||
733 | }; | 739 | }; |
734 | 740 | ||
735 | union radeon_irq_stat_regs { | 741 | union radeon_irq_stat_regs { |
diff --git a/drivers/gpu/drm/radeon/radeon_asic.c b/drivers/gpu/drm/radeon/radeon_asic.c index b8a24a75d4ff..be20e62dac83 100644 --- a/drivers/gpu/drm/radeon/radeon_asic.c +++ b/drivers/gpu/drm/radeon/radeon_asic.c | |||
@@ -2516,6 +2516,7 @@ int radeon_asic_init(struct radeon_device *rdev) | |||
2516 | break; | 2516 | break; |
2517 | case CHIP_KAVERI: | 2517 | case CHIP_KAVERI: |
2518 | case CHIP_KABINI: | 2518 | case CHIP_KABINI: |
2519 | case CHIP_MULLINS: | ||
2519 | rdev->asic = &kv_asic; | 2520 | rdev->asic = &kv_asic; |
2520 | /* set num crtcs */ | 2521 | /* set num crtcs */ |
2521 | if (rdev->family == CHIP_KAVERI) { | 2522 | if (rdev->family == CHIP_KAVERI) { |
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c index 511fe26198e4..0e770bbf7e29 100644 --- a/drivers/gpu/drm/radeon/radeon_device.c +++ b/drivers/gpu/drm/radeon/radeon_device.c | |||
@@ -99,6 +99,7 @@ static const char radeon_family_name[][16] = { | |||
99 | "KAVERI", | 99 | "KAVERI", |
100 | "KABINI", | 100 | "KABINI", |
101 | "HAWAII", | 101 | "HAWAII", |
102 | "MULLINS", | ||
102 | "LAST", | 103 | "LAST", |
103 | }; | 104 | }; |
104 | 105 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 8d99d5ee8014..408b6ac53f0b 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -284,6 +284,10 @@ void radeon_crtc_handle_flip(struct radeon_device *rdev, int crtc_id) | |||
284 | u32 update_pending; | 284 | u32 update_pending; |
285 | int vpos, hpos; | 285 | int vpos, hpos; |
286 | 286 | ||
287 | /* can happen during initialization */ | ||
288 | if (radeon_crtc == NULL) | ||
289 | return; | ||
290 | |||
287 | spin_lock_irqsave(&rdev->ddev->event_lock, flags); | 291 | spin_lock_irqsave(&rdev->ddev->event_lock, flags); |
288 | work = radeon_crtc->unpin_work; | 292 | work = radeon_crtc->unpin_work; |
289 | if (work == NULL || | 293 | if (work == NULL || |
@@ -826,14 +830,14 @@ static void avivo_reduce_ratio(unsigned *nom, unsigned *den, | |||
826 | 830 | ||
827 | /* make sure nominator is large enough */ | 831 | /* make sure nominator is large enough */ |
828 | if (*nom < nom_min) { | 832 | if (*nom < nom_min) { |
829 | tmp = (nom_min + *nom - 1) / *nom; | 833 | tmp = DIV_ROUND_UP(nom_min, *nom); |
830 | *nom *= tmp; | 834 | *nom *= tmp; |
831 | *den *= tmp; | 835 | *den *= tmp; |
832 | } | 836 | } |
833 | 837 | ||
834 | /* make sure the denominator is large enough */ | 838 | /* make sure the denominator is large enough */ |
835 | if (*den < den_min) { | 839 | if (*den < den_min) { |
836 | tmp = (den_min + *den - 1) / *den; | 840 | tmp = DIV_ROUND_UP(den_min, *den); |
837 | *nom *= tmp; | 841 | *nom *= tmp; |
838 | *den *= tmp; | 842 | *den *= tmp; |
839 | } | 843 | } |
@@ -858,7 +862,7 @@ static void avivo_get_fb_ref_div(unsigned nom, unsigned den, unsigned post_div, | |||
858 | unsigned *fb_div, unsigned *ref_div) | 862 | unsigned *fb_div, unsigned *ref_div) |
859 | { | 863 | { |
860 | /* limit reference * post divider to a maximum */ | 864 | /* limit reference * post divider to a maximum */ |
861 | ref_div_max = min(210 / post_div, ref_div_max); | 865 | ref_div_max = min(128 / post_div, ref_div_max); |
862 | 866 | ||
863 | /* get matching reference and feedback divider */ | 867 | /* get matching reference and feedback divider */ |
864 | *ref_div = min(max(DIV_ROUND_CLOSEST(den, post_div), 1u), ref_div_max); | 868 | *ref_div = min(max(DIV_ROUND_CLOSEST(den, post_div), 1u), ref_div_max); |
@@ -993,6 +997,16 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll, | |||
993 | /* this also makes sure that the reference divider is large enough */ | 997 | /* this also makes sure that the reference divider is large enough */ |
994 | avivo_reduce_ratio(&fb_div, &ref_div, fb_div_min, ref_div_min); | 998 | avivo_reduce_ratio(&fb_div, &ref_div, fb_div_min, ref_div_min); |
995 | 999 | ||
1000 | /* avoid high jitter with small fractional dividers */ | ||
1001 | if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV && (fb_div % 10)) { | ||
1002 | fb_div_min = max(fb_div_min, (9 - (fb_div % 10)) * 20 + 60); | ||
1003 | if (fb_div < fb_div_min) { | ||
1004 | unsigned tmp = DIV_ROUND_UP(fb_div_min, fb_div); | ||
1005 | fb_div *= tmp; | ||
1006 | ref_div *= tmp; | ||
1007 | } | ||
1008 | } | ||
1009 | |||
996 | /* and finally save the result */ | 1010 | /* and finally save the result */ |
997 | if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) { | 1011 | if (pll->flags & RADEON_PLL_USE_FRAC_FB_DIV) { |
998 | *fb_div_p = fb_div / 10; | 1012 | *fb_div_p = fb_div / 10; |
diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h index 9da5da4ffd17..4b7b87f71a63 100644 --- a/drivers/gpu/drm/radeon/radeon_family.h +++ b/drivers/gpu/drm/radeon/radeon_family.h | |||
@@ -97,6 +97,7 @@ enum radeon_family { | |||
97 | CHIP_KAVERI, | 97 | CHIP_KAVERI, |
98 | CHIP_KABINI, | 98 | CHIP_KABINI, |
99 | CHIP_HAWAII, | 99 | CHIP_HAWAII, |
100 | CHIP_MULLINS, | ||
100 | CHIP_LAST, | 101 | CHIP_LAST, |
101 | }; | 102 | }; |
102 | 103 | ||
diff --git a/drivers/gpu/drm/radeon/radeon_pm.c b/drivers/gpu/drm/radeon/radeon_pm.c index 6fac8efe8340..f30b8426eee2 100644 --- a/drivers/gpu/drm/radeon/radeon_pm.c +++ b/drivers/gpu/drm/radeon/radeon_pm.c | |||
@@ -1300,6 +1300,7 @@ int radeon_pm_init(struct radeon_device *rdev) | |||
1300 | case CHIP_KABINI: | 1300 | case CHIP_KABINI: |
1301 | case CHIP_KAVERI: | 1301 | case CHIP_KAVERI: |
1302 | case CHIP_HAWAII: | 1302 | case CHIP_HAWAII: |
1303 | case CHIP_MULLINS: | ||
1303 | /* DPM requires the RLC, RV770+ dGPU requires SMC */ | 1304 | /* DPM requires the RLC, RV770+ dGPU requires SMC */ |
1304 | if (!rdev->rlc_fw) | 1305 | if (!rdev->rlc_fw) |
1305 | rdev->pm.pm_method = PM_METHOD_PROFILE; | 1306 | rdev->pm.pm_method = PM_METHOD_PROFILE; |
diff --git a/drivers/gpu/drm/radeon/radeon_ucode.h b/drivers/gpu/drm/radeon/radeon_ucode.h index 58d12938c0b8..4e7c3269b183 100644 --- a/drivers/gpu/drm/radeon/radeon_ucode.h +++ b/drivers/gpu/drm/radeon/radeon_ucode.h | |||
@@ -52,6 +52,7 @@ | |||
52 | #define BONAIRE_RLC_UCODE_SIZE 2048 | 52 | #define BONAIRE_RLC_UCODE_SIZE 2048 |
53 | #define KB_RLC_UCODE_SIZE 2560 | 53 | #define KB_RLC_UCODE_SIZE 2560 |
54 | #define KV_RLC_UCODE_SIZE 2560 | 54 | #define KV_RLC_UCODE_SIZE 2560 |
55 | #define ML_RLC_UCODE_SIZE 2560 | ||
55 | 56 | ||
56 | /* MC */ | 57 | /* MC */ |
57 | #define BTC_MC_UCODE_SIZE 6024 | 58 | #define BTC_MC_UCODE_SIZE 6024 |
diff --git a/drivers/gpu/drm/radeon/radeon_uvd.c b/drivers/gpu/drm/radeon/radeon_uvd.c index 5748bdaeacce..1b65ae2433cd 100644 --- a/drivers/gpu/drm/radeon/radeon_uvd.c +++ b/drivers/gpu/drm/radeon/radeon_uvd.c | |||
@@ -99,6 +99,7 @@ int radeon_uvd_init(struct radeon_device *rdev) | |||
99 | case CHIP_KABINI: | 99 | case CHIP_KABINI: |
100 | case CHIP_KAVERI: | 100 | case CHIP_KAVERI: |
101 | case CHIP_HAWAII: | 101 | case CHIP_HAWAII: |
102 | case CHIP_MULLINS: | ||
102 | fw_name = FIRMWARE_BONAIRE; | 103 | fw_name = FIRMWARE_BONAIRE; |
103 | break; | 104 | break; |
104 | 105 | ||
@@ -465,6 +466,10 @@ static int radeon_uvd_cs_reloc(struct radeon_cs_parser *p, | |||
465 | cmd = radeon_get_ib_value(p, p->idx) >> 1; | 466 | cmd = radeon_get_ib_value(p, p->idx) >> 1; |
466 | 467 | ||
467 | if (cmd < 0x4) { | 468 | if (cmd < 0x4) { |
469 | if (end <= start) { | ||
470 | DRM_ERROR("invalid reloc offset %X!\n", offset); | ||
471 | return -EINVAL; | ||
472 | } | ||
468 | if ((end - start) < buf_sizes[cmd]) { | 473 | if ((end - start) < buf_sizes[cmd]) { |
469 | DRM_ERROR("buffer (%d) to small (%d / %d)!\n", cmd, | 474 | DRM_ERROR("buffer (%d) to small (%d / %d)!\n", cmd, |
470 | (unsigned)(end - start), buf_sizes[cmd]); | 475 | (unsigned)(end - start), buf_sizes[cmd]); |
diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c index ced53dd03e7c..f73324c81491 100644 --- a/drivers/gpu/drm/radeon/radeon_vce.c +++ b/drivers/gpu/drm/radeon/radeon_vce.c | |||
@@ -66,6 +66,7 @@ int radeon_vce_init(struct radeon_device *rdev) | |||
66 | case CHIP_BONAIRE: | 66 | case CHIP_BONAIRE: |
67 | case CHIP_KAVERI: | 67 | case CHIP_KAVERI: |
68 | case CHIP_KABINI: | 68 | case CHIP_KABINI: |
69 | case CHIP_MULLINS: | ||
69 | fw_name = FIRMWARE_BONAIRE; | 70 | fw_name = FIRMWARE_BONAIRE; |
70 | break; | 71 | break; |
71 | 72 | ||
diff --git a/drivers/gpu/drm/radeon/rv770_dma.c b/drivers/gpu/drm/radeon/rv770_dma.c index aca8cbe8a335..bbf2e076ee45 100644 --- a/drivers/gpu/drm/radeon/rv770_dma.c +++ b/drivers/gpu/drm/radeon/rv770_dma.c | |||
@@ -86,6 +86,7 @@ int rv770_copy_dma(struct radeon_device *rdev, | |||
86 | r = radeon_fence_emit(rdev, fence, ring->idx); | 86 | r = radeon_fence_emit(rdev, fence, ring->idx); |
87 | if (r) { | 87 | if (r) { |
88 | radeon_ring_unlock_undo(rdev, ring); | 88 | radeon_ring_unlock_undo(rdev, ring); |
89 | radeon_semaphore_free(rdev, &sem, NULL); | ||
89 | return r; | 90 | return r; |
90 | } | 91 | } |
91 | 92 | ||
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c index ac708e006180..22a63c98ba14 100644 --- a/drivers/gpu/drm/radeon/si.c +++ b/drivers/gpu/drm/radeon/si.c | |||
@@ -5780,7 +5780,6 @@ int si_irq_set(struct radeon_device *rdev) | |||
5780 | u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; | 5780 | u32 crtc1 = 0, crtc2 = 0, crtc3 = 0, crtc4 = 0, crtc5 = 0, crtc6 = 0; |
5781 | u32 hpd1 = 0, hpd2 = 0, hpd3 = 0, hpd4 = 0, hpd5 = 0, hpd6 = 0; | 5781 | u32 hpd1 = 0, hpd2 = 0, hpd3 = 0, hpd4 = 0, hpd5 = 0, hpd6 = 0; |
5782 | u32 grbm_int_cntl = 0; | 5782 | u32 grbm_int_cntl = 0; |
5783 | u32 grph1 = 0, grph2 = 0, grph3 = 0, grph4 = 0, grph5 = 0, grph6 = 0; | ||
5784 | u32 dma_cntl, dma_cntl1; | 5783 | u32 dma_cntl, dma_cntl1; |
5785 | u32 thermal_int = 0; | 5784 | u32 thermal_int = 0; |
5786 | 5785 | ||
@@ -5919,16 +5918,22 @@ int si_irq_set(struct radeon_device *rdev) | |||
5919 | } | 5918 | } |
5920 | 5919 | ||
5921 | if (rdev->num_crtc >= 2) { | 5920 | if (rdev->num_crtc >= 2) { |
5922 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, grph1); | 5921 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC0_REGISTER_OFFSET, |
5923 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, grph2); | 5922 | GRPH_PFLIP_INT_MASK); |
5923 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC1_REGISTER_OFFSET, | ||
5924 | GRPH_PFLIP_INT_MASK); | ||
5924 | } | 5925 | } |
5925 | if (rdev->num_crtc >= 4) { | 5926 | if (rdev->num_crtc >= 4) { |
5926 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, grph3); | 5927 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC2_REGISTER_OFFSET, |
5927 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, grph4); | 5928 | GRPH_PFLIP_INT_MASK); |
5929 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC3_REGISTER_OFFSET, | ||
5930 | GRPH_PFLIP_INT_MASK); | ||
5928 | } | 5931 | } |
5929 | if (rdev->num_crtc >= 6) { | 5932 | if (rdev->num_crtc >= 6) { |
5930 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, grph5); | 5933 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC4_REGISTER_OFFSET, |
5931 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, grph6); | 5934 | GRPH_PFLIP_INT_MASK); |
5935 | WREG32(GRPH_INT_CONTROL + EVERGREEN_CRTC5_REGISTER_OFFSET, | ||
5936 | GRPH_PFLIP_INT_MASK); | ||
5932 | } | 5937 | } |
5933 | 5938 | ||
5934 | if (!ASIC_IS_NODCE(rdev)) { | 5939 | if (!ASIC_IS_NODCE(rdev)) { |
@@ -6292,6 +6297,15 @@ restart_ih: | |||
6292 | break; | 6297 | break; |
6293 | } | 6298 | } |
6294 | break; | 6299 | break; |
6300 | case 8: /* D1 page flip */ | ||
6301 | case 10: /* D2 page flip */ | ||
6302 | case 12: /* D3 page flip */ | ||
6303 | case 14: /* D4 page flip */ | ||
6304 | case 16: /* D5 page flip */ | ||
6305 | case 18: /* D6 page flip */ | ||
6306 | DRM_DEBUG("IH: D%d flip\n", ((src_id - 8) >> 1) + 1); | ||
6307 | radeon_crtc_handle_flip(rdev, (src_id - 8) >> 1); | ||
6308 | break; | ||
6295 | case 42: /* HPD hotplug */ | 6309 | case 42: /* HPD hotplug */ |
6296 | switch (src_data) { | 6310 | switch (src_data) { |
6297 | case 0: | 6311 | case 0: |
diff --git a/drivers/gpu/drm/radeon/si_dma.c b/drivers/gpu/drm/radeon/si_dma.c index cf0fdad8c278..de0ca070122f 100644 --- a/drivers/gpu/drm/radeon/si_dma.c +++ b/drivers/gpu/drm/radeon/si_dma.c | |||
@@ -213,6 +213,7 @@ int si_copy_dma(struct radeon_device *rdev, | |||
213 | r = radeon_fence_emit(rdev, fence, ring->idx); | 213 | r = radeon_fence_emit(rdev, fence, ring->idx); |
214 | if (r) { | 214 | if (r) { |
215 | radeon_ring_unlock_undo(rdev, ring); | 215 | radeon_ring_unlock_undo(rdev, ring); |
216 | radeon_semaphore_free(rdev, &sem, NULL); | ||
216 | return r; | 217 | return r; |
217 | } | 218 | } |
218 | 219 | ||
diff --git a/drivers/gpu/drm/radeon/uvd_v1_0.c b/drivers/gpu/drm/radeon/uvd_v1_0.c index 0a243f0e5d68..be42c8125203 100644 --- a/drivers/gpu/drm/radeon/uvd_v1_0.c +++ b/drivers/gpu/drm/radeon/uvd_v1_0.c | |||
@@ -83,7 +83,10 @@ int uvd_v1_0_init(struct radeon_device *rdev) | |||
83 | int r; | 83 | int r; |
84 | 84 | ||
85 | /* raise clocks while booting up the VCPU */ | 85 | /* raise clocks while booting up the VCPU */ |
86 | radeon_set_uvd_clocks(rdev, 53300, 40000); | 86 | if (rdev->family < CHIP_RV740) |
87 | radeon_set_uvd_clocks(rdev, 10000, 10000); | ||
88 | else | ||
89 | radeon_set_uvd_clocks(rdev, 53300, 40000); | ||
87 | 90 | ||
88 | r = uvd_v1_0_start(rdev); | 91 | r = uvd_v1_0_start(rdev); |
89 | if (r) | 92 | if (r) |
@@ -407,7 +410,10 @@ int uvd_v1_0_ib_test(struct radeon_device *rdev, struct radeon_ring *ring) | |||
407 | struct radeon_fence *fence = NULL; | 410 | struct radeon_fence *fence = NULL; |
408 | int r; | 411 | int r; |
409 | 412 | ||
410 | r = radeon_set_uvd_clocks(rdev, 53300, 40000); | 413 | if (rdev->family < CHIP_RV740) |
414 | r = radeon_set_uvd_clocks(rdev, 10000, 10000); | ||
415 | else | ||
416 | r = radeon_set_uvd_clocks(rdev, 53300, 40000); | ||
411 | if (r) { | 417 | if (r) { |
412 | DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r); | 418 | DRM_ERROR("radeon: failed to raise UVD clocks (%d).\n", r); |
413 | return r; | 419 | return r; |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 10a2c0866459..da52279de939 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1253,7 +1253,8 @@ EXPORT_SYMBOL_GPL(hid_output_report); | |||
1253 | 1253 | ||
1254 | static int hid_report_len(struct hid_report *report) | 1254 | static int hid_report_len(struct hid_report *report) |
1255 | { | 1255 | { |
1256 | return ((report->size - 1) >> 3) + 1 + (report->id > 0) + 7; | 1256 | /* equivalent to DIV_ROUND_UP(report->size, 8) + !!(report->id > 0) */ |
1257 | return ((report->size - 1) >> 3) + 1 + (report->id > 0); | ||
1257 | } | 1258 | } |
1258 | 1259 | ||
1259 | /* | 1260 | /* |
@@ -1266,7 +1267,7 @@ u8 *hid_alloc_report_buf(struct hid_report *report, gfp_t flags) | |||
1266 | * of implement() working on 8 byte chunks | 1267 | * of implement() working on 8 byte chunks |
1267 | */ | 1268 | */ |
1268 | 1269 | ||
1269 | int len = hid_report_len(report); | 1270 | int len = hid_report_len(report) + 7; |
1270 | 1271 | ||
1271 | return kmalloc(len, flags); | 1272 | return kmalloc(len, flags); |
1272 | } | 1273 | } |
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h index c8af7202c28d..34bb2205d2ea 100644 --- a/drivers/hid/hid-ids.h +++ b/drivers/hid/hid-ids.h | |||
@@ -301,6 +301,9 @@ | |||
301 | 301 | ||
302 | #define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34 | 302 | #define USB_VENDOR_ID_DREAM_CHEEKY 0x1d34 |
303 | 303 | ||
304 | #define USB_VENDOR_ID_ELITEGROUP 0x03fc | ||
305 | #define USB_DEVICE_ID_ELITEGROUP_05D8 0x05d8 | ||
306 | |||
304 | #define USB_VENDOR_ID_ELO 0x04E7 | 307 | #define USB_VENDOR_ID_ELO 0x04E7 |
305 | #define USB_DEVICE_ID_ELO_TS2515 0x0022 | 308 | #define USB_DEVICE_ID_ELO_TS2515 0x0022 |
306 | #define USB_DEVICE_ID_ELO_TS2700 0x0020 | 309 | #define USB_DEVICE_ID_ELO_TS2700 0x0020 |
@@ -834,6 +837,10 @@ | |||
834 | #define USB_DEVICE_ID_SYNAPTICS_LTS2 0x1d10 | 837 | #define USB_DEVICE_ID_SYNAPTICS_LTS2 0x1d10 |
835 | #define USB_DEVICE_ID_SYNAPTICS_HD 0x0ac3 | 838 | #define USB_DEVICE_ID_SYNAPTICS_HD 0x0ac3 |
836 | #define USB_DEVICE_ID_SYNAPTICS_QUAD_HD 0x1ac3 | 839 | #define USB_DEVICE_ID_SYNAPTICS_QUAD_HD 0x1ac3 |
840 | #define USB_DEVICE_ID_SYNAPTICS_TP_V103 0x5710 | ||
841 | |||
842 | #define USB_VENDOR_ID_TEXAS_INSTRUMENTS 0x2047 | ||
843 | #define USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA 0x0855 | ||
837 | 844 | ||
838 | #define USB_VENDOR_ID_THINGM 0x27b8 | 845 | #define USB_VENDOR_ID_THINGM 0x27b8 |
839 | #define USB_DEVICE_ID_BLINK1 0x01ed | 846 | #define USB_DEVICE_ID_BLINK1 0x01ed |
diff --git a/drivers/hid/hid-multitouch.c b/drivers/hid/hid-multitouch.c index 35278e43c7a4..51e25b9407f2 100644 --- a/drivers/hid/hid-multitouch.c +++ b/drivers/hid/hid-multitouch.c | |||
@@ -1155,6 +1155,11 @@ static const struct hid_device_id mt_devices[] = { | |||
1155 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, | 1155 | MT_USB_DEVICE(USB_VENDOR_ID_DWAV, |
1156 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, | 1156 | USB_DEVICE_ID_DWAV_EGALAX_MULTITOUCH_A001) }, |
1157 | 1157 | ||
1158 | /* Elitegroup panel */ | ||
1159 | { .driver_data = MT_CLS_SERIAL, | ||
1160 | MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP, | ||
1161 | USB_DEVICE_ID_ELITEGROUP_05D8) }, | ||
1162 | |||
1158 | /* Flatfrog Panels */ | 1163 | /* Flatfrog Panels */ |
1159 | { .driver_data = MT_CLS_FLATFROG, | 1164 | { .driver_data = MT_CLS_FLATFROG, |
1160 | MT_USB_DEVICE(USB_VENDOR_ID_FLATFROG, | 1165 | MT_USB_DEVICE(USB_VENDOR_ID_FLATFROG, |
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c index af8244b1c1f4..be14b5690e94 100644 --- a/drivers/hid/hid-sensor-hub.c +++ b/drivers/hid/hid-sensor-hub.c | |||
@@ -708,6 +708,9 @@ static const struct hid_device_id sensor_hub_devices[] = { | |||
708 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0, | 708 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0, |
709 | USB_DEVICE_ID_STM_HID_SENSOR), | 709 | USB_DEVICE_ID_STM_HID_SENSOR), |
710 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, | 710 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, |
711 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_TEXAS_INSTRUMENTS, | ||
712 | USB_DEVICE_ID_TEXAS_INSTRUMENTS_LENOVO_YOGA), | ||
713 | .driver_data = HID_SENSOR_HUB_ENUM_QUIRK}, | ||
711 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, | 714 | { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, HID_ANY_ID, |
712 | HID_ANY_ID) }, | 715 | HID_ANY_ID) }, |
713 | { } | 716 | { } |
diff --git a/drivers/hid/usbhid/hid-quirks.c b/drivers/hid/usbhid/hid-quirks.c index dbd83878ff99..8e4ddb369883 100644 --- a/drivers/hid/usbhid/hid-quirks.c +++ b/drivers/hid/usbhid/hid-quirks.c | |||
@@ -119,6 +119,7 @@ static const struct hid_blacklist { | |||
119 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS2, HID_QUIRK_NO_INIT_REPORTS }, | 119 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_LTS2, HID_QUIRK_NO_INIT_REPORTS }, |
120 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD, HID_QUIRK_NO_INIT_REPORTS }, | 120 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_HD, HID_QUIRK_NO_INIT_REPORTS }, |
121 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD, HID_QUIRK_NO_INIT_REPORTS }, | 121 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_QUAD_HD, HID_QUIRK_NO_INIT_REPORTS }, |
122 | { USB_VENDOR_ID_SYNAPTICS, USB_DEVICE_ID_SYNAPTICS_TP_V103, HID_QUIRK_NO_INIT_REPORTS }, | ||
122 | 123 | ||
123 | { 0, 0 } | 124 | { 0, 0 } |
124 | }; | 125 | }; |
diff --git a/drivers/hwmon/vexpress.c b/drivers/hwmon/vexpress.c index 8242b75d96c8..611f34c7333d 100644 --- a/drivers/hwmon/vexpress.c +++ b/drivers/hwmon/vexpress.c | |||
@@ -26,7 +26,7 @@ | |||
26 | 26 | ||
27 | struct vexpress_hwmon_data { | 27 | struct vexpress_hwmon_data { |
28 | struct device *hwmon_dev; | 28 | struct device *hwmon_dev; |
29 | struct vexpress_config_func *func; | 29 | struct regmap *reg; |
30 | const char *name; | 30 | const char *name; |
31 | }; | 31 | }; |
32 | 32 | ||
@@ -53,7 +53,7 @@ static ssize_t vexpress_hwmon_u32_show(struct device *dev, | |||
53 | int err; | 53 | int err; |
54 | u32 value; | 54 | u32 value; |
55 | 55 | ||
56 | err = vexpress_config_read(data->func, 0, &value); | 56 | err = regmap_read(data->reg, 0, &value); |
57 | if (err) | 57 | if (err) |
58 | return err; | 58 | return err; |
59 | 59 | ||
@@ -68,11 +68,11 @@ static ssize_t vexpress_hwmon_u64_show(struct device *dev, | |||
68 | int err; | 68 | int err; |
69 | u32 value_hi, value_lo; | 69 | u32 value_hi, value_lo; |
70 | 70 | ||
71 | err = vexpress_config_read(data->func, 0, &value_lo); | 71 | err = regmap_read(data->reg, 0, &value_lo); |
72 | if (err) | 72 | if (err) |
73 | return err; | 73 | return err; |
74 | 74 | ||
75 | err = vexpress_config_read(data->func, 1, &value_hi); | 75 | err = regmap_read(data->reg, 1, &value_hi); |
76 | if (err) | 76 | if (err) |
77 | return err; | 77 | return err; |
78 | 78 | ||
@@ -234,9 +234,9 @@ static int vexpress_hwmon_probe(struct platform_device *pdev) | |||
234 | type = match->data; | 234 | type = match->data; |
235 | data->name = type->name; | 235 | data->name = type->name; |
236 | 236 | ||
237 | data->func = vexpress_config_func_get_by_dev(&pdev->dev); | 237 | data->reg = devm_regmap_init_vexpress_config(&pdev->dev); |
238 | if (!data->func) | 238 | if (IS_ERR(data->reg)) |
239 | return -ENODEV; | 239 | return PTR_ERR(data->reg); |
240 | 240 | ||
241 | err = sysfs_create_groups(&pdev->dev.kobj, type->attr_groups); | 241 | err = sysfs_create_groups(&pdev->dev.kobj, type->attr_groups); |
242 | if (err) | 242 | if (err) |
@@ -252,7 +252,6 @@ static int vexpress_hwmon_probe(struct platform_device *pdev) | |||
252 | 252 | ||
253 | error: | 253 | error: |
254 | sysfs_remove_group(&pdev->dev.kobj, match->data); | 254 | sysfs_remove_group(&pdev->dev.kobj, match->data); |
255 | vexpress_config_func_put(data->func); | ||
256 | return err; | 255 | return err; |
257 | } | 256 | } |
258 | 257 | ||
@@ -266,8 +265,6 @@ static int vexpress_hwmon_remove(struct platform_device *pdev) | |||
266 | match = of_match_device(vexpress_hwmon_of_match, &pdev->dev); | 265 | match = of_match_device(vexpress_hwmon_of_match, &pdev->dev); |
267 | sysfs_remove_group(&pdev->dev.kobj, match->data); | 266 | sysfs_remove_group(&pdev->dev.kobj, match->data); |
268 | 267 | ||
269 | vexpress_config_func_put(data->func); | ||
270 | |||
271 | return 0; | 268 | return 0; |
272 | } | 269 | } |
273 | 270 | ||
diff --git a/drivers/iio/adc/Kconfig b/drivers/iio/adc/Kconfig index d86196cfe4b4..24c28e3f93a3 100644 --- a/drivers/iio/adc/Kconfig +++ b/drivers/iio/adc/Kconfig | |||
@@ -106,7 +106,7 @@ config AT91_ADC | |||
106 | Say yes here to build support for Atmel AT91 ADC. | 106 | Say yes here to build support for Atmel AT91 ADC. |
107 | 107 | ||
108 | config EXYNOS_ADC | 108 | config EXYNOS_ADC |
109 | bool "Exynos ADC driver support" | 109 | tristate "Exynos ADC driver support" |
110 | depends on OF | 110 | depends on OF |
111 | help | 111 | help |
112 | Core support for the ADC block found in the Samsung EXYNOS series | 112 | Core support for the ADC block found in the Samsung EXYNOS series |
@@ -114,7 +114,7 @@ config EXYNOS_ADC | |||
114 | this resource. | 114 | this resource. |
115 | 115 | ||
116 | config LP8788_ADC | 116 | config LP8788_ADC |
117 | bool "LP8788 ADC driver" | 117 | tristate "LP8788 ADC driver" |
118 | depends on MFD_LP8788 | 118 | depends on MFD_LP8788 |
119 | help | 119 | help |
120 | Say yes here to build support for TI LP8788 ADC. | 120 | Say yes here to build support for TI LP8788 ADC. |
diff --git a/drivers/iio/adc/exynos_adc.c b/drivers/iio/adc/exynos_adc.c index d25b262193a7..affa93f51789 100644 --- a/drivers/iio/adc/exynos_adc.c +++ b/drivers/iio/adc/exynos_adc.c | |||
@@ -344,7 +344,7 @@ static int exynos_adc_probe(struct platform_device *pdev) | |||
344 | 344 | ||
345 | exynos_adc_hw_init(info); | 345 | exynos_adc_hw_init(info); |
346 | 346 | ||
347 | ret = of_platform_populate(np, exynos_adc_match, NULL, &pdev->dev); | 347 | ret = of_platform_populate(np, exynos_adc_match, NULL, &indio_dev->dev); |
348 | if (ret < 0) { | 348 | if (ret < 0) { |
349 | dev_err(&pdev->dev, "failed adding child nodes\n"); | 349 | dev_err(&pdev->dev, "failed adding child nodes\n"); |
350 | goto err_of_populate; | 350 | goto err_of_populate; |
@@ -353,7 +353,7 @@ static int exynos_adc_probe(struct platform_device *pdev) | |||
353 | return 0; | 353 | return 0; |
354 | 354 | ||
355 | err_of_populate: | 355 | err_of_populate: |
356 | device_for_each_child(&pdev->dev, NULL, | 356 | device_for_each_child(&indio_dev->dev, NULL, |
357 | exynos_adc_remove_devices); | 357 | exynos_adc_remove_devices); |
358 | regulator_disable(info->vdd); | 358 | regulator_disable(info->vdd); |
359 | clk_disable_unprepare(info->clk); | 359 | clk_disable_unprepare(info->clk); |
@@ -369,7 +369,7 @@ static int exynos_adc_remove(struct platform_device *pdev) | |||
369 | struct iio_dev *indio_dev = platform_get_drvdata(pdev); | 369 | struct iio_dev *indio_dev = platform_get_drvdata(pdev); |
370 | struct exynos_adc *info = iio_priv(indio_dev); | 370 | struct exynos_adc *info = iio_priv(indio_dev); |
371 | 371 | ||
372 | device_for_each_child(&pdev->dev, NULL, | 372 | device_for_each_child(&indio_dev->dev, NULL, |
373 | exynos_adc_remove_devices); | 373 | exynos_adc_remove_devices); |
374 | regulator_disable(info->vdd); | 374 | regulator_disable(info->vdd); |
375 | clk_disable_unprepare(info->clk); | 375 | clk_disable_unprepare(info->clk); |
diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c index cb9f96b446a5..d8ad606c7cd0 100644 --- a/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c +++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_core.c | |||
@@ -660,6 +660,7 @@ static int inv_mpu_probe(struct i2c_client *client, | |||
660 | { | 660 | { |
661 | struct inv_mpu6050_state *st; | 661 | struct inv_mpu6050_state *st; |
662 | struct iio_dev *indio_dev; | 662 | struct iio_dev *indio_dev; |
663 | struct inv_mpu6050_platform_data *pdata; | ||
663 | int result; | 664 | int result; |
664 | 665 | ||
665 | if (!i2c_check_functionality(client->adapter, | 666 | if (!i2c_check_functionality(client->adapter, |
@@ -672,8 +673,10 @@ static int inv_mpu_probe(struct i2c_client *client, | |||
672 | 673 | ||
673 | st = iio_priv(indio_dev); | 674 | st = iio_priv(indio_dev); |
674 | st->client = client; | 675 | st->client = client; |
675 | st->plat_data = *(struct inv_mpu6050_platform_data | 676 | pdata = (struct inv_mpu6050_platform_data |
676 | *)dev_get_platdata(&client->dev); | 677 | *)dev_get_platdata(&client->dev); |
678 | if (pdata) | ||
679 | st->plat_data = *pdata; | ||
677 | /* power is turned on inside check chip type*/ | 680 | /* power is turned on inside check chip type*/ |
678 | result = inv_check_and_setup_chip(st, id); | 681 | result = inv_check_and_setup_chip(st, id); |
679 | if (result) | 682 | if (result) |
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index 2626773ff29b..2dd1d0dd4f7d 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -243,6 +243,12 @@ static void (*atkbd_platform_fixup)(struct atkbd *, const void *data); | |||
243 | static void *atkbd_platform_fixup_data; | 243 | static void *atkbd_platform_fixup_data; |
244 | static unsigned int (*atkbd_platform_scancode_fixup)(struct atkbd *, unsigned int); | 244 | static unsigned int (*atkbd_platform_scancode_fixup)(struct atkbd *, unsigned int); |
245 | 245 | ||
246 | /* | ||
247 | * Certain keyboards to not like ATKBD_CMD_RESET_DIS and stop responding | ||
248 | * to many commands until full reset (ATKBD_CMD_RESET_BAT) is performed. | ||
249 | */ | ||
250 | static bool atkbd_skip_deactivate; | ||
251 | |||
246 | static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, | 252 | static ssize_t atkbd_attr_show_helper(struct device *dev, char *buf, |
247 | ssize_t (*handler)(struct atkbd *, char *)); | 253 | ssize_t (*handler)(struct atkbd *, char *)); |
248 | static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count, | 254 | static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t count, |
@@ -768,7 +774,8 @@ static int atkbd_probe(struct atkbd *atkbd) | |||
768 | * Make sure nothing is coming from the keyboard and disturbs our | 774 | * Make sure nothing is coming from the keyboard and disturbs our |
769 | * internal state. | 775 | * internal state. |
770 | */ | 776 | */ |
771 | atkbd_deactivate(atkbd); | 777 | if (!atkbd_skip_deactivate) |
778 | atkbd_deactivate(atkbd); | ||
772 | 779 | ||
773 | return 0; | 780 | return 0; |
774 | } | 781 | } |
@@ -1638,6 +1645,12 @@ static int __init atkbd_setup_scancode_fixup(const struct dmi_system_id *id) | |||
1638 | return 1; | 1645 | return 1; |
1639 | } | 1646 | } |
1640 | 1647 | ||
1648 | static int __init atkbd_deactivate_fixup(const struct dmi_system_id *id) | ||
1649 | { | ||
1650 | atkbd_skip_deactivate = true; | ||
1651 | return 1; | ||
1652 | } | ||
1653 | |||
1641 | static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = { | 1654 | static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = { |
1642 | { | 1655 | { |
1643 | .matches = { | 1656 | .matches = { |
@@ -1775,6 +1788,20 @@ static const struct dmi_system_id atkbd_dmi_quirk_table[] __initconst = { | |||
1775 | .callback = atkbd_setup_scancode_fixup, | 1788 | .callback = atkbd_setup_scancode_fixup, |
1776 | .driver_data = atkbd_oqo_01plus_scancode_fixup, | 1789 | .driver_data = atkbd_oqo_01plus_scancode_fixup, |
1777 | }, | 1790 | }, |
1791 | { | ||
1792 | .matches = { | ||
1793 | DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"), | ||
1794 | DMI_MATCH(DMI_PRODUCT_NAME, "LW25-B7HV"), | ||
1795 | }, | ||
1796 | .callback = atkbd_deactivate_fixup, | ||
1797 | }, | ||
1798 | { | ||
1799 | .matches = { | ||
1800 | DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"), | ||
1801 | DMI_MATCH(DMI_PRODUCT_NAME, "P1-J273B"), | ||
1802 | }, | ||
1803 | .callback = atkbd_deactivate_fixup, | ||
1804 | }, | ||
1778 | { } | 1805 | { } |
1779 | }; | 1806 | }; |
1780 | 1807 | ||
diff --git a/drivers/input/keyboard/tca8418_keypad.c b/drivers/input/keyboard/tca8418_keypad.c index 55c15304ddbc..4e491c1762cf 100644 --- a/drivers/input/keyboard/tca8418_keypad.c +++ b/drivers/input/keyboard/tca8418_keypad.c | |||
@@ -392,6 +392,13 @@ static const struct of_device_id tca8418_dt_ids[] = { | |||
392 | { } | 392 | { } |
393 | }; | 393 | }; |
394 | MODULE_DEVICE_TABLE(of, tca8418_dt_ids); | 394 | MODULE_DEVICE_TABLE(of, tca8418_dt_ids); |
395 | |||
396 | /* | ||
397 | * The device tree based i2c loader looks for | ||
398 | * "i2c:" + second_component_of(property("compatible")) | ||
399 | * and therefore we need an alias to be found. | ||
400 | */ | ||
401 | MODULE_ALIAS("i2c:tca8418"); | ||
395 | #endif | 402 | #endif |
396 | 403 | ||
397 | static struct i2c_driver tca8418_keypad_driver = { | 404 | static struct i2c_driver tca8418_keypad_driver = { |
diff --git a/drivers/input/misc/bma150.c b/drivers/input/misc/bma150.c index 52d3a9b28f0b..b36831c828d3 100644 --- a/drivers/input/misc/bma150.c +++ b/drivers/input/misc/bma150.c | |||
@@ -70,6 +70,7 @@ | |||
70 | #define BMA150_CFG_5_REG 0x11 | 70 | #define BMA150_CFG_5_REG 0x11 |
71 | 71 | ||
72 | #define BMA150_CHIP_ID 2 | 72 | #define BMA150_CHIP_ID 2 |
73 | #define BMA180_CHIP_ID 3 | ||
73 | #define BMA150_CHIP_ID_REG BMA150_DATA_0_REG | 74 | #define BMA150_CHIP_ID_REG BMA150_DATA_0_REG |
74 | 75 | ||
75 | #define BMA150_ACC_X_LSB_REG BMA150_DATA_2_REG | 76 | #define BMA150_ACC_X_LSB_REG BMA150_DATA_2_REG |
@@ -539,7 +540,7 @@ static int bma150_probe(struct i2c_client *client, | |||
539 | } | 540 | } |
540 | 541 | ||
541 | chip_id = i2c_smbus_read_byte_data(client, BMA150_CHIP_ID_REG); | 542 | chip_id = i2c_smbus_read_byte_data(client, BMA150_CHIP_ID_REG); |
542 | if (chip_id != BMA150_CHIP_ID) { | 543 | if (chip_id != BMA150_CHIP_ID && chip_id != BMA180_CHIP_ID) { |
543 | dev_err(&client->dev, "BMA150 chip id error: %d\n", chip_id); | 544 | dev_err(&client->dev, "BMA150 chip id error: %d\n", chip_id); |
544 | return -EINVAL; | 545 | return -EINVAL; |
545 | } | 546 | } |
@@ -643,6 +644,7 @@ static UNIVERSAL_DEV_PM_OPS(bma150_pm, bma150_suspend, bma150_resume, NULL); | |||
643 | 644 | ||
644 | static const struct i2c_device_id bma150_id[] = { | 645 | static const struct i2c_device_id bma150_id[] = { |
645 | { "bma150", 0 }, | 646 | { "bma150", 0 }, |
647 | { "bma180", 0 }, | ||
646 | { "smb380", 0 }, | 648 | { "smb380", 0 }, |
647 | { "bma023", 0 }, | 649 | { "bma023", 0 }, |
648 | { } | 650 | { } |
diff --git a/drivers/input/mouse/elantech.c b/drivers/input/mouse/elantech.c index 088d3541c7d3..b96e978a37b7 100644 --- a/drivers/input/mouse/elantech.c +++ b/drivers/input/mouse/elantech.c | |||
@@ -11,6 +11,7 @@ | |||
11 | */ | 11 | */ |
12 | 12 | ||
13 | #include <linux/delay.h> | 13 | #include <linux/delay.h> |
14 | #include <linux/dmi.h> | ||
14 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
15 | #include <linux/module.h> | 16 | #include <linux/module.h> |
16 | #include <linux/input.h> | 17 | #include <linux/input.h> |
@@ -831,7 +832,11 @@ static int elantech_set_absolute_mode(struct psmouse *psmouse) | |||
831 | break; | 832 | break; |
832 | 833 | ||
833 | case 3: | 834 | case 3: |
834 | etd->reg_10 = 0x0b; | 835 | if (etd->set_hw_resolution) |
836 | etd->reg_10 = 0x0b; | ||
837 | else | ||
838 | etd->reg_10 = 0x03; | ||
839 | |||
835 | if (elantech_write_reg(psmouse, 0x10, etd->reg_10)) | 840 | if (elantech_write_reg(psmouse, 0x10, etd->reg_10)) |
836 | rc = -1; | 841 | rc = -1; |
837 | 842 | ||
@@ -1331,6 +1336,22 @@ static int elantech_reconnect(struct psmouse *psmouse) | |||
1331 | } | 1336 | } |
1332 | 1337 | ||
1333 | /* | 1338 | /* |
1339 | * Some hw_version 3 models go into error state when we try to set bit 3 of r10 | ||
1340 | */ | ||
1341 | static const struct dmi_system_id no_hw_res_dmi_table[] = { | ||
1342 | #if defined(CONFIG_DMI) && defined(CONFIG_X86) | ||
1343 | { | ||
1344 | /* Gigabyte U2442 */ | ||
1345 | .matches = { | ||
1346 | DMI_MATCH(DMI_SYS_VENDOR, "GIGABYTE"), | ||
1347 | DMI_MATCH(DMI_PRODUCT_NAME, "U2442"), | ||
1348 | }, | ||
1349 | }, | ||
1350 | #endif | ||
1351 | { } | ||
1352 | }; | ||
1353 | |||
1354 | /* | ||
1334 | * determine hardware version and set some properties according to it. | 1355 | * determine hardware version and set some properties according to it. |
1335 | */ | 1356 | */ |
1336 | static int elantech_set_properties(struct elantech_data *etd) | 1357 | static int elantech_set_properties(struct elantech_data *etd) |
@@ -1390,6 +1411,9 @@ static int elantech_set_properties(struct elantech_data *etd) | |||
1390 | */ | 1411 | */ |
1391 | etd->crc_enabled = ((etd->fw_version & 0x4000) == 0x4000); | 1412 | etd->crc_enabled = ((etd->fw_version & 0x4000) == 0x4000); |
1392 | 1413 | ||
1414 | /* Enable real hardware resolution on hw_version 3 ? */ | ||
1415 | etd->set_hw_resolution = !dmi_check_system(no_hw_res_dmi_table); | ||
1416 | |||
1393 | return 0; | 1417 | return 0; |
1394 | } | 1418 | } |
1395 | 1419 | ||
diff --git a/drivers/input/mouse/elantech.h b/drivers/input/mouse/elantech.h index 036a04abaef7..9e0e2a1f340d 100644 --- a/drivers/input/mouse/elantech.h +++ b/drivers/input/mouse/elantech.h | |||
@@ -130,6 +130,7 @@ struct elantech_data { | |||
130 | bool jumpy_cursor; | 130 | bool jumpy_cursor; |
131 | bool reports_pressure; | 131 | bool reports_pressure; |
132 | bool crc_enabled; | 132 | bool crc_enabled; |
133 | bool set_hw_resolution; | ||
133 | unsigned char hw_version; | 134 | unsigned char hw_version; |
134 | unsigned int fw_version; | 135 | unsigned int fw_version; |
135 | unsigned int single_finger_reports; | 136 | unsigned int single_finger_reports; |
diff --git a/drivers/input/mouse/synaptics.c b/drivers/input/mouse/synaptics.c index ef9f4913450d..d68d33fb5ac2 100644 --- a/drivers/input/mouse/synaptics.c +++ b/drivers/input/mouse/synaptics.c | |||
@@ -1566,6 +1566,14 @@ static const struct dmi_system_id min_max_dmi_table[] __initconst = { | |||
1566 | .driver_data = (int []){1232, 5710, 1156, 4696}, | 1566 | .driver_data = (int []){1232, 5710, 1156, 4696}, |
1567 | }, | 1567 | }, |
1568 | { | 1568 | { |
1569 | /* Lenovo ThinkPad Edge E431 */ | ||
1570 | .matches = { | ||
1571 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | ||
1572 | DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad Edge E431"), | ||
1573 | }, | ||
1574 | .driver_data = (int []){1024, 5022, 2508, 4832}, | ||
1575 | }, | ||
1576 | { | ||
1569 | /* Lenovo ThinkPad T431s */ | 1577 | /* Lenovo ThinkPad T431s */ |
1570 | .matches = { | 1578 | .matches = { |
1571 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), | 1579 | DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
diff --git a/drivers/irqchip/irq-sirfsoc.c b/drivers/irqchip/irq-sirfsoc.c index 581eefe331ae..5e54f6d71e77 100644 --- a/drivers/irqchip/irq-sirfsoc.c +++ b/drivers/irqchip/irq-sirfsoc.c | |||
@@ -58,7 +58,8 @@ static void __exception_irq_entry sirfsoc_handle_irq(struct pt_regs *regs) | |||
58 | handle_IRQ(irqnr, regs); | 58 | handle_IRQ(irqnr, regs); |
59 | } | 59 | } |
60 | 60 | ||
61 | static int __init sirfsoc_irq_init(struct device_node *np, struct device_node *parent) | 61 | static int __init sirfsoc_irq_init(struct device_node *np, |
62 | struct device_node *parent) | ||
62 | { | 63 | { |
63 | void __iomem *base = of_iomap(np, 0); | 64 | void __iomem *base = of_iomap(np, 0); |
64 | if (!base) | 65 | if (!base) |
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c index 51dae9167238..96d1df05044f 100644 --- a/drivers/isdn/hisax/icc.c +++ b/drivers/isdn/hisax/icc.c | |||
@@ -425,7 +425,7 @@ afterXPR: | |||
425 | if (cs->debug & L1_DEB_MONITOR) | 425 | if (cs->debug & L1_DEB_MONITOR) |
426 | debugl1(cs, "ICC %02x -> MOX1", cs->dc.icc.mon_tx[cs->dc.icc.mon_txp - 1]); | 426 | debugl1(cs, "ICC %02x -> MOX1", cs->dc.icc.mon_tx[cs->dc.icc.mon_txp - 1]); |
427 | } | 427 | } |
428 | AfterMOX1: | 428 | AfterMOX1: ; |
429 | #endif | 429 | #endif |
430 | } | 430 | } |
431 | } | 431 | } |
diff --git a/drivers/leds/Kconfig b/drivers/leds/Kconfig index 6de9dfbf61c1..39e717797cc0 100644 --- a/drivers/leds/Kconfig +++ b/drivers/leds/Kconfig | |||
@@ -487,6 +487,14 @@ config LEDS_BLINKM | |||
487 | This option enables support for the BlinkM RGB LED connected | 487 | This option enables support for the BlinkM RGB LED connected |
488 | through I2C. Say Y to enable support for the BlinkM LED. | 488 | through I2C. Say Y to enable support for the BlinkM LED. |
489 | 489 | ||
490 | config LEDS_VERSATILE | ||
491 | tristate "LED support for the ARM Versatile and RealView" | ||
492 | depends on ARCH_REALVIEW || ARCH_VERSATILE | ||
493 | depends on LEDS_CLASS | ||
494 | help | ||
495 | This option enabled support for the LEDs on the ARM Versatile | ||
496 | and RealView boards. Say Y to enabled these. | ||
497 | |||
490 | comment "LED Triggers" | 498 | comment "LED Triggers" |
491 | source "drivers/leds/trigger/Kconfig" | 499 | source "drivers/leds/trigger/Kconfig" |
492 | 500 | ||
diff --git a/drivers/leds/Makefile b/drivers/leds/Makefile index 3cd76dbd9be2..8b4c956e11ba 100644 --- a/drivers/leds/Makefile +++ b/drivers/leds/Makefile | |||
@@ -54,6 +54,7 @@ obj-$(CONFIG_LEDS_ASIC3) += leds-asic3.o | |||
54 | obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o | 54 | obj-$(CONFIG_LEDS_MAX8997) += leds-max8997.o |
55 | obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o | 55 | obj-$(CONFIG_LEDS_LM355x) += leds-lm355x.o |
56 | obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o | 56 | obj-$(CONFIG_LEDS_BLINKM) += leds-blinkm.o |
57 | obj-$(CONFIG_LEDS_VERSATILE) += leds-versatile.o | ||
57 | 58 | ||
58 | # LED SPI Drivers | 59 | # LED SPI Drivers |
59 | obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o | 60 | obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o |
diff --git a/arch/arm/plat-versatile/leds.c b/drivers/leds/leds-versatile.c index d2490d00b46c..80553022d661 100644 --- a/arch/arm/plat-versatile/leds.c +++ b/drivers/leds/leds-versatile.c | |||
@@ -7,22 +7,14 @@ | |||
7 | */ | 7 | */ |
8 | #include <linux/kernel.h> | 8 | #include <linux/kernel.h> |
9 | #include <linux/init.h> | 9 | #include <linux/init.h> |
10 | #include <linux/module.h> | ||
10 | #include <linux/io.h> | 11 | #include <linux/io.h> |
11 | #include <linux/slab.h> | 12 | #include <linux/slab.h> |
12 | #include <linux/leds.h> | 13 | #include <linux/leds.h> |
13 | 14 | #include <linux/platform_device.h> | |
14 | #include <mach/hardware.h> | ||
15 | #include <mach/platform.h> | ||
16 | |||
17 | #ifdef VERSATILE_SYS_BASE | ||
18 | #define LEDREG (__io_address(VERSATILE_SYS_BASE) + VERSATILE_SYS_LED_OFFSET) | ||
19 | #endif | ||
20 | |||
21 | #ifdef REALVIEW_SYS_BASE | ||
22 | #define LEDREG (__io_address(REALVIEW_SYS_BASE) + REALVIEW_SYS_LED_OFFSET) | ||
23 | #endif | ||
24 | 15 | ||
25 | struct versatile_led { | 16 | struct versatile_led { |
17 | void __iomem *base; | ||
26 | struct led_classdev cdev; | 18 | struct led_classdev cdev; |
27 | u8 mask; | 19 | u8 mask; |
28 | }; | 20 | }; |
@@ -50,30 +42,37 @@ static void versatile_led_set(struct led_classdev *cdev, | |||
50 | { | 42 | { |
51 | struct versatile_led *led = container_of(cdev, | 43 | struct versatile_led *led = container_of(cdev, |
52 | struct versatile_led, cdev); | 44 | struct versatile_led, cdev); |
53 | u32 reg = readl(LEDREG); | 45 | u32 reg = readl(led->base); |
54 | 46 | ||
55 | if (b != LED_OFF) | 47 | if (b != LED_OFF) |
56 | reg |= led->mask; | 48 | reg |= led->mask; |
57 | else | 49 | else |
58 | reg &= ~led->mask; | 50 | reg &= ~led->mask; |
59 | writel(reg, LEDREG); | 51 | writel(reg, led->base); |
60 | } | 52 | } |
61 | 53 | ||
62 | static enum led_brightness versatile_led_get(struct led_classdev *cdev) | 54 | static enum led_brightness versatile_led_get(struct led_classdev *cdev) |
63 | { | 55 | { |
64 | struct versatile_led *led = container_of(cdev, | 56 | struct versatile_led *led = container_of(cdev, |
65 | struct versatile_led, cdev); | 57 | struct versatile_led, cdev); |
66 | u32 reg = readl(LEDREG); | 58 | u32 reg = readl(led->base); |
67 | 59 | ||
68 | return (reg & led->mask) ? LED_FULL : LED_OFF; | 60 | return (reg & led->mask) ? LED_FULL : LED_OFF; |
69 | } | 61 | } |
70 | 62 | ||
71 | static int __init versatile_leds_init(void) | 63 | static int versatile_leds_probe(struct platform_device *dev) |
72 | { | 64 | { |
73 | int i; | 65 | int i; |
66 | struct resource *res; | ||
67 | void __iomem *base; | ||
74 | 68 | ||
75 | /* All ON */ | 69 | res = platform_get_resource(dev, IORESOURCE_MEM, 0); |
76 | writel(0xff, LEDREG); | 70 | base = devm_ioremap_resource(&dev->dev, res); |
71 | if (IS_ERR(base)) | ||
72 | return PTR_ERR(base); | ||
73 | |||
74 | /* All off */ | ||
75 | writel(0, base); | ||
77 | for (i = 0; i < ARRAY_SIZE(versatile_leds); i++) { | 76 | for (i = 0; i < ARRAY_SIZE(versatile_leds); i++) { |
78 | struct versatile_led *led; | 77 | struct versatile_led *led; |
79 | 78 | ||
@@ -81,6 +80,7 @@ static int __init versatile_leds_init(void) | |||
81 | if (!led) | 80 | if (!led) |
82 | break; | 81 | break; |
83 | 82 | ||
83 | led->base = base; | ||
84 | led->cdev.name = versatile_leds[i].name; | 84 | led->cdev.name = versatile_leds[i].name; |
85 | led->cdev.brightness_set = versatile_led_set; | 85 | led->cdev.brightness_set = versatile_led_set; |
86 | led->cdev.brightness_get = versatile_led_get; | 86 | led->cdev.brightness_get = versatile_led_get; |
@@ -96,8 +96,15 @@ static int __init versatile_leds_init(void) | |||
96 | return 0; | 96 | return 0; |
97 | } | 97 | } |
98 | 98 | ||
99 | /* | 99 | static struct platform_driver versatile_leds_driver = { |
100 | * Since we may have triggers on any subsystem, defer registration | 100 | .driver = { |
101 | * until after subsystem_init. | 101 | .name = "versatile-leds", |
102 | */ | 102 | }, |
103 | fs_initcall(versatile_leds_init); | 103 | .probe = versatile_leds_probe, |
104 | }; | ||
105 | |||
106 | module_platform_driver(versatile_leds_driver); | ||
107 | |||
108 | MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>"); | ||
109 | MODULE_DESCRIPTION("ARM Versatile LED driver"); | ||
110 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 33834120d057..f04ac62dd76b 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -1227,12 +1227,17 @@ config MCP_UCB1200_TS | |||
1227 | 1227 | ||
1228 | endmenu | 1228 | endmenu |
1229 | 1229 | ||
1230 | config VEXPRESS_CONFIG | 1230 | config MFD_VEXPRESS_SYSREG |
1231 | bool "ARM Versatile Express platform infrastructure" | 1231 | bool "Versatile Express System Registers" |
1232 | depends on ARM || ARM64 | 1232 | depends on VEXPRESS_CONFIG && GPIOLIB |
1233 | default y | ||
1234 | select CLKSRC_MMIO | ||
1235 | select GPIO_GENERIC_PLATFORM | ||
1236 | select MFD_CORE | ||
1237 | select MFD_SYSCON | ||
1233 | help | 1238 | help |
1234 | Platform configuration infrastructure for the ARM Ltd. | 1239 | System Registers are the platform configuration block |
1235 | Versatile Express. | 1240 | on the ARM Ltd. Versatile Express board. |
1236 | 1241 | ||
1237 | endmenu | 1242 | endmenu |
1238 | endif | 1243 | endif |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 2851275e2656..cec3487b539e 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -161,7 +161,7 @@ obj-$(CONFIG_MFD_RC5T583) += rc5t583.o rc5t583-irq.o | |||
161 | obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o | 161 | obj-$(CONFIG_MFD_SEC_CORE) += sec-core.o sec-irq.o |
162 | obj-$(CONFIG_MFD_SYSCON) += syscon.o | 162 | obj-$(CONFIG_MFD_SYSCON) += syscon.o |
163 | obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o | 163 | obj-$(CONFIG_MFD_LM3533) += lm3533-core.o lm3533-ctrlbank.o |
164 | obj-$(CONFIG_VEXPRESS_CONFIG) += vexpress-config.o vexpress-sysreg.o | 164 | obj-$(CONFIG_MFD_VEXPRESS_SYSREG) += vexpress-sysreg.o |
165 | obj-$(CONFIG_MFD_RETU) += retu-mfd.o | 165 | obj-$(CONFIG_MFD_RETU) += retu-mfd.o |
166 | obj-$(CONFIG_MFD_AS3711) += as3711.o | 166 | obj-$(CONFIG_MFD_AS3711) += as3711.o |
167 | obj-$(CONFIG_MFD_AS3722) += as3722.o | 167 | obj-$(CONFIG_MFD_AS3722) += as3722.o |
diff --git a/drivers/mfd/rtsx_pcr.c b/drivers/mfd/rtsx_pcr.c index c9de3d598ea5..1d15735f9ef9 100644 --- a/drivers/mfd/rtsx_pcr.c +++ b/drivers/mfd/rtsx_pcr.c | |||
@@ -338,28 +338,58 @@ int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, | |||
338 | int num_sg, bool read, int timeout) | 338 | int num_sg, bool read, int timeout) |
339 | { | 339 | { |
340 | struct completion trans_done; | 340 | struct completion trans_done; |
341 | int err = 0, count; | 341 | u8 dir; |
342 | int err = 0, i, count; | ||
342 | long timeleft; | 343 | long timeleft; |
343 | unsigned long flags; | 344 | unsigned long flags; |
345 | struct scatterlist *sg; | ||
346 | enum dma_data_direction dma_dir; | ||
347 | u32 val; | ||
348 | dma_addr_t addr; | ||
349 | unsigned int len; | ||
350 | |||
351 | dev_dbg(&(pcr->pci->dev), "--> %s: num_sg = %d\n", __func__, num_sg); | ||
352 | |||
353 | /* don't transfer data during abort processing */ | ||
354 | if (pcr->remove_pci) | ||
355 | return -EINVAL; | ||
356 | |||
357 | if ((sglist == NULL) || (num_sg <= 0)) | ||
358 | return -EINVAL; | ||
344 | 359 | ||
345 | count = rtsx_pci_dma_map_sg(pcr, sglist, num_sg, read); | 360 | if (read) { |
361 | dir = DEVICE_TO_HOST; | ||
362 | dma_dir = DMA_FROM_DEVICE; | ||
363 | } else { | ||
364 | dir = HOST_TO_DEVICE; | ||
365 | dma_dir = DMA_TO_DEVICE; | ||
366 | } | ||
367 | |||
368 | count = dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); | ||
346 | if (count < 1) { | 369 | if (count < 1) { |
347 | dev_err(&(pcr->pci->dev), "scatterlist map failed\n"); | 370 | dev_err(&(pcr->pci->dev), "scatterlist map failed\n"); |
348 | return -EINVAL; | 371 | return -EINVAL; |
349 | } | 372 | } |
350 | dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count); | 373 | dev_dbg(&(pcr->pci->dev), "DMA mapping count: %d\n", count); |
351 | 374 | ||
375 | val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; | ||
376 | pcr->sgi = 0; | ||
377 | for_each_sg(sglist, sg, count, i) { | ||
378 | addr = sg_dma_address(sg); | ||
379 | len = sg_dma_len(sg); | ||
380 | rtsx_pci_add_sg_tbl(pcr, addr, len, i == count - 1); | ||
381 | } | ||
352 | 382 | ||
353 | spin_lock_irqsave(&pcr->lock, flags); | 383 | spin_lock_irqsave(&pcr->lock, flags); |
354 | 384 | ||
355 | pcr->done = &trans_done; | 385 | pcr->done = &trans_done; |
356 | pcr->trans_result = TRANS_NOT_READY; | 386 | pcr->trans_result = TRANS_NOT_READY; |
357 | init_completion(&trans_done); | 387 | init_completion(&trans_done); |
388 | rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr); | ||
389 | rtsx_pci_writel(pcr, RTSX_HDBCTLR, val); | ||
358 | 390 | ||
359 | spin_unlock_irqrestore(&pcr->lock, flags); | 391 | spin_unlock_irqrestore(&pcr->lock, flags); |
360 | 392 | ||
361 | rtsx_pci_dma_transfer(pcr, sglist, count, read); | ||
362 | |||
363 | timeleft = wait_for_completion_interruptible_timeout( | 393 | timeleft = wait_for_completion_interruptible_timeout( |
364 | &trans_done, msecs_to_jiffies(timeout)); | 394 | &trans_done, msecs_to_jiffies(timeout)); |
365 | if (timeleft <= 0) { | 395 | if (timeleft <= 0) { |
@@ -383,7 +413,7 @@ out: | |||
383 | pcr->done = NULL; | 413 | pcr->done = NULL; |
384 | spin_unlock_irqrestore(&pcr->lock, flags); | 414 | spin_unlock_irqrestore(&pcr->lock, flags); |
385 | 415 | ||
386 | rtsx_pci_dma_unmap_sg(pcr, sglist, num_sg, read); | 416 | dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dma_dir); |
387 | 417 | ||
388 | if ((err < 0) && (err != -ENODEV)) | 418 | if ((err < 0) && (err != -ENODEV)) |
389 | rtsx_pci_stop_cmd(pcr); | 419 | rtsx_pci_stop_cmd(pcr); |
@@ -395,73 +425,6 @@ out: | |||
395 | } | 425 | } |
396 | EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data); | 426 | EXPORT_SYMBOL_GPL(rtsx_pci_transfer_data); |
397 | 427 | ||
398 | int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
399 | int num_sg, bool read) | ||
400 | { | ||
401 | enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
402 | |||
403 | if (pcr->remove_pci) | ||
404 | return -EINVAL; | ||
405 | |||
406 | if ((sglist == NULL) || num_sg < 1) | ||
407 | return -EINVAL; | ||
408 | |||
409 | return dma_map_sg(&(pcr->pci->dev), sglist, num_sg, dir); | ||
410 | } | ||
411 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_map_sg); | ||
412 | |||
413 | int rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
414 | int num_sg, bool read) | ||
415 | { | ||
416 | enum dma_data_direction dir = read ? DMA_FROM_DEVICE : DMA_TO_DEVICE; | ||
417 | |||
418 | if (pcr->remove_pci) | ||
419 | return -EINVAL; | ||
420 | |||
421 | if (sglist == NULL || num_sg < 1) | ||
422 | return -EINVAL; | ||
423 | |||
424 | dma_unmap_sg(&(pcr->pci->dev), sglist, num_sg, dir); | ||
425 | return num_sg; | ||
426 | } | ||
427 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_unmap_sg); | ||
428 | |||
429 | int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
430 | int sg_count, bool read) | ||
431 | { | ||
432 | struct scatterlist *sg; | ||
433 | dma_addr_t addr; | ||
434 | unsigned int len; | ||
435 | int i; | ||
436 | u32 val; | ||
437 | u8 dir = read ? DEVICE_TO_HOST : HOST_TO_DEVICE; | ||
438 | unsigned long flags; | ||
439 | |||
440 | if (pcr->remove_pci) | ||
441 | return -EINVAL; | ||
442 | |||
443 | if ((sglist == NULL) || (sg_count < 1)) | ||
444 | return -EINVAL; | ||
445 | |||
446 | val = ((u32)(dir & 0x01) << 29) | TRIG_DMA | ADMA_MODE; | ||
447 | pcr->sgi = 0; | ||
448 | for_each_sg(sglist, sg, sg_count, i) { | ||
449 | addr = sg_dma_address(sg); | ||
450 | len = sg_dma_len(sg); | ||
451 | rtsx_pci_add_sg_tbl(pcr, addr, len, i == sg_count - 1); | ||
452 | } | ||
453 | |||
454 | spin_lock_irqsave(&pcr->lock, flags); | ||
455 | |||
456 | rtsx_pci_writel(pcr, RTSX_HDBAR, pcr->host_sg_tbl_addr); | ||
457 | rtsx_pci_writel(pcr, RTSX_HDBCTLR, val); | ||
458 | |||
459 | spin_unlock_irqrestore(&pcr->lock, flags); | ||
460 | |||
461 | return 0; | ||
462 | } | ||
463 | EXPORT_SYMBOL_GPL(rtsx_pci_dma_transfer); | ||
464 | |||
465 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len) | 428 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len) |
466 | { | 429 | { |
467 | int err; | 430 | int err; |
@@ -873,8 +836,6 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) | |||
873 | int_reg = rtsx_pci_readl(pcr, RTSX_BIPR); | 836 | int_reg = rtsx_pci_readl(pcr, RTSX_BIPR); |
874 | /* Clear interrupt flag */ | 837 | /* Clear interrupt flag */ |
875 | rtsx_pci_writel(pcr, RTSX_BIPR, int_reg); | 838 | rtsx_pci_writel(pcr, RTSX_BIPR, int_reg); |
876 | dev_dbg(&pcr->pci->dev, "=========== BIPR 0x%8x ==========\n", int_reg); | ||
877 | |||
878 | if ((int_reg & pcr->bier) == 0) { | 839 | if ((int_reg & pcr->bier) == 0) { |
879 | spin_unlock(&pcr->lock); | 840 | spin_unlock(&pcr->lock); |
880 | return IRQ_NONE; | 841 | return IRQ_NONE; |
@@ -905,28 +866,17 @@ static irqreturn_t rtsx_pci_isr(int irq, void *dev_id) | |||
905 | } | 866 | } |
906 | 867 | ||
907 | if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) { | 868 | if (int_reg & (NEED_COMPLETE_INT | DELINK_INT)) { |
908 | if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) | 869 | if (int_reg & (TRANS_FAIL_INT | DELINK_INT)) { |
909 | pcr->trans_result = TRANS_RESULT_FAIL; | 870 | pcr->trans_result = TRANS_RESULT_FAIL; |
910 | else if (int_reg & TRANS_OK_INT) | 871 | if (pcr->done) |
872 | complete(pcr->done); | ||
873 | } else if (int_reg & TRANS_OK_INT) { | ||
911 | pcr->trans_result = TRANS_RESULT_OK; | 874 | pcr->trans_result = TRANS_RESULT_OK; |
912 | 875 | if (pcr->done) | |
913 | if (pcr->done) | 876 | complete(pcr->done); |
914 | complete(pcr->done); | ||
915 | |||
916 | if (int_reg & SD_EXIST) { | ||
917 | struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD]; | ||
918 | if (slot && slot->done_transfer) | ||
919 | slot->done_transfer(slot->p_dev); | ||
920 | } | ||
921 | |||
922 | if (int_reg & MS_EXIST) { | ||
923 | struct rtsx_slot *slot = &pcr->slots[RTSX_SD_CARD]; | ||
924 | if (slot && slot->done_transfer) | ||
925 | slot->done_transfer(slot->p_dev); | ||
926 | } | 877 | } |
927 | } | 878 | } |
928 | 879 | ||
929 | |||
930 | if (pcr->card_inserted || pcr->card_removed) | 880 | if (pcr->card_inserted || pcr->card_removed) |
931 | schedule_delayed_work(&pcr->carddet_work, | 881 | schedule_delayed_work(&pcr->carddet_work, |
932 | msecs_to_jiffies(200)); | 882 | msecs_to_jiffies(200)); |
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c index dbea55de4397..e2a04bb8bc1e 100644 --- a/drivers/mfd/syscon.c +++ b/drivers/mfd/syscon.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include <linux/of.h> | 18 | #include <linux/of.h> |
19 | #include <linux/of_address.h> | 19 | #include <linux/of_address.h> |
20 | #include <linux/of_platform.h> | 20 | #include <linux/of_platform.h> |
21 | #include <linux/platform_data/syscon.h> | ||
21 | #include <linux/platform_device.h> | 22 | #include <linux/platform_device.h> |
22 | #include <linux/regmap.h> | 23 | #include <linux/regmap.h> |
23 | #include <linux/mfd/syscon.h> | 24 | #include <linux/mfd/syscon.h> |
@@ -119,6 +120,7 @@ static struct regmap_config syscon_regmap_config = { | |||
119 | static int syscon_probe(struct platform_device *pdev) | 120 | static int syscon_probe(struct platform_device *pdev) |
120 | { | 121 | { |
121 | struct device *dev = &pdev->dev; | 122 | struct device *dev = &pdev->dev; |
123 | struct syscon_platform_data *pdata = dev_get_platdata(dev); | ||
122 | struct syscon *syscon; | 124 | struct syscon *syscon; |
123 | struct resource *res; | 125 | struct resource *res; |
124 | void __iomem *base; | 126 | void __iomem *base; |
@@ -136,6 +138,8 @@ static int syscon_probe(struct platform_device *pdev) | |||
136 | return -ENOMEM; | 138 | return -ENOMEM; |
137 | 139 | ||
138 | syscon_regmap_config.max_register = res->end - res->start - 3; | 140 | syscon_regmap_config.max_register = res->end - res->start - 3; |
141 | if (pdata) | ||
142 | syscon_regmap_config.name = pdata->label; | ||
139 | syscon->regmap = devm_regmap_init_mmio(dev, base, | 143 | syscon->regmap = devm_regmap_init_mmio(dev, base, |
140 | &syscon_regmap_config); | 144 | &syscon_regmap_config); |
141 | if (IS_ERR(syscon->regmap)) { | 145 | if (IS_ERR(syscon->regmap)) { |
diff --git a/drivers/mfd/vexpress-config.c b/drivers/mfd/vexpress-config.c deleted file mode 100644 index d0db89d13e01..000000000000 --- a/drivers/mfd/vexpress-config.c +++ /dev/null | |||
@@ -1,287 +0,0 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License version 2 as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * Copyright (C) 2012 ARM Limited | ||
12 | */ | ||
13 | |||
14 | #define pr_fmt(fmt) "vexpress-config: " fmt | ||
15 | |||
16 | #include <linux/bitops.h> | ||
17 | #include <linux/completion.h> | ||
18 | #include <linux/export.h> | ||
19 | #include <linux/list.h> | ||
20 | #include <linux/of.h> | ||
21 | #include <linux/of_device.h> | ||
22 | #include <linux/slab.h> | ||
23 | #include <linux/string.h> | ||
24 | #include <linux/vexpress.h> | ||
25 | |||
26 | |||
27 | #define VEXPRESS_CONFIG_MAX_BRIDGES 2 | ||
28 | |||
29 | static struct vexpress_config_bridge { | ||
30 | struct device_node *node; | ||
31 | struct vexpress_config_bridge_info *info; | ||
32 | struct list_head transactions; | ||
33 | spinlock_t transactions_lock; | ||
34 | } vexpress_config_bridges[VEXPRESS_CONFIG_MAX_BRIDGES]; | ||
35 | |||
36 | static DECLARE_BITMAP(vexpress_config_bridges_map, | ||
37 | ARRAY_SIZE(vexpress_config_bridges)); | ||
38 | static DEFINE_MUTEX(vexpress_config_bridges_mutex); | ||
39 | |||
40 | struct vexpress_config_bridge *vexpress_config_bridge_register( | ||
41 | struct device_node *node, | ||
42 | struct vexpress_config_bridge_info *info) | ||
43 | { | ||
44 | struct vexpress_config_bridge *bridge; | ||
45 | int i; | ||
46 | |||
47 | pr_debug("Registering bridge '%s'\n", info->name); | ||
48 | |||
49 | mutex_lock(&vexpress_config_bridges_mutex); | ||
50 | i = find_first_zero_bit(vexpress_config_bridges_map, | ||
51 | ARRAY_SIZE(vexpress_config_bridges)); | ||
52 | if (i >= ARRAY_SIZE(vexpress_config_bridges)) { | ||
53 | pr_err("Can't register more bridges!\n"); | ||
54 | mutex_unlock(&vexpress_config_bridges_mutex); | ||
55 | return NULL; | ||
56 | } | ||
57 | __set_bit(i, vexpress_config_bridges_map); | ||
58 | bridge = &vexpress_config_bridges[i]; | ||
59 | |||
60 | bridge->node = node; | ||
61 | bridge->info = info; | ||
62 | INIT_LIST_HEAD(&bridge->transactions); | ||
63 | spin_lock_init(&bridge->transactions_lock); | ||
64 | |||
65 | mutex_unlock(&vexpress_config_bridges_mutex); | ||
66 | |||
67 | return bridge; | ||
68 | } | ||
69 | EXPORT_SYMBOL(vexpress_config_bridge_register); | ||
70 | |||
71 | void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge) | ||
72 | { | ||
73 | struct vexpress_config_bridge __bridge = *bridge; | ||
74 | int i; | ||
75 | |||
76 | mutex_lock(&vexpress_config_bridges_mutex); | ||
77 | for (i = 0; i < ARRAY_SIZE(vexpress_config_bridges); i++) | ||
78 | if (&vexpress_config_bridges[i] == bridge) | ||
79 | __clear_bit(i, vexpress_config_bridges_map); | ||
80 | mutex_unlock(&vexpress_config_bridges_mutex); | ||
81 | |||
82 | WARN_ON(!list_empty(&__bridge.transactions)); | ||
83 | while (!list_empty(&__bridge.transactions)) | ||
84 | cpu_relax(); | ||
85 | } | ||
86 | EXPORT_SYMBOL(vexpress_config_bridge_unregister); | ||
87 | |||
88 | |||
89 | struct vexpress_config_func { | ||
90 | struct vexpress_config_bridge *bridge; | ||
91 | void *func; | ||
92 | }; | ||
93 | |||
94 | struct vexpress_config_func *__vexpress_config_func_get(struct device *dev, | ||
95 | struct device_node *node) | ||
96 | { | ||
97 | struct device_node *bridge_node; | ||
98 | struct vexpress_config_func *func; | ||
99 | int i; | ||
100 | |||
101 | if (WARN_ON(dev && node && dev->of_node != node)) | ||
102 | return NULL; | ||
103 | if (dev && !node) | ||
104 | node = dev->of_node; | ||
105 | |||
106 | func = kzalloc(sizeof(*func), GFP_KERNEL); | ||
107 | if (!func) | ||
108 | return NULL; | ||
109 | |||
110 | bridge_node = of_node_get(node); | ||
111 | while (bridge_node) { | ||
112 | const __be32 *prop = of_get_property(bridge_node, | ||
113 | "arm,vexpress,config-bridge", NULL); | ||
114 | |||
115 | if (prop) { | ||
116 | bridge_node = of_find_node_by_phandle( | ||
117 | be32_to_cpup(prop)); | ||
118 | break; | ||
119 | } | ||
120 | |||
121 | bridge_node = of_get_next_parent(bridge_node); | ||
122 | } | ||
123 | |||
124 | mutex_lock(&vexpress_config_bridges_mutex); | ||
125 | for (i = 0; i < ARRAY_SIZE(vexpress_config_bridges); i++) { | ||
126 | struct vexpress_config_bridge *bridge = | ||
127 | &vexpress_config_bridges[i]; | ||
128 | |||
129 | if (test_bit(i, vexpress_config_bridges_map) && | ||
130 | bridge->node == bridge_node) { | ||
131 | func->bridge = bridge; | ||
132 | func->func = bridge->info->func_get(dev, node); | ||
133 | break; | ||
134 | } | ||
135 | } | ||
136 | mutex_unlock(&vexpress_config_bridges_mutex); | ||
137 | |||
138 | if (!func->func) { | ||
139 | of_node_put(node); | ||
140 | kfree(func); | ||
141 | return NULL; | ||
142 | } | ||
143 | |||
144 | return func; | ||
145 | } | ||
146 | EXPORT_SYMBOL(__vexpress_config_func_get); | ||
147 | |||
148 | void vexpress_config_func_put(struct vexpress_config_func *func) | ||
149 | { | ||
150 | func->bridge->info->func_put(func->func); | ||
151 | of_node_put(func->bridge->node); | ||
152 | kfree(func); | ||
153 | } | ||
154 | EXPORT_SYMBOL(vexpress_config_func_put); | ||
155 | |||
156 | struct vexpress_config_trans { | ||
157 | struct vexpress_config_func *func; | ||
158 | int offset; | ||
159 | bool write; | ||
160 | u32 *data; | ||
161 | int status; | ||
162 | struct completion completion; | ||
163 | struct list_head list; | ||
164 | }; | ||
165 | |||
166 | static void vexpress_config_dump_trans(const char *what, | ||
167 | struct vexpress_config_trans *trans) | ||
168 | { | ||
169 | pr_debug("%s %s trans %p func 0x%p offset %d data 0x%x status %d\n", | ||
170 | what, trans->write ? "write" : "read", trans, | ||
171 | trans->func->func, trans->offset, | ||
172 | trans->data ? *trans->data : 0, trans->status); | ||
173 | } | ||
174 | |||
175 | static int vexpress_config_schedule(struct vexpress_config_trans *trans) | ||
176 | { | ||
177 | int status; | ||
178 | struct vexpress_config_bridge *bridge = trans->func->bridge; | ||
179 | unsigned long flags; | ||
180 | |||
181 | init_completion(&trans->completion); | ||
182 | trans->status = -EFAULT; | ||
183 | |||
184 | spin_lock_irqsave(&bridge->transactions_lock, flags); | ||
185 | |||
186 | if (list_empty(&bridge->transactions)) { | ||
187 | vexpress_config_dump_trans("Executing", trans); | ||
188 | status = bridge->info->func_exec(trans->func->func, | ||
189 | trans->offset, trans->write, trans->data); | ||
190 | } else { | ||
191 | vexpress_config_dump_trans("Queuing", trans); | ||
192 | status = VEXPRESS_CONFIG_STATUS_WAIT; | ||
193 | } | ||
194 | |||
195 | switch (status) { | ||
196 | case VEXPRESS_CONFIG_STATUS_DONE: | ||
197 | vexpress_config_dump_trans("Finished", trans); | ||
198 | trans->status = status; | ||
199 | break; | ||
200 | case VEXPRESS_CONFIG_STATUS_WAIT: | ||
201 | list_add_tail(&trans->list, &bridge->transactions); | ||
202 | break; | ||
203 | } | ||
204 | |||
205 | spin_unlock_irqrestore(&bridge->transactions_lock, flags); | ||
206 | |||
207 | return status; | ||
208 | } | ||
209 | |||
210 | void vexpress_config_complete(struct vexpress_config_bridge *bridge, | ||
211 | int status) | ||
212 | { | ||
213 | struct vexpress_config_trans *trans; | ||
214 | unsigned long flags; | ||
215 | const char *message = "Completed"; | ||
216 | |||
217 | spin_lock_irqsave(&bridge->transactions_lock, flags); | ||
218 | |||
219 | trans = list_first_entry(&bridge->transactions, | ||
220 | struct vexpress_config_trans, list); | ||
221 | trans->status = status; | ||
222 | |||
223 | do { | ||
224 | vexpress_config_dump_trans(message, trans); | ||
225 | list_del(&trans->list); | ||
226 | complete(&trans->completion); | ||
227 | |||
228 | if (list_empty(&bridge->transactions)) | ||
229 | break; | ||
230 | |||
231 | trans = list_first_entry(&bridge->transactions, | ||
232 | struct vexpress_config_trans, list); | ||
233 | vexpress_config_dump_trans("Executing pending", trans); | ||
234 | trans->status = bridge->info->func_exec(trans->func->func, | ||
235 | trans->offset, trans->write, trans->data); | ||
236 | message = "Finished pending"; | ||
237 | } while (trans->status == VEXPRESS_CONFIG_STATUS_DONE); | ||
238 | |||
239 | spin_unlock_irqrestore(&bridge->transactions_lock, flags); | ||
240 | } | ||
241 | EXPORT_SYMBOL(vexpress_config_complete); | ||
242 | |||
243 | int vexpress_config_wait(struct vexpress_config_trans *trans) | ||
244 | { | ||
245 | wait_for_completion(&trans->completion); | ||
246 | |||
247 | return trans->status; | ||
248 | } | ||
249 | EXPORT_SYMBOL(vexpress_config_wait); | ||
250 | |||
251 | int vexpress_config_read(struct vexpress_config_func *func, int offset, | ||
252 | u32 *data) | ||
253 | { | ||
254 | struct vexpress_config_trans trans = { | ||
255 | .func = func, | ||
256 | .offset = offset, | ||
257 | .write = false, | ||
258 | .data = data, | ||
259 | .status = 0, | ||
260 | }; | ||
261 | int status = vexpress_config_schedule(&trans); | ||
262 | |||
263 | if (status == VEXPRESS_CONFIG_STATUS_WAIT) | ||
264 | status = vexpress_config_wait(&trans); | ||
265 | |||
266 | return status; | ||
267 | } | ||
268 | EXPORT_SYMBOL(vexpress_config_read); | ||
269 | |||
270 | int vexpress_config_write(struct vexpress_config_func *func, int offset, | ||
271 | u32 data) | ||
272 | { | ||
273 | struct vexpress_config_trans trans = { | ||
274 | .func = func, | ||
275 | .offset = offset, | ||
276 | .write = true, | ||
277 | .data = &data, | ||
278 | .status = 0, | ||
279 | }; | ||
280 | int status = vexpress_config_schedule(&trans); | ||
281 | |||
282 | if (status == VEXPRESS_CONFIG_STATUS_WAIT) | ||
283 | status = vexpress_config_wait(&trans); | ||
284 | |||
285 | return status; | ||
286 | } | ||
287 | EXPORT_SYMBOL(vexpress_config_write); | ||
diff --git a/drivers/mfd/vexpress-sysreg.c b/drivers/mfd/vexpress-sysreg.c index 35281e804e7e..9e21e4fc9599 100644 --- a/drivers/mfd/vexpress-sysreg.c +++ b/drivers/mfd/vexpress-sysreg.c | |||
@@ -11,23 +11,22 @@ | |||
11 | * Copyright (C) 2012 ARM Limited | 11 | * Copyright (C) 2012 ARM Limited |
12 | */ | 12 | */ |
13 | 13 | ||
14 | #include <linux/basic_mmio_gpio.h> | ||
14 | #include <linux/err.h> | 15 | #include <linux/err.h> |
15 | #include <linux/gpio.h> | ||
16 | #include <linux/io.h> | 16 | #include <linux/io.h> |
17 | #include <linux/leds.h> | 17 | #include <linux/mfd/core.h> |
18 | #include <linux/of_address.h> | 18 | #include <linux/of_address.h> |
19 | #include <linux/of_platform.h> | ||
20 | #include <linux/platform_data/syscon.h> | ||
19 | #include <linux/platform_device.h> | 21 | #include <linux/platform_device.h> |
20 | #include <linux/regulator/driver.h> | ||
21 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
22 | #include <linux/stat.h> | 23 | #include <linux/stat.h> |
23 | #include <linux/timer.h> | ||
24 | #include <linux/vexpress.h> | 24 | #include <linux/vexpress.h> |
25 | 25 | ||
26 | #define SYS_ID 0x000 | 26 | #define SYS_ID 0x000 |
27 | #define SYS_SW 0x004 | 27 | #define SYS_SW 0x004 |
28 | #define SYS_LED 0x008 | 28 | #define SYS_LED 0x008 |
29 | #define SYS_100HZ 0x024 | 29 | #define SYS_100HZ 0x024 |
30 | #define SYS_FLAGS 0x030 | ||
31 | #define SYS_FLAGSSET 0x030 | 30 | #define SYS_FLAGSSET 0x030 |
32 | #define SYS_FLAGSCLR 0x034 | 31 | #define SYS_FLAGSCLR 0x034 |
33 | #define SYS_NVFLAGS 0x038 | 32 | #define SYS_NVFLAGS 0x038 |
@@ -46,465 +45,209 @@ | |||
46 | #define SYS_CFGSTAT 0x0a8 | 45 | #define SYS_CFGSTAT 0x0a8 |
47 | 46 | ||
48 | #define SYS_HBI_MASK 0xfff | 47 | #define SYS_HBI_MASK 0xfff |
49 | #define SYS_ID_HBI_SHIFT 16 | ||
50 | #define SYS_PROCIDx_HBI_SHIFT 0 | 48 | #define SYS_PROCIDx_HBI_SHIFT 0 |
51 | 49 | ||
52 | #define SYS_LED_LED(n) (1 << (n)) | ||
53 | |||
54 | #define SYS_MCI_CARDIN (1 << 0) | 50 | #define SYS_MCI_CARDIN (1 << 0) |
55 | #define SYS_MCI_WPROT (1 << 1) | 51 | #define SYS_MCI_WPROT (1 << 1) |
56 | 52 | ||
57 | #define SYS_FLASH_WPn (1 << 0) | ||
58 | |||
59 | #define SYS_MISC_MASTERSITE (1 << 14) | 53 | #define SYS_MISC_MASTERSITE (1 << 14) |
60 | 54 | ||
61 | #define SYS_CFGCTRL_START (1 << 31) | ||
62 | #define SYS_CFGCTRL_WRITE (1 << 30) | ||
63 | #define SYS_CFGCTRL_DCC(n) (((n) & 0xf) << 26) | ||
64 | #define SYS_CFGCTRL_FUNC(n) (((n) & 0x3f) << 20) | ||
65 | #define SYS_CFGCTRL_SITE(n) (((n) & 0x3) << 16) | ||
66 | #define SYS_CFGCTRL_POSITION(n) (((n) & 0xf) << 12) | ||
67 | #define SYS_CFGCTRL_DEVICE(n) (((n) & 0xfff) << 0) | ||
68 | |||
69 | #define SYS_CFGSTAT_ERR (1 << 1) | ||
70 | #define SYS_CFGSTAT_COMPLETE (1 << 0) | ||
71 | |||
72 | |||
73 | static void __iomem *vexpress_sysreg_base; | ||
74 | static struct device *vexpress_sysreg_dev; | ||
75 | static int vexpress_master_site; | ||
76 | |||
77 | 55 | ||
78 | void vexpress_flags_set(u32 data) | 56 | static void __iomem *__vexpress_sysreg_base; |
79 | { | ||
80 | writel(~0, vexpress_sysreg_base + SYS_FLAGSCLR); | ||
81 | writel(data, vexpress_sysreg_base + SYS_FLAGSSET); | ||
82 | } | ||
83 | 57 | ||
84 | u32 vexpress_get_procid(int site) | 58 | static void __iomem *vexpress_sysreg_base(void) |
85 | { | 59 | { |
86 | if (site == VEXPRESS_SITE_MASTER) | 60 | if (!__vexpress_sysreg_base) { |
87 | site = vexpress_master_site; | 61 | struct device_node *node = of_find_compatible_node(NULL, NULL, |
88 | 62 | "arm,vexpress-sysreg"); | |
89 | return readl(vexpress_sysreg_base + (site == VEXPRESS_SITE_DB1 ? | ||
90 | SYS_PROCID0 : SYS_PROCID1)); | ||
91 | } | ||
92 | 63 | ||
93 | u32 vexpress_get_hbi(int site) | 64 | __vexpress_sysreg_base = of_iomap(node, 0); |
94 | { | ||
95 | u32 id; | ||
96 | |||
97 | switch (site) { | ||
98 | case VEXPRESS_SITE_MB: | ||
99 | id = readl(vexpress_sysreg_base + SYS_ID); | ||
100 | return (id >> SYS_ID_HBI_SHIFT) & SYS_HBI_MASK; | ||
101 | case VEXPRESS_SITE_MASTER: | ||
102 | case VEXPRESS_SITE_DB1: | ||
103 | case VEXPRESS_SITE_DB2: | ||
104 | id = vexpress_get_procid(site); | ||
105 | return (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK; | ||
106 | } | 65 | } |
107 | 66 | ||
108 | return ~0; | 67 | WARN_ON(!__vexpress_sysreg_base); |
109 | } | ||
110 | 68 | ||
111 | void __iomem *vexpress_get_24mhz_clock_base(void) | 69 | return __vexpress_sysreg_base; |
112 | { | ||
113 | return vexpress_sysreg_base + SYS_24MHZ; | ||
114 | } | 70 | } |
115 | 71 | ||
116 | 72 | ||
117 | static void vexpress_sysreg_find_prop(struct device_node *node, | 73 | static int vexpress_sysreg_get_master(void) |
118 | const char *name, u32 *val) | ||
119 | { | 74 | { |
120 | of_node_get(node); | 75 | if (readl(vexpress_sysreg_base() + SYS_MISC) & SYS_MISC_MASTERSITE) |
121 | while (node) { | 76 | return VEXPRESS_SITE_DB2; |
122 | if (of_property_read_u32(node, name, val) == 0) { | ||
123 | of_node_put(node); | ||
124 | return; | ||
125 | } | ||
126 | node = of_get_next_parent(node); | ||
127 | } | ||
128 | } | ||
129 | |||
130 | unsigned __vexpress_get_site(struct device *dev, struct device_node *node) | ||
131 | { | ||
132 | u32 site = 0; | ||
133 | |||
134 | WARN_ON(dev && node && dev->of_node != node); | ||
135 | if (dev && !node) | ||
136 | node = dev->of_node; | ||
137 | |||
138 | if (node) { | ||
139 | vexpress_sysreg_find_prop(node, "arm,vexpress,site", &site); | ||
140 | } else if (dev && dev->bus == &platform_bus_type) { | ||
141 | struct platform_device *pdev = to_platform_device(dev); | ||
142 | |||
143 | if (pdev->num_resources == 1 && | ||
144 | pdev->resource[0].flags == IORESOURCE_BUS) | ||
145 | site = pdev->resource[0].start; | ||
146 | } else if (dev && strncmp(dev_name(dev), "ct:", 3) == 0) { | ||
147 | site = VEXPRESS_SITE_MASTER; | ||
148 | } | ||
149 | 77 | ||
150 | if (site == VEXPRESS_SITE_MASTER) | 78 | return VEXPRESS_SITE_DB1; |
151 | site = vexpress_master_site; | ||
152 | |||
153 | return site; | ||
154 | } | 79 | } |
155 | 80 | ||
156 | 81 | void vexpress_flags_set(u32 data) | |
157 | struct vexpress_sysreg_config_func { | ||
158 | u32 template; | ||
159 | u32 device; | ||
160 | }; | ||
161 | |||
162 | static struct vexpress_config_bridge *vexpress_sysreg_config_bridge; | ||
163 | static struct timer_list vexpress_sysreg_config_timer; | ||
164 | static u32 *vexpress_sysreg_config_data; | ||
165 | static int vexpress_sysreg_config_tries; | ||
166 | |||
167 | static void *vexpress_sysreg_config_func_get(struct device *dev, | ||
168 | struct device_node *node) | ||
169 | { | 82 | { |
170 | struct vexpress_sysreg_config_func *config_func; | 83 | writel(~0, vexpress_sysreg_base() + SYS_FLAGSCLR); |
171 | u32 site = 0; | 84 | writel(data, vexpress_sysreg_base() + SYS_FLAGSSET); |
172 | u32 position = 0; | ||
173 | u32 dcc = 0; | ||
174 | u32 func_device[2]; | ||
175 | int err = -EFAULT; | ||
176 | |||
177 | if (node) { | ||
178 | of_node_get(node); | ||
179 | vexpress_sysreg_find_prop(node, "arm,vexpress,site", &site); | ||
180 | vexpress_sysreg_find_prop(node, "arm,vexpress,position", | ||
181 | &position); | ||
182 | vexpress_sysreg_find_prop(node, "arm,vexpress,dcc", &dcc); | ||
183 | err = of_property_read_u32_array(node, | ||
184 | "arm,vexpress-sysreg,func", func_device, | ||
185 | ARRAY_SIZE(func_device)); | ||
186 | of_node_put(node); | ||
187 | } else if (dev && dev->bus == &platform_bus_type) { | ||
188 | struct platform_device *pdev = to_platform_device(dev); | ||
189 | |||
190 | if (pdev->num_resources == 1 && | ||
191 | pdev->resource[0].flags == IORESOURCE_BUS) { | ||
192 | site = pdev->resource[0].start; | ||
193 | func_device[0] = pdev->resource[0].end; | ||
194 | func_device[1] = pdev->id; | ||
195 | err = 0; | ||
196 | } | ||
197 | } | ||
198 | if (err) | ||
199 | return NULL; | ||
200 | |||
201 | config_func = kzalloc(sizeof(*config_func), GFP_KERNEL); | ||
202 | if (!config_func) | ||
203 | return NULL; | ||
204 | |||
205 | config_func->template = SYS_CFGCTRL_DCC(dcc); | ||
206 | config_func->template |= SYS_CFGCTRL_FUNC(func_device[0]); | ||
207 | config_func->template |= SYS_CFGCTRL_SITE(site == VEXPRESS_SITE_MASTER ? | ||
208 | vexpress_master_site : site); | ||
209 | config_func->template |= SYS_CFGCTRL_POSITION(position); | ||
210 | config_func->device |= func_device[1]; | ||
211 | |||
212 | dev_dbg(vexpress_sysreg_dev, "func 0x%p = 0x%x, %d\n", config_func, | ||
213 | config_func->template, config_func->device); | ||
214 | |||
215 | return config_func; | ||
216 | } | 85 | } |
217 | 86 | ||
218 | static void vexpress_sysreg_config_func_put(void *func) | 87 | unsigned int vexpress_get_mci_cardin(struct device *dev) |
219 | { | 88 | { |
220 | kfree(func); | 89 | return readl(vexpress_sysreg_base() + SYS_MCI) & SYS_MCI_CARDIN; |
221 | } | 90 | } |
222 | 91 | ||
223 | static int vexpress_sysreg_config_func_exec(void *func, int offset, | 92 | u32 vexpress_get_procid(int site) |
224 | bool write, u32 *data) | ||
225 | { | 93 | { |
226 | int status; | 94 | if (site == VEXPRESS_SITE_MASTER) |
227 | struct vexpress_sysreg_config_func *config_func = func; | 95 | site = vexpress_sysreg_get_master(); |
228 | u32 command; | ||
229 | |||
230 | if (WARN_ON(!vexpress_sysreg_base)) | ||
231 | return -ENOENT; | ||
232 | |||
233 | command = readl(vexpress_sysreg_base + SYS_CFGCTRL); | ||
234 | if (WARN_ON(command & SYS_CFGCTRL_START)) | ||
235 | return -EBUSY; | ||
236 | |||
237 | command = SYS_CFGCTRL_START; | ||
238 | command |= write ? SYS_CFGCTRL_WRITE : 0; | ||
239 | command |= config_func->template; | ||
240 | command |= SYS_CFGCTRL_DEVICE(config_func->device + offset); | ||
241 | |||
242 | /* Use a canary for reads */ | ||
243 | if (!write) | ||
244 | *data = 0xdeadbeef; | ||
245 | |||
246 | dev_dbg(vexpress_sysreg_dev, "command %x, data %x\n", | ||
247 | command, *data); | ||
248 | writel(*data, vexpress_sysreg_base + SYS_CFGDATA); | ||
249 | writel(0, vexpress_sysreg_base + SYS_CFGSTAT); | ||
250 | writel(command, vexpress_sysreg_base + SYS_CFGCTRL); | ||
251 | mb(); | ||
252 | |||
253 | if (vexpress_sysreg_dev) { | ||
254 | /* Schedule completion check */ | ||
255 | if (!write) | ||
256 | vexpress_sysreg_config_data = data; | ||
257 | vexpress_sysreg_config_tries = 100; | ||
258 | mod_timer(&vexpress_sysreg_config_timer, | ||
259 | jiffies + usecs_to_jiffies(100)); | ||
260 | status = VEXPRESS_CONFIG_STATUS_WAIT; | ||
261 | } else { | ||
262 | /* Early execution, no timer available, have to spin */ | ||
263 | u32 cfgstat; | ||
264 | |||
265 | do { | ||
266 | cpu_relax(); | ||
267 | cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT); | ||
268 | } while (!cfgstat); | ||
269 | |||
270 | if (!write && (cfgstat & SYS_CFGSTAT_COMPLETE)) | ||
271 | *data = readl(vexpress_sysreg_base + SYS_CFGDATA); | ||
272 | status = VEXPRESS_CONFIG_STATUS_DONE; | ||
273 | |||
274 | if (cfgstat & SYS_CFGSTAT_ERR) | ||
275 | status = -EINVAL; | ||
276 | } | ||
277 | 96 | ||
278 | return status; | 97 | return readl(vexpress_sysreg_base() + (site == VEXPRESS_SITE_DB1 ? |
98 | SYS_PROCID0 : SYS_PROCID1)); | ||
279 | } | 99 | } |
280 | 100 | ||
281 | struct vexpress_config_bridge_info vexpress_sysreg_config_bridge_info = { | 101 | void __iomem *vexpress_get_24mhz_clock_base(void) |
282 | .name = "vexpress-sysreg", | ||
283 | .func_get = vexpress_sysreg_config_func_get, | ||
284 | .func_put = vexpress_sysreg_config_func_put, | ||
285 | .func_exec = vexpress_sysreg_config_func_exec, | ||
286 | }; | ||
287 | |||
288 | static void vexpress_sysreg_config_complete(unsigned long data) | ||
289 | { | 102 | { |
290 | int status = VEXPRESS_CONFIG_STATUS_DONE; | 103 | return vexpress_sysreg_base() + SYS_24MHZ; |
291 | u32 cfgstat = readl(vexpress_sysreg_base + SYS_CFGSTAT); | ||
292 | |||
293 | if (cfgstat & SYS_CFGSTAT_ERR) | ||
294 | status = -EINVAL; | ||
295 | if (!vexpress_sysreg_config_tries--) | ||
296 | status = -ETIMEDOUT; | ||
297 | |||
298 | if (status < 0) { | ||
299 | dev_err(vexpress_sysreg_dev, "error %d\n", status); | ||
300 | } else if (!(cfgstat & SYS_CFGSTAT_COMPLETE)) { | ||
301 | mod_timer(&vexpress_sysreg_config_timer, | ||
302 | jiffies + usecs_to_jiffies(50)); | ||
303 | return; | ||
304 | } | ||
305 | |||
306 | if (vexpress_sysreg_config_data) { | ||
307 | *vexpress_sysreg_config_data = readl(vexpress_sysreg_base + | ||
308 | SYS_CFGDATA); | ||
309 | dev_dbg(vexpress_sysreg_dev, "read data %x\n", | ||
310 | *vexpress_sysreg_config_data); | ||
311 | vexpress_sysreg_config_data = NULL; | ||
312 | } | ||
313 | |||
314 | vexpress_config_complete(vexpress_sysreg_config_bridge, status); | ||
315 | } | 104 | } |
316 | 105 | ||
317 | 106 | ||
318 | void vexpress_sysreg_setup(struct device_node *node) | ||
319 | { | ||
320 | if (WARN_ON(!vexpress_sysreg_base)) | ||
321 | return; | ||
322 | |||
323 | if (readl(vexpress_sysreg_base + SYS_MISC) & SYS_MISC_MASTERSITE) | ||
324 | vexpress_master_site = VEXPRESS_SITE_DB2; | ||
325 | else | ||
326 | vexpress_master_site = VEXPRESS_SITE_DB1; | ||
327 | |||
328 | vexpress_sysreg_config_bridge = vexpress_config_bridge_register( | ||
329 | node, &vexpress_sysreg_config_bridge_info); | ||
330 | WARN_ON(!vexpress_sysreg_config_bridge); | ||
331 | } | ||
332 | |||
333 | void __init vexpress_sysreg_early_init(void __iomem *base) | 107 | void __init vexpress_sysreg_early_init(void __iomem *base) |
334 | { | 108 | { |
335 | vexpress_sysreg_base = base; | 109 | __vexpress_sysreg_base = base; |
336 | vexpress_sysreg_setup(NULL); | ||
337 | } | ||
338 | |||
339 | void __init vexpress_sysreg_of_early_init(void) | ||
340 | { | ||
341 | struct device_node *node; | ||
342 | |||
343 | if (vexpress_sysreg_base) | ||
344 | return; | ||
345 | 110 | ||
346 | node = of_find_compatible_node(NULL, NULL, "arm,vexpress-sysreg"); | 111 | vexpress_config_set_master(vexpress_sysreg_get_master()); |
347 | if (node) { | ||
348 | vexpress_sysreg_base = of_iomap(node, 0); | ||
349 | vexpress_sysreg_setup(node); | ||
350 | } | ||
351 | } | 112 | } |
352 | 113 | ||
353 | 114 | ||
354 | #ifdef CONFIG_GPIOLIB | 115 | /* The sysreg block is just a random collection of various functions... */ |
355 | |||
356 | #define VEXPRESS_SYSREG_GPIO(_name, _reg, _value) \ | ||
357 | [VEXPRESS_GPIO_##_name] = { \ | ||
358 | .reg = _reg, \ | ||
359 | .value = _reg##_##_value, \ | ||
360 | } | ||
361 | 116 | ||
362 | static struct vexpress_sysreg_gpio { | 117 | static struct syscon_platform_data vexpress_sysreg_sys_id_pdata = { |
363 | unsigned long reg; | 118 | .label = "sys_id", |
364 | u32 value; | ||
365 | } vexpress_sysreg_gpios[] = { | ||
366 | VEXPRESS_SYSREG_GPIO(MMC_CARDIN, SYS_MCI, CARDIN), | ||
367 | VEXPRESS_SYSREG_GPIO(MMC_WPROT, SYS_MCI, WPROT), | ||
368 | VEXPRESS_SYSREG_GPIO(FLASH_WPn, SYS_FLASH, WPn), | ||
369 | VEXPRESS_SYSREG_GPIO(LED0, SYS_LED, LED(0)), | ||
370 | VEXPRESS_SYSREG_GPIO(LED1, SYS_LED, LED(1)), | ||
371 | VEXPRESS_SYSREG_GPIO(LED2, SYS_LED, LED(2)), | ||
372 | VEXPRESS_SYSREG_GPIO(LED3, SYS_LED, LED(3)), | ||
373 | VEXPRESS_SYSREG_GPIO(LED4, SYS_LED, LED(4)), | ||
374 | VEXPRESS_SYSREG_GPIO(LED5, SYS_LED, LED(5)), | ||
375 | VEXPRESS_SYSREG_GPIO(LED6, SYS_LED, LED(6)), | ||
376 | VEXPRESS_SYSREG_GPIO(LED7, SYS_LED, LED(7)), | ||
377 | }; | 119 | }; |
378 | 120 | ||
379 | static int vexpress_sysreg_gpio_direction_input(struct gpio_chip *chip, | 121 | static struct bgpio_pdata vexpress_sysreg_sys_led_pdata = { |
380 | unsigned offset) | 122 | .label = "sys_led", |
381 | { | 123 | .base = -1, |
382 | return 0; | 124 | .ngpio = 8, |
383 | } | ||
384 | |||
385 | static int vexpress_sysreg_gpio_get(struct gpio_chip *chip, | ||
386 | unsigned offset) | ||
387 | { | ||
388 | struct vexpress_sysreg_gpio *gpio = &vexpress_sysreg_gpios[offset]; | ||
389 | u32 reg_value = readl(vexpress_sysreg_base + gpio->reg); | ||
390 | |||
391 | return !!(reg_value & gpio->value); | ||
392 | } | ||
393 | |||
394 | static void vexpress_sysreg_gpio_set(struct gpio_chip *chip, | ||
395 | unsigned offset, int value) | ||
396 | { | ||
397 | struct vexpress_sysreg_gpio *gpio = &vexpress_sysreg_gpios[offset]; | ||
398 | u32 reg_value = readl(vexpress_sysreg_base + gpio->reg); | ||
399 | |||
400 | if (value) | ||
401 | reg_value |= gpio->value; | ||
402 | else | ||
403 | reg_value &= ~gpio->value; | ||
404 | |||
405 | writel(reg_value, vexpress_sysreg_base + gpio->reg); | ||
406 | } | ||
407 | |||
408 | static int vexpress_sysreg_gpio_direction_output(struct gpio_chip *chip, | ||
409 | unsigned offset, int value) | ||
410 | { | ||
411 | vexpress_sysreg_gpio_set(chip, offset, value); | ||
412 | |||
413 | return 0; | ||
414 | } | ||
415 | |||
416 | static struct gpio_chip vexpress_sysreg_gpio_chip = { | ||
417 | .label = "vexpress-sysreg", | ||
418 | .direction_input = vexpress_sysreg_gpio_direction_input, | ||
419 | .direction_output = vexpress_sysreg_gpio_direction_output, | ||
420 | .get = vexpress_sysreg_gpio_get, | ||
421 | .set = vexpress_sysreg_gpio_set, | ||
422 | .ngpio = ARRAY_SIZE(vexpress_sysreg_gpios), | ||
423 | .base = 0, | ||
424 | }; | 125 | }; |
425 | 126 | ||
426 | 127 | static struct bgpio_pdata vexpress_sysreg_sys_mci_pdata = { | |
427 | #define VEXPRESS_SYSREG_GREEN_LED(_name, _default_trigger, _gpio) \ | 128 | .label = "sys_mci", |
428 | { \ | 129 | .base = -1, |
429 | .name = "v2m:green:"_name, \ | 130 | .ngpio = 2, |
430 | .default_trigger = _default_trigger, \ | ||
431 | .gpio = VEXPRESS_GPIO_##_gpio, \ | ||
432 | } | ||
433 | |||
434 | struct gpio_led vexpress_sysreg_leds[] = { | ||
435 | VEXPRESS_SYSREG_GREEN_LED("user1", "heartbeat", LED0), | ||
436 | VEXPRESS_SYSREG_GREEN_LED("user2", "mmc0", LED1), | ||
437 | VEXPRESS_SYSREG_GREEN_LED("user3", "cpu0", LED2), | ||
438 | VEXPRESS_SYSREG_GREEN_LED("user4", "cpu1", LED3), | ||
439 | VEXPRESS_SYSREG_GREEN_LED("user5", "cpu2", LED4), | ||
440 | VEXPRESS_SYSREG_GREEN_LED("user6", "cpu3", LED5), | ||
441 | VEXPRESS_SYSREG_GREEN_LED("user7", "cpu4", LED6), | ||
442 | VEXPRESS_SYSREG_GREEN_LED("user8", "cpu5", LED7), | ||
443 | }; | 131 | }; |
444 | 132 | ||
445 | struct gpio_led_platform_data vexpress_sysreg_leds_pdata = { | 133 | static struct bgpio_pdata vexpress_sysreg_sys_flash_pdata = { |
446 | .num_leds = ARRAY_SIZE(vexpress_sysreg_leds), | 134 | .label = "sys_flash", |
447 | .leds = vexpress_sysreg_leds, | 135 | .base = -1, |
136 | .ngpio = 1, | ||
448 | }; | 137 | }; |
449 | 138 | ||
450 | #endif | 139 | static struct syscon_platform_data vexpress_sysreg_sys_misc_pdata = { |
451 | 140 | .label = "sys_misc", | |
141 | }; | ||
452 | 142 | ||
453 | static ssize_t vexpress_sysreg_sys_id_show(struct device *dev, | 143 | static struct syscon_platform_data vexpress_sysreg_sys_procid_pdata = { |
454 | struct device_attribute *attr, char *buf) | 144 | .label = "sys_procid", |
455 | { | 145 | }; |
456 | return sprintf(buf, "0x%08x\n", readl(vexpress_sysreg_base + SYS_ID)); | ||
457 | } | ||
458 | 146 | ||
459 | DEVICE_ATTR(sys_id, S_IRUGO, vexpress_sysreg_sys_id_show, NULL); | 147 | static struct mfd_cell vexpress_sysreg_cells[] = { |
148 | { | ||
149 | .name = "syscon", | ||
150 | .num_resources = 1, | ||
151 | .resources = (struct resource []) { | ||
152 | DEFINE_RES_MEM(SYS_ID, 0x4), | ||
153 | }, | ||
154 | .platform_data = &vexpress_sysreg_sys_id_pdata, | ||
155 | .pdata_size = sizeof(vexpress_sysreg_sys_id_pdata), | ||
156 | }, { | ||
157 | .name = "basic-mmio-gpio", | ||
158 | .of_compatible = "arm,vexpress-sysreg,sys_led", | ||
159 | .num_resources = 1, | ||
160 | .resources = (struct resource []) { | ||
161 | DEFINE_RES_MEM_NAMED(SYS_LED, 0x4, "dat"), | ||
162 | }, | ||
163 | .platform_data = &vexpress_sysreg_sys_led_pdata, | ||
164 | .pdata_size = sizeof(vexpress_sysreg_sys_led_pdata), | ||
165 | }, { | ||
166 | .name = "basic-mmio-gpio", | ||
167 | .of_compatible = "arm,vexpress-sysreg,sys_mci", | ||
168 | .num_resources = 1, | ||
169 | .resources = (struct resource []) { | ||
170 | DEFINE_RES_MEM_NAMED(SYS_MCI, 0x4, "dat"), | ||
171 | }, | ||
172 | .platform_data = &vexpress_sysreg_sys_mci_pdata, | ||
173 | .pdata_size = sizeof(vexpress_sysreg_sys_mci_pdata), | ||
174 | }, { | ||
175 | .name = "basic-mmio-gpio", | ||
176 | .of_compatible = "arm,vexpress-sysreg,sys_flash", | ||
177 | .num_resources = 1, | ||
178 | .resources = (struct resource []) { | ||
179 | DEFINE_RES_MEM_NAMED(SYS_FLASH, 0x4, "dat"), | ||
180 | }, | ||
181 | .platform_data = &vexpress_sysreg_sys_flash_pdata, | ||
182 | .pdata_size = sizeof(vexpress_sysreg_sys_flash_pdata), | ||
183 | }, { | ||
184 | .name = "syscon", | ||
185 | .num_resources = 1, | ||
186 | .resources = (struct resource []) { | ||
187 | DEFINE_RES_MEM(SYS_MISC, 0x4), | ||
188 | }, | ||
189 | .platform_data = &vexpress_sysreg_sys_misc_pdata, | ||
190 | .pdata_size = sizeof(vexpress_sysreg_sys_misc_pdata), | ||
191 | }, { | ||
192 | .name = "syscon", | ||
193 | .num_resources = 1, | ||
194 | .resources = (struct resource []) { | ||
195 | DEFINE_RES_MEM(SYS_PROCID0, 0x8), | ||
196 | }, | ||
197 | .platform_data = &vexpress_sysreg_sys_procid_pdata, | ||
198 | .pdata_size = sizeof(vexpress_sysreg_sys_procid_pdata), | ||
199 | }, { | ||
200 | .name = "vexpress-syscfg", | ||
201 | .num_resources = 1, | ||
202 | .resources = (struct resource []) { | ||
203 | DEFINE_RES_MEM(SYS_CFGDATA, 0xc), | ||
204 | }, | ||
205 | } | ||
206 | }; | ||
460 | 207 | ||
461 | static int vexpress_sysreg_probe(struct platform_device *pdev) | 208 | static int vexpress_sysreg_probe(struct platform_device *pdev) |
462 | { | 209 | { |
463 | int err; | 210 | struct resource *mem; |
464 | struct resource *res = platform_get_resource(pdev, | 211 | void __iomem *base; |
465 | IORESOURCE_MEM, 0); | 212 | struct bgpio_chip *mmc_gpio_chip; |
466 | 213 | u32 dt_hbi; | |
467 | if (!devm_request_mem_region(&pdev->dev, res->start, | ||
468 | resource_size(res), pdev->name)) { | ||
469 | dev_err(&pdev->dev, "Failed to request memory region!\n"); | ||
470 | return -EBUSY; | ||
471 | } | ||
472 | 214 | ||
473 | if (!vexpress_sysreg_base) { | 215 | mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
474 | vexpress_sysreg_base = devm_ioremap(&pdev->dev, res->start, | 216 | if (!mem) |
475 | resource_size(res)); | 217 | return -EINVAL; |
476 | vexpress_sysreg_setup(pdev->dev.of_node); | ||
477 | } | ||
478 | 218 | ||
479 | if (!vexpress_sysreg_base) { | 219 | base = devm_ioremap(&pdev->dev, mem->start, resource_size(mem)); |
480 | dev_err(&pdev->dev, "Failed to obtain base address!\n"); | 220 | if (!base) |
481 | return -EFAULT; | 221 | return -ENOMEM; |
482 | } | ||
483 | 222 | ||
484 | setup_timer(&vexpress_sysreg_config_timer, | 223 | vexpress_config_set_master(vexpress_sysreg_get_master()); |
485 | vexpress_sysreg_config_complete, 0); | ||
486 | 224 | ||
487 | vexpress_sysreg_dev = &pdev->dev; | 225 | /* Confirm board type against DT property, if available */ |
226 | if (of_property_read_u32(of_allnodes, "arm,hbi", &dt_hbi) == 0) { | ||
227 | u32 id = vexpress_get_procid(VEXPRESS_SITE_MASTER); | ||
228 | u32 hbi = (id >> SYS_PROCIDx_HBI_SHIFT) & SYS_HBI_MASK; | ||
488 | 229 | ||
489 | #ifdef CONFIG_GPIOLIB | 230 | if (WARN_ON(dt_hbi != hbi)) |
490 | vexpress_sysreg_gpio_chip.dev = &pdev->dev; | 231 | dev_warn(&pdev->dev, "DT HBI (%x) is not matching hardware (%x)!\n", |
491 | err = gpiochip_add(&vexpress_sysreg_gpio_chip); | 232 | dt_hbi, hbi); |
492 | if (err) { | ||
493 | vexpress_config_bridge_unregister( | ||
494 | vexpress_sysreg_config_bridge); | ||
495 | dev_err(&pdev->dev, "Failed to register GPIO chip! (%d)\n", | ||
496 | err); | ||
497 | return err; | ||
498 | } | 233 | } |
499 | 234 | ||
500 | platform_device_register_data(vexpress_sysreg_dev, "leds-gpio", | 235 | /* |
501 | PLATFORM_DEVID_AUTO, &vexpress_sysreg_leds_pdata, | 236 | * Duplicated SYS_MCI pseudo-GPIO controller for compatibility with |
502 | sizeof(vexpress_sysreg_leds_pdata)); | 237 | * older trees using sysreg node for MMC control lines. |
503 | #endif | 238 | */ |
504 | 239 | mmc_gpio_chip = devm_kzalloc(&pdev->dev, sizeof(*mmc_gpio_chip), | |
505 | device_create_file(vexpress_sysreg_dev, &dev_attr_sys_id); | 240 | GFP_KERNEL); |
506 | 241 | if (!mmc_gpio_chip) | |
507 | return 0; | 242 | return -ENOMEM; |
243 | bgpio_init(mmc_gpio_chip, &pdev->dev, 0x4, base + SYS_MCI, | ||
244 | NULL, NULL, NULL, NULL, 0); | ||
245 | mmc_gpio_chip->gc.ngpio = 2; | ||
246 | gpiochip_add(&mmc_gpio_chip->gc); | ||
247 | |||
248 | return mfd_add_devices(&pdev->dev, PLATFORM_DEVID_AUTO, | ||
249 | vexpress_sysreg_cells, | ||
250 | ARRAY_SIZE(vexpress_sysreg_cells), mem, 0, NULL); | ||
508 | } | 251 | } |
509 | 252 | ||
510 | static const struct of_device_id vexpress_sysreg_match[] = { | 253 | static const struct of_device_id vexpress_sysreg_match[] = { |
@@ -522,7 +265,12 @@ static struct platform_driver vexpress_sysreg_driver = { | |||
522 | 265 | ||
523 | static int __init vexpress_sysreg_init(void) | 266 | static int __init vexpress_sysreg_init(void) |
524 | { | 267 | { |
525 | vexpress_sysreg_of_early_init(); | 268 | struct device_node *node; |
269 | |||
270 | /* Need the sysreg early, before any other device... */ | ||
271 | for_each_matching_node(node, vexpress_sysreg_match) | ||
272 | of_platform_device_create(node, NULL, NULL); | ||
273 | |||
526 | return platform_driver_register(&vexpress_sysreg_driver); | 274 | return platform_driver_register(&vexpress_sysreg_driver); |
527 | } | 275 | } |
528 | core_initcall(vexpress_sysreg_init); | 276 | core_initcall(vexpress_sysreg_init); |
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 8baff0effc7d..d9663ef90ce8 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig | |||
@@ -515,6 +515,15 @@ config SRAM | |||
515 | the genalloc API. It is supposed to be used for small on-chip SRAM | 515 | the genalloc API. It is supposed to be used for small on-chip SRAM |
516 | areas found on many SoCs. | 516 | areas found on many SoCs. |
517 | 517 | ||
518 | config VEXPRESS_SYSCFG | ||
519 | bool "Versatile Express System Configuration driver" | ||
520 | depends on VEXPRESS_CONFIG | ||
521 | default y | ||
522 | help | ||
523 | ARM Ltd. Versatile Express uses specialised platform configuration | ||
524 | bus. System Configuration interface is one of the possible means | ||
525 | of generating transactions on this bus. | ||
526 | |||
518 | source "drivers/misc/c2port/Kconfig" | 527 | source "drivers/misc/c2port/Kconfig" |
519 | source "drivers/misc/eeprom/Kconfig" | 528 | source "drivers/misc/eeprom/Kconfig" |
520 | source "drivers/misc/cb710/Kconfig" | 529 | source "drivers/misc/cb710/Kconfig" |
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 7eb4b69580c0..d59ce1261b38 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile | |||
@@ -55,3 +55,4 @@ obj-$(CONFIG_SRAM) += sram.o | |||
55 | obj-y += mic/ | 55 | obj-y += mic/ |
56 | obj-$(CONFIG_GENWQE) += genwqe/ | 56 | obj-$(CONFIG_GENWQE) += genwqe/ |
57 | obj-$(CONFIG_ECHO) += echo/ | 57 | obj-$(CONFIG_ECHO) += echo/ |
58 | obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o | ||
diff --git a/drivers/misc/vexpress-syscfg.c b/drivers/misc/vexpress-syscfg.c new file mode 100644 index 000000000000..73068e50e56d --- /dev/null +++ b/drivers/misc/vexpress-syscfg.c | |||
@@ -0,0 +1,324 @@ | |||
1 | /* | ||
2 | * This program is free software; you can redistribute it and/or modify | ||
3 | * it under the terms of the GNU General Public License version 2 as | ||
4 | * published by the Free Software Foundation. | ||
5 | * | ||
6 | * This program is distributed in the hope that it will be useful, | ||
7 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
8 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
9 | * GNU General Public License for more details. | ||
10 | * | ||
11 | * Copyright (C) 2014 ARM Limited | ||
12 | */ | ||
13 | |||
14 | #include <linux/delay.h> | ||
15 | #include <linux/err.h> | ||
16 | #include <linux/io.h> | ||
17 | #include <linux/of.h> | ||
18 | #include <linux/platform_device.h> | ||
19 | #include <linux/sched.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <linux/syscore_ops.h> | ||
22 | #include <linux/vexpress.h> | ||
23 | |||
24 | |||
25 | #define SYS_CFGDATA 0x0 | ||
26 | |||
27 | #define SYS_CFGCTRL 0x4 | ||
28 | #define SYS_CFGCTRL_START (1 << 31) | ||
29 | #define SYS_CFGCTRL_WRITE (1 << 30) | ||
30 | #define SYS_CFGCTRL_DCC(n) (((n) & 0xf) << 26) | ||
31 | #define SYS_CFGCTRL_FUNC(n) (((n) & 0x3f) << 20) | ||
32 | #define SYS_CFGCTRL_SITE(n) (((n) & 0x3) << 16) | ||
33 | #define SYS_CFGCTRL_POSITION(n) (((n) & 0xf) << 12) | ||
34 | #define SYS_CFGCTRL_DEVICE(n) (((n) & 0xfff) << 0) | ||
35 | |||
36 | #define SYS_CFGSTAT 0x8 | ||
37 | #define SYS_CFGSTAT_ERR (1 << 1) | ||
38 | #define SYS_CFGSTAT_COMPLETE (1 << 0) | ||
39 | |||
40 | |||
41 | struct vexpress_syscfg { | ||
42 | struct device *dev; | ||
43 | void __iomem *base; | ||
44 | struct list_head funcs; | ||
45 | }; | ||
46 | |||
47 | struct vexpress_syscfg_func { | ||
48 | struct list_head list; | ||
49 | struct vexpress_syscfg *syscfg; | ||
50 | struct regmap *regmap; | ||
51 | int num_templates; | ||
52 | u32 template[0]; /* Keep it last! */ | ||
53 | }; | ||
54 | |||
55 | |||
56 | static int vexpress_syscfg_exec(struct vexpress_syscfg_func *func, | ||
57 | int index, bool write, u32 *data) | ||
58 | { | ||
59 | struct vexpress_syscfg *syscfg = func->syscfg; | ||
60 | u32 command, status; | ||
61 | int tries; | ||
62 | long timeout; | ||
63 | |||
64 | if (WARN_ON(index > func->num_templates)) | ||
65 | return -EINVAL; | ||
66 | |||
67 | command = readl(syscfg->base + SYS_CFGCTRL); | ||
68 | if (WARN_ON(command & SYS_CFGCTRL_START)) | ||
69 | return -EBUSY; | ||
70 | |||
71 | command = func->template[index]; | ||
72 | command |= SYS_CFGCTRL_START; | ||
73 | command |= write ? SYS_CFGCTRL_WRITE : 0; | ||
74 | |||
75 | /* Use a canary for reads */ | ||
76 | if (!write) | ||
77 | *data = 0xdeadbeef; | ||
78 | |||
79 | dev_dbg(syscfg->dev, "func %p, command %x, data %x\n", | ||
80 | func, command, *data); | ||
81 | writel(*data, syscfg->base + SYS_CFGDATA); | ||
82 | writel(0, syscfg->base + SYS_CFGSTAT); | ||
83 | writel(command, syscfg->base + SYS_CFGCTRL); | ||
84 | mb(); | ||
85 | |||
86 | /* The operation can take ages... Go to sleep, 100us initially */ | ||
87 | tries = 100; | ||
88 | timeout = 100; | ||
89 | do { | ||
90 | if (!irqs_disabled()) { | ||
91 | set_current_state(TASK_INTERRUPTIBLE); | ||
92 | schedule_timeout(usecs_to_jiffies(timeout)); | ||
93 | if (signal_pending(current)) | ||
94 | return -EINTR; | ||
95 | } else { | ||
96 | udelay(timeout); | ||
97 | } | ||
98 | |||
99 | status = readl(syscfg->base + SYS_CFGSTAT); | ||
100 | if (status & SYS_CFGSTAT_ERR) | ||
101 | return -EFAULT; | ||
102 | |||
103 | if (timeout > 20) | ||
104 | timeout -= 20; | ||
105 | } while (--tries && !(status & SYS_CFGSTAT_COMPLETE)); | ||
106 | if (WARN_ON_ONCE(!tries)) | ||
107 | return -ETIMEDOUT; | ||
108 | |||
109 | if (!write) { | ||
110 | *data = readl(syscfg->base + SYS_CFGDATA); | ||
111 | dev_dbg(syscfg->dev, "func %p, read data %x\n", func, *data); | ||
112 | } | ||
113 | |||
114 | return 0; | ||
115 | } | ||
116 | |||
117 | static int vexpress_syscfg_read(void *context, unsigned int index, | ||
118 | unsigned int *val) | ||
119 | { | ||
120 | struct vexpress_syscfg_func *func = context; | ||
121 | |||
122 | return vexpress_syscfg_exec(func, index, false, val); | ||
123 | } | ||
124 | |||
125 | static int vexpress_syscfg_write(void *context, unsigned int index, | ||
126 | unsigned int val) | ||
127 | { | ||
128 | struct vexpress_syscfg_func *func = context; | ||
129 | |||
130 | return vexpress_syscfg_exec(func, index, true, &val); | ||
131 | } | ||
132 | |||
133 | struct regmap_config vexpress_syscfg_regmap_config = { | ||
134 | .lock = vexpress_config_lock, | ||
135 | .unlock = vexpress_config_unlock, | ||
136 | .reg_bits = 32, | ||
137 | .val_bits = 32, | ||
138 | .reg_read = vexpress_syscfg_read, | ||
139 | .reg_write = vexpress_syscfg_write, | ||
140 | .reg_format_endian = REGMAP_ENDIAN_LITTLE, | ||
141 | .val_format_endian = REGMAP_ENDIAN_LITTLE, | ||
142 | }; | ||
143 | |||
144 | |||
145 | static struct regmap *vexpress_syscfg_regmap_init(struct device *dev, | ||
146 | void *context) | ||
147 | { | ||
148 | struct platform_device *pdev = to_platform_device(dev); | ||
149 | struct vexpress_syscfg *syscfg = context; | ||
150 | struct vexpress_syscfg_func *func; | ||
151 | struct property *prop; | ||
152 | const __be32 *val = NULL; | ||
153 | __be32 energy_quirk[4]; | ||
154 | int num; | ||
155 | u32 site, position, dcc; | ||
156 | int i; | ||
157 | |||
158 | if (dev->of_node) { | ||
159 | int err = vexpress_config_get_topo(dev->of_node, &site, | ||
160 | &position, &dcc); | ||
161 | |||
162 | if (err) | ||
163 | return ERR_PTR(err); | ||
164 | |||
165 | prop = of_find_property(dev->of_node, | ||
166 | "arm,vexpress-sysreg,func", NULL); | ||
167 | if (!prop) | ||
168 | return ERR_PTR(-EINVAL); | ||
169 | |||
170 | num = prop->length / sizeof(u32) / 2; | ||
171 | val = prop->value; | ||
172 | } else { | ||
173 | if (pdev->num_resources != 1 || | ||
174 | pdev->resource[0].flags != IORESOURCE_BUS) | ||
175 | return ERR_PTR(-EFAULT); | ||
176 | |||
177 | site = pdev->resource[0].start; | ||
178 | if (site == VEXPRESS_SITE_MASTER) | ||
179 | site = vexpress_config_get_master(); | ||
180 | position = 0; | ||
181 | dcc = 0; | ||
182 | num = 1; | ||
183 | } | ||
184 | |||
185 | /* | ||
186 | * "arm,vexpress-energy" function used to be described | ||
187 | * by its first device only, now it requires both | ||
188 | */ | ||
189 | if (num == 1 && of_device_is_compatible(dev->of_node, | ||
190 | "arm,vexpress-energy")) { | ||
191 | num = 2; | ||
192 | energy_quirk[0] = *val; | ||
193 | energy_quirk[2] = *val++; | ||
194 | energy_quirk[1] = *val; | ||
195 | energy_quirk[3] = cpu_to_be32(be32_to_cpup(val) + 1); | ||
196 | val = energy_quirk; | ||
197 | } | ||
198 | |||
199 | func = kzalloc(sizeof(*func) + sizeof(*func->template) * num, | ||
200 | GFP_KERNEL); | ||
201 | if (!func) | ||
202 | return NULL; | ||
203 | |||
204 | func->syscfg = syscfg; | ||
205 | func->num_templates = num; | ||
206 | |||
207 | for (i = 0; i < num; i++) { | ||
208 | u32 function, device; | ||
209 | |||
210 | if (dev->of_node) { | ||
211 | function = be32_to_cpup(val++); | ||
212 | device = be32_to_cpup(val++); | ||
213 | } else { | ||
214 | function = pdev->resource[0].end; | ||
215 | device = pdev->id; | ||
216 | } | ||
217 | |||
218 | dev_dbg(dev, "func %p: %u/%u/%u/%u/%u\n", | ||
219 | func, site, position, dcc, | ||
220 | function, device); | ||
221 | |||
222 | func->template[i] = SYS_CFGCTRL_DCC(dcc); | ||
223 | func->template[i] |= SYS_CFGCTRL_SITE(site); | ||
224 | func->template[i] |= SYS_CFGCTRL_POSITION(position); | ||
225 | func->template[i] |= SYS_CFGCTRL_FUNC(function); | ||
226 | func->template[i] |= SYS_CFGCTRL_DEVICE(device); | ||
227 | } | ||
228 | |||
229 | vexpress_syscfg_regmap_config.max_register = num - 1; | ||
230 | |||
231 | func->regmap = regmap_init(dev, NULL, func, | ||
232 | &vexpress_syscfg_regmap_config); | ||
233 | |||
234 | if (IS_ERR(func->regmap)) | ||
235 | kfree(func); | ||
236 | else | ||
237 | list_add(&func->list, &syscfg->funcs); | ||
238 | |||
239 | return func->regmap; | ||
240 | } | ||
241 | |||
242 | static void vexpress_syscfg_regmap_exit(struct regmap *regmap, void *context) | ||
243 | { | ||
244 | struct vexpress_syscfg *syscfg = context; | ||
245 | struct vexpress_syscfg_func *func, *tmp; | ||
246 | |||
247 | regmap_exit(regmap); | ||
248 | |||
249 | list_for_each_entry_safe(func, tmp, &syscfg->funcs, list) { | ||
250 | if (func->regmap == regmap) { | ||
251 | list_del(&syscfg->funcs); | ||
252 | kfree(func); | ||
253 | break; | ||
254 | } | ||
255 | } | ||
256 | } | ||
257 | |||
258 | static struct vexpress_config_bridge_ops vexpress_syscfg_bridge_ops = { | ||
259 | .regmap_init = vexpress_syscfg_regmap_init, | ||
260 | .regmap_exit = vexpress_syscfg_regmap_exit, | ||
261 | }; | ||
262 | |||
263 | |||
264 | /* Non-DT hack, to be gone... */ | ||
265 | static struct device *vexpress_syscfg_bridge; | ||
266 | |||
267 | int vexpress_syscfg_device_register(struct platform_device *pdev) | ||
268 | { | ||
269 | pdev->dev.parent = vexpress_syscfg_bridge; | ||
270 | |||
271 | return platform_device_register(pdev); | ||
272 | } | ||
273 | |||
274 | |||
275 | int vexpress_syscfg_probe(struct platform_device *pdev) | ||
276 | { | ||
277 | struct vexpress_syscfg *syscfg; | ||
278 | struct resource *res; | ||
279 | struct device *bridge; | ||
280 | |||
281 | syscfg = devm_kzalloc(&pdev->dev, sizeof(*syscfg), GFP_KERNEL); | ||
282 | if (!syscfg) | ||
283 | return -ENOMEM; | ||
284 | syscfg->dev = &pdev->dev; | ||
285 | INIT_LIST_HEAD(&syscfg->funcs); | ||
286 | |||
287 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | ||
288 | if (!devm_request_mem_region(&pdev->dev, res->start, | ||
289 | resource_size(res), pdev->name)) | ||
290 | return -EBUSY; | ||
291 | |||
292 | syscfg->base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); | ||
293 | if (!syscfg->base) | ||
294 | return -EFAULT; | ||
295 | |||
296 | /* Must use dev.parent (MFD), as that's where DT phandle points at... */ | ||
297 | bridge = vexpress_config_bridge_register(pdev->dev.parent, | ||
298 | &vexpress_syscfg_bridge_ops, syscfg); | ||
299 | if (IS_ERR(bridge)) | ||
300 | return PTR_ERR(bridge); | ||
301 | |||
302 | /* Non-DT case */ | ||
303 | if (!pdev->dev.of_node) | ||
304 | vexpress_syscfg_bridge = bridge; | ||
305 | |||
306 | return 0; | ||
307 | } | ||
308 | |||
309 | static const struct platform_device_id vexpress_syscfg_id_table[] = { | ||
310 | { "vexpress-syscfg", }, | ||
311 | {}, | ||
312 | }; | ||
313 | |||
314 | static struct platform_driver vexpress_syscfg_driver = { | ||
315 | .driver.name = "vexpress-syscfg", | ||
316 | .id_table = vexpress_syscfg_id_table, | ||
317 | .probe = vexpress_syscfg_probe, | ||
318 | }; | ||
319 | |||
320 | static int __init vexpress_syscfg_init(void) | ||
321 | { | ||
322 | return platform_driver_register(&vexpress_syscfg_driver); | ||
323 | } | ||
324 | core_initcall(vexpress_syscfg_init); | ||
diff --git a/drivers/mmc/host/rtsx_pci_sdmmc.c b/drivers/mmc/host/rtsx_pci_sdmmc.c index 5fb994f9a653..0b9ded13a3ae 100644 --- a/drivers/mmc/host/rtsx_pci_sdmmc.c +++ b/drivers/mmc/host/rtsx_pci_sdmmc.c | |||
@@ -31,28 +31,14 @@ | |||
31 | #include <linux/mfd/rtsx_pci.h> | 31 | #include <linux/mfd/rtsx_pci.h> |
32 | #include <asm/unaligned.h> | 32 | #include <asm/unaligned.h> |
33 | 33 | ||
34 | struct realtek_next { | ||
35 | unsigned int sg_count; | ||
36 | s32 cookie; | ||
37 | }; | ||
38 | |||
39 | struct realtek_pci_sdmmc { | 34 | struct realtek_pci_sdmmc { |
40 | struct platform_device *pdev; | 35 | struct platform_device *pdev; |
41 | struct rtsx_pcr *pcr; | 36 | struct rtsx_pcr *pcr; |
42 | struct mmc_host *mmc; | 37 | struct mmc_host *mmc; |
43 | struct mmc_request *mrq; | 38 | struct mmc_request *mrq; |
44 | struct mmc_command *cmd; | 39 | |
45 | struct mmc_data *data; | 40 | struct mutex host_mutex; |
46 | 41 | ||
47 | spinlock_t lock; | ||
48 | struct timer_list timer; | ||
49 | struct tasklet_struct cmd_tasklet; | ||
50 | struct tasklet_struct data_tasklet; | ||
51 | struct tasklet_struct finish_tasklet; | ||
52 | |||
53 | u8 rsp_type; | ||
54 | u8 rsp_len; | ||
55 | int sg_count; | ||
56 | u8 ssc_depth; | 42 | u8 ssc_depth; |
57 | unsigned int clock; | 43 | unsigned int clock; |
58 | bool vpclk; | 44 | bool vpclk; |
@@ -62,13 +48,8 @@ struct realtek_pci_sdmmc { | |||
62 | int power_state; | 48 | int power_state; |
63 | #define SDMMC_POWER_ON 1 | 49 | #define SDMMC_POWER_ON 1 |
64 | #define SDMMC_POWER_OFF 0 | 50 | #define SDMMC_POWER_OFF 0 |
65 | |||
66 | struct realtek_next next_data; | ||
67 | }; | 51 | }; |
68 | 52 | ||
69 | static int sd_start_multi_rw(struct realtek_pci_sdmmc *host, | ||
70 | struct mmc_request *mrq); | ||
71 | |||
72 | static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host) | 53 | static inline struct device *sdmmc_dev(struct realtek_pci_sdmmc *host) |
73 | { | 54 | { |
74 | return &(host->pdev->dev); | 55 | return &(host->pdev->dev); |
@@ -105,95 +86,6 @@ static void sd_print_debug_regs(struct realtek_pci_sdmmc *host) | |||
105 | #define sd_print_debug_regs(host) | 86 | #define sd_print_debug_regs(host) |
106 | #endif /* DEBUG */ | 87 | #endif /* DEBUG */ |
107 | 88 | ||
108 | static void sd_isr_done_transfer(struct platform_device *pdev) | ||
109 | { | ||
110 | struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); | ||
111 | |||
112 | spin_lock(&host->lock); | ||
113 | if (host->cmd) | ||
114 | tasklet_schedule(&host->cmd_tasklet); | ||
115 | if (host->data) | ||
116 | tasklet_schedule(&host->data_tasklet); | ||
117 | spin_unlock(&host->lock); | ||
118 | } | ||
119 | |||
120 | static void sd_request_timeout(unsigned long host_addr) | ||
121 | { | ||
122 | struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr; | ||
123 | unsigned long flags; | ||
124 | |||
125 | spin_lock_irqsave(&host->lock, flags); | ||
126 | |||
127 | if (!host->mrq) { | ||
128 | dev_err(sdmmc_dev(host), "error: no request exist\n"); | ||
129 | goto out; | ||
130 | } | ||
131 | |||
132 | if (host->cmd) | ||
133 | host->cmd->error = -ETIMEDOUT; | ||
134 | if (host->data) | ||
135 | host->data->error = -ETIMEDOUT; | ||
136 | |||
137 | dev_dbg(sdmmc_dev(host), "timeout for request\n"); | ||
138 | |||
139 | out: | ||
140 | tasklet_schedule(&host->finish_tasklet); | ||
141 | spin_unlock_irqrestore(&host->lock, flags); | ||
142 | } | ||
143 | |||
144 | static void sd_finish_request(unsigned long host_addr) | ||
145 | { | ||
146 | struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr; | ||
147 | struct rtsx_pcr *pcr = host->pcr; | ||
148 | struct mmc_request *mrq; | ||
149 | struct mmc_command *cmd; | ||
150 | struct mmc_data *data; | ||
151 | unsigned long flags; | ||
152 | bool any_error; | ||
153 | |||
154 | spin_lock_irqsave(&host->lock, flags); | ||
155 | |||
156 | del_timer(&host->timer); | ||
157 | mrq = host->mrq; | ||
158 | if (!mrq) { | ||
159 | dev_err(sdmmc_dev(host), "error: no request need finish\n"); | ||
160 | goto out; | ||
161 | } | ||
162 | |||
163 | cmd = mrq->cmd; | ||
164 | data = mrq->data; | ||
165 | |||
166 | any_error = (mrq->sbc && mrq->sbc->error) || | ||
167 | (mrq->stop && mrq->stop->error) || | ||
168 | (cmd && cmd->error) || (data && data->error); | ||
169 | |||
170 | if (any_error) { | ||
171 | rtsx_pci_stop_cmd(pcr); | ||
172 | sd_clear_error(host); | ||
173 | } | ||
174 | |||
175 | if (data) { | ||
176 | if (any_error) | ||
177 | data->bytes_xfered = 0; | ||
178 | else | ||
179 | data->bytes_xfered = data->blocks * data->blksz; | ||
180 | |||
181 | if (!data->host_cookie) | ||
182 | rtsx_pci_dma_unmap_sg(pcr, data->sg, data->sg_len, | ||
183 | data->flags & MMC_DATA_READ); | ||
184 | |||
185 | } | ||
186 | |||
187 | host->mrq = NULL; | ||
188 | host->cmd = NULL; | ||
189 | host->data = NULL; | ||
190 | |||
191 | out: | ||
192 | spin_unlock_irqrestore(&host->lock, flags); | ||
193 | mutex_unlock(&pcr->pcr_mutex); | ||
194 | mmc_request_done(host->mmc, mrq); | ||
195 | } | ||
196 | |||
197 | static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, | 89 | static int sd_read_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, |
198 | u8 *buf, int buf_len, int timeout) | 90 | u8 *buf, int buf_len, int timeout) |
199 | { | 91 | { |
@@ -311,7 +203,8 @@ static int sd_write_data(struct realtek_pci_sdmmc *host, u8 *cmd, u16 byte_cnt, | |||
311 | return 0; | 203 | return 0; |
312 | } | 204 | } |
313 | 205 | ||
314 | static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd) | 206 | static void sd_send_cmd_get_rsp(struct realtek_pci_sdmmc *host, |
207 | struct mmc_command *cmd) | ||
315 | { | 208 | { |
316 | struct rtsx_pcr *pcr = host->pcr; | 209 | struct rtsx_pcr *pcr = host->pcr; |
317 | u8 cmd_idx = (u8)cmd->opcode; | 210 | u8 cmd_idx = (u8)cmd->opcode; |
@@ -319,14 +212,11 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd) | |||
319 | int err = 0; | 212 | int err = 0; |
320 | int timeout = 100; | 213 | int timeout = 100; |
321 | int i; | 214 | int i; |
215 | u8 *ptr; | ||
216 | int stat_idx = 0; | ||
322 | u8 rsp_type; | 217 | u8 rsp_type; |
323 | int rsp_len = 5; | 218 | int rsp_len = 5; |
324 | unsigned long flags; | 219 | bool clock_toggled = false; |
325 | |||
326 | if (host->cmd) | ||
327 | dev_err(sdmmc_dev(host), "error: cmd already exist\n"); | ||
328 | |||
329 | host->cmd = cmd; | ||
330 | 220 | ||
331 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", | 221 | dev_dbg(sdmmc_dev(host), "%s: SD/MMC CMD %d, arg = 0x%08x\n", |
332 | __func__, cmd_idx, arg); | 222 | __func__, cmd_idx, arg); |
@@ -361,8 +251,6 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd) | |||
361 | err = -EINVAL; | 251 | err = -EINVAL; |
362 | goto out; | 252 | goto out; |
363 | } | 253 | } |
364 | host->rsp_type = rsp_type; | ||
365 | host->rsp_len = rsp_len; | ||
366 | 254 | ||
367 | if (rsp_type == SD_RSP_TYPE_R1b) | 255 | if (rsp_type == SD_RSP_TYPE_R1b) |
368 | timeout = 3000; | 256 | timeout = 3000; |
@@ -372,6 +260,8 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd) | |||
372 | 0xFF, SD_CLK_TOGGLE_EN); | 260 | 0xFF, SD_CLK_TOGGLE_EN); |
373 | if (err < 0) | 261 | if (err < 0) |
374 | goto out; | 262 | goto out; |
263 | |||
264 | clock_toggled = true; | ||
375 | } | 265 | } |
376 | 266 | ||
377 | rtsx_pci_init_cmd(pcr); | 267 | rtsx_pci_init_cmd(pcr); |
@@ -395,60 +285,25 @@ static void sd_send_cmd(struct realtek_pci_sdmmc *host, struct mmc_command *cmd) | |||
395 | /* Read data from ping-pong buffer */ | 285 | /* Read data from ping-pong buffer */ |
396 | for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++) | 286 | for (i = PPBUF_BASE2; i < PPBUF_BASE2 + 16; i++) |
397 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); | 287 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); |
288 | stat_idx = 16; | ||
398 | } else if (rsp_type != SD_RSP_TYPE_R0) { | 289 | } else if (rsp_type != SD_RSP_TYPE_R0) { |
399 | /* Read data from SD_CMDx registers */ | 290 | /* Read data from SD_CMDx registers */ |
400 | for (i = SD_CMD0; i <= SD_CMD4; i++) | 291 | for (i = SD_CMD0; i <= SD_CMD4; i++) |
401 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); | 292 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, (u16)i, 0, 0); |
293 | stat_idx = 5; | ||
402 | } | 294 | } |
403 | 295 | ||
404 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, SD_STAT1, 0, 0); | 296 | rtsx_pci_add_cmd(pcr, READ_REG_CMD, SD_STAT1, 0, 0); |
405 | 297 | ||
406 | mod_timer(&host->timer, jiffies + msecs_to_jiffies(timeout)); | 298 | err = rtsx_pci_send_cmd(pcr, timeout); |
407 | 299 | if (err < 0) { | |
408 | spin_lock_irqsave(&pcr->lock, flags); | 300 | sd_print_debug_regs(host); |
409 | pcr->trans_result = TRANS_NOT_READY; | 301 | sd_clear_error(host); |
410 | rtsx_pci_send_cmd_no_wait(pcr); | 302 | dev_dbg(sdmmc_dev(host), |
411 | spin_unlock_irqrestore(&pcr->lock, flags); | 303 | "rtsx_pci_send_cmd error (err = %d)\n", err); |
412 | |||
413 | return; | ||
414 | |||
415 | out: | ||
416 | cmd->error = err; | ||
417 | tasklet_schedule(&host->finish_tasklet); | ||
418 | } | ||
419 | |||
420 | static void sd_get_rsp(unsigned long host_addr) | ||
421 | { | ||
422 | struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr; | ||
423 | struct rtsx_pcr *pcr = host->pcr; | ||
424 | struct mmc_command *cmd; | ||
425 | int i, err = 0, stat_idx; | ||
426 | u8 *ptr, rsp_type; | ||
427 | unsigned long flags; | ||
428 | |||
429 | spin_lock_irqsave(&host->lock, flags); | ||
430 | |||
431 | cmd = host->cmd; | ||
432 | host->cmd = NULL; | ||
433 | |||
434 | if (!cmd) { | ||
435 | dev_err(sdmmc_dev(host), "error: cmd not exist\n"); | ||
436 | goto out; | 304 | goto out; |
437 | } | 305 | } |
438 | 306 | ||
439 | spin_lock(&pcr->lock); | ||
440 | if (pcr->trans_result == TRANS_NO_DEVICE) | ||
441 | err = -ENODEV; | ||
442 | else if (pcr->trans_result != TRANS_RESULT_OK) | ||
443 | err = -EINVAL; | ||
444 | spin_unlock(&pcr->lock); | ||
445 | |||
446 | if (err < 0) | ||
447 | goto out; | ||
448 | |||
449 | rsp_type = host->rsp_type; | ||
450 | stat_idx = host->rsp_len; | ||
451 | |||
452 | if (rsp_type == SD_RSP_TYPE_R0) { | 307 | if (rsp_type == SD_RSP_TYPE_R0) { |
453 | err = 0; | 308 | err = 0; |
454 | goto out; | 309 | goto out; |
@@ -485,106 +340,26 @@ static void sd_get_rsp(unsigned long host_addr) | |||
485 | cmd->resp[0]); | 340 | cmd->resp[0]); |
486 | } | 341 | } |
487 | 342 | ||
488 | if (cmd == host->mrq->sbc) { | ||
489 | sd_send_cmd(host, host->mrq->cmd); | ||
490 | spin_unlock_irqrestore(&host->lock, flags); | ||
491 | return; | ||
492 | } | ||
493 | |||
494 | if (cmd == host->mrq->stop) | ||
495 | goto out; | ||
496 | |||
497 | if (cmd->data) { | ||
498 | sd_start_multi_rw(host, host->mrq); | ||
499 | spin_unlock_irqrestore(&host->lock, flags); | ||
500 | return; | ||
501 | } | ||
502 | |||
503 | out: | 343 | out: |
504 | cmd->error = err; | 344 | cmd->error = err; |
505 | 345 | ||
506 | tasklet_schedule(&host->finish_tasklet); | 346 | if (err && clock_toggled) |
507 | spin_unlock_irqrestore(&host->lock, flags); | 347 | rtsx_pci_write_register(pcr, SD_BUS_STAT, |
508 | } | 348 | SD_CLK_TOGGLE_EN | SD_CLK_FORCE_STOP, 0); |
509 | |||
510 | static int sd_pre_dma_transfer(struct realtek_pci_sdmmc *host, | ||
511 | struct mmc_data *data, struct realtek_next *next) | ||
512 | { | ||
513 | struct rtsx_pcr *pcr = host->pcr; | ||
514 | int read = data->flags & MMC_DATA_READ; | ||
515 | int sg_count = 0; | ||
516 | |||
517 | if (!next && data->host_cookie && | ||
518 | data->host_cookie != host->next_data.cookie) { | ||
519 | dev_err(sdmmc_dev(host), | ||
520 | "error: invalid cookie data[%d] host[%d]\n", | ||
521 | data->host_cookie, host->next_data.cookie); | ||
522 | data->host_cookie = 0; | ||
523 | } | ||
524 | |||
525 | if (next || (!next && data->host_cookie != host->next_data.cookie)) | ||
526 | sg_count = rtsx_pci_dma_map_sg(pcr, | ||
527 | data->sg, data->sg_len, read); | ||
528 | else | ||
529 | sg_count = host->next_data.sg_count; | ||
530 | |||
531 | if (next) { | ||
532 | next->sg_count = sg_count; | ||
533 | if (++next->cookie < 0) | ||
534 | next->cookie = 1; | ||
535 | data->host_cookie = next->cookie; | ||
536 | } | ||
537 | |||
538 | return sg_count; | ||
539 | } | ||
540 | |||
541 | static void sdmmc_pre_req(struct mmc_host *mmc, struct mmc_request *mrq, | ||
542 | bool is_first_req) | ||
543 | { | ||
544 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); | ||
545 | struct mmc_data *data = mrq->data; | ||
546 | |||
547 | if (data->host_cookie) { | ||
548 | dev_err(sdmmc_dev(host), | ||
549 | "error: descard already cookie data[%d]\n", | ||
550 | data->host_cookie); | ||
551 | data->host_cookie = 0; | ||
552 | } | ||
553 | |||
554 | dev_dbg(sdmmc_dev(host), "dma sg prepared: %d\n", | ||
555 | sd_pre_dma_transfer(host, data, &host->next_data)); | ||
556 | } | ||
557 | |||
558 | static void sdmmc_post_req(struct mmc_host *mmc, struct mmc_request *mrq, | ||
559 | int err) | ||
560 | { | ||
561 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); | ||
562 | struct rtsx_pcr *pcr = host->pcr; | ||
563 | struct mmc_data *data = mrq->data; | ||
564 | int read = data->flags & MMC_DATA_READ; | ||
565 | |||
566 | rtsx_pci_dma_unmap_sg(pcr, data->sg, data->sg_len, read); | ||
567 | data->host_cookie = 0; | ||
568 | } | 349 | } |
569 | 350 | ||
570 | static int sd_start_multi_rw(struct realtek_pci_sdmmc *host, | 351 | static int sd_rw_multi(struct realtek_pci_sdmmc *host, struct mmc_request *mrq) |
571 | struct mmc_request *mrq) | ||
572 | { | 352 | { |
573 | struct rtsx_pcr *pcr = host->pcr; | 353 | struct rtsx_pcr *pcr = host->pcr; |
574 | struct mmc_host *mmc = host->mmc; | 354 | struct mmc_host *mmc = host->mmc; |
575 | struct mmc_card *card = mmc->card; | 355 | struct mmc_card *card = mmc->card; |
576 | struct mmc_data *data = mrq->data; | 356 | struct mmc_data *data = mrq->data; |
577 | int uhs = mmc_card_uhs(card); | 357 | int uhs = mmc_card_uhs(card); |
578 | int read = data->flags & MMC_DATA_READ; | 358 | int read = (data->flags & MMC_DATA_READ) ? 1 : 0; |
579 | u8 cfg2, trans_mode; | 359 | u8 cfg2, trans_mode; |
580 | int err; | 360 | int err; |
581 | size_t data_len = data->blksz * data->blocks; | 361 | size_t data_len = data->blksz * data->blocks; |
582 | 362 | ||
583 | if (host->data) | ||
584 | dev_err(sdmmc_dev(host), "error: data already exist\n"); | ||
585 | |||
586 | host->data = data; | ||
587 | |||
588 | if (read) { | 363 | if (read) { |
589 | cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | | 364 | cfg2 = SD_CALCULATE_CRC7 | SD_CHECK_CRC16 | |
590 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0; | 365 | SD_NO_WAIT_BUSY_END | SD_CHECK_CRC7 | SD_RSP_LEN_0; |
@@ -635,54 +410,15 @@ static int sd_start_multi_rw(struct realtek_pci_sdmmc *host, | |||
635 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, | 410 | rtsx_pci_add_cmd(pcr, CHECK_REG_CMD, SD_TRANSFER, |
636 | SD_TRANSFER_END, SD_TRANSFER_END); | 411 | SD_TRANSFER_END, SD_TRANSFER_END); |
637 | 412 | ||
638 | mod_timer(&host->timer, jiffies + 10 * HZ); | ||
639 | rtsx_pci_send_cmd_no_wait(pcr); | 413 | rtsx_pci_send_cmd_no_wait(pcr); |
640 | 414 | ||
641 | err = rtsx_pci_dma_transfer(pcr, data->sg, host->sg_count, read); | 415 | err = rtsx_pci_transfer_data(pcr, data->sg, data->sg_len, read, 10000); |
642 | if (err < 0) { | ||
643 | data->error = err; | ||
644 | tasklet_schedule(&host->finish_tasklet); | ||
645 | } | ||
646 | return 0; | ||
647 | } | ||
648 | |||
649 | static void sd_finish_multi_rw(unsigned long host_addr) | ||
650 | { | ||
651 | struct realtek_pci_sdmmc *host = (struct realtek_pci_sdmmc *)host_addr; | ||
652 | struct rtsx_pcr *pcr = host->pcr; | ||
653 | struct mmc_data *data; | ||
654 | int err = 0; | ||
655 | unsigned long flags; | ||
656 | |||
657 | spin_lock_irqsave(&host->lock, flags); | ||
658 | |||
659 | if (!host->data) { | ||
660 | dev_err(sdmmc_dev(host), "error: no data exist\n"); | ||
661 | goto out; | ||
662 | } | ||
663 | |||
664 | data = host->data; | ||
665 | host->data = NULL; | ||
666 | |||
667 | if (pcr->trans_result == TRANS_NO_DEVICE) | ||
668 | err = -ENODEV; | ||
669 | else if (pcr->trans_result != TRANS_RESULT_OK) | ||
670 | err = -EINVAL; | ||
671 | |||
672 | if (err < 0) { | 416 | if (err < 0) { |
673 | data->error = err; | 417 | sd_clear_error(host); |
674 | goto out; | 418 | return err; |
675 | } | ||
676 | |||
677 | if (!host->mrq->sbc && data->stop) { | ||
678 | sd_send_cmd(host, data->stop); | ||
679 | spin_unlock_irqrestore(&host->lock, flags); | ||
680 | return; | ||
681 | } | 419 | } |
682 | 420 | ||
683 | out: | 421 | return 0; |
684 | tasklet_schedule(&host->finish_tasklet); | ||
685 | spin_unlock_irqrestore(&host->lock, flags); | ||
686 | } | 422 | } |
687 | 423 | ||
688 | static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) | 424 | static inline void sd_enable_initial_mode(struct realtek_pci_sdmmc *host) |
@@ -901,13 +637,6 @@ static int sd_tuning_rx(struct realtek_pci_sdmmc *host, u8 opcode) | |||
901 | return 0; | 637 | return 0; |
902 | } | 638 | } |
903 | 639 | ||
904 | static inline bool sd_use_muti_rw(struct mmc_command *cmd) | ||
905 | { | ||
906 | return mmc_op_multi(cmd->opcode) || | ||
907 | (cmd->opcode == MMC_READ_SINGLE_BLOCK) || | ||
908 | (cmd->opcode == MMC_WRITE_BLOCK); | ||
909 | } | ||
910 | |||
911 | static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | 640 | static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) |
912 | { | 641 | { |
913 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); | 642 | struct realtek_pci_sdmmc *host = mmc_priv(mmc); |
@@ -916,14 +645,6 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
916 | struct mmc_data *data = mrq->data; | 645 | struct mmc_data *data = mrq->data; |
917 | unsigned int data_size = 0; | 646 | unsigned int data_size = 0; |
918 | int err; | 647 | int err; |
919 | unsigned long flags; | ||
920 | |||
921 | mutex_lock(&pcr->pcr_mutex); | ||
922 | spin_lock_irqsave(&host->lock, flags); | ||
923 | |||
924 | if (host->mrq) | ||
925 | dev_err(sdmmc_dev(host), "error: request already exist\n"); | ||
926 | host->mrq = mrq; | ||
927 | 648 | ||
928 | if (host->eject) { | 649 | if (host->eject) { |
929 | cmd->error = -ENOMEDIUM; | 650 | cmd->error = -ENOMEDIUM; |
@@ -936,6 +657,8 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
936 | goto finish; | 657 | goto finish; |
937 | } | 658 | } |
938 | 659 | ||
660 | mutex_lock(&pcr->pcr_mutex); | ||
661 | |||
939 | rtsx_pci_start_run(pcr); | 662 | rtsx_pci_start_run(pcr); |
940 | 663 | ||
941 | rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth, | 664 | rtsx_pci_switch_clock(pcr, host->clock, host->ssc_depth, |
@@ -944,28 +667,46 @@ static void sdmmc_request(struct mmc_host *mmc, struct mmc_request *mrq) | |||
944 | rtsx_pci_write_register(pcr, CARD_SHARE_MODE, | 667 | rtsx_pci_write_register(pcr, CARD_SHARE_MODE, |
945 | CARD_SHARE_MASK, CARD_SHARE_48_SD); | 668 | CARD_SHARE_MASK, CARD_SHARE_48_SD); |
946 | 669 | ||
670 | mutex_lock(&host->host_mutex); | ||
671 | host->mrq = mrq; | ||
672 | mutex_unlock(&host->host_mutex); | ||
673 | |||
947 | if (mrq->data) | 674 | if (mrq->data) |
948 | data_size = data->blocks * data->blksz; | 675 | data_size = data->blocks * data->blksz; |
949 | 676 | ||
950 | if (sd_use_muti_rw(cmd)) | 677 | if (!data_size || mmc_op_multi(cmd->opcode) || |
951 | host->sg_count = sd_pre_dma_transfer(host, data, NULL); | 678 | (cmd->opcode == MMC_READ_SINGLE_BLOCK) || |
679 | (cmd->opcode == MMC_WRITE_BLOCK)) { | ||
680 | sd_send_cmd_get_rsp(host, cmd); | ||
952 | 681 | ||
953 | if (!data_size || sd_use_muti_rw(cmd)) { | 682 | if (!cmd->error && data_size) { |
954 | if (mrq->sbc) | 683 | sd_rw_multi(host, mrq); |
955 | sd_send_cmd(host, mrq->sbc); | 684 | |
956 | else | 685 | if (mmc_op_multi(cmd->opcode) && mrq->stop) |
957 | sd_send_cmd(host, cmd); | 686 | sd_send_cmd_get_rsp(host, mrq->stop); |
958 | spin_unlock_irqrestore(&host->lock, flags); | 687 | } |
959 | } else { | 688 | } else { |
960 | spin_unlock_irqrestore(&host->lock, flags); | ||
961 | sd_normal_rw(host, mrq); | 689 | sd_normal_rw(host, mrq); |
962 | tasklet_schedule(&host->finish_tasklet); | ||
963 | } | 690 | } |
964 | return; | 691 | |
692 | if (mrq->data) { | ||
693 | if (cmd->error || data->error) | ||
694 | data->bytes_xfered = 0; | ||
695 | else | ||
696 | data->bytes_xfered = data->blocks * data->blksz; | ||
697 | } | ||
698 | |||
699 | mutex_unlock(&pcr->pcr_mutex); | ||
965 | 700 | ||
966 | finish: | 701 | finish: |
967 | tasklet_schedule(&host->finish_tasklet); | 702 | if (cmd->error) |
968 | spin_unlock_irqrestore(&host->lock, flags); | 703 | dev_dbg(sdmmc_dev(host), "cmd->error = %d\n", cmd->error); |
704 | |||
705 | mutex_lock(&host->host_mutex); | ||
706 | host->mrq = NULL; | ||
707 | mutex_unlock(&host->host_mutex); | ||
708 | |||
709 | mmc_request_done(mmc, mrq); | ||
969 | } | 710 | } |
970 | 711 | ||
971 | static int sd_set_bus_width(struct realtek_pci_sdmmc *host, | 712 | static int sd_set_bus_width(struct realtek_pci_sdmmc *host, |
@@ -1400,8 +1141,6 @@ out: | |||
1400 | } | 1141 | } |
1401 | 1142 | ||
1402 | static const struct mmc_host_ops realtek_pci_sdmmc_ops = { | 1143 | static const struct mmc_host_ops realtek_pci_sdmmc_ops = { |
1403 | .pre_req = sdmmc_pre_req, | ||
1404 | .post_req = sdmmc_post_req, | ||
1405 | .request = sdmmc_request, | 1144 | .request = sdmmc_request, |
1406 | .set_ios = sdmmc_set_ios, | 1145 | .set_ios = sdmmc_set_ios, |
1407 | .get_ro = sdmmc_get_ro, | 1146 | .get_ro = sdmmc_get_ro, |
@@ -1465,7 +1204,6 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev) | |||
1465 | struct realtek_pci_sdmmc *host; | 1204 | struct realtek_pci_sdmmc *host; |
1466 | struct rtsx_pcr *pcr; | 1205 | struct rtsx_pcr *pcr; |
1467 | struct pcr_handle *handle = pdev->dev.platform_data; | 1206 | struct pcr_handle *handle = pdev->dev.platform_data; |
1468 | unsigned long host_addr; | ||
1469 | 1207 | ||
1470 | if (!handle) | 1208 | if (!handle) |
1471 | return -ENXIO; | 1209 | return -ENXIO; |
@@ -1489,15 +1227,8 @@ static int rtsx_pci_sdmmc_drv_probe(struct platform_device *pdev) | |||
1489 | pcr->slots[RTSX_SD_CARD].p_dev = pdev; | 1227 | pcr->slots[RTSX_SD_CARD].p_dev = pdev; |
1490 | pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event; | 1228 | pcr->slots[RTSX_SD_CARD].card_event = rtsx_pci_sdmmc_card_event; |
1491 | 1229 | ||
1492 | host_addr = (unsigned long)host; | 1230 | mutex_init(&host->host_mutex); |
1493 | host->next_data.cookie = 1; | ||
1494 | setup_timer(&host->timer, sd_request_timeout, host_addr); | ||
1495 | tasklet_init(&host->cmd_tasklet, sd_get_rsp, host_addr); | ||
1496 | tasklet_init(&host->data_tasklet, sd_finish_multi_rw, host_addr); | ||
1497 | tasklet_init(&host->finish_tasklet, sd_finish_request, host_addr); | ||
1498 | spin_lock_init(&host->lock); | ||
1499 | 1231 | ||
1500 | pcr->slots[RTSX_SD_CARD].done_transfer = sd_isr_done_transfer; | ||
1501 | realtek_init_host(host); | 1232 | realtek_init_host(host); |
1502 | 1233 | ||
1503 | mmc_add_host(mmc); | 1234 | mmc_add_host(mmc); |
@@ -1510,8 +1241,6 @@ static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev) | |||
1510 | struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); | 1241 | struct realtek_pci_sdmmc *host = platform_get_drvdata(pdev); |
1511 | struct rtsx_pcr *pcr; | 1242 | struct rtsx_pcr *pcr; |
1512 | struct mmc_host *mmc; | 1243 | struct mmc_host *mmc; |
1513 | struct mmc_request *mrq; | ||
1514 | unsigned long flags; | ||
1515 | 1244 | ||
1516 | if (!host) | 1245 | if (!host) |
1517 | return 0; | 1246 | return 0; |
@@ -1519,33 +1248,22 @@ static int rtsx_pci_sdmmc_drv_remove(struct platform_device *pdev) | |||
1519 | pcr = host->pcr; | 1248 | pcr = host->pcr; |
1520 | pcr->slots[RTSX_SD_CARD].p_dev = NULL; | 1249 | pcr->slots[RTSX_SD_CARD].p_dev = NULL; |
1521 | pcr->slots[RTSX_SD_CARD].card_event = NULL; | 1250 | pcr->slots[RTSX_SD_CARD].card_event = NULL; |
1522 | pcr->slots[RTSX_SD_CARD].done_transfer = NULL; | ||
1523 | mmc = host->mmc; | 1251 | mmc = host->mmc; |
1524 | mrq = host->mrq; | ||
1525 | 1252 | ||
1526 | spin_lock_irqsave(&host->lock, flags); | 1253 | mutex_lock(&host->host_mutex); |
1527 | if (host->mrq) { | 1254 | if (host->mrq) { |
1528 | dev_dbg(&(pdev->dev), | 1255 | dev_dbg(&(pdev->dev), |
1529 | "%s: Controller removed during transfer\n", | 1256 | "%s: Controller removed during transfer\n", |
1530 | mmc_hostname(mmc)); | 1257 | mmc_hostname(mmc)); |
1531 | 1258 | ||
1532 | if (mrq->sbc) | 1259 | rtsx_pci_complete_unfinished_transfer(pcr); |
1533 | mrq->sbc->error = -ENOMEDIUM; | ||
1534 | if (mrq->cmd) | ||
1535 | mrq->cmd->error = -ENOMEDIUM; | ||
1536 | if (mrq->stop) | ||
1537 | mrq->stop->error = -ENOMEDIUM; | ||
1538 | if (mrq->data) | ||
1539 | mrq->data->error = -ENOMEDIUM; | ||
1540 | 1260 | ||
1541 | tasklet_schedule(&host->finish_tasklet); | 1261 | host->mrq->cmd->error = -ENOMEDIUM; |
1262 | if (host->mrq->stop) | ||
1263 | host->mrq->stop->error = -ENOMEDIUM; | ||
1264 | mmc_request_done(mmc, host->mrq); | ||
1542 | } | 1265 | } |
1543 | spin_unlock_irqrestore(&host->lock, flags); | 1266 | mutex_unlock(&host->host_mutex); |
1544 | |||
1545 | del_timer_sync(&host->timer); | ||
1546 | tasklet_kill(&host->cmd_tasklet); | ||
1547 | tasklet_kill(&host->data_tasklet); | ||
1548 | tasklet_kill(&host->finish_tasklet); | ||
1549 | 1267 | ||
1550 | mmc_remove_host(mmc); | 1268 | mmc_remove_host(mmc); |
1551 | host->eject = true; | 1269 | host->eject = true; |
diff --git a/drivers/mtd/nand/davinci_nand.c b/drivers/mtd/nand/davinci_nand.c index 4615d79fc93f..b922c8efcf40 100644 --- a/drivers/mtd/nand/davinci_nand.c +++ b/drivers/mtd/nand/davinci_nand.c | |||
@@ -523,6 +523,7 @@ static struct nand_ecclayout hwecc4_2048 = { | |||
523 | #if defined(CONFIG_OF) | 523 | #if defined(CONFIG_OF) |
524 | static const struct of_device_id davinci_nand_of_match[] = { | 524 | static const struct of_device_id davinci_nand_of_match[] = { |
525 | {.compatible = "ti,davinci-nand", }, | 525 | {.compatible = "ti,davinci-nand", }, |
526 | {.compatible = "ti,keystone-nand", }, | ||
526 | {}, | 527 | {}, |
527 | }; | 528 | }; |
528 | MODULE_DEVICE_TABLE(of, davinci_nand_of_match); | 529 | MODULE_DEVICE_TABLE(of, davinci_nand_of_match); |
@@ -581,6 +582,11 @@ static struct davinci_nand_pdata | |||
581 | of_property_read_bool(pdev->dev.of_node, | 582 | of_property_read_bool(pdev->dev.of_node, |
582 | "ti,davinci-nand-use-bbt")) | 583 | "ti,davinci-nand-use-bbt")) |
583 | pdata->bbt_options = NAND_BBT_USE_FLASH; | 584 | pdata->bbt_options = NAND_BBT_USE_FLASH; |
585 | |||
586 | if (of_device_is_compatible(pdev->dev.of_node, | ||
587 | "ti,keystone-nand")) { | ||
588 | pdata->options |= NAND_NO_SUBPAGE_WRITE; | ||
589 | } | ||
584 | } | 590 | } |
585 | 591 | ||
586 | return dev_get_platdata(&pdev->dev); | 592 | return dev_get_platdata(&pdev->dev); |
diff --git a/drivers/mtd/ubi/block.c b/drivers/mtd/ubi/block.c index 7ff473c871a9..8d659e6a1b4c 100644 --- a/drivers/mtd/ubi/block.c +++ b/drivers/mtd/ubi/block.c | |||
@@ -431,7 +431,7 @@ int ubiblock_create(struct ubi_volume_info *vi) | |||
431 | * Create one workqueue per volume (per registered block device). | 431 | * Create one workqueue per volume (per registered block device). |
432 | * Rembember workqueues are cheap, they're not threads. | 432 | * Rembember workqueues are cheap, they're not threads. |
433 | */ | 433 | */ |
434 | dev->wq = alloc_workqueue(gd->disk_name, 0, 0); | 434 | dev->wq = alloc_workqueue("%s", 0, 0, gd->disk_name); |
435 | if (!dev->wq) | 435 | if (!dev->wq) |
436 | goto out_free_queue; | 436 | goto out_free_queue; |
437 | INIT_WORK(&dev->work, ubiblock_do_work); | 437 | INIT_WORK(&dev->work, ubiblock_do_work); |
diff --git a/drivers/mtd/ubi/wl.c b/drivers/mtd/ubi/wl.c index 02317c1c0238..0f3425dac910 100644 --- a/drivers/mtd/ubi/wl.c +++ b/drivers/mtd/ubi/wl.c | |||
@@ -671,6 +671,8 @@ static struct ubi_wl_entry *get_peb_for_wl(struct ubi_device *ubi) | |||
671 | 671 | ||
672 | e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); | 672 | e = find_wl_entry(ubi, &ubi->free, WL_FREE_MAX_DIFF); |
673 | self_check_in_wl_tree(ubi, e, &ubi->free); | 673 | self_check_in_wl_tree(ubi, e, &ubi->free); |
674 | ubi->free_count--; | ||
675 | ubi_assert(ubi->free_count >= 0); | ||
674 | rb_erase(&e->u.rb, &ubi->free); | 676 | rb_erase(&e->u.rb, &ubi->free); |
675 | 677 | ||
676 | return e; | 678 | return e; |
@@ -684,6 +686,9 @@ int ubi_wl_get_peb(struct ubi_device *ubi) | |||
684 | peb = __wl_get_peb(ubi); | 686 | peb = __wl_get_peb(ubi); |
685 | spin_unlock(&ubi->wl_lock); | 687 | spin_unlock(&ubi->wl_lock); |
686 | 688 | ||
689 | if (peb < 0) | ||
690 | return peb; | ||
691 | |||
687 | err = ubi_self_check_all_ff(ubi, peb, ubi->vid_hdr_aloffset, | 692 | err = ubi_self_check_all_ff(ubi, peb, ubi->vid_hdr_aloffset, |
688 | ubi->peb_size - ubi->vid_hdr_aloffset); | 693 | ubi->peb_size - ubi->vid_hdr_aloffset); |
689 | if (err) { | 694 | if (err) { |
@@ -1068,6 +1073,7 @@ static int wear_leveling_worker(struct ubi_device *ubi, struct ubi_work *wrk, | |||
1068 | 1073 | ||
1069 | /* Give the unused PEB back */ | 1074 | /* Give the unused PEB back */ |
1070 | wl_tree_add(e2, &ubi->free); | 1075 | wl_tree_add(e2, &ubi->free); |
1076 | ubi->free_count++; | ||
1071 | goto out_cancel; | 1077 | goto out_cancel; |
1072 | } | 1078 | } |
1073 | self_check_in_wl_tree(ubi, e1, &ubi->used); | 1079 | self_check_in_wl_tree(ubi, e1, &ubi->used); |
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c index 0e8b268da0a0..5f6babcfc26e 100644 --- a/drivers/net/bonding/bond_sysfs.c +++ b/drivers/net/bonding/bond_sysfs.c | |||
@@ -534,7 +534,7 @@ static ssize_t bonding_show_min_links(struct device *d, | |||
534 | { | 534 | { |
535 | struct bonding *bond = to_bond(d); | 535 | struct bonding *bond = to_bond(d); |
536 | 536 | ||
537 | return sprintf(buf, "%d\n", bond->params.min_links); | 537 | return sprintf(buf, "%u\n", bond->params.min_links); |
538 | } | 538 | } |
539 | 539 | ||
540 | static ssize_t bonding_store_min_links(struct device *d, | 540 | static ssize_t bonding_store_min_links(struct device *d, |
diff --git a/drivers/net/can/c_can/Kconfig b/drivers/net/can/c_can/Kconfig index 61ffc12d8fd8..8ab7103d4f44 100644 --- a/drivers/net/can/c_can/Kconfig +++ b/drivers/net/can/c_can/Kconfig | |||
@@ -14,6 +14,13 @@ config CAN_C_CAN_PLATFORM | |||
14 | SPEAr1310 and SPEAr320 evaluation boards & TI (www.ti.com) | 14 | SPEAr1310 and SPEAr320 evaluation boards & TI (www.ti.com) |
15 | boards like am335x, dm814x, dm813x and dm811x. | 15 | boards like am335x, dm814x, dm813x and dm811x. |
16 | 16 | ||
17 | config CAN_C_CAN_STRICT_FRAME_ORDERING | ||
18 | bool "Force a strict RX CAN frame order (may cause frame loss)" | ||
19 | ---help--- | ||
20 | The RX split buffer prevents packet reordering but can cause packet | ||
21 | loss. Only enable this option when you accept to lose CAN frames | ||
22 | in favour of getting the received CAN frames in the correct order. | ||
23 | |||
17 | config CAN_C_CAN_PCI | 24 | config CAN_C_CAN_PCI |
18 | tristate "Generic PCI Bus based C_CAN/D_CAN driver" | 25 | tristate "Generic PCI Bus based C_CAN/D_CAN driver" |
19 | depends on PCI | 26 | depends on PCI |
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index a5c8dcfa8357..a2ca820b5373 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c | |||
@@ -60,6 +60,8 @@ | |||
60 | #define CONTROL_IE BIT(1) | 60 | #define CONTROL_IE BIT(1) |
61 | #define CONTROL_INIT BIT(0) | 61 | #define CONTROL_INIT BIT(0) |
62 | 62 | ||
63 | #define CONTROL_IRQMSK (CONTROL_EIE | CONTROL_IE | CONTROL_SIE) | ||
64 | |||
63 | /* test register */ | 65 | /* test register */ |
64 | #define TEST_RX BIT(7) | 66 | #define TEST_RX BIT(7) |
65 | #define TEST_TX1 BIT(6) | 67 | #define TEST_TX1 BIT(6) |
@@ -108,11 +110,14 @@ | |||
108 | #define IF_COMM_CONTROL BIT(4) | 110 | #define IF_COMM_CONTROL BIT(4) |
109 | #define IF_COMM_CLR_INT_PND BIT(3) | 111 | #define IF_COMM_CLR_INT_PND BIT(3) |
110 | #define IF_COMM_TXRQST BIT(2) | 112 | #define IF_COMM_TXRQST BIT(2) |
113 | #define IF_COMM_CLR_NEWDAT IF_COMM_TXRQST | ||
111 | #define IF_COMM_DATAA BIT(1) | 114 | #define IF_COMM_DATAA BIT(1) |
112 | #define IF_COMM_DATAB BIT(0) | 115 | #define IF_COMM_DATAB BIT(0) |
113 | #define IF_COMM_ALL (IF_COMM_MASK | IF_COMM_ARB | \ | 116 | |
114 | IF_COMM_CONTROL | IF_COMM_TXRQST | \ | 117 | /* TX buffer setup */ |
115 | IF_COMM_DATAA | IF_COMM_DATAB) | 118 | #define IF_COMM_TX (IF_COMM_ARB | IF_COMM_CONTROL | \ |
119 | IF_COMM_TXRQST | \ | ||
120 | IF_COMM_DATAA | IF_COMM_DATAB) | ||
116 | 121 | ||
117 | /* For the low buffers we clear the interrupt bit, but keep newdat */ | 122 | /* For the low buffers we clear the interrupt bit, but keep newdat */ |
118 | #define IF_COMM_RCV_LOW (IF_COMM_MASK | IF_COMM_ARB | \ | 123 | #define IF_COMM_RCV_LOW (IF_COMM_MASK | IF_COMM_ARB | \ |
@@ -120,12 +125,19 @@ | |||
120 | IF_COMM_DATAA | IF_COMM_DATAB) | 125 | IF_COMM_DATAA | IF_COMM_DATAB) |
121 | 126 | ||
122 | /* For the high buffers we clear the interrupt bit and newdat */ | 127 | /* For the high buffers we clear the interrupt bit and newdat */ |
123 | #define IF_COMM_RCV_HIGH (IF_COMM_RCV_LOW | IF_COMM_TXRQST) | 128 | #define IF_COMM_RCV_HIGH (IF_COMM_RCV_LOW | IF_COMM_CLR_NEWDAT) |
129 | |||
130 | |||
131 | /* Receive setup of message objects */ | ||
132 | #define IF_COMM_RCV_SETUP (IF_COMM_MASK | IF_COMM_ARB | IF_COMM_CONTROL) | ||
133 | |||
134 | /* Invalidation of message objects */ | ||
135 | #define IF_COMM_INVAL (IF_COMM_ARB | IF_COMM_CONTROL) | ||
124 | 136 | ||
125 | /* IFx arbitration */ | 137 | /* IFx arbitration */ |
126 | #define IF_ARB_MSGVAL BIT(15) | 138 | #define IF_ARB_MSGVAL BIT(31) |
127 | #define IF_ARB_MSGXTD BIT(14) | 139 | #define IF_ARB_MSGXTD BIT(30) |
128 | #define IF_ARB_TRANSMIT BIT(13) | 140 | #define IF_ARB_TRANSMIT BIT(29) |
129 | 141 | ||
130 | /* IFx message control */ | 142 | /* IFx message control */ |
131 | #define IF_MCONT_NEWDAT BIT(15) | 143 | #define IF_MCONT_NEWDAT BIT(15) |
@@ -139,19 +151,17 @@ | |||
139 | #define IF_MCONT_EOB BIT(7) | 151 | #define IF_MCONT_EOB BIT(7) |
140 | #define IF_MCONT_DLC_MASK 0xf | 152 | #define IF_MCONT_DLC_MASK 0xf |
141 | 153 | ||
154 | #define IF_MCONT_RCV (IF_MCONT_RXIE | IF_MCONT_UMASK) | ||
155 | #define IF_MCONT_RCV_EOB (IF_MCONT_RCV | IF_MCONT_EOB) | ||
156 | |||
157 | #define IF_MCONT_TX (IF_MCONT_TXIE | IF_MCONT_EOB) | ||
158 | |||
142 | /* | 159 | /* |
143 | * Use IF1 for RX and IF2 for TX | 160 | * Use IF1 for RX and IF2 for TX |
144 | */ | 161 | */ |
145 | #define IF_RX 0 | 162 | #define IF_RX 0 |
146 | #define IF_TX 1 | 163 | #define IF_TX 1 |
147 | 164 | ||
148 | /* status interrupt */ | ||
149 | #define STATUS_INTERRUPT 0x8000 | ||
150 | |||
151 | /* global interrupt masks */ | ||
152 | #define ENABLE_ALL_INTERRUPTS 1 | ||
153 | #define DISABLE_ALL_INTERRUPTS 0 | ||
154 | |||
155 | /* minimum timeout for checking BUSY status */ | 165 | /* minimum timeout for checking BUSY status */ |
156 | #define MIN_TIMEOUT_VALUE 6 | 166 | #define MIN_TIMEOUT_VALUE 6 |
157 | 167 | ||
@@ -171,6 +181,7 @@ enum c_can_lec_type { | |||
171 | LEC_BIT0_ERROR, | 181 | LEC_BIT0_ERROR, |
172 | LEC_CRC_ERROR, | 182 | LEC_CRC_ERROR, |
173 | LEC_UNUSED, | 183 | LEC_UNUSED, |
184 | LEC_MASK = LEC_UNUSED, | ||
174 | }; | 185 | }; |
175 | 186 | ||
176 | /* | 187 | /* |
@@ -226,143 +237,115 @@ static inline void c_can_reset_ram(const struct c_can_priv *priv, bool enable) | |||
226 | priv->raminit(priv, enable); | 237 | priv->raminit(priv, enable); |
227 | } | 238 | } |
228 | 239 | ||
229 | static inline int get_tx_next_msg_obj(const struct c_can_priv *priv) | 240 | static void c_can_irq_control(struct c_can_priv *priv, bool enable) |
230 | { | 241 | { |
231 | return (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) + | 242 | u32 ctrl = priv->read_reg(priv, C_CAN_CTRL_REG) & ~CONTROL_IRQMSK; |
232 | C_CAN_MSG_OBJ_TX_FIRST; | ||
233 | } | ||
234 | |||
235 | static inline int get_tx_echo_msg_obj(int txecho) | ||
236 | { | ||
237 | return (txecho & C_CAN_NEXT_MSG_OBJ_MASK) + C_CAN_MSG_OBJ_TX_FIRST; | ||
238 | } | ||
239 | |||
240 | static u32 c_can_read_reg32(struct c_can_priv *priv, enum reg index) | ||
241 | { | ||
242 | u32 val = priv->read_reg(priv, index); | ||
243 | val |= ((u32) priv->read_reg(priv, index + 1)) << 16; | ||
244 | return val; | ||
245 | } | ||
246 | |||
247 | static void c_can_enable_all_interrupts(struct c_can_priv *priv, | ||
248 | int enable) | ||
249 | { | ||
250 | unsigned int cntrl_save = priv->read_reg(priv, | ||
251 | C_CAN_CTRL_REG); | ||
252 | 243 | ||
253 | if (enable) | 244 | if (enable) |
254 | cntrl_save |= (CONTROL_SIE | CONTROL_EIE | CONTROL_IE); | 245 | ctrl |= CONTROL_IRQMSK; |
255 | else | ||
256 | cntrl_save &= ~(CONTROL_EIE | CONTROL_IE | CONTROL_SIE); | ||
257 | 246 | ||
258 | priv->write_reg(priv, C_CAN_CTRL_REG, cntrl_save); | 247 | priv->write_reg(priv, C_CAN_CTRL_REG, ctrl); |
259 | } | 248 | } |
260 | 249 | ||
261 | static inline int c_can_msg_obj_is_busy(struct c_can_priv *priv, int iface) | 250 | static void c_can_obj_update(struct net_device *dev, int iface, u32 cmd, u32 obj) |
262 | { | 251 | { |
263 | int count = MIN_TIMEOUT_VALUE; | 252 | struct c_can_priv *priv = netdev_priv(dev); |
253 | int cnt, reg = C_CAN_IFACE(COMREQ_REG, iface); | ||
254 | |||
255 | priv->write_reg(priv, reg + 1, cmd); | ||
256 | priv->write_reg(priv, reg, obj); | ||
264 | 257 | ||
265 | while (count && priv->read_reg(priv, | 258 | for (cnt = MIN_TIMEOUT_VALUE; cnt; cnt--) { |
266 | C_CAN_IFACE(COMREQ_REG, iface)) & | 259 | if (!(priv->read_reg(priv, reg) & IF_COMR_BUSY)) |
267 | IF_COMR_BUSY) { | 260 | return; |
268 | count--; | ||
269 | udelay(1); | 261 | udelay(1); |
270 | } | 262 | } |
263 | netdev_err(dev, "Updating object timed out\n"); | ||
271 | 264 | ||
272 | if (!count) | 265 | } |
273 | return 1; | ||
274 | 266 | ||
275 | return 0; | 267 | static inline void c_can_object_get(struct net_device *dev, int iface, |
268 | u32 obj, u32 cmd) | ||
269 | { | ||
270 | c_can_obj_update(dev, iface, cmd, obj); | ||
276 | } | 271 | } |
277 | 272 | ||
278 | static inline void c_can_object_get(struct net_device *dev, | 273 | static inline void c_can_object_put(struct net_device *dev, int iface, |
279 | int iface, int objno, int mask) | 274 | u32 obj, u32 cmd) |
280 | { | 275 | { |
281 | struct c_can_priv *priv = netdev_priv(dev); | 276 | c_can_obj_update(dev, iface, cmd | IF_COMM_WR, obj); |
277 | } | ||
282 | 278 | ||
283 | /* | 279 | /* |
284 | * As per specs, after writting the message object number in the | 280 | * Note: According to documentation clearing TXIE while MSGVAL is set |
285 | * IF command request register the transfer b/w interface | 281 | * is not allowed, but works nicely on C/DCAN. And that lowers the I/O |
286 | * register and message RAM must be complete in 6 CAN-CLK | 282 | * load significantly. |
287 | * period. | 283 | */ |
288 | */ | 284 | static void c_can_inval_tx_object(struct net_device *dev, int iface, int obj) |
289 | priv->write_reg(priv, C_CAN_IFACE(COMMSK_REG, iface), | 285 | { |
290 | IFX_WRITE_LOW_16BIT(mask)); | 286 | struct c_can_priv *priv = netdev_priv(dev); |
291 | priv->write_reg(priv, C_CAN_IFACE(COMREQ_REG, iface), | ||
292 | IFX_WRITE_LOW_16BIT(objno)); | ||
293 | 287 | ||
294 | if (c_can_msg_obj_is_busy(priv, iface)) | 288 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0); |
295 | netdev_err(dev, "timed out in object get\n"); | 289 | c_can_object_put(dev, iface, obj, IF_COMM_INVAL); |
296 | } | 290 | } |
297 | 291 | ||
298 | static inline void c_can_object_put(struct net_device *dev, | 292 | static void c_can_inval_msg_object(struct net_device *dev, int iface, int obj) |
299 | int iface, int objno, int mask) | ||
300 | { | 293 | { |
301 | struct c_can_priv *priv = netdev_priv(dev); | 294 | struct c_can_priv *priv = netdev_priv(dev); |
302 | 295 | ||
303 | /* | 296 | priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), 0); |
304 | * As per specs, after writting the message object number in the | 297 | priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), 0); |
305 | * IF command request register the transfer b/w interface | 298 | c_can_inval_tx_object(dev, iface, obj); |
306 | * register and message RAM must be complete in 6 CAN-CLK | ||
307 | * period. | ||
308 | */ | ||
309 | priv->write_reg(priv, C_CAN_IFACE(COMMSK_REG, iface), | ||
310 | (IF_COMM_WR | IFX_WRITE_LOW_16BIT(mask))); | ||
311 | priv->write_reg(priv, C_CAN_IFACE(COMREQ_REG, iface), | ||
312 | IFX_WRITE_LOW_16BIT(objno)); | ||
313 | |||
314 | if (c_can_msg_obj_is_busy(priv, iface)) | ||
315 | netdev_err(dev, "timed out in object put\n"); | ||
316 | } | 299 | } |
317 | 300 | ||
318 | static void c_can_write_msg_object(struct net_device *dev, | 301 | static void c_can_setup_tx_object(struct net_device *dev, int iface, |
319 | int iface, struct can_frame *frame, int objno) | 302 | struct can_frame *frame, int idx) |
320 | { | 303 | { |
321 | int i; | ||
322 | u16 flags = 0; | ||
323 | unsigned int id; | ||
324 | struct c_can_priv *priv = netdev_priv(dev); | 304 | struct c_can_priv *priv = netdev_priv(dev); |
325 | 305 | u16 ctrl = IF_MCONT_TX | frame->can_dlc; | |
326 | if (!(frame->can_id & CAN_RTR_FLAG)) | 306 | bool rtr = frame->can_id & CAN_RTR_FLAG; |
327 | flags |= IF_ARB_TRANSMIT; | 307 | u32 arb = IF_ARB_MSGVAL; |
308 | int i; | ||
328 | 309 | ||
329 | if (frame->can_id & CAN_EFF_FLAG) { | 310 | if (frame->can_id & CAN_EFF_FLAG) { |
330 | id = frame->can_id & CAN_EFF_MASK; | 311 | arb |= frame->can_id & CAN_EFF_MASK; |
331 | flags |= IF_ARB_MSGXTD; | 312 | arb |= IF_ARB_MSGXTD; |
332 | } else | 313 | } else { |
333 | id = ((frame->can_id & CAN_SFF_MASK) << 18); | 314 | arb |= (frame->can_id & CAN_SFF_MASK) << 18; |
315 | } | ||
316 | |||
317 | if (!rtr) | ||
318 | arb |= IF_ARB_TRANSMIT; | ||
334 | 319 | ||
335 | flags |= IF_ARB_MSGVAL; | 320 | /* |
321 | * If we change the DIR bit, we need to invalidate the buffer | ||
322 | * first, i.e. clear the MSGVAL flag in the arbiter. | ||
323 | */ | ||
324 | if (rtr != (bool)test_bit(idx, &priv->tx_dir)) { | ||
325 | u32 obj = idx + C_CAN_MSG_OBJ_TX_FIRST; | ||
326 | |||
327 | c_can_inval_msg_object(dev, iface, obj); | ||
328 | change_bit(idx, &priv->tx_dir); | ||
329 | } | ||
330 | |||
331 | priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), arb); | ||
332 | priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), arb >> 16); | ||
336 | 333 | ||
337 | priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), | 334 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl); |
338 | IFX_WRITE_LOW_16BIT(id)); | ||
339 | priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), flags | | ||
340 | IFX_WRITE_HIGH_16BIT(id)); | ||
341 | 335 | ||
342 | for (i = 0; i < frame->can_dlc; i += 2) { | 336 | for (i = 0; i < frame->can_dlc; i += 2) { |
343 | priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2, | 337 | priv->write_reg(priv, C_CAN_IFACE(DATA1_REG, iface) + i / 2, |
344 | frame->data[i] | (frame->data[i + 1] << 8)); | 338 | frame->data[i] | (frame->data[i + 1] << 8)); |
345 | } | 339 | } |
346 | |||
347 | /* enable interrupt for this message object */ | ||
348 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), | ||
349 | IF_MCONT_TXIE | IF_MCONT_TXRQST | IF_MCONT_EOB | | ||
350 | frame->can_dlc); | ||
351 | c_can_object_put(dev, iface, objno, IF_COMM_ALL); | ||
352 | } | 340 | } |
353 | 341 | ||
354 | static inline void c_can_activate_all_lower_rx_msg_obj(struct net_device *dev, | 342 | static inline void c_can_activate_all_lower_rx_msg_obj(struct net_device *dev, |
355 | int iface, | 343 | int iface) |
356 | int ctrl_mask) | ||
357 | { | 344 | { |
358 | int i; | 345 | int i; |
359 | struct c_can_priv *priv = netdev_priv(dev); | ||
360 | 346 | ||
361 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_RX_LOW_LAST; i++) { | 347 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i <= C_CAN_MSG_RX_LOW_LAST; i++) |
362 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), | 348 | c_can_object_get(dev, iface, i, IF_COMM_CLR_NEWDAT); |
363 | ctrl_mask & ~IF_MCONT_NEWDAT); | ||
364 | c_can_object_put(dev, iface, i, IF_COMM_CONTROL); | ||
365 | } | ||
366 | } | 349 | } |
367 | 350 | ||
368 | static int c_can_handle_lost_msg_obj(struct net_device *dev, | 351 | static int c_can_handle_lost_msg_obj(struct net_device *dev, |
@@ -377,6 +360,9 @@ static int c_can_handle_lost_msg_obj(struct net_device *dev, | |||
377 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl); | 360 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), ctrl); |
378 | c_can_object_put(dev, iface, objno, IF_COMM_CONTROL); | 361 | c_can_object_put(dev, iface, objno, IF_COMM_CONTROL); |
379 | 362 | ||
363 | stats->rx_errors++; | ||
364 | stats->rx_over_errors++; | ||
365 | |||
380 | /* create an error msg */ | 366 | /* create an error msg */ |
381 | skb = alloc_can_err_skb(dev, &frame); | 367 | skb = alloc_can_err_skb(dev, &frame); |
382 | if (unlikely(!skb)) | 368 | if (unlikely(!skb)) |
@@ -384,22 +370,18 @@ static int c_can_handle_lost_msg_obj(struct net_device *dev, | |||
384 | 370 | ||
385 | frame->can_id |= CAN_ERR_CRTL; | 371 | frame->can_id |= CAN_ERR_CRTL; |
386 | frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; | 372 | frame->data[1] = CAN_ERR_CRTL_RX_OVERFLOW; |
387 | stats->rx_errors++; | ||
388 | stats->rx_over_errors++; | ||
389 | 373 | ||
390 | netif_receive_skb(skb); | 374 | netif_receive_skb(skb); |
391 | return 1; | 375 | return 1; |
392 | } | 376 | } |
393 | 377 | ||
394 | static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl) | 378 | static int c_can_read_msg_object(struct net_device *dev, int iface, u32 ctrl) |
395 | { | 379 | { |
396 | u16 flags, data; | ||
397 | int i; | ||
398 | unsigned int val; | ||
399 | struct c_can_priv *priv = netdev_priv(dev); | ||
400 | struct net_device_stats *stats = &dev->stats; | 380 | struct net_device_stats *stats = &dev->stats; |
401 | struct sk_buff *skb; | 381 | struct c_can_priv *priv = netdev_priv(dev); |
402 | struct can_frame *frame; | 382 | struct can_frame *frame; |
383 | struct sk_buff *skb; | ||
384 | u32 arb, data; | ||
403 | 385 | ||
404 | skb = alloc_can_skb(dev, &frame); | 386 | skb = alloc_can_skb(dev, &frame); |
405 | if (!skb) { | 387 | if (!skb) { |
@@ -409,115 +391,82 @@ static int c_can_read_msg_object(struct net_device *dev, int iface, int ctrl) | |||
409 | 391 | ||
410 | frame->can_dlc = get_can_dlc(ctrl & 0x0F); | 392 | frame->can_dlc = get_can_dlc(ctrl & 0x0F); |
411 | 393 | ||
412 | flags = priv->read_reg(priv, C_CAN_IFACE(ARB2_REG, iface)); | 394 | arb = priv->read_reg(priv, C_CAN_IFACE(ARB1_REG, iface)); |
413 | val = priv->read_reg(priv, C_CAN_IFACE(ARB1_REG, iface)) | | 395 | arb |= priv->read_reg(priv, C_CAN_IFACE(ARB2_REG, iface)) << 16; |
414 | (flags << 16); | ||
415 | 396 | ||
416 | if (flags & IF_ARB_MSGXTD) | 397 | if (arb & IF_ARB_MSGXTD) |
417 | frame->can_id = (val & CAN_EFF_MASK) | CAN_EFF_FLAG; | 398 | frame->can_id = (arb & CAN_EFF_MASK) | CAN_EFF_FLAG; |
418 | else | 399 | else |
419 | frame->can_id = (val >> 18) & CAN_SFF_MASK; | 400 | frame->can_id = (arb >> 18) & CAN_SFF_MASK; |
420 | 401 | ||
421 | if (flags & IF_ARB_TRANSMIT) | 402 | if (arb & IF_ARB_TRANSMIT) { |
422 | frame->can_id |= CAN_RTR_FLAG; | 403 | frame->can_id |= CAN_RTR_FLAG; |
423 | else { | 404 | } else { |
424 | for (i = 0; i < frame->can_dlc; i += 2) { | 405 | int i, dreg = C_CAN_IFACE(DATA1_REG, iface); |
425 | data = priv->read_reg(priv, | 406 | |
426 | C_CAN_IFACE(DATA1_REG, iface) + i / 2); | 407 | for (i = 0; i < frame->can_dlc; i += 2, dreg ++) { |
408 | data = priv->read_reg(priv, dreg); | ||
427 | frame->data[i] = data; | 409 | frame->data[i] = data; |
428 | frame->data[i + 1] = data >> 8; | 410 | frame->data[i + 1] = data >> 8; |
429 | } | 411 | } |
430 | } | 412 | } |
431 | 413 | ||
432 | netif_receive_skb(skb); | ||
433 | |||
434 | stats->rx_packets++; | 414 | stats->rx_packets++; |
435 | stats->rx_bytes += frame->can_dlc; | 415 | stats->rx_bytes += frame->can_dlc; |
416 | |||
417 | netif_receive_skb(skb); | ||
436 | return 0; | 418 | return 0; |
437 | } | 419 | } |
438 | 420 | ||
439 | static void c_can_setup_receive_object(struct net_device *dev, int iface, | 421 | static void c_can_setup_receive_object(struct net_device *dev, int iface, |
440 | int objno, unsigned int mask, | 422 | u32 obj, u32 mask, u32 id, u32 mcont) |
441 | unsigned int id, unsigned int mcont) | ||
442 | { | 423 | { |
443 | struct c_can_priv *priv = netdev_priv(dev); | 424 | struct c_can_priv *priv = netdev_priv(dev); |
444 | 425 | ||
445 | priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface), | 426 | mask |= BIT(29); |
446 | IFX_WRITE_LOW_16BIT(mask)); | 427 | priv->write_reg(priv, C_CAN_IFACE(MASK1_REG, iface), mask); |
447 | 428 | priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface), mask >> 16); | |
448 | /* According to C_CAN documentation, the reserved bit | ||
449 | * in IFx_MASK2 register is fixed 1 | ||
450 | */ | ||
451 | priv->write_reg(priv, C_CAN_IFACE(MASK2_REG, iface), | ||
452 | IFX_WRITE_HIGH_16BIT(mask) | BIT(13)); | ||
453 | 429 | ||
454 | priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), | 430 | id |= IF_ARB_MSGVAL; |
455 | IFX_WRITE_LOW_16BIT(id)); | 431 | priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), id); |
456 | priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), | 432 | priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), id >> 16); |
457 | (IF_ARB_MSGVAL | IFX_WRITE_HIGH_16BIT(id))); | ||
458 | 433 | ||
459 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), mcont); | 434 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), mcont); |
460 | c_can_object_put(dev, iface, objno, IF_COMM_ALL & ~IF_COMM_TXRQST); | 435 | c_can_object_put(dev, iface, obj, IF_COMM_RCV_SETUP); |
461 | |||
462 | netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, | ||
463 | c_can_read_reg32(priv, C_CAN_MSGVAL1_REG)); | ||
464 | } | ||
465 | |||
466 | static void c_can_inval_msg_object(struct net_device *dev, int iface, int objno) | ||
467 | { | ||
468 | struct c_can_priv *priv = netdev_priv(dev); | ||
469 | |||
470 | priv->write_reg(priv, C_CAN_IFACE(ARB1_REG, iface), 0); | ||
471 | priv->write_reg(priv, C_CAN_IFACE(ARB2_REG, iface), 0); | ||
472 | priv->write_reg(priv, C_CAN_IFACE(MSGCTRL_REG, iface), 0); | ||
473 | |||
474 | c_can_object_put(dev, iface, objno, IF_COMM_ARB | IF_COMM_CONTROL); | ||
475 | |||
476 | netdev_dbg(dev, "obj no:%d, msgval:0x%08x\n", objno, | ||
477 | c_can_read_reg32(priv, C_CAN_MSGVAL1_REG)); | ||
478 | } | ||
479 | |||
480 | static inline int c_can_is_next_tx_obj_busy(struct c_can_priv *priv, int objno) | ||
481 | { | ||
482 | int val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG); | ||
483 | |||
484 | /* | ||
485 | * as transmission request register's bit n-1 corresponds to | ||
486 | * message object n, we need to handle the same properly. | ||
487 | */ | ||
488 | if (val & (1 << (objno - 1))) | ||
489 | return 1; | ||
490 | |||
491 | return 0; | ||
492 | } | 436 | } |
493 | 437 | ||
494 | static netdev_tx_t c_can_start_xmit(struct sk_buff *skb, | 438 | static netdev_tx_t c_can_start_xmit(struct sk_buff *skb, |
495 | struct net_device *dev) | 439 | struct net_device *dev) |
496 | { | 440 | { |
497 | u32 msg_obj_no; | ||
498 | struct c_can_priv *priv = netdev_priv(dev); | ||
499 | struct can_frame *frame = (struct can_frame *)skb->data; | 441 | struct can_frame *frame = (struct can_frame *)skb->data; |
442 | struct c_can_priv *priv = netdev_priv(dev); | ||
443 | u32 idx, obj; | ||
500 | 444 | ||
501 | if (can_dropped_invalid_skb(dev, skb)) | 445 | if (can_dropped_invalid_skb(dev, skb)) |
502 | return NETDEV_TX_OK; | 446 | return NETDEV_TX_OK; |
503 | |||
504 | spin_lock_bh(&priv->xmit_lock); | ||
505 | msg_obj_no = get_tx_next_msg_obj(priv); | ||
506 | |||
507 | /* prepare message object for transmission */ | ||
508 | c_can_write_msg_object(dev, IF_TX, frame, msg_obj_no); | ||
509 | priv->dlc[msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST] = frame->can_dlc; | ||
510 | can_put_echo_skb(skb, dev, msg_obj_no - C_CAN_MSG_OBJ_TX_FIRST); | ||
511 | |||
512 | /* | 447 | /* |
513 | * we have to stop the queue in case of a wrap around or | 448 | * This is not a FIFO. C/D_CAN sends out the buffers |
514 | * if the next TX message object is still in use | 449 | * prioritized. The lowest buffer number wins. |
515 | */ | 450 | */ |
516 | priv->tx_next++; | 451 | idx = fls(atomic_read(&priv->tx_active)); |
517 | if (c_can_is_next_tx_obj_busy(priv, get_tx_next_msg_obj(priv)) || | 452 | obj = idx + C_CAN_MSG_OBJ_TX_FIRST; |
518 | (priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) == 0) | 453 | |
454 | /* If this is the last buffer, stop the xmit queue */ | ||
455 | if (idx == C_CAN_MSG_OBJ_TX_NUM - 1) | ||
519 | netif_stop_queue(dev); | 456 | netif_stop_queue(dev); |
520 | spin_unlock_bh(&priv->xmit_lock); | 457 | /* |
458 | * Store the message in the interface so we can call | ||
459 | * can_put_echo_skb(). We must do this before we enable | ||
460 | * transmit as we might race against do_tx(). | ||
461 | */ | ||
462 | c_can_setup_tx_object(dev, IF_TX, frame, idx); | ||
463 | priv->dlc[idx] = frame->can_dlc; | ||
464 | can_put_echo_skb(skb, dev, idx); | ||
465 | |||
466 | /* Update the active bits */ | ||
467 | atomic_add((1 << idx), &priv->tx_active); | ||
468 | /* Start transmission */ | ||
469 | c_can_object_put(dev, IF_TX, obj, IF_COMM_TX); | ||
521 | 470 | ||
522 | return NETDEV_TX_OK; | 471 | return NETDEV_TX_OK; |
523 | } | 472 | } |
@@ -594,11 +543,10 @@ static void c_can_configure_msg_objects(struct net_device *dev) | |||
594 | 543 | ||
595 | /* setup receive message objects */ | 544 | /* setup receive message objects */ |
596 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++) | 545 | for (i = C_CAN_MSG_OBJ_RX_FIRST; i < C_CAN_MSG_OBJ_RX_LAST; i++) |
597 | c_can_setup_receive_object(dev, IF_RX, i, 0, 0, | 546 | c_can_setup_receive_object(dev, IF_RX, i, 0, 0, IF_MCONT_RCV); |
598 | (IF_MCONT_RXIE | IF_MCONT_UMASK) & ~IF_MCONT_EOB); | ||
599 | 547 | ||
600 | c_can_setup_receive_object(dev, IF_RX, C_CAN_MSG_OBJ_RX_LAST, 0, 0, | 548 | c_can_setup_receive_object(dev, IF_RX, C_CAN_MSG_OBJ_RX_LAST, 0, 0, |
601 | IF_MCONT_EOB | IF_MCONT_RXIE | IF_MCONT_UMASK); | 549 | IF_MCONT_RCV_EOB); |
602 | } | 550 | } |
603 | 551 | ||
604 | /* | 552 | /* |
@@ -612,30 +560,22 @@ static int c_can_chip_config(struct net_device *dev) | |||
612 | struct c_can_priv *priv = netdev_priv(dev); | 560 | struct c_can_priv *priv = netdev_priv(dev); |
613 | 561 | ||
614 | /* enable automatic retransmission */ | 562 | /* enable automatic retransmission */ |
615 | priv->write_reg(priv, C_CAN_CTRL_REG, | 563 | priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_ENABLE_AR); |
616 | CONTROL_ENABLE_AR); | ||
617 | 564 | ||
618 | if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) && | 565 | if ((priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) && |
619 | (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) { | 566 | (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK)) { |
620 | /* loopback + silent mode : useful for hot self-test */ | 567 | /* loopback + silent mode : useful for hot self-test */ |
621 | priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE | | 568 | priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST); |
622 | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); | 569 | priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK | TEST_SILENT); |
623 | priv->write_reg(priv, C_CAN_TEST_REG, | ||
624 | TEST_LBACK | TEST_SILENT); | ||
625 | } else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { | 570 | } else if (priv->can.ctrlmode & CAN_CTRLMODE_LOOPBACK) { |
626 | /* loopback mode : useful for self-test function */ | 571 | /* loopback mode : useful for self-test function */ |
627 | priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE | | 572 | priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST); |
628 | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); | ||
629 | priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK); | 573 | priv->write_reg(priv, C_CAN_TEST_REG, TEST_LBACK); |
630 | } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) { | 574 | } else if (priv->can.ctrlmode & CAN_CTRLMODE_LISTENONLY) { |
631 | /* silent mode : bus-monitoring mode */ | 575 | /* silent mode : bus-monitoring mode */ |
632 | priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_EIE | | 576 | priv->write_reg(priv, C_CAN_CTRL_REG, CONTROL_TEST); |
633 | CONTROL_SIE | CONTROL_IE | CONTROL_TEST); | ||
634 | priv->write_reg(priv, C_CAN_TEST_REG, TEST_SILENT); | 577 | priv->write_reg(priv, C_CAN_TEST_REG, TEST_SILENT); |
635 | } else | 578 | } |
636 | /* normal mode*/ | ||
637 | priv->write_reg(priv, C_CAN_CTRL_REG, | ||
638 | CONTROL_EIE | CONTROL_SIE | CONTROL_IE); | ||
639 | 579 | ||
640 | /* configure message objects */ | 580 | /* configure message objects */ |
641 | c_can_configure_msg_objects(dev); | 581 | c_can_configure_msg_objects(dev); |
@@ -643,6 +583,11 @@ static int c_can_chip_config(struct net_device *dev) | |||
643 | /* set a `lec` value so that we can check for updates later */ | 583 | /* set a `lec` value so that we can check for updates later */ |
644 | priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED); | 584 | priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED); |
645 | 585 | ||
586 | /* Clear all internal status */ | ||
587 | atomic_set(&priv->tx_active, 0); | ||
588 | priv->rxmasked = 0; | ||
589 | priv->tx_dir = 0; | ||
590 | |||
646 | /* set bittiming params */ | 591 | /* set bittiming params */ |
647 | return c_can_set_bittiming(dev); | 592 | return c_can_set_bittiming(dev); |
648 | } | 593 | } |
@@ -657,13 +602,11 @@ static int c_can_start(struct net_device *dev) | |||
657 | if (err) | 602 | if (err) |
658 | return err; | 603 | return err; |
659 | 604 | ||
660 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 605 | /* Setup the command for new messages */ |
661 | 606 | priv->comm_rcv_high = priv->type != BOSCH_D_CAN ? | |
662 | /* reset tx helper pointers */ | 607 | IF_COMM_RCV_LOW : IF_COMM_RCV_HIGH; |
663 | priv->tx_next = priv->tx_echo = 0; | ||
664 | 608 | ||
665 | /* enable status change, error and module interrupts */ | 609 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
666 | c_can_enable_all_interrupts(priv, ENABLE_ALL_INTERRUPTS); | ||
667 | 610 | ||
668 | return 0; | 611 | return 0; |
669 | } | 612 | } |
@@ -672,15 +615,13 @@ static void c_can_stop(struct net_device *dev) | |||
672 | { | 615 | { |
673 | struct c_can_priv *priv = netdev_priv(dev); | 616 | struct c_can_priv *priv = netdev_priv(dev); |
674 | 617 | ||
675 | /* disable all interrupts */ | 618 | c_can_irq_control(priv, false); |
676 | c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); | ||
677 | |||
678 | /* set the state as STOPPED */ | ||
679 | priv->can.state = CAN_STATE_STOPPED; | 619 | priv->can.state = CAN_STATE_STOPPED; |
680 | } | 620 | } |
681 | 621 | ||
682 | static int c_can_set_mode(struct net_device *dev, enum can_mode mode) | 622 | static int c_can_set_mode(struct net_device *dev, enum can_mode mode) |
683 | { | 623 | { |
624 | struct c_can_priv *priv = netdev_priv(dev); | ||
684 | int err; | 625 | int err; |
685 | 626 | ||
686 | switch (mode) { | 627 | switch (mode) { |
@@ -689,6 +630,7 @@ static int c_can_set_mode(struct net_device *dev, enum can_mode mode) | |||
689 | if (err) | 630 | if (err) |
690 | return err; | 631 | return err; |
691 | netif_wake_queue(dev); | 632 | netif_wake_queue(dev); |
633 | c_can_irq_control(priv, true); | ||
692 | break; | 634 | break; |
693 | default: | 635 | default: |
694 | return -EOPNOTSUPP; | 636 | return -EOPNOTSUPP; |
@@ -724,42 +666,29 @@ static int c_can_get_berr_counter(const struct net_device *dev, | |||
724 | return err; | 666 | return err; |
725 | } | 667 | } |
726 | 668 | ||
727 | /* | ||
728 | * priv->tx_echo holds the number of the oldest can_frame put for | ||
729 | * transmission into the hardware, but not yet ACKed by the CAN tx | ||
730 | * complete IRQ. | ||
731 | * | ||
732 | * We iterate from priv->tx_echo to priv->tx_next and check if the | ||
733 | * packet has been transmitted, echo it back to the CAN framework. | ||
734 | * If we discover a not yet transmitted packet, stop looking for more. | ||
735 | */ | ||
736 | static void c_can_do_tx(struct net_device *dev) | 669 | static void c_can_do_tx(struct net_device *dev) |
737 | { | 670 | { |
738 | struct c_can_priv *priv = netdev_priv(dev); | 671 | struct c_can_priv *priv = netdev_priv(dev); |
739 | struct net_device_stats *stats = &dev->stats; | 672 | struct net_device_stats *stats = &dev->stats; |
740 | u32 val, obj, pkts = 0, bytes = 0; | 673 | u32 idx, obj, pkts = 0, bytes = 0, pend, clr; |
741 | |||
742 | spin_lock_bh(&priv->xmit_lock); | ||
743 | 674 | ||
744 | for (; (priv->tx_next - priv->tx_echo) > 0; priv->tx_echo++) { | 675 | clr = pend = priv->read_reg(priv, C_CAN_INTPND2_REG); |
745 | obj = get_tx_echo_msg_obj(priv->tx_echo); | ||
746 | val = c_can_read_reg32(priv, C_CAN_TXRQST1_REG); | ||
747 | 676 | ||
748 | if (val & (1 << (obj - 1))) | 677 | while ((idx = ffs(pend))) { |
749 | break; | 678 | idx--; |
750 | 679 | pend &= ~(1 << idx); | |
751 | can_get_echo_skb(dev, obj - C_CAN_MSG_OBJ_TX_FIRST); | 680 | obj = idx + C_CAN_MSG_OBJ_TX_FIRST; |
752 | bytes += priv->dlc[obj - C_CAN_MSG_OBJ_TX_FIRST]; | 681 | c_can_inval_tx_object(dev, IF_RX, obj); |
682 | can_get_echo_skb(dev, idx); | ||
683 | bytes += priv->dlc[idx]; | ||
753 | pkts++; | 684 | pkts++; |
754 | c_can_inval_msg_object(dev, IF_TX, obj); | ||
755 | } | 685 | } |
756 | 686 | ||
757 | /* restart queue if wrap-up or if queue stalled on last pkt */ | 687 | /* Clear the bits in the tx_active mask */ |
758 | if (((priv->tx_next & C_CAN_NEXT_MSG_OBJ_MASK) != 0) || | 688 | atomic_sub(clr, &priv->tx_active); |
759 | ((priv->tx_echo & C_CAN_NEXT_MSG_OBJ_MASK) == 0)) | ||
760 | netif_wake_queue(dev); | ||
761 | 689 | ||
762 | spin_unlock_bh(&priv->xmit_lock); | 690 | if (clr & (1 << (C_CAN_MSG_OBJ_TX_NUM - 1))) |
691 | netif_wake_queue(dev); | ||
763 | 692 | ||
764 | if (pkts) { | 693 | if (pkts) { |
765 | stats->tx_bytes += bytes; | 694 | stats->tx_bytes += bytes; |
@@ -800,18 +729,42 @@ static u32 c_can_adjust_pending(u32 pend) | |||
800 | return pend & ~((1 << lasts) - 1); | 729 | return pend & ~((1 << lasts) - 1); |
801 | } | 730 | } |
802 | 731 | ||
732 | static inline void c_can_rx_object_get(struct net_device *dev, | ||
733 | struct c_can_priv *priv, u32 obj) | ||
734 | { | ||
735 | #ifdef CONFIG_CAN_C_CAN_STRICT_FRAME_ORDERING | ||
736 | if (obj < C_CAN_MSG_RX_LOW_LAST) | ||
737 | c_can_object_get(dev, IF_RX, obj, IF_COMM_RCV_LOW); | ||
738 | else | ||
739 | #endif | ||
740 | c_can_object_get(dev, IF_RX, obj, priv->comm_rcv_high); | ||
741 | } | ||
742 | |||
743 | static inline void c_can_rx_finalize(struct net_device *dev, | ||
744 | struct c_can_priv *priv, u32 obj) | ||
745 | { | ||
746 | #ifdef CONFIG_CAN_C_CAN_STRICT_FRAME_ORDERING | ||
747 | if (obj < C_CAN_MSG_RX_LOW_LAST) | ||
748 | priv->rxmasked |= BIT(obj - 1); | ||
749 | else if (obj == C_CAN_MSG_RX_LOW_LAST) { | ||
750 | priv->rxmasked = 0; | ||
751 | /* activate all lower message objects */ | ||
752 | c_can_activate_all_lower_rx_msg_obj(dev, IF_RX); | ||
753 | } | ||
754 | #endif | ||
755 | if (priv->type != BOSCH_D_CAN) | ||
756 | c_can_object_get(dev, IF_RX, obj, IF_COMM_CLR_NEWDAT); | ||
757 | } | ||
758 | |||
803 | static int c_can_read_objects(struct net_device *dev, struct c_can_priv *priv, | 759 | static int c_can_read_objects(struct net_device *dev, struct c_can_priv *priv, |
804 | u32 pend, int quota) | 760 | u32 pend, int quota) |
805 | { | 761 | { |
806 | u32 pkts = 0, ctrl, obj, mcmd; | 762 | u32 pkts = 0, ctrl, obj; |
807 | 763 | ||
808 | while ((obj = ffs(pend)) && quota > 0) { | 764 | while ((obj = ffs(pend)) && quota > 0) { |
809 | pend &= ~BIT(obj - 1); | 765 | pend &= ~BIT(obj - 1); |
810 | 766 | ||
811 | mcmd = obj < C_CAN_MSG_RX_LOW_LAST ? | 767 | c_can_rx_object_get(dev, priv, obj); |
812 | IF_COMM_RCV_LOW : IF_COMM_RCV_HIGH; | ||
813 | |||
814 | c_can_object_get(dev, IF_RX, obj, mcmd); | ||
815 | ctrl = priv->read_reg(priv, C_CAN_IFACE(MSGCTRL_REG, IF_RX)); | 768 | ctrl = priv->read_reg(priv, C_CAN_IFACE(MSGCTRL_REG, IF_RX)); |
816 | 769 | ||
817 | if (ctrl & IF_MCONT_MSGLST) { | 770 | if (ctrl & IF_MCONT_MSGLST) { |
@@ -833,9 +786,7 @@ static int c_can_read_objects(struct net_device *dev, struct c_can_priv *priv, | |||
833 | /* read the data from the message object */ | 786 | /* read the data from the message object */ |
834 | c_can_read_msg_object(dev, IF_RX, ctrl); | 787 | c_can_read_msg_object(dev, IF_RX, ctrl); |
835 | 788 | ||
836 | if (obj == C_CAN_MSG_RX_LOW_LAST) | 789 | c_can_rx_finalize(dev, priv, obj); |
837 | /* activate all lower message objects */ | ||
838 | c_can_activate_all_lower_rx_msg_obj(dev, IF_RX, ctrl); | ||
839 | 790 | ||
840 | pkts++; | 791 | pkts++; |
841 | quota--; | 792 | quota--; |
@@ -844,6 +795,16 @@ static int c_can_read_objects(struct net_device *dev, struct c_can_priv *priv, | |||
844 | return pkts; | 795 | return pkts; |
845 | } | 796 | } |
846 | 797 | ||
798 | static inline u32 c_can_get_pending(struct c_can_priv *priv) | ||
799 | { | ||
800 | u32 pend = priv->read_reg(priv, C_CAN_NEWDAT1_REG); | ||
801 | |||
802 | #ifdef CONFIG_CAN_C_CAN_STRICT_FRAME_ORDERING | ||
803 | pend &= ~priv->rxmasked; | ||
804 | #endif | ||
805 | return pend; | ||
806 | } | ||
807 | |||
847 | /* | 808 | /* |
848 | * theory of operation: | 809 | * theory of operation: |
849 | * | 810 | * |
@@ -853,6 +814,8 @@ static int c_can_read_objects(struct net_device *dev, struct c_can_priv *priv, | |||
853 | * has arrived. To work-around this issue, we keep two groups of message | 814 | * has arrived. To work-around this issue, we keep two groups of message |
854 | * objects whose partitioning is defined by C_CAN_MSG_OBJ_RX_SPLIT. | 815 | * objects whose partitioning is defined by C_CAN_MSG_OBJ_RX_SPLIT. |
855 | * | 816 | * |
817 | * If CONFIG_CAN_C_CAN_STRICT_FRAME_ORDERING = y | ||
818 | * | ||
856 | * To ensure in-order frame reception we use the following | 819 | * To ensure in-order frame reception we use the following |
857 | * approach while re-activating a message object to receive further | 820 | * approach while re-activating a message object to receive further |
858 | * frames: | 821 | * frames: |
@@ -865,6 +828,14 @@ static int c_can_read_objects(struct net_device *dev, struct c_can_priv *priv, | |||
865 | * - if the current message object number is greater than | 828 | * - if the current message object number is greater than |
866 | * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of | 829 | * C_CAN_MSG_RX_LOW_LAST then clear the NEWDAT bit of |
867 | * only this message object. | 830 | * only this message object. |
831 | * | ||
832 | * This can cause packet loss! | ||
833 | * | ||
834 | * If CONFIG_CAN_C_CAN_STRICT_FRAME_ORDERING = n | ||
835 | * | ||
836 | * We clear the newdat bit right away. | ||
837 | * | ||
838 | * This can result in packet reordering when the readout is slow. | ||
868 | */ | 839 | */ |
869 | static int c_can_do_rx_poll(struct net_device *dev, int quota) | 840 | static int c_can_do_rx_poll(struct net_device *dev, int quota) |
870 | { | 841 | { |
@@ -880,7 +851,7 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota) | |||
880 | 851 | ||
881 | while (quota > 0) { | 852 | while (quota > 0) { |
882 | if (!pend) { | 853 | if (!pend) { |
883 | pend = priv->read_reg(priv, C_CAN_INTPND1_REG); | 854 | pend = c_can_get_pending(priv); |
884 | if (!pend) | 855 | if (!pend) |
885 | break; | 856 | break; |
886 | /* | 857 | /* |
@@ -905,12 +876,6 @@ static int c_can_do_rx_poll(struct net_device *dev, int quota) | |||
905 | return pkts; | 876 | return pkts; |
906 | } | 877 | } |
907 | 878 | ||
908 | static inline int c_can_has_and_handle_berr(struct c_can_priv *priv) | ||
909 | { | ||
910 | return (priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) && | ||
911 | (priv->current_status & LEC_UNUSED); | ||
912 | } | ||
913 | |||
914 | static int c_can_handle_state_change(struct net_device *dev, | 879 | static int c_can_handle_state_change(struct net_device *dev, |
915 | enum c_can_bus_error_types error_type) | 880 | enum c_can_bus_error_types error_type) |
916 | { | 881 | { |
@@ -922,6 +887,26 @@ static int c_can_handle_state_change(struct net_device *dev, | |||
922 | struct sk_buff *skb; | 887 | struct sk_buff *skb; |
923 | struct can_berr_counter bec; | 888 | struct can_berr_counter bec; |
924 | 889 | ||
890 | switch (error_type) { | ||
891 | case C_CAN_ERROR_WARNING: | ||
892 | /* error warning state */ | ||
893 | priv->can.can_stats.error_warning++; | ||
894 | priv->can.state = CAN_STATE_ERROR_WARNING; | ||
895 | break; | ||
896 | case C_CAN_ERROR_PASSIVE: | ||
897 | /* error passive state */ | ||
898 | priv->can.can_stats.error_passive++; | ||
899 | priv->can.state = CAN_STATE_ERROR_PASSIVE; | ||
900 | break; | ||
901 | case C_CAN_BUS_OFF: | ||
902 | /* bus-off state */ | ||
903 | priv->can.state = CAN_STATE_BUS_OFF; | ||
904 | can_bus_off(dev); | ||
905 | break; | ||
906 | default: | ||
907 | break; | ||
908 | } | ||
909 | |||
925 | /* propagate the error condition to the CAN stack */ | 910 | /* propagate the error condition to the CAN stack */ |
926 | skb = alloc_can_err_skb(dev, &cf); | 911 | skb = alloc_can_err_skb(dev, &cf); |
927 | if (unlikely(!skb)) | 912 | if (unlikely(!skb)) |
@@ -935,8 +920,6 @@ static int c_can_handle_state_change(struct net_device *dev, | |||
935 | switch (error_type) { | 920 | switch (error_type) { |
936 | case C_CAN_ERROR_WARNING: | 921 | case C_CAN_ERROR_WARNING: |
937 | /* error warning state */ | 922 | /* error warning state */ |
938 | priv->can.can_stats.error_warning++; | ||
939 | priv->can.state = CAN_STATE_ERROR_WARNING; | ||
940 | cf->can_id |= CAN_ERR_CRTL; | 923 | cf->can_id |= CAN_ERR_CRTL; |
941 | cf->data[1] = (bec.txerr > bec.rxerr) ? | 924 | cf->data[1] = (bec.txerr > bec.rxerr) ? |
942 | CAN_ERR_CRTL_TX_WARNING : | 925 | CAN_ERR_CRTL_TX_WARNING : |
@@ -947,8 +930,6 @@ static int c_can_handle_state_change(struct net_device *dev, | |||
947 | break; | 930 | break; |
948 | case C_CAN_ERROR_PASSIVE: | 931 | case C_CAN_ERROR_PASSIVE: |
949 | /* error passive state */ | 932 | /* error passive state */ |
950 | priv->can.can_stats.error_passive++; | ||
951 | priv->can.state = CAN_STATE_ERROR_PASSIVE; | ||
952 | cf->can_id |= CAN_ERR_CRTL; | 933 | cf->can_id |= CAN_ERR_CRTL; |
953 | if (rx_err_passive) | 934 | if (rx_err_passive) |
954 | cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; | 935 | cf->data[1] |= CAN_ERR_CRTL_RX_PASSIVE; |
@@ -960,22 +941,16 @@ static int c_can_handle_state_change(struct net_device *dev, | |||
960 | break; | 941 | break; |
961 | case C_CAN_BUS_OFF: | 942 | case C_CAN_BUS_OFF: |
962 | /* bus-off state */ | 943 | /* bus-off state */ |
963 | priv->can.state = CAN_STATE_BUS_OFF; | ||
964 | cf->can_id |= CAN_ERR_BUSOFF; | 944 | cf->can_id |= CAN_ERR_BUSOFF; |
965 | /* | ||
966 | * disable all interrupts in bus-off mode to ensure that | ||
967 | * the CPU is not hogged down | ||
968 | */ | ||
969 | c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); | ||
970 | can_bus_off(dev); | 945 | can_bus_off(dev); |
971 | break; | 946 | break; |
972 | default: | 947 | default: |
973 | break; | 948 | break; |
974 | } | 949 | } |
975 | 950 | ||
976 | netif_receive_skb(skb); | ||
977 | stats->rx_packets++; | 951 | stats->rx_packets++; |
978 | stats->rx_bytes += cf->can_dlc; | 952 | stats->rx_bytes += cf->can_dlc; |
953 | netif_receive_skb(skb); | ||
979 | 954 | ||
980 | return 1; | 955 | return 1; |
981 | } | 956 | } |
@@ -996,6 +971,13 @@ static int c_can_handle_bus_err(struct net_device *dev, | |||
996 | if (lec_type == LEC_UNUSED || lec_type == LEC_NO_ERROR) | 971 | if (lec_type == LEC_UNUSED || lec_type == LEC_NO_ERROR) |
997 | return 0; | 972 | return 0; |
998 | 973 | ||
974 | if (!(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) | ||
975 | return 0; | ||
976 | |||
977 | /* common for all type of bus errors */ | ||
978 | priv->can.can_stats.bus_error++; | ||
979 | stats->rx_errors++; | ||
980 | |||
999 | /* propagate the error condition to the CAN stack */ | 981 | /* propagate the error condition to the CAN stack */ |
1000 | skb = alloc_can_err_skb(dev, &cf); | 982 | skb = alloc_can_err_skb(dev, &cf); |
1001 | if (unlikely(!skb)) | 983 | if (unlikely(!skb)) |
@@ -1005,10 +987,6 @@ static int c_can_handle_bus_err(struct net_device *dev, | |||
1005 | * check for 'last error code' which tells us the | 987 | * check for 'last error code' which tells us the |
1006 | * type of the last error to occur on the CAN bus | 988 | * type of the last error to occur on the CAN bus |
1007 | */ | 989 | */ |
1008 | |||
1009 | /* common for all type of bus errors */ | ||
1010 | priv->can.can_stats.bus_error++; | ||
1011 | stats->rx_errors++; | ||
1012 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; | 990 | cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR; |
1013 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; | 991 | cf->data[2] |= CAN_ERR_PROT_UNSPEC; |
1014 | 992 | ||
@@ -1043,95 +1021,64 @@ static int c_can_handle_bus_err(struct net_device *dev, | |||
1043 | break; | 1021 | break; |
1044 | } | 1022 | } |
1045 | 1023 | ||
1046 | /* set a `lec` value so that we can check for updates later */ | ||
1047 | priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED); | ||
1048 | |||
1049 | netif_receive_skb(skb); | ||
1050 | stats->rx_packets++; | 1024 | stats->rx_packets++; |
1051 | stats->rx_bytes += cf->can_dlc; | 1025 | stats->rx_bytes += cf->can_dlc; |
1052 | 1026 | netif_receive_skb(skb); | |
1053 | return 1; | 1027 | return 1; |
1054 | } | 1028 | } |
1055 | 1029 | ||
1056 | static int c_can_poll(struct napi_struct *napi, int quota) | 1030 | static int c_can_poll(struct napi_struct *napi, int quota) |
1057 | { | 1031 | { |
1058 | u16 irqstatus; | ||
1059 | int lec_type = 0; | ||
1060 | int work_done = 0; | ||
1061 | struct net_device *dev = napi->dev; | 1032 | struct net_device *dev = napi->dev; |
1062 | struct c_can_priv *priv = netdev_priv(dev); | 1033 | struct c_can_priv *priv = netdev_priv(dev); |
1034 | u16 curr, last = priv->last_status; | ||
1035 | int work_done = 0; | ||
1063 | 1036 | ||
1064 | irqstatus = priv->irqstatus; | 1037 | priv->last_status = curr = priv->read_reg(priv, C_CAN_STS_REG); |
1065 | if (!irqstatus) | 1038 | /* Ack status on C_CAN. D_CAN is self clearing */ |
1066 | goto end; | 1039 | if (priv->type != BOSCH_D_CAN) |
1040 | priv->write_reg(priv, C_CAN_STS_REG, LEC_UNUSED); | ||
1067 | 1041 | ||
1068 | /* status events have the highest priority */ | 1042 | /* handle state changes */ |
1069 | if (irqstatus == STATUS_INTERRUPT) { | 1043 | if ((curr & STATUS_EWARN) && (!(last & STATUS_EWARN))) { |
1070 | priv->current_status = priv->read_reg(priv, | 1044 | netdev_dbg(dev, "entered error warning state\n"); |
1071 | C_CAN_STS_REG); | 1045 | work_done += c_can_handle_state_change(dev, C_CAN_ERROR_WARNING); |
1072 | 1046 | } | |
1073 | /* handle Tx/Rx events */ | ||
1074 | if (priv->current_status & STATUS_TXOK) | ||
1075 | priv->write_reg(priv, C_CAN_STS_REG, | ||
1076 | priv->current_status & ~STATUS_TXOK); | ||
1077 | |||
1078 | if (priv->current_status & STATUS_RXOK) | ||
1079 | priv->write_reg(priv, C_CAN_STS_REG, | ||
1080 | priv->current_status & ~STATUS_RXOK); | ||
1081 | |||
1082 | /* handle state changes */ | ||
1083 | if ((priv->current_status & STATUS_EWARN) && | ||
1084 | (!(priv->last_status & STATUS_EWARN))) { | ||
1085 | netdev_dbg(dev, "entered error warning state\n"); | ||
1086 | work_done += c_can_handle_state_change(dev, | ||
1087 | C_CAN_ERROR_WARNING); | ||
1088 | } | ||
1089 | if ((priv->current_status & STATUS_EPASS) && | ||
1090 | (!(priv->last_status & STATUS_EPASS))) { | ||
1091 | netdev_dbg(dev, "entered error passive state\n"); | ||
1092 | work_done += c_can_handle_state_change(dev, | ||
1093 | C_CAN_ERROR_PASSIVE); | ||
1094 | } | ||
1095 | if ((priv->current_status & STATUS_BOFF) && | ||
1096 | (!(priv->last_status & STATUS_BOFF))) { | ||
1097 | netdev_dbg(dev, "entered bus off state\n"); | ||
1098 | work_done += c_can_handle_state_change(dev, | ||
1099 | C_CAN_BUS_OFF); | ||
1100 | } | ||
1101 | 1047 | ||
1102 | /* handle bus recovery events */ | 1048 | if ((curr & STATUS_EPASS) && (!(last & STATUS_EPASS))) { |
1103 | if ((!(priv->current_status & STATUS_BOFF)) && | 1049 | netdev_dbg(dev, "entered error passive state\n"); |
1104 | (priv->last_status & STATUS_BOFF)) { | 1050 | work_done += c_can_handle_state_change(dev, C_CAN_ERROR_PASSIVE); |
1105 | netdev_dbg(dev, "left bus off state\n"); | 1051 | } |
1106 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 1052 | |
1107 | } | 1053 | if ((curr & STATUS_BOFF) && (!(last & STATUS_BOFF))) { |
1108 | if ((!(priv->current_status & STATUS_EPASS)) && | 1054 | netdev_dbg(dev, "entered bus off state\n"); |
1109 | (priv->last_status & STATUS_EPASS)) { | 1055 | work_done += c_can_handle_state_change(dev, C_CAN_BUS_OFF); |
1110 | netdev_dbg(dev, "left error passive state\n"); | 1056 | goto end; |
1111 | priv->can.state = CAN_STATE_ERROR_ACTIVE; | 1057 | } |
1112 | } | ||
1113 | 1058 | ||
1114 | priv->last_status = priv->current_status; | 1059 | /* handle bus recovery events */ |
1115 | 1060 | if ((!(curr & STATUS_BOFF)) && (last & STATUS_BOFF)) { | |
1116 | /* handle lec errors on the bus */ | 1061 | netdev_dbg(dev, "left bus off state\n"); |
1117 | lec_type = c_can_has_and_handle_berr(priv); | 1062 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
1118 | if (lec_type) | 1063 | } |
1119 | work_done += c_can_handle_bus_err(dev, lec_type); | 1064 | if ((!(curr & STATUS_EPASS)) && (last & STATUS_EPASS)) { |
1120 | } else if ((irqstatus >= C_CAN_MSG_OBJ_RX_FIRST) && | 1065 | netdev_dbg(dev, "left error passive state\n"); |
1121 | (irqstatus <= C_CAN_MSG_OBJ_RX_LAST)) { | 1066 | priv->can.state = CAN_STATE_ERROR_ACTIVE; |
1122 | /* handle events corresponding to receive message objects */ | ||
1123 | work_done += c_can_do_rx_poll(dev, (quota - work_done)); | ||
1124 | } else if ((irqstatus >= C_CAN_MSG_OBJ_TX_FIRST) && | ||
1125 | (irqstatus <= C_CAN_MSG_OBJ_TX_LAST)) { | ||
1126 | /* handle events corresponding to transmit message objects */ | ||
1127 | c_can_do_tx(dev); | ||
1128 | } | 1067 | } |
1129 | 1068 | ||
1069 | /* handle lec errors on the bus */ | ||
1070 | work_done += c_can_handle_bus_err(dev, curr & LEC_MASK); | ||
1071 | |||
1072 | /* Handle Tx/Rx events. We do this unconditionally */ | ||
1073 | work_done += c_can_do_rx_poll(dev, (quota - work_done)); | ||
1074 | c_can_do_tx(dev); | ||
1075 | |||
1130 | end: | 1076 | end: |
1131 | if (work_done < quota) { | 1077 | if (work_done < quota) { |
1132 | napi_complete(napi); | 1078 | napi_complete(napi); |
1133 | /* enable all IRQs */ | 1079 | /* enable all IRQs if we are not in bus off state */ |
1134 | c_can_enable_all_interrupts(priv, ENABLE_ALL_INTERRUPTS); | 1080 | if (priv->can.state != CAN_STATE_BUS_OFF) |
1081 | c_can_irq_control(priv, true); | ||
1135 | } | 1082 | } |
1136 | 1083 | ||
1137 | return work_done; | 1084 | return work_done; |
@@ -1142,12 +1089,11 @@ static irqreturn_t c_can_isr(int irq, void *dev_id) | |||
1142 | struct net_device *dev = (struct net_device *)dev_id; | 1089 | struct net_device *dev = (struct net_device *)dev_id; |
1143 | struct c_can_priv *priv = netdev_priv(dev); | 1090 | struct c_can_priv *priv = netdev_priv(dev); |
1144 | 1091 | ||
1145 | priv->irqstatus = priv->read_reg(priv, C_CAN_INT_REG); | 1092 | if (!priv->read_reg(priv, C_CAN_INT_REG)) |
1146 | if (!priv->irqstatus) | ||
1147 | return IRQ_NONE; | 1093 | return IRQ_NONE; |
1148 | 1094 | ||
1149 | /* disable all interrupts and schedule the NAPI */ | 1095 | /* disable all interrupts and schedule the NAPI */ |
1150 | c_can_enable_all_interrupts(priv, DISABLE_ALL_INTERRUPTS); | 1096 | c_can_irq_control(priv, false); |
1151 | napi_schedule(&priv->napi); | 1097 | napi_schedule(&priv->napi); |
1152 | 1098 | ||
1153 | return IRQ_HANDLED; | 1099 | return IRQ_HANDLED; |
@@ -1184,6 +1130,8 @@ static int c_can_open(struct net_device *dev) | |||
1184 | can_led_event(dev, CAN_LED_EVENT_OPEN); | 1130 | can_led_event(dev, CAN_LED_EVENT_OPEN); |
1185 | 1131 | ||
1186 | napi_enable(&priv->napi); | 1132 | napi_enable(&priv->napi); |
1133 | /* enable status change, error and module interrupts */ | ||
1134 | c_can_irq_control(priv, true); | ||
1187 | netif_start_queue(dev); | 1135 | netif_start_queue(dev); |
1188 | 1136 | ||
1189 | return 0; | 1137 | return 0; |
@@ -1226,7 +1174,6 @@ struct net_device *alloc_c_can_dev(void) | |||
1226 | return NULL; | 1174 | return NULL; |
1227 | 1175 | ||
1228 | priv = netdev_priv(dev); | 1176 | priv = netdev_priv(dev); |
1229 | spin_lock_init(&priv->xmit_lock); | ||
1230 | netif_napi_add(dev, &priv->napi, c_can_poll, C_CAN_NAPI_WEIGHT); | 1177 | netif_napi_add(dev, &priv->napi, c_can_poll, C_CAN_NAPI_WEIGHT); |
1231 | 1178 | ||
1232 | priv->dev = dev; | 1179 | priv->dev = dev; |
@@ -1281,6 +1228,7 @@ int c_can_power_up(struct net_device *dev) | |||
1281 | u32 val; | 1228 | u32 val; |
1282 | unsigned long time_out; | 1229 | unsigned long time_out; |
1283 | struct c_can_priv *priv = netdev_priv(dev); | 1230 | struct c_can_priv *priv = netdev_priv(dev); |
1231 | int ret; | ||
1284 | 1232 | ||
1285 | if (!(dev->flags & IFF_UP)) | 1233 | if (!(dev->flags & IFF_UP)) |
1286 | return 0; | 1234 | return 0; |
@@ -1307,7 +1255,11 @@ int c_can_power_up(struct net_device *dev) | |||
1307 | if (time_after(jiffies, time_out)) | 1255 | if (time_after(jiffies, time_out)) |
1308 | return -ETIMEDOUT; | 1256 | return -ETIMEDOUT; |
1309 | 1257 | ||
1310 | return c_can_start(dev); | 1258 | ret = c_can_start(dev); |
1259 | if (!ret) | ||
1260 | c_can_irq_control(priv, true); | ||
1261 | |||
1262 | return ret; | ||
1311 | } | 1263 | } |
1312 | EXPORT_SYMBOL_GPL(c_can_power_up); | 1264 | EXPORT_SYMBOL_GPL(c_can_power_up); |
1313 | #endif | 1265 | #endif |
diff --git a/drivers/net/can/c_can/c_can.h b/drivers/net/can/c_can/c_can.h index faa8404162b3..c56f1b1c11ca 100644 --- a/drivers/net/can/c_can/c_can.h +++ b/drivers/net/can/c_can/c_can.h | |||
@@ -22,14 +22,6 @@ | |||
22 | #ifndef C_CAN_H | 22 | #ifndef C_CAN_H |
23 | #define C_CAN_H | 23 | #define C_CAN_H |
24 | 24 | ||
25 | /* | ||
26 | * IFx register masks: | ||
27 | * allow easy operation on 16-bit registers when the | ||
28 | * argument is 32-bit instead | ||
29 | */ | ||
30 | #define IFX_WRITE_LOW_16BIT(x) ((x) & 0xFFFF) | ||
31 | #define IFX_WRITE_HIGH_16BIT(x) (((x) & 0xFFFF0000) >> 16) | ||
32 | |||
33 | /* message object split */ | 25 | /* message object split */ |
34 | #define C_CAN_NO_OF_OBJECTS 32 | 26 | #define C_CAN_NO_OF_OBJECTS 32 |
35 | #define C_CAN_MSG_OBJ_RX_NUM 16 | 27 | #define C_CAN_MSG_OBJ_RX_NUM 16 |
@@ -45,8 +37,6 @@ | |||
45 | 37 | ||
46 | #define C_CAN_MSG_OBJ_RX_SPLIT 9 | 38 | #define C_CAN_MSG_OBJ_RX_SPLIT 9 |
47 | #define C_CAN_MSG_RX_LOW_LAST (C_CAN_MSG_OBJ_RX_SPLIT - 1) | 39 | #define C_CAN_MSG_RX_LOW_LAST (C_CAN_MSG_OBJ_RX_SPLIT - 1) |
48 | |||
49 | #define C_CAN_NEXT_MSG_OBJ_MASK (C_CAN_MSG_OBJ_TX_NUM - 1) | ||
50 | #define RECEIVE_OBJECT_BITS 0x0000ffff | 40 | #define RECEIVE_OBJECT_BITS 0x0000ffff |
51 | 41 | ||
52 | enum reg { | 42 | enum reg { |
@@ -183,23 +173,20 @@ struct c_can_priv { | |||
183 | struct napi_struct napi; | 173 | struct napi_struct napi; |
184 | struct net_device *dev; | 174 | struct net_device *dev; |
185 | struct device *device; | 175 | struct device *device; |
186 | spinlock_t xmit_lock; | 176 | atomic_t tx_active; |
187 | int tx_object; | 177 | unsigned long tx_dir; |
188 | int current_status; | ||
189 | int last_status; | 178 | int last_status; |
190 | u16 (*read_reg) (struct c_can_priv *priv, enum reg index); | 179 | u16 (*read_reg) (struct c_can_priv *priv, enum reg index); |
191 | void (*write_reg) (struct c_can_priv *priv, enum reg index, u16 val); | 180 | void (*write_reg) (struct c_can_priv *priv, enum reg index, u16 val); |
192 | void __iomem *base; | 181 | void __iomem *base; |
193 | const u16 *regs; | 182 | const u16 *regs; |
194 | unsigned long irq_flags; /* for request_irq() */ | ||
195 | unsigned int tx_next; | ||
196 | unsigned int tx_echo; | ||
197 | void *priv; /* for board-specific data */ | 183 | void *priv; /* for board-specific data */ |
198 | u16 irqstatus; | ||
199 | enum c_can_dev_id type; | 184 | enum c_can_dev_id type; |
200 | u32 __iomem *raminit_ctrlreg; | 185 | u32 __iomem *raminit_ctrlreg; |
201 | unsigned int instance; | 186 | int instance; |
202 | void (*raminit) (const struct c_can_priv *priv, bool enable); | 187 | void (*raminit) (const struct c_can_priv *priv, bool enable); |
188 | u32 comm_rcv_high; | ||
189 | u32 rxmasked; | ||
203 | u32 dlc[C_CAN_MSG_OBJ_TX_NUM]; | 190 | u32 dlc[C_CAN_MSG_OBJ_TX_NUM]; |
204 | }; | 191 | }; |
205 | 192 | ||
diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c index bce0be54c2f5..fe5f6303b584 100644 --- a/drivers/net/can/c_can/c_can_pci.c +++ b/drivers/net/can/c_can/c_can_pci.c | |||
@@ -84,8 +84,11 @@ static int c_can_pci_probe(struct pci_dev *pdev, | |||
84 | goto out_disable_device; | 84 | goto out_disable_device; |
85 | } | 85 | } |
86 | 86 | ||
87 | pci_set_master(pdev); | 87 | ret = pci_enable_msi(pdev); |
88 | pci_enable_msi(pdev); | 88 | if (!ret) { |
89 | dev_info(&pdev->dev, "MSI enabled\n"); | ||
90 | pci_set_master(pdev); | ||
91 | } | ||
89 | 92 | ||
90 | addr = pci_iomap(pdev, 0, pci_resource_len(pdev, 0)); | 93 | addr = pci_iomap(pdev, 0, pci_resource_len(pdev, 0)); |
91 | if (!addr) { | 94 | if (!addr) { |
@@ -132,6 +135,8 @@ static int c_can_pci_probe(struct pci_dev *pdev, | |||
132 | goto out_free_c_can; | 135 | goto out_free_c_can; |
133 | } | 136 | } |
134 | 137 | ||
138 | priv->type = c_can_pci_data->type; | ||
139 | |||
135 | /* Configure access to registers */ | 140 | /* Configure access to registers */ |
136 | switch (c_can_pci_data->reg_align) { | 141 | switch (c_can_pci_data->reg_align) { |
137 | case C_CAN_REG_ALIGN_32: | 142 | case C_CAN_REG_ALIGN_32: |
diff --git a/drivers/net/can/c_can/c_can_platform.c b/drivers/net/can/c_can/c_can_platform.c index 806d92753427..1df0b322d1e4 100644 --- a/drivers/net/can/c_can/c_can_platform.c +++ b/drivers/net/can/c_can/c_can_platform.c | |||
@@ -222,7 +222,7 @@ static int c_can_plat_probe(struct platform_device *pdev) | |||
222 | 222 | ||
223 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | 223 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); |
224 | priv->raminit_ctrlreg = devm_ioremap_resource(&pdev->dev, res); | 224 | priv->raminit_ctrlreg = devm_ioremap_resource(&pdev->dev, res); |
225 | if (IS_ERR(priv->raminit_ctrlreg) || (int)priv->instance < 0) | 225 | if (IS_ERR(priv->raminit_ctrlreg) || priv->instance < 0) |
226 | dev_info(&pdev->dev, "control memory is not used for raminit\n"); | 226 | dev_info(&pdev->dev, "control memory is not used for raminit\n"); |
227 | else | 227 | else |
228 | priv->raminit = c_can_hw_raminit; | 228 | priv->raminit = c_can_hw_raminit; |
diff --git a/drivers/net/can/dev.c b/drivers/net/can/dev.c index c7a260478749..e318e87e2bfc 100644 --- a/drivers/net/can/dev.c +++ b/drivers/net/can/dev.c | |||
@@ -256,7 +256,7 @@ static int can_get_bittiming(struct net_device *dev, struct can_bittiming *bt, | |||
256 | 256 | ||
257 | /* Check if the CAN device has bit-timing parameters */ | 257 | /* Check if the CAN device has bit-timing parameters */ |
258 | if (!btc) | 258 | if (!btc) |
259 | return -ENOTSUPP; | 259 | return -EOPNOTSUPP; |
260 | 260 | ||
261 | /* | 261 | /* |
262 | * Depending on the given can_bittiming parameter structure the CAN | 262 | * Depending on the given can_bittiming parameter structure the CAN |
diff --git a/drivers/net/can/sja1000/sja1000_isa.c b/drivers/net/can/sja1000/sja1000_isa.c index df136a2516c4..014695d7e6a3 100644 --- a/drivers/net/can/sja1000/sja1000_isa.c +++ b/drivers/net/can/sja1000/sja1000_isa.c | |||
@@ -46,6 +46,7 @@ static int clk[MAXDEV]; | |||
46 | static unsigned char cdr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff}; | 46 | static unsigned char cdr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff}; |
47 | static unsigned char ocr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff}; | 47 | static unsigned char ocr[MAXDEV] = {[0 ... (MAXDEV - 1)] = 0xff}; |
48 | static int indirect[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1}; | 48 | static int indirect[MAXDEV] = {[0 ... (MAXDEV - 1)] = -1}; |
49 | static spinlock_t indirect_lock[MAXDEV]; /* lock for indirect access mode */ | ||
49 | 50 | ||
50 | module_param_array(port, ulong, NULL, S_IRUGO); | 51 | module_param_array(port, ulong, NULL, S_IRUGO); |
51 | MODULE_PARM_DESC(port, "I/O port number"); | 52 | MODULE_PARM_DESC(port, "I/O port number"); |
@@ -101,19 +102,26 @@ static void sja1000_isa_port_write_reg(const struct sja1000_priv *priv, | |||
101 | static u8 sja1000_isa_port_read_reg_indirect(const struct sja1000_priv *priv, | 102 | static u8 sja1000_isa_port_read_reg_indirect(const struct sja1000_priv *priv, |
102 | int reg) | 103 | int reg) |
103 | { | 104 | { |
104 | unsigned long base = (unsigned long)priv->reg_base; | 105 | unsigned long flags, base = (unsigned long)priv->reg_base; |
106 | u8 readval; | ||
105 | 107 | ||
108 | spin_lock_irqsave(&indirect_lock[priv->dev->dev_id], flags); | ||
106 | outb(reg, base); | 109 | outb(reg, base); |
107 | return inb(base + 1); | 110 | readval = inb(base + 1); |
111 | spin_unlock_irqrestore(&indirect_lock[priv->dev->dev_id], flags); | ||
112 | |||
113 | return readval; | ||
108 | } | 114 | } |
109 | 115 | ||
110 | static void sja1000_isa_port_write_reg_indirect(const struct sja1000_priv *priv, | 116 | static void sja1000_isa_port_write_reg_indirect(const struct sja1000_priv *priv, |
111 | int reg, u8 val) | 117 | int reg, u8 val) |
112 | { | 118 | { |
113 | unsigned long base = (unsigned long)priv->reg_base; | 119 | unsigned long flags, base = (unsigned long)priv->reg_base; |
114 | 120 | ||
121 | spin_lock_irqsave(&indirect_lock[priv->dev->dev_id], flags); | ||
115 | outb(reg, base); | 122 | outb(reg, base); |
116 | outb(val, base + 1); | 123 | outb(val, base + 1); |
124 | spin_unlock_irqrestore(&indirect_lock[priv->dev->dev_id], flags); | ||
117 | } | 125 | } |
118 | 126 | ||
119 | static int sja1000_isa_probe(struct platform_device *pdev) | 127 | static int sja1000_isa_probe(struct platform_device *pdev) |
@@ -169,6 +177,7 @@ static int sja1000_isa_probe(struct platform_device *pdev) | |||
169 | if (iosize == SJA1000_IOSIZE_INDIRECT) { | 177 | if (iosize == SJA1000_IOSIZE_INDIRECT) { |
170 | priv->read_reg = sja1000_isa_port_read_reg_indirect; | 178 | priv->read_reg = sja1000_isa_port_read_reg_indirect; |
171 | priv->write_reg = sja1000_isa_port_write_reg_indirect; | 179 | priv->write_reg = sja1000_isa_port_write_reg_indirect; |
180 | spin_lock_init(&indirect_lock[idx]); | ||
172 | } else { | 181 | } else { |
173 | priv->read_reg = sja1000_isa_port_read_reg; | 182 | priv->read_reg = sja1000_isa_port_read_reg; |
174 | priv->write_reg = sja1000_isa_port_write_reg; | 183 | priv->write_reg = sja1000_isa_port_write_reg; |
@@ -198,6 +207,7 @@ static int sja1000_isa_probe(struct platform_device *pdev) | |||
198 | 207 | ||
199 | platform_set_drvdata(pdev, dev); | 208 | platform_set_drvdata(pdev, dev); |
200 | SET_NETDEV_DEV(dev, &pdev->dev); | 209 | SET_NETDEV_DEV(dev, &pdev->dev); |
210 | dev->dev_id = idx; | ||
201 | 211 | ||
202 | err = register_sja1000dev(dev); | 212 | err = register_sja1000dev(dev); |
203 | if (err) { | 213 | if (err) { |
diff --git a/drivers/net/can/slcan.c b/drivers/net/can/slcan.c index f5b16e0e3a12..dcf9196f6316 100644 --- a/drivers/net/can/slcan.c +++ b/drivers/net/can/slcan.c | |||
@@ -322,13 +322,13 @@ static void slcan_write_wakeup(struct tty_struct *tty) | |||
322 | if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) | 322 | if (!sl || sl->magic != SLCAN_MAGIC || !netif_running(sl->dev)) |
323 | return; | 323 | return; |
324 | 324 | ||
325 | spin_lock(&sl->lock); | 325 | spin_lock_bh(&sl->lock); |
326 | if (sl->xleft <= 0) { | 326 | if (sl->xleft <= 0) { |
327 | /* Now serial buffer is almost free & we can start | 327 | /* Now serial buffer is almost free & we can start |
328 | * transmission of another packet */ | 328 | * transmission of another packet */ |
329 | sl->dev->stats.tx_packets++; | 329 | sl->dev->stats.tx_packets++; |
330 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 330 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
331 | spin_unlock(&sl->lock); | 331 | spin_unlock_bh(&sl->lock); |
332 | netif_wake_queue(sl->dev); | 332 | netif_wake_queue(sl->dev); |
333 | return; | 333 | return; |
334 | } | 334 | } |
@@ -336,7 +336,7 @@ static void slcan_write_wakeup(struct tty_struct *tty) | |||
336 | actual = tty->ops->write(tty, sl->xhead, sl->xleft); | 336 | actual = tty->ops->write(tty, sl->xhead, sl->xleft); |
337 | sl->xleft -= actual; | 337 | sl->xleft -= actual; |
338 | sl->xhead += actual; | 338 | sl->xhead += actual; |
339 | spin_unlock(&sl->lock); | 339 | spin_unlock_bh(&sl->lock); |
340 | } | 340 | } |
341 | 341 | ||
342 | /* Send a can_frame to a TTY queue. */ | 342 | /* Send a can_frame to a TTY queue. */ |
diff --git a/drivers/net/ethernet/altera/Kconfig b/drivers/net/ethernet/altera/Kconfig index 80c1ab74a4b8..fdddba51473e 100644 --- a/drivers/net/ethernet/altera/Kconfig +++ b/drivers/net/ethernet/altera/Kconfig | |||
@@ -1,5 +1,6 @@ | |||
1 | config ALTERA_TSE | 1 | config ALTERA_TSE |
2 | tristate "Altera Triple-Speed Ethernet MAC support" | 2 | tristate "Altera Triple-Speed Ethernet MAC support" |
3 | depends on HAS_DMA | ||
3 | select PHYLIB | 4 | select PHYLIB |
4 | ---help--- | 5 | ---help--- |
5 | This driver supports the Altera Triple-Speed (TSE) Ethernet MAC. | 6 | This driver supports the Altera Triple-Speed (TSE) Ethernet MAC. |
diff --git a/drivers/net/ethernet/altera/altera_msgdma.c b/drivers/net/ethernet/altera/altera_msgdma.c index 3df18669ea30..4d1f2fdd5c32 100644 --- a/drivers/net/ethernet/altera/altera_msgdma.c +++ b/drivers/net/ethernet/altera/altera_msgdma.c | |||
@@ -18,6 +18,7 @@ | |||
18 | #include "altera_utils.h" | 18 | #include "altera_utils.h" |
19 | #include "altera_tse.h" | 19 | #include "altera_tse.h" |
20 | #include "altera_msgdmahw.h" | 20 | #include "altera_msgdmahw.h" |
21 | #include "altera_msgdma.h" | ||
21 | 22 | ||
22 | /* No initialization work to do for MSGDMA */ | 23 | /* No initialization work to do for MSGDMA */ |
23 | int msgdma_initialize(struct altera_tse_private *priv) | 24 | int msgdma_initialize(struct altera_tse_private *priv) |
@@ -29,6 +30,10 @@ void msgdma_uninitialize(struct altera_tse_private *priv) | |||
29 | { | 30 | { |
30 | } | 31 | } |
31 | 32 | ||
33 | void msgdma_start_rxdma(struct altera_tse_private *priv) | ||
34 | { | ||
35 | } | ||
36 | |||
32 | void msgdma_reset(struct altera_tse_private *priv) | 37 | void msgdma_reset(struct altera_tse_private *priv) |
33 | { | 38 | { |
34 | int counter; | 39 | int counter; |
@@ -154,7 +159,7 @@ u32 msgdma_tx_completions(struct altera_tse_private *priv) | |||
154 | 159 | ||
155 | /* Put buffer to the mSGDMA RX FIFO | 160 | /* Put buffer to the mSGDMA RX FIFO |
156 | */ | 161 | */ |
157 | int msgdma_add_rx_desc(struct altera_tse_private *priv, | 162 | void msgdma_add_rx_desc(struct altera_tse_private *priv, |
158 | struct tse_buffer *rxbuffer) | 163 | struct tse_buffer *rxbuffer) |
159 | { | 164 | { |
160 | struct msgdma_extended_desc *desc = priv->rx_dma_desc; | 165 | struct msgdma_extended_desc *desc = priv->rx_dma_desc; |
@@ -175,7 +180,6 @@ int msgdma_add_rx_desc(struct altera_tse_private *priv, | |||
175 | iowrite32(0, &desc->burst_seq_num); | 180 | iowrite32(0, &desc->burst_seq_num); |
176 | iowrite32(0x00010001, &desc->stride); | 181 | iowrite32(0x00010001, &desc->stride); |
177 | iowrite32(control, &desc->control); | 182 | iowrite32(control, &desc->control); |
178 | return 1; | ||
179 | } | 183 | } |
180 | 184 | ||
181 | /* status is returned on upper 16 bits, | 185 | /* status is returned on upper 16 bits, |
diff --git a/drivers/net/ethernet/altera/altera_msgdma.h b/drivers/net/ethernet/altera/altera_msgdma.h index 7f0f5bf2bba2..42cf61c81057 100644 --- a/drivers/net/ethernet/altera/altera_msgdma.h +++ b/drivers/net/ethernet/altera/altera_msgdma.h | |||
@@ -25,10 +25,11 @@ void msgdma_disable_txirq(struct altera_tse_private *); | |||
25 | void msgdma_clear_rxirq(struct altera_tse_private *); | 25 | void msgdma_clear_rxirq(struct altera_tse_private *); |
26 | void msgdma_clear_txirq(struct altera_tse_private *); | 26 | void msgdma_clear_txirq(struct altera_tse_private *); |
27 | u32 msgdma_tx_completions(struct altera_tse_private *); | 27 | u32 msgdma_tx_completions(struct altera_tse_private *); |
28 | int msgdma_add_rx_desc(struct altera_tse_private *, struct tse_buffer *); | 28 | void msgdma_add_rx_desc(struct altera_tse_private *, struct tse_buffer *); |
29 | int msgdma_tx_buffer(struct altera_tse_private *, struct tse_buffer *); | 29 | int msgdma_tx_buffer(struct altera_tse_private *, struct tse_buffer *); |
30 | u32 msgdma_rx_status(struct altera_tse_private *); | 30 | u32 msgdma_rx_status(struct altera_tse_private *); |
31 | int msgdma_initialize(struct altera_tse_private *); | 31 | int msgdma_initialize(struct altera_tse_private *); |
32 | void msgdma_uninitialize(struct altera_tse_private *); | 32 | void msgdma_uninitialize(struct altera_tse_private *); |
33 | void msgdma_start_rxdma(struct altera_tse_private *); | ||
33 | 34 | ||
34 | #endif /* __ALTERA_MSGDMA_H__ */ | 35 | #endif /* __ALTERA_MSGDMA_H__ */ |
diff --git a/drivers/net/ethernet/altera/altera_sgdma.c b/drivers/net/ethernet/altera/altera_sgdma.c index 0ee96639ae44..9ce8630692b6 100644 --- a/drivers/net/ethernet/altera/altera_sgdma.c +++ b/drivers/net/ethernet/altera/altera_sgdma.c | |||
@@ -20,15 +20,15 @@ | |||
20 | #include "altera_sgdmahw.h" | 20 | #include "altera_sgdmahw.h" |
21 | #include "altera_sgdma.h" | 21 | #include "altera_sgdma.h" |
22 | 22 | ||
23 | static void sgdma_descrip(struct sgdma_descrip *desc, | 23 | static void sgdma_setup_descrip(struct sgdma_descrip *desc, |
24 | struct sgdma_descrip *ndesc, | 24 | struct sgdma_descrip *ndesc, |
25 | dma_addr_t ndesc_phys, | 25 | dma_addr_t ndesc_phys, |
26 | dma_addr_t raddr, | 26 | dma_addr_t raddr, |
27 | dma_addr_t waddr, | 27 | dma_addr_t waddr, |
28 | u16 length, | 28 | u16 length, |
29 | int generate_eop, | 29 | int generate_eop, |
30 | int rfixed, | 30 | int rfixed, |
31 | int wfixed); | 31 | int wfixed); |
32 | 32 | ||
33 | static int sgdma_async_write(struct altera_tse_private *priv, | 33 | static int sgdma_async_write(struct altera_tse_private *priv, |
34 | struct sgdma_descrip *desc); | 34 | struct sgdma_descrip *desc); |
@@ -64,11 +64,15 @@ queue_rx_peekhead(struct altera_tse_private *priv); | |||
64 | 64 | ||
65 | int sgdma_initialize(struct altera_tse_private *priv) | 65 | int sgdma_initialize(struct altera_tse_private *priv) |
66 | { | 66 | { |
67 | priv->txctrlreg = SGDMA_CTRLREG_ILASTD; | 67 | priv->txctrlreg = SGDMA_CTRLREG_ILASTD | |
68 | SGDMA_CTRLREG_INTEN; | ||
68 | 69 | ||
69 | priv->rxctrlreg = SGDMA_CTRLREG_IDESCRIP | | 70 | priv->rxctrlreg = SGDMA_CTRLREG_IDESCRIP | |
71 | SGDMA_CTRLREG_INTEN | | ||
70 | SGDMA_CTRLREG_ILASTD; | 72 | SGDMA_CTRLREG_ILASTD; |
71 | 73 | ||
74 | priv->sgdmadesclen = sizeof(struct sgdma_descrip); | ||
75 | |||
72 | INIT_LIST_HEAD(&priv->txlisthd); | 76 | INIT_LIST_HEAD(&priv->txlisthd); |
73 | INIT_LIST_HEAD(&priv->rxlisthd); | 77 | INIT_LIST_HEAD(&priv->rxlisthd); |
74 | 78 | ||
@@ -93,6 +97,16 @@ int sgdma_initialize(struct altera_tse_private *priv) | |||
93 | return -EINVAL; | 97 | return -EINVAL; |
94 | } | 98 | } |
95 | 99 | ||
100 | /* Initialize descriptor memory to all 0's, sync memory to cache */ | ||
101 | memset(priv->tx_dma_desc, 0, priv->txdescmem); | ||
102 | memset(priv->rx_dma_desc, 0, priv->rxdescmem); | ||
103 | |||
104 | dma_sync_single_for_device(priv->device, priv->txdescphys, | ||
105 | priv->txdescmem, DMA_TO_DEVICE); | ||
106 | |||
107 | dma_sync_single_for_device(priv->device, priv->rxdescphys, | ||
108 | priv->rxdescmem, DMA_TO_DEVICE); | ||
109 | |||
96 | return 0; | 110 | return 0; |
97 | } | 111 | } |
98 | 112 | ||
@@ -130,26 +144,23 @@ void sgdma_reset(struct altera_tse_private *priv) | |||
130 | iowrite32(0, &prxsgdma->control); | 144 | iowrite32(0, &prxsgdma->control); |
131 | } | 145 | } |
132 | 146 | ||
147 | /* For SGDMA, interrupts remain enabled after initially enabling, | ||
148 | * so no need to provide implementations for abstract enable | ||
149 | * and disable | ||
150 | */ | ||
151 | |||
133 | void sgdma_enable_rxirq(struct altera_tse_private *priv) | 152 | void sgdma_enable_rxirq(struct altera_tse_private *priv) |
134 | { | 153 | { |
135 | struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr; | ||
136 | priv->rxctrlreg |= SGDMA_CTRLREG_INTEN; | ||
137 | tse_set_bit(&csr->control, SGDMA_CTRLREG_INTEN); | ||
138 | } | 154 | } |
139 | 155 | ||
140 | void sgdma_enable_txirq(struct altera_tse_private *priv) | 156 | void sgdma_enable_txirq(struct altera_tse_private *priv) |
141 | { | 157 | { |
142 | struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr; | ||
143 | priv->txctrlreg |= SGDMA_CTRLREG_INTEN; | ||
144 | tse_set_bit(&csr->control, SGDMA_CTRLREG_INTEN); | ||
145 | } | 158 | } |
146 | 159 | ||
147 | /* for SGDMA, RX interrupts remain enabled after enabling */ | ||
148 | void sgdma_disable_rxirq(struct altera_tse_private *priv) | 160 | void sgdma_disable_rxirq(struct altera_tse_private *priv) |
149 | { | 161 | { |
150 | } | 162 | } |
151 | 163 | ||
152 | /* for SGDMA, TX interrupts remain enabled after enabling */ | ||
153 | void sgdma_disable_txirq(struct altera_tse_private *priv) | 164 | void sgdma_disable_txirq(struct altera_tse_private *priv) |
154 | { | 165 | { |
155 | } | 166 | } |
@@ -184,15 +195,15 @@ int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer) | |||
184 | if (sgdma_txbusy(priv)) | 195 | if (sgdma_txbusy(priv)) |
185 | return 0; | 196 | return 0; |
186 | 197 | ||
187 | sgdma_descrip(cdesc, /* current descriptor */ | 198 | sgdma_setup_descrip(cdesc, /* current descriptor */ |
188 | ndesc, /* next descriptor */ | 199 | ndesc, /* next descriptor */ |
189 | sgdma_txphysaddr(priv, ndesc), | 200 | sgdma_txphysaddr(priv, ndesc), |
190 | buffer->dma_addr, /* address of packet to xmit */ | 201 | buffer->dma_addr, /* address of packet to xmit */ |
191 | 0, /* write addr 0 for tx dma */ | 202 | 0, /* write addr 0 for tx dma */ |
192 | buffer->len, /* length of packet */ | 203 | buffer->len, /* length of packet */ |
193 | SGDMA_CONTROL_EOP, /* Generate EOP */ | 204 | SGDMA_CONTROL_EOP, /* Generate EOP */ |
194 | 0, /* read fixed */ | 205 | 0, /* read fixed */ |
195 | SGDMA_CONTROL_WR_FIXED); /* Generate SOP */ | 206 | SGDMA_CONTROL_WR_FIXED); /* Generate SOP */ |
196 | 207 | ||
197 | pktstx = sgdma_async_write(priv, cdesc); | 208 | pktstx = sgdma_async_write(priv, cdesc); |
198 | 209 | ||
@@ -219,11 +230,15 @@ u32 sgdma_tx_completions(struct altera_tse_private *priv) | |||
219 | return ready; | 230 | return ready; |
220 | } | 231 | } |
221 | 232 | ||
222 | int sgdma_add_rx_desc(struct altera_tse_private *priv, | 233 | void sgdma_start_rxdma(struct altera_tse_private *priv) |
223 | struct tse_buffer *rxbuffer) | 234 | { |
235 | sgdma_async_read(priv); | ||
236 | } | ||
237 | |||
238 | void sgdma_add_rx_desc(struct altera_tse_private *priv, | ||
239 | struct tse_buffer *rxbuffer) | ||
224 | { | 240 | { |
225 | queue_rx(priv, rxbuffer); | 241 | queue_rx(priv, rxbuffer); |
226 | return sgdma_async_read(priv); | ||
227 | } | 242 | } |
228 | 243 | ||
229 | /* status is returned on upper 16 bits, | 244 | /* status is returned on upper 16 bits, |
@@ -240,28 +255,52 @@ u32 sgdma_rx_status(struct altera_tse_private *priv) | |||
240 | unsigned int pktstatus = 0; | 255 | unsigned int pktstatus = 0; |
241 | struct tse_buffer *rxbuffer = NULL; | 256 | struct tse_buffer *rxbuffer = NULL; |
242 | 257 | ||
243 | dma_sync_single_for_cpu(priv->device, | 258 | u32 sts = ioread32(&csr->status); |
244 | priv->rxdescphys, | ||
245 | priv->rxdescmem, | ||
246 | DMA_BIDIRECTIONAL); | ||
247 | 259 | ||
248 | desc = &base[0]; | 260 | desc = &base[0]; |
249 | if ((ioread32(&csr->status) & SGDMA_STSREG_EOP) || | 261 | if (sts & SGDMA_STSREG_EOP) { |
250 | (desc->status & SGDMA_STATUS_EOP)) { | 262 | dma_sync_single_for_cpu(priv->device, |
263 | priv->rxdescphys, | ||
264 | priv->sgdmadesclen, | ||
265 | DMA_FROM_DEVICE); | ||
266 | |||
251 | pktlength = desc->bytes_xferred; | 267 | pktlength = desc->bytes_xferred; |
252 | pktstatus = desc->status & 0x3f; | 268 | pktstatus = desc->status & 0x3f; |
253 | rxstatus = pktstatus; | 269 | rxstatus = pktstatus; |
254 | rxstatus = rxstatus << 16; | 270 | rxstatus = rxstatus << 16; |
255 | rxstatus |= (pktlength & 0xffff); | 271 | rxstatus |= (pktlength & 0xffff); |
256 | 272 | ||
257 | desc->status = 0; | 273 | if (rxstatus) { |
274 | desc->status = 0; | ||
258 | 275 | ||
259 | rxbuffer = dequeue_rx(priv); | 276 | rxbuffer = dequeue_rx(priv); |
260 | if (rxbuffer == NULL) | 277 | if (rxbuffer == NULL) |
261 | netdev_err(priv->dev, | 278 | netdev_info(priv->dev, |
262 | "sgdma rx and rx queue empty!\n"); | 279 | "sgdma rx and rx queue empty!\n"); |
280 | |||
281 | /* Clear control */ | ||
282 | iowrite32(0, &csr->control); | ||
283 | /* clear status */ | ||
284 | iowrite32(0xf, &csr->status); | ||
263 | 285 | ||
264 | /* kick the rx sgdma after reaping this descriptor */ | 286 | /* kick the rx sgdma after reaping this descriptor */ |
287 | pktsrx = sgdma_async_read(priv); | ||
288 | |||
289 | } else { | ||
290 | /* If the SGDMA indicated an end of packet on recv, | ||
291 | * then it's expected that the rxstatus from the | ||
292 | * descriptor is non-zero - meaning a valid packet | ||
293 | * with a nonzero length, or an error has been | ||
294 | * indicated. if not, then all we can do is signal | ||
295 | * an error and return no packet received. Most likely | ||
296 | * there is a system design error, or an error in the | ||
297 | * underlying kernel (cache or cache management problem) | ||
298 | */ | ||
299 | netdev_err(priv->dev, | ||
300 | "SGDMA RX Error Info: %x, %x, %x\n", | ||
301 | sts, desc->status, rxstatus); | ||
302 | } | ||
303 | } else if (sts == 0) { | ||
265 | pktsrx = sgdma_async_read(priv); | 304 | pktsrx = sgdma_async_read(priv); |
266 | } | 305 | } |
267 | 306 | ||
@@ -270,15 +309,15 @@ u32 sgdma_rx_status(struct altera_tse_private *priv) | |||
270 | 309 | ||
271 | 310 | ||
272 | /* Private functions */ | 311 | /* Private functions */ |
273 | static void sgdma_descrip(struct sgdma_descrip *desc, | 312 | static void sgdma_setup_descrip(struct sgdma_descrip *desc, |
274 | struct sgdma_descrip *ndesc, | 313 | struct sgdma_descrip *ndesc, |
275 | dma_addr_t ndesc_phys, | 314 | dma_addr_t ndesc_phys, |
276 | dma_addr_t raddr, | 315 | dma_addr_t raddr, |
277 | dma_addr_t waddr, | 316 | dma_addr_t waddr, |
278 | u16 length, | 317 | u16 length, |
279 | int generate_eop, | 318 | int generate_eop, |
280 | int rfixed, | 319 | int rfixed, |
281 | int wfixed) | 320 | int wfixed) |
282 | { | 321 | { |
283 | /* Clear the next descriptor as not owned by hardware */ | 322 | /* Clear the next descriptor as not owned by hardware */ |
284 | u32 ctrl = ndesc->control; | 323 | u32 ctrl = ndesc->control; |
@@ -319,35 +358,29 @@ static int sgdma_async_read(struct altera_tse_private *priv) | |||
319 | struct sgdma_descrip *cdesc = &descbase[0]; | 358 | struct sgdma_descrip *cdesc = &descbase[0]; |
320 | struct sgdma_descrip *ndesc = &descbase[1]; | 359 | struct sgdma_descrip *ndesc = &descbase[1]; |
321 | 360 | ||
322 | unsigned int sts = ioread32(&csr->status); | ||
323 | struct tse_buffer *rxbuffer = NULL; | 361 | struct tse_buffer *rxbuffer = NULL; |
324 | 362 | ||
325 | if (!sgdma_rxbusy(priv)) { | 363 | if (!sgdma_rxbusy(priv)) { |
326 | rxbuffer = queue_rx_peekhead(priv); | 364 | rxbuffer = queue_rx_peekhead(priv); |
327 | if (rxbuffer == NULL) | 365 | if (rxbuffer == NULL) { |
366 | netdev_err(priv->dev, "no rx buffers available\n"); | ||
328 | return 0; | 367 | return 0; |
329 | 368 | } | |
330 | sgdma_descrip(cdesc, /* current descriptor */ | 369 | |
331 | ndesc, /* next descriptor */ | 370 | sgdma_setup_descrip(cdesc, /* current descriptor */ |
332 | sgdma_rxphysaddr(priv, ndesc), | 371 | ndesc, /* next descriptor */ |
333 | 0, /* read addr 0 for rx dma */ | 372 | sgdma_rxphysaddr(priv, ndesc), |
334 | rxbuffer->dma_addr, /* write addr for rx dma */ | 373 | 0, /* read addr 0 for rx dma */ |
335 | 0, /* read 'til EOP */ | 374 | rxbuffer->dma_addr, /* write addr for rx dma */ |
336 | 0, /* EOP: NA for rx dma */ | 375 | 0, /* read 'til EOP */ |
337 | 0, /* read fixed: NA for rx dma */ | 376 | 0, /* EOP: NA for rx dma */ |
338 | 0); /* SOP: NA for rx DMA */ | 377 | 0, /* read fixed: NA for rx dma */ |
339 | 378 | 0); /* SOP: NA for rx DMA */ | |
340 | /* clear control and status */ | ||
341 | iowrite32(0, &csr->control); | ||
342 | |||
343 | /* If status available, clear those bits */ | ||
344 | if (sts & 0xf) | ||
345 | iowrite32(0xf, &csr->status); | ||
346 | 379 | ||
347 | dma_sync_single_for_device(priv->device, | 380 | dma_sync_single_for_device(priv->device, |
348 | priv->rxdescphys, | 381 | priv->rxdescphys, |
349 | priv->rxdescmem, | 382 | priv->sgdmadesclen, |
350 | DMA_BIDIRECTIONAL); | 383 | DMA_TO_DEVICE); |
351 | 384 | ||
352 | iowrite32(lower_32_bits(sgdma_rxphysaddr(priv, cdesc)), | 385 | iowrite32(lower_32_bits(sgdma_rxphysaddr(priv, cdesc)), |
353 | &csr->next_descrip); | 386 | &csr->next_descrip); |
@@ -374,7 +407,7 @@ static int sgdma_async_write(struct altera_tse_private *priv, | |||
374 | iowrite32(0x1f, &csr->status); | 407 | iowrite32(0x1f, &csr->status); |
375 | 408 | ||
376 | dma_sync_single_for_device(priv->device, priv->txdescphys, | 409 | dma_sync_single_for_device(priv->device, priv->txdescphys, |
377 | priv->txdescmem, DMA_TO_DEVICE); | 410 | priv->sgdmadesclen, DMA_TO_DEVICE); |
378 | 411 | ||
379 | iowrite32(lower_32_bits(sgdma_txphysaddr(priv, desc)), | 412 | iowrite32(lower_32_bits(sgdma_txphysaddr(priv, desc)), |
380 | &csr->next_descrip); | 413 | &csr->next_descrip); |
diff --git a/drivers/net/ethernet/altera/altera_sgdma.h b/drivers/net/ethernet/altera/altera_sgdma.h index 07d471729dc4..584977e29ef9 100644 --- a/drivers/net/ethernet/altera/altera_sgdma.h +++ b/drivers/net/ethernet/altera/altera_sgdma.h | |||
@@ -26,10 +26,11 @@ void sgdma_clear_rxirq(struct altera_tse_private *); | |||
26 | void sgdma_clear_txirq(struct altera_tse_private *); | 26 | void sgdma_clear_txirq(struct altera_tse_private *); |
27 | int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *); | 27 | int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *); |
28 | u32 sgdma_tx_completions(struct altera_tse_private *); | 28 | u32 sgdma_tx_completions(struct altera_tse_private *); |
29 | int sgdma_add_rx_desc(struct altera_tse_private *priv, struct tse_buffer *); | 29 | void sgdma_add_rx_desc(struct altera_tse_private *priv, struct tse_buffer *); |
30 | void sgdma_status(struct altera_tse_private *); | 30 | void sgdma_status(struct altera_tse_private *); |
31 | u32 sgdma_rx_status(struct altera_tse_private *); | 31 | u32 sgdma_rx_status(struct altera_tse_private *); |
32 | int sgdma_initialize(struct altera_tse_private *); | 32 | int sgdma_initialize(struct altera_tse_private *); |
33 | void sgdma_uninitialize(struct altera_tse_private *); | 33 | void sgdma_uninitialize(struct altera_tse_private *); |
34 | void sgdma_start_rxdma(struct altera_tse_private *); | ||
34 | 35 | ||
35 | #endif /* __ALTERA_SGDMA_H__ */ | 36 | #endif /* __ALTERA_SGDMA_H__ */ |
diff --git a/drivers/net/ethernet/altera/altera_tse.h b/drivers/net/ethernet/altera/altera_tse.h index 8feeed05de0e..465c4aabebbd 100644 --- a/drivers/net/ethernet/altera/altera_tse.h +++ b/drivers/net/ethernet/altera/altera_tse.h | |||
@@ -58,6 +58,8 @@ | |||
58 | /* MAC function configuration default settings */ | 58 | /* MAC function configuration default settings */ |
59 | #define ALTERA_TSE_TX_IPG_LENGTH 12 | 59 | #define ALTERA_TSE_TX_IPG_LENGTH 12 |
60 | 60 | ||
61 | #define ALTERA_TSE_PAUSE_QUANTA 0xffff | ||
62 | |||
61 | #define GET_BIT_VALUE(v, bit) (((v) >> (bit)) & 0x1) | 63 | #define GET_BIT_VALUE(v, bit) (((v) >> (bit)) & 0x1) |
62 | 64 | ||
63 | /* MAC Command_Config Register Bit Definitions | 65 | /* MAC Command_Config Register Bit Definitions |
@@ -390,10 +392,11 @@ struct altera_dmaops { | |||
390 | void (*clear_rxirq)(struct altera_tse_private *); | 392 | void (*clear_rxirq)(struct altera_tse_private *); |
391 | int (*tx_buffer)(struct altera_tse_private *, struct tse_buffer *); | 393 | int (*tx_buffer)(struct altera_tse_private *, struct tse_buffer *); |
392 | u32 (*tx_completions)(struct altera_tse_private *); | 394 | u32 (*tx_completions)(struct altera_tse_private *); |
393 | int (*add_rx_desc)(struct altera_tse_private *, struct tse_buffer *); | 395 | void (*add_rx_desc)(struct altera_tse_private *, struct tse_buffer *); |
394 | u32 (*get_rx_status)(struct altera_tse_private *); | 396 | u32 (*get_rx_status)(struct altera_tse_private *); |
395 | int (*init_dma)(struct altera_tse_private *); | 397 | int (*init_dma)(struct altera_tse_private *); |
396 | void (*uninit_dma)(struct altera_tse_private *); | 398 | void (*uninit_dma)(struct altera_tse_private *); |
399 | void (*start_rxdma)(struct altera_tse_private *); | ||
397 | }; | 400 | }; |
398 | 401 | ||
399 | /* This structure is private to each device. | 402 | /* This structure is private to each device. |
@@ -453,6 +456,7 @@ struct altera_tse_private { | |||
453 | u32 rxctrlreg; | 456 | u32 rxctrlreg; |
454 | dma_addr_t rxdescphys; | 457 | dma_addr_t rxdescphys; |
455 | dma_addr_t txdescphys; | 458 | dma_addr_t txdescphys; |
459 | size_t sgdmadesclen; | ||
456 | 460 | ||
457 | struct list_head txlisthd; | 461 | struct list_head txlisthd; |
458 | struct list_head rxlisthd; | 462 | struct list_head rxlisthd; |
diff --git a/drivers/net/ethernet/altera/altera_tse_ethtool.c b/drivers/net/ethernet/altera/altera_tse_ethtool.c index 319ca74f5e74..76133caffa78 100644 --- a/drivers/net/ethernet/altera/altera_tse_ethtool.c +++ b/drivers/net/ethernet/altera/altera_tse_ethtool.c | |||
@@ -77,7 +77,7 @@ static void tse_get_drvinfo(struct net_device *dev, | |||
77 | struct altera_tse_private *priv = netdev_priv(dev); | 77 | struct altera_tse_private *priv = netdev_priv(dev); |
78 | u32 rev = ioread32(&priv->mac_dev->megacore_revision); | 78 | u32 rev = ioread32(&priv->mac_dev->megacore_revision); |
79 | 79 | ||
80 | strcpy(info->driver, "Altera TSE MAC IP Driver"); | 80 | strcpy(info->driver, "altera_tse"); |
81 | strcpy(info->version, "v8.0"); | 81 | strcpy(info->version, "v8.0"); |
82 | snprintf(info->fw_version, ETHTOOL_FWVERS_LEN, "v%d.%d", | 82 | snprintf(info->fw_version, ETHTOOL_FWVERS_LEN, "v%d.%d", |
83 | rev & 0xFFFF, (rev & 0xFFFF0000) >> 16); | 83 | rev & 0xFFFF, (rev & 0xFFFF0000) >> 16); |
@@ -185,6 +185,12 @@ static void tse_get_regs(struct net_device *dev, struct ethtool_regs *regs, | |||
185 | * how to do any special formatting of this data. | 185 | * how to do any special formatting of this data. |
186 | * This version number will need to change if and | 186 | * This version number will need to change if and |
187 | * when this register table is changed. | 187 | * when this register table is changed. |
188 | * | ||
189 | * version[31:0] = 1: Dump the first 128 TSE Registers | ||
190 | * Upper bits are all 0 by default | ||
191 | * | ||
192 | * Upper 16-bits will indicate feature presence for | ||
193 | * Ethtool register decoding in future version. | ||
188 | */ | 194 | */ |
189 | 195 | ||
190 | regs->version = 1; | 196 | regs->version = 1; |
diff --git a/drivers/net/ethernet/altera/altera_tse_main.c b/drivers/net/ethernet/altera/altera_tse_main.c index c70a29e0b9f7..e44a4aeb9701 100644 --- a/drivers/net/ethernet/altera/altera_tse_main.c +++ b/drivers/net/ethernet/altera/altera_tse_main.c | |||
@@ -224,6 +224,7 @@ static int tse_init_rx_buffer(struct altera_tse_private *priv, | |||
224 | dev_kfree_skb_any(rxbuffer->skb); | 224 | dev_kfree_skb_any(rxbuffer->skb); |
225 | return -EINVAL; | 225 | return -EINVAL; |
226 | } | 226 | } |
227 | rxbuffer->dma_addr &= (dma_addr_t)~3; | ||
227 | rxbuffer->len = len; | 228 | rxbuffer->len = len; |
228 | return 0; | 229 | return 0; |
229 | } | 230 | } |
@@ -425,9 +426,10 @@ static int tse_rx(struct altera_tse_private *priv, int limit) | |||
425 | priv->dev->stats.rx_bytes += pktlength; | 426 | priv->dev->stats.rx_bytes += pktlength; |
426 | 427 | ||
427 | entry = next_entry; | 428 | entry = next_entry; |
429 | |||
430 | tse_rx_refill(priv); | ||
428 | } | 431 | } |
429 | 432 | ||
430 | tse_rx_refill(priv); | ||
431 | return count; | 433 | return count; |
432 | } | 434 | } |
433 | 435 | ||
@@ -520,7 +522,6 @@ static irqreturn_t altera_isr(int irq, void *dev_id) | |||
520 | struct altera_tse_private *priv; | 522 | struct altera_tse_private *priv; |
521 | unsigned long int flags; | 523 | unsigned long int flags; |
522 | 524 | ||
523 | |||
524 | if (unlikely(!dev)) { | 525 | if (unlikely(!dev)) { |
525 | pr_err("%s: invalid dev pointer\n", __func__); | 526 | pr_err("%s: invalid dev pointer\n", __func__); |
526 | return IRQ_NONE; | 527 | return IRQ_NONE; |
@@ -868,13 +869,13 @@ static int init_mac(struct altera_tse_private *priv) | |||
868 | /* Disable RX/TX shift 16 for alignment of all received frames on 16-bit | 869 | /* Disable RX/TX shift 16 for alignment of all received frames on 16-bit |
869 | * start address | 870 | * start address |
870 | */ | 871 | */ |
871 | tse_clear_bit(&mac->rx_cmd_stat, ALTERA_TSE_RX_CMD_STAT_RX_SHIFT16); | 872 | tse_set_bit(&mac->rx_cmd_stat, ALTERA_TSE_RX_CMD_STAT_RX_SHIFT16); |
872 | tse_clear_bit(&mac->tx_cmd_stat, ALTERA_TSE_TX_CMD_STAT_TX_SHIFT16 | | 873 | tse_clear_bit(&mac->tx_cmd_stat, ALTERA_TSE_TX_CMD_STAT_TX_SHIFT16 | |
873 | ALTERA_TSE_TX_CMD_STAT_OMIT_CRC); | 874 | ALTERA_TSE_TX_CMD_STAT_OMIT_CRC); |
874 | 875 | ||
875 | /* Set the MAC options */ | 876 | /* Set the MAC options */ |
876 | cmd = ioread32(&mac->command_config); | 877 | cmd = ioread32(&mac->command_config); |
877 | cmd |= MAC_CMDCFG_PAD_EN; /* Padding Removal on Receive */ | 878 | cmd &= ~MAC_CMDCFG_PAD_EN; /* No padding Removal on Receive */ |
878 | cmd &= ~MAC_CMDCFG_CRC_FWD; /* CRC Removal */ | 879 | cmd &= ~MAC_CMDCFG_CRC_FWD; /* CRC Removal */ |
879 | cmd |= MAC_CMDCFG_RX_ERR_DISC; /* Automatically discard frames | 880 | cmd |= MAC_CMDCFG_RX_ERR_DISC; /* Automatically discard frames |
880 | * with CRC errors | 881 | * with CRC errors |
@@ -882,8 +883,16 @@ static int init_mac(struct altera_tse_private *priv) | |||
882 | cmd |= MAC_CMDCFG_CNTL_FRM_ENA; | 883 | cmd |= MAC_CMDCFG_CNTL_FRM_ENA; |
883 | cmd &= ~MAC_CMDCFG_TX_ENA; | 884 | cmd &= ~MAC_CMDCFG_TX_ENA; |
884 | cmd &= ~MAC_CMDCFG_RX_ENA; | 885 | cmd &= ~MAC_CMDCFG_RX_ENA; |
886 | |||
887 | /* Default speed and duplex setting, full/100 */ | ||
888 | cmd &= ~MAC_CMDCFG_HD_ENA; | ||
889 | cmd &= ~MAC_CMDCFG_ETH_SPEED; | ||
890 | cmd &= ~MAC_CMDCFG_ENA_10; | ||
891 | |||
885 | iowrite32(cmd, &mac->command_config); | 892 | iowrite32(cmd, &mac->command_config); |
886 | 893 | ||
894 | iowrite32(ALTERA_TSE_PAUSE_QUANTA, &mac->pause_quanta); | ||
895 | |||
887 | if (netif_msg_hw(priv)) | 896 | if (netif_msg_hw(priv)) |
888 | dev_dbg(priv->device, | 897 | dev_dbg(priv->device, |
889 | "MAC post-initialization: CMD_CONFIG = 0x%08x\n", cmd); | 898 | "MAC post-initialization: CMD_CONFIG = 0x%08x\n", cmd); |
@@ -1085,17 +1094,19 @@ static int tse_open(struct net_device *dev) | |||
1085 | 1094 | ||
1086 | spin_unlock_irqrestore(&priv->rxdma_irq_lock, flags); | 1095 | spin_unlock_irqrestore(&priv->rxdma_irq_lock, flags); |
1087 | 1096 | ||
1088 | /* Start MAC Rx/Tx */ | ||
1089 | spin_lock(&priv->mac_cfg_lock); | ||
1090 | tse_set_mac(priv, true); | ||
1091 | spin_unlock(&priv->mac_cfg_lock); | ||
1092 | |||
1093 | if (priv->phydev) | 1097 | if (priv->phydev) |
1094 | phy_start(priv->phydev); | 1098 | phy_start(priv->phydev); |
1095 | 1099 | ||
1096 | napi_enable(&priv->napi); | 1100 | napi_enable(&priv->napi); |
1097 | netif_start_queue(dev); | 1101 | netif_start_queue(dev); |
1098 | 1102 | ||
1103 | priv->dmaops->start_rxdma(priv); | ||
1104 | |||
1105 | /* Start MAC Rx/Tx */ | ||
1106 | spin_lock(&priv->mac_cfg_lock); | ||
1107 | tse_set_mac(priv, true); | ||
1108 | spin_unlock(&priv->mac_cfg_lock); | ||
1109 | |||
1099 | return 0; | 1110 | return 0; |
1100 | 1111 | ||
1101 | tx_request_irq_error: | 1112 | tx_request_irq_error: |
@@ -1167,7 +1178,6 @@ static struct net_device_ops altera_tse_netdev_ops = { | |||
1167 | .ndo_validate_addr = eth_validate_addr, | 1178 | .ndo_validate_addr = eth_validate_addr, |
1168 | }; | 1179 | }; |
1169 | 1180 | ||
1170 | |||
1171 | static int request_and_map(struct platform_device *pdev, const char *name, | 1181 | static int request_and_map(struct platform_device *pdev, const char *name, |
1172 | struct resource **res, void __iomem **ptr) | 1182 | struct resource **res, void __iomem **ptr) |
1173 | { | 1183 | { |
@@ -1235,7 +1245,7 @@ static int altera_tse_probe(struct platform_device *pdev) | |||
1235 | /* Get the mapped address to the SGDMA descriptor memory */ | 1245 | /* Get the mapped address to the SGDMA descriptor memory */ |
1236 | ret = request_and_map(pdev, "s1", &dma_res, &descmap); | 1246 | ret = request_and_map(pdev, "s1", &dma_res, &descmap); |
1237 | if (ret) | 1247 | if (ret) |
1238 | goto out_free; | 1248 | goto err_free_netdev; |
1239 | 1249 | ||
1240 | /* Start of that memory is for transmit descriptors */ | 1250 | /* Start of that memory is for transmit descriptors */ |
1241 | priv->tx_dma_desc = descmap; | 1251 | priv->tx_dma_desc = descmap; |
@@ -1254,24 +1264,24 @@ static int altera_tse_probe(struct platform_device *pdev) | |||
1254 | if (upper_32_bits(priv->rxdescmem_busaddr)) { | 1264 | if (upper_32_bits(priv->rxdescmem_busaddr)) { |
1255 | dev_dbg(priv->device, | 1265 | dev_dbg(priv->device, |
1256 | "SGDMA bus addresses greater than 32-bits\n"); | 1266 | "SGDMA bus addresses greater than 32-bits\n"); |
1257 | goto out_free; | 1267 | goto err_free_netdev; |
1258 | } | 1268 | } |
1259 | if (upper_32_bits(priv->txdescmem_busaddr)) { | 1269 | if (upper_32_bits(priv->txdescmem_busaddr)) { |
1260 | dev_dbg(priv->device, | 1270 | dev_dbg(priv->device, |
1261 | "SGDMA bus addresses greater than 32-bits\n"); | 1271 | "SGDMA bus addresses greater than 32-bits\n"); |
1262 | goto out_free; | 1272 | goto err_free_netdev; |
1263 | } | 1273 | } |
1264 | } else if (priv->dmaops && | 1274 | } else if (priv->dmaops && |
1265 | priv->dmaops->altera_dtype == ALTERA_DTYPE_MSGDMA) { | 1275 | priv->dmaops->altera_dtype == ALTERA_DTYPE_MSGDMA) { |
1266 | ret = request_and_map(pdev, "rx_resp", &dma_res, | 1276 | ret = request_and_map(pdev, "rx_resp", &dma_res, |
1267 | &priv->rx_dma_resp); | 1277 | &priv->rx_dma_resp); |
1268 | if (ret) | 1278 | if (ret) |
1269 | goto out_free; | 1279 | goto err_free_netdev; |
1270 | 1280 | ||
1271 | ret = request_and_map(pdev, "tx_desc", &dma_res, | 1281 | ret = request_and_map(pdev, "tx_desc", &dma_res, |
1272 | &priv->tx_dma_desc); | 1282 | &priv->tx_dma_desc); |
1273 | if (ret) | 1283 | if (ret) |
1274 | goto out_free; | 1284 | goto err_free_netdev; |
1275 | 1285 | ||
1276 | priv->txdescmem = resource_size(dma_res); | 1286 | priv->txdescmem = resource_size(dma_res); |
1277 | priv->txdescmem_busaddr = dma_res->start; | 1287 | priv->txdescmem_busaddr = dma_res->start; |
@@ -1279,13 +1289,13 @@ static int altera_tse_probe(struct platform_device *pdev) | |||
1279 | ret = request_and_map(pdev, "rx_desc", &dma_res, | 1289 | ret = request_and_map(pdev, "rx_desc", &dma_res, |
1280 | &priv->rx_dma_desc); | 1290 | &priv->rx_dma_desc); |
1281 | if (ret) | 1291 | if (ret) |
1282 | goto out_free; | 1292 | goto err_free_netdev; |
1283 | 1293 | ||
1284 | priv->rxdescmem = resource_size(dma_res); | 1294 | priv->rxdescmem = resource_size(dma_res); |
1285 | priv->rxdescmem_busaddr = dma_res->start; | 1295 | priv->rxdescmem_busaddr = dma_res->start; |
1286 | 1296 | ||
1287 | } else { | 1297 | } else { |
1288 | goto out_free; | 1298 | goto err_free_netdev; |
1289 | } | 1299 | } |
1290 | 1300 | ||
1291 | if (!dma_set_mask(priv->device, DMA_BIT_MASK(priv->dmaops->dmamask))) | 1301 | if (!dma_set_mask(priv->device, DMA_BIT_MASK(priv->dmaops->dmamask))) |
@@ -1294,26 +1304,26 @@ static int altera_tse_probe(struct platform_device *pdev) | |||
1294 | else if (!dma_set_mask(priv->device, DMA_BIT_MASK(32))) | 1304 | else if (!dma_set_mask(priv->device, DMA_BIT_MASK(32))) |
1295 | dma_set_coherent_mask(priv->device, DMA_BIT_MASK(32)); | 1305 | dma_set_coherent_mask(priv->device, DMA_BIT_MASK(32)); |
1296 | else | 1306 | else |
1297 | goto out_free; | 1307 | goto err_free_netdev; |
1298 | 1308 | ||
1299 | /* MAC address space */ | 1309 | /* MAC address space */ |
1300 | ret = request_and_map(pdev, "control_port", &control_port, | 1310 | ret = request_and_map(pdev, "control_port", &control_port, |
1301 | (void __iomem **)&priv->mac_dev); | 1311 | (void __iomem **)&priv->mac_dev); |
1302 | if (ret) | 1312 | if (ret) |
1303 | goto out_free; | 1313 | goto err_free_netdev; |
1304 | 1314 | ||
1305 | /* xSGDMA Rx Dispatcher address space */ | 1315 | /* xSGDMA Rx Dispatcher address space */ |
1306 | ret = request_and_map(pdev, "rx_csr", &dma_res, | 1316 | ret = request_and_map(pdev, "rx_csr", &dma_res, |
1307 | &priv->rx_dma_csr); | 1317 | &priv->rx_dma_csr); |
1308 | if (ret) | 1318 | if (ret) |
1309 | goto out_free; | 1319 | goto err_free_netdev; |
1310 | 1320 | ||
1311 | 1321 | ||
1312 | /* xSGDMA Tx Dispatcher address space */ | 1322 | /* xSGDMA Tx Dispatcher address space */ |
1313 | ret = request_and_map(pdev, "tx_csr", &dma_res, | 1323 | ret = request_and_map(pdev, "tx_csr", &dma_res, |
1314 | &priv->tx_dma_csr); | 1324 | &priv->tx_dma_csr); |
1315 | if (ret) | 1325 | if (ret) |
1316 | goto out_free; | 1326 | goto err_free_netdev; |
1317 | 1327 | ||
1318 | 1328 | ||
1319 | /* Rx IRQ */ | 1329 | /* Rx IRQ */ |
@@ -1321,7 +1331,7 @@ static int altera_tse_probe(struct platform_device *pdev) | |||
1321 | if (priv->rx_irq == -ENXIO) { | 1331 | if (priv->rx_irq == -ENXIO) { |
1322 | dev_err(&pdev->dev, "cannot obtain Rx IRQ\n"); | 1332 | dev_err(&pdev->dev, "cannot obtain Rx IRQ\n"); |
1323 | ret = -ENXIO; | 1333 | ret = -ENXIO; |
1324 | goto out_free; | 1334 | goto err_free_netdev; |
1325 | } | 1335 | } |
1326 | 1336 | ||
1327 | /* Tx IRQ */ | 1337 | /* Tx IRQ */ |
@@ -1329,7 +1339,7 @@ static int altera_tse_probe(struct platform_device *pdev) | |||
1329 | if (priv->tx_irq == -ENXIO) { | 1339 | if (priv->tx_irq == -ENXIO) { |
1330 | dev_err(&pdev->dev, "cannot obtain Tx IRQ\n"); | 1340 | dev_err(&pdev->dev, "cannot obtain Tx IRQ\n"); |
1331 | ret = -ENXIO; | 1341 | ret = -ENXIO; |
1332 | goto out_free; | 1342 | goto err_free_netdev; |
1333 | } | 1343 | } |
1334 | 1344 | ||
1335 | /* get FIFO depths from device tree */ | 1345 | /* get FIFO depths from device tree */ |
@@ -1337,14 +1347,14 @@ static int altera_tse_probe(struct platform_device *pdev) | |||
1337 | &priv->rx_fifo_depth)) { | 1347 | &priv->rx_fifo_depth)) { |
1338 | dev_err(&pdev->dev, "cannot obtain rx-fifo-depth\n"); | 1348 | dev_err(&pdev->dev, "cannot obtain rx-fifo-depth\n"); |
1339 | ret = -ENXIO; | 1349 | ret = -ENXIO; |
1340 | goto out_free; | 1350 | goto err_free_netdev; |
1341 | } | 1351 | } |
1342 | 1352 | ||
1343 | if (of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth", | 1353 | if (of_property_read_u32(pdev->dev.of_node, "tx-fifo-depth", |
1344 | &priv->rx_fifo_depth)) { | 1354 | &priv->rx_fifo_depth)) { |
1345 | dev_err(&pdev->dev, "cannot obtain tx-fifo-depth\n"); | 1355 | dev_err(&pdev->dev, "cannot obtain tx-fifo-depth\n"); |
1346 | ret = -ENXIO; | 1356 | ret = -ENXIO; |
1347 | goto out_free; | 1357 | goto err_free_netdev; |
1348 | } | 1358 | } |
1349 | 1359 | ||
1350 | /* get hash filter settings for this instance */ | 1360 | /* get hash filter settings for this instance */ |
@@ -1393,7 +1403,7 @@ static int altera_tse_probe(struct platform_device *pdev) | |||
1393 | ((priv->phy_addr >= 0) && (priv->phy_addr < PHY_MAX_ADDR)))) { | 1403 | ((priv->phy_addr >= 0) && (priv->phy_addr < PHY_MAX_ADDR)))) { |
1394 | dev_err(&pdev->dev, "invalid phy-addr specified %d\n", | 1404 | dev_err(&pdev->dev, "invalid phy-addr specified %d\n", |
1395 | priv->phy_addr); | 1405 | priv->phy_addr); |
1396 | goto out_free; | 1406 | goto err_free_netdev; |
1397 | } | 1407 | } |
1398 | 1408 | ||
1399 | /* Create/attach to MDIO bus */ | 1409 | /* Create/attach to MDIO bus */ |
@@ -1401,7 +1411,7 @@ static int altera_tse_probe(struct platform_device *pdev) | |||
1401 | atomic_add_return(1, &instance_count)); | 1411 | atomic_add_return(1, &instance_count)); |
1402 | 1412 | ||
1403 | if (ret) | 1413 | if (ret) |
1404 | goto out_free; | 1414 | goto err_free_netdev; |
1405 | 1415 | ||
1406 | /* initialize netdev */ | 1416 | /* initialize netdev */ |
1407 | ether_setup(ndev); | 1417 | ether_setup(ndev); |
@@ -1438,7 +1448,7 @@ static int altera_tse_probe(struct platform_device *pdev) | |||
1438 | ret = register_netdev(ndev); | 1448 | ret = register_netdev(ndev); |
1439 | if (ret) { | 1449 | if (ret) { |
1440 | dev_err(&pdev->dev, "failed to register TSE net device\n"); | 1450 | dev_err(&pdev->dev, "failed to register TSE net device\n"); |
1441 | goto out_free_mdio; | 1451 | goto err_register_netdev; |
1442 | } | 1452 | } |
1443 | 1453 | ||
1444 | platform_set_drvdata(pdev, ndev); | 1454 | platform_set_drvdata(pdev, ndev); |
@@ -1455,13 +1465,16 @@ static int altera_tse_probe(struct platform_device *pdev) | |||
1455 | ret = init_phy(ndev); | 1465 | ret = init_phy(ndev); |
1456 | if (ret != 0) { | 1466 | if (ret != 0) { |
1457 | netdev_err(ndev, "Cannot attach to PHY (error: %d)\n", ret); | 1467 | netdev_err(ndev, "Cannot attach to PHY (error: %d)\n", ret); |
1458 | goto out_free_mdio; | 1468 | goto err_init_phy; |
1459 | } | 1469 | } |
1460 | return 0; | 1470 | return 0; |
1461 | 1471 | ||
1462 | out_free_mdio: | 1472 | err_init_phy: |
1473 | unregister_netdev(ndev); | ||
1474 | err_register_netdev: | ||
1475 | netif_napi_del(&priv->napi); | ||
1463 | altera_tse_mdio_destroy(ndev); | 1476 | altera_tse_mdio_destroy(ndev); |
1464 | out_free: | 1477 | err_free_netdev: |
1465 | free_netdev(ndev); | 1478 | free_netdev(ndev); |
1466 | return ret; | 1479 | return ret; |
1467 | } | 1480 | } |
@@ -1496,6 +1509,7 @@ struct altera_dmaops altera_dtype_sgdma = { | |||
1496 | .get_rx_status = sgdma_rx_status, | 1509 | .get_rx_status = sgdma_rx_status, |
1497 | .init_dma = sgdma_initialize, | 1510 | .init_dma = sgdma_initialize, |
1498 | .uninit_dma = sgdma_uninitialize, | 1511 | .uninit_dma = sgdma_uninitialize, |
1512 | .start_rxdma = sgdma_start_rxdma, | ||
1499 | }; | 1513 | }; |
1500 | 1514 | ||
1501 | struct altera_dmaops altera_dtype_msgdma = { | 1515 | struct altera_dmaops altera_dtype_msgdma = { |
@@ -1514,6 +1528,7 @@ struct altera_dmaops altera_dtype_msgdma = { | |||
1514 | .get_rx_status = msgdma_rx_status, | 1528 | .get_rx_status = msgdma_rx_status, |
1515 | .init_dma = msgdma_initialize, | 1529 | .init_dma = msgdma_initialize, |
1516 | .uninit_dma = msgdma_uninitialize, | 1530 | .uninit_dma = msgdma_uninitialize, |
1531 | .start_rxdma = msgdma_start_rxdma, | ||
1517 | }; | 1532 | }; |
1518 | 1533 | ||
1519 | static struct of_device_id altera_tse_ids[] = { | 1534 | static struct of_device_id altera_tse_ids[] = { |
diff --git a/drivers/net/ethernet/arc/emac.h b/drivers/net/ethernet/arc/emac.h index 928fac6dd10a..53f85bf71526 100644 --- a/drivers/net/ethernet/arc/emac.h +++ b/drivers/net/ethernet/arc/emac.h | |||
@@ -11,6 +11,7 @@ | |||
11 | #include <linux/dma-mapping.h> | 11 | #include <linux/dma-mapping.h> |
12 | #include <linux/netdevice.h> | 12 | #include <linux/netdevice.h> |
13 | #include <linux/phy.h> | 13 | #include <linux/phy.h> |
14 | #include <linux/clk.h> | ||
14 | 15 | ||
15 | /* STATUS and ENABLE Register bit masks */ | 16 | /* STATUS and ENABLE Register bit masks */ |
16 | #define TXINT_MASK (1<<0) /* Transmit interrupt */ | 17 | #define TXINT_MASK (1<<0) /* Transmit interrupt */ |
@@ -131,6 +132,7 @@ struct arc_emac_priv { | |||
131 | struct mii_bus *bus; | 132 | struct mii_bus *bus; |
132 | 133 | ||
133 | void __iomem *regs; | 134 | void __iomem *regs; |
135 | struct clk *clk; | ||
134 | 136 | ||
135 | struct napi_struct napi; | 137 | struct napi_struct napi; |
136 | struct net_device_stats stats; | 138 | struct net_device_stats stats; |
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c index eeecc29cf5b7..d647a7d115ac 100644 --- a/drivers/net/ethernet/arc/emac_main.c +++ b/drivers/net/ethernet/arc/emac_main.c | |||
@@ -574,6 +574,18 @@ static int arc_emac_tx(struct sk_buff *skb, struct net_device *ndev) | |||
574 | return NETDEV_TX_OK; | 574 | return NETDEV_TX_OK; |
575 | } | 575 | } |
576 | 576 | ||
577 | static void arc_emac_set_address_internal(struct net_device *ndev) | ||
578 | { | ||
579 | struct arc_emac_priv *priv = netdev_priv(ndev); | ||
580 | unsigned int addr_low, addr_hi; | ||
581 | |||
582 | addr_low = le32_to_cpu(*(__le32 *) &ndev->dev_addr[0]); | ||
583 | addr_hi = le16_to_cpu(*(__le16 *) &ndev->dev_addr[4]); | ||
584 | |||
585 | arc_reg_set(priv, R_ADDRL, addr_low); | ||
586 | arc_reg_set(priv, R_ADDRH, addr_hi); | ||
587 | } | ||
588 | |||
577 | /** | 589 | /** |
578 | * arc_emac_set_address - Set the MAC address for this device. | 590 | * arc_emac_set_address - Set the MAC address for this device. |
579 | * @ndev: Pointer to net_device structure. | 591 | * @ndev: Pointer to net_device structure. |
@@ -587,9 +599,7 @@ static int arc_emac_tx(struct sk_buff *skb, struct net_device *ndev) | |||
587 | */ | 599 | */ |
588 | static int arc_emac_set_address(struct net_device *ndev, void *p) | 600 | static int arc_emac_set_address(struct net_device *ndev, void *p) |
589 | { | 601 | { |
590 | struct arc_emac_priv *priv = netdev_priv(ndev); | ||
591 | struct sockaddr *addr = p; | 602 | struct sockaddr *addr = p; |
592 | unsigned int addr_low, addr_hi; | ||
593 | 603 | ||
594 | if (netif_running(ndev)) | 604 | if (netif_running(ndev)) |
595 | return -EBUSY; | 605 | return -EBUSY; |
@@ -599,11 +609,7 @@ static int arc_emac_set_address(struct net_device *ndev, void *p) | |||
599 | 609 | ||
600 | memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len); | 610 | memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len); |
601 | 611 | ||
602 | addr_low = le32_to_cpu(*(__le32 *) &ndev->dev_addr[0]); | 612 | arc_emac_set_address_internal(ndev); |
603 | addr_hi = le16_to_cpu(*(__le16 *) &ndev->dev_addr[4]); | ||
604 | |||
605 | arc_reg_set(priv, R_ADDRL, addr_low); | ||
606 | arc_reg_set(priv, R_ADDRH, addr_hi); | ||
607 | 613 | ||
608 | return 0; | 614 | return 0; |
609 | } | 615 | } |
@@ -643,13 +649,6 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
643 | return -ENODEV; | 649 | return -ENODEV; |
644 | } | 650 | } |
645 | 651 | ||
646 | /* Get CPU clock frequency from device tree */ | ||
647 | if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", | ||
648 | &clock_frequency)) { | ||
649 | dev_err(&pdev->dev, "failed to retrieve <clock-frequency> from device tree\n"); | ||
650 | return -EINVAL; | ||
651 | } | ||
652 | |||
653 | /* Get IRQ from device tree */ | 652 | /* Get IRQ from device tree */ |
654 | irq = irq_of_parse_and_map(pdev->dev.of_node, 0); | 653 | irq = irq_of_parse_and_map(pdev->dev.of_node, 0); |
655 | if (!irq) { | 654 | if (!irq) { |
@@ -677,17 +676,36 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
677 | priv->regs = devm_ioremap_resource(&pdev->dev, &res_regs); | 676 | priv->regs = devm_ioremap_resource(&pdev->dev, &res_regs); |
678 | if (IS_ERR(priv->regs)) { | 677 | if (IS_ERR(priv->regs)) { |
679 | err = PTR_ERR(priv->regs); | 678 | err = PTR_ERR(priv->regs); |
680 | goto out; | 679 | goto out_netdev; |
681 | } | 680 | } |
682 | dev_dbg(&pdev->dev, "Registers base address is 0x%p\n", priv->regs); | 681 | dev_dbg(&pdev->dev, "Registers base address is 0x%p\n", priv->regs); |
683 | 682 | ||
683 | priv->clk = of_clk_get(pdev->dev.of_node, 0); | ||
684 | if (IS_ERR(priv->clk)) { | ||
685 | /* Get CPU clock frequency from device tree */ | ||
686 | if (of_property_read_u32(pdev->dev.of_node, "clock-frequency", | ||
687 | &clock_frequency)) { | ||
688 | dev_err(&pdev->dev, "failed to retrieve <clock-frequency> from device tree\n"); | ||
689 | err = -EINVAL; | ||
690 | goto out_netdev; | ||
691 | } | ||
692 | } else { | ||
693 | err = clk_prepare_enable(priv->clk); | ||
694 | if (err) { | ||
695 | dev_err(&pdev->dev, "failed to enable clock\n"); | ||
696 | goto out_clkget; | ||
697 | } | ||
698 | |||
699 | clock_frequency = clk_get_rate(priv->clk); | ||
700 | } | ||
701 | |||
684 | id = arc_reg_get(priv, R_ID); | 702 | id = arc_reg_get(priv, R_ID); |
685 | 703 | ||
686 | /* Check for EMAC revision 5 or 7, magic number */ | 704 | /* Check for EMAC revision 5 or 7, magic number */ |
687 | if (!(id == 0x0005fd02 || id == 0x0007fd02)) { | 705 | if (!(id == 0x0005fd02 || id == 0x0007fd02)) { |
688 | dev_err(&pdev->dev, "ARC EMAC not detected, id=0x%x\n", id); | 706 | dev_err(&pdev->dev, "ARC EMAC not detected, id=0x%x\n", id); |
689 | err = -ENODEV; | 707 | err = -ENODEV; |
690 | goto out; | 708 | goto out_clken; |
691 | } | 709 | } |
692 | dev_info(&pdev->dev, "ARC EMAC detected with id: 0x%x\n", id); | 710 | dev_info(&pdev->dev, "ARC EMAC detected with id: 0x%x\n", id); |
693 | 711 | ||
@@ -702,7 +720,7 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
702 | ndev->name, ndev); | 720 | ndev->name, ndev); |
703 | if (err) { | 721 | if (err) { |
704 | dev_err(&pdev->dev, "could not allocate IRQ\n"); | 722 | dev_err(&pdev->dev, "could not allocate IRQ\n"); |
705 | goto out; | 723 | goto out_clken; |
706 | } | 724 | } |
707 | 725 | ||
708 | /* Get MAC address from device tree */ | 726 | /* Get MAC address from device tree */ |
@@ -713,6 +731,7 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
713 | else | 731 | else |
714 | eth_hw_addr_random(ndev); | 732 | eth_hw_addr_random(ndev); |
715 | 733 | ||
734 | arc_emac_set_address_internal(ndev); | ||
716 | dev_info(&pdev->dev, "MAC address is now %pM\n", ndev->dev_addr); | 735 | dev_info(&pdev->dev, "MAC address is now %pM\n", ndev->dev_addr); |
717 | 736 | ||
718 | /* Do 1 allocation instead of 2 separate ones for Rx and Tx BD rings */ | 737 | /* Do 1 allocation instead of 2 separate ones for Rx and Tx BD rings */ |
@@ -722,7 +741,7 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
722 | if (!priv->rxbd) { | 741 | if (!priv->rxbd) { |
723 | dev_err(&pdev->dev, "failed to allocate data buffers\n"); | 742 | dev_err(&pdev->dev, "failed to allocate data buffers\n"); |
724 | err = -ENOMEM; | 743 | err = -ENOMEM; |
725 | goto out; | 744 | goto out_clken; |
726 | } | 745 | } |
727 | 746 | ||
728 | priv->txbd = priv->rxbd + RX_BD_NUM; | 747 | priv->txbd = priv->rxbd + RX_BD_NUM; |
@@ -734,7 +753,7 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
734 | err = arc_mdio_probe(pdev, priv); | 753 | err = arc_mdio_probe(pdev, priv); |
735 | if (err) { | 754 | if (err) { |
736 | dev_err(&pdev->dev, "failed to probe MII bus\n"); | 755 | dev_err(&pdev->dev, "failed to probe MII bus\n"); |
737 | goto out; | 756 | goto out_clken; |
738 | } | 757 | } |
739 | 758 | ||
740 | priv->phy_dev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0, | 759 | priv->phy_dev = of_phy_connect(ndev, phy_node, arc_emac_adjust_link, 0, |
@@ -742,7 +761,7 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
742 | if (!priv->phy_dev) { | 761 | if (!priv->phy_dev) { |
743 | dev_err(&pdev->dev, "of_phy_connect() failed\n"); | 762 | dev_err(&pdev->dev, "of_phy_connect() failed\n"); |
744 | err = -ENODEV; | 763 | err = -ENODEV; |
745 | goto out; | 764 | goto out_mdio; |
746 | } | 765 | } |
747 | 766 | ||
748 | dev_info(&pdev->dev, "connected to %s phy with id 0x%x\n", | 767 | dev_info(&pdev->dev, "connected to %s phy with id 0x%x\n", |
@@ -752,14 +771,25 @@ static int arc_emac_probe(struct platform_device *pdev) | |||
752 | 771 | ||
753 | err = register_netdev(ndev); | 772 | err = register_netdev(ndev); |
754 | if (err) { | 773 | if (err) { |
755 | netif_napi_del(&priv->napi); | ||
756 | dev_err(&pdev->dev, "failed to register network device\n"); | 774 | dev_err(&pdev->dev, "failed to register network device\n"); |
757 | goto out; | 775 | goto out_netif_api; |
758 | } | 776 | } |
759 | 777 | ||
760 | return 0; | 778 | return 0; |
761 | 779 | ||
762 | out: | 780 | out_netif_api: |
781 | netif_napi_del(&priv->napi); | ||
782 | phy_disconnect(priv->phy_dev); | ||
783 | priv->phy_dev = NULL; | ||
784 | out_mdio: | ||
785 | arc_mdio_remove(priv); | ||
786 | out_clken: | ||
787 | if (!IS_ERR(priv->clk)) | ||
788 | clk_disable_unprepare(priv->clk); | ||
789 | out_clkget: | ||
790 | if (!IS_ERR(priv->clk)) | ||
791 | clk_put(priv->clk); | ||
792 | out_netdev: | ||
763 | free_netdev(ndev); | 793 | free_netdev(ndev); |
764 | return err; | 794 | return err; |
765 | } | 795 | } |
@@ -774,6 +804,12 @@ static int arc_emac_remove(struct platform_device *pdev) | |||
774 | arc_mdio_remove(priv); | 804 | arc_mdio_remove(priv); |
775 | unregister_netdev(ndev); | 805 | unregister_netdev(ndev); |
776 | netif_napi_del(&priv->napi); | 806 | netif_napi_del(&priv->napi); |
807 | |||
808 | if (!IS_ERR(priv->clk)) { | ||
809 | clk_disable_unprepare(priv->clk); | ||
810 | clk_put(priv->clk); | ||
811 | } | ||
812 | |||
777 | free_netdev(ndev); | 813 | free_netdev(ndev); |
778 | 814 | ||
779 | return 0; | 815 | return 0; |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index a78edaccceee..b260913db236 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | |||
@@ -13233,6 +13233,8 @@ static void __bnx2x_remove(struct pci_dev *pdev, | |||
13233 | iounmap(bp->doorbells); | 13233 | iounmap(bp->doorbells); |
13234 | 13234 | ||
13235 | bnx2x_release_firmware(bp); | 13235 | bnx2x_release_firmware(bp); |
13236 | } else { | ||
13237 | bnx2x_vf_pci_dealloc(bp); | ||
13236 | } | 13238 | } |
13237 | bnx2x_free_mem_bp(bp); | 13239 | bnx2x_free_mem_bp(bp); |
13238 | 13240 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c index 5c523b32db70..81cc2d9831c2 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.c | |||
@@ -427,7 +427,9 @@ static int bnx2x_vf_mac_vlan_config(struct bnx2x *bp, | |||
427 | if (filter->add && filter->type == BNX2X_VF_FILTER_VLAN && | 427 | if (filter->add && filter->type == BNX2X_VF_FILTER_VLAN && |
428 | (atomic_read(&bnx2x_vfq(vf, qid, vlan_count)) >= | 428 | (atomic_read(&bnx2x_vfq(vf, qid, vlan_count)) >= |
429 | vf_vlan_rules_cnt(vf))) { | 429 | vf_vlan_rules_cnt(vf))) { |
430 | BNX2X_ERR("No credits for vlan\n"); | 430 | BNX2X_ERR("No credits for vlan [%d >= %d]\n", |
431 | atomic_read(&bnx2x_vfq(vf, qid, vlan_count)), | ||
432 | vf_vlan_rules_cnt(vf)); | ||
431 | return -ENOMEM; | 433 | return -ENOMEM; |
432 | } | 434 | } |
433 | 435 | ||
@@ -610,6 +612,7 @@ int bnx2x_vf_mcast(struct bnx2x *bp, struct bnx2x_virtf *vf, | |||
610 | } | 612 | } |
611 | 613 | ||
612 | /* add new mcasts */ | 614 | /* add new mcasts */ |
615 | mcast.mcast_list_len = mc_num; | ||
613 | rc = bnx2x_config_mcast(bp, &mcast, BNX2X_MCAST_CMD_ADD); | 616 | rc = bnx2x_config_mcast(bp, &mcast, BNX2X_MCAST_CMD_ADD); |
614 | if (rc) | 617 | if (rc) |
615 | BNX2X_ERR("Faled to add multicasts\n"); | 618 | BNX2X_ERR("Faled to add multicasts\n"); |
@@ -837,6 +840,29 @@ int bnx2x_vf_flr_clnup_epilog(struct bnx2x *bp, u8 abs_vfid) | |||
837 | return 0; | 840 | return 0; |
838 | } | 841 | } |
839 | 842 | ||
843 | static void bnx2x_iov_re_set_vlan_filters(struct bnx2x *bp, | ||
844 | struct bnx2x_virtf *vf, | ||
845 | int new) | ||
846 | { | ||
847 | int num = vf_vlan_rules_cnt(vf); | ||
848 | int diff = new - num; | ||
849 | bool rc = true; | ||
850 | |||
851 | DP(BNX2X_MSG_IOV, "vf[%d] - %d vlan filter credits [previously %d]\n", | ||
852 | vf->abs_vfid, new, num); | ||
853 | |||
854 | if (diff > 0) | ||
855 | rc = bp->vlans_pool.get(&bp->vlans_pool, diff); | ||
856 | else if (diff < 0) | ||
857 | rc = bp->vlans_pool.put(&bp->vlans_pool, -diff); | ||
858 | |||
859 | if (rc) | ||
860 | vf_vlan_rules_cnt(vf) = new; | ||
861 | else | ||
862 | DP(BNX2X_MSG_IOV, "vf[%d] - Failed to configure vlan filter credits change\n", | ||
863 | vf->abs_vfid); | ||
864 | } | ||
865 | |||
840 | /* must be called after the number of PF queues and the number of VFs are | 866 | /* must be called after the number of PF queues and the number of VFs are |
841 | * both known | 867 | * both known |
842 | */ | 868 | */ |
@@ -854,9 +880,11 @@ bnx2x_iov_static_resc(struct bnx2x *bp, struct bnx2x_virtf *vf) | |||
854 | resc->num_mac_filters = 1; | 880 | resc->num_mac_filters = 1; |
855 | 881 | ||
856 | /* divvy up vlan rules */ | 882 | /* divvy up vlan rules */ |
883 | bnx2x_iov_re_set_vlan_filters(bp, vf, 0); | ||
857 | vlan_count = bp->vlans_pool.check(&bp->vlans_pool); | 884 | vlan_count = bp->vlans_pool.check(&bp->vlans_pool); |
858 | vlan_count = 1 << ilog2(vlan_count); | 885 | vlan_count = 1 << ilog2(vlan_count); |
859 | resc->num_vlan_filters = vlan_count / BNX2X_NR_VIRTFN(bp); | 886 | bnx2x_iov_re_set_vlan_filters(bp, vf, |
887 | vlan_count / BNX2X_NR_VIRTFN(bp)); | ||
860 | 888 | ||
861 | /* no real limitation */ | 889 | /* no real limitation */ |
862 | resc->num_mc_filters = 0; | 890 | resc->num_mc_filters = 0; |
@@ -1478,10 +1506,6 @@ int bnx2x_iov_nic_init(struct bnx2x *bp) | |||
1478 | bnx2x_iov_static_resc(bp, vf); | 1506 | bnx2x_iov_static_resc(bp, vf); |
1479 | 1507 | ||
1480 | /* queues are initialized during VF-ACQUIRE */ | 1508 | /* queues are initialized during VF-ACQUIRE */ |
1481 | |||
1482 | /* reserve the vf vlan credit */ | ||
1483 | bp->vlans_pool.get(&bp->vlans_pool, vf_vlan_rules_cnt(vf)); | ||
1484 | |||
1485 | vf->filter_state = 0; | 1509 | vf->filter_state = 0; |
1486 | vf->sp_cl_id = bnx2x_fp(bp, 0, cl_id); | 1510 | vf->sp_cl_id = bnx2x_fp(bp, 0, cl_id); |
1487 | 1511 | ||
@@ -1912,11 +1936,12 @@ int bnx2x_vf_chk_avail_resc(struct bnx2x *bp, struct bnx2x_virtf *vf, | |||
1912 | u8 rxq_cnt = vf_rxq_count(vf) ? : bnx2x_vf_max_queue_cnt(bp, vf); | 1936 | u8 rxq_cnt = vf_rxq_count(vf) ? : bnx2x_vf_max_queue_cnt(bp, vf); |
1913 | u8 txq_cnt = vf_txq_count(vf) ? : bnx2x_vf_max_queue_cnt(bp, vf); | 1937 | u8 txq_cnt = vf_txq_count(vf) ? : bnx2x_vf_max_queue_cnt(bp, vf); |
1914 | 1938 | ||
1939 | /* Save a vlan filter for the Hypervisor */ | ||
1915 | return ((req_resc->num_rxqs <= rxq_cnt) && | 1940 | return ((req_resc->num_rxqs <= rxq_cnt) && |
1916 | (req_resc->num_txqs <= txq_cnt) && | 1941 | (req_resc->num_txqs <= txq_cnt) && |
1917 | (req_resc->num_sbs <= vf_sb_count(vf)) && | 1942 | (req_resc->num_sbs <= vf_sb_count(vf)) && |
1918 | (req_resc->num_mac_filters <= vf_mac_rules_cnt(vf)) && | 1943 | (req_resc->num_mac_filters <= vf_mac_rules_cnt(vf)) && |
1919 | (req_resc->num_vlan_filters <= vf_vlan_rules_cnt(vf))); | 1944 | (req_resc->num_vlan_filters <= vf_vlan_rules_visible_cnt(vf))); |
1920 | } | 1945 | } |
1921 | 1946 | ||
1922 | /* CORE VF API */ | 1947 | /* CORE VF API */ |
@@ -1972,14 +1997,14 @@ int bnx2x_vf_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf, | |||
1972 | vf_txq_count(vf) = resc->num_txqs ? : bnx2x_vf_max_queue_cnt(bp, vf); | 1997 | vf_txq_count(vf) = resc->num_txqs ? : bnx2x_vf_max_queue_cnt(bp, vf); |
1973 | if (resc->num_mac_filters) | 1998 | if (resc->num_mac_filters) |
1974 | vf_mac_rules_cnt(vf) = resc->num_mac_filters; | 1999 | vf_mac_rules_cnt(vf) = resc->num_mac_filters; |
1975 | if (resc->num_vlan_filters) | 2000 | /* Add an additional vlan filter credit for the hypervisor */ |
1976 | vf_vlan_rules_cnt(vf) = resc->num_vlan_filters; | 2001 | bnx2x_iov_re_set_vlan_filters(bp, vf, resc->num_vlan_filters + 1); |
1977 | 2002 | ||
1978 | DP(BNX2X_MSG_IOV, | 2003 | DP(BNX2X_MSG_IOV, |
1979 | "Fulfilling vf request: sb count %d, tx_count %d, rx_count %d, mac_rules_count %d, vlan_rules_count %d\n", | 2004 | "Fulfilling vf request: sb count %d, tx_count %d, rx_count %d, mac_rules_count %d, vlan_rules_count %d\n", |
1980 | vf_sb_count(vf), vf_rxq_count(vf), | 2005 | vf_sb_count(vf), vf_rxq_count(vf), |
1981 | vf_txq_count(vf), vf_mac_rules_cnt(vf), | 2006 | vf_txq_count(vf), vf_mac_rules_cnt(vf), |
1982 | vf_vlan_rules_cnt(vf)); | 2007 | vf_vlan_rules_visible_cnt(vf)); |
1983 | 2008 | ||
1984 | /* Initialize the queues */ | 2009 | /* Initialize the queues */ |
1985 | if (!vf->vfqs) { | 2010 | if (!vf->vfqs) { |
@@ -2896,6 +2921,14 @@ void __iomem *bnx2x_vf_doorbells(struct bnx2x *bp) | |||
2896 | return bp->regview + PXP_VF_ADDR_DB_START; | 2921 | return bp->regview + PXP_VF_ADDR_DB_START; |
2897 | } | 2922 | } |
2898 | 2923 | ||
2924 | void bnx2x_vf_pci_dealloc(struct bnx2x *bp) | ||
2925 | { | ||
2926 | BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->vf2pf_mbox_mapping, | ||
2927 | sizeof(struct bnx2x_vf_mbx_msg)); | ||
2928 | BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->pf2vf_bulletin_mapping, | ||
2929 | sizeof(union pf_vf_bulletin)); | ||
2930 | } | ||
2931 | |||
2899 | int bnx2x_vf_pci_alloc(struct bnx2x *bp) | 2932 | int bnx2x_vf_pci_alloc(struct bnx2x *bp) |
2900 | { | 2933 | { |
2901 | mutex_init(&bp->vf2pf_mutex); | 2934 | mutex_init(&bp->vf2pf_mutex); |
@@ -2915,10 +2948,7 @@ int bnx2x_vf_pci_alloc(struct bnx2x *bp) | |||
2915 | return 0; | 2948 | return 0; |
2916 | 2949 | ||
2917 | alloc_mem_err: | 2950 | alloc_mem_err: |
2918 | BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->vf2pf_mbox_mapping, | 2951 | bnx2x_vf_pci_dealloc(bp); |
2919 | sizeof(struct bnx2x_vf_mbx_msg)); | ||
2920 | BNX2X_PCI_FREE(bp->vf2pf_mbox, bp->pf2vf_bulletin_mapping, | ||
2921 | sizeof(union pf_vf_bulletin)); | ||
2922 | return -ENOMEM; | 2952 | return -ENOMEM; |
2923 | } | 2953 | } |
2924 | 2954 | ||
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h index 8bf764570eef..6929adba52f9 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_sriov.h | |||
@@ -159,6 +159,8 @@ struct bnx2x_virtf { | |||
159 | #define vf_mac_rules_cnt(vf) ((vf)->alloc_resc.num_mac_filters) | 159 | #define vf_mac_rules_cnt(vf) ((vf)->alloc_resc.num_mac_filters) |
160 | #define vf_vlan_rules_cnt(vf) ((vf)->alloc_resc.num_vlan_filters) | 160 | #define vf_vlan_rules_cnt(vf) ((vf)->alloc_resc.num_vlan_filters) |
161 | #define vf_mc_rules_cnt(vf) ((vf)->alloc_resc.num_mc_filters) | 161 | #define vf_mc_rules_cnt(vf) ((vf)->alloc_resc.num_mc_filters) |
162 | /* Hide a single vlan filter credit for the hypervisor */ | ||
163 | #define vf_vlan_rules_visible_cnt(vf) (vf_vlan_rules_cnt(vf) - 1) | ||
162 | 164 | ||
163 | u8 sb_count; /* actual number of SBs */ | 165 | u8 sb_count; /* actual number of SBs */ |
164 | u8 igu_base_id; /* base igu status block id */ | 166 | u8 igu_base_id; /* base igu status block id */ |
@@ -502,6 +504,7 @@ static inline int bnx2x_vf_ustorm_prods_offset(struct bnx2x *bp, | |||
502 | enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp); | 504 | enum sample_bulletin_result bnx2x_sample_bulletin(struct bnx2x *bp); |
503 | void bnx2x_timer_sriov(struct bnx2x *bp); | 505 | void bnx2x_timer_sriov(struct bnx2x *bp); |
504 | void __iomem *bnx2x_vf_doorbells(struct bnx2x *bp); | 506 | void __iomem *bnx2x_vf_doorbells(struct bnx2x *bp); |
507 | void bnx2x_vf_pci_dealloc(struct bnx2x *bp); | ||
505 | int bnx2x_vf_pci_alloc(struct bnx2x *bp); | 508 | int bnx2x_vf_pci_alloc(struct bnx2x *bp); |
506 | int bnx2x_enable_sriov(struct bnx2x *bp); | 509 | int bnx2x_enable_sriov(struct bnx2x *bp); |
507 | void bnx2x_disable_sriov(struct bnx2x *bp); | 510 | void bnx2x_disable_sriov(struct bnx2x *bp); |
@@ -568,6 +571,7 @@ static inline void __iomem *bnx2x_vf_doorbells(struct bnx2x *bp) | |||
568 | return NULL; | 571 | return NULL; |
569 | } | 572 | } |
570 | 573 | ||
574 | static inline void bnx2x_vf_pci_dealloc(struct bnx2 *bp) {return 0; } | ||
571 | static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; } | 575 | static inline int bnx2x_vf_pci_alloc(struct bnx2x *bp) {return 0; } |
572 | static inline void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) {} | 576 | static inline void bnx2x_pf_set_vfs_vlan(struct bnx2x *bp) {} |
573 | static inline int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs) {return 0; } | 577 | static inline int bnx2x_sriov_configure(struct pci_dev *dev, int num_vfs) {return 0; } |
diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c index 0622884596b2..0c067e8564dd 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c | |||
@@ -1163,7 +1163,7 @@ static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf, | |||
1163 | bnx2x_vf_max_queue_cnt(bp, vf); | 1163 | bnx2x_vf_max_queue_cnt(bp, vf); |
1164 | resc->num_sbs = vf_sb_count(vf); | 1164 | resc->num_sbs = vf_sb_count(vf); |
1165 | resc->num_mac_filters = vf_mac_rules_cnt(vf); | 1165 | resc->num_mac_filters = vf_mac_rules_cnt(vf); |
1166 | resc->num_vlan_filters = vf_vlan_rules_cnt(vf); | 1166 | resc->num_vlan_filters = vf_vlan_rules_visible_cnt(vf); |
1167 | resc->num_mc_filters = 0; | 1167 | resc->num_mc_filters = 0; |
1168 | 1168 | ||
1169 | if (status == PFVF_STATUS_SUCCESS) { | 1169 | if (status == PFVF_STATUS_SUCCESS) { |
diff --git a/drivers/net/ethernet/cadence/Kconfig b/drivers/net/ethernet/cadence/Kconfig index 7e49c43b7af3..9e089d24466e 100644 --- a/drivers/net/ethernet/cadence/Kconfig +++ b/drivers/net/ethernet/cadence/Kconfig | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | config NET_CADENCE | 5 | config NET_CADENCE |
6 | bool "Cadence devices" | 6 | bool "Cadence devices" |
7 | depends on HAS_IOMEM && (ARM || AVR32 || COMPILE_TEST) | 7 | depends on HAS_IOMEM && (ARM || AVR32 || MICROBLAZE || COMPILE_TEST) |
8 | default y | 8 | default y |
9 | ---help--- | 9 | ---help--- |
10 | If you have a network (Ethernet) card belonging to this class, say Y. | 10 | If you have a network (Ethernet) card belonging to this class, say Y. |
@@ -30,7 +30,7 @@ config ARM_AT91_ETHER | |||
30 | 30 | ||
31 | config MACB | 31 | config MACB |
32 | tristate "Cadence MACB/GEM support" | 32 | tristate "Cadence MACB/GEM support" |
33 | depends on HAS_DMA && (PLATFORM_AT32AP || ARCH_AT91 || ARCH_PICOXCELL || ARCH_ZYNQ || COMPILE_TEST) | 33 | depends on HAS_DMA && (PLATFORM_AT32AP || ARCH_AT91 || ARCH_PICOXCELL || ARCH_ZYNQ || MICROBLAZE || COMPILE_TEST) |
34 | select PHYLIB | 34 | select PHYLIB |
35 | ---help--- | 35 | ---help--- |
36 | The Cadence MACB ethernet interface is found on many Atmel AT32 and | 36 | The Cadence MACB ethernet interface is found on many Atmel AT32 and |
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index ca97005e24b4..e9daa072ebb4 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c | |||
@@ -599,25 +599,16 @@ static void gem_rx_refill(struct macb *bp) | |||
599 | { | 599 | { |
600 | unsigned int entry; | 600 | unsigned int entry; |
601 | struct sk_buff *skb; | 601 | struct sk_buff *skb; |
602 | struct macb_dma_desc *desc; | ||
603 | dma_addr_t paddr; | 602 | dma_addr_t paddr; |
604 | 603 | ||
605 | while (CIRC_SPACE(bp->rx_prepared_head, bp->rx_tail, RX_RING_SIZE) > 0) { | 604 | while (CIRC_SPACE(bp->rx_prepared_head, bp->rx_tail, RX_RING_SIZE) > 0) { |
606 | u32 addr, ctrl; | ||
607 | |||
608 | entry = macb_rx_ring_wrap(bp->rx_prepared_head); | 605 | entry = macb_rx_ring_wrap(bp->rx_prepared_head); |
609 | desc = &bp->rx_ring[entry]; | ||
610 | 606 | ||
611 | /* Make hw descriptor updates visible to CPU */ | 607 | /* Make hw descriptor updates visible to CPU */ |
612 | rmb(); | 608 | rmb(); |
613 | 609 | ||
614 | addr = desc->addr; | ||
615 | ctrl = desc->ctrl; | ||
616 | bp->rx_prepared_head++; | 610 | bp->rx_prepared_head++; |
617 | 611 | ||
618 | if ((addr & MACB_BIT(RX_USED))) | ||
619 | continue; | ||
620 | |||
621 | if (bp->rx_skbuff[entry] == NULL) { | 612 | if (bp->rx_skbuff[entry] == NULL) { |
622 | /* allocate sk_buff for this free entry in ring */ | 613 | /* allocate sk_buff for this free entry in ring */ |
623 | skb = netdev_alloc_skb(bp->dev, bp->rx_buffer_size); | 614 | skb = netdev_alloc_skb(bp->dev, bp->rx_buffer_size); |
@@ -698,7 +689,6 @@ static int gem_rx(struct macb *bp, int budget) | |||
698 | if (!(addr & MACB_BIT(RX_USED))) | 689 | if (!(addr & MACB_BIT(RX_USED))) |
699 | break; | 690 | break; |
700 | 691 | ||
701 | desc->addr &= ~MACB_BIT(RX_USED); | ||
702 | bp->rx_tail++; | 692 | bp->rx_tail++; |
703 | count++; | 693 | count++; |
704 | 694 | ||
@@ -891,16 +881,15 @@ static int macb_poll(struct napi_struct *napi, int budget) | |||
891 | if (work_done < budget) { | 881 | if (work_done < budget) { |
892 | napi_complete(napi); | 882 | napi_complete(napi); |
893 | 883 | ||
894 | /* | ||
895 | * We've done what we can to clean the buffers. Make sure we | ||
896 | * get notified when new packets arrive. | ||
897 | */ | ||
898 | macb_writel(bp, IER, MACB_RX_INT_FLAGS); | ||
899 | |||
900 | /* Packets received while interrupts were disabled */ | 884 | /* Packets received while interrupts were disabled */ |
901 | status = macb_readl(bp, RSR); | 885 | status = macb_readl(bp, RSR); |
902 | if (unlikely(status)) | 886 | if (status) { |
887 | if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) | ||
888 | macb_writel(bp, ISR, MACB_BIT(RCOMP)); | ||
903 | napi_reschedule(napi); | 889 | napi_reschedule(napi); |
890 | } else { | ||
891 | macb_writel(bp, IER, MACB_RX_INT_FLAGS); | ||
892 | } | ||
904 | } | 893 | } |
905 | 894 | ||
906 | /* TODO: Handle errors */ | 895 | /* TODO: Handle errors */ |
@@ -951,6 +940,10 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) | |||
951 | if (unlikely(status & (MACB_TX_ERR_FLAGS))) { | 940 | if (unlikely(status & (MACB_TX_ERR_FLAGS))) { |
952 | macb_writel(bp, IDR, MACB_TX_INT_FLAGS); | 941 | macb_writel(bp, IDR, MACB_TX_INT_FLAGS); |
953 | schedule_work(&bp->tx_error_task); | 942 | schedule_work(&bp->tx_error_task); |
943 | |||
944 | if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) | ||
945 | macb_writel(bp, ISR, MACB_TX_ERR_FLAGS); | ||
946 | |||
954 | break; | 947 | break; |
955 | } | 948 | } |
956 | 949 | ||
@@ -968,6 +961,9 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) | |||
968 | bp->hw_stats.gem.rx_overruns++; | 961 | bp->hw_stats.gem.rx_overruns++; |
969 | else | 962 | else |
970 | bp->hw_stats.macb.rx_overruns++; | 963 | bp->hw_stats.macb.rx_overruns++; |
964 | |||
965 | if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) | ||
966 | macb_writel(bp, ISR, MACB_BIT(ISR_ROVR)); | ||
971 | } | 967 | } |
972 | 968 | ||
973 | if (status & MACB_BIT(HRESP)) { | 969 | if (status & MACB_BIT(HRESP)) { |
@@ -977,6 +973,9 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id) | |||
977 | * (work queue?) | 973 | * (work queue?) |
978 | */ | 974 | */ |
979 | netdev_err(dev, "DMA bus error: HRESP not OK\n"); | 975 | netdev_err(dev, "DMA bus error: HRESP not OK\n"); |
976 | |||
977 | if (bp->caps & MACB_CAPS_ISR_CLEAR_ON_WRITE) | ||
978 | macb_writel(bp, ISR, MACB_BIT(HRESP)); | ||
980 | } | 979 | } |
981 | 980 | ||
982 | status = macb_readl(bp, ISR); | 981 | status = macb_readl(bp, ISR); |
@@ -1113,7 +1112,7 @@ static void gem_free_rx_buffers(struct macb *bp) | |||
1113 | 1112 | ||
1114 | desc = &bp->rx_ring[i]; | 1113 | desc = &bp->rx_ring[i]; |
1115 | addr = MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, desc->addr)); | 1114 | addr = MACB_BF(RX_WADDR, MACB_BFEXT(RX_WADDR, desc->addr)); |
1116 | dma_unmap_single(&bp->pdev->dev, addr, skb->len, | 1115 | dma_unmap_single(&bp->pdev->dev, addr, bp->rx_buffer_size, |
1117 | DMA_FROM_DEVICE); | 1116 | DMA_FROM_DEVICE); |
1118 | dev_kfree_skb_any(skb); | 1117 | dev_kfree_skb_any(skb); |
1119 | skb = NULL; | 1118 | skb = NULL; |
diff --git a/drivers/net/ethernet/chelsio/Kconfig b/drivers/net/ethernet/chelsio/Kconfig index d40c994a4f6a..570222c33410 100644 --- a/drivers/net/ethernet/chelsio/Kconfig +++ b/drivers/net/ethernet/chelsio/Kconfig | |||
@@ -67,13 +67,13 @@ config CHELSIO_T3 | |||
67 | will be called cxgb3. | 67 | will be called cxgb3. |
68 | 68 | ||
69 | config CHELSIO_T4 | 69 | config CHELSIO_T4 |
70 | tristate "Chelsio Communications T4 Ethernet support" | 70 | tristate "Chelsio Communications T4/T5 Ethernet support" |
71 | depends on PCI | 71 | depends on PCI |
72 | select FW_LOADER | 72 | select FW_LOADER |
73 | select MDIO | 73 | select MDIO |
74 | ---help--- | 74 | ---help--- |
75 | This driver supports Chelsio T4-based gigabit and 10Gb Ethernet | 75 | This driver supports Chelsio T4 and T5 based gigabit, 10Gb Ethernet |
76 | adapters. | 76 | adapter and T5 based 40Gb Ethernet adapter. |
77 | 77 | ||
78 | For general information about Chelsio and our products, visit | 78 | For general information about Chelsio and our products, visit |
79 | our website at <http://www.chelsio.com>. | 79 | our website at <http://www.chelsio.com>. |
@@ -87,11 +87,12 @@ config CHELSIO_T4 | |||
87 | will be called cxgb4. | 87 | will be called cxgb4. |
88 | 88 | ||
89 | config CHELSIO_T4VF | 89 | config CHELSIO_T4VF |
90 | tristate "Chelsio Communications T4 Virtual Function Ethernet support" | 90 | tristate "Chelsio Communications T4/T5 Virtual Function Ethernet support" |
91 | depends on PCI | 91 | depends on PCI |
92 | ---help--- | 92 | ---help--- |
93 | This driver supports Chelsio T4-based gigabit and 10Gb Ethernet | 93 | This driver supports Chelsio T4 and T5 based gigabit, 10Gb Ethernet |
94 | adapters with PCI-E SR-IOV Virtual Functions. | 94 | adapters and T5 based 40Gb Ethernet adapters with PCI-E SR-IOV Virtual |
95 | Functions. | ||
95 | 96 | ||
96 | For general information about Chelsio and our products, visit | 97 | For general information about Chelsio and our products, visit |
97 | our website at <http://www.chelsio.com>. | 98 | our website at <http://www.chelsio.com>. |
diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c index 6fe58913403a..24e16e3301e0 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_main.c | |||
@@ -5870,6 +5870,8 @@ static void print_port_info(const struct net_device *dev) | |||
5870 | spd = " 2.5 GT/s"; | 5870 | spd = " 2.5 GT/s"; |
5871 | else if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_5_0GB) | 5871 | else if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_5_0GB) |
5872 | spd = " 5 GT/s"; | 5872 | spd = " 5 GT/s"; |
5873 | else if (adap->params.pci.speed == PCI_EXP_LNKSTA_CLS_8_0GB) | ||
5874 | spd = " 8 GT/s"; | ||
5873 | 5875 | ||
5874 | if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100M) | 5876 | if (pi->link_cfg.supported & FW_PORT_CAP_SPEED_100M) |
5875 | bufp += sprintf(bufp, "100/"); | 5877 | bufp += sprintf(bufp, "100/"); |
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c index 9125d9abf099..e2d42475b006 100644 --- a/drivers/net/ethernet/freescale/gianfar.c +++ b/drivers/net/ethernet/freescale/gianfar.c | |||
@@ -121,6 +121,7 @@ static irqreturn_t gfar_error(int irq, void *dev_id); | |||
121 | static irqreturn_t gfar_transmit(int irq, void *dev_id); | 121 | static irqreturn_t gfar_transmit(int irq, void *dev_id); |
122 | static irqreturn_t gfar_interrupt(int irq, void *dev_id); | 122 | static irqreturn_t gfar_interrupt(int irq, void *dev_id); |
123 | static void adjust_link(struct net_device *dev); | 123 | static void adjust_link(struct net_device *dev); |
124 | static noinline void gfar_update_link_state(struct gfar_private *priv); | ||
124 | static int init_phy(struct net_device *dev); | 125 | static int init_phy(struct net_device *dev); |
125 | static int gfar_probe(struct platform_device *ofdev); | 126 | static int gfar_probe(struct platform_device *ofdev); |
126 | static int gfar_remove(struct platform_device *ofdev); | 127 | static int gfar_remove(struct platform_device *ofdev); |
@@ -3076,41 +3077,6 @@ static irqreturn_t gfar_interrupt(int irq, void *grp_id) | |||
3076 | return IRQ_HANDLED; | 3077 | return IRQ_HANDLED; |
3077 | } | 3078 | } |
3078 | 3079 | ||
3079 | static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv) | ||
3080 | { | ||
3081 | struct phy_device *phydev = priv->phydev; | ||
3082 | u32 val = 0; | ||
3083 | |||
3084 | if (!phydev->duplex) | ||
3085 | return val; | ||
3086 | |||
3087 | if (!priv->pause_aneg_en) { | ||
3088 | if (priv->tx_pause_en) | ||
3089 | val |= MACCFG1_TX_FLOW; | ||
3090 | if (priv->rx_pause_en) | ||
3091 | val |= MACCFG1_RX_FLOW; | ||
3092 | } else { | ||
3093 | u16 lcl_adv, rmt_adv; | ||
3094 | u8 flowctrl; | ||
3095 | /* get link partner capabilities */ | ||
3096 | rmt_adv = 0; | ||
3097 | if (phydev->pause) | ||
3098 | rmt_adv = LPA_PAUSE_CAP; | ||
3099 | if (phydev->asym_pause) | ||
3100 | rmt_adv |= LPA_PAUSE_ASYM; | ||
3101 | |||
3102 | lcl_adv = mii_advertise_flowctrl(phydev->advertising); | ||
3103 | |||
3104 | flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); | ||
3105 | if (flowctrl & FLOW_CTRL_TX) | ||
3106 | val |= MACCFG1_TX_FLOW; | ||
3107 | if (flowctrl & FLOW_CTRL_RX) | ||
3108 | val |= MACCFG1_RX_FLOW; | ||
3109 | } | ||
3110 | |||
3111 | return val; | ||
3112 | } | ||
3113 | |||
3114 | /* Called every time the controller might need to be made | 3080 | /* Called every time the controller might need to be made |
3115 | * aware of new link state. The PHY code conveys this | 3081 | * aware of new link state. The PHY code conveys this |
3116 | * information through variables in the phydev structure, and this | 3082 | * information through variables in the phydev structure, and this |
@@ -3120,83 +3086,12 @@ static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv) | |||
3120 | static void adjust_link(struct net_device *dev) | 3086 | static void adjust_link(struct net_device *dev) |
3121 | { | 3087 | { |
3122 | struct gfar_private *priv = netdev_priv(dev); | 3088 | struct gfar_private *priv = netdev_priv(dev); |
3123 | struct gfar __iomem *regs = priv->gfargrp[0].regs; | ||
3124 | struct phy_device *phydev = priv->phydev; | 3089 | struct phy_device *phydev = priv->phydev; |
3125 | int new_state = 0; | ||
3126 | 3090 | ||
3127 | if (test_bit(GFAR_RESETTING, &priv->state)) | 3091 | if (unlikely(phydev->link != priv->oldlink || |
3128 | return; | 3092 | phydev->duplex != priv->oldduplex || |
3129 | 3093 | phydev->speed != priv->oldspeed)) | |
3130 | if (phydev->link) { | 3094 | gfar_update_link_state(priv); |
3131 | u32 tempval1 = gfar_read(®s->maccfg1); | ||
3132 | u32 tempval = gfar_read(®s->maccfg2); | ||
3133 | u32 ecntrl = gfar_read(®s->ecntrl); | ||
3134 | |||
3135 | /* Now we make sure that we can be in full duplex mode. | ||
3136 | * If not, we operate in half-duplex mode. | ||
3137 | */ | ||
3138 | if (phydev->duplex != priv->oldduplex) { | ||
3139 | new_state = 1; | ||
3140 | if (!(phydev->duplex)) | ||
3141 | tempval &= ~(MACCFG2_FULL_DUPLEX); | ||
3142 | else | ||
3143 | tempval |= MACCFG2_FULL_DUPLEX; | ||
3144 | |||
3145 | priv->oldduplex = phydev->duplex; | ||
3146 | } | ||
3147 | |||
3148 | if (phydev->speed != priv->oldspeed) { | ||
3149 | new_state = 1; | ||
3150 | switch (phydev->speed) { | ||
3151 | case 1000: | ||
3152 | tempval = | ||
3153 | ((tempval & ~(MACCFG2_IF)) | MACCFG2_GMII); | ||
3154 | |||
3155 | ecntrl &= ~(ECNTRL_R100); | ||
3156 | break; | ||
3157 | case 100: | ||
3158 | case 10: | ||
3159 | tempval = | ||
3160 | ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII); | ||
3161 | |||
3162 | /* Reduced mode distinguishes | ||
3163 | * between 10 and 100 | ||
3164 | */ | ||
3165 | if (phydev->speed == SPEED_100) | ||
3166 | ecntrl |= ECNTRL_R100; | ||
3167 | else | ||
3168 | ecntrl &= ~(ECNTRL_R100); | ||
3169 | break; | ||
3170 | default: | ||
3171 | netif_warn(priv, link, dev, | ||
3172 | "Ack! Speed (%d) is not 10/100/1000!\n", | ||
3173 | phydev->speed); | ||
3174 | break; | ||
3175 | } | ||
3176 | |||
3177 | priv->oldspeed = phydev->speed; | ||
3178 | } | ||
3179 | |||
3180 | tempval1 &= ~(MACCFG1_TX_FLOW | MACCFG1_RX_FLOW); | ||
3181 | tempval1 |= gfar_get_flowctrl_cfg(priv); | ||
3182 | |||
3183 | gfar_write(®s->maccfg1, tempval1); | ||
3184 | gfar_write(®s->maccfg2, tempval); | ||
3185 | gfar_write(®s->ecntrl, ecntrl); | ||
3186 | |||
3187 | if (!priv->oldlink) { | ||
3188 | new_state = 1; | ||
3189 | priv->oldlink = 1; | ||
3190 | } | ||
3191 | } else if (priv->oldlink) { | ||
3192 | new_state = 1; | ||
3193 | priv->oldlink = 0; | ||
3194 | priv->oldspeed = 0; | ||
3195 | priv->oldduplex = -1; | ||
3196 | } | ||
3197 | |||
3198 | if (new_state && netif_msg_link(priv)) | ||
3199 | phy_print_status(phydev); | ||
3200 | } | 3095 | } |
3201 | 3096 | ||
3202 | /* Update the hash table based on the current list of multicast | 3097 | /* Update the hash table based on the current list of multicast |
@@ -3442,6 +3337,114 @@ static irqreturn_t gfar_error(int irq, void *grp_id) | |||
3442 | return IRQ_HANDLED; | 3337 | return IRQ_HANDLED; |
3443 | } | 3338 | } |
3444 | 3339 | ||
3340 | static u32 gfar_get_flowctrl_cfg(struct gfar_private *priv) | ||
3341 | { | ||
3342 | struct phy_device *phydev = priv->phydev; | ||
3343 | u32 val = 0; | ||
3344 | |||
3345 | if (!phydev->duplex) | ||
3346 | return val; | ||
3347 | |||
3348 | if (!priv->pause_aneg_en) { | ||
3349 | if (priv->tx_pause_en) | ||
3350 | val |= MACCFG1_TX_FLOW; | ||
3351 | if (priv->rx_pause_en) | ||
3352 | val |= MACCFG1_RX_FLOW; | ||
3353 | } else { | ||
3354 | u16 lcl_adv, rmt_adv; | ||
3355 | u8 flowctrl; | ||
3356 | /* get link partner capabilities */ | ||
3357 | rmt_adv = 0; | ||
3358 | if (phydev->pause) | ||
3359 | rmt_adv = LPA_PAUSE_CAP; | ||
3360 | if (phydev->asym_pause) | ||
3361 | rmt_adv |= LPA_PAUSE_ASYM; | ||
3362 | |||
3363 | lcl_adv = mii_advertise_flowctrl(phydev->advertising); | ||
3364 | |||
3365 | flowctrl = mii_resolve_flowctrl_fdx(lcl_adv, rmt_adv); | ||
3366 | if (flowctrl & FLOW_CTRL_TX) | ||
3367 | val |= MACCFG1_TX_FLOW; | ||
3368 | if (flowctrl & FLOW_CTRL_RX) | ||
3369 | val |= MACCFG1_RX_FLOW; | ||
3370 | } | ||
3371 | |||
3372 | return val; | ||
3373 | } | ||
3374 | |||
3375 | static noinline void gfar_update_link_state(struct gfar_private *priv) | ||
3376 | { | ||
3377 | struct gfar __iomem *regs = priv->gfargrp[0].regs; | ||
3378 | struct phy_device *phydev = priv->phydev; | ||
3379 | |||
3380 | if (unlikely(test_bit(GFAR_RESETTING, &priv->state))) | ||
3381 | return; | ||
3382 | |||
3383 | if (phydev->link) { | ||
3384 | u32 tempval1 = gfar_read(®s->maccfg1); | ||
3385 | u32 tempval = gfar_read(®s->maccfg2); | ||
3386 | u32 ecntrl = gfar_read(®s->ecntrl); | ||
3387 | |||
3388 | if (phydev->duplex != priv->oldduplex) { | ||
3389 | if (!(phydev->duplex)) | ||
3390 | tempval &= ~(MACCFG2_FULL_DUPLEX); | ||
3391 | else | ||
3392 | tempval |= MACCFG2_FULL_DUPLEX; | ||
3393 | |||
3394 | priv->oldduplex = phydev->duplex; | ||
3395 | } | ||
3396 | |||
3397 | if (phydev->speed != priv->oldspeed) { | ||
3398 | switch (phydev->speed) { | ||
3399 | case 1000: | ||
3400 | tempval = | ||
3401 | ((tempval & ~(MACCFG2_IF)) | MACCFG2_GMII); | ||
3402 | |||
3403 | ecntrl &= ~(ECNTRL_R100); | ||
3404 | break; | ||
3405 | case 100: | ||
3406 | case 10: | ||
3407 | tempval = | ||
3408 | ((tempval & ~(MACCFG2_IF)) | MACCFG2_MII); | ||
3409 | |||
3410 | /* Reduced mode distinguishes | ||
3411 | * between 10 and 100 | ||
3412 | */ | ||
3413 | if (phydev->speed == SPEED_100) | ||
3414 | ecntrl |= ECNTRL_R100; | ||
3415 | else | ||
3416 | ecntrl &= ~(ECNTRL_R100); | ||
3417 | break; | ||
3418 | default: | ||
3419 | netif_warn(priv, link, priv->ndev, | ||
3420 | "Ack! Speed (%d) is not 10/100/1000!\n", | ||
3421 | phydev->speed); | ||
3422 | break; | ||
3423 | } | ||
3424 | |||
3425 | priv->oldspeed = phydev->speed; | ||
3426 | } | ||
3427 | |||
3428 | tempval1 &= ~(MACCFG1_TX_FLOW | MACCFG1_RX_FLOW); | ||
3429 | tempval1 |= gfar_get_flowctrl_cfg(priv); | ||
3430 | |||
3431 | gfar_write(®s->maccfg1, tempval1); | ||
3432 | gfar_write(®s->maccfg2, tempval); | ||
3433 | gfar_write(®s->ecntrl, ecntrl); | ||
3434 | |||
3435 | if (!priv->oldlink) | ||
3436 | priv->oldlink = 1; | ||
3437 | |||
3438 | } else if (priv->oldlink) { | ||
3439 | priv->oldlink = 0; | ||
3440 | priv->oldspeed = 0; | ||
3441 | priv->oldduplex = -1; | ||
3442 | } | ||
3443 | |||
3444 | if (netif_msg_link(priv)) | ||
3445 | phy_print_status(phydev); | ||
3446 | } | ||
3447 | |||
3445 | static struct of_device_id gfar_match[] = | 3448 | static struct of_device_id gfar_match[] = |
3446 | { | 3449 | { |
3447 | { | 3450 | { |
diff --git a/drivers/net/ethernet/freescale/gianfar_ethtool.c b/drivers/net/ethernet/freescale/gianfar_ethtool.c index 891dbee6e6c1..76d70708f864 100644 --- a/drivers/net/ethernet/freescale/gianfar_ethtool.c +++ b/drivers/net/ethernet/freescale/gianfar_ethtool.c | |||
@@ -533,6 +533,9 @@ static int gfar_spauseparam(struct net_device *dev, | |||
533 | struct gfar __iomem *regs = priv->gfargrp[0].regs; | 533 | struct gfar __iomem *regs = priv->gfargrp[0].regs; |
534 | u32 oldadv, newadv; | 534 | u32 oldadv, newadv; |
535 | 535 | ||
536 | if (!phydev) | ||
537 | return -ENODEV; | ||
538 | |||
536 | if (!(phydev->supported & SUPPORTED_Pause) || | 539 | if (!(phydev->supported & SUPPORTED_Pause) || |
537 | (!(phydev->supported & SUPPORTED_Asym_Pause) && | 540 | (!(phydev->supported & SUPPORTED_Asym_Pause) && |
538 | (epause->rx_pause != epause->tx_pause))) | 541 | (epause->rx_pause != epause->tx_pause))) |
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c index 9866f264f55e..f0bbd4246d71 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.c +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c | |||
@@ -186,7 +186,7 @@ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw) | |||
186 | { | 186 | { |
187 | u16 phy_reg = 0; | 187 | u16 phy_reg = 0; |
188 | u32 phy_id = 0; | 188 | u32 phy_id = 0; |
189 | s32 ret_val; | 189 | s32 ret_val = 0; |
190 | u16 retry_count; | 190 | u16 retry_count; |
191 | u32 mac_reg = 0; | 191 | u32 mac_reg = 0; |
192 | 192 | ||
@@ -217,11 +217,13 @@ static bool e1000_phy_is_accessible_pchlan(struct e1000_hw *hw) | |||
217 | /* In case the PHY needs to be in mdio slow mode, | 217 | /* In case the PHY needs to be in mdio slow mode, |
218 | * set slow mode and try to get the PHY id again. | 218 | * set slow mode and try to get the PHY id again. |
219 | */ | 219 | */ |
220 | hw->phy.ops.release(hw); | 220 | if (hw->mac.type < e1000_pch_lpt) { |
221 | ret_val = e1000_set_mdio_slow_mode_hv(hw); | 221 | hw->phy.ops.release(hw); |
222 | if (!ret_val) | 222 | ret_val = e1000_set_mdio_slow_mode_hv(hw); |
223 | ret_val = e1000e_get_phy_id(hw); | 223 | if (!ret_val) |
224 | hw->phy.ops.acquire(hw); | 224 | ret_val = e1000e_get_phy_id(hw); |
225 | hw->phy.ops.acquire(hw); | ||
226 | } | ||
225 | 227 | ||
226 | if (ret_val) | 228 | if (ret_val) |
227 | return false; | 229 | return false; |
@@ -842,6 +844,17 @@ s32 e1000_set_eee_pchlan(struct e1000_hw *hw) | |||
842 | } | 844 | } |
843 | } | 845 | } |
844 | 846 | ||
847 | if (hw->phy.type == e1000_phy_82579) { | ||
848 | ret_val = e1000_read_emi_reg_locked(hw, I82579_LPI_PLL_SHUT, | ||
849 | &data); | ||
850 | if (ret_val) | ||
851 | goto release; | ||
852 | |||
853 | data &= ~I82579_LPI_100_PLL_SHUT; | ||
854 | ret_val = e1000_write_emi_reg_locked(hw, I82579_LPI_PLL_SHUT, | ||
855 | data); | ||
856 | } | ||
857 | |||
845 | /* R/Clr IEEE MMD 3.1 bits 11:10 - Tx/Rx LPI Received */ | 858 | /* R/Clr IEEE MMD 3.1 bits 11:10 - Tx/Rx LPI Received */ |
846 | ret_val = e1000_read_emi_reg_locked(hw, pcs_status, &data); | 859 | ret_val = e1000_read_emi_reg_locked(hw, pcs_status, &data); |
847 | if (ret_val) | 860 | if (ret_val) |
@@ -1314,14 +1327,17 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
1314 | return ret_val; | 1327 | return ret_val; |
1315 | } | 1328 | } |
1316 | 1329 | ||
1317 | /* When connected at 10Mbps half-duplex, 82579 parts are excessively | 1330 | /* When connected at 10Mbps half-duplex, some parts are excessively |
1318 | * aggressive resulting in many collisions. To avoid this, increase | 1331 | * aggressive resulting in many collisions. To avoid this, increase |
1319 | * the IPG and reduce Rx latency in the PHY. | 1332 | * the IPG and reduce Rx latency in the PHY. |
1320 | */ | 1333 | */ |
1321 | if ((hw->mac.type == e1000_pch2lan) && link) { | 1334 | if (((hw->mac.type == e1000_pch2lan) || |
1335 | (hw->mac.type == e1000_pch_lpt)) && link) { | ||
1322 | u32 reg; | 1336 | u32 reg; |
1323 | reg = er32(STATUS); | 1337 | reg = er32(STATUS); |
1324 | if (!(reg & (E1000_STATUS_FD | E1000_STATUS_SPEED_MASK))) { | 1338 | if (!(reg & (E1000_STATUS_FD | E1000_STATUS_SPEED_MASK))) { |
1339 | u16 emi_addr; | ||
1340 | |||
1325 | reg = er32(TIPG); | 1341 | reg = er32(TIPG); |
1326 | reg &= ~E1000_TIPG_IPGT_MASK; | 1342 | reg &= ~E1000_TIPG_IPGT_MASK; |
1327 | reg |= 0xFF; | 1343 | reg |= 0xFF; |
@@ -1332,8 +1348,12 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw) | |||
1332 | if (ret_val) | 1348 | if (ret_val) |
1333 | return ret_val; | 1349 | return ret_val; |
1334 | 1350 | ||
1335 | ret_val = | 1351 | if (hw->mac.type == e1000_pch2lan) |
1336 | e1000_write_emi_reg_locked(hw, I82579_RX_CONFIG, 0); | 1352 | emi_addr = I82579_RX_CONFIG; |
1353 | else | ||
1354 | emi_addr = I217_RX_CONFIG; | ||
1355 | |||
1356 | ret_val = e1000_write_emi_reg_locked(hw, emi_addr, 0); | ||
1337 | 1357 | ||
1338 | hw->phy.ops.release(hw); | 1358 | hw->phy.ops.release(hw); |
1339 | 1359 | ||
@@ -2493,51 +2513,44 @@ release: | |||
2493 | * e1000_k1_gig_workaround_lv - K1 Si workaround | 2513 | * e1000_k1_gig_workaround_lv - K1 Si workaround |
2494 | * @hw: pointer to the HW structure | 2514 | * @hw: pointer to the HW structure |
2495 | * | 2515 | * |
2496 | * Workaround to set the K1 beacon duration for 82579 parts | 2516 | * Workaround to set the K1 beacon duration for 82579 parts in 10Mbps |
2517 | * Disable K1 in 1000Mbps and 100Mbps | ||
2497 | **/ | 2518 | **/ |
2498 | static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) | 2519 | static s32 e1000_k1_workaround_lv(struct e1000_hw *hw) |
2499 | { | 2520 | { |
2500 | s32 ret_val = 0; | 2521 | s32 ret_val = 0; |
2501 | u16 status_reg = 0; | 2522 | u16 status_reg = 0; |
2502 | u32 mac_reg; | ||
2503 | u16 phy_reg; | ||
2504 | 2523 | ||
2505 | if (hw->mac.type != e1000_pch2lan) | 2524 | if (hw->mac.type != e1000_pch2lan) |
2506 | return 0; | 2525 | return 0; |
2507 | 2526 | ||
2508 | /* Set K1 beacon duration based on 1Gbps speed or otherwise */ | 2527 | /* Set K1 beacon duration based on 10Mbs speed */ |
2509 | ret_val = e1e_rphy(hw, HV_M_STATUS, &status_reg); | 2528 | ret_val = e1e_rphy(hw, HV_M_STATUS, &status_reg); |
2510 | if (ret_val) | 2529 | if (ret_val) |
2511 | return ret_val; | 2530 | return ret_val; |
2512 | 2531 | ||
2513 | if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) | 2532 | if ((status_reg & (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) |
2514 | == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) { | 2533 | == (HV_M_STATUS_LINK_UP | HV_M_STATUS_AUTONEG_COMPLETE)) { |
2515 | mac_reg = er32(FEXTNVM4); | 2534 | if (status_reg & |
2516 | mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK; | 2535 | (HV_M_STATUS_SPEED_1000 | HV_M_STATUS_SPEED_100)) { |
2517 | |||
2518 | ret_val = e1e_rphy(hw, I82579_LPI_CTRL, &phy_reg); | ||
2519 | if (ret_val) | ||
2520 | return ret_val; | ||
2521 | |||
2522 | if (status_reg & HV_M_STATUS_SPEED_1000) { | ||
2523 | u16 pm_phy_reg; | 2536 | u16 pm_phy_reg; |
2524 | 2537 | ||
2525 | mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_8USEC; | 2538 | /* LV 1G/100 Packet drop issue wa */ |
2526 | phy_reg &= ~I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT; | ||
2527 | /* LV 1G Packet drop issue wa */ | ||
2528 | ret_val = e1e_rphy(hw, HV_PM_CTRL, &pm_phy_reg); | 2539 | ret_val = e1e_rphy(hw, HV_PM_CTRL, &pm_phy_reg); |
2529 | if (ret_val) | 2540 | if (ret_val) |
2530 | return ret_val; | 2541 | return ret_val; |
2531 | pm_phy_reg &= ~HV_PM_CTRL_PLL_STOP_IN_K1_GIGA; | 2542 | pm_phy_reg &= ~HV_PM_CTRL_K1_ENABLE; |
2532 | ret_val = e1e_wphy(hw, HV_PM_CTRL, pm_phy_reg); | 2543 | ret_val = e1e_wphy(hw, HV_PM_CTRL, pm_phy_reg); |
2533 | if (ret_val) | 2544 | if (ret_val) |
2534 | return ret_val; | 2545 | return ret_val; |
2535 | } else { | 2546 | } else { |
2547 | u32 mac_reg; | ||
2548 | |||
2549 | mac_reg = er32(FEXTNVM4); | ||
2550 | mac_reg &= ~E1000_FEXTNVM4_BEACON_DURATION_MASK; | ||
2536 | mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC; | 2551 | mac_reg |= E1000_FEXTNVM4_BEACON_DURATION_16USEC; |
2537 | phy_reg |= I82579_LPI_CTRL_FORCE_PLL_LOCK_COUNT; | 2552 | ew32(FEXTNVM4, mac_reg); |
2538 | } | 2553 | } |
2539 | ew32(FEXTNVM4, mac_reg); | ||
2540 | ret_val = e1e_wphy(hw, I82579_LPI_CTRL, phy_reg); | ||
2541 | } | 2554 | } |
2542 | 2555 | ||
2543 | return ret_val; | 2556 | return ret_val; |
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.h b/drivers/net/ethernet/intel/e1000e/ich8lan.h index bead50f9187b..5515126c81c1 100644 --- a/drivers/net/ethernet/intel/e1000e/ich8lan.h +++ b/drivers/net/ethernet/intel/e1000e/ich8lan.h | |||
@@ -232,16 +232,19 @@ | |||
232 | #define I82577_MSE_THRESHOLD 0x0887 /* 82577 Mean Square Error Threshold */ | 232 | #define I82577_MSE_THRESHOLD 0x0887 /* 82577 Mean Square Error Threshold */ |
233 | #define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */ | 233 | #define I82579_MSE_LINK_DOWN 0x2411 /* MSE count before dropping link */ |
234 | #define I82579_RX_CONFIG 0x3412 /* Receive configuration */ | 234 | #define I82579_RX_CONFIG 0x3412 /* Receive configuration */ |
235 | #define I82579_LPI_PLL_SHUT 0x4412 /* LPI PLL Shut Enable */ | ||
235 | #define I82579_EEE_PCS_STATUS 0x182E /* IEEE MMD Register 3.1 >> 8 */ | 236 | #define I82579_EEE_PCS_STATUS 0x182E /* IEEE MMD Register 3.1 >> 8 */ |
236 | #define I82579_EEE_CAPABILITY 0x0410 /* IEEE MMD Register 3.20 */ | 237 | #define I82579_EEE_CAPABILITY 0x0410 /* IEEE MMD Register 3.20 */ |
237 | #define I82579_EEE_ADVERTISEMENT 0x040E /* IEEE MMD Register 7.60 */ | 238 | #define I82579_EEE_ADVERTISEMENT 0x040E /* IEEE MMD Register 7.60 */ |
238 | #define I82579_EEE_LP_ABILITY 0x040F /* IEEE MMD Register 7.61 */ | 239 | #define I82579_EEE_LP_ABILITY 0x040F /* IEEE MMD Register 7.61 */ |
239 | #define I82579_EEE_100_SUPPORTED (1 << 1) /* 100BaseTx EEE */ | 240 | #define I82579_EEE_100_SUPPORTED (1 << 1) /* 100BaseTx EEE */ |
240 | #define I82579_EEE_1000_SUPPORTED (1 << 2) /* 1000BaseTx EEE */ | 241 | #define I82579_EEE_1000_SUPPORTED (1 << 2) /* 1000BaseTx EEE */ |
242 | #define I82579_LPI_100_PLL_SHUT (1 << 2) /* 100M LPI PLL Shut Enabled */ | ||
241 | #define I217_EEE_PCS_STATUS 0x9401 /* IEEE MMD Register 3.1 */ | 243 | #define I217_EEE_PCS_STATUS 0x9401 /* IEEE MMD Register 3.1 */ |
242 | #define I217_EEE_CAPABILITY 0x8000 /* IEEE MMD Register 3.20 */ | 244 | #define I217_EEE_CAPABILITY 0x8000 /* IEEE MMD Register 3.20 */ |
243 | #define I217_EEE_ADVERTISEMENT 0x8001 /* IEEE MMD Register 7.60 */ | 245 | #define I217_EEE_ADVERTISEMENT 0x8001 /* IEEE MMD Register 7.60 */ |
244 | #define I217_EEE_LP_ABILITY 0x8002 /* IEEE MMD Register 7.61 */ | 246 | #define I217_EEE_LP_ABILITY 0x8002 /* IEEE MMD Register 7.61 */ |
247 | #define I217_RX_CONFIG 0xB20C /* Receive configuration */ | ||
245 | 248 | ||
246 | #define E1000_EEE_RX_LPI_RCVD 0x0400 /* Tx LP idle received */ | 249 | #define E1000_EEE_RX_LPI_RCVD 0x0400 /* Tx LP idle received */ |
247 | #define E1000_EEE_TX_LPI_RCVD 0x0800 /* Rx LP idle received */ | 250 | #define E1000_EEE_TX_LPI_RCVD 0x0800 /* Rx LP idle received */ |
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c index d50c91e50528..3e69386add04 100644 --- a/drivers/net/ethernet/intel/e1000e/netdev.c +++ b/drivers/net/ethernet/intel/e1000e/netdev.c | |||
@@ -1165,7 +1165,7 @@ static void e1000e_tx_hwtstamp_work(struct work_struct *work) | |||
1165 | dev_kfree_skb_any(adapter->tx_hwtstamp_skb); | 1165 | dev_kfree_skb_any(adapter->tx_hwtstamp_skb); |
1166 | adapter->tx_hwtstamp_skb = NULL; | 1166 | adapter->tx_hwtstamp_skb = NULL; |
1167 | adapter->tx_hwtstamp_timeouts++; | 1167 | adapter->tx_hwtstamp_timeouts++; |
1168 | e_warn("clearing Tx timestamp hang"); | 1168 | e_warn("clearing Tx timestamp hang\n"); |
1169 | } else { | 1169 | } else { |
1170 | /* reschedule to check later */ | 1170 | /* reschedule to check later */ |
1171 | schedule_work(&adapter->tx_hwtstamp_work); | 1171 | schedule_work(&adapter->tx_hwtstamp_work); |
@@ -5687,7 +5687,7 @@ struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev, | |||
5687 | static int e1000_change_mtu(struct net_device *netdev, int new_mtu) | 5687 | static int e1000_change_mtu(struct net_device *netdev, int new_mtu) |
5688 | { | 5688 | { |
5689 | struct e1000_adapter *adapter = netdev_priv(netdev); | 5689 | struct e1000_adapter *adapter = netdev_priv(netdev); |
5690 | int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; | 5690 | int max_frame = new_mtu + VLAN_HLEN + ETH_HLEN + ETH_FCS_LEN; |
5691 | 5691 | ||
5692 | /* Jumbo frame support */ | 5692 | /* Jumbo frame support */ |
5693 | if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) && | 5693 | if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) && |
@@ -6235,6 +6235,7 @@ static int __e1000_resume(struct pci_dev *pdev) | |||
6235 | return 0; | 6235 | return 0; |
6236 | } | 6236 | } |
6237 | 6237 | ||
6238 | #ifdef CONFIG_PM_SLEEP | ||
6238 | static int e1000e_pm_thaw(struct device *dev) | 6239 | static int e1000e_pm_thaw(struct device *dev) |
6239 | { | 6240 | { |
6240 | struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); | 6241 | struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev)); |
@@ -6255,7 +6256,6 @@ static int e1000e_pm_thaw(struct device *dev) | |||
6255 | return 0; | 6256 | return 0; |
6256 | } | 6257 | } |
6257 | 6258 | ||
6258 | #ifdef CONFIG_PM_SLEEP | ||
6259 | static int e1000e_pm_suspend(struct device *dev) | 6259 | static int e1000e_pm_suspend(struct device *dev) |
6260 | { | 6260 | { |
6261 | struct pci_dev *pdev = to_pci_dev(dev); | 6261 | struct pci_dev *pdev = to_pci_dev(dev); |
diff --git a/drivers/net/ethernet/intel/e1000e/phy.h b/drivers/net/ethernet/intel/e1000e/phy.h index 3841bccf058c..537d2780b408 100644 --- a/drivers/net/ethernet/intel/e1000e/phy.h +++ b/drivers/net/ethernet/intel/e1000e/phy.h | |||
@@ -164,6 +164,7 @@ s32 e1000_get_cable_length_82577(struct e1000_hw *hw); | |||
164 | #define HV_M_STATUS_AUTONEG_COMPLETE 0x1000 | 164 | #define HV_M_STATUS_AUTONEG_COMPLETE 0x1000 |
165 | #define HV_M_STATUS_SPEED_MASK 0x0300 | 165 | #define HV_M_STATUS_SPEED_MASK 0x0300 |
166 | #define HV_M_STATUS_SPEED_1000 0x0200 | 166 | #define HV_M_STATUS_SPEED_1000 0x0200 |
167 | #define HV_M_STATUS_SPEED_100 0x0100 | ||
167 | #define HV_M_STATUS_LINK_UP 0x0040 | 168 | #define HV_M_STATUS_LINK_UP 0x0040 |
168 | 169 | ||
169 | #define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 | 170 | #define IGP01E1000_PHY_PCS_INIT_REG 0x00B4 |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c index 861b722c2672..cf0761f08911 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_main.c +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c | |||
@@ -2897,12 +2897,9 @@ static irqreturn_t i40e_intr(int irq, void *data) | |||
2897 | u32 prttsyn_stat = rd32(hw, I40E_PRTTSYN_STAT_0); | 2897 | u32 prttsyn_stat = rd32(hw, I40E_PRTTSYN_STAT_0); |
2898 | 2898 | ||
2899 | if (prttsyn_stat & I40E_PRTTSYN_STAT_0_TXTIME_MASK) { | 2899 | if (prttsyn_stat & I40E_PRTTSYN_STAT_0_TXTIME_MASK) { |
2900 | ena_mask &= ~I40E_PFINT_ICR0_ENA_TIMESYNC_MASK; | 2900 | icr0 &= ~I40E_PFINT_ICR0_ENA_TIMESYNC_MASK; |
2901 | i40e_ptp_tx_hwtstamp(pf); | 2901 | i40e_ptp_tx_hwtstamp(pf); |
2902 | prttsyn_stat &= ~I40E_PRTTSYN_STAT_0_TXTIME_MASK; | ||
2903 | } | 2902 | } |
2904 | |||
2905 | wr32(hw, I40E_PRTTSYN_STAT_0, prttsyn_stat); | ||
2906 | } | 2903 | } |
2907 | 2904 | ||
2908 | /* If a critical error is pending we have no choice but to reset the | 2905 | /* If a critical error is pending we have no choice but to reset the |
@@ -4271,6 +4268,14 @@ static int i40e_open(struct net_device *netdev) | |||
4271 | if (err) | 4268 | if (err) |
4272 | return err; | 4269 | return err; |
4273 | 4270 | ||
4271 | /* configure global TSO hardware offload settings */ | ||
4272 | wr32(&pf->hw, I40E_GLLAN_TSOMSK_F, be32_to_cpu(TCP_FLAG_PSH | | ||
4273 | TCP_FLAG_FIN) >> 16); | ||
4274 | wr32(&pf->hw, I40E_GLLAN_TSOMSK_M, be32_to_cpu(TCP_FLAG_PSH | | ||
4275 | TCP_FLAG_FIN | | ||
4276 | TCP_FLAG_CWR) >> 16); | ||
4277 | wr32(&pf->hw, I40E_GLLAN_TSOMSK_L, be32_to_cpu(TCP_FLAG_CWR) >> 16); | ||
4278 | |||
4274 | #ifdef CONFIG_I40E_VXLAN | 4279 | #ifdef CONFIG_I40E_VXLAN |
4275 | vxlan_get_rx_port(netdev); | 4280 | vxlan_get_rx_port(netdev); |
4276 | #endif | 4281 | #endif |
@@ -6712,6 +6717,7 @@ static int i40e_config_netdev(struct i40e_vsi *vsi) | |||
6712 | NETIF_F_HW_VLAN_CTAG_FILTER | | 6717 | NETIF_F_HW_VLAN_CTAG_FILTER | |
6713 | NETIF_F_IPV6_CSUM | | 6718 | NETIF_F_IPV6_CSUM | |
6714 | NETIF_F_TSO | | 6719 | NETIF_F_TSO | |
6720 | NETIF_F_TSO_ECN | | ||
6715 | NETIF_F_TSO6 | | 6721 | NETIF_F_TSO6 | |
6716 | NETIF_F_RXCSUM | | 6722 | NETIF_F_RXCSUM | |
6717 | NETIF_F_NTUPLE | | 6723 | NETIF_F_NTUPLE | |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c index 262bdf11d221..81299189a47d 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c +++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c | |||
@@ -160,7 +160,7 @@ static i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw) | |||
160 | udelay(5); | 160 | udelay(5); |
161 | } | 161 | } |
162 | if (ret_code == I40E_ERR_TIMEOUT) | 162 | if (ret_code == I40E_ERR_TIMEOUT) |
163 | hw_dbg(hw, "Done bit in GLNVM_SRCTL not set"); | 163 | hw_dbg(hw, "Done bit in GLNVM_SRCTL not set\n"); |
164 | return ret_code; | 164 | return ret_code; |
165 | } | 165 | } |
166 | 166 | ||
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c index e33ec6c842b7..e61e63720800 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c +++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c | |||
@@ -239,7 +239,7 @@ static void i40e_ptp_tx_work(struct work_struct *work) | |||
239 | dev_kfree_skb_any(pf->ptp_tx_skb); | 239 | dev_kfree_skb_any(pf->ptp_tx_skb); |
240 | pf->ptp_tx_skb = NULL; | 240 | pf->ptp_tx_skb = NULL; |
241 | pf->tx_hwtstamp_timeouts++; | 241 | pf->tx_hwtstamp_timeouts++; |
242 | dev_warn(&pf->pdev->dev, "clearing Tx timestamp hang"); | 242 | dev_warn(&pf->pdev->dev, "clearing Tx timestamp hang\n"); |
243 | return; | 243 | return; |
244 | } | 244 | } |
245 | 245 | ||
@@ -321,7 +321,7 @@ void i40e_ptp_rx_hang(struct i40e_vsi *vsi) | |||
321 | pf->last_rx_ptp_check = jiffies; | 321 | pf->last_rx_ptp_check = jiffies; |
322 | pf->rx_hwtstamp_cleared++; | 322 | pf->rx_hwtstamp_cleared++; |
323 | dev_warn(&vsi->back->pdev->dev, | 323 | dev_warn(&vsi->back->pdev->dev, |
324 | "%s: clearing Rx timestamp hang", | 324 | "%s: clearing Rx timestamp hang\n", |
325 | __func__); | 325 | __func__); |
326 | } | 326 | } |
327 | } | 327 | } |
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c index 0f5d96ad281d..9478ddc66caf 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c +++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c | |||
@@ -418,7 +418,7 @@ int i40e_add_del_fdir(struct i40e_vsi *vsi, | |||
418 | } | 418 | } |
419 | break; | 419 | break; |
420 | default: | 420 | default: |
421 | dev_info(&pf->pdev->dev, "Could not specify spec type %d", | 421 | dev_info(&pf->pdev->dev, "Could not specify spec type %d\n", |
422 | input->flow_type); | 422 | input->flow_type); |
423 | ret = -EINVAL; | 423 | ret = -EINVAL; |
424 | } | 424 | } |
@@ -478,7 +478,7 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring, | |||
478 | pf->flags |= I40E_FLAG_FDIR_REQUIRES_REINIT; | 478 | pf->flags |= I40E_FLAG_FDIR_REQUIRES_REINIT; |
479 | } | 479 | } |
480 | } else { | 480 | } else { |
481 | dev_info(&pdev->dev, "FD filter programming error"); | 481 | dev_info(&pdev->dev, "FD filter programming error\n"); |
482 | } | 482 | } |
483 | } else if (error == | 483 | } else if (error == |
484 | (0x1 << I40E_RX_PROG_STATUS_DESC_NO_FD_ENTRY_SHIFT)) { | 484 | (0x1 << I40E_RX_PROG_STATUS_DESC_NO_FD_ENTRY_SHIFT)) { |
@@ -1713,9 +1713,11 @@ static int i40e_tx_prepare_vlan_flags(struct sk_buff *skb, | |||
1713 | I40E_TX_FLAGS_VLAN_PRIO_SHIFT; | 1713 | I40E_TX_FLAGS_VLAN_PRIO_SHIFT; |
1714 | if (tx_flags & I40E_TX_FLAGS_SW_VLAN) { | 1714 | if (tx_flags & I40E_TX_FLAGS_SW_VLAN) { |
1715 | struct vlan_ethhdr *vhdr; | 1715 | struct vlan_ethhdr *vhdr; |
1716 | if (skb_header_cloned(skb) && | 1716 | int rc; |
1717 | pskb_expand_head(skb, 0, 0, GFP_ATOMIC)) | 1717 | |
1718 | return -ENOMEM; | 1718 | rc = skb_cow_head(skb, 0); |
1719 | if (rc < 0) | ||
1720 | return rc; | ||
1719 | vhdr = (struct vlan_ethhdr *)skb->data; | 1721 | vhdr = (struct vlan_ethhdr *)skb->data; |
1720 | vhdr->h_vlan_TCI = htons(tx_flags >> | 1722 | vhdr->h_vlan_TCI = htons(tx_flags >> |
1721 | I40E_TX_FLAGS_VLAN_SHIFT); | 1723 | I40E_TX_FLAGS_VLAN_SHIFT); |
@@ -1743,20 +1745,18 @@ static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb, | |||
1743 | u64 *cd_type_cmd_tso_mss, u32 *cd_tunneling) | 1745 | u64 *cd_type_cmd_tso_mss, u32 *cd_tunneling) |
1744 | { | 1746 | { |
1745 | u32 cd_cmd, cd_tso_len, cd_mss; | 1747 | u32 cd_cmd, cd_tso_len, cd_mss; |
1748 | struct ipv6hdr *ipv6h; | ||
1746 | struct tcphdr *tcph; | 1749 | struct tcphdr *tcph; |
1747 | struct iphdr *iph; | 1750 | struct iphdr *iph; |
1748 | u32 l4len; | 1751 | u32 l4len; |
1749 | int err; | 1752 | int err; |
1750 | struct ipv6hdr *ipv6h; | ||
1751 | 1753 | ||
1752 | if (!skb_is_gso(skb)) | 1754 | if (!skb_is_gso(skb)) |
1753 | return 0; | 1755 | return 0; |
1754 | 1756 | ||
1755 | if (skb_header_cloned(skb)) { | 1757 | err = skb_cow_head(skb, 0); |
1756 | err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC); | 1758 | if (err < 0) |
1757 | if (err) | 1759 | return err; |
1758 | return err; | ||
1759 | } | ||
1760 | 1760 | ||
1761 | if (protocol == htons(ETH_P_IP)) { | 1761 | if (protocol == htons(ETH_P_IP)) { |
1762 | iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb); | 1762 | iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb); |
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c index db963397cc27..f67f8a170b90 100644 --- a/drivers/net/ethernet/intel/igb/e1000_i210.c +++ b/drivers/net/ethernet/intel/igb/e1000_i210.c | |||
@@ -365,7 +365,7 @@ static s32 igb_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data) | |||
365 | word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword); | 365 | word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword); |
366 | if (word_address == address) { | 366 | if (word_address == address) { |
367 | *data = INVM_DWORD_TO_WORD_DATA(invm_dword); | 367 | *data = INVM_DWORD_TO_WORD_DATA(invm_dword); |
368 | hw_dbg("Read INVM Word 0x%02x = %x", | 368 | hw_dbg("Read INVM Word 0x%02x = %x\n", |
369 | address, *data); | 369 | address, *data); |
370 | status = E1000_SUCCESS; | 370 | status = E1000_SUCCESS; |
371 | break; | 371 | break; |
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.c b/drivers/net/ethernet/intel/igb/e1000_mac.c index 5910a932ea7c..1e0c404db81a 100644 --- a/drivers/net/ethernet/intel/igb/e1000_mac.c +++ b/drivers/net/ethernet/intel/igb/e1000_mac.c | |||
@@ -929,11 +929,10 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw) | |||
929 | */ | 929 | */ |
930 | if (hw->fc.requested_mode == e1000_fc_full) { | 930 | if (hw->fc.requested_mode == e1000_fc_full) { |
931 | hw->fc.current_mode = e1000_fc_full; | 931 | hw->fc.current_mode = e1000_fc_full; |
932 | hw_dbg("Flow Control = FULL.\r\n"); | 932 | hw_dbg("Flow Control = FULL.\n"); |
933 | } else { | 933 | } else { |
934 | hw->fc.current_mode = e1000_fc_rx_pause; | 934 | hw->fc.current_mode = e1000_fc_rx_pause; |
935 | hw_dbg("Flow Control = " | 935 | hw_dbg("Flow Control = RX PAUSE frames only.\n"); |
936 | "RX PAUSE frames only.\r\n"); | ||
937 | } | 936 | } |
938 | } | 937 | } |
939 | /* For receiving PAUSE frames ONLY. | 938 | /* For receiving PAUSE frames ONLY. |
@@ -948,7 +947,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw) | |||
948 | (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && | 947 | (mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && |
949 | (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { | 948 | (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { |
950 | hw->fc.current_mode = e1000_fc_tx_pause; | 949 | hw->fc.current_mode = e1000_fc_tx_pause; |
951 | hw_dbg("Flow Control = TX PAUSE frames only.\r\n"); | 950 | hw_dbg("Flow Control = TX PAUSE frames only.\n"); |
952 | } | 951 | } |
953 | /* For transmitting PAUSE frames ONLY. | 952 | /* For transmitting PAUSE frames ONLY. |
954 | * | 953 | * |
@@ -962,7 +961,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw) | |||
962 | !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && | 961 | !(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) && |
963 | (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { | 962 | (mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) { |
964 | hw->fc.current_mode = e1000_fc_rx_pause; | 963 | hw->fc.current_mode = e1000_fc_rx_pause; |
965 | hw_dbg("Flow Control = RX PAUSE frames only.\r\n"); | 964 | hw_dbg("Flow Control = RX PAUSE frames only.\n"); |
966 | } | 965 | } |
967 | /* Per the IEEE spec, at this point flow control should be | 966 | /* Per the IEEE spec, at this point flow control should be |
968 | * disabled. However, we want to consider that we could | 967 | * disabled. However, we want to consider that we could |
@@ -988,10 +987,10 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw) | |||
988 | (hw->fc.requested_mode == e1000_fc_tx_pause) || | 987 | (hw->fc.requested_mode == e1000_fc_tx_pause) || |
989 | (hw->fc.strict_ieee)) { | 988 | (hw->fc.strict_ieee)) { |
990 | hw->fc.current_mode = e1000_fc_none; | 989 | hw->fc.current_mode = e1000_fc_none; |
991 | hw_dbg("Flow Control = NONE.\r\n"); | 990 | hw_dbg("Flow Control = NONE.\n"); |
992 | } else { | 991 | } else { |
993 | hw->fc.current_mode = e1000_fc_rx_pause; | 992 | hw->fc.current_mode = e1000_fc_rx_pause; |
994 | hw_dbg("Flow Control = RX PAUSE frames only.\r\n"); | 993 | hw_dbg("Flow Control = RX PAUSE frames only.\n"); |
995 | } | 994 | } |
996 | 995 | ||
997 | /* Now we need to do one last check... If we auto- | 996 | /* Now we need to do one last check... If we auto- |
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c index fb98d4602f9d..16430a8440fa 100644 --- a/drivers/net/ethernet/intel/igb/igb_main.c +++ b/drivers/net/ethernet/intel/igb/igb_main.c | |||
@@ -5193,8 +5193,10 @@ void igb_update_stats(struct igb_adapter *adapter, | |||
5193 | 5193 | ||
5194 | rcu_read_lock(); | 5194 | rcu_read_lock(); |
5195 | for (i = 0; i < adapter->num_rx_queues; i++) { | 5195 | for (i = 0; i < adapter->num_rx_queues; i++) { |
5196 | u32 rqdpc = rd32(E1000_RQDPC(i)); | ||
5197 | struct igb_ring *ring = adapter->rx_ring[i]; | 5196 | struct igb_ring *ring = adapter->rx_ring[i]; |
5197 | u32 rqdpc = rd32(E1000_RQDPC(i)); | ||
5198 | if (hw->mac.type >= e1000_i210) | ||
5199 | wr32(E1000_RQDPC(i), 0); | ||
5198 | 5200 | ||
5199 | if (rqdpc) { | 5201 | if (rqdpc) { |
5200 | ring->rx_stats.drops += rqdpc; | 5202 | ring->rx_stats.drops += rqdpc; |
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c index 9209d652e1c9..ab25e49365f7 100644 --- a/drivers/net/ethernet/intel/igb/igb_ptp.c +++ b/drivers/net/ethernet/intel/igb/igb_ptp.c | |||
@@ -389,7 +389,7 @@ static void igb_ptp_tx_work(struct work_struct *work) | |||
389 | adapter->ptp_tx_skb = NULL; | 389 | adapter->ptp_tx_skb = NULL; |
390 | clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state); | 390 | clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state); |
391 | adapter->tx_hwtstamp_timeouts++; | 391 | adapter->tx_hwtstamp_timeouts++; |
392 | dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang"); | 392 | dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang\n"); |
393 | return; | 393 | return; |
394 | } | 394 | } |
395 | 395 | ||
@@ -451,7 +451,7 @@ void igb_ptp_rx_hang(struct igb_adapter *adapter) | |||
451 | rd32(E1000_RXSTMPH); | 451 | rd32(E1000_RXSTMPH); |
452 | adapter->last_rx_ptp_check = jiffies; | 452 | adapter->last_rx_ptp_check = jiffies; |
453 | adapter->rx_hwtstamp_cleared++; | 453 | adapter->rx_hwtstamp_cleared++; |
454 | dev_warn(&adapter->pdev->dev, "clearing Rx timestamp hang"); | 454 | dev_warn(&adapter->pdev->dev, "clearing Rx timestamp hang\n"); |
455 | } | 455 | } |
456 | } | 456 | } |
457 | 457 | ||
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h index 1a12c1dd7a27..c6c4ca7d68e6 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h | |||
@@ -256,7 +256,6 @@ struct ixgbe_ring { | |||
256 | struct ixgbe_tx_buffer *tx_buffer_info; | 256 | struct ixgbe_tx_buffer *tx_buffer_info; |
257 | struct ixgbe_rx_buffer *rx_buffer_info; | 257 | struct ixgbe_rx_buffer *rx_buffer_info; |
258 | }; | 258 | }; |
259 | unsigned long last_rx_timestamp; | ||
260 | unsigned long state; | 259 | unsigned long state; |
261 | u8 __iomem *tail; | 260 | u8 __iomem *tail; |
262 | dma_addr_t dma; /* phys. address of descriptor ring */ | 261 | dma_addr_t dma; /* phys. address of descriptor ring */ |
@@ -770,6 +769,7 @@ struct ixgbe_adapter { | |||
770 | unsigned long ptp_tx_start; | 769 | unsigned long ptp_tx_start; |
771 | unsigned long last_overflow_check; | 770 | unsigned long last_overflow_check; |
772 | unsigned long last_rx_ptp_check; | 771 | unsigned long last_rx_ptp_check; |
772 | unsigned long last_rx_timestamp; | ||
773 | spinlock_t tmreg_lock; | 773 | spinlock_t tmreg_lock; |
774 | struct cyclecounter cc; | 774 | struct cyclecounter cc; |
775 | struct timecounter tc; | 775 | struct timecounter tc; |
@@ -944,24 +944,7 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter); | |||
944 | void ixgbe_ptp_stop(struct ixgbe_adapter *adapter); | 944 | void ixgbe_ptp_stop(struct ixgbe_adapter *adapter); |
945 | void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); | 945 | void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter); |
946 | void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter); | 946 | void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter); |
947 | void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, | 947 | void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb); |
948 | struct sk_buff *skb); | ||
949 | static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring, | ||
950 | union ixgbe_adv_rx_desc *rx_desc, | ||
951 | struct sk_buff *skb) | ||
952 | { | ||
953 | if (unlikely(!ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS))) | ||
954 | return; | ||
955 | |||
956 | __ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, skb); | ||
957 | |||
958 | /* | ||
959 | * Update the last_rx_timestamp timer in order to enable watchdog check | ||
960 | * for error case of latched timestamp on a dropped packet. | ||
961 | */ | ||
962 | rx_ring->last_rx_timestamp = jiffies; | ||
963 | } | ||
964 | |||
965 | int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); | 948 | int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); |
966 | int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); | 949 | int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr); |
967 | void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); | 950 | void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter); |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c index 24fba39e194e..981b8a7b100d 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c | |||
@@ -1195,7 +1195,7 @@ static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw, | |||
1195 | */ | 1195 | */ |
1196 | hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX - data[0]; | 1196 | hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX - data[0]; |
1197 | 1197 | ||
1198 | hw_dbg(hw, "Detected EEPROM page size = %d words.", | 1198 | hw_dbg(hw, "Detected EEPROM page size = %d words.\n", |
1199 | hw->eeprom.word_page_size); | 1199 | hw->eeprom.word_page_size); |
1200 | out: | 1200 | out: |
1201 | return status; | 1201 | return status; |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c index c4c526b7f99f..d62e7a25cf97 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | |||
@@ -1664,7 +1664,8 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring, | |||
1664 | 1664 | ||
1665 | ixgbe_rx_checksum(rx_ring, rx_desc, skb); | 1665 | ixgbe_rx_checksum(rx_ring, rx_desc, skb); |
1666 | 1666 | ||
1667 | ixgbe_ptp_rx_hwtstamp(rx_ring, rx_desc, skb); | 1667 | if (unlikely(ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS))) |
1668 | ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector->adapter, skb); | ||
1668 | 1669 | ||
1669 | if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) && | 1670 | if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) && |
1670 | ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { | 1671 | ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) { |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c index 23f765263f12..a76af8e28a04 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c | |||
@@ -536,7 +536,7 @@ s32 ixgbe_setup_phy_link_generic(struct ixgbe_hw *hw) | |||
536 | 536 | ||
537 | if (time_out == max_time_out) { | 537 | if (time_out == max_time_out) { |
538 | status = IXGBE_ERR_LINK_SETUP; | 538 | status = IXGBE_ERR_LINK_SETUP; |
539 | hw_dbg(hw, "ixgbe_setup_phy_link_generic: time out"); | 539 | hw_dbg(hw, "ixgbe_setup_phy_link_generic: time out\n"); |
540 | } | 540 | } |
541 | 541 | ||
542 | return status; | 542 | return status; |
@@ -745,7 +745,7 @@ s32 ixgbe_setup_phy_link_tnx(struct ixgbe_hw *hw) | |||
745 | 745 | ||
746 | if (time_out == max_time_out) { | 746 | if (time_out == max_time_out) { |
747 | status = IXGBE_ERR_LINK_SETUP; | 747 | status = IXGBE_ERR_LINK_SETUP; |
748 | hw_dbg(hw, "ixgbe_setup_phy_link_tnx: time out"); | 748 | hw_dbg(hw, "ixgbe_setup_phy_link_tnx: time out\n"); |
749 | } | 749 | } |
750 | 750 | ||
751 | return status; | 751 | return status; |
@@ -1175,7 +1175,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw) | |||
1175 | status = 0; | 1175 | status = 0; |
1176 | } else { | 1176 | } else { |
1177 | if (hw->allow_unsupported_sfp) { | 1177 | if (hw->allow_unsupported_sfp) { |
1178 | e_warn(drv, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules."); | 1178 | e_warn(drv, "WARNING: Intel (R) Network Connections are quality tested using Intel (R) Ethernet Optics. Using untested modules is not supported and may cause unstable operation or damage to the module or the adapter. Intel Corporation is not responsible for any harm caused by using untested modules.\n"); |
1179 | status = 0; | 1179 | status = 0; |
1180 | } else { | 1180 | } else { |
1181 | hw_dbg(hw, | 1181 | hw_dbg(hw, |
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c index 63515a6f67fa..8902ae683457 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | |||
@@ -435,10 +435,8 @@ void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter) | |||
435 | void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter) | 435 | void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter) |
436 | { | 436 | { |
437 | struct ixgbe_hw *hw = &adapter->hw; | 437 | struct ixgbe_hw *hw = &adapter->hw; |
438 | struct ixgbe_ring *rx_ring; | ||
439 | u32 tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); | 438 | u32 tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); |
440 | unsigned long rx_event; | 439 | unsigned long rx_event; |
441 | int n; | ||
442 | 440 | ||
443 | /* if we don't have a valid timestamp in the registers, just update the | 441 | /* if we don't have a valid timestamp in the registers, just update the |
444 | * timeout counter and exit | 442 | * timeout counter and exit |
@@ -450,18 +448,15 @@ void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter) | |||
450 | 448 | ||
451 | /* determine the most recent watchdog or rx_timestamp event */ | 449 | /* determine the most recent watchdog or rx_timestamp event */ |
452 | rx_event = adapter->last_rx_ptp_check; | 450 | rx_event = adapter->last_rx_ptp_check; |
453 | for (n = 0; n < adapter->num_rx_queues; n++) { | 451 | if (time_after(adapter->last_rx_timestamp, rx_event)) |
454 | rx_ring = adapter->rx_ring[n]; | 452 | rx_event = adapter->last_rx_timestamp; |
455 | if (time_after(rx_ring->last_rx_timestamp, rx_event)) | ||
456 | rx_event = rx_ring->last_rx_timestamp; | ||
457 | } | ||
458 | 453 | ||
459 | /* only need to read the high RXSTMP register to clear the lock */ | 454 | /* only need to read the high RXSTMP register to clear the lock */ |
460 | if (time_is_before_jiffies(rx_event + 5*HZ)) { | 455 | if (time_is_before_jiffies(rx_event + 5*HZ)) { |
461 | IXGBE_READ_REG(hw, IXGBE_RXSTMPH); | 456 | IXGBE_READ_REG(hw, IXGBE_RXSTMPH); |
462 | adapter->last_rx_ptp_check = jiffies; | 457 | adapter->last_rx_ptp_check = jiffies; |
463 | 458 | ||
464 | e_warn(drv, "clearing RX Timestamp hang"); | 459 | e_warn(drv, "clearing RX Timestamp hang\n"); |
465 | } | 460 | } |
466 | } | 461 | } |
467 | 462 | ||
@@ -517,7 +512,7 @@ static void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work) | |||
517 | dev_kfree_skb_any(adapter->ptp_tx_skb); | 512 | dev_kfree_skb_any(adapter->ptp_tx_skb); |
518 | adapter->ptp_tx_skb = NULL; | 513 | adapter->ptp_tx_skb = NULL; |
519 | clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state); | 514 | clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state); |
520 | e_warn(drv, "clearing Tx Timestamp hang"); | 515 | e_warn(drv, "clearing Tx Timestamp hang\n"); |
521 | return; | 516 | return; |
522 | } | 517 | } |
523 | 518 | ||
@@ -530,35 +525,22 @@ static void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work) | |||
530 | } | 525 | } |
531 | 526 | ||
532 | /** | 527 | /** |
533 | * __ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp | 528 | * ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp |
534 | * @q_vector: structure containing interrupt and ring information | 529 | * @adapter: pointer to adapter struct |
535 | * @skb: particular skb to send timestamp with | 530 | * @skb: particular skb to send timestamp with |
536 | * | 531 | * |
537 | * if the timestamp is valid, we convert it into the timecounter ns | 532 | * if the timestamp is valid, we convert it into the timecounter ns |
538 | * value, then store that result into the shhwtstamps structure which | 533 | * value, then store that result into the shhwtstamps structure which |
539 | * is passed up the network stack | 534 | * is passed up the network stack |
540 | */ | 535 | */ |
541 | void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, | 536 | void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb) |
542 | struct sk_buff *skb) | ||
543 | { | 537 | { |
544 | struct ixgbe_adapter *adapter; | 538 | struct ixgbe_hw *hw = &adapter->hw; |
545 | struct ixgbe_hw *hw; | ||
546 | struct skb_shared_hwtstamps *shhwtstamps; | 539 | struct skb_shared_hwtstamps *shhwtstamps; |
547 | u64 regval = 0, ns; | 540 | u64 regval = 0, ns; |
548 | u32 tsyncrxctl; | 541 | u32 tsyncrxctl; |
549 | unsigned long flags; | 542 | unsigned long flags; |
550 | 543 | ||
551 | /* we cannot process timestamps on a ring without a q_vector */ | ||
552 | if (!q_vector || !q_vector->adapter) | ||
553 | return; | ||
554 | |||
555 | adapter = q_vector->adapter; | ||
556 | hw = &adapter->hw; | ||
557 | |||
558 | /* | ||
559 | * Read the tsyncrxctl register afterwards in order to prevent taking an | ||
560 | * I/O hit on every packet. | ||
561 | */ | ||
562 | tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); | 544 | tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); |
563 | if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID)) | 545 | if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID)) |
564 | return; | 546 | return; |
@@ -566,13 +548,17 @@ void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, | |||
566 | regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL); | 548 | regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL); |
567 | regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32; | 549 | regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32; |
568 | 550 | ||
569 | |||
570 | spin_lock_irqsave(&adapter->tmreg_lock, flags); | 551 | spin_lock_irqsave(&adapter->tmreg_lock, flags); |
571 | ns = timecounter_cyc2time(&adapter->tc, regval); | 552 | ns = timecounter_cyc2time(&adapter->tc, regval); |
572 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); | 553 | spin_unlock_irqrestore(&adapter->tmreg_lock, flags); |
573 | 554 | ||
574 | shhwtstamps = skb_hwtstamps(skb); | 555 | shhwtstamps = skb_hwtstamps(skb); |
575 | shhwtstamps->hwtstamp = ns_to_ktime(ns); | 556 | shhwtstamps->hwtstamp = ns_to_ktime(ns); |
557 | |||
558 | /* Update the last_rx_timestamp timer in order to enable watchdog check | ||
559 | * for error case of latched timestamp on a dropped packet. | ||
560 | */ | ||
561 | adapter->last_rx_timestamp = jiffies; | ||
576 | } | 562 | } |
577 | 563 | ||
578 | int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr) | 564 | int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr) |
diff --git a/drivers/net/ethernet/marvell/mvmdio.c b/drivers/net/ethernet/marvell/mvmdio.c index b161a525fc5b..9d5ced263a5e 100644 --- a/drivers/net/ethernet/marvell/mvmdio.c +++ b/drivers/net/ethernet/marvell/mvmdio.c | |||
@@ -232,7 +232,7 @@ static int orion_mdio_probe(struct platform_device *pdev) | |||
232 | clk_prepare_enable(dev->clk); | 232 | clk_prepare_enable(dev->clk); |
233 | 233 | ||
234 | dev->err_interrupt = platform_get_irq(pdev, 0); | 234 | dev->err_interrupt = platform_get_irq(pdev, 0); |
235 | if (dev->err_interrupt != -ENXIO) { | 235 | if (dev->err_interrupt > 0) { |
236 | ret = devm_request_irq(&pdev->dev, dev->err_interrupt, | 236 | ret = devm_request_irq(&pdev->dev, dev->err_interrupt, |
237 | orion_mdio_err_irq, | 237 | orion_mdio_err_irq, |
238 | IRQF_SHARED, pdev->name, dev); | 238 | IRQF_SHARED, pdev->name, dev); |
@@ -241,6 +241,9 @@ static int orion_mdio_probe(struct platform_device *pdev) | |||
241 | 241 | ||
242 | writel(MVMDIO_ERR_INT_SMI_DONE, | 242 | writel(MVMDIO_ERR_INT_SMI_DONE, |
243 | dev->regs + MVMDIO_ERR_INT_MASK); | 243 | dev->regs + MVMDIO_ERR_INT_MASK); |
244 | |||
245 | } else if (dev->err_interrupt == -EPROBE_DEFER) { | ||
246 | return -EPROBE_DEFER; | ||
244 | } | 247 | } |
245 | 248 | ||
246 | mutex_init(&dev->lock); | 249 | mutex_init(&dev->lock); |
diff --git a/drivers/net/ethernet/mellanox/mlx4/main.c b/drivers/net/ethernet/mellanox/mlx4/main.c index cef267e24f9c..7cf9dadcb471 100644 --- a/drivers/net/ethernet/mellanox/mlx4/main.c +++ b/drivers/net/ethernet/mellanox/mlx4/main.c | |||
@@ -754,10 +754,10 @@ static void mlx4_request_modules(struct mlx4_dev *dev) | |||
754 | has_eth_port = true; | 754 | has_eth_port = true; |
755 | } | 755 | } |
756 | 756 | ||
757 | if (has_ib_port || (dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE)) | ||
758 | request_module_nowait(IB_DRV_NAME); | ||
759 | if (has_eth_port) | 757 | if (has_eth_port) |
760 | request_module_nowait(EN_DRV_NAME); | 758 | request_module_nowait(EN_DRV_NAME); |
759 | if (has_ib_port || (dev->caps.flags & MLX4_DEV_CAP_FLAG_IBOE)) | ||
760 | request_module_nowait(IB_DRV_NAME); | ||
761 | } | 761 | } |
762 | 762 | ||
763 | /* | 763 | /* |
@@ -2440,7 +2440,8 @@ slave_start: | |||
2440 | * No return code for this call, just warn the user in case of PCI | 2440 | * No return code for this call, just warn the user in case of PCI |
2441 | * express device capabilities are under-satisfied by the bus. | 2441 | * express device capabilities are under-satisfied by the bus. |
2442 | */ | 2442 | */ |
2443 | mlx4_check_pcie_caps(dev); | 2443 | if (!mlx4_is_slave(dev)) |
2444 | mlx4_check_pcie_caps(dev); | ||
2444 | 2445 | ||
2445 | /* In master functions, the communication channel must be initialized | 2446 | /* In master functions, the communication channel must be initialized |
2446 | * after obtaining its address from fw */ | 2447 | * after obtaining its address from fw */ |
diff --git a/drivers/net/ethernet/mellanox/mlx4/port.c b/drivers/net/ethernet/mellanox/mlx4/port.c index cfcad26ed40f..b5b3549b0c8d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/port.c +++ b/drivers/net/ethernet/mellanox/mlx4/port.c | |||
@@ -1106,6 +1106,9 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid, | |||
1106 | } | 1106 | } |
1107 | 1107 | ||
1108 | if (found_ix >= 0) { | 1108 | if (found_ix >= 0) { |
1109 | /* Calculate a slave_gid which is the slave number in the gid | ||
1110 | * table and not a globally unique slave number. | ||
1111 | */ | ||
1109 | if (found_ix < MLX4_ROCE_PF_GIDS) | 1112 | if (found_ix < MLX4_ROCE_PF_GIDS) |
1110 | slave_gid = 0; | 1113 | slave_gid = 0; |
1111 | else if (found_ix < MLX4_ROCE_PF_GIDS + (vf_gids % num_vfs) * | 1114 | else if (found_ix < MLX4_ROCE_PF_GIDS + (vf_gids % num_vfs) * |
@@ -1118,41 +1121,43 @@ int mlx4_get_slave_from_roce_gid(struct mlx4_dev *dev, int port, u8 *gid, | |||
1118 | ((vf_gids % num_vfs) * ((vf_gids / num_vfs + 1)))) / | 1121 | ((vf_gids % num_vfs) * ((vf_gids / num_vfs + 1)))) / |
1119 | (vf_gids / num_vfs)) + vf_gids % num_vfs + 1; | 1122 | (vf_gids / num_vfs)) + vf_gids % num_vfs + 1; |
1120 | 1123 | ||
1124 | /* Calculate the globally unique slave id */ | ||
1121 | if (slave_gid) { | 1125 | if (slave_gid) { |
1122 | struct mlx4_active_ports exclusive_ports; | 1126 | struct mlx4_active_ports exclusive_ports; |
1123 | struct mlx4_active_ports actv_ports; | 1127 | struct mlx4_active_ports actv_ports; |
1124 | struct mlx4_slaves_pport slaves_pport_actv; | 1128 | struct mlx4_slaves_pport slaves_pport_actv; |
1125 | unsigned max_port_p_one; | 1129 | unsigned max_port_p_one; |
1126 | int num_slaves_before = 1; | 1130 | int num_vfs_before = 0; |
1131 | int candidate_slave_gid; | ||
1127 | 1132 | ||
1133 | /* Calculate how many VFs are on the previous port, if exists */ | ||
1128 | for (i = 1; i < port; i++) { | 1134 | for (i = 1; i < port; i++) { |
1129 | bitmap_zero(exclusive_ports.ports, dev->caps.num_ports); | 1135 | bitmap_zero(exclusive_ports.ports, dev->caps.num_ports); |
1130 | set_bit(i, exclusive_ports.ports); | 1136 | set_bit(i - 1, exclusive_ports.ports); |
1131 | slaves_pport_actv = | 1137 | slaves_pport_actv = |
1132 | mlx4_phys_to_slaves_pport_actv( | 1138 | mlx4_phys_to_slaves_pport_actv( |
1133 | dev, &exclusive_ports); | 1139 | dev, &exclusive_ports); |
1134 | num_slaves_before += bitmap_weight( | 1140 | num_vfs_before += bitmap_weight( |
1135 | slaves_pport_actv.slaves, | 1141 | slaves_pport_actv.slaves, |
1136 | dev->num_vfs + 1); | 1142 | dev->num_vfs + 1); |
1137 | } | 1143 | } |
1138 | 1144 | ||
1139 | if (slave_gid < num_slaves_before) { | 1145 | /* candidate_slave_gid isn't necessarily the correct slave, but |
1140 | bitmap_zero(exclusive_ports.ports, dev->caps.num_ports); | 1146 | * it has the same number of ports and is assigned to the same |
1141 | set_bit(port - 1, exclusive_ports.ports); | 1147 | * ports as the real slave we're looking for. On dual port VF, |
1142 | slaves_pport_actv = | 1148 | * slave_gid = [single port VFs on port <port>] + |
1143 | mlx4_phys_to_slaves_pport_actv( | 1149 | * [offset of the current slave from the first dual port VF] + |
1144 | dev, &exclusive_ports); | 1150 | * 1 (for the PF). |
1145 | slave_gid += bitmap_weight( | 1151 | */ |
1146 | slaves_pport_actv.slaves, | 1152 | candidate_slave_gid = slave_gid + num_vfs_before; |
1147 | dev->num_vfs + 1) - | 1153 | |
1148 | num_slaves_before; | 1154 | actv_ports = mlx4_get_active_ports(dev, candidate_slave_gid); |
1149 | } | ||
1150 | actv_ports = mlx4_get_active_ports(dev, slave_gid); | ||
1151 | max_port_p_one = find_first_bit( | 1155 | max_port_p_one = find_first_bit( |
1152 | actv_ports.ports, dev->caps.num_ports) + | 1156 | actv_ports.ports, dev->caps.num_ports) + |
1153 | bitmap_weight(actv_ports.ports, | 1157 | bitmap_weight(actv_ports.ports, |
1154 | dev->caps.num_ports) + 1; | 1158 | dev->caps.num_ports) + 1; |
1155 | 1159 | ||
1160 | /* Calculate the real slave number */ | ||
1156 | for (i = 1; i < max_port_p_one; i++) { | 1161 | for (i = 1; i < max_port_p_one; i++) { |
1157 | if (i == port) | 1162 | if (i == port) |
1158 | continue; | 1163 | continue; |
diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 3b5f53ef29b2..1c3fdd4a1f7d 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | |||
@@ -3733,6 +3733,25 @@ static int qp_detach(struct mlx4_dev *dev, struct mlx4_qp *qp, | |||
3733 | } | 3733 | } |
3734 | } | 3734 | } |
3735 | 3735 | ||
3736 | static int mlx4_adjust_port(struct mlx4_dev *dev, int slave, | ||
3737 | u8 *gid, enum mlx4_protocol prot) | ||
3738 | { | ||
3739 | int real_port; | ||
3740 | |||
3741 | if (prot != MLX4_PROT_ETH) | ||
3742 | return 0; | ||
3743 | |||
3744 | if (dev->caps.steering_mode == MLX4_STEERING_MODE_B0 || | ||
3745 | dev->caps.steering_mode == MLX4_STEERING_MODE_DEVICE_MANAGED) { | ||
3746 | real_port = mlx4_slave_convert_port(dev, slave, gid[5]); | ||
3747 | if (real_port < 0) | ||
3748 | return -EINVAL; | ||
3749 | gid[5] = real_port; | ||
3750 | } | ||
3751 | |||
3752 | return 0; | ||
3753 | } | ||
3754 | |||
3736 | int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | 3755 | int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, |
3737 | struct mlx4_vhcr *vhcr, | 3756 | struct mlx4_vhcr *vhcr, |
3738 | struct mlx4_cmd_mailbox *inbox, | 3757 | struct mlx4_cmd_mailbox *inbox, |
@@ -3768,6 +3787,10 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, | |||
3768 | if (err) | 3787 | if (err) |
3769 | goto ex_detach; | 3788 | goto ex_detach; |
3770 | } else { | 3789 | } else { |
3790 | err = mlx4_adjust_port(dev, slave, gid, prot); | ||
3791 | if (err) | ||
3792 | goto ex_put; | ||
3793 | |||
3771 | err = rem_mcg_res(dev, slave, rqp, gid, prot, type, ®_id); | 3794 | err = rem_mcg_res(dev, slave, rqp, gid, prot, type, ®_id); |
3772 | if (err) | 3795 | if (err) |
3773 | goto ex_put; | 3796 | goto ex_put; |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c index dbf75393f758..0bc914859e38 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c | |||
@@ -2374,6 +2374,14 @@ void qlcnic_set_drv_version(struct qlcnic_adapter *adapter) | |||
2374 | qlcnic_fw_cmd_set_drv_version(adapter, fw_cmd); | 2374 | qlcnic_fw_cmd_set_drv_version(adapter, fw_cmd); |
2375 | } | 2375 | } |
2376 | 2376 | ||
2377 | /* Reset firmware API lock */ | ||
2378 | static void qlcnic_reset_api_lock(struct qlcnic_adapter *adapter) | ||
2379 | { | ||
2380 | qlcnic_api_lock(adapter); | ||
2381 | qlcnic_api_unlock(adapter); | ||
2382 | } | ||
2383 | |||
2384 | |||
2377 | static int | 2385 | static int |
2378 | qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | 2386 | qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
2379 | { | 2387 | { |
@@ -2476,6 +2484,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2476 | if (qlcnic_82xx_check(adapter)) { | 2484 | if (qlcnic_82xx_check(adapter)) { |
2477 | qlcnic_check_vf(adapter, ent); | 2485 | qlcnic_check_vf(adapter, ent); |
2478 | adapter->portnum = adapter->ahw->pci_func; | 2486 | adapter->portnum = adapter->ahw->pci_func; |
2487 | qlcnic_reset_api_lock(adapter); | ||
2479 | err = qlcnic_start_firmware(adapter); | 2488 | err = qlcnic_start_firmware(adapter); |
2480 | if (err) { | 2489 | if (err) { |
2481 | dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n" | 2490 | dev_err(&pdev->dev, "Loading fw failed.Please Reboot\n" |
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c index 0638c1810d54..6afe9c1f5ab9 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_common.c | |||
@@ -1370,7 +1370,7 @@ static int qlcnic_sriov_issue_cmd(struct qlcnic_adapter *adapter, | |||
1370 | 1370 | ||
1371 | rsp = qlcnic_sriov_alloc_bc_trans(&trans); | 1371 | rsp = qlcnic_sriov_alloc_bc_trans(&trans); |
1372 | if (rsp) | 1372 | if (rsp) |
1373 | return rsp; | 1373 | goto free_cmd; |
1374 | 1374 | ||
1375 | rsp = qlcnic_sriov_prepare_bc_hdr(trans, cmd, seq, QLC_BC_COMMAND); | 1375 | rsp = qlcnic_sriov_prepare_bc_hdr(trans, cmd, seq, QLC_BC_COMMAND); |
1376 | if (rsp) | 1376 | if (rsp) |
@@ -1425,6 +1425,13 @@ err_out: | |||
1425 | 1425 | ||
1426 | cleanup_transaction: | 1426 | cleanup_transaction: |
1427 | qlcnic_sriov_cleanup_transaction(trans); | 1427 | qlcnic_sriov_cleanup_transaction(trans); |
1428 | |||
1429 | free_cmd: | ||
1430 | if (cmd->type == QLC_83XX_MBX_CMD_NO_WAIT) { | ||
1431 | qlcnic_free_mbx_args(cmd); | ||
1432 | kfree(cmd); | ||
1433 | } | ||
1434 | |||
1428 | return rsp; | 1435 | return rsp; |
1429 | } | 1436 | } |
1430 | 1437 | ||
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h index 6203c7d8550f..45019649bbbd 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_common.h | |||
@@ -358,6 +358,8 @@ struct sxgbe_core_ops { | |||
358 | /* Enable disable checksum offload operations */ | 358 | /* Enable disable checksum offload operations */ |
359 | void (*enable_rx_csum)(void __iomem *ioaddr); | 359 | void (*enable_rx_csum)(void __iomem *ioaddr); |
360 | void (*disable_rx_csum)(void __iomem *ioaddr); | 360 | void (*disable_rx_csum)(void __iomem *ioaddr); |
361 | void (*enable_rxqueue)(void __iomem *ioaddr, int queue_num); | ||
362 | void (*disable_rxqueue)(void __iomem *ioaddr, int queue_num); | ||
361 | }; | 363 | }; |
362 | 364 | ||
363 | const struct sxgbe_core_ops *sxgbe_get_core_ops(void); | 365 | const struct sxgbe_core_ops *sxgbe_get_core_ops(void); |
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c index c4da7a2b002a..58c35692560e 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_core.c | |||
@@ -165,6 +165,26 @@ static void sxgbe_core_set_speed(void __iomem *ioaddr, unsigned char speed) | |||
165 | writel(tx_cfg, ioaddr + SXGBE_CORE_TX_CONFIG_REG); | 165 | writel(tx_cfg, ioaddr + SXGBE_CORE_TX_CONFIG_REG); |
166 | } | 166 | } |
167 | 167 | ||
168 | static void sxgbe_core_enable_rxqueue(void __iomem *ioaddr, int queue_num) | ||
169 | { | ||
170 | u32 reg_val; | ||
171 | |||
172 | reg_val = readl(ioaddr + SXGBE_CORE_RX_CTL0_REG); | ||
173 | reg_val &= ~(SXGBE_CORE_RXQ_ENABLE_MASK << queue_num); | ||
174 | reg_val |= SXGBE_CORE_RXQ_ENABLE; | ||
175 | writel(reg_val, ioaddr + SXGBE_CORE_RX_CTL0_REG); | ||
176 | } | ||
177 | |||
178 | static void sxgbe_core_disable_rxqueue(void __iomem *ioaddr, int queue_num) | ||
179 | { | ||
180 | u32 reg_val; | ||
181 | |||
182 | reg_val = readl(ioaddr + SXGBE_CORE_RX_CTL0_REG); | ||
183 | reg_val &= ~(SXGBE_CORE_RXQ_ENABLE_MASK << queue_num); | ||
184 | reg_val |= SXGBE_CORE_RXQ_DISABLE; | ||
185 | writel(reg_val, ioaddr + SXGBE_CORE_RX_CTL0_REG); | ||
186 | } | ||
187 | |||
168 | static void sxgbe_set_eee_mode(void __iomem *ioaddr) | 188 | static void sxgbe_set_eee_mode(void __iomem *ioaddr) |
169 | { | 189 | { |
170 | u32 ctrl; | 190 | u32 ctrl; |
@@ -254,6 +274,8 @@ static const struct sxgbe_core_ops core_ops = { | |||
254 | .set_eee_pls = sxgbe_set_eee_pls, | 274 | .set_eee_pls = sxgbe_set_eee_pls, |
255 | .enable_rx_csum = sxgbe_enable_rx_csum, | 275 | .enable_rx_csum = sxgbe_enable_rx_csum, |
256 | .disable_rx_csum = sxgbe_disable_rx_csum, | 276 | .disable_rx_csum = sxgbe_disable_rx_csum, |
277 | .enable_rxqueue = sxgbe_core_enable_rxqueue, | ||
278 | .disable_rxqueue = sxgbe_core_disable_rxqueue, | ||
257 | }; | 279 | }; |
258 | 280 | ||
259 | const struct sxgbe_core_ops *sxgbe_get_core_ops(void) | 281 | const struct sxgbe_core_ops *sxgbe_get_core_ops(void) |
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c index e896dbbd2e15..2686bb5b6765 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c | |||
@@ -45,10 +45,10 @@ static void sxgbe_prepare_tx_desc(struct sxgbe_tx_norm_desc *p, u8 is_fd, | |||
45 | p->tdes23.tx_rd_des23.first_desc = is_fd; | 45 | p->tdes23.tx_rd_des23.first_desc = is_fd; |
46 | p->tdes23.tx_rd_des23.buf1_size = buf1_len; | 46 | p->tdes23.tx_rd_des23.buf1_size = buf1_len; |
47 | 47 | ||
48 | p->tdes23.tx_rd_des23.tx_pkt_len.cksum_pktlen.total_pkt_len = pkt_len; | 48 | p->tdes23.tx_rd_des23.tx_pkt_len.pkt_len.total_pkt_len = pkt_len; |
49 | 49 | ||
50 | if (cksum) | 50 | if (cksum) |
51 | p->tdes23.tx_rd_des23.tx_pkt_len.cksum_pktlen.cksum_ctl = cic_full; | 51 | p->tdes23.tx_rd_des23.cksum_ctl = cic_full; |
52 | } | 52 | } |
53 | 53 | ||
54 | /* Set VLAN control information */ | 54 | /* Set VLAN control information */ |
@@ -233,6 +233,12 @@ static void sxgbe_set_rx_owner(struct sxgbe_rx_norm_desc *p) | |||
233 | p->rdes23.rx_rd_des23.own_bit = 1; | 233 | p->rdes23.rx_rd_des23.own_bit = 1; |
234 | } | 234 | } |
235 | 235 | ||
236 | /* Set Interrupt on completion bit */ | ||
237 | static void sxgbe_set_rx_int_on_com(struct sxgbe_rx_norm_desc *p) | ||
238 | { | ||
239 | p->rdes23.rx_rd_des23.int_on_com = 1; | ||
240 | } | ||
241 | |||
236 | /* Get the receive frame size */ | 242 | /* Get the receive frame size */ |
237 | static int sxgbe_get_rx_frame_len(struct sxgbe_rx_norm_desc *p) | 243 | static int sxgbe_get_rx_frame_len(struct sxgbe_rx_norm_desc *p) |
238 | { | 244 | { |
@@ -498,6 +504,7 @@ static const struct sxgbe_desc_ops desc_ops = { | |||
498 | .init_rx_desc = sxgbe_init_rx_desc, | 504 | .init_rx_desc = sxgbe_init_rx_desc, |
499 | .get_rx_owner = sxgbe_get_rx_owner, | 505 | .get_rx_owner = sxgbe_get_rx_owner, |
500 | .set_rx_owner = sxgbe_set_rx_owner, | 506 | .set_rx_owner = sxgbe_set_rx_owner, |
507 | .set_rx_int_on_com = sxgbe_set_rx_int_on_com, | ||
501 | .get_rx_frame_len = sxgbe_get_rx_frame_len, | 508 | .get_rx_frame_len = sxgbe_get_rx_frame_len, |
502 | .get_rx_fd_status = sxgbe_get_rx_fd_status, | 509 | .get_rx_fd_status = sxgbe_get_rx_fd_status, |
503 | .get_rx_ld_status = sxgbe_get_rx_ld_status, | 510 | .get_rx_ld_status = sxgbe_get_rx_ld_status, |
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h index 838cb9fb0ea9..18609324db72 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h | |||
@@ -39,22 +39,22 @@ struct sxgbe_tx_norm_desc { | |||
39 | u32 int_on_com:1; | 39 | u32 int_on_com:1; |
40 | /* TDES3 */ | 40 | /* TDES3 */ |
41 | union { | 41 | union { |
42 | u32 tcp_payload_len:18; | 42 | u16 tcp_payload_len; |
43 | struct { | 43 | struct { |
44 | u32 total_pkt_len:15; | 44 | u32 total_pkt_len:15; |
45 | u32 reserved1:1; | 45 | u32 reserved1:1; |
46 | u32 cksum_ctl:2; | 46 | } pkt_len; |
47 | } cksum_pktlen; | ||
48 | } tx_pkt_len; | 47 | } tx_pkt_len; |
49 | 48 | ||
50 | u32 tse_bit:1; | 49 | u16 cksum_ctl:2; |
51 | u32 tcp_hdr_len:4; | 50 | u16 tse_bit:1; |
52 | u32 sa_insert_ctl:3; | 51 | u16 tcp_hdr_len:4; |
53 | u32 crc_pad_ctl:2; | 52 | u16 sa_insert_ctl:3; |
54 | u32 last_desc:1; | 53 | u16 crc_pad_ctl:2; |
55 | u32 first_desc:1; | 54 | u16 last_desc:1; |
56 | u32 ctxt_bit:1; | 55 | u16 first_desc:1; |
57 | u32 own_bit:1; | 56 | u16 ctxt_bit:1; |
57 | u16 own_bit:1; | ||
58 | } tx_rd_des23; | 58 | } tx_rd_des23; |
59 | 59 | ||
60 | /* tx write back Desc 2,3 */ | 60 | /* tx write back Desc 2,3 */ |
@@ -70,25 +70,20 @@ struct sxgbe_tx_norm_desc { | |||
70 | 70 | ||
71 | struct sxgbe_rx_norm_desc { | 71 | struct sxgbe_rx_norm_desc { |
72 | union { | 72 | union { |
73 | u32 rdes0; /* buf1 address */ | 73 | u64 rdes01; /* buf1 address */ |
74 | struct { | 74 | union { |
75 | u32 out_vlan_tag:16; | 75 | u32 out_vlan_tag:16; |
76 | u32 in_vlan_tag:16; | 76 | u32 in_vlan_tag:16; |
77 | } wb_rx_des0; | 77 | u32 rss_hash; |
78 | } rd_wb_des0; | 78 | } rx_wb_des01; |
79 | 79 | } rdes01; | |
80 | union { | ||
81 | u32 rdes1; /* buf2 address or buf1[63:32] */ | ||
82 | u32 rss_hash; /* Write-back RX */ | ||
83 | } rd_wb_des1; | ||
84 | 80 | ||
85 | union { | 81 | union { |
86 | /* RX Read format Desc 2,3 */ | 82 | /* RX Read format Desc 2,3 */ |
87 | struct{ | 83 | struct{ |
88 | /* RDES2 */ | 84 | /* RDES2 */ |
89 | u32 buf2_addr; | 85 | u64 buf2_addr:62; |
90 | /* RDES3 */ | 86 | /* RDES3 */ |
91 | u32 buf2_hi_addr:30; | ||
92 | u32 int_on_com:1; | 87 | u32 int_on_com:1; |
93 | u32 own_bit:1; | 88 | u32 own_bit:1; |
94 | } rx_rd_des23; | 89 | } rx_rd_des23; |
@@ -263,6 +258,9 @@ struct sxgbe_desc_ops { | |||
263 | /* Set own bit */ | 258 | /* Set own bit */ |
264 | void (*set_rx_owner)(struct sxgbe_rx_norm_desc *p); | 259 | void (*set_rx_owner)(struct sxgbe_rx_norm_desc *p); |
265 | 260 | ||
261 | /* Set Interrupt on completion bit */ | ||
262 | void (*set_rx_int_on_com)(struct sxgbe_rx_norm_desc *p); | ||
263 | |||
266 | /* Get the receive frame size */ | 264 | /* Get the receive frame size */ |
267 | int (*get_rx_frame_len)(struct sxgbe_rx_norm_desc *p); | 265 | int (*get_rx_frame_len)(struct sxgbe_rx_norm_desc *p); |
268 | 266 | ||
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.c index 4d989ff6c978..bb9b5b8afc5f 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_dma.c | |||
@@ -23,21 +23,8 @@ | |||
23 | /* DMA core initialization */ | 23 | /* DMA core initialization */ |
24 | static int sxgbe_dma_init(void __iomem *ioaddr, int fix_burst, int burst_map) | 24 | static int sxgbe_dma_init(void __iomem *ioaddr, int fix_burst, int burst_map) |
25 | { | 25 | { |
26 | int retry_count = 10; | ||
27 | u32 reg_val; | 26 | u32 reg_val; |
28 | 27 | ||
29 | /* reset the DMA */ | ||
30 | writel(SXGBE_DMA_SOFT_RESET, ioaddr + SXGBE_DMA_MODE_REG); | ||
31 | while (retry_count--) { | ||
32 | if (!(readl(ioaddr + SXGBE_DMA_MODE_REG) & | ||
33 | SXGBE_DMA_SOFT_RESET)) | ||
34 | break; | ||
35 | mdelay(10); | ||
36 | } | ||
37 | |||
38 | if (retry_count < 0) | ||
39 | return -EBUSY; | ||
40 | |||
41 | reg_val = readl(ioaddr + SXGBE_DMA_SYSBUS_MODE_REG); | 28 | reg_val = readl(ioaddr + SXGBE_DMA_SYSBUS_MODE_REG); |
42 | 29 | ||
43 | /* if fix_burst = 0, Set UNDEF = 1 of DMA_Sys_Mode Register. | 30 | /* if fix_burst = 0, Set UNDEF = 1 of DMA_Sys_Mode Register. |
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c index 27e8c824b204..82a9a983869f 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c | |||
@@ -1076,6 +1076,9 @@ static int sxgbe_open(struct net_device *dev) | |||
1076 | 1076 | ||
1077 | /* Initialize the MAC Core */ | 1077 | /* Initialize the MAC Core */ |
1078 | priv->hw->mac->core_init(priv->ioaddr); | 1078 | priv->hw->mac->core_init(priv->ioaddr); |
1079 | SXGBE_FOR_EACH_QUEUE(SXGBE_RX_QUEUES, queue_num) { | ||
1080 | priv->hw->mac->enable_rxqueue(priv->ioaddr, queue_num); | ||
1081 | } | ||
1079 | 1082 | ||
1080 | /* Request the IRQ lines */ | 1083 | /* Request the IRQ lines */ |
1081 | ret = devm_request_irq(priv->device, priv->irq, sxgbe_common_interrupt, | 1084 | ret = devm_request_irq(priv->device, priv->irq, sxgbe_common_interrupt, |
@@ -1453,6 +1456,7 @@ static void sxgbe_rx_refill(struct sxgbe_priv_data *priv) | |||
1453 | /* Added memory barrier for RX descriptor modification */ | 1456 | /* Added memory barrier for RX descriptor modification */ |
1454 | wmb(); | 1457 | wmb(); |
1455 | priv->hw->desc->set_rx_owner(p); | 1458 | priv->hw->desc->set_rx_owner(p); |
1459 | priv->hw->desc->set_rx_int_on_com(p); | ||
1456 | /* Added memory barrier for RX descriptor modification */ | 1460 | /* Added memory barrier for RX descriptor modification */ |
1457 | wmb(); | 1461 | wmb(); |
1458 | } | 1462 | } |
@@ -2070,6 +2074,24 @@ static int sxgbe_hw_init(struct sxgbe_priv_data * const priv) | |||
2070 | return 0; | 2074 | return 0; |
2071 | } | 2075 | } |
2072 | 2076 | ||
2077 | static int sxgbe_sw_reset(void __iomem *addr) | ||
2078 | { | ||
2079 | int retry_count = 10; | ||
2080 | |||
2081 | writel(SXGBE_DMA_SOFT_RESET, addr + SXGBE_DMA_MODE_REG); | ||
2082 | while (retry_count--) { | ||
2083 | if (!(readl(addr + SXGBE_DMA_MODE_REG) & | ||
2084 | SXGBE_DMA_SOFT_RESET)) | ||
2085 | break; | ||
2086 | mdelay(10); | ||
2087 | } | ||
2088 | |||
2089 | if (retry_count < 0) | ||
2090 | return -EBUSY; | ||
2091 | |||
2092 | return 0; | ||
2093 | } | ||
2094 | |||
2073 | /** | 2095 | /** |
2074 | * sxgbe_drv_probe | 2096 | * sxgbe_drv_probe |
2075 | * @device: device pointer | 2097 | * @device: device pointer |
@@ -2102,6 +2124,10 @@ struct sxgbe_priv_data *sxgbe_drv_probe(struct device *device, | |||
2102 | priv->plat = plat_dat; | 2124 | priv->plat = plat_dat; |
2103 | priv->ioaddr = addr; | 2125 | priv->ioaddr = addr; |
2104 | 2126 | ||
2127 | ret = sxgbe_sw_reset(priv->ioaddr); | ||
2128 | if (ret) | ||
2129 | goto error_free_netdev; | ||
2130 | |||
2105 | /* Verify driver arguments */ | 2131 | /* Verify driver arguments */ |
2106 | sxgbe_verify_args(); | 2132 | sxgbe_verify_args(); |
2107 | 2133 | ||
@@ -2218,9 +2244,14 @@ error_free_netdev: | |||
2218 | int sxgbe_drv_remove(struct net_device *ndev) | 2244 | int sxgbe_drv_remove(struct net_device *ndev) |
2219 | { | 2245 | { |
2220 | struct sxgbe_priv_data *priv = netdev_priv(ndev); | 2246 | struct sxgbe_priv_data *priv = netdev_priv(ndev); |
2247 | u8 queue_num; | ||
2221 | 2248 | ||
2222 | netdev_info(ndev, "%s: removing driver\n", __func__); | 2249 | netdev_info(ndev, "%s: removing driver\n", __func__); |
2223 | 2250 | ||
2251 | SXGBE_FOR_EACH_QUEUE(SXGBE_RX_QUEUES, queue_num) { | ||
2252 | priv->hw->mac->disable_rxqueue(priv->ioaddr, queue_num); | ||
2253 | } | ||
2254 | |||
2224 | priv->hw->dma->stop_rx(priv->ioaddr, SXGBE_RX_QUEUES); | 2255 | priv->hw->dma->stop_rx(priv->ioaddr, SXGBE_RX_QUEUES); |
2225 | priv->hw->dma->stop_tx(priv->ioaddr, SXGBE_TX_QUEUES); | 2256 | priv->hw->dma->stop_tx(priv->ioaddr, SXGBE_TX_QUEUES); |
2226 | 2257 | ||
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c index 01af2cbb479d..43ccb4a6de15 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c | |||
@@ -27,7 +27,7 @@ | |||
27 | #define SXGBE_SMA_PREAD_CMD 0x02 /* post read increament address */ | 27 | #define SXGBE_SMA_PREAD_CMD 0x02 /* post read increament address */ |
28 | #define SXGBE_SMA_READ_CMD 0x03 /* read command */ | 28 | #define SXGBE_SMA_READ_CMD 0x03 /* read command */ |
29 | #define SXGBE_SMA_SKIP_ADDRFRM 0x00040000 /* skip the address frame */ | 29 | #define SXGBE_SMA_SKIP_ADDRFRM 0x00040000 /* skip the address frame */ |
30 | #define SXGBE_MII_BUSY 0x00800000 /* mii busy */ | 30 | #define SXGBE_MII_BUSY 0x00400000 /* mii busy */ |
31 | 31 | ||
32 | static int sxgbe_mdio_busy_wait(void __iomem *ioaddr, unsigned int mii_data) | 32 | static int sxgbe_mdio_busy_wait(void __iomem *ioaddr, unsigned int mii_data) |
33 | { | 33 | { |
@@ -147,6 +147,7 @@ int sxgbe_mdio_register(struct net_device *ndev) | |||
147 | struct sxgbe_mdio_bus_data *mdio_data = priv->plat->mdio_bus_data; | 147 | struct sxgbe_mdio_bus_data *mdio_data = priv->plat->mdio_bus_data; |
148 | int err, phy_addr; | 148 | int err, phy_addr; |
149 | int *irqlist; | 149 | int *irqlist; |
150 | bool phy_found = false; | ||
150 | bool act; | 151 | bool act; |
151 | 152 | ||
152 | /* allocate the new mdio bus */ | 153 | /* allocate the new mdio bus */ |
@@ -162,7 +163,7 @@ int sxgbe_mdio_register(struct net_device *ndev) | |||
162 | irqlist = priv->mii_irq; | 163 | irqlist = priv->mii_irq; |
163 | 164 | ||
164 | /* assign mii bus fields */ | 165 | /* assign mii bus fields */ |
165 | mdio_bus->name = "samsxgbe"; | 166 | mdio_bus->name = "sxgbe"; |
166 | mdio_bus->read = &sxgbe_mdio_read; | 167 | mdio_bus->read = &sxgbe_mdio_read; |
167 | mdio_bus->write = &sxgbe_mdio_write; | 168 | mdio_bus->write = &sxgbe_mdio_write; |
168 | snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s-%x", | 169 | snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s-%x", |
@@ -216,13 +217,22 @@ int sxgbe_mdio_register(struct net_device *ndev) | |||
216 | netdev_info(ndev, "PHY ID %08x at %d IRQ %s (%s)%s\n", | 217 | netdev_info(ndev, "PHY ID %08x at %d IRQ %s (%s)%s\n", |
217 | phy->phy_id, phy_addr, irq_str, | 218 | phy->phy_id, phy_addr, irq_str, |
218 | dev_name(&phy->dev), act ? " active" : ""); | 219 | dev_name(&phy->dev), act ? " active" : ""); |
220 | phy_found = true; | ||
219 | } | 221 | } |
220 | } | 222 | } |
221 | 223 | ||
224 | if (!phy_found) { | ||
225 | netdev_err(ndev, "PHY not found\n"); | ||
226 | goto phyfound_err; | ||
227 | } | ||
228 | |||
222 | priv->mii = mdio_bus; | 229 | priv->mii = mdio_bus; |
223 | 230 | ||
224 | return 0; | 231 | return 0; |
225 | 232 | ||
233 | phyfound_err: | ||
234 | err = -ENODEV; | ||
235 | mdiobus_unregister(mdio_bus); | ||
226 | mdiobus_err: | 236 | mdiobus_err: |
227 | mdiobus_free(mdio_bus); | 237 | mdiobus_free(mdio_bus); |
228 | return err; | 238 | return err; |
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_reg.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_reg.h index 5a89acb4c505..56f8bf5a3f1b 100644 --- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_reg.h +++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_reg.h | |||
@@ -52,6 +52,10 @@ | |||
52 | #define SXGBE_CORE_RX_CTL2_REG 0x00A8 | 52 | #define SXGBE_CORE_RX_CTL2_REG 0x00A8 |
53 | #define SXGBE_CORE_RX_CTL3_REG 0x00AC | 53 | #define SXGBE_CORE_RX_CTL3_REG 0x00AC |
54 | 54 | ||
55 | #define SXGBE_CORE_RXQ_ENABLE_MASK 0x0003 | ||
56 | #define SXGBE_CORE_RXQ_ENABLE 0x0002 | ||
57 | #define SXGBE_CORE_RXQ_DISABLE 0x0000 | ||
58 | |||
55 | /* Interrupt Registers */ | 59 | /* Interrupt Registers */ |
56 | #define SXGBE_CORE_INT_STATUS_REG 0x00B0 | 60 | #define SXGBE_CORE_INT_STATUS_REG 0x00B0 |
57 | #define SXGBE_CORE_INT_ENABLE_REG 0x00B4 | 61 | #define SXGBE_CORE_INT_ENABLE_REG 0x00B4 |
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c index d1b4dca53a9d..bcaa41af1e62 100644 --- a/drivers/net/ethernet/smsc/smc91x.c +++ b/drivers/net/ethernet/smsc/smc91x.c | |||
@@ -147,18 +147,19 @@ MODULE_ALIAS("platform:smc91x"); | |||
147 | */ | 147 | */ |
148 | #define MII_DELAY 1 | 148 | #define MII_DELAY 1 |
149 | 149 | ||
150 | #if SMC_DEBUG > 0 | 150 | #define DBG(n, dev, fmt, ...) \ |
151 | #define DBG(n, dev, args...) \ | 151 | do { \ |
152 | do { \ | 152 | if (SMC_DEBUG >= (n)) \ |
153 | if (SMC_DEBUG >= (n)) \ | 153 | netdev_dbg(dev, fmt, ##__VA_ARGS__); \ |
154 | netdev_dbg(dev, args); \ | ||
155 | } while (0) | 154 | } while (0) |
156 | 155 | ||
157 | #define PRINTK(dev, args...) netdev_info(dev, args) | 156 | #define PRINTK(dev, fmt, ...) \ |
158 | #else | 157 | do { \ |
159 | #define DBG(n, dev, args...) do { } while (0) | 158 | if (SMC_DEBUG > 0) \ |
160 | #define PRINTK(dev, args...) netdev_dbg(dev, args) | 159 | netdev_info(dev, fmt, ##__VA_ARGS__); \ |
161 | #endif | 160 | else \ |
161 | netdev_dbg(dev, fmt, ##__VA_ARGS__); \ | ||
162 | } while (0) | ||
162 | 163 | ||
163 | #if SMC_DEBUG > 3 | 164 | #if SMC_DEBUG > 3 |
164 | static void PRINT_PKT(u_char *buf, int length) | 165 | static void PRINT_PKT(u_char *buf, int length) |
@@ -191,7 +192,7 @@ static void PRINT_PKT(u_char *buf, int length) | |||
191 | pr_cont("\n"); | 192 | pr_cont("\n"); |
192 | } | 193 | } |
193 | #else | 194 | #else |
194 | #define PRINT_PKT(x...) do { } while (0) | 195 | static inline void PRINT_PKT(u_char *buf, int length) { } |
195 | #endif | 196 | #endif |
196 | 197 | ||
197 | 198 | ||
@@ -1781,7 +1782,7 @@ static int smc_findirq(struct smc_local *lp) | |||
1781 | int timeout = 20; | 1782 | int timeout = 20; |
1782 | unsigned long cookie; | 1783 | unsigned long cookie; |
1783 | 1784 | ||
1784 | DBG(2, dev, "%s: %s\n", CARDNAME, __func__); | 1785 | DBG(2, lp->dev, "%s: %s\n", CARDNAME, __func__); |
1785 | 1786 | ||
1786 | cookie = probe_irq_on(); | 1787 | cookie = probe_irq_on(); |
1787 | 1788 | ||
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c index 31e55fba7cad..7918d5132c1f 100644 --- a/drivers/net/hyperv/netvsc_drv.c +++ b/drivers/net/hyperv/netvsc_drv.c | |||
@@ -382,6 +382,10 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net) | |||
382 | if (skb_is_gso(skb)) | 382 | if (skb_is_gso(skb)) |
383 | goto do_lso; | 383 | goto do_lso; |
384 | 384 | ||
385 | if ((skb->ip_summed == CHECKSUM_NONE) || | ||
386 | (skb->ip_summed == CHECKSUM_UNNECESSARY)) | ||
387 | goto do_send; | ||
388 | |||
385 | rndis_msg_size += NDIS_CSUM_PPI_SIZE; | 389 | rndis_msg_size += NDIS_CSUM_PPI_SIZE; |
386 | ppi = init_ppi_data(rndis_msg, NDIS_CSUM_PPI_SIZE, | 390 | ppi = init_ppi_data(rndis_msg, NDIS_CSUM_PPI_SIZE, |
387 | TCPIP_CHKSUM_PKTINFO); | 391 | TCPIP_CHKSUM_PKTINFO); |
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 753a8c23d15d..b0e2865a6810 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c | |||
@@ -263,11 +263,9 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) | |||
263 | const struct macvlan_dev *vlan = netdev_priv(dev); | 263 | const struct macvlan_dev *vlan = netdev_priv(dev); |
264 | const struct macvlan_port *port = vlan->port; | 264 | const struct macvlan_port *port = vlan->port; |
265 | const struct macvlan_dev *dest; | 265 | const struct macvlan_dev *dest; |
266 | __u8 ip_summed = skb->ip_summed; | ||
267 | 266 | ||
268 | if (vlan->mode == MACVLAN_MODE_BRIDGE) { | 267 | if (vlan->mode == MACVLAN_MODE_BRIDGE) { |
269 | const struct ethhdr *eth = (void *)skb->data; | 268 | const struct ethhdr *eth = (void *)skb->data; |
270 | skb->ip_summed = CHECKSUM_UNNECESSARY; | ||
271 | 269 | ||
272 | /* send to other bridge ports directly */ | 270 | /* send to other bridge ports directly */ |
273 | if (is_multicast_ether_addr(eth->h_dest)) { | 271 | if (is_multicast_ether_addr(eth->h_dest)) { |
@@ -285,7 +283,6 @@ static int macvlan_queue_xmit(struct sk_buff *skb, struct net_device *dev) | |||
285 | } | 283 | } |
286 | 284 | ||
287 | xmit_world: | 285 | xmit_world: |
288 | skb->ip_summed = ip_summed; | ||
289 | skb->dev = vlan->lowerdev; | 286 | skb->dev = vlan->lowerdev; |
290 | return dev_queue_xmit(skb); | 287 | return dev_queue_xmit(skb); |
291 | } | 288 | } |
diff --git a/drivers/net/macvtap.c b/drivers/net/macvtap.c index ff111a89e17f..3381c4f91a8c 100644 --- a/drivers/net/macvtap.c +++ b/drivers/net/macvtap.c | |||
@@ -322,6 +322,15 @@ static rx_handler_result_t macvtap_handle_frame(struct sk_buff **pskb) | |||
322 | segs = nskb; | 322 | segs = nskb; |
323 | } | 323 | } |
324 | } else { | 324 | } else { |
325 | /* If we receive a partial checksum and the tap side | ||
326 | * doesn't support checksum offload, compute the checksum. | ||
327 | * Note: it doesn't matter which checksum feature to | ||
328 | * check, we either support them all or none. | ||
329 | */ | ||
330 | if (skb->ip_summed == CHECKSUM_PARTIAL && | ||
331 | !(features & NETIF_F_ALL_CSUM) && | ||
332 | skb_checksum_help(skb)) | ||
333 | goto drop; | ||
325 | skb_queue_tail(&q->sk.sk_receive_queue, skb); | 334 | skb_queue_tail(&q->sk.sk_receive_queue, skb); |
326 | } | 335 | } |
327 | 336 | ||
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 5ad971a55c5d..d849684231c1 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c | |||
@@ -246,13 +246,13 @@ static int ksz9021_load_values_from_of(struct phy_device *phydev, | |||
246 | if (val1 != -1) | 246 | if (val1 != -1) |
247 | newval = ((newval & 0xfff0) | ((val1 / PS_TO_REG) & 0xf) << 0); | 247 | newval = ((newval & 0xfff0) | ((val1 / PS_TO_REG) & 0xf) << 0); |
248 | 248 | ||
249 | if (val2 != -1) | 249 | if (val2 != -2) |
250 | newval = ((newval & 0xff0f) | ((val2 / PS_TO_REG) & 0xf) << 4); | 250 | newval = ((newval & 0xff0f) | ((val2 / PS_TO_REG) & 0xf) << 4); |
251 | 251 | ||
252 | if (val3 != -1) | 252 | if (val3 != -3) |
253 | newval = ((newval & 0xf0ff) | ((val3 / PS_TO_REG) & 0xf) << 8); | 253 | newval = ((newval & 0xf0ff) | ((val3 / PS_TO_REG) & 0xf) << 8); |
254 | 254 | ||
255 | if (val4 != -1) | 255 | if (val4 != -4) |
256 | newval = ((newval & 0x0fff) | ((val4 / PS_TO_REG) & 0xf) << 12); | 256 | newval = ((newval & 0x0fff) | ((val4 / PS_TO_REG) & 0xf) << 12); |
257 | 257 | ||
258 | return kszphy_extended_write(phydev, reg, newval); | 258 | return kszphy_extended_write(phydev, reg, newval); |
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index 1b6d09aef427..a972056b2249 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c | |||
@@ -765,6 +765,17 @@ void phy_state_machine(struct work_struct *work) | |||
765 | break; | 765 | break; |
766 | 766 | ||
767 | if (phydev->link) { | 767 | if (phydev->link) { |
768 | if (AUTONEG_ENABLE == phydev->autoneg) { | ||
769 | err = phy_aneg_done(phydev); | ||
770 | if (err < 0) | ||
771 | break; | ||
772 | |||
773 | if (!err) { | ||
774 | phydev->state = PHY_AN; | ||
775 | phydev->link_timeout = PHY_AN_TIMEOUT; | ||
776 | break; | ||
777 | } | ||
778 | } | ||
768 | phydev->state = PHY_RUNNING; | 779 | phydev->state = PHY_RUNNING; |
769 | netif_carrier_on(phydev->attached_dev); | 780 | netif_carrier_on(phydev->attached_dev); |
770 | phydev->adjust_link(phydev->attached_dev); | 781 | phydev->adjust_link(phydev->attached_dev); |
diff --git a/drivers/net/slip/slip.c b/drivers/net/slip/slip.c index cc70ecfc7062..ad4a94e9ff57 100644 --- a/drivers/net/slip/slip.c +++ b/drivers/net/slip/slip.c | |||
@@ -429,13 +429,13 @@ static void slip_write_wakeup(struct tty_struct *tty) | |||
429 | if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) | 429 | if (!sl || sl->magic != SLIP_MAGIC || !netif_running(sl->dev)) |
430 | return; | 430 | return; |
431 | 431 | ||
432 | spin_lock(&sl->lock); | 432 | spin_lock_bh(&sl->lock); |
433 | if (sl->xleft <= 0) { | 433 | if (sl->xleft <= 0) { |
434 | /* Now serial buffer is almost free & we can start | 434 | /* Now serial buffer is almost free & we can start |
435 | * transmission of another packet */ | 435 | * transmission of another packet */ |
436 | sl->dev->stats.tx_packets++; | 436 | sl->dev->stats.tx_packets++; |
437 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); | 437 | clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); |
438 | spin_unlock(&sl->lock); | 438 | spin_unlock_bh(&sl->lock); |
439 | sl_unlock(sl); | 439 | sl_unlock(sl); |
440 | return; | 440 | return; |
441 | } | 441 | } |
@@ -443,7 +443,7 @@ static void slip_write_wakeup(struct tty_struct *tty) | |||
443 | actual = tty->ops->write(tty, sl->xhead, sl->xleft); | 443 | actual = tty->ops->write(tty, sl->xhead, sl->xleft); |
444 | sl->xleft -= actual; | 444 | sl->xleft -= actual; |
445 | sl->xhead += actual; | 445 | sl->xhead += actual; |
446 | spin_unlock(&sl->lock); | 446 | spin_unlock_bh(&sl->lock); |
447 | } | 447 | } |
448 | 448 | ||
449 | static void sl_tx_timeout(struct net_device *dev) | 449 | static void sl_tx_timeout(struct net_device *dev) |
diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c index 33008c1d1d67..767fe61b5ac9 100644 --- a/drivers/net/team/team.c +++ b/drivers/net/team/team.c | |||
@@ -2834,8 +2834,10 @@ static int team_device_event(struct notifier_block *unused, | |||
2834 | case NETDEV_UP: | 2834 | case NETDEV_UP: |
2835 | if (netif_carrier_ok(dev)) | 2835 | if (netif_carrier_ok(dev)) |
2836 | team_port_change_check(port, true); | 2836 | team_port_change_check(port, true); |
2837 | break; | ||
2837 | case NETDEV_DOWN: | 2838 | case NETDEV_DOWN: |
2838 | team_port_change_check(port, false); | 2839 | team_port_change_check(port, false); |
2840 | break; | ||
2839 | case NETDEV_CHANGE: | 2841 | case NETDEV_CHANGE: |
2840 | if (netif_running(port->dev)) | 2842 | if (netif_running(port->dev)) |
2841 | team_port_change_check(port, | 2843 | team_port_change_check(port, |
diff --git a/drivers/net/usb/cdc_ncm.c b/drivers/net/usb/cdc_ncm.c index 549dbac710ed..9a2bd11943eb 100644 --- a/drivers/net/usb/cdc_ncm.c +++ b/drivers/net/usb/cdc_ncm.c | |||
@@ -785,7 +785,7 @@ cdc_ncm_fill_tx_frame(struct usbnet *dev, struct sk_buff *skb, __le32 sign) | |||
785 | skb_out->len > CDC_NCM_MIN_TX_PKT) | 785 | skb_out->len > CDC_NCM_MIN_TX_PKT) |
786 | memset(skb_put(skb_out, ctx->tx_max - skb_out->len), 0, | 786 | memset(skb_put(skb_out, ctx->tx_max - skb_out->len), 0, |
787 | ctx->tx_max - skb_out->len); | 787 | ctx->tx_max - skb_out->len); |
788 | else if ((skb_out->len % dev->maxpacket) == 0) | 788 | else if (skb_out->len < ctx->tx_max && (skb_out->len % dev->maxpacket) == 0) |
789 | *skb_put(skb_out, 1) = 0; /* force short packet */ | 789 | *skb_put(skb_out, 1) = 0; /* force short packet */ |
790 | 790 | ||
791 | /* set final frame length */ | 791 | /* set final frame length */ |
diff --git a/drivers/net/usb/qmi_wwan.c b/drivers/net/usb/qmi_wwan.c index e3458e3c44f1..83208d4fdc59 100644 --- a/drivers/net/usb/qmi_wwan.c +++ b/drivers/net/usb/qmi_wwan.c | |||
@@ -669,6 +669,22 @@ static const struct usb_device_id products[] = { | |||
669 | {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, | 669 | {QMI_FIXED_INTF(0x05c6, 0x920d, 5)}, |
670 | {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ | 670 | {QMI_FIXED_INTF(0x12d1, 0x140c, 1)}, /* Huawei E173 */ |
671 | {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */ | 671 | {QMI_FIXED_INTF(0x12d1, 0x14ac, 1)}, /* Huawei E1820 */ |
672 | {QMI_FIXED_INTF(0x16d8, 0x6003, 0)}, /* CMOTech 6003 */ | ||
673 | {QMI_FIXED_INTF(0x16d8, 0x6007, 0)}, /* CMOTech CHE-628S */ | ||
674 | {QMI_FIXED_INTF(0x16d8, 0x6008, 0)}, /* CMOTech CMU-301 */ | ||
675 | {QMI_FIXED_INTF(0x16d8, 0x6280, 0)}, /* CMOTech CHU-628 */ | ||
676 | {QMI_FIXED_INTF(0x16d8, 0x7001, 0)}, /* CMOTech CHU-720S */ | ||
677 | {QMI_FIXED_INTF(0x16d8, 0x7002, 0)}, /* CMOTech 7002 */ | ||
678 | {QMI_FIXED_INTF(0x16d8, 0x7003, 4)}, /* CMOTech CHU-629K */ | ||
679 | {QMI_FIXED_INTF(0x16d8, 0x7004, 3)}, /* CMOTech 7004 */ | ||
680 | {QMI_FIXED_INTF(0x16d8, 0x7006, 5)}, /* CMOTech CGU-629 */ | ||
681 | {QMI_FIXED_INTF(0x16d8, 0x700a, 4)}, /* CMOTech CHU-629S */ | ||
682 | {QMI_FIXED_INTF(0x16d8, 0x7211, 0)}, /* CMOTech CHU-720I */ | ||
683 | {QMI_FIXED_INTF(0x16d8, 0x7212, 0)}, /* CMOTech 7212 */ | ||
684 | {QMI_FIXED_INTF(0x16d8, 0x7213, 0)}, /* CMOTech 7213 */ | ||
685 | {QMI_FIXED_INTF(0x16d8, 0x7251, 1)}, /* CMOTech 7251 */ | ||
686 | {QMI_FIXED_INTF(0x16d8, 0x7252, 1)}, /* CMOTech 7252 */ | ||
687 | {QMI_FIXED_INTF(0x16d8, 0x7253, 1)}, /* CMOTech 7253 */ | ||
672 | {QMI_FIXED_INTF(0x19d2, 0x0002, 1)}, | 688 | {QMI_FIXED_INTF(0x19d2, 0x0002, 1)}, |
673 | {QMI_FIXED_INTF(0x19d2, 0x0012, 1)}, | 689 | {QMI_FIXED_INTF(0x19d2, 0x0012, 1)}, |
674 | {QMI_FIXED_INTF(0x19d2, 0x0017, 3)}, | 690 | {QMI_FIXED_INTF(0x19d2, 0x0017, 3)}, |
@@ -730,16 +746,28 @@ static const struct usb_device_id products[] = { | |||
730 | {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ | 746 | {QMI_FIXED_INTF(0x114f, 0x68a2, 8)}, /* Sierra Wireless MC7750 */ |
731 | {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ | 747 | {QMI_FIXED_INTF(0x1199, 0x68a2, 8)}, /* Sierra Wireless MC7710 in QMI mode */ |
732 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ | 748 | {QMI_FIXED_INTF(0x1199, 0x68a2, 19)}, /* Sierra Wireless MC7710 in QMI mode */ |
749 | {QMI_FIXED_INTF(0x1199, 0x68c0, 8)}, /* Sierra Wireless MC73xx */ | ||
750 | {QMI_FIXED_INTF(0x1199, 0x68c0, 10)}, /* Sierra Wireless MC73xx */ | ||
751 | {QMI_FIXED_INTF(0x1199, 0x68c0, 11)}, /* Sierra Wireless MC73xx */ | ||
733 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ | 752 | {QMI_FIXED_INTF(0x1199, 0x901c, 8)}, /* Sierra Wireless EM7700 */ |
753 | {QMI_FIXED_INTF(0x1199, 0x901f, 8)}, /* Sierra Wireless EM7355 */ | ||
754 | {QMI_FIXED_INTF(0x1199, 0x9041, 8)}, /* Sierra Wireless MC7305/MC7355 */ | ||
734 | {QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */ | 755 | {QMI_FIXED_INTF(0x1199, 0x9051, 8)}, /* Netgear AirCard 340U */ |
735 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ | 756 | {QMI_FIXED_INTF(0x1bbb, 0x011e, 4)}, /* Telekom Speedstick LTE II (Alcatel One Touch L100V LTE) */ |
757 | {QMI_FIXED_INTF(0x1bbb, 0x0203, 2)}, /* Alcatel L800MA */ | ||
736 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ | 758 | {QMI_FIXED_INTF(0x2357, 0x0201, 4)}, /* TP-LINK HSUPA Modem MA180 */ |
737 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ | 759 | {QMI_FIXED_INTF(0x2357, 0x9000, 4)}, /* TP-LINK MA260 */ |
738 | {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ | 760 | {QMI_FIXED_INTF(0x1bc7, 0x1200, 5)}, /* Telit LE920 */ |
739 | {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ | 761 | {QMI_FIXED_INTF(0x1bc7, 0x1201, 2)}, /* Telit LE920 */ |
740 | {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */ | 762 | {QMI_FIXED_INTF(0x0b3c, 0xc005, 6)}, /* Olivetti Olicard 200 */ |
763 | {QMI_FIXED_INTF(0x0b3c, 0xc00b, 4)}, /* Olivetti Olicard 500 */ | ||
741 | {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ | 764 | {QMI_FIXED_INTF(0x1e2d, 0x0060, 4)}, /* Cinterion PLxx */ |
742 | {QMI_FIXED_INTF(0x1e2d, 0x0053, 4)}, /* Cinterion PHxx,PXxx */ | 765 | {QMI_FIXED_INTF(0x1e2d, 0x0053, 4)}, /* Cinterion PHxx,PXxx */ |
766 | {QMI_FIXED_INTF(0x413c, 0x81a2, 8)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card */ | ||
767 | {QMI_FIXED_INTF(0x413c, 0x81a3, 8)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card */ | ||
768 | {QMI_FIXED_INTF(0x413c, 0x81a4, 8)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card */ | ||
769 | {QMI_FIXED_INTF(0x413c, 0x81a8, 8)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card */ | ||
770 | {QMI_FIXED_INTF(0x413c, 0x81a9, 8)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card */ | ||
743 | 771 | ||
744 | /* 4. Gobi 1000 devices */ | 772 | /* 4. Gobi 1000 devices */ |
745 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ | 773 | {QMI_GOBI1K_DEVICE(0x05c6, 0x9212)}, /* Acer Gobi Modem Device */ |
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c index 7b687469199b..8a852b5f215f 100644 --- a/drivers/net/virtio_net.c +++ b/drivers/net/virtio_net.c | |||
@@ -1285,7 +1285,7 @@ static int virtnet_set_channels(struct net_device *dev, | |||
1285 | if (channels->rx_count || channels->tx_count || channels->other_count) | 1285 | if (channels->rx_count || channels->tx_count || channels->other_count) |
1286 | return -EINVAL; | 1286 | return -EINVAL; |
1287 | 1287 | ||
1288 | if (queue_pairs > vi->max_queue_pairs) | 1288 | if (queue_pairs > vi->max_queue_pairs || queue_pairs == 0) |
1289 | return -EINVAL; | 1289 | return -EINVAL; |
1290 | 1290 | ||
1291 | get_online_cpus(); | 1291 | get_online_cpus(); |
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 82355d5d155a..4dbb2ed85b97 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c | |||
@@ -389,8 +389,8 @@ static inline size_t vxlan_nlmsg_size(void) | |||
389 | + nla_total_size(sizeof(struct nda_cacheinfo)); | 389 | + nla_total_size(sizeof(struct nda_cacheinfo)); |
390 | } | 390 | } |
391 | 391 | ||
392 | static void vxlan_fdb_notify(struct vxlan_dev *vxlan, | 392 | static void vxlan_fdb_notify(struct vxlan_dev *vxlan, struct vxlan_fdb *fdb, |
393 | struct vxlan_fdb *fdb, int type) | 393 | struct vxlan_rdst *rd, int type) |
394 | { | 394 | { |
395 | struct net *net = dev_net(vxlan->dev); | 395 | struct net *net = dev_net(vxlan->dev); |
396 | struct sk_buff *skb; | 396 | struct sk_buff *skb; |
@@ -400,8 +400,7 @@ static void vxlan_fdb_notify(struct vxlan_dev *vxlan, | |||
400 | if (skb == NULL) | 400 | if (skb == NULL) |
401 | goto errout; | 401 | goto errout; |
402 | 402 | ||
403 | err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0, | 403 | err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0, rd); |
404 | first_remote_rtnl(fdb)); | ||
405 | if (err < 0) { | 404 | if (err < 0) { |
406 | /* -EMSGSIZE implies BUG in vxlan_nlmsg_size() */ | 405 | /* -EMSGSIZE implies BUG in vxlan_nlmsg_size() */ |
407 | WARN_ON(err == -EMSGSIZE); | 406 | WARN_ON(err == -EMSGSIZE); |
@@ -427,10 +426,7 @@ static void vxlan_ip_miss(struct net_device *dev, union vxlan_addr *ipa) | |||
427 | .remote_vni = VXLAN_N_VID, | 426 | .remote_vni = VXLAN_N_VID, |
428 | }; | 427 | }; |
429 | 428 | ||
430 | INIT_LIST_HEAD(&f.remotes); | 429 | vxlan_fdb_notify(vxlan, &f, &remote, RTM_GETNEIGH); |
431 | list_add_rcu(&remote.list, &f.remotes); | ||
432 | |||
433 | vxlan_fdb_notify(vxlan, &f, RTM_GETNEIGH); | ||
434 | } | 430 | } |
435 | 431 | ||
436 | static void vxlan_fdb_miss(struct vxlan_dev *vxlan, const u8 eth_addr[ETH_ALEN]) | 432 | static void vxlan_fdb_miss(struct vxlan_dev *vxlan, const u8 eth_addr[ETH_ALEN]) |
@@ -438,11 +434,11 @@ static void vxlan_fdb_miss(struct vxlan_dev *vxlan, const u8 eth_addr[ETH_ALEN]) | |||
438 | struct vxlan_fdb f = { | 434 | struct vxlan_fdb f = { |
439 | .state = NUD_STALE, | 435 | .state = NUD_STALE, |
440 | }; | 436 | }; |
437 | struct vxlan_rdst remote = { }; | ||
441 | 438 | ||
442 | INIT_LIST_HEAD(&f.remotes); | ||
443 | memcpy(f.eth_addr, eth_addr, ETH_ALEN); | 439 | memcpy(f.eth_addr, eth_addr, ETH_ALEN); |
444 | 440 | ||
445 | vxlan_fdb_notify(vxlan, &f, RTM_GETNEIGH); | 441 | vxlan_fdb_notify(vxlan, &f, &remote, RTM_GETNEIGH); |
446 | } | 442 | } |
447 | 443 | ||
448 | /* Hash Ethernet address */ | 444 | /* Hash Ethernet address */ |
@@ -533,7 +529,8 @@ static int vxlan_fdb_replace(struct vxlan_fdb *f, | |||
533 | 529 | ||
534 | /* Add/update destinations for multicast */ | 530 | /* Add/update destinations for multicast */ |
535 | static int vxlan_fdb_append(struct vxlan_fdb *f, | 531 | static int vxlan_fdb_append(struct vxlan_fdb *f, |
536 | union vxlan_addr *ip, __be16 port, __u32 vni, __u32 ifindex) | 532 | union vxlan_addr *ip, __be16 port, __u32 vni, |
533 | __u32 ifindex, struct vxlan_rdst **rdp) | ||
537 | { | 534 | { |
538 | struct vxlan_rdst *rd; | 535 | struct vxlan_rdst *rd; |
539 | 536 | ||
@@ -551,6 +548,7 @@ static int vxlan_fdb_append(struct vxlan_fdb *f, | |||
551 | 548 | ||
552 | list_add_tail_rcu(&rd->list, &f->remotes); | 549 | list_add_tail_rcu(&rd->list, &f->remotes); |
553 | 550 | ||
551 | *rdp = rd; | ||
554 | return 1; | 552 | return 1; |
555 | } | 553 | } |
556 | 554 | ||
@@ -690,6 +688,7 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan, | |||
690 | __be16 port, __u32 vni, __u32 ifindex, | 688 | __be16 port, __u32 vni, __u32 ifindex, |
691 | __u8 ndm_flags) | 689 | __u8 ndm_flags) |
692 | { | 690 | { |
691 | struct vxlan_rdst *rd = NULL; | ||
693 | struct vxlan_fdb *f; | 692 | struct vxlan_fdb *f; |
694 | int notify = 0; | 693 | int notify = 0; |
695 | 694 | ||
@@ -726,7 +725,8 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan, | |||
726 | if ((flags & NLM_F_APPEND) && | 725 | if ((flags & NLM_F_APPEND) && |
727 | (is_multicast_ether_addr(f->eth_addr) || | 726 | (is_multicast_ether_addr(f->eth_addr) || |
728 | is_zero_ether_addr(f->eth_addr))) { | 727 | is_zero_ether_addr(f->eth_addr))) { |
729 | int rc = vxlan_fdb_append(f, ip, port, vni, ifindex); | 728 | int rc = vxlan_fdb_append(f, ip, port, vni, ifindex, |
729 | &rd); | ||
730 | 730 | ||
731 | if (rc < 0) | 731 | if (rc < 0) |
732 | return rc; | 732 | return rc; |
@@ -756,15 +756,18 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan, | |||
756 | INIT_LIST_HEAD(&f->remotes); | 756 | INIT_LIST_HEAD(&f->remotes); |
757 | memcpy(f->eth_addr, mac, ETH_ALEN); | 757 | memcpy(f->eth_addr, mac, ETH_ALEN); |
758 | 758 | ||
759 | vxlan_fdb_append(f, ip, port, vni, ifindex); | 759 | vxlan_fdb_append(f, ip, port, vni, ifindex, &rd); |
760 | 760 | ||
761 | ++vxlan->addrcnt; | 761 | ++vxlan->addrcnt; |
762 | hlist_add_head_rcu(&f->hlist, | 762 | hlist_add_head_rcu(&f->hlist, |
763 | vxlan_fdb_head(vxlan, mac)); | 763 | vxlan_fdb_head(vxlan, mac)); |
764 | } | 764 | } |
765 | 765 | ||
766 | if (notify) | 766 | if (notify) { |
767 | vxlan_fdb_notify(vxlan, f, RTM_NEWNEIGH); | 767 | if (rd == NULL) |
768 | rd = first_remote_rtnl(f); | ||
769 | vxlan_fdb_notify(vxlan, f, rd, RTM_NEWNEIGH); | ||
770 | } | ||
768 | 771 | ||
769 | return 0; | 772 | return 0; |
770 | } | 773 | } |
@@ -785,7 +788,7 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f) | |||
785 | "delete %pM\n", f->eth_addr); | 788 | "delete %pM\n", f->eth_addr); |
786 | 789 | ||
787 | --vxlan->addrcnt; | 790 | --vxlan->addrcnt; |
788 | vxlan_fdb_notify(vxlan, f, RTM_DELNEIGH); | 791 | vxlan_fdb_notify(vxlan, f, first_remote_rtnl(f), RTM_DELNEIGH); |
789 | 792 | ||
790 | hlist_del_rcu(&f->hlist); | 793 | hlist_del_rcu(&f->hlist); |
791 | call_rcu(&f->rcu, vxlan_fdb_free); | 794 | call_rcu(&f->rcu, vxlan_fdb_free); |
@@ -919,6 +922,7 @@ static int vxlan_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], | |||
919 | */ | 922 | */ |
920 | if (rd && !list_is_singular(&f->remotes)) { | 923 | if (rd && !list_is_singular(&f->remotes)) { |
921 | list_del_rcu(&rd->list); | 924 | list_del_rcu(&rd->list); |
925 | vxlan_fdb_notify(vxlan, f, rd, RTM_DELNEIGH); | ||
922 | kfree_rcu(rd, rcu); | 926 | kfree_rcu(rd, rcu); |
923 | goto out; | 927 | goto out; |
924 | } | 928 | } |
@@ -993,7 +997,7 @@ static bool vxlan_snoop(struct net_device *dev, | |||
993 | 997 | ||
994 | rdst->remote_ip = *src_ip; | 998 | rdst->remote_ip = *src_ip; |
995 | f->updated = jiffies; | 999 | f->updated = jiffies; |
996 | vxlan_fdb_notify(vxlan, f, RTM_NEWNEIGH); | 1000 | vxlan_fdb_notify(vxlan, f, rdst, RTM_NEWNEIGH); |
997 | } else { | 1001 | } else { |
998 | /* learned new entry */ | 1002 | /* learned new entry */ |
999 | spin_lock(&vxlan->hash_lock); | 1003 | spin_lock(&vxlan->hash_lock); |
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c index a0398fe3eb28..be3eb2a8d602 100644 --- a/drivers/net/wireless/ath/ath9k/ahb.c +++ b/drivers/net/wireless/ath/ath9k/ahb.c | |||
@@ -86,7 +86,6 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
86 | int irq; | 86 | int irq; |
87 | int ret = 0; | 87 | int ret = 0; |
88 | struct ath_hw *ah; | 88 | struct ath_hw *ah; |
89 | struct ath_common *common; | ||
90 | char hw_name[64]; | 89 | char hw_name[64]; |
91 | 90 | ||
92 | if (!dev_get_platdata(&pdev->dev)) { | 91 | if (!dev_get_platdata(&pdev->dev)) { |
@@ -146,9 +145,6 @@ static int ath_ahb_probe(struct platform_device *pdev) | |||
146 | wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", | 145 | wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", |
147 | hw_name, (unsigned long)mem, irq); | 146 | hw_name, (unsigned long)mem, irq); |
148 | 147 | ||
149 | common = ath9k_hw_common(sc->sc_ah); | ||
150 | /* Will be cleared in ath9k_start() */ | ||
151 | set_bit(ATH_OP_INVALID, &common->op_flags); | ||
152 | return 0; | 148 | return 0; |
153 | 149 | ||
154 | err_irq: | 150 | err_irq: |
diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 6d47783f2e5b..ba502a2d199b 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c | |||
@@ -155,6 +155,9 @@ static void ath9k_hw_set_ofdm_nil(struct ath_hw *ah, u8 immunityLevel, | |||
155 | ATH9K_ANI_RSSI_THR_LOW, | 155 | ATH9K_ANI_RSSI_THR_LOW, |
156 | ATH9K_ANI_RSSI_THR_HIGH); | 156 | ATH9K_ANI_RSSI_THR_HIGH); |
157 | 157 | ||
158 | if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_OFDM_DEF_LEVEL) | ||
159 | immunityLevel = ATH9K_ANI_OFDM_DEF_LEVEL; | ||
160 | |||
158 | if (!scan) | 161 | if (!scan) |
159 | aniState->ofdmNoiseImmunityLevel = immunityLevel; | 162 | aniState->ofdmNoiseImmunityLevel = immunityLevel; |
160 | 163 | ||
@@ -235,6 +238,9 @@ static void ath9k_hw_set_cck_nil(struct ath_hw *ah, u_int8_t immunityLevel, | |||
235 | BEACON_RSSI(ah), ATH9K_ANI_RSSI_THR_LOW, | 238 | BEACON_RSSI(ah), ATH9K_ANI_RSSI_THR_LOW, |
236 | ATH9K_ANI_RSSI_THR_HIGH); | 239 | ATH9K_ANI_RSSI_THR_HIGH); |
237 | 240 | ||
241 | if (AR_SREV_9100(ah) && immunityLevel < ATH9K_ANI_CCK_DEF_LEVEL) | ||
242 | immunityLevel = ATH9K_ANI_CCK_DEF_LEVEL; | ||
243 | |||
238 | if (ah->opmode == NL80211_IFTYPE_STATION && | 244 | if (ah->opmode == NL80211_IFTYPE_STATION && |
239 | BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_LOW && | 245 | BEACON_RSSI(ah) <= ATH9K_ANI_RSSI_THR_LOW && |
240 | immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI) | 246 | immunityLevel > ATH9K_ANI_CCK_MAX_LEVEL_LOW_RSSI) |
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h index 44d74495c4de..3ba03dde4215 100644 --- a/drivers/net/wireless/ath/ath9k/ath9k.h +++ b/drivers/net/wireless/ath/ath9k/ath9k.h | |||
@@ -251,7 +251,6 @@ struct ath_atx_tid { | |||
251 | 251 | ||
252 | s8 bar_index; | 252 | s8 bar_index; |
253 | bool sched; | 253 | bool sched; |
254 | bool paused; | ||
255 | bool active; | 254 | bool active; |
256 | }; | 255 | }; |
257 | 256 | ||
diff --git a/drivers/net/wireless/ath/ath9k/debug_sta.c b/drivers/net/wireless/ath/ath9k/debug_sta.c index d76e6e0120d2..ffca918ff16a 100644 --- a/drivers/net/wireless/ath/ath9k/debug_sta.c +++ b/drivers/net/wireless/ath/ath9k/debug_sta.c | |||
@@ -72,7 +72,7 @@ static ssize_t read_file_node_aggr(struct file *file, char __user *user_buf, | |||
72 | ath_txq_lock(sc, txq); | 72 | ath_txq_lock(sc, txq); |
73 | if (tid->active) { | 73 | if (tid->active) { |
74 | len += scnprintf(buf + len, size - len, | 74 | len += scnprintf(buf + len, size - len, |
75 | "%3d%11d%10d%10d%10d%10d%9d%6d%8d\n", | 75 | "%3d%11d%10d%10d%10d%10d%9d%6d\n", |
76 | tid->tidno, | 76 | tid->tidno, |
77 | tid->seq_start, | 77 | tid->seq_start, |
78 | tid->seq_next, | 78 | tid->seq_next, |
@@ -80,8 +80,7 @@ static ssize_t read_file_node_aggr(struct file *file, char __user *user_buf, | |||
80 | tid->baw_head, | 80 | tid->baw_head, |
81 | tid->baw_tail, | 81 | tid->baw_tail, |
82 | tid->bar_index, | 82 | tid->bar_index, |
83 | tid->sched, | 83 | tid->sched); |
84 | tid->paused); | ||
85 | } | 84 | } |
86 | ath_txq_unlock(sc, txq); | 85 | ath_txq_unlock(sc, txq); |
87 | } | 86 | } |
diff --git a/drivers/net/wireless/ath/ath9k/init.c b/drivers/net/wireless/ath/ath9k/init.c index cbbb02a6b13b..36ae6490e554 100644 --- a/drivers/net/wireless/ath/ath9k/init.c +++ b/drivers/net/wireless/ath/ath9k/init.c | |||
@@ -783,6 +783,9 @@ int ath9k_init_device(u16 devid, struct ath_softc *sc, | |||
783 | common = ath9k_hw_common(ah); | 783 | common = ath9k_hw_common(ah); |
784 | ath9k_set_hw_capab(sc, hw); | 784 | ath9k_set_hw_capab(sc, hw); |
785 | 785 | ||
786 | /* Will be cleared in ath9k_start() */ | ||
787 | set_bit(ATH_OP_INVALID, &common->op_flags); | ||
788 | |||
786 | /* Initialize regulatory */ | 789 | /* Initialize regulatory */ |
787 | error = ath_regd_init(&common->regulatory, sc->hw->wiphy, | 790 | error = ath_regd_init(&common->regulatory, sc->hw->wiphy, |
788 | ath9k_reg_notifier); | 791 | ath9k_reg_notifier); |
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c index 25304adece57..914dbc6b1720 100644 --- a/drivers/net/wireless/ath/ath9k/pci.c +++ b/drivers/net/wireless/ath/ath9k/pci.c | |||
@@ -784,7 +784,6 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
784 | { | 784 | { |
785 | struct ath_softc *sc; | 785 | struct ath_softc *sc; |
786 | struct ieee80211_hw *hw; | 786 | struct ieee80211_hw *hw; |
787 | struct ath_common *common; | ||
788 | u8 csz; | 787 | u8 csz; |
789 | u32 val; | 788 | u32 val; |
790 | int ret = 0; | 789 | int ret = 0; |
@@ -877,10 +876,6 @@ static int ath_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
877 | wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", | 876 | wiphy_info(hw->wiphy, "%s mem=0x%lx, irq=%d\n", |
878 | hw_name, (unsigned long)sc->mem, pdev->irq); | 877 | hw_name, (unsigned long)sc->mem, pdev->irq); |
879 | 878 | ||
880 | /* Will be cleared in ath9k_start() */ | ||
881 | common = ath9k_hw_common(sc->sc_ah); | ||
882 | set_bit(ATH_OP_INVALID, &common->op_flags); | ||
883 | |||
884 | return 0; | 879 | return 0; |
885 | 880 | ||
886 | err_init: | 881 | err_init: |
diff --git a/drivers/net/wireless/ath/ath9k/recv.c b/drivers/net/wireless/ath/ath9k/recv.c index 6c9accdb52e4..19df969ec909 100644 --- a/drivers/net/wireless/ath/ath9k/recv.c +++ b/drivers/net/wireless/ath/ath9k/recv.c | |||
@@ -975,6 +975,7 @@ int ath_rx_tasklet(struct ath_softc *sc, int flush, bool hp) | |||
975 | u64 tsf = 0; | 975 | u64 tsf = 0; |
976 | unsigned long flags; | 976 | unsigned long flags; |
977 | dma_addr_t new_buf_addr; | 977 | dma_addr_t new_buf_addr; |
978 | unsigned int budget = 512; | ||
978 | 979 | ||
979 | if (edma) | 980 | if (edma) |
980 | dma_type = DMA_BIDIRECTIONAL; | 981 | dma_type = DMA_BIDIRECTIONAL; |
@@ -1113,15 +1114,17 @@ requeue_drop_frag: | |||
1113 | } | 1114 | } |
1114 | requeue: | 1115 | requeue: |
1115 | list_add_tail(&bf->list, &sc->rx.rxbuf); | 1116 | list_add_tail(&bf->list, &sc->rx.rxbuf); |
1116 | if (flush) | ||
1117 | continue; | ||
1118 | 1117 | ||
1119 | if (edma) { | 1118 | if (edma) { |
1120 | ath_rx_edma_buf_link(sc, qtype); | 1119 | ath_rx_edma_buf_link(sc, qtype); |
1121 | } else { | 1120 | } else { |
1122 | ath_rx_buf_relink(sc, bf); | 1121 | ath_rx_buf_relink(sc, bf); |
1123 | ath9k_hw_rxena(ah); | 1122 | if (!flush) |
1123 | ath9k_hw_rxena(ah); | ||
1124 | } | 1124 | } |
1125 | |||
1126 | if (!budget--) | ||
1127 | break; | ||
1125 | } while (1); | 1128 | } while (1); |
1126 | 1129 | ||
1127 | if (!(ah->imask & ATH9K_INT_RXEOL)) { | 1130 | if (!(ah->imask & ATH9K_INT_RXEOL)) { |
diff --git a/drivers/net/wireless/ath/ath9k/xmit.c b/drivers/net/wireless/ath/ath9k/xmit.c index 87cbec47fb48..66acb2cbd9df 100644 --- a/drivers/net/wireless/ath/ath9k/xmit.c +++ b/drivers/net/wireless/ath/ath9k/xmit.c | |||
@@ -107,9 +107,6 @@ static void ath_tx_queue_tid(struct ath_txq *txq, struct ath_atx_tid *tid) | |||
107 | { | 107 | { |
108 | struct ath_atx_ac *ac = tid->ac; | 108 | struct ath_atx_ac *ac = tid->ac; |
109 | 109 | ||
110 | if (tid->paused) | ||
111 | return; | ||
112 | |||
113 | if (tid->sched) | 110 | if (tid->sched) |
114 | return; | 111 | return; |
115 | 112 | ||
@@ -1407,7 +1404,6 @@ int ath_tx_aggr_start(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
1407 | ath_tx_tid_change_state(sc, txtid); | 1404 | ath_tx_tid_change_state(sc, txtid); |
1408 | 1405 | ||
1409 | txtid->active = true; | 1406 | txtid->active = true; |
1410 | txtid->paused = true; | ||
1411 | *ssn = txtid->seq_start = txtid->seq_next; | 1407 | *ssn = txtid->seq_start = txtid->seq_next; |
1412 | txtid->bar_index = -1; | 1408 | txtid->bar_index = -1; |
1413 | 1409 | ||
@@ -1427,7 +1423,6 @@ void ath_tx_aggr_stop(struct ath_softc *sc, struct ieee80211_sta *sta, u16 tid) | |||
1427 | 1423 | ||
1428 | ath_txq_lock(sc, txq); | 1424 | ath_txq_lock(sc, txq); |
1429 | txtid->active = false; | 1425 | txtid->active = false; |
1430 | txtid->paused = false; | ||
1431 | ath_tx_flush_tid(sc, txtid); | 1426 | ath_tx_flush_tid(sc, txtid); |
1432 | ath_tx_tid_change_state(sc, txtid); | 1427 | ath_tx_tid_change_state(sc, txtid); |
1433 | ath_txq_unlock_complete(sc, txq); | 1428 | ath_txq_unlock_complete(sc, txq); |
@@ -1487,7 +1482,7 @@ void ath_tx_aggr_wakeup(struct ath_softc *sc, struct ath_node *an) | |||
1487 | ath_txq_lock(sc, txq); | 1482 | ath_txq_lock(sc, txq); |
1488 | ac->clear_ps_filter = true; | 1483 | ac->clear_ps_filter = true; |
1489 | 1484 | ||
1490 | if (!tid->paused && ath_tid_has_buffered(tid)) { | 1485 | if (ath_tid_has_buffered(tid)) { |
1491 | ath_tx_queue_tid(txq, tid); | 1486 | ath_tx_queue_tid(txq, tid); |
1492 | ath_txq_schedule(sc, txq); | 1487 | ath_txq_schedule(sc, txq); |
1493 | } | 1488 | } |
@@ -1510,7 +1505,6 @@ void ath_tx_aggr_resume(struct ath_softc *sc, struct ieee80211_sta *sta, | |||
1510 | ath_txq_lock(sc, txq); | 1505 | ath_txq_lock(sc, txq); |
1511 | 1506 | ||
1512 | tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; | 1507 | tid->baw_size = IEEE80211_MIN_AMPDU_BUF << sta->ht_cap.ampdu_factor; |
1513 | tid->paused = false; | ||
1514 | 1508 | ||
1515 | if (ath_tid_has_buffered(tid)) { | 1509 | if (ath_tid_has_buffered(tid)) { |
1516 | ath_tx_queue_tid(txq, tid); | 1510 | ath_tx_queue_tid(txq, tid); |
@@ -1544,8 +1538,6 @@ void ath9k_release_buffered_frames(struct ieee80211_hw *hw, | |||
1544 | continue; | 1538 | continue; |
1545 | 1539 | ||
1546 | tid = ATH_AN_2_TID(an, i); | 1540 | tid = ATH_AN_2_TID(an, i); |
1547 | if (tid->paused) | ||
1548 | continue; | ||
1549 | 1541 | ||
1550 | ath_txq_lock(sc, tid->ac->txq); | 1542 | ath_txq_lock(sc, tid->ac->txq); |
1551 | while (nframes > 0) { | 1543 | while (nframes > 0) { |
@@ -1844,9 +1836,6 @@ void ath_txq_schedule(struct ath_softc *sc, struct ath_txq *txq) | |||
1844 | list_del(&tid->list); | 1836 | list_del(&tid->list); |
1845 | tid->sched = false; | 1837 | tid->sched = false; |
1846 | 1838 | ||
1847 | if (tid->paused) | ||
1848 | continue; | ||
1849 | |||
1850 | if (ath_tx_sched_aggr(sc, txq, tid, &stop)) | 1839 | if (ath_tx_sched_aggr(sc, txq, tid, &stop)) |
1851 | sent = true; | 1840 | sent = true; |
1852 | 1841 | ||
@@ -2698,7 +2687,6 @@ void ath_tx_node_init(struct ath_softc *sc, struct ath_node *an) | |||
2698 | tid->baw_size = WME_MAX_BA; | 2687 | tid->baw_size = WME_MAX_BA; |
2699 | tid->baw_head = tid->baw_tail = 0; | 2688 | tid->baw_head = tid->baw_tail = 0; |
2700 | tid->sched = false; | 2689 | tid->sched = false; |
2701 | tid->paused = false; | ||
2702 | tid->active = false; | 2690 | tid->active = false; |
2703 | __skb_queue_head_init(&tid->buf_q); | 2691 | __skb_queue_head_init(&tid->buf_q); |
2704 | __skb_queue_head_init(&tid->retry_q); | 2692 | __skb_queue_head_init(&tid->retry_q); |
diff --git a/drivers/net/wireless/brcm80211/brcmfmac/chip.c b/drivers/net/wireless/brcm80211/brcmfmac/chip.c index df130ef53d1c..c7c9f15c0fe0 100644 --- a/drivers/net/wireless/brcm80211/brcmfmac/chip.c +++ b/drivers/net/wireless/brcm80211/brcmfmac/chip.c | |||
@@ -303,10 +303,10 @@ static void brcmf_chip_ai_coredisable(struct brcmf_core_priv *core, | |||
303 | 303 | ||
304 | ci = core->chip; | 304 | ci = core->chip; |
305 | 305 | ||
306 | /* if core is already in reset, just return */ | 306 | /* if core is already in reset, skip reset */ |
307 | regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL); | 307 | regdata = ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL); |
308 | if ((regdata & BCMA_RESET_CTL_RESET) != 0) | 308 | if ((regdata & BCMA_RESET_CTL_RESET) != 0) |
309 | return; | 309 | goto in_reset_configure; |
310 | 310 | ||
311 | /* configure reset */ | 311 | /* configure reset */ |
312 | ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL, | 312 | ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL, |
@@ -322,6 +322,7 @@ static void brcmf_chip_ai_coredisable(struct brcmf_core_priv *core, | |||
322 | SPINWAIT(ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) != | 322 | SPINWAIT(ci->ops->read32(ci->ctx, core->wrapbase + BCMA_RESET_CTL) != |
323 | BCMA_RESET_CTL_RESET, 300); | 323 | BCMA_RESET_CTL_RESET, 300); |
324 | 324 | ||
325 | in_reset_configure: | ||
325 | /* in-reset configure */ | 326 | /* in-reset configure */ |
326 | ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL, | 327 | ci->ops->write32(ci->ctx, core->wrapbase + BCMA_IOCTL, |
327 | reset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK); | 328 | reset | BCMA_IOCTL_FGC | BCMA_IOCTL_CLK); |
diff --git a/drivers/net/wireless/rt2x00/rt2x00mac.c b/drivers/net/wireless/rt2x00/rt2x00mac.c index ddeb5a709aa3..a87ee9b6585a 100644 --- a/drivers/net/wireless/rt2x00/rt2x00mac.c +++ b/drivers/net/wireless/rt2x00/rt2x00mac.c | |||
@@ -621,20 +621,18 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, | |||
621 | bss_conf->bssid); | 621 | bss_conf->bssid); |
622 | 622 | ||
623 | /* | 623 | /* |
624 | * Update the beacon. This is only required on USB devices. PCI | ||
625 | * devices fetch beacons periodically. | ||
626 | */ | ||
627 | if (changes & BSS_CHANGED_BEACON && rt2x00_is_usb(rt2x00dev)) | ||
628 | rt2x00queue_update_beacon(rt2x00dev, vif); | ||
629 | |||
630 | /* | ||
631 | * Start/stop beaconing. | 624 | * Start/stop beaconing. |
632 | */ | 625 | */ |
633 | if (changes & BSS_CHANGED_BEACON_ENABLED) { | 626 | if (changes & BSS_CHANGED_BEACON_ENABLED) { |
634 | if (!bss_conf->enable_beacon && intf->enable_beacon) { | 627 | if (!bss_conf->enable_beacon && intf->enable_beacon) { |
635 | rt2x00queue_clear_beacon(rt2x00dev, vif); | ||
636 | rt2x00dev->intf_beaconing--; | 628 | rt2x00dev->intf_beaconing--; |
637 | intf->enable_beacon = false; | 629 | intf->enable_beacon = false; |
630 | /* | ||
631 | * Clear beacon in the H/W for this vif. This is needed | ||
632 | * to disable beaconing on this particular interface | ||
633 | * and keep it running on other interfaces. | ||
634 | */ | ||
635 | rt2x00queue_clear_beacon(rt2x00dev, vif); | ||
638 | 636 | ||
639 | if (rt2x00dev->intf_beaconing == 0) { | 637 | if (rt2x00dev->intf_beaconing == 0) { |
640 | /* | 638 | /* |
@@ -645,11 +643,15 @@ void rt2x00mac_bss_info_changed(struct ieee80211_hw *hw, | |||
645 | rt2x00queue_stop_queue(rt2x00dev->bcn); | 643 | rt2x00queue_stop_queue(rt2x00dev->bcn); |
646 | mutex_unlock(&intf->beacon_skb_mutex); | 644 | mutex_unlock(&intf->beacon_skb_mutex); |
647 | } | 645 | } |
648 | |||
649 | |||
650 | } else if (bss_conf->enable_beacon && !intf->enable_beacon) { | 646 | } else if (bss_conf->enable_beacon && !intf->enable_beacon) { |
651 | rt2x00dev->intf_beaconing++; | 647 | rt2x00dev->intf_beaconing++; |
652 | intf->enable_beacon = true; | 648 | intf->enable_beacon = true; |
649 | /* | ||
650 | * Upload beacon to the H/W. This is only required on | ||
651 | * USB devices. PCI devices fetch beacons periodically. | ||
652 | */ | ||
653 | if (rt2x00_is_usb(rt2x00dev)) | ||
654 | rt2x00queue_update_beacon(rt2x00dev, vif); | ||
653 | 655 | ||
654 | if (rt2x00dev->intf_beaconing == 1) { | 656 | if (rt2x00dev->intf_beaconing == 1) { |
655 | /* | 657 | /* |
diff --git a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c index 06ef47cd6203..5b4c225396f2 100644 --- a/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8188ee/trx.c | |||
@@ -293,7 +293,7 @@ static void _rtl88ee_translate_rx_signal_stuff(struct ieee80211_hw *hw, | |||
293 | u8 *psaddr; | 293 | u8 *psaddr; |
294 | __le16 fc; | 294 | __le16 fc; |
295 | u16 type, ufc; | 295 | u16 type, ufc; |
296 | bool match_bssid, packet_toself, packet_beacon, addr; | 296 | bool match_bssid, packet_toself, packet_beacon = false, addr; |
297 | 297 | ||
298 | tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift; | 298 | tmp_buf = skb->data + pstatus->rx_drvinfo_size + pstatus->rx_bufshift; |
299 | 299 | ||
diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c index 68b5c7e92cfb..07cb06da6729 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c +++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c | |||
@@ -1001,7 +1001,7 @@ int rtl92cu_hw_init(struct ieee80211_hw *hw) | |||
1001 | err = _rtl92cu_init_mac(hw); | 1001 | err = _rtl92cu_init_mac(hw); |
1002 | if (err) { | 1002 | if (err) { |
1003 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "init mac failed!\n"); | 1003 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "init mac failed!\n"); |
1004 | return err; | 1004 | goto exit; |
1005 | } | 1005 | } |
1006 | err = rtl92c_download_fw(hw); | 1006 | err = rtl92c_download_fw(hw); |
1007 | if (err) { | 1007 | if (err) { |
diff --git a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c index 36b48be8329c..2b3c78baa9f8 100644 --- a/drivers/net/wireless/rtlwifi/rtl8192se/trx.c +++ b/drivers/net/wireless/rtlwifi/rtl8192se/trx.c | |||
@@ -49,6 +49,12 @@ static u8 _rtl92se_map_hwqueue_to_fwqueue(struct sk_buff *skb, u8 skb_queue) | |||
49 | if (ieee80211_is_nullfunc(fc)) | 49 | if (ieee80211_is_nullfunc(fc)) |
50 | return QSLT_HIGH; | 50 | return QSLT_HIGH; |
51 | 51 | ||
52 | /* Kernel commit 1bf4bbb4024dcdab changed EAPOL packets to use | ||
53 | * queue V0 at priority 7; however, the RTL8192SE appears to have | ||
54 | * that queue at priority 6 | ||
55 | */ | ||
56 | if (skb->priority == 7) | ||
57 | return QSLT_VO; | ||
52 | return skb->priority; | 58 | return skb->priority; |
53 | } | 59 | } |
54 | 60 | ||
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index bd47fbc53dc9..e8376d646d98 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -206,12 +206,13 @@ static struct platform_device *of_platform_device_create_pdata( | |||
206 | { | 206 | { |
207 | struct platform_device *dev; | 207 | struct platform_device *dev; |
208 | 208 | ||
209 | if (!of_device_is_available(np)) | 209 | if (!of_device_is_available(np) || |
210 | of_node_test_and_set_flag(np, OF_POPULATED)) | ||
210 | return NULL; | 211 | return NULL; |
211 | 212 | ||
212 | dev = of_device_alloc(np, bus_id, parent); | 213 | dev = of_device_alloc(np, bus_id, parent); |
213 | if (!dev) | 214 | if (!dev) |
214 | return NULL; | 215 | goto err_clear_flag; |
215 | 216 | ||
216 | #if defined(CONFIG_MICROBLAZE) | 217 | #if defined(CONFIG_MICROBLAZE) |
217 | dev->archdata.dma_mask = 0xffffffffUL; | 218 | dev->archdata.dma_mask = 0xffffffffUL; |
@@ -229,10 +230,14 @@ static struct platform_device *of_platform_device_create_pdata( | |||
229 | 230 | ||
230 | if (of_device_add(dev) != 0) { | 231 | if (of_device_add(dev) != 0) { |
231 | platform_device_put(dev); | 232 | platform_device_put(dev); |
232 | return NULL; | 233 | goto err_clear_flag; |
233 | } | 234 | } |
234 | 235 | ||
235 | return dev; | 236 | return dev; |
237 | |||
238 | err_clear_flag: | ||
239 | of_node_clear_flag(np, OF_POPULATED); | ||
240 | return NULL; | ||
236 | } | 241 | } |
237 | 242 | ||
238 | /** | 243 | /** |
@@ -264,14 +269,15 @@ static struct amba_device *of_amba_device_create(struct device_node *node, | |||
264 | 269 | ||
265 | pr_debug("Creating amba device %s\n", node->full_name); | 270 | pr_debug("Creating amba device %s\n", node->full_name); |
266 | 271 | ||
267 | if (!of_device_is_available(node)) | 272 | if (!of_device_is_available(node) || |
273 | of_node_test_and_set_flag(node, OF_POPULATED)) | ||
268 | return NULL; | 274 | return NULL; |
269 | 275 | ||
270 | dev = amba_device_alloc(NULL, 0, 0); | 276 | dev = amba_device_alloc(NULL, 0, 0); |
271 | if (!dev) { | 277 | if (!dev) { |
272 | pr_err("%s(): amba_device_alloc() failed for %s\n", | 278 | pr_err("%s(): amba_device_alloc() failed for %s\n", |
273 | __func__, node->full_name); | 279 | __func__, node->full_name); |
274 | return NULL; | 280 | goto err_clear_flag; |
275 | } | 281 | } |
276 | 282 | ||
277 | /* setup generic device info */ | 283 | /* setup generic device info */ |
@@ -311,6 +317,8 @@ static struct amba_device *of_amba_device_create(struct device_node *node, | |||
311 | 317 | ||
312 | err_free: | 318 | err_free: |
313 | amba_device_put(dev); | 319 | amba_device_put(dev); |
320 | err_clear_flag: | ||
321 | of_node_clear_flag(node, OF_POPULATED); | ||
314 | return NULL; | 322 | return NULL; |
315 | } | 323 | } |
316 | #else /* CONFIG_ARM_AMBA */ | 324 | #else /* CONFIG_ARM_AMBA */ |
@@ -487,4 +495,60 @@ int of_platform_populate(struct device_node *root, | |||
487 | return rc; | 495 | return rc; |
488 | } | 496 | } |
489 | EXPORT_SYMBOL_GPL(of_platform_populate); | 497 | EXPORT_SYMBOL_GPL(of_platform_populate); |
498 | |||
499 | static int of_platform_device_destroy(struct device *dev, void *data) | ||
500 | { | ||
501 | bool *children_left = data; | ||
502 | |||
503 | /* Do not touch devices not populated from the device tree */ | ||
504 | if (!dev->of_node || !of_node_check_flag(dev->of_node, OF_POPULATED)) { | ||
505 | *children_left = true; | ||
506 | return 0; | ||
507 | } | ||
508 | |||
509 | /* Recurse, but don't touch this device if it has any children left */ | ||
510 | if (of_platform_depopulate(dev) != 0) { | ||
511 | *children_left = true; | ||
512 | return 0; | ||
513 | } | ||
514 | |||
515 | if (dev->bus == &platform_bus_type) | ||
516 | platform_device_unregister(to_platform_device(dev)); | ||
517 | #ifdef CONFIG_ARM_AMBA | ||
518 | else if (dev->bus == &amba_bustype) | ||
519 | amba_device_unregister(to_amba_device(dev)); | ||
520 | #endif | ||
521 | else { | ||
522 | *children_left = true; | ||
523 | return 0; | ||
524 | } | ||
525 | |||
526 | of_node_clear_flag(dev->of_node, OF_POPULATED); | ||
527 | |||
528 | return 0; | ||
529 | } | ||
530 | |||
531 | /** | ||
532 | * of_platform_depopulate() - Remove devices populated from device tree | ||
533 | * @parent: device which childred will be removed | ||
534 | * | ||
535 | * Complementary to of_platform_populate(), this function removes children | ||
536 | * of the given device (and, recurrently, their children) that have been | ||
537 | * created from their respective device tree nodes (and only those, | ||
538 | * leaving others - eg. manually created - unharmed). | ||
539 | * | ||
540 | * Returns 0 when all children devices have been removed or | ||
541 | * -EBUSY when some children remained. | ||
542 | */ | ||
543 | int of_platform_depopulate(struct device *parent) | ||
544 | { | ||
545 | bool children_left = false; | ||
546 | |||
547 | device_for_each_child(parent, &children_left, | ||
548 | of_platform_device_destroy); | ||
549 | |||
550 | return children_left ? -EBUSY : 0; | ||
551 | } | ||
552 | EXPORT_SYMBOL_GPL(of_platform_depopulate); | ||
553 | |||
490 | #endif /* CONFIG_OF_ADDRESS */ | 554 | #endif /* CONFIG_OF_ADDRESS */ |
diff --git a/drivers/pnp/pnpbios/bioscalls.c b/drivers/pnp/pnpbios/bioscalls.c index deb7f4bcdb7b..438d4c72c7b3 100644 --- a/drivers/pnp/pnpbios/bioscalls.c +++ b/drivers/pnp/pnpbios/bioscalls.c | |||
@@ -37,7 +37,7 @@ __visible struct { | |||
37 | * kernel begins at offset 3GB... | 37 | * kernel begins at offset 3GB... |
38 | */ | 38 | */ |
39 | 39 | ||
40 | asmlinkage void pnp_bios_callfunc(void); | 40 | asmlinkage __visible void pnp_bios_callfunc(void); |
41 | 41 | ||
42 | __asm__(".text \n" | 42 | __asm__(".text \n" |
43 | __ALIGN_STR "\n" | 43 | __ALIGN_STR "\n" |
diff --git a/drivers/power/reset/vexpress-poweroff.c b/drivers/power/reset/vexpress-poweroff.c index b95cf71ed695..4dc102e2b230 100644 --- a/drivers/power/reset/vexpress-poweroff.c +++ b/drivers/power/reset/vexpress-poweroff.c | |||
@@ -23,10 +23,10 @@ | |||
23 | static void vexpress_reset_do(struct device *dev, const char *what) | 23 | static void vexpress_reset_do(struct device *dev, const char *what) |
24 | { | 24 | { |
25 | int err = -ENOENT; | 25 | int err = -ENOENT; |
26 | struct vexpress_config_func *func = dev_get_drvdata(dev); | 26 | struct regmap *reg = dev_get_drvdata(dev); |
27 | 27 | ||
28 | if (func) { | 28 | if (reg) { |
29 | err = vexpress_config_write(func, 0, 0); | 29 | err = regmap_write(reg, 0, 0); |
30 | if (!err) | 30 | if (!err) |
31 | mdelay(1000); | 31 | mdelay(1000); |
32 | } | 32 | } |
@@ -91,17 +91,17 @@ static int vexpress_reset_probe(struct platform_device *pdev) | |||
91 | enum vexpress_reset_func func; | 91 | enum vexpress_reset_func func; |
92 | const struct of_device_id *match = | 92 | const struct of_device_id *match = |
93 | of_match_device(vexpress_reset_of_match, &pdev->dev); | 93 | of_match_device(vexpress_reset_of_match, &pdev->dev); |
94 | struct vexpress_config_func *config_func; | 94 | struct regmap *regmap; |
95 | 95 | ||
96 | if (match) | 96 | if (match) |
97 | func = (enum vexpress_reset_func)match->data; | 97 | func = (enum vexpress_reset_func)match->data; |
98 | else | 98 | else |
99 | func = pdev->id_entry->driver_data; | 99 | func = pdev->id_entry->driver_data; |
100 | 100 | ||
101 | config_func = vexpress_config_func_get_by_dev(&pdev->dev); | 101 | regmap = devm_regmap_init_vexpress_config(&pdev->dev); |
102 | if (!config_func) | 102 | if (IS_ERR(regmap)) |
103 | return -EINVAL; | 103 | return PTR_ERR(regmap); |
104 | dev_set_drvdata(&pdev->dev, config_func); | 104 | dev_set_drvdata(&pdev->dev, regmap); |
105 | 105 | ||
106 | switch (func) { | 106 | switch (func) { |
107 | case FUNC_SHUTDOWN: | 107 | case FUNC_SHUTDOWN: |
diff --git a/drivers/regulator/vexpress.c b/drivers/regulator/vexpress.c index f3ae28a7e663..2863428813e4 100644 --- a/drivers/regulator/vexpress.c +++ b/drivers/regulator/vexpress.c | |||
@@ -26,14 +26,14 @@ | |||
26 | struct vexpress_regulator { | 26 | struct vexpress_regulator { |
27 | struct regulator_desc desc; | 27 | struct regulator_desc desc; |
28 | struct regulator_dev *regdev; | 28 | struct regulator_dev *regdev; |
29 | struct vexpress_config_func *func; | 29 | struct regmap *regmap; |
30 | }; | 30 | }; |
31 | 31 | ||
32 | static int vexpress_regulator_get_voltage(struct regulator_dev *regdev) | 32 | static int vexpress_regulator_get_voltage(struct regulator_dev *regdev) |
33 | { | 33 | { |
34 | struct vexpress_regulator *reg = rdev_get_drvdata(regdev); | 34 | struct vexpress_regulator *reg = rdev_get_drvdata(regdev); |
35 | u32 uV; | 35 | u32 uV; |
36 | int err = vexpress_config_read(reg->func, 0, &uV); | 36 | int err = regmap_read(reg->regmap, 0, &uV); |
37 | 37 | ||
38 | return err ? err : uV; | 38 | return err ? err : uV; |
39 | } | 39 | } |
@@ -43,7 +43,7 @@ static int vexpress_regulator_set_voltage(struct regulator_dev *regdev, | |||
43 | { | 43 | { |
44 | struct vexpress_regulator *reg = rdev_get_drvdata(regdev); | 44 | struct vexpress_regulator *reg = rdev_get_drvdata(regdev); |
45 | 45 | ||
46 | return vexpress_config_write(reg->func, 0, min_uV); | 46 | return regmap_write(reg->regmap, 0, min_uV); |
47 | } | 47 | } |
48 | 48 | ||
49 | static struct regulator_ops vexpress_regulator_ops_ro = { | 49 | static struct regulator_ops vexpress_regulator_ops_ro = { |
@@ -57,22 +57,17 @@ static struct regulator_ops vexpress_regulator_ops = { | |||
57 | 57 | ||
58 | static int vexpress_regulator_probe(struct platform_device *pdev) | 58 | static int vexpress_regulator_probe(struct platform_device *pdev) |
59 | { | 59 | { |
60 | int err; | ||
61 | struct vexpress_regulator *reg; | 60 | struct vexpress_regulator *reg; |
62 | struct regulator_init_data *init_data; | 61 | struct regulator_init_data *init_data; |
63 | struct regulator_config config = { }; | 62 | struct regulator_config config = { }; |
64 | 63 | ||
65 | reg = devm_kzalloc(&pdev->dev, sizeof(*reg), GFP_KERNEL); | 64 | reg = devm_kzalloc(&pdev->dev, sizeof(*reg), GFP_KERNEL); |
66 | if (!reg) { | 65 | if (!reg) |
67 | err = -ENOMEM; | 66 | return -ENOMEM; |
68 | goto error_kzalloc; | ||
69 | } | ||
70 | 67 | ||
71 | reg->func = vexpress_config_func_get_by_dev(&pdev->dev); | 68 | reg->regmap = devm_regmap_init_vexpress_config(&pdev->dev); |
72 | if (!reg->func) { | 69 | if (IS_ERR(reg->regmap)) |
73 | err = -ENXIO; | 70 | return PTR_ERR(reg->regmap); |
74 | goto error_get_func; | ||
75 | } | ||
76 | 71 | ||
77 | reg->desc.name = dev_name(&pdev->dev); | 72 | reg->desc.name = dev_name(&pdev->dev); |
78 | reg->desc.type = REGULATOR_VOLTAGE; | 73 | reg->desc.type = REGULATOR_VOLTAGE; |
@@ -80,10 +75,8 @@ static int vexpress_regulator_probe(struct platform_device *pdev) | |||
80 | reg->desc.continuous_voltage_range = true; | 75 | reg->desc.continuous_voltage_range = true; |
81 | 76 | ||
82 | init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); | 77 | init_data = of_get_regulator_init_data(&pdev->dev, pdev->dev.of_node); |
83 | if (!init_data) { | 78 | if (!init_data) |
84 | err = -EINVAL; | 79 | return -EINVAL; |
85 | goto error_get_regulator_init_data; | ||
86 | } | ||
87 | 80 | ||
88 | init_data->constraints.apply_uV = 0; | 81 | init_data->constraints.apply_uV = 0; |
89 | if (init_data->constraints.min_uV && init_data->constraints.max_uV) | 82 | if (init_data->constraints.min_uV && init_data->constraints.max_uV) |
@@ -97,30 +90,12 @@ static int vexpress_regulator_probe(struct platform_device *pdev) | |||
97 | config.of_node = pdev->dev.of_node; | 90 | config.of_node = pdev->dev.of_node; |
98 | 91 | ||
99 | reg->regdev = devm_regulator_register(&pdev->dev, ®->desc, &config); | 92 | reg->regdev = devm_regulator_register(&pdev->dev, ®->desc, &config); |
100 | if (IS_ERR(reg->regdev)) { | 93 | if (IS_ERR(reg->regdev)) |
101 | err = PTR_ERR(reg->regdev); | 94 | return PTR_ERR(reg->regdev); |
102 | goto error_regulator_register; | ||
103 | } | ||
104 | 95 | ||
105 | platform_set_drvdata(pdev, reg); | 96 | platform_set_drvdata(pdev, reg); |
106 | 97 | ||
107 | return 0; | 98 | return 0; |
108 | |||
109 | error_regulator_register: | ||
110 | error_get_regulator_init_data: | ||
111 | vexpress_config_func_put(reg->func); | ||
112 | error_get_func: | ||
113 | error_kzalloc: | ||
114 | return err; | ||
115 | } | ||
116 | |||
117 | static int vexpress_regulator_remove(struct platform_device *pdev) | ||
118 | { | ||
119 | struct vexpress_regulator *reg = platform_get_drvdata(pdev); | ||
120 | |||
121 | vexpress_config_func_put(reg->func); | ||
122 | |||
123 | return 0; | ||
124 | } | 99 | } |
125 | 100 | ||
126 | static struct of_device_id vexpress_regulator_of_match[] = { | 101 | static struct of_device_id vexpress_regulator_of_match[] = { |
@@ -130,7 +105,6 @@ static struct of_device_id vexpress_regulator_of_match[] = { | |||
130 | 105 | ||
131 | static struct platform_driver vexpress_regulator_driver = { | 106 | static struct platform_driver vexpress_regulator_driver = { |
132 | .probe = vexpress_regulator_probe, | 107 | .probe = vexpress_regulator_probe, |
133 | .remove = vexpress_regulator_remove, | ||
134 | .driver = { | 108 | .driver = { |
135 | .name = DRVNAME, | 109 | .name = DRVNAME, |
136 | .owner = THIS_MODULE, | 110 | .owner = THIS_MODULE, |
diff --git a/drivers/rtc/rtc-pcf8523.c b/drivers/rtc/rtc-pcf8523.c index 5c8f8226c848..4cdb64be061b 100644 --- a/drivers/rtc/rtc-pcf8523.c +++ b/drivers/rtc/rtc-pcf8523.c | |||
@@ -206,7 +206,7 @@ static int pcf8523_rtc_read_time(struct device *dev, struct rtc_time *tm) | |||
206 | tm->tm_hour = bcd2bin(regs[2] & 0x3f); | 206 | tm->tm_hour = bcd2bin(regs[2] & 0x3f); |
207 | tm->tm_mday = bcd2bin(regs[3] & 0x3f); | 207 | tm->tm_mday = bcd2bin(regs[3] & 0x3f); |
208 | tm->tm_wday = regs[4] & 0x7; | 208 | tm->tm_wday = regs[4] & 0x7; |
209 | tm->tm_mon = bcd2bin(regs[5] & 0x1f); | 209 | tm->tm_mon = bcd2bin(regs[5] & 0x1f) - 1; |
210 | tm->tm_year = bcd2bin(regs[6]) + 100; | 210 | tm->tm_year = bcd2bin(regs[6]) + 100; |
211 | 211 | ||
212 | return rtc_valid_tm(tm); | 212 | return rtc_valid_tm(tm); |
@@ -229,7 +229,7 @@ static int pcf8523_rtc_set_time(struct device *dev, struct rtc_time *tm) | |||
229 | regs[3] = bin2bcd(tm->tm_hour); | 229 | regs[3] = bin2bcd(tm->tm_hour); |
230 | regs[4] = bin2bcd(tm->tm_mday); | 230 | regs[4] = bin2bcd(tm->tm_mday); |
231 | regs[5] = tm->tm_wday; | 231 | regs[5] = tm->tm_wday; |
232 | regs[6] = bin2bcd(tm->tm_mon); | 232 | regs[6] = bin2bcd(tm->tm_mon + 1); |
233 | regs[7] = bin2bcd(tm->tm_year - 100); | 233 | regs[7] = bin2bcd(tm->tm_year - 100); |
234 | 234 | ||
235 | msg.addr = client->addr; | 235 | msg.addr = client->addr; |
diff --git a/drivers/scsi/scsi_netlink.c b/drivers/scsi/scsi_netlink.c index fe30ea94ffe6..109802f776ed 100644 --- a/drivers/scsi/scsi_netlink.c +++ b/drivers/scsi/scsi_netlink.c | |||
@@ -77,7 +77,7 @@ scsi_nl_rcv_msg(struct sk_buff *skb) | |||
77 | goto next_msg; | 77 | goto next_msg; |
78 | } | 78 | } |
79 | 79 | ||
80 | if (!capable(CAP_SYS_ADMIN)) { | 80 | if (!netlink_capable(skb, CAP_SYS_ADMIN)) { |
81 | err = -EPERM; | 81 | err = -EPERM; |
82 | goto next_msg; | 82 | goto next_msg; |
83 | } | 83 | } |
diff --git a/drivers/staging/iio/resolver/ad2s1200.c b/drivers/staging/iio/resolver/ad2s1200.c index e2b482045158..017d2f8379b7 100644 --- a/drivers/staging/iio/resolver/ad2s1200.c +++ b/drivers/staging/iio/resolver/ad2s1200.c | |||
@@ -107,7 +107,7 @@ static int ad2s1200_probe(struct spi_device *spi) | |||
107 | int pn, ret = 0; | 107 | int pn, ret = 0; |
108 | unsigned short *pins = spi->dev.platform_data; | 108 | unsigned short *pins = spi->dev.platform_data; |
109 | 109 | ||
110 | for (pn = 0; pn < AD2S1200_PN; pn++) | 110 | for (pn = 0; pn < AD2S1200_PN; pn++) { |
111 | ret = devm_gpio_request_one(&spi->dev, pins[pn], GPIOF_DIR_OUT, | 111 | ret = devm_gpio_request_one(&spi->dev, pins[pn], GPIOF_DIR_OUT, |
112 | DRV_NAME); | 112 | DRV_NAME); |
113 | if (ret) { | 113 | if (ret) { |
@@ -115,6 +115,7 @@ static int ad2s1200_probe(struct spi_device *spi) | |||
115 | pins[pn]); | 115 | pins[pn]); |
116 | return ret; | 116 | return ret; |
117 | } | 117 | } |
118 | } | ||
118 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); | 119 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); |
119 | if (!indio_dev) | 120 | if (!indio_dev) |
120 | return -ENOMEM; | 121 | return -ENOMEM; |
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 94f9e3a38412..0ff7fda0742f 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c | |||
@@ -190,7 +190,7 @@ static struct tty_driver *hvc_console_device(struct console *c, int *index) | |||
190 | return hvc_driver; | 190 | return hvc_driver; |
191 | } | 191 | } |
192 | 192 | ||
193 | static int __init hvc_console_setup(struct console *co, char *options) | 193 | static int hvc_console_setup(struct console *co, char *options) |
194 | { | 194 | { |
195 | if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES) | 195 | if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES) |
196 | return -ENODEV; | 196 | return -ENODEV; |
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index 41fe8a047d37..fe9d129c8735 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c | |||
@@ -2353,8 +2353,12 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, | |||
2353 | if (tty->ops->flush_chars) | 2353 | if (tty->ops->flush_chars) |
2354 | tty->ops->flush_chars(tty); | 2354 | tty->ops->flush_chars(tty); |
2355 | } else { | 2355 | } else { |
2356 | struct n_tty_data *ldata = tty->disc_data; | ||
2357 | |||
2356 | while (nr > 0) { | 2358 | while (nr > 0) { |
2359 | mutex_lock(&ldata->output_lock); | ||
2357 | c = tty->ops->write(tty, b, nr); | 2360 | c = tty->ops->write(tty, b, nr); |
2361 | mutex_unlock(&ldata->output_lock); | ||
2358 | if (c < 0) { | 2362 | if (c < 0) { |
2359 | retval = c; | 2363 | retval = c; |
2360 | goto break_out; | 2364 | goto break_out; |
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c index 0e1bf8858431..2d4bd3929e50 100644 --- a/drivers/tty/serial/8250/8250_core.c +++ b/drivers/tty/serial/8250/8250_core.c | |||
@@ -555,7 +555,7 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep) | |||
555 | */ | 555 | */ |
556 | if ((p->port.type == PORT_XR17V35X) || | 556 | if ((p->port.type == PORT_XR17V35X) || |
557 | (p->port.type == PORT_XR17D15X)) { | 557 | (p->port.type == PORT_XR17D15X)) { |
558 | serial_out(p, UART_EXAR_SLEEP, 0xff); | 558 | serial_out(p, UART_EXAR_SLEEP, sleep ? 0xff : 0); |
559 | return; | 559 | return; |
560 | } | 560 | } |
561 | 561 | ||
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c index f1d30f6945af..cf78d1985cd8 100644 --- a/drivers/tty/tty_buffer.c +++ b/drivers/tty/tty_buffer.c | |||
@@ -255,16 +255,15 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size, | |||
255 | if (change || left < size) { | 255 | if (change || left < size) { |
256 | /* This is the slow path - looking for new buffers to use */ | 256 | /* This is the slow path - looking for new buffers to use */ |
257 | if ((n = tty_buffer_alloc(port, size)) != NULL) { | 257 | if ((n = tty_buffer_alloc(port, size)) != NULL) { |
258 | unsigned long iflags; | ||
259 | |||
260 | n->flags = flags; | 258 | n->flags = flags; |
261 | buf->tail = n; | 259 | buf->tail = n; |
262 | |||
263 | spin_lock_irqsave(&buf->flush_lock, iflags); | ||
264 | b->commit = b->used; | 260 | b->commit = b->used; |
261 | /* paired w/ barrier in flush_to_ldisc(); ensures the | ||
262 | * latest commit value can be read before the head is | ||
263 | * advanced to the next buffer | ||
264 | */ | ||
265 | smp_wmb(); | ||
265 | b->next = n; | 266 | b->next = n; |
266 | spin_unlock_irqrestore(&buf->flush_lock, iflags); | ||
267 | |||
268 | } else if (change) | 267 | } else if (change) |
269 | size = 0; | 268 | size = 0; |
270 | else | 269 | else |
@@ -448,27 +447,28 @@ static void flush_to_ldisc(struct work_struct *work) | |||
448 | mutex_lock(&buf->lock); | 447 | mutex_lock(&buf->lock); |
449 | 448 | ||
450 | while (1) { | 449 | while (1) { |
451 | unsigned long flags; | ||
452 | struct tty_buffer *head = buf->head; | 450 | struct tty_buffer *head = buf->head; |
451 | struct tty_buffer *next; | ||
453 | int count; | 452 | int count; |
454 | 453 | ||
455 | /* Ldisc or user is trying to gain exclusive access */ | 454 | /* Ldisc or user is trying to gain exclusive access */ |
456 | if (atomic_read(&buf->priority)) | 455 | if (atomic_read(&buf->priority)) |
457 | break; | 456 | break; |
458 | 457 | ||
459 | spin_lock_irqsave(&buf->flush_lock, flags); | 458 | next = head->next; |
459 | /* paired w/ barrier in __tty_buffer_request_room(); | ||
460 | * ensures commit value read is not stale if the head | ||
461 | * is advancing to the next buffer | ||
462 | */ | ||
463 | smp_rmb(); | ||
460 | count = head->commit - head->read; | 464 | count = head->commit - head->read; |
461 | if (!count) { | 465 | if (!count) { |
462 | if (head->next == NULL) { | 466 | if (next == NULL) |
463 | spin_unlock_irqrestore(&buf->flush_lock, flags); | ||
464 | break; | 467 | break; |
465 | } | 468 | buf->head = next; |
466 | buf->head = head->next; | ||
467 | spin_unlock_irqrestore(&buf->flush_lock, flags); | ||
468 | tty_buffer_free(port, head); | 469 | tty_buffer_free(port, head); |
469 | continue; | 470 | continue; |
470 | } | 471 | } |
471 | spin_unlock_irqrestore(&buf->flush_lock, flags); | ||
472 | 472 | ||
473 | count = receive_buf(tty, head, count); | 473 | count = receive_buf(tty, head, count); |
474 | if (!count) | 474 | if (!count) |
@@ -523,7 +523,6 @@ void tty_buffer_init(struct tty_port *port) | |||
523 | struct tty_bufhead *buf = &port->buf; | 523 | struct tty_bufhead *buf = &port->buf; |
524 | 524 | ||
525 | mutex_init(&buf->lock); | 525 | mutex_init(&buf->lock); |
526 | spin_lock_init(&buf->flush_lock); | ||
527 | tty_buffer_reset(&buf->sentinel, 0); | 526 | tty_buffer_reset(&buf->sentinel, 0); |
528 | buf->head = &buf->sentinel; | 527 | buf->head = &buf->sentinel; |
529 | buf->tail = &buf->sentinel; | 528 | buf->tail = &buf->sentinel; |
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index f605ad8c1902..cfd18bcca723 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c | |||
@@ -1709,16 +1709,6 @@ static int at91udc_probe(struct platform_device *pdev) | |||
1709 | return -ENODEV; | 1709 | return -ENODEV; |
1710 | } | 1710 | } |
1711 | 1711 | ||
1712 | if (pdev->num_resources != 2) { | ||
1713 | DBG("invalid num_resources\n"); | ||
1714 | return -ENODEV; | ||
1715 | } | ||
1716 | if ((pdev->resource[0].flags != IORESOURCE_MEM) | ||
1717 | || (pdev->resource[1].flags != IORESOURCE_IRQ)) { | ||
1718 | DBG("invalid resource type\n"); | ||
1719 | return -ENODEV; | ||
1720 | } | ||
1721 | |||
1722 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1712 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1723 | if (!res) | 1713 | if (!res) |
1724 | return -ENXIO; | 1714 | return -ENXIO; |
diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index 6f2c8d3899d2..cf2734b532a7 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c | |||
@@ -248,7 +248,8 @@ static int ehci_fsl_setup_phy(struct usb_hcd *hcd, | |||
248 | break; | 248 | break; |
249 | } | 249 | } |
250 | 250 | ||
251 | if (pdata->have_sysif_regs && pdata->controller_ver && | 251 | if (pdata->have_sysif_regs && |
252 | pdata->controller_ver > FSL_USB_VER_1_6 && | ||
252 | (phy_mode == FSL_USB2_PHY_ULPI)) { | 253 | (phy_mode == FSL_USB2_PHY_ULPI)) { |
253 | /* check PHY_CLK_VALID to get phy clk valid */ | 254 | /* check PHY_CLK_VALID to get phy clk valid */ |
254 | if (!(spin_event_timeout(in_be32(non_ehci + FSL_SOC_USB_CTRL) & | 255 | if (!(spin_event_timeout(in_be32(non_ehci + FSL_SOC_USB_CTRL) & |
diff --git a/drivers/usb/host/ohci-hub.c b/drivers/usb/host/ohci-hub.c index c81c8721cc5a..cd871b895013 100644 --- a/drivers/usb/host/ohci-hub.c +++ b/drivers/usb/host/ohci-hub.c | |||
@@ -90,6 +90,24 @@ __acquires(ohci->lock) | |||
90 | dl_done_list (ohci); | 90 | dl_done_list (ohci); |
91 | finish_unlinks (ohci, ohci_frame_no(ohci)); | 91 | finish_unlinks (ohci, ohci_frame_no(ohci)); |
92 | 92 | ||
93 | /* | ||
94 | * Some controllers don't handle "global" suspend properly if | ||
95 | * there are unsuspended ports. For these controllers, put all | ||
96 | * the enabled ports into suspend before suspending the root hub. | ||
97 | */ | ||
98 | if (ohci->flags & OHCI_QUIRK_GLOBAL_SUSPEND) { | ||
99 | __hc32 __iomem *portstat = ohci->regs->roothub.portstatus; | ||
100 | int i; | ||
101 | unsigned temp; | ||
102 | |||
103 | for (i = 0; i < ohci->num_ports; (++i, ++portstat)) { | ||
104 | temp = ohci_readl(ohci, portstat); | ||
105 | if ((temp & (RH_PS_PES | RH_PS_PSS)) == | ||
106 | RH_PS_PES) | ||
107 | ohci_writel(ohci, RH_PS_PSS, portstat); | ||
108 | } | ||
109 | } | ||
110 | |||
93 | /* maybe resume can wake root hub */ | 111 | /* maybe resume can wake root hub */ |
94 | if (ohci_to_hcd(ohci)->self.root_hub->do_remote_wakeup || autostop) { | 112 | if (ohci_to_hcd(ohci)->self.root_hub->do_remote_wakeup || autostop) { |
95 | ohci->hc_control |= OHCI_CTRL_RWE; | 113 | ohci->hc_control |= OHCI_CTRL_RWE; |
diff --git a/drivers/usb/host/ohci-pci.c b/drivers/usb/host/ohci-pci.c index 90879e9ccbec..bb1509675727 100644 --- a/drivers/usb/host/ohci-pci.c +++ b/drivers/usb/host/ohci-pci.c | |||
@@ -160,6 +160,7 @@ static int ohci_quirk_amd700(struct usb_hcd *hcd) | |||
160 | ohci_dbg(ohci, "enabled AMD prefetch quirk\n"); | 160 | ohci_dbg(ohci, "enabled AMD prefetch quirk\n"); |
161 | } | 161 | } |
162 | 162 | ||
163 | ohci->flags |= OHCI_QUIRK_GLOBAL_SUSPEND; | ||
163 | return 0; | 164 | return 0; |
164 | } | 165 | } |
165 | 166 | ||
diff --git a/drivers/usb/host/ohci.h b/drivers/usb/host/ohci.h index 9250cada13f0..4550ce05af7f 100644 --- a/drivers/usb/host/ohci.h +++ b/drivers/usb/host/ohci.h | |||
@@ -405,6 +405,8 @@ struct ohci_hcd { | |||
405 | #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ | 405 | #define OHCI_QUIRK_HUB_POWER 0x100 /* distrust firmware power/oc setup */ |
406 | #define OHCI_QUIRK_AMD_PLL 0x200 /* AMD PLL quirk*/ | 406 | #define OHCI_QUIRK_AMD_PLL 0x200 /* AMD PLL quirk*/ |
407 | #define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ | 407 | #define OHCI_QUIRK_AMD_PREFETCH 0x400 /* pre-fetch for ISO transfer */ |
408 | #define OHCI_QUIRK_GLOBAL_SUSPEND 0x800 /* must suspend ports */ | ||
409 | |||
408 | // there are also chip quirks/bugs in init logic | 410 | // there are also chip quirks/bugs in init logic |
409 | 411 | ||
410 | struct work_struct nec_work; /* Worker for NEC quirk */ | 412 | struct work_struct nec_work; /* Worker for NEC quirk */ |
diff --git a/drivers/usb/phy/phy-fsm-usb.c b/drivers/usb/phy/phy-fsm-usb.c index c47e5a6edde2..d03fadd2629f 100644 --- a/drivers/usb/phy/phy-fsm-usb.c +++ b/drivers/usb/phy/phy-fsm-usb.c | |||
@@ -303,17 +303,18 @@ int otg_statemachine(struct otg_fsm *fsm) | |||
303 | otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE); | 303 | otg_set_state(fsm, OTG_STATE_A_WAIT_VRISE); |
304 | break; | 304 | break; |
305 | case OTG_STATE_A_WAIT_VRISE: | 305 | case OTG_STATE_A_WAIT_VRISE: |
306 | if (fsm->id || fsm->a_bus_drop || fsm->a_vbus_vld || | 306 | if (fsm->a_vbus_vld) |
307 | fsm->a_wait_vrise_tmout) { | ||
308 | otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); | 307 | otg_set_state(fsm, OTG_STATE_A_WAIT_BCON); |
309 | } | 308 | else if (fsm->id || fsm->a_bus_drop || |
309 | fsm->a_wait_vrise_tmout) | ||
310 | otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | ||
310 | break; | 311 | break; |
311 | case OTG_STATE_A_WAIT_BCON: | 312 | case OTG_STATE_A_WAIT_BCON: |
312 | if (!fsm->a_vbus_vld) | 313 | if (!fsm->a_vbus_vld) |
313 | otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); | 314 | otg_set_state(fsm, OTG_STATE_A_VBUS_ERR); |
314 | else if (fsm->b_conn) | 315 | else if (fsm->b_conn) |
315 | otg_set_state(fsm, OTG_STATE_A_HOST); | 316 | otg_set_state(fsm, OTG_STATE_A_HOST); |
316 | else if (fsm->id | fsm->a_bus_drop | fsm->a_wait_bcon_tmout) | 317 | else if (fsm->id || fsm->a_bus_drop || fsm->a_wait_bcon_tmout) |
317 | otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); | 318 | otg_set_state(fsm, OTG_STATE_A_WAIT_VFALL); |
318 | break; | 319 | break; |
319 | case OTG_STATE_A_HOST: | 320 | case OTG_STATE_A_HOST: |
diff --git a/drivers/usb/serial/qcserial.c b/drivers/usb/serial/qcserial.c index 7ed681a714a5..6c0a542e8ec1 100644 --- a/drivers/usb/serial/qcserial.c +++ b/drivers/usb/serial/qcserial.c | |||
@@ -151,6 +151,21 @@ static const struct usb_device_id id_table[] = { | |||
151 | {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 0)}, /* Netgear AirCard 340U Device Management */ | 151 | {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 0)}, /* Netgear AirCard 340U Device Management */ |
152 | {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 2)}, /* Netgear AirCard 340U NMEA */ | 152 | {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 2)}, /* Netgear AirCard 340U NMEA */ |
153 | {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 3)}, /* Netgear AirCard 340U Modem */ | 153 | {USB_DEVICE_INTERFACE_NUMBER(0x1199, 0x9051, 3)}, /* Netgear AirCard 340U Modem */ |
154 | {USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a2, 0)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card Device Management */ | ||
155 | {USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a2, 2)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card NMEA */ | ||
156 | {USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a2, 3)}, /* Dell Wireless 5806 Gobi(TM) 4G LTE Mobile Broadband Card Modem */ | ||
157 | {USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a3, 0)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card Device Management */ | ||
158 | {USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a3, 2)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card NMEA */ | ||
159 | {USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a3, 3)}, /* Dell Wireless 5570 HSPA+ (42Mbps) Mobile Broadband Card Modem */ | ||
160 | {USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a4, 0)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card Device Management */ | ||
161 | {USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a4, 2)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card NMEA */ | ||
162 | {USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a4, 3)}, /* Dell Wireless 5570e HSPA+ (42Mbps) Mobile Broadband Card Modem */ | ||
163 | {USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a8, 0)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card Device Management */ | ||
164 | {USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a8, 2)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card NMEA */ | ||
165 | {USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a8, 3)}, /* Dell Wireless 5808 Gobi(TM) 4G LTE Mobile Broadband Card Modem */ | ||
166 | {USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a9, 0)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card Device Management */ | ||
167 | {USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a9, 2)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card NMEA */ | ||
168 | {USB_DEVICE_INTERFACE_NUMBER(0x413c, 0x81a9, 3)}, /* Dell Wireless 5808e Gobi(TM) 4G LTE Mobile Broadband Card Modem */ | ||
154 | 169 | ||
155 | { } /* Terminating entry */ | 170 | { } /* Terminating entry */ |
156 | }; | 171 | }; |
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c index 4ef2a80728f7..008d805c3d21 100644 --- a/drivers/usb/storage/shuttle_usbat.c +++ b/drivers/usb/storage/shuttle_usbat.c | |||
@@ -1851,7 +1851,7 @@ static int usbat_probe(struct usb_interface *intf, | |||
1851 | us->transport_name = "Shuttle USBAT"; | 1851 | us->transport_name = "Shuttle USBAT"; |
1852 | us->transport = usbat_flash_transport; | 1852 | us->transport = usbat_flash_transport; |
1853 | us->transport_reset = usb_stor_CB_reset; | 1853 | us->transport_reset = usb_stor_CB_reset; |
1854 | us->max_lun = 1; | 1854 | us->max_lun = 0; |
1855 | 1855 | ||
1856 | result = usb_stor_probe2(us); | 1856 | result = usb_stor_probe2(us); |
1857 | return result; | 1857 | return result; |
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h index f4a82291894a..174a447868cd 100644 --- a/drivers/usb/storage/unusual_devs.h +++ b/drivers/usb/storage/unusual_devs.h | |||
@@ -234,6 +234,20 @@ UNUSUAL_DEV( 0x0421, 0x0495, 0x0370, 0x0370, | |||
234 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | 234 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, |
235 | US_FL_MAX_SECTORS_64 ), | 235 | US_FL_MAX_SECTORS_64 ), |
236 | 236 | ||
237 | /* Reported by Daniele Forsi <dforsi@gmail.com> */ | ||
238 | UNUSUAL_DEV( 0x0421, 0x04b9, 0x0350, 0x0350, | ||
239 | "Nokia", | ||
240 | "5300", | ||
241 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
242 | US_FL_MAX_SECTORS_64 ), | ||
243 | |||
244 | /* Patch submitted by Victor A. Santos <victoraur.santos@gmail.com> */ | ||
245 | UNUSUAL_DEV( 0x0421, 0x05af, 0x0742, 0x0742, | ||
246 | "Nokia", | ||
247 | "305", | ||
248 | USB_SC_DEVICE, USB_PR_DEVICE, NULL, | ||
249 | US_FL_MAX_SECTORS_64), | ||
250 | |||
237 | /* Patch submitted by Mikhail Zolotaryov <lebon@lebon.org.ua> */ | 251 | /* Patch submitted by Mikhail Zolotaryov <lebon@lebon.org.ua> */ |
238 | UNUSUAL_DEV( 0x0421, 0x06aa, 0x1110, 0x1110, | 252 | UNUSUAL_DEV( 0x0421, 0x06aa, 0x1110, 0x1110, |
239 | "Nokia", | 253 | "Nokia", |
diff --git a/fs/affs/super.c b/fs/affs/super.c index 6d589f28bf9b..895ac7dc9dbf 100644 --- a/fs/affs/super.c +++ b/fs/affs/super.c | |||
@@ -340,8 +340,6 @@ static int affs_fill_super(struct super_block *sb, void *data, int silent) | |||
340 | &blocksize,&sbi->s_prefix, | 340 | &blocksize,&sbi->s_prefix, |
341 | sbi->s_volume, &mount_flags)) { | 341 | sbi->s_volume, &mount_flags)) { |
342 | printk(KERN_ERR "AFFS: Error parsing options\n"); | 342 | printk(KERN_ERR "AFFS: Error parsing options\n"); |
343 | kfree(sbi->s_prefix); | ||
344 | kfree(sbi); | ||
345 | return -EINVAL; | 343 | return -EINVAL; |
346 | } | 344 | } |
347 | /* N.B. after this point s_prefix must be released */ | 345 | /* N.B. after this point s_prefix must be released */ |
diff --git a/fs/autofs4/root.c b/fs/autofs4/root.c index 2caf36ac3e93..cc87c1abac97 100644 --- a/fs/autofs4/root.c +++ b/fs/autofs4/root.c | |||
@@ -179,7 +179,7 @@ static struct dentry *autofs4_lookup_active(struct dentry *dentry) | |||
179 | spin_lock(&active->d_lock); | 179 | spin_lock(&active->d_lock); |
180 | 180 | ||
181 | /* Already gone? */ | 181 | /* Already gone? */ |
182 | if (!d_count(active)) | 182 | if ((int) d_count(active) <= 0) |
183 | goto next; | 183 | goto next; |
184 | 184 | ||
185 | qstr = &active->d_name; | 185 | qstr = &active->d_name; |
@@ -230,7 +230,7 @@ static struct dentry *autofs4_lookup_expiring(struct dentry *dentry) | |||
230 | 230 | ||
231 | spin_lock(&expiring->d_lock); | 231 | spin_lock(&expiring->d_lock); |
232 | 232 | ||
233 | /* Bad luck, we've already been dentry_iput */ | 233 | /* We've already been dentry_iput or unlinked */ |
234 | if (!expiring->d_inode) | 234 | if (!expiring->d_inode) |
235 | goto next; | 235 | goto next; |
236 | 236 | ||
diff --git a/fs/ceph/caps.c b/fs/ceph/caps.c index 2e5e648eb5c3..c561b628ebce 100644 --- a/fs/ceph/caps.c +++ b/fs/ceph/caps.c | |||
@@ -3261,7 +3261,7 @@ int ceph_encode_inode_release(void **p, struct inode *inode, | |||
3261 | rel->seq = cpu_to_le32(cap->seq); | 3261 | rel->seq = cpu_to_le32(cap->seq); |
3262 | rel->issue_seq = cpu_to_le32(cap->issue_seq), | 3262 | rel->issue_seq = cpu_to_le32(cap->issue_seq), |
3263 | rel->mseq = cpu_to_le32(cap->mseq); | 3263 | rel->mseq = cpu_to_le32(cap->mseq); |
3264 | rel->caps = cpu_to_le32(cap->issued); | 3264 | rel->caps = cpu_to_le32(cap->implemented); |
3265 | rel->wanted = cpu_to_le32(cap->mds_wanted); | 3265 | rel->wanted = cpu_to_le32(cap->mds_wanted); |
3266 | rel->dname_len = 0; | 3266 | rel->dname_len = 0; |
3267 | rel->dname_seq = 0; | 3267 | rel->dname_seq = 0; |
diff --git a/fs/ceph/dir.c b/fs/ceph/dir.c index 766410a12c2c..c29d6ae68874 100644 --- a/fs/ceph/dir.c +++ b/fs/ceph/dir.c | |||
@@ -141,7 +141,7 @@ static int __dcache_readdir(struct file *file, struct dir_context *ctx, | |||
141 | 141 | ||
142 | /* start at beginning? */ | 142 | /* start at beginning? */ |
143 | if (ctx->pos == 2 || last == NULL || | 143 | if (ctx->pos == 2 || last == NULL || |
144 | ctx->pos < ceph_dentry(last)->offset) { | 144 | fpos_cmp(ctx->pos, ceph_dentry(last)->offset) < 0) { |
145 | if (list_empty(&parent->d_subdirs)) | 145 | if (list_empty(&parent->d_subdirs)) |
146 | goto out_unlock; | 146 | goto out_unlock; |
147 | p = parent->d_subdirs.prev; | 147 | p = parent->d_subdirs.prev; |
@@ -182,9 +182,16 @@ more: | |||
182 | spin_unlock(&dentry->d_lock); | 182 | spin_unlock(&dentry->d_lock); |
183 | spin_unlock(&parent->d_lock); | 183 | spin_unlock(&parent->d_lock); |
184 | 184 | ||
185 | /* make sure a dentry wasn't dropped while we didn't have parent lock */ | ||
186 | if (!ceph_dir_is_complete(dir)) { | ||
187 | dout(" lost dir complete on %p; falling back to mds\n", dir); | ||
188 | dput(dentry); | ||
189 | err = -EAGAIN; | ||
190 | goto out; | ||
191 | } | ||
192 | |||
185 | dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, ctx->pos, | 193 | dout(" %llu (%llu) dentry %p %.*s %p\n", di->offset, ctx->pos, |
186 | dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); | 194 | dentry, dentry->d_name.len, dentry->d_name.name, dentry->d_inode); |
187 | ctx->pos = di->offset; | ||
188 | if (!dir_emit(ctx, dentry->d_name.name, | 195 | if (!dir_emit(ctx, dentry->d_name.name, |
189 | dentry->d_name.len, | 196 | dentry->d_name.len, |
190 | ceph_translate_ino(dentry->d_sb, dentry->d_inode->i_ino), | 197 | ceph_translate_ino(dentry->d_sb, dentry->d_inode->i_ino), |
@@ -198,19 +205,12 @@ more: | |||
198 | return 0; | 205 | return 0; |
199 | } | 206 | } |
200 | 207 | ||
208 | ctx->pos = di->offset + 1; | ||
209 | |||
201 | if (last) | 210 | if (last) |
202 | dput(last); | 211 | dput(last); |
203 | last = dentry; | 212 | last = dentry; |
204 | 213 | ||
205 | ctx->pos++; | ||
206 | |||
207 | /* make sure a dentry wasn't dropped while we didn't have parent lock */ | ||
208 | if (!ceph_dir_is_complete(dir)) { | ||
209 | dout(" lost dir complete on %p; falling back to mds\n", dir); | ||
210 | err = -EAGAIN; | ||
211 | goto out; | ||
212 | } | ||
213 | |||
214 | spin_lock(&parent->d_lock); | 214 | spin_lock(&parent->d_lock); |
215 | p = p->prev; /* advance to next dentry */ | 215 | p = p->prev; /* advance to next dentry */ |
216 | goto more; | 216 | goto more; |
@@ -296,6 +296,8 @@ static int ceph_readdir(struct file *file, struct dir_context *ctx) | |||
296 | err = __dcache_readdir(file, ctx, shared_gen); | 296 | err = __dcache_readdir(file, ctx, shared_gen); |
297 | if (err != -EAGAIN) | 297 | if (err != -EAGAIN) |
298 | return err; | 298 | return err; |
299 | frag = fpos_frag(ctx->pos); | ||
300 | off = fpos_off(ctx->pos); | ||
299 | } else { | 301 | } else { |
300 | spin_unlock(&ci->i_ceph_lock); | 302 | spin_unlock(&ci->i_ceph_lock); |
301 | } | 303 | } |
@@ -446,7 +448,6 @@ more: | |||
446 | if (atomic_read(&ci->i_release_count) == fi->dir_release_count) { | 448 | if (atomic_read(&ci->i_release_count) == fi->dir_release_count) { |
447 | dout(" marking %p complete\n", inode); | 449 | dout(" marking %p complete\n", inode); |
448 | __ceph_dir_set_complete(ci, fi->dir_release_count); | 450 | __ceph_dir_set_complete(ci, fi->dir_release_count); |
449 | ci->i_max_offset = ctx->pos; | ||
450 | } | 451 | } |
451 | spin_unlock(&ci->i_ceph_lock); | 452 | spin_unlock(&ci->i_ceph_lock); |
452 | 453 | ||
@@ -935,14 +936,16 @@ static int ceph_rename(struct inode *old_dir, struct dentry *old_dentry, | |||
935 | * to do it here. | 936 | * to do it here. |
936 | */ | 937 | */ |
937 | 938 | ||
938 | /* d_move screws up d_subdirs order */ | ||
939 | ceph_dir_clear_complete(new_dir); | ||
940 | |||
941 | d_move(old_dentry, new_dentry); | 939 | d_move(old_dentry, new_dentry); |
942 | 940 | ||
943 | /* ensure target dentry is invalidated, despite | 941 | /* ensure target dentry is invalidated, despite |
944 | rehashing bug in vfs_rename_dir */ | 942 | rehashing bug in vfs_rename_dir */ |
945 | ceph_invalidate_dentry_lease(new_dentry); | 943 | ceph_invalidate_dentry_lease(new_dentry); |
944 | |||
945 | /* d_move screws up sibling dentries' offsets */ | ||
946 | ceph_dir_clear_complete(old_dir); | ||
947 | ceph_dir_clear_complete(new_dir); | ||
948 | |||
946 | } | 949 | } |
947 | ceph_mdsc_put_request(req); | 950 | ceph_mdsc_put_request(req); |
948 | return err; | 951 | return err; |
diff --git a/fs/ceph/inode.c b/fs/ceph/inode.c index 0b0728e5be2d..233c6f96910a 100644 --- a/fs/ceph/inode.c +++ b/fs/ceph/inode.c | |||
@@ -744,7 +744,6 @@ static int fill_inode(struct inode *inode, | |||
744 | !__ceph_dir_is_complete(ci)) { | 744 | !__ceph_dir_is_complete(ci)) { |
745 | dout(" marking %p complete (empty)\n", inode); | 745 | dout(" marking %p complete (empty)\n", inode); |
746 | __ceph_dir_set_complete(ci, atomic_read(&ci->i_release_count)); | 746 | __ceph_dir_set_complete(ci, atomic_read(&ci->i_release_count)); |
747 | ci->i_max_offset = 2; | ||
748 | } | 747 | } |
749 | no_change: | 748 | no_change: |
750 | /* only update max_size on auth cap */ | 749 | /* only update max_size on auth cap */ |
@@ -890,41 +889,6 @@ out_unlock: | |||
890 | } | 889 | } |
891 | 890 | ||
892 | /* | 891 | /* |
893 | * Set dentry's directory position based on the current dir's max, and | ||
894 | * order it in d_subdirs, so that dcache_readdir behaves. | ||
895 | * | ||
896 | * Always called under directory's i_mutex. | ||
897 | */ | ||
898 | static void ceph_set_dentry_offset(struct dentry *dn) | ||
899 | { | ||
900 | struct dentry *dir = dn->d_parent; | ||
901 | struct inode *inode = dir->d_inode; | ||
902 | struct ceph_inode_info *ci; | ||
903 | struct ceph_dentry_info *di; | ||
904 | |||
905 | BUG_ON(!inode); | ||
906 | |||
907 | ci = ceph_inode(inode); | ||
908 | di = ceph_dentry(dn); | ||
909 | |||
910 | spin_lock(&ci->i_ceph_lock); | ||
911 | if (!__ceph_dir_is_complete(ci)) { | ||
912 | spin_unlock(&ci->i_ceph_lock); | ||
913 | return; | ||
914 | } | ||
915 | di->offset = ceph_inode(inode)->i_max_offset++; | ||
916 | spin_unlock(&ci->i_ceph_lock); | ||
917 | |||
918 | spin_lock(&dir->d_lock); | ||
919 | spin_lock_nested(&dn->d_lock, DENTRY_D_LOCK_NESTED); | ||
920 | list_move(&dn->d_u.d_child, &dir->d_subdirs); | ||
921 | dout("set_dentry_offset %p %lld (%p %p)\n", dn, di->offset, | ||
922 | dn->d_u.d_child.prev, dn->d_u.d_child.next); | ||
923 | spin_unlock(&dn->d_lock); | ||
924 | spin_unlock(&dir->d_lock); | ||
925 | } | ||
926 | |||
927 | /* | ||
928 | * splice a dentry to an inode. | 892 | * splice a dentry to an inode. |
929 | * caller must hold directory i_mutex for this to be safe. | 893 | * caller must hold directory i_mutex for this to be safe. |
930 | * | 894 | * |
@@ -933,7 +897,7 @@ static void ceph_set_dentry_offset(struct dentry *dn) | |||
933 | * the caller) if we fail. | 897 | * the caller) if we fail. |
934 | */ | 898 | */ |
935 | static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, | 899 | static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, |
936 | bool *prehash, bool set_offset) | 900 | bool *prehash) |
937 | { | 901 | { |
938 | struct dentry *realdn; | 902 | struct dentry *realdn; |
939 | 903 | ||
@@ -965,8 +929,6 @@ static struct dentry *splice_dentry(struct dentry *dn, struct inode *in, | |||
965 | } | 929 | } |
966 | if ((!prehash || *prehash) && d_unhashed(dn)) | 930 | if ((!prehash || *prehash) && d_unhashed(dn)) |
967 | d_rehash(dn); | 931 | d_rehash(dn); |
968 | if (set_offset) | ||
969 | ceph_set_dentry_offset(dn); | ||
970 | out: | 932 | out: |
971 | return dn; | 933 | return dn; |
972 | } | 934 | } |
@@ -987,7 +949,6 @@ int ceph_fill_trace(struct super_block *sb, struct ceph_mds_request *req, | |||
987 | { | 949 | { |
988 | struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info; | 950 | struct ceph_mds_reply_info_parsed *rinfo = &req->r_reply_info; |
989 | struct inode *in = NULL; | 951 | struct inode *in = NULL; |
990 | struct ceph_mds_reply_inode *ininfo; | ||
991 | struct ceph_vino vino; | 952 | struct ceph_vino vino; |
992 | struct ceph_fs_client *fsc = ceph_sb_to_client(sb); | 953 | struct ceph_fs_client *fsc = ceph_sb_to_client(sb); |
993 | int err = 0; | 954 | int err = 0; |
@@ -1161,6 +1122,9 @@ retry_lookup: | |||
1161 | 1122 | ||
1162 | /* rename? */ | 1123 | /* rename? */ |
1163 | if (req->r_old_dentry && req->r_op == CEPH_MDS_OP_RENAME) { | 1124 | if (req->r_old_dentry && req->r_op == CEPH_MDS_OP_RENAME) { |
1125 | struct inode *olddir = req->r_old_dentry_dir; | ||
1126 | BUG_ON(!olddir); | ||
1127 | |||
1164 | dout(" src %p '%.*s' dst %p '%.*s'\n", | 1128 | dout(" src %p '%.*s' dst %p '%.*s'\n", |
1165 | req->r_old_dentry, | 1129 | req->r_old_dentry, |
1166 | req->r_old_dentry->d_name.len, | 1130 | req->r_old_dentry->d_name.len, |
@@ -1180,13 +1144,10 @@ retry_lookup: | |||
1180 | rehashing bug in vfs_rename_dir */ | 1144 | rehashing bug in vfs_rename_dir */ |
1181 | ceph_invalidate_dentry_lease(dn); | 1145 | ceph_invalidate_dentry_lease(dn); |
1182 | 1146 | ||
1183 | /* | 1147 | /* d_move screws up sibling dentries' offsets */ |
1184 | * d_move() puts the renamed dentry at the end of | 1148 | ceph_dir_clear_complete(dir); |
1185 | * d_subdirs. We need to assign it an appropriate | 1149 | ceph_dir_clear_complete(olddir); |
1186 | * directory offset so we can behave when dir is | 1150 | |
1187 | * complete. | ||
1188 | */ | ||
1189 | ceph_set_dentry_offset(req->r_old_dentry); | ||
1190 | dout("dn %p gets new offset %lld\n", req->r_old_dentry, | 1151 | dout("dn %p gets new offset %lld\n", req->r_old_dentry, |
1191 | ceph_dentry(req->r_old_dentry)->offset); | 1152 | ceph_dentry(req->r_old_dentry)->offset); |
1192 | 1153 | ||
@@ -1213,8 +1174,9 @@ retry_lookup: | |||
1213 | 1174 | ||
1214 | /* attach proper inode */ | 1175 | /* attach proper inode */ |
1215 | if (!dn->d_inode) { | 1176 | if (!dn->d_inode) { |
1177 | ceph_dir_clear_complete(dir); | ||
1216 | ihold(in); | 1178 | ihold(in); |
1217 | dn = splice_dentry(dn, in, &have_lease, true); | 1179 | dn = splice_dentry(dn, in, &have_lease); |
1218 | if (IS_ERR(dn)) { | 1180 | if (IS_ERR(dn)) { |
1219 | err = PTR_ERR(dn); | 1181 | err = PTR_ERR(dn); |
1220 | goto done; | 1182 | goto done; |
@@ -1235,17 +1197,16 @@ retry_lookup: | |||
1235 | (req->r_op == CEPH_MDS_OP_LOOKUPSNAP || | 1197 | (req->r_op == CEPH_MDS_OP_LOOKUPSNAP || |
1236 | req->r_op == CEPH_MDS_OP_MKSNAP)) { | 1198 | req->r_op == CEPH_MDS_OP_MKSNAP)) { |
1237 | struct dentry *dn = req->r_dentry; | 1199 | struct dentry *dn = req->r_dentry; |
1200 | struct inode *dir = req->r_locked_dir; | ||
1238 | 1201 | ||
1239 | /* fill out a snapdir LOOKUPSNAP dentry */ | 1202 | /* fill out a snapdir LOOKUPSNAP dentry */ |
1240 | BUG_ON(!dn); | 1203 | BUG_ON(!dn); |
1241 | BUG_ON(!req->r_locked_dir); | 1204 | BUG_ON(!dir); |
1242 | BUG_ON(ceph_snap(req->r_locked_dir) != CEPH_SNAPDIR); | 1205 | BUG_ON(ceph_snap(dir) != CEPH_SNAPDIR); |
1243 | ininfo = rinfo->targeti.in; | ||
1244 | vino.ino = le64_to_cpu(ininfo->ino); | ||
1245 | vino.snap = le64_to_cpu(ininfo->snapid); | ||
1246 | dout(" linking snapped dir %p to dn %p\n", in, dn); | 1206 | dout(" linking snapped dir %p to dn %p\n", in, dn); |
1207 | ceph_dir_clear_complete(dir); | ||
1247 | ihold(in); | 1208 | ihold(in); |
1248 | dn = splice_dentry(dn, in, NULL, true); | 1209 | dn = splice_dentry(dn, in, NULL); |
1249 | if (IS_ERR(dn)) { | 1210 | if (IS_ERR(dn)) { |
1250 | err = PTR_ERR(dn); | 1211 | err = PTR_ERR(dn); |
1251 | goto done; | 1212 | goto done; |
@@ -1407,7 +1368,7 @@ retry_lookup: | |||
1407 | } | 1368 | } |
1408 | 1369 | ||
1409 | if (!dn->d_inode) { | 1370 | if (!dn->d_inode) { |
1410 | dn = splice_dentry(dn, in, NULL, false); | 1371 | dn = splice_dentry(dn, in, NULL); |
1411 | if (IS_ERR(dn)) { | 1372 | if (IS_ERR(dn)) { |
1412 | err = PTR_ERR(dn); | 1373 | err = PTR_ERR(dn); |
1413 | dn = NULL; | 1374 | dn = NULL; |
diff --git a/fs/ceph/ioctl.c b/fs/ceph/ioctl.c index fdf941b44ff1..a822a6e58290 100644 --- a/fs/ceph/ioctl.c +++ b/fs/ceph/ioctl.c | |||
@@ -109,6 +109,8 @@ static long ceph_ioctl_set_layout(struct file *file, void __user *arg) | |||
109 | return PTR_ERR(req); | 109 | return PTR_ERR(req); |
110 | req->r_inode = inode; | 110 | req->r_inode = inode; |
111 | ihold(inode); | 111 | ihold(inode); |
112 | req->r_num_caps = 1; | ||
113 | |||
112 | req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL; | 114 | req->r_inode_drop = CEPH_CAP_FILE_SHARED | CEPH_CAP_FILE_EXCL; |
113 | 115 | ||
114 | req->r_args.setlayout.layout.fl_stripe_unit = | 116 | req->r_args.setlayout.layout.fl_stripe_unit = |
@@ -153,6 +155,7 @@ static long ceph_ioctl_set_layout_policy (struct file *file, void __user *arg) | |||
153 | return PTR_ERR(req); | 155 | return PTR_ERR(req); |
154 | req->r_inode = inode; | 156 | req->r_inode = inode; |
155 | ihold(inode); | 157 | ihold(inode); |
158 | req->r_num_caps = 1; | ||
156 | 159 | ||
157 | req->r_args.setlayout.layout.fl_stripe_unit = | 160 | req->r_args.setlayout.layout.fl_stripe_unit = |
158 | cpu_to_le32(l.stripe_unit); | 161 | cpu_to_le32(l.stripe_unit); |
diff --git a/fs/ceph/locks.c b/fs/ceph/locks.c index d94ba0df9f4d..191398852a2e 100644 --- a/fs/ceph/locks.c +++ b/fs/ceph/locks.c | |||
@@ -45,6 +45,7 @@ static int ceph_lock_message(u8 lock_type, u16 operation, struct file *file, | |||
45 | return PTR_ERR(req); | 45 | return PTR_ERR(req); |
46 | req->r_inode = inode; | 46 | req->r_inode = inode; |
47 | ihold(inode); | 47 | ihold(inode); |
48 | req->r_num_caps = 1; | ||
48 | 49 | ||
49 | /* mds requires start and length rather than start and end */ | 50 | /* mds requires start and length rather than start and end */ |
50 | if (LLONG_MAX == fl->fl_end) | 51 | if (LLONG_MAX == fl->fl_end) |
diff --git a/fs/ceph/super.h b/fs/ceph/super.h index 7866cd05a6bb..ead05cc1f447 100644 --- a/fs/ceph/super.h +++ b/fs/ceph/super.h | |||
@@ -266,7 +266,6 @@ struct ceph_inode_info { | |||
266 | struct timespec i_rctime; | 266 | struct timespec i_rctime; |
267 | u64 i_rbytes, i_rfiles, i_rsubdirs; | 267 | u64 i_rbytes, i_rfiles, i_rsubdirs; |
268 | u64 i_files, i_subdirs; | 268 | u64 i_files, i_subdirs; |
269 | u64 i_max_offset; /* largest readdir offset, set with complete dir */ | ||
270 | 269 | ||
271 | struct rb_root i_fragtree; | 270 | struct rb_root i_fragtree; |
272 | struct mutex i_fragtree_mutex; | 271 | struct mutex i_fragtree_mutex; |
diff --git a/fs/dcache.c b/fs/dcache.c index 40707d88a945..42ae01eefc07 100644 --- a/fs/dcache.c +++ b/fs/dcache.c | |||
@@ -246,16 +246,8 @@ static void __d_free(struct rcu_head *head) | |||
246 | kmem_cache_free(dentry_cache, dentry); | 246 | kmem_cache_free(dentry_cache, dentry); |
247 | } | 247 | } |
248 | 248 | ||
249 | /* | 249 | static void dentry_free(struct dentry *dentry) |
250 | * no locks, please. | ||
251 | */ | ||
252 | static void d_free(struct dentry *dentry) | ||
253 | { | 250 | { |
254 | BUG_ON((int)dentry->d_lockref.count > 0); | ||
255 | this_cpu_dec(nr_dentry); | ||
256 | if (dentry->d_op && dentry->d_op->d_release) | ||
257 | dentry->d_op->d_release(dentry); | ||
258 | |||
259 | /* if dentry was never visible to RCU, immediate free is OK */ | 251 | /* if dentry was never visible to RCU, immediate free is OK */ |
260 | if (!(dentry->d_flags & DCACHE_RCUACCESS)) | 252 | if (!(dentry->d_flags & DCACHE_RCUACCESS)) |
261 | __d_free(&dentry->d_u.d_rcu); | 253 | __d_free(&dentry->d_u.d_rcu); |
@@ -403,56 +395,6 @@ static void dentry_lru_add(struct dentry *dentry) | |||
403 | d_lru_add(dentry); | 395 | d_lru_add(dentry); |
404 | } | 396 | } |
405 | 397 | ||
406 | /* | ||
407 | * Remove a dentry with references from the LRU. | ||
408 | * | ||
409 | * If we are on the shrink list, then we can get to try_prune_one_dentry() and | ||
410 | * lose our last reference through the parent walk. In this case, we need to | ||
411 | * remove ourselves from the shrink list, not the LRU. | ||
412 | */ | ||
413 | static void dentry_lru_del(struct dentry *dentry) | ||
414 | { | ||
415 | if (dentry->d_flags & DCACHE_LRU_LIST) { | ||
416 | if (dentry->d_flags & DCACHE_SHRINK_LIST) | ||
417 | return d_shrink_del(dentry); | ||
418 | d_lru_del(dentry); | ||
419 | } | ||
420 | } | ||
421 | |||
422 | /** | ||
423 | * d_kill - kill dentry and return parent | ||
424 | * @dentry: dentry to kill | ||
425 | * @parent: parent dentry | ||
426 | * | ||
427 | * The dentry must already be unhashed and removed from the LRU. | ||
428 | * | ||
429 | * If this is the root of the dentry tree, return NULL. | ||
430 | * | ||
431 | * dentry->d_lock and parent->d_lock must be held by caller, and are dropped by | ||
432 | * d_kill. | ||
433 | */ | ||
434 | static struct dentry *d_kill(struct dentry *dentry, struct dentry *parent) | ||
435 | __releases(dentry->d_lock) | ||
436 | __releases(parent->d_lock) | ||
437 | __releases(dentry->d_inode->i_lock) | ||
438 | { | ||
439 | list_del(&dentry->d_u.d_child); | ||
440 | /* | ||
441 | * Inform d_walk() that we are no longer attached to the | ||
442 | * dentry tree | ||
443 | */ | ||
444 | dentry->d_flags |= DCACHE_DENTRY_KILLED; | ||
445 | if (parent) | ||
446 | spin_unlock(&parent->d_lock); | ||
447 | dentry_iput(dentry); | ||
448 | /* | ||
449 | * dentry_iput drops the locks, at which point nobody (except | ||
450 | * transient RCU lookups) can reach this dentry. | ||
451 | */ | ||
452 | d_free(dentry); | ||
453 | return parent; | ||
454 | } | ||
455 | |||
456 | /** | 398 | /** |
457 | * d_drop - drop a dentry | 399 | * d_drop - drop a dentry |
458 | * @dentry: dentry to drop | 400 | * @dentry: dentry to drop |
@@ -510,7 +452,14 @@ dentry_kill(struct dentry *dentry, int unlock_on_failure) | |||
510 | __releases(dentry->d_lock) | 452 | __releases(dentry->d_lock) |
511 | { | 453 | { |
512 | struct inode *inode; | 454 | struct inode *inode; |
513 | struct dentry *parent; | 455 | struct dentry *parent = NULL; |
456 | bool can_free = true; | ||
457 | |||
458 | if (unlikely(dentry->d_flags & DCACHE_DENTRY_KILLED)) { | ||
459 | can_free = dentry->d_flags & DCACHE_MAY_FREE; | ||
460 | spin_unlock(&dentry->d_lock); | ||
461 | goto out; | ||
462 | } | ||
514 | 463 | ||
515 | inode = dentry->d_inode; | 464 | inode = dentry->d_inode; |
516 | if (inode && !spin_trylock(&inode->i_lock)) { | 465 | if (inode && !spin_trylock(&inode->i_lock)) { |
@@ -521,9 +470,7 @@ relock: | |||
521 | } | 470 | } |
522 | return dentry; /* try again with same dentry */ | 471 | return dentry; /* try again with same dentry */ |
523 | } | 472 | } |
524 | if (IS_ROOT(dentry)) | 473 | if (!IS_ROOT(dentry)) |
525 | parent = NULL; | ||
526 | else | ||
527 | parent = dentry->d_parent; | 474 | parent = dentry->d_parent; |
528 | if (parent && !spin_trylock(&parent->d_lock)) { | 475 | if (parent && !spin_trylock(&parent->d_lock)) { |
529 | if (inode) | 476 | if (inode) |
@@ -543,10 +490,40 @@ relock: | |||
543 | if ((dentry->d_flags & DCACHE_OP_PRUNE) && !d_unhashed(dentry)) | 490 | if ((dentry->d_flags & DCACHE_OP_PRUNE) && !d_unhashed(dentry)) |
544 | dentry->d_op->d_prune(dentry); | 491 | dentry->d_op->d_prune(dentry); |
545 | 492 | ||
546 | dentry_lru_del(dentry); | 493 | if (dentry->d_flags & DCACHE_LRU_LIST) { |
494 | if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) | ||
495 | d_lru_del(dentry); | ||
496 | } | ||
547 | /* if it was on the hash then remove it */ | 497 | /* if it was on the hash then remove it */ |
548 | __d_drop(dentry); | 498 | __d_drop(dentry); |
549 | return d_kill(dentry, parent); | 499 | list_del(&dentry->d_u.d_child); |
500 | /* | ||
501 | * Inform d_walk() that we are no longer attached to the | ||
502 | * dentry tree | ||
503 | */ | ||
504 | dentry->d_flags |= DCACHE_DENTRY_KILLED; | ||
505 | if (parent) | ||
506 | spin_unlock(&parent->d_lock); | ||
507 | dentry_iput(dentry); | ||
508 | /* | ||
509 | * dentry_iput drops the locks, at which point nobody (except | ||
510 | * transient RCU lookups) can reach this dentry. | ||
511 | */ | ||
512 | BUG_ON((int)dentry->d_lockref.count > 0); | ||
513 | this_cpu_dec(nr_dentry); | ||
514 | if (dentry->d_op && dentry->d_op->d_release) | ||
515 | dentry->d_op->d_release(dentry); | ||
516 | |||
517 | spin_lock(&dentry->d_lock); | ||
518 | if (dentry->d_flags & DCACHE_SHRINK_LIST) { | ||
519 | dentry->d_flags |= DCACHE_MAY_FREE; | ||
520 | can_free = false; | ||
521 | } | ||
522 | spin_unlock(&dentry->d_lock); | ||
523 | out: | ||
524 | if (likely(can_free)) | ||
525 | dentry_free(dentry); | ||
526 | return parent; | ||
550 | } | 527 | } |
551 | 528 | ||
552 | /* | 529 | /* |
@@ -815,65 +792,13 @@ restart: | |||
815 | } | 792 | } |
816 | EXPORT_SYMBOL(d_prune_aliases); | 793 | EXPORT_SYMBOL(d_prune_aliases); |
817 | 794 | ||
818 | /* | ||
819 | * Try to throw away a dentry - free the inode, dput the parent. | ||
820 | * Requires dentry->d_lock is held, and dentry->d_count == 0. | ||
821 | * Releases dentry->d_lock. | ||
822 | * | ||
823 | * This may fail if locks cannot be acquired no problem, just try again. | ||
824 | */ | ||
825 | static struct dentry * try_prune_one_dentry(struct dentry *dentry) | ||
826 | __releases(dentry->d_lock) | ||
827 | { | ||
828 | struct dentry *parent; | ||
829 | |||
830 | parent = dentry_kill(dentry, 0); | ||
831 | /* | ||
832 | * If dentry_kill returns NULL, we have nothing more to do. | ||
833 | * if it returns the same dentry, trylocks failed. In either | ||
834 | * case, just loop again. | ||
835 | * | ||
836 | * Otherwise, we need to prune ancestors too. This is necessary | ||
837 | * to prevent quadratic behavior of shrink_dcache_parent(), but | ||
838 | * is also expected to be beneficial in reducing dentry cache | ||
839 | * fragmentation. | ||
840 | */ | ||
841 | if (!parent) | ||
842 | return NULL; | ||
843 | if (parent == dentry) | ||
844 | return dentry; | ||
845 | |||
846 | /* Prune ancestors. */ | ||
847 | dentry = parent; | ||
848 | while (dentry) { | ||
849 | if (lockref_put_or_lock(&dentry->d_lockref)) | ||
850 | return NULL; | ||
851 | dentry = dentry_kill(dentry, 1); | ||
852 | } | ||
853 | return NULL; | ||
854 | } | ||
855 | |||
856 | static void shrink_dentry_list(struct list_head *list) | 795 | static void shrink_dentry_list(struct list_head *list) |
857 | { | 796 | { |
858 | struct dentry *dentry; | 797 | struct dentry *dentry, *parent; |
859 | 798 | ||
860 | rcu_read_lock(); | 799 | while (!list_empty(list)) { |
861 | for (;;) { | 800 | dentry = list_entry(list->prev, struct dentry, d_lru); |
862 | dentry = list_entry_rcu(list->prev, struct dentry, d_lru); | ||
863 | if (&dentry->d_lru == list) | ||
864 | break; /* empty */ | ||
865 | |||
866 | /* | ||
867 | * Get the dentry lock, and re-verify that the dentry is | ||
868 | * this on the shrinking list. If it is, we know that | ||
869 | * DCACHE_SHRINK_LIST and DCACHE_LRU_LIST are set. | ||
870 | */ | ||
871 | spin_lock(&dentry->d_lock); | 801 | spin_lock(&dentry->d_lock); |
872 | if (dentry != list_entry(list->prev, struct dentry, d_lru)) { | ||
873 | spin_unlock(&dentry->d_lock); | ||
874 | continue; | ||
875 | } | ||
876 | |||
877 | /* | 802 | /* |
878 | * The dispose list is isolated and dentries are not accounted | 803 | * The dispose list is isolated and dentries are not accounted |
879 | * to the LRU here, so we can simply remove it from the list | 804 | * to the LRU here, so we can simply remove it from the list |
@@ -885,30 +810,38 @@ static void shrink_dentry_list(struct list_head *list) | |||
885 | * We found an inuse dentry which was not removed from | 810 | * We found an inuse dentry which was not removed from |
886 | * the LRU because of laziness during lookup. Do not free it. | 811 | * the LRU because of laziness during lookup. Do not free it. |
887 | */ | 812 | */ |
888 | if (dentry->d_lockref.count) { | 813 | if ((int)dentry->d_lockref.count > 0) { |
889 | spin_unlock(&dentry->d_lock); | 814 | spin_unlock(&dentry->d_lock); |
890 | continue; | 815 | continue; |
891 | } | 816 | } |
892 | rcu_read_unlock(); | ||
893 | 817 | ||
818 | parent = dentry_kill(dentry, 0); | ||
894 | /* | 819 | /* |
895 | * If 'try_to_prune()' returns a dentry, it will | 820 | * If dentry_kill returns NULL, we have nothing more to do. |
896 | * be the same one we passed in, and d_lock will | ||
897 | * have been held the whole time, so it will not | ||
898 | * have been added to any other lists. We failed | ||
899 | * to get the inode lock. | ||
900 | * | ||
901 | * We just add it back to the shrink list. | ||
902 | */ | 821 | */ |
903 | dentry = try_prune_one_dentry(dentry); | 822 | if (!parent) |
823 | continue; | ||
904 | 824 | ||
905 | rcu_read_lock(); | 825 | if (unlikely(parent == dentry)) { |
906 | if (dentry) { | 826 | /* |
827 | * trylocks have failed and d_lock has been held the | ||
828 | * whole time, so it could not have been added to any | ||
829 | * other lists. Just add it back to the shrink list. | ||
830 | */ | ||
907 | d_shrink_add(dentry, list); | 831 | d_shrink_add(dentry, list); |
908 | spin_unlock(&dentry->d_lock); | 832 | spin_unlock(&dentry->d_lock); |
833 | continue; | ||
909 | } | 834 | } |
835 | /* | ||
836 | * We need to prune ancestors too. This is necessary to prevent | ||
837 | * quadratic behavior of shrink_dcache_parent(), but is also | ||
838 | * expected to be beneficial in reducing dentry cache | ||
839 | * fragmentation. | ||
840 | */ | ||
841 | dentry = parent; | ||
842 | while (dentry && !lockref_put_or_lock(&dentry->d_lockref)) | ||
843 | dentry = dentry_kill(dentry, 1); | ||
910 | } | 844 | } |
911 | rcu_read_unlock(); | ||
912 | } | 845 | } |
913 | 846 | ||
914 | static enum lru_status | 847 | static enum lru_status |
@@ -1261,34 +1194,23 @@ static enum d_walk_ret select_collect(void *_data, struct dentry *dentry) | |||
1261 | if (data->start == dentry) | 1194 | if (data->start == dentry) |
1262 | goto out; | 1195 | goto out; |
1263 | 1196 | ||
1264 | /* | 1197 | if (dentry->d_flags & DCACHE_SHRINK_LIST) { |
1265 | * move only zero ref count dentries to the dispose list. | ||
1266 | * | ||
1267 | * Those which are presently on the shrink list, being processed | ||
1268 | * by shrink_dentry_list(), shouldn't be moved. Otherwise the | ||
1269 | * loop in shrink_dcache_parent() might not make any progress | ||
1270 | * and loop forever. | ||
1271 | */ | ||
1272 | if (dentry->d_lockref.count) { | ||
1273 | dentry_lru_del(dentry); | ||
1274 | } else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) { | ||
1275 | /* | ||
1276 | * We can't use d_lru_shrink_move() because we | ||
1277 | * need to get the global LRU lock and do the | ||
1278 | * LRU accounting. | ||
1279 | */ | ||
1280 | d_lru_del(dentry); | ||
1281 | d_shrink_add(dentry, &data->dispose); | ||
1282 | data->found++; | 1198 | data->found++; |
1283 | ret = D_WALK_NORETRY; | 1199 | } else { |
1200 | if (dentry->d_flags & DCACHE_LRU_LIST) | ||
1201 | d_lru_del(dentry); | ||
1202 | if (!dentry->d_lockref.count) { | ||
1203 | d_shrink_add(dentry, &data->dispose); | ||
1204 | data->found++; | ||
1205 | } | ||
1284 | } | 1206 | } |
1285 | /* | 1207 | /* |
1286 | * We can return to the caller if we have found some (this | 1208 | * We can return to the caller if we have found some (this |
1287 | * ensures forward progress). We'll be coming back to find | 1209 | * ensures forward progress). We'll be coming back to find |
1288 | * the rest. | 1210 | * the rest. |
1289 | */ | 1211 | */ |
1290 | if (data->found && need_resched()) | 1212 | if (!list_empty(&data->dispose)) |
1291 | ret = D_WALK_QUIT; | 1213 | ret = need_resched() ? D_WALK_QUIT : D_WALK_NORETRY; |
1292 | out: | 1214 | out: |
1293 | return ret; | 1215 | return ret; |
1294 | } | 1216 | } |
@@ -1318,45 +1240,35 @@ void shrink_dcache_parent(struct dentry *parent) | |||
1318 | } | 1240 | } |
1319 | EXPORT_SYMBOL(shrink_dcache_parent); | 1241 | EXPORT_SYMBOL(shrink_dcache_parent); |
1320 | 1242 | ||
1321 | static enum d_walk_ret umount_collect(void *_data, struct dentry *dentry) | 1243 | static enum d_walk_ret umount_check(void *_data, struct dentry *dentry) |
1322 | { | 1244 | { |
1323 | struct select_data *data = _data; | 1245 | /* it has busy descendents; complain about those instead */ |
1324 | enum d_walk_ret ret = D_WALK_CONTINUE; | 1246 | if (!list_empty(&dentry->d_subdirs)) |
1247 | return D_WALK_CONTINUE; | ||
1325 | 1248 | ||
1326 | if (dentry->d_lockref.count) { | 1249 | /* root with refcount 1 is fine */ |
1327 | dentry_lru_del(dentry); | 1250 | if (dentry == _data && dentry->d_lockref.count == 1) |
1328 | if (likely(!list_empty(&dentry->d_subdirs))) | 1251 | return D_WALK_CONTINUE; |
1329 | goto out; | 1252 | |
1330 | if (dentry == data->start && dentry->d_lockref.count == 1) | 1253 | printk(KERN_ERR "BUG: Dentry %p{i=%lx,n=%pd} " |
1331 | goto out; | 1254 | " still in use (%d) [unmount of %s %s]\n", |
1332 | printk(KERN_ERR | ||
1333 | "BUG: Dentry %p{i=%lx,n=%s}" | ||
1334 | " still in use (%d)" | ||
1335 | " [unmount of %s %s]\n", | ||
1336 | dentry, | 1255 | dentry, |
1337 | dentry->d_inode ? | 1256 | dentry->d_inode ? |
1338 | dentry->d_inode->i_ino : 0UL, | 1257 | dentry->d_inode->i_ino : 0UL, |
1339 | dentry->d_name.name, | 1258 | dentry, |
1340 | dentry->d_lockref.count, | 1259 | dentry->d_lockref.count, |
1341 | dentry->d_sb->s_type->name, | 1260 | dentry->d_sb->s_type->name, |
1342 | dentry->d_sb->s_id); | 1261 | dentry->d_sb->s_id); |
1343 | BUG(); | 1262 | WARN_ON(1); |
1344 | } else if (!(dentry->d_flags & DCACHE_SHRINK_LIST)) { | 1263 | return D_WALK_CONTINUE; |
1345 | /* | 1264 | } |
1346 | * We can't use d_lru_shrink_move() because we | 1265 | |
1347 | * need to get the global LRU lock and do the | 1266 | static void do_one_tree(struct dentry *dentry) |
1348 | * LRU accounting. | 1267 | { |
1349 | */ | 1268 | shrink_dcache_parent(dentry); |
1350 | if (dentry->d_flags & DCACHE_LRU_LIST) | 1269 | d_walk(dentry, dentry, umount_check, NULL); |
1351 | d_lru_del(dentry); | 1270 | d_drop(dentry); |
1352 | d_shrink_add(dentry, &data->dispose); | 1271 | dput(dentry); |
1353 | data->found++; | ||
1354 | ret = D_WALK_NORETRY; | ||
1355 | } | ||
1356 | out: | ||
1357 | if (data->found && need_resched()) | ||
1358 | ret = D_WALK_QUIT; | ||
1359 | return ret; | ||
1360 | } | 1272 | } |
1361 | 1273 | ||
1362 | /* | 1274 | /* |
@@ -1366,40 +1278,15 @@ void shrink_dcache_for_umount(struct super_block *sb) | |||
1366 | { | 1278 | { |
1367 | struct dentry *dentry; | 1279 | struct dentry *dentry; |
1368 | 1280 | ||
1369 | if (down_read_trylock(&sb->s_umount)) | 1281 | WARN(down_read_trylock(&sb->s_umount), "s_umount should've been locked"); |
1370 | BUG(); | ||
1371 | 1282 | ||
1372 | dentry = sb->s_root; | 1283 | dentry = sb->s_root; |
1373 | sb->s_root = NULL; | 1284 | sb->s_root = NULL; |
1374 | for (;;) { | 1285 | do_one_tree(dentry); |
1375 | struct select_data data; | ||
1376 | |||
1377 | INIT_LIST_HEAD(&data.dispose); | ||
1378 | data.start = dentry; | ||
1379 | data.found = 0; | ||
1380 | |||
1381 | d_walk(dentry, &data, umount_collect, NULL); | ||
1382 | if (!data.found) | ||
1383 | break; | ||
1384 | |||
1385 | shrink_dentry_list(&data.dispose); | ||
1386 | cond_resched(); | ||
1387 | } | ||
1388 | d_drop(dentry); | ||
1389 | dput(dentry); | ||
1390 | 1286 | ||
1391 | while (!hlist_bl_empty(&sb->s_anon)) { | 1287 | while (!hlist_bl_empty(&sb->s_anon)) { |
1392 | struct select_data data; | 1288 | dentry = dget(hlist_bl_entry(hlist_bl_first(&sb->s_anon), struct dentry, d_hash)); |
1393 | dentry = hlist_bl_entry(hlist_bl_first(&sb->s_anon), struct dentry, d_hash); | 1289 | do_one_tree(dentry); |
1394 | |||
1395 | INIT_LIST_HEAD(&data.dispose); | ||
1396 | data.start = NULL; | ||
1397 | data.found = 0; | ||
1398 | |||
1399 | d_walk(dentry, &data, umount_collect, NULL); | ||
1400 | if (data.found) | ||
1401 | shrink_dentry_list(&data.dispose); | ||
1402 | cond_resched(); | ||
1403 | } | 1290 | } |
1404 | } | 1291 | } |
1405 | 1292 | ||
@@ -1647,8 +1534,7 @@ static void __d_instantiate(struct dentry *dentry, struct inode *inode) | |||
1647 | unsigned add_flags = d_flags_for_inode(inode); | 1534 | unsigned add_flags = d_flags_for_inode(inode); |
1648 | 1535 | ||
1649 | spin_lock(&dentry->d_lock); | 1536 | spin_lock(&dentry->d_lock); |
1650 | dentry->d_flags &= ~DCACHE_ENTRY_TYPE; | 1537 | __d_set_type(dentry, add_flags); |
1651 | dentry->d_flags |= add_flags; | ||
1652 | if (inode) | 1538 | if (inode) |
1653 | hlist_add_head(&dentry->d_alias, &inode->i_dentry); | 1539 | hlist_add_head(&dentry->d_alias, &inode->i_dentry); |
1654 | dentry->d_inode = inode; | 1540 | dentry->d_inode = inode; |
diff --git a/fs/fuse/control.c b/fs/fuse/control.c index a0b0855d00a9..205e0d5d5307 100644 --- a/fs/fuse/control.c +++ b/fs/fuse/control.c | |||
@@ -348,7 +348,7 @@ int __init fuse_ctl_init(void) | |||
348 | return register_filesystem(&fuse_ctl_fs_type); | 348 | return register_filesystem(&fuse_ctl_fs_type); |
349 | } | 349 | } |
350 | 350 | ||
351 | void fuse_ctl_cleanup(void) | 351 | void __exit fuse_ctl_cleanup(void) |
352 | { | 352 | { |
353 | unregister_filesystem(&fuse_ctl_fs_type); | 353 | unregister_filesystem(&fuse_ctl_fs_type); |
354 | } | 354 | } |
diff --git a/fs/fuse/dir.c b/fs/fuse/dir.c index 5b4e035b364c..42198359fa1b 100644 --- a/fs/fuse/dir.c +++ b/fs/fuse/dir.c | |||
@@ -679,6 +679,14 @@ static int fuse_symlink(struct inode *dir, struct dentry *entry, | |||
679 | return create_new_entry(fc, req, dir, entry, S_IFLNK); | 679 | return create_new_entry(fc, req, dir, entry, S_IFLNK); |
680 | } | 680 | } |
681 | 681 | ||
682 | static inline void fuse_update_ctime(struct inode *inode) | ||
683 | { | ||
684 | if (!IS_NOCMTIME(inode)) { | ||
685 | inode->i_ctime = current_fs_time(inode->i_sb); | ||
686 | mark_inode_dirty_sync(inode); | ||
687 | } | ||
688 | } | ||
689 | |||
682 | static int fuse_unlink(struct inode *dir, struct dentry *entry) | 690 | static int fuse_unlink(struct inode *dir, struct dentry *entry) |
683 | { | 691 | { |
684 | int err; | 692 | int err; |
@@ -713,6 +721,7 @@ static int fuse_unlink(struct inode *dir, struct dentry *entry) | |||
713 | fuse_invalidate_attr(inode); | 721 | fuse_invalidate_attr(inode); |
714 | fuse_invalidate_attr(dir); | 722 | fuse_invalidate_attr(dir); |
715 | fuse_invalidate_entry_cache(entry); | 723 | fuse_invalidate_entry_cache(entry); |
724 | fuse_update_ctime(inode); | ||
716 | } else if (err == -EINTR) | 725 | } else if (err == -EINTR) |
717 | fuse_invalidate_entry(entry); | 726 | fuse_invalidate_entry(entry); |
718 | return err; | 727 | return err; |
@@ -743,23 +752,26 @@ static int fuse_rmdir(struct inode *dir, struct dentry *entry) | |||
743 | return err; | 752 | return err; |
744 | } | 753 | } |
745 | 754 | ||
746 | static int fuse_rename(struct inode *olddir, struct dentry *oldent, | 755 | static int fuse_rename_common(struct inode *olddir, struct dentry *oldent, |
747 | struct inode *newdir, struct dentry *newent) | 756 | struct inode *newdir, struct dentry *newent, |
757 | unsigned int flags, int opcode, size_t argsize) | ||
748 | { | 758 | { |
749 | int err; | 759 | int err; |
750 | struct fuse_rename_in inarg; | 760 | struct fuse_rename2_in inarg; |
751 | struct fuse_conn *fc = get_fuse_conn(olddir); | 761 | struct fuse_conn *fc = get_fuse_conn(olddir); |
752 | struct fuse_req *req = fuse_get_req_nopages(fc); | 762 | struct fuse_req *req; |
753 | 763 | ||
764 | req = fuse_get_req_nopages(fc); | ||
754 | if (IS_ERR(req)) | 765 | if (IS_ERR(req)) |
755 | return PTR_ERR(req); | 766 | return PTR_ERR(req); |
756 | 767 | ||
757 | memset(&inarg, 0, sizeof(inarg)); | 768 | memset(&inarg, 0, argsize); |
758 | inarg.newdir = get_node_id(newdir); | 769 | inarg.newdir = get_node_id(newdir); |
759 | req->in.h.opcode = FUSE_RENAME; | 770 | inarg.flags = flags; |
771 | req->in.h.opcode = opcode; | ||
760 | req->in.h.nodeid = get_node_id(olddir); | 772 | req->in.h.nodeid = get_node_id(olddir); |
761 | req->in.numargs = 3; | 773 | req->in.numargs = 3; |
762 | req->in.args[0].size = sizeof(inarg); | 774 | req->in.args[0].size = argsize; |
763 | req->in.args[0].value = &inarg; | 775 | req->in.args[0].value = &inarg; |
764 | req->in.args[1].size = oldent->d_name.len + 1; | 776 | req->in.args[1].size = oldent->d_name.len + 1; |
765 | req->in.args[1].value = oldent->d_name.name; | 777 | req->in.args[1].value = oldent->d_name.name; |
@@ -771,15 +783,22 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, | |||
771 | if (!err) { | 783 | if (!err) { |
772 | /* ctime changes */ | 784 | /* ctime changes */ |
773 | fuse_invalidate_attr(oldent->d_inode); | 785 | fuse_invalidate_attr(oldent->d_inode); |
786 | fuse_update_ctime(oldent->d_inode); | ||
787 | |||
788 | if (flags & RENAME_EXCHANGE) { | ||
789 | fuse_invalidate_attr(newent->d_inode); | ||
790 | fuse_update_ctime(newent->d_inode); | ||
791 | } | ||
774 | 792 | ||
775 | fuse_invalidate_attr(olddir); | 793 | fuse_invalidate_attr(olddir); |
776 | if (olddir != newdir) | 794 | if (olddir != newdir) |
777 | fuse_invalidate_attr(newdir); | 795 | fuse_invalidate_attr(newdir); |
778 | 796 | ||
779 | /* newent will end up negative */ | 797 | /* newent will end up negative */ |
780 | if (newent->d_inode) { | 798 | if (!(flags & RENAME_EXCHANGE) && newent->d_inode) { |
781 | fuse_invalidate_attr(newent->d_inode); | 799 | fuse_invalidate_attr(newent->d_inode); |
782 | fuse_invalidate_entry_cache(newent); | 800 | fuse_invalidate_entry_cache(newent); |
801 | fuse_update_ctime(newent->d_inode); | ||
783 | } | 802 | } |
784 | } else if (err == -EINTR) { | 803 | } else if (err == -EINTR) { |
785 | /* If request was interrupted, DEITY only knows if the | 804 | /* If request was interrupted, DEITY only knows if the |
@@ -795,6 +814,36 @@ static int fuse_rename(struct inode *olddir, struct dentry *oldent, | |||
795 | return err; | 814 | return err; |
796 | } | 815 | } |
797 | 816 | ||
817 | static int fuse_rename(struct inode *olddir, struct dentry *oldent, | ||
818 | struct inode *newdir, struct dentry *newent) | ||
819 | { | ||
820 | return fuse_rename_common(olddir, oldent, newdir, newent, 0, | ||
821 | FUSE_RENAME, sizeof(struct fuse_rename_in)); | ||
822 | } | ||
823 | |||
824 | static int fuse_rename2(struct inode *olddir, struct dentry *oldent, | ||
825 | struct inode *newdir, struct dentry *newent, | ||
826 | unsigned int flags) | ||
827 | { | ||
828 | struct fuse_conn *fc = get_fuse_conn(olddir); | ||
829 | int err; | ||
830 | |||
831 | if (flags & ~(RENAME_NOREPLACE | RENAME_EXCHANGE)) | ||
832 | return -EINVAL; | ||
833 | |||
834 | if (fc->no_rename2 || fc->minor < 23) | ||
835 | return -EINVAL; | ||
836 | |||
837 | err = fuse_rename_common(olddir, oldent, newdir, newent, flags, | ||
838 | FUSE_RENAME2, sizeof(struct fuse_rename2_in)); | ||
839 | if (err == -ENOSYS) { | ||
840 | fc->no_rename2 = 1; | ||
841 | err = -EINVAL; | ||
842 | } | ||
843 | return err; | ||
844 | |||
845 | } | ||
846 | |||
798 | static int fuse_link(struct dentry *entry, struct inode *newdir, | 847 | static int fuse_link(struct dentry *entry, struct inode *newdir, |
799 | struct dentry *newent) | 848 | struct dentry *newent) |
800 | { | 849 | { |
@@ -829,6 +878,7 @@ static int fuse_link(struct dentry *entry, struct inode *newdir, | |||
829 | inc_nlink(inode); | 878 | inc_nlink(inode); |
830 | spin_unlock(&fc->lock); | 879 | spin_unlock(&fc->lock); |
831 | fuse_invalidate_attr(inode); | 880 | fuse_invalidate_attr(inode); |
881 | fuse_update_ctime(inode); | ||
832 | } else if (err == -EINTR) { | 882 | } else if (err == -EINTR) { |
833 | fuse_invalidate_attr(inode); | 883 | fuse_invalidate_attr(inode); |
834 | } | 884 | } |
@@ -846,6 +896,8 @@ static void fuse_fillattr(struct inode *inode, struct fuse_attr *attr, | |||
846 | attr->size = i_size_read(inode); | 896 | attr->size = i_size_read(inode); |
847 | attr->mtime = inode->i_mtime.tv_sec; | 897 | attr->mtime = inode->i_mtime.tv_sec; |
848 | attr->mtimensec = inode->i_mtime.tv_nsec; | 898 | attr->mtimensec = inode->i_mtime.tv_nsec; |
899 | attr->ctime = inode->i_ctime.tv_sec; | ||
900 | attr->ctimensec = inode->i_ctime.tv_nsec; | ||
849 | } | 901 | } |
850 | 902 | ||
851 | stat->dev = inode->i_sb->s_dev; | 903 | stat->dev = inode->i_sb->s_dev; |
@@ -1504,7 +1556,7 @@ static bool update_mtime(unsigned ivalid, bool trust_local_mtime) | |||
1504 | } | 1556 | } |
1505 | 1557 | ||
1506 | static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg, | 1558 | static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg, |
1507 | bool trust_local_mtime) | 1559 | bool trust_local_cmtime) |
1508 | { | 1560 | { |
1509 | unsigned ivalid = iattr->ia_valid; | 1561 | unsigned ivalid = iattr->ia_valid; |
1510 | 1562 | ||
@@ -1523,13 +1575,18 @@ static void iattr_to_fattr(struct iattr *iattr, struct fuse_setattr_in *arg, | |||
1523 | if (!(ivalid & ATTR_ATIME_SET)) | 1575 | if (!(ivalid & ATTR_ATIME_SET)) |
1524 | arg->valid |= FATTR_ATIME_NOW; | 1576 | arg->valid |= FATTR_ATIME_NOW; |
1525 | } | 1577 | } |
1526 | if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_mtime)) { | 1578 | if ((ivalid & ATTR_MTIME) && update_mtime(ivalid, trust_local_cmtime)) { |
1527 | arg->valid |= FATTR_MTIME; | 1579 | arg->valid |= FATTR_MTIME; |
1528 | arg->mtime = iattr->ia_mtime.tv_sec; | 1580 | arg->mtime = iattr->ia_mtime.tv_sec; |
1529 | arg->mtimensec = iattr->ia_mtime.tv_nsec; | 1581 | arg->mtimensec = iattr->ia_mtime.tv_nsec; |
1530 | if (!(ivalid & ATTR_MTIME_SET) && !trust_local_mtime) | 1582 | if (!(ivalid & ATTR_MTIME_SET) && !trust_local_cmtime) |
1531 | arg->valid |= FATTR_MTIME_NOW; | 1583 | arg->valid |= FATTR_MTIME_NOW; |
1532 | } | 1584 | } |
1585 | if ((ivalid & ATTR_CTIME) && trust_local_cmtime) { | ||
1586 | arg->valid |= FATTR_CTIME; | ||
1587 | arg->ctime = iattr->ia_ctime.tv_sec; | ||
1588 | arg->ctimensec = iattr->ia_ctime.tv_nsec; | ||
1589 | } | ||
1533 | } | 1590 | } |
1534 | 1591 | ||
1535 | /* | 1592 | /* |
@@ -1597,39 +1654,38 @@ static void fuse_setattr_fill(struct fuse_conn *fc, struct fuse_req *req, | |||
1597 | /* | 1654 | /* |
1598 | * Flush inode->i_mtime to the server | 1655 | * Flush inode->i_mtime to the server |
1599 | */ | 1656 | */ |
1600 | int fuse_flush_mtime(struct file *file, bool nofail) | 1657 | int fuse_flush_times(struct inode *inode, struct fuse_file *ff) |
1601 | { | 1658 | { |
1602 | struct inode *inode = file->f_mapping->host; | ||
1603 | struct fuse_inode *fi = get_fuse_inode(inode); | ||
1604 | struct fuse_conn *fc = get_fuse_conn(inode); | 1659 | struct fuse_conn *fc = get_fuse_conn(inode); |
1605 | struct fuse_req *req = NULL; | 1660 | struct fuse_req *req; |
1606 | struct fuse_setattr_in inarg; | 1661 | struct fuse_setattr_in inarg; |
1607 | struct fuse_attr_out outarg; | 1662 | struct fuse_attr_out outarg; |
1608 | int err; | 1663 | int err; |
1609 | 1664 | ||
1610 | if (nofail) { | 1665 | req = fuse_get_req_nopages(fc); |
1611 | req = fuse_get_req_nofail_nopages(fc, file); | 1666 | if (IS_ERR(req)) |
1612 | } else { | 1667 | return PTR_ERR(req); |
1613 | req = fuse_get_req_nopages(fc); | ||
1614 | if (IS_ERR(req)) | ||
1615 | return PTR_ERR(req); | ||
1616 | } | ||
1617 | 1668 | ||
1618 | memset(&inarg, 0, sizeof(inarg)); | 1669 | memset(&inarg, 0, sizeof(inarg)); |
1619 | memset(&outarg, 0, sizeof(outarg)); | 1670 | memset(&outarg, 0, sizeof(outarg)); |
1620 | 1671 | ||
1621 | inarg.valid |= FATTR_MTIME; | 1672 | inarg.valid = FATTR_MTIME; |
1622 | inarg.mtime = inode->i_mtime.tv_sec; | 1673 | inarg.mtime = inode->i_mtime.tv_sec; |
1623 | inarg.mtimensec = inode->i_mtime.tv_nsec; | 1674 | inarg.mtimensec = inode->i_mtime.tv_nsec; |
1624 | 1675 | if (fc->minor >= 23) { | |
1676 | inarg.valid |= FATTR_CTIME; | ||
1677 | inarg.ctime = inode->i_ctime.tv_sec; | ||
1678 | inarg.ctimensec = inode->i_ctime.tv_nsec; | ||
1679 | } | ||
1680 | if (ff) { | ||
1681 | inarg.valid |= FATTR_FH; | ||
1682 | inarg.fh = ff->fh; | ||
1683 | } | ||
1625 | fuse_setattr_fill(fc, req, inode, &inarg, &outarg); | 1684 | fuse_setattr_fill(fc, req, inode, &inarg, &outarg); |
1626 | fuse_request_send(fc, req); | 1685 | fuse_request_send(fc, req); |
1627 | err = req->out.h.error; | 1686 | err = req->out.h.error; |
1628 | fuse_put_request(fc, req); | 1687 | fuse_put_request(fc, req); |
1629 | 1688 | ||
1630 | if (!err) | ||
1631 | clear_bit(FUSE_I_MTIME_DIRTY, &fi->state); | ||
1632 | |||
1633 | return err; | 1689 | return err; |
1634 | } | 1690 | } |
1635 | 1691 | ||
@@ -1653,7 +1709,7 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr, | |||
1653 | bool is_wb = fc->writeback_cache; | 1709 | bool is_wb = fc->writeback_cache; |
1654 | loff_t oldsize; | 1710 | loff_t oldsize; |
1655 | int err; | 1711 | int err; |
1656 | bool trust_local_mtime = is_wb && S_ISREG(inode->i_mode); | 1712 | bool trust_local_cmtime = is_wb && S_ISREG(inode->i_mode); |
1657 | 1713 | ||
1658 | if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS)) | 1714 | if (!(fc->flags & FUSE_DEFAULT_PERMISSIONS)) |
1659 | attr->ia_valid |= ATTR_FORCE; | 1715 | attr->ia_valid |= ATTR_FORCE; |
@@ -1678,11 +1734,13 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr, | |||
1678 | if (is_truncate) { | 1734 | if (is_truncate) { |
1679 | fuse_set_nowrite(inode); | 1735 | fuse_set_nowrite(inode); |
1680 | set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); | 1736 | set_bit(FUSE_I_SIZE_UNSTABLE, &fi->state); |
1737 | if (trust_local_cmtime && attr->ia_size != inode->i_size) | ||
1738 | attr->ia_valid |= ATTR_MTIME | ATTR_CTIME; | ||
1681 | } | 1739 | } |
1682 | 1740 | ||
1683 | memset(&inarg, 0, sizeof(inarg)); | 1741 | memset(&inarg, 0, sizeof(inarg)); |
1684 | memset(&outarg, 0, sizeof(outarg)); | 1742 | memset(&outarg, 0, sizeof(outarg)); |
1685 | iattr_to_fattr(attr, &inarg, trust_local_mtime); | 1743 | iattr_to_fattr(attr, &inarg, trust_local_cmtime); |
1686 | if (file) { | 1744 | if (file) { |
1687 | struct fuse_file *ff = file->private_data; | 1745 | struct fuse_file *ff = file->private_data; |
1688 | inarg.valid |= FATTR_FH; | 1746 | inarg.valid |= FATTR_FH; |
@@ -1711,9 +1769,12 @@ int fuse_do_setattr(struct inode *inode, struct iattr *attr, | |||
1711 | 1769 | ||
1712 | spin_lock(&fc->lock); | 1770 | spin_lock(&fc->lock); |
1713 | /* the kernel maintains i_mtime locally */ | 1771 | /* the kernel maintains i_mtime locally */ |
1714 | if (trust_local_mtime && (attr->ia_valid & ATTR_MTIME)) { | 1772 | if (trust_local_cmtime) { |
1715 | inode->i_mtime = attr->ia_mtime; | 1773 | if (attr->ia_valid & ATTR_MTIME) |
1716 | clear_bit(FUSE_I_MTIME_DIRTY, &fi->state); | 1774 | inode->i_mtime = attr->ia_mtime; |
1775 | if (attr->ia_valid & ATTR_CTIME) | ||
1776 | inode->i_ctime = attr->ia_ctime; | ||
1777 | /* FIXME: clear I_DIRTY_SYNC? */ | ||
1717 | } | 1778 | } |
1718 | 1779 | ||
1719 | fuse_change_attributes_common(inode, &outarg.attr, | 1780 | fuse_change_attributes_common(inode, &outarg.attr, |
@@ -1810,8 +1871,10 @@ static int fuse_setxattr(struct dentry *entry, const char *name, | |||
1810 | fc->no_setxattr = 1; | 1871 | fc->no_setxattr = 1; |
1811 | err = -EOPNOTSUPP; | 1872 | err = -EOPNOTSUPP; |
1812 | } | 1873 | } |
1813 | if (!err) | 1874 | if (!err) { |
1814 | fuse_invalidate_attr(inode); | 1875 | fuse_invalidate_attr(inode); |
1876 | fuse_update_ctime(inode); | ||
1877 | } | ||
1815 | return err; | 1878 | return err; |
1816 | } | 1879 | } |
1817 | 1880 | ||
@@ -1941,20 +2004,11 @@ static int fuse_removexattr(struct dentry *entry, const char *name) | |||
1941 | fc->no_removexattr = 1; | 2004 | fc->no_removexattr = 1; |
1942 | err = -EOPNOTSUPP; | 2005 | err = -EOPNOTSUPP; |
1943 | } | 2006 | } |
1944 | if (!err) | 2007 | if (!err) { |
1945 | fuse_invalidate_attr(inode); | 2008 | fuse_invalidate_attr(inode); |
1946 | return err; | 2009 | fuse_update_ctime(inode); |
1947 | } | ||
1948 | |||
1949 | static int fuse_update_time(struct inode *inode, struct timespec *now, | ||
1950 | int flags) | ||
1951 | { | ||
1952 | if (flags & S_MTIME) { | ||
1953 | inode->i_mtime = *now; | ||
1954 | set_bit(FUSE_I_MTIME_DIRTY, &get_fuse_inode(inode)->state); | ||
1955 | BUG_ON(!S_ISREG(inode->i_mode)); | ||
1956 | } | 2010 | } |
1957 | return 0; | 2011 | return err; |
1958 | } | 2012 | } |
1959 | 2013 | ||
1960 | static const struct inode_operations fuse_dir_inode_operations = { | 2014 | static const struct inode_operations fuse_dir_inode_operations = { |
@@ -1964,6 +2018,7 @@ static const struct inode_operations fuse_dir_inode_operations = { | |||
1964 | .unlink = fuse_unlink, | 2018 | .unlink = fuse_unlink, |
1965 | .rmdir = fuse_rmdir, | 2019 | .rmdir = fuse_rmdir, |
1966 | .rename = fuse_rename, | 2020 | .rename = fuse_rename, |
2021 | .rename2 = fuse_rename2, | ||
1967 | .link = fuse_link, | 2022 | .link = fuse_link, |
1968 | .setattr = fuse_setattr, | 2023 | .setattr = fuse_setattr, |
1969 | .create = fuse_create, | 2024 | .create = fuse_create, |
@@ -1996,7 +2051,6 @@ static const struct inode_operations fuse_common_inode_operations = { | |||
1996 | .getxattr = fuse_getxattr, | 2051 | .getxattr = fuse_getxattr, |
1997 | .listxattr = fuse_listxattr, | 2052 | .listxattr = fuse_listxattr, |
1998 | .removexattr = fuse_removexattr, | 2053 | .removexattr = fuse_removexattr, |
1999 | .update_time = fuse_update_time, | ||
2000 | }; | 2054 | }; |
2001 | 2055 | ||
2002 | static const struct inode_operations fuse_symlink_inode_operations = { | 2056 | static const struct inode_operations fuse_symlink_inode_operations = { |
diff --git a/fs/fuse/file.c b/fs/fuse/file.c index 13f8bdec5110..96d513e01a5d 100644 --- a/fs/fuse/file.c +++ b/fs/fuse/file.c | |||
@@ -223,6 +223,8 @@ void fuse_finish_open(struct inode *inode, struct file *file) | |||
223 | i_size_write(inode, 0); | 223 | i_size_write(inode, 0); |
224 | spin_unlock(&fc->lock); | 224 | spin_unlock(&fc->lock); |
225 | fuse_invalidate_attr(inode); | 225 | fuse_invalidate_attr(inode); |
226 | if (fc->writeback_cache) | ||
227 | file_update_time(file); | ||
226 | } | 228 | } |
227 | if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache) | 229 | if ((file->f_mode & FMODE_WRITE) && fc->writeback_cache) |
228 | fuse_link_write_file(file); | 230 | fuse_link_write_file(file); |
@@ -232,18 +234,26 @@ int fuse_open_common(struct inode *inode, struct file *file, bool isdir) | |||
232 | { | 234 | { |
233 | struct fuse_conn *fc = get_fuse_conn(inode); | 235 | struct fuse_conn *fc = get_fuse_conn(inode); |
234 | int err; | 236 | int err; |
237 | bool lock_inode = (file->f_flags & O_TRUNC) && | ||
238 | fc->atomic_o_trunc && | ||
239 | fc->writeback_cache; | ||
235 | 240 | ||
236 | err = generic_file_open(inode, file); | 241 | err = generic_file_open(inode, file); |
237 | if (err) | 242 | if (err) |
238 | return err; | 243 | return err; |
239 | 244 | ||
245 | if (lock_inode) | ||
246 | mutex_lock(&inode->i_mutex); | ||
247 | |||
240 | err = fuse_do_open(fc, get_node_id(inode), file, isdir); | 248 | err = fuse_do_open(fc, get_node_id(inode), file, isdir); |
241 | if (err) | ||
242 | return err; | ||
243 | 249 | ||
244 | fuse_finish_open(inode, file); | 250 | if (!err) |
251 | fuse_finish_open(inode, file); | ||
245 | 252 | ||
246 | return 0; | 253 | if (lock_inode) |
254 | mutex_unlock(&inode->i_mutex); | ||
255 | |||
256 | return err; | ||
247 | } | 257 | } |
248 | 258 | ||
249 | static void fuse_prepare_release(struct fuse_file *ff, int flags, int opcode) | 259 | static void fuse_prepare_release(struct fuse_file *ff, int flags, int opcode) |
@@ -314,10 +324,7 @@ static int fuse_release(struct inode *inode, struct file *file) | |||
314 | 324 | ||
315 | /* see fuse_vma_close() for !writeback_cache case */ | 325 | /* see fuse_vma_close() for !writeback_cache case */ |
316 | if (fc->writeback_cache) | 326 | if (fc->writeback_cache) |
317 | filemap_write_and_wait(file->f_mapping); | 327 | write_inode_now(inode, 1); |
318 | |||
319 | if (test_bit(FUSE_I_MTIME_DIRTY, &get_fuse_inode(inode)->state)) | ||
320 | fuse_flush_mtime(file, true); | ||
321 | 328 | ||
322 | fuse_release_common(file, FUSE_RELEASE); | 329 | fuse_release_common(file, FUSE_RELEASE); |
323 | 330 | ||
@@ -439,7 +446,7 @@ static int fuse_flush(struct file *file, fl_owner_t id) | |||
439 | if (fc->no_flush) | 446 | if (fc->no_flush) |
440 | return 0; | 447 | return 0; |
441 | 448 | ||
442 | err = filemap_write_and_wait(file->f_mapping); | 449 | err = write_inode_now(inode, 1); |
443 | if (err) | 450 | if (err) |
444 | return err; | 451 | return err; |
445 | 452 | ||
@@ -480,13 +487,6 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end, | |||
480 | if (is_bad_inode(inode)) | 487 | if (is_bad_inode(inode)) |
481 | return -EIO; | 488 | return -EIO; |
482 | 489 | ||
483 | err = filemap_write_and_wait_range(inode->i_mapping, start, end); | ||
484 | if (err) | ||
485 | return err; | ||
486 | |||
487 | if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir)) | ||
488 | return 0; | ||
489 | |||
490 | mutex_lock(&inode->i_mutex); | 490 | mutex_lock(&inode->i_mutex); |
491 | 491 | ||
492 | /* | 492 | /* |
@@ -494,17 +494,17 @@ int fuse_fsync_common(struct file *file, loff_t start, loff_t end, | |||
494 | * wait for all outstanding writes, before sending the FSYNC | 494 | * wait for all outstanding writes, before sending the FSYNC |
495 | * request. | 495 | * request. |
496 | */ | 496 | */ |
497 | err = write_inode_now(inode, 0); | 497 | err = filemap_write_and_wait_range(inode->i_mapping, start, end); |
498 | if (err) | 498 | if (err) |
499 | goto out; | 499 | goto out; |
500 | 500 | ||
501 | fuse_sync_writes(inode); | 501 | fuse_sync_writes(inode); |
502 | err = sync_inode_metadata(inode, 1); | ||
503 | if (err) | ||
504 | goto out; | ||
502 | 505 | ||
503 | if (test_bit(FUSE_I_MTIME_DIRTY, &get_fuse_inode(inode)->state)) { | 506 | if ((!isdir && fc->no_fsync) || (isdir && fc->no_fsyncdir)) |
504 | int err = fuse_flush_mtime(file, false); | 507 | goto out; |
505 | if (err) | ||
506 | goto out; | ||
507 | } | ||
508 | 508 | ||
509 | req = fuse_get_req_nopages(fc); | 509 | req = fuse_get_req_nopages(fc); |
510 | if (IS_ERR(req)) { | 510 | if (IS_ERR(req)) { |
@@ -1659,13 +1659,13 @@ static void fuse_writepage_end(struct fuse_conn *fc, struct fuse_req *req) | |||
1659 | fuse_writepage_free(fc, req); | 1659 | fuse_writepage_free(fc, req); |
1660 | } | 1660 | } |
1661 | 1661 | ||
1662 | static struct fuse_file *fuse_write_file_get(struct fuse_conn *fc, | 1662 | static struct fuse_file *__fuse_write_file_get(struct fuse_conn *fc, |
1663 | struct fuse_inode *fi) | 1663 | struct fuse_inode *fi) |
1664 | { | 1664 | { |
1665 | struct fuse_file *ff = NULL; | 1665 | struct fuse_file *ff = NULL; |
1666 | 1666 | ||
1667 | spin_lock(&fc->lock); | 1667 | spin_lock(&fc->lock); |
1668 | if (!WARN_ON(list_empty(&fi->write_files))) { | 1668 | if (!list_empty(&fi->write_files)) { |
1669 | ff = list_entry(fi->write_files.next, struct fuse_file, | 1669 | ff = list_entry(fi->write_files.next, struct fuse_file, |
1670 | write_entry); | 1670 | write_entry); |
1671 | fuse_file_get(ff); | 1671 | fuse_file_get(ff); |
@@ -1675,6 +1675,29 @@ static struct fuse_file *fuse_write_file_get(struct fuse_conn *fc, | |||
1675 | return ff; | 1675 | return ff; |
1676 | } | 1676 | } |
1677 | 1677 | ||
1678 | static struct fuse_file *fuse_write_file_get(struct fuse_conn *fc, | ||
1679 | struct fuse_inode *fi) | ||
1680 | { | ||
1681 | struct fuse_file *ff = __fuse_write_file_get(fc, fi); | ||
1682 | WARN_ON(!ff); | ||
1683 | return ff; | ||
1684 | } | ||
1685 | |||
1686 | int fuse_write_inode(struct inode *inode, struct writeback_control *wbc) | ||
1687 | { | ||
1688 | struct fuse_conn *fc = get_fuse_conn(inode); | ||
1689 | struct fuse_inode *fi = get_fuse_inode(inode); | ||
1690 | struct fuse_file *ff; | ||
1691 | int err; | ||
1692 | |||
1693 | ff = __fuse_write_file_get(fc, fi); | ||
1694 | err = fuse_flush_times(inode, ff); | ||
1695 | if (ff) | ||
1696 | fuse_file_put(ff, 0); | ||
1697 | |||
1698 | return err; | ||
1699 | } | ||
1700 | |||
1678 | static int fuse_writepage_locked(struct page *page) | 1701 | static int fuse_writepage_locked(struct page *page) |
1679 | { | 1702 | { |
1680 | struct address_space *mapping = page->mapping; | 1703 | struct address_space *mapping = page->mapping; |
@@ -2972,6 +2995,9 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
2972 | bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) || | 2995 | bool lock_inode = !(mode & FALLOC_FL_KEEP_SIZE) || |
2973 | (mode & FALLOC_FL_PUNCH_HOLE); | 2996 | (mode & FALLOC_FL_PUNCH_HOLE); |
2974 | 2997 | ||
2998 | if (mode & ~(FALLOC_FL_KEEP_SIZE | FALLOC_FL_PUNCH_HOLE)) | ||
2999 | return -EOPNOTSUPP; | ||
3000 | |||
2975 | if (fc->no_fallocate) | 3001 | if (fc->no_fallocate) |
2976 | return -EOPNOTSUPP; | 3002 | return -EOPNOTSUPP; |
2977 | 3003 | ||
@@ -3017,12 +3043,8 @@ static long fuse_file_fallocate(struct file *file, int mode, loff_t offset, | |||
3017 | if (!(mode & FALLOC_FL_KEEP_SIZE)) { | 3043 | if (!(mode & FALLOC_FL_KEEP_SIZE)) { |
3018 | bool changed = fuse_write_update_size(inode, offset + length); | 3044 | bool changed = fuse_write_update_size(inode, offset + length); |
3019 | 3045 | ||
3020 | if (changed && fc->writeback_cache) { | 3046 | if (changed && fc->writeback_cache) |
3021 | struct fuse_inode *fi = get_fuse_inode(inode); | 3047 | file_update_time(file); |
3022 | |||
3023 | inode->i_mtime = current_fs_time(inode->i_sb); | ||
3024 | set_bit(FUSE_I_MTIME_DIRTY, &fi->state); | ||
3025 | } | ||
3026 | } | 3048 | } |
3027 | 3049 | ||
3028 | if (mode & FALLOC_FL_PUNCH_HOLE) | 3050 | if (mode & FALLOC_FL_PUNCH_HOLE) |
diff --git a/fs/fuse/fuse_i.h b/fs/fuse/fuse_i.h index a257ed8ebee6..7aa5c75e0de1 100644 --- a/fs/fuse/fuse_i.h +++ b/fs/fuse/fuse_i.h | |||
@@ -119,8 +119,6 @@ enum { | |||
119 | FUSE_I_INIT_RDPLUS, | 119 | FUSE_I_INIT_RDPLUS, |
120 | /** An operation changing file size is in progress */ | 120 | /** An operation changing file size is in progress */ |
121 | FUSE_I_SIZE_UNSTABLE, | 121 | FUSE_I_SIZE_UNSTABLE, |
122 | /** i_mtime has been updated locally; a flush to userspace needed */ | ||
123 | FUSE_I_MTIME_DIRTY, | ||
124 | }; | 122 | }; |
125 | 123 | ||
126 | struct fuse_conn; | 124 | struct fuse_conn; |
@@ -544,6 +542,9 @@ struct fuse_conn { | |||
544 | /** Is fallocate not implemented by fs? */ | 542 | /** Is fallocate not implemented by fs? */ |
545 | unsigned no_fallocate:1; | 543 | unsigned no_fallocate:1; |
546 | 544 | ||
545 | /** Is rename with flags implemented by fs? */ | ||
546 | unsigned no_rename2:1; | ||
547 | |||
547 | /** Use enhanced/automatic page cache invalidation. */ | 548 | /** Use enhanced/automatic page cache invalidation. */ |
548 | unsigned auto_inval_data:1; | 549 | unsigned auto_inval_data:1; |
549 | 550 | ||
@@ -725,7 +726,7 @@ int fuse_dev_init(void); | |||
725 | void fuse_dev_cleanup(void); | 726 | void fuse_dev_cleanup(void); |
726 | 727 | ||
727 | int fuse_ctl_init(void); | 728 | int fuse_ctl_init(void); |
728 | void fuse_ctl_cleanup(void); | 729 | void __exit fuse_ctl_cleanup(void); |
729 | 730 | ||
730 | /** | 731 | /** |
731 | * Allocate a request | 732 | * Allocate a request |
@@ -891,7 +892,8 @@ int fuse_dev_release(struct inode *inode, struct file *file); | |||
891 | 892 | ||
892 | bool fuse_write_update_size(struct inode *inode, loff_t pos); | 893 | bool fuse_write_update_size(struct inode *inode, loff_t pos); |
893 | 894 | ||
894 | int fuse_flush_mtime(struct file *file, bool nofail); | 895 | int fuse_flush_times(struct inode *inode, struct fuse_file *ff); |
896 | int fuse_write_inode(struct inode *inode, struct writeback_control *wbc); | ||
895 | 897 | ||
896 | int fuse_do_setattr(struct inode *inode, struct iattr *attr, | 898 | int fuse_do_setattr(struct inode *inode, struct iattr *attr, |
897 | struct file *file); | 899 | struct file *file); |
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c index 8d611696fcad..754dcf23de8a 100644 --- a/fs/fuse/inode.c +++ b/fs/fuse/inode.c | |||
@@ -175,9 +175,9 @@ void fuse_change_attributes_common(struct inode *inode, struct fuse_attr *attr, | |||
175 | if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) { | 175 | if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) { |
176 | inode->i_mtime.tv_sec = attr->mtime; | 176 | inode->i_mtime.tv_sec = attr->mtime; |
177 | inode->i_mtime.tv_nsec = attr->mtimensec; | 177 | inode->i_mtime.tv_nsec = attr->mtimensec; |
178 | inode->i_ctime.tv_sec = attr->ctime; | ||
179 | inode->i_ctime.tv_nsec = attr->ctimensec; | ||
178 | } | 180 | } |
179 | inode->i_ctime.tv_sec = attr->ctime; | ||
180 | inode->i_ctime.tv_nsec = attr->ctimensec; | ||
181 | 181 | ||
182 | if (attr->blksize != 0) | 182 | if (attr->blksize != 0) |
183 | inode->i_blkbits = ilog2(attr->blksize); | 183 | inode->i_blkbits = ilog2(attr->blksize); |
@@ -256,6 +256,8 @@ static void fuse_init_inode(struct inode *inode, struct fuse_attr *attr) | |||
256 | inode->i_size = attr->size; | 256 | inode->i_size = attr->size; |
257 | inode->i_mtime.tv_sec = attr->mtime; | 257 | inode->i_mtime.tv_sec = attr->mtime; |
258 | inode->i_mtime.tv_nsec = attr->mtimensec; | 258 | inode->i_mtime.tv_nsec = attr->mtimensec; |
259 | inode->i_ctime.tv_sec = attr->ctime; | ||
260 | inode->i_ctime.tv_nsec = attr->ctimensec; | ||
259 | if (S_ISREG(inode->i_mode)) { | 261 | if (S_ISREG(inode->i_mode)) { |
260 | fuse_init_common(inode); | 262 | fuse_init_common(inode); |
261 | fuse_init_file_inode(inode); | 263 | fuse_init_file_inode(inode); |
@@ -303,7 +305,7 @@ struct inode *fuse_iget(struct super_block *sb, u64 nodeid, | |||
303 | 305 | ||
304 | if ((inode->i_state & I_NEW)) { | 306 | if ((inode->i_state & I_NEW)) { |
305 | inode->i_flags |= S_NOATIME; | 307 | inode->i_flags |= S_NOATIME; |
306 | if (!fc->writeback_cache || !S_ISREG(inode->i_mode)) | 308 | if (!fc->writeback_cache || !S_ISREG(attr->mode)) |
307 | inode->i_flags |= S_NOCMTIME; | 309 | inode->i_flags |= S_NOCMTIME; |
308 | inode->i_generation = generation; | 310 | inode->i_generation = generation; |
309 | inode->i_data.backing_dev_info = &fc->bdi; | 311 | inode->i_data.backing_dev_info = &fc->bdi; |
@@ -788,6 +790,7 @@ static const struct super_operations fuse_super_operations = { | |||
788 | .alloc_inode = fuse_alloc_inode, | 790 | .alloc_inode = fuse_alloc_inode, |
789 | .destroy_inode = fuse_destroy_inode, | 791 | .destroy_inode = fuse_destroy_inode, |
790 | .evict_inode = fuse_evict_inode, | 792 | .evict_inode = fuse_evict_inode, |
793 | .write_inode = fuse_write_inode, | ||
791 | .drop_inode = generic_delete_inode, | 794 | .drop_inode = generic_delete_inode, |
792 | .remount_fs = fuse_remount_fs, | 795 | .remount_fs = fuse_remount_fs, |
793 | .put_super = fuse_put_super, | 796 | .put_super = fuse_put_super, |
@@ -890,6 +893,11 @@ static void process_init_reply(struct fuse_conn *fc, struct fuse_req *req) | |||
890 | fc->async_dio = 1; | 893 | fc->async_dio = 1; |
891 | if (arg->flags & FUSE_WRITEBACK_CACHE) | 894 | if (arg->flags & FUSE_WRITEBACK_CACHE) |
892 | fc->writeback_cache = 1; | 895 | fc->writeback_cache = 1; |
896 | if (arg->time_gran && arg->time_gran <= 1000000000) | ||
897 | fc->sb->s_time_gran = arg->time_gran; | ||
898 | else | ||
899 | fc->sb->s_time_gran = 1000000000; | ||
900 | |||
893 | } else { | 901 | } else { |
894 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; | 902 | ra_pages = fc->max_read / PAGE_CACHE_SIZE; |
895 | fc->no_lock = 1; | 903 | fc->no_lock = 1; |
@@ -996,7 +1004,7 @@ static int fuse_fill_super(struct super_block *sb, void *data, int silent) | |||
996 | if (sb->s_flags & MS_MANDLOCK) | 1004 | if (sb->s_flags & MS_MANDLOCK) |
997 | goto err; | 1005 | goto err; |
998 | 1006 | ||
999 | sb->s_flags &= ~MS_NOSEC; | 1007 | sb->s_flags &= ~(MS_NOSEC | MS_I_VERSION); |
1000 | 1008 | ||
1001 | if (!parse_fuse_opt((char *) data, &d, is_bdev)) | 1009 | if (!parse_fuse_opt((char *) data, &d, is_bdev)) |
1002 | goto err; | 1010 | goto err; |
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index 204027520937..e19d4c0cacae 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c | |||
@@ -1030,6 +1030,11 @@ static int __init init_hugetlbfs_fs(void) | |||
1030 | int error; | 1030 | int error; |
1031 | int i; | 1031 | int i; |
1032 | 1032 | ||
1033 | if (!hugepages_supported()) { | ||
1034 | pr_info("hugetlbfs: disabling because there are no supported hugepage sizes\n"); | ||
1035 | return -ENOTSUPP; | ||
1036 | } | ||
1037 | |||
1033 | error = bdi_init(&hugetlbfs_backing_dev_info); | 1038 | error = bdi_init(&hugetlbfs_backing_dev_info); |
1034 | if (error) | 1039 | if (error) |
1035 | return error; | 1040 | return error; |
diff --git a/fs/namei.c b/fs/namei.c index c6157c894fce..80168273396b 100644 --- a/fs/namei.c +++ b/fs/namei.c | |||
@@ -1542,7 +1542,7 @@ static inline int walk_component(struct nameidata *nd, struct path *path, | |||
1542 | inode = path->dentry->d_inode; | 1542 | inode = path->dentry->d_inode; |
1543 | } | 1543 | } |
1544 | err = -ENOENT; | 1544 | err = -ENOENT; |
1545 | if (!inode) | 1545 | if (!inode || d_is_negative(path->dentry)) |
1546 | goto out_path_put; | 1546 | goto out_path_put; |
1547 | 1547 | ||
1548 | if (should_follow_link(path->dentry, follow)) { | 1548 | if (should_follow_link(path->dentry, follow)) { |
@@ -2249,7 +2249,7 @@ mountpoint_last(struct nameidata *nd, struct path *path) | |||
2249 | mutex_unlock(&dir->d_inode->i_mutex); | 2249 | mutex_unlock(&dir->d_inode->i_mutex); |
2250 | 2250 | ||
2251 | done: | 2251 | done: |
2252 | if (!dentry->d_inode) { | 2252 | if (!dentry->d_inode || d_is_negative(dentry)) { |
2253 | error = -ENOENT; | 2253 | error = -ENOENT; |
2254 | dput(dentry); | 2254 | dput(dentry); |
2255 | goto out; | 2255 | goto out; |
@@ -2994,7 +2994,7 @@ retry_lookup: | |||
2994 | finish_lookup: | 2994 | finish_lookup: |
2995 | /* we _can_ be in RCU mode here */ | 2995 | /* we _can_ be in RCU mode here */ |
2996 | error = -ENOENT; | 2996 | error = -ENOENT; |
2997 | if (d_is_negative(path->dentry)) { | 2997 | if (!inode || d_is_negative(path->dentry)) { |
2998 | path_to_nameidata(path, nd); | 2998 | path_to_nameidata(path, nd); |
2999 | goto out; | 2999 | goto out; |
3000 | } | 3000 | } |
diff --git a/fs/notify/fanotify/fanotify_user.c b/fs/notify/fanotify/fanotify_user.c index 4e565c814309..732648b270dc 100644 --- a/fs/notify/fanotify/fanotify_user.c +++ b/fs/notify/fanotify/fanotify_user.c | |||
@@ -698,6 +698,8 @@ SYSCALL_DEFINE2(fanotify_init, unsigned int, flags, unsigned int, event_f_flags) | |||
698 | } | 698 | } |
699 | group->overflow_event = &oevent->fse; | 699 | group->overflow_event = &oevent->fse; |
700 | 700 | ||
701 | if (force_o_largefile()) | ||
702 | event_f_flags |= O_LARGEFILE; | ||
701 | group->fanotify_data.f_flags = event_f_flags; | 703 | group->fanotify_data.f_flags = event_f_flags; |
702 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS | 704 | #ifdef CONFIG_FANOTIFY_ACCESS_PERMISSIONS |
703 | spin_lock_init(&group->fanotify_data.access_lock); | 705 | spin_lock_init(&group->fanotify_data.access_lock); |
diff --git a/fs/posix_acl.c b/fs/posix_acl.c index 9e363e41dacc..0855f772cd41 100644 --- a/fs/posix_acl.c +++ b/fs/posix_acl.c | |||
@@ -246,6 +246,12 @@ posix_acl_equiv_mode(const struct posix_acl *acl, umode_t *mode_p) | |||
246 | umode_t mode = 0; | 246 | umode_t mode = 0; |
247 | int not_equiv = 0; | 247 | int not_equiv = 0; |
248 | 248 | ||
249 | /* | ||
250 | * A null ACL can always be presented as mode bits. | ||
251 | */ | ||
252 | if (!acl) | ||
253 | return 0; | ||
254 | |||
249 | FOREACH_ACL_ENTRY(pa, acl, pe) { | 255 | FOREACH_ACL_ENTRY(pa, acl, pe) { |
250 | switch (pa->e_tag) { | 256 | switch (pa->e_tag) { |
251 | case ACL_USER_OBJ: | 257 | case ACL_USER_OBJ: |
diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c index a1266089eca1..a81c7b556896 100644 --- a/fs/ubifs/super.c +++ b/fs/ubifs/super.c | |||
@@ -1556,7 +1556,7 @@ static int ubifs_remount_rw(struct ubifs_info *c) | |||
1556 | if (c->space_fixup) { | 1556 | if (c->space_fixup) { |
1557 | err = ubifs_fixup_free_space(c); | 1557 | err = ubifs_fixup_free_space(c); |
1558 | if (err) | 1558 | if (err) |
1559 | return err; | 1559 | goto out; |
1560 | } | 1560 | } |
1561 | 1561 | ||
1562 | err = check_free_space(c); | 1562 | err = check_free_space(c); |
diff --git a/fs/xfs/xfs_attr.c b/fs/xfs/xfs_attr.c index 01b6a0102fbd..abda1124a70f 100644 --- a/fs/xfs/xfs_attr.c +++ b/fs/xfs/xfs_attr.c | |||
@@ -213,7 +213,7 @@ xfs_attr_calc_size( | |||
213 | * Out of line attribute, cannot double split, but | 213 | * Out of line attribute, cannot double split, but |
214 | * make room for the attribute value itself. | 214 | * make room for the attribute value itself. |
215 | */ | 215 | */ |
216 | uint dblocks = XFS_B_TO_FSB(mp, valuelen); | 216 | uint dblocks = xfs_attr3_rmt_blocks(mp, valuelen); |
217 | nblks += dblocks; | 217 | nblks += dblocks; |
218 | nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK); | 218 | nblks += XFS_NEXTENTADD_SPACE_RES(mp, dblocks, XFS_ATTR_FORK); |
219 | } | 219 | } |
@@ -698,11 +698,22 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) | |||
698 | 698 | ||
699 | trace_xfs_attr_leaf_replace(args); | 699 | trace_xfs_attr_leaf_replace(args); |
700 | 700 | ||
701 | /* save the attribute state for later removal*/ | ||
701 | args->op_flags |= XFS_DA_OP_RENAME; /* an atomic rename */ | 702 | args->op_flags |= XFS_DA_OP_RENAME; /* an atomic rename */ |
702 | args->blkno2 = args->blkno; /* set 2nd entry info*/ | 703 | args->blkno2 = args->blkno; /* set 2nd entry info*/ |
703 | args->index2 = args->index; | 704 | args->index2 = args->index; |
704 | args->rmtblkno2 = args->rmtblkno; | 705 | args->rmtblkno2 = args->rmtblkno; |
705 | args->rmtblkcnt2 = args->rmtblkcnt; | 706 | args->rmtblkcnt2 = args->rmtblkcnt; |
707 | args->rmtvaluelen2 = args->rmtvaluelen; | ||
708 | |||
709 | /* | ||
710 | * clear the remote attr state now that it is saved so that the | ||
711 | * values reflect the state of the attribute we are about to | ||
712 | * add, not the attribute we just found and will remove later. | ||
713 | */ | ||
714 | args->rmtblkno = 0; | ||
715 | args->rmtblkcnt = 0; | ||
716 | args->rmtvaluelen = 0; | ||
706 | } | 717 | } |
707 | 718 | ||
708 | /* | 719 | /* |
@@ -794,6 +805,7 @@ xfs_attr_leaf_addname(xfs_da_args_t *args) | |||
794 | args->blkno = args->blkno2; | 805 | args->blkno = args->blkno2; |
795 | args->rmtblkno = args->rmtblkno2; | 806 | args->rmtblkno = args->rmtblkno2; |
796 | args->rmtblkcnt = args->rmtblkcnt2; | 807 | args->rmtblkcnt = args->rmtblkcnt2; |
808 | args->rmtvaluelen = args->rmtvaluelen2; | ||
797 | if (args->rmtblkno) { | 809 | if (args->rmtblkno) { |
798 | error = xfs_attr_rmtval_remove(args); | 810 | error = xfs_attr_rmtval_remove(args); |
799 | if (error) | 811 | if (error) |
@@ -999,13 +1011,22 @@ restart: | |||
999 | 1011 | ||
1000 | trace_xfs_attr_node_replace(args); | 1012 | trace_xfs_attr_node_replace(args); |
1001 | 1013 | ||
1014 | /* save the attribute state for later removal*/ | ||
1002 | args->op_flags |= XFS_DA_OP_RENAME; /* atomic rename op */ | 1015 | args->op_flags |= XFS_DA_OP_RENAME; /* atomic rename op */ |
1003 | args->blkno2 = args->blkno; /* set 2nd entry info*/ | 1016 | args->blkno2 = args->blkno; /* set 2nd entry info*/ |
1004 | args->index2 = args->index; | 1017 | args->index2 = args->index; |
1005 | args->rmtblkno2 = args->rmtblkno; | 1018 | args->rmtblkno2 = args->rmtblkno; |
1006 | args->rmtblkcnt2 = args->rmtblkcnt; | 1019 | args->rmtblkcnt2 = args->rmtblkcnt; |
1020 | args->rmtvaluelen2 = args->rmtvaluelen; | ||
1021 | |||
1022 | /* | ||
1023 | * clear the remote attr state now that it is saved so that the | ||
1024 | * values reflect the state of the attribute we are about to | ||
1025 | * add, not the attribute we just found and will remove later. | ||
1026 | */ | ||
1007 | args->rmtblkno = 0; | 1027 | args->rmtblkno = 0; |
1008 | args->rmtblkcnt = 0; | 1028 | args->rmtblkcnt = 0; |
1029 | args->rmtvaluelen = 0; | ||
1009 | } | 1030 | } |
1010 | 1031 | ||
1011 | retval = xfs_attr3_leaf_add(blk->bp, state->args); | 1032 | retval = xfs_attr3_leaf_add(blk->bp, state->args); |
@@ -1133,6 +1154,7 @@ restart: | |||
1133 | args->blkno = args->blkno2; | 1154 | args->blkno = args->blkno2; |
1134 | args->rmtblkno = args->rmtblkno2; | 1155 | args->rmtblkno = args->rmtblkno2; |
1135 | args->rmtblkcnt = args->rmtblkcnt2; | 1156 | args->rmtblkcnt = args->rmtblkcnt2; |
1157 | args->rmtvaluelen = args->rmtvaluelen2; | ||
1136 | if (args->rmtblkno) { | 1158 | if (args->rmtblkno) { |
1137 | error = xfs_attr_rmtval_remove(args); | 1159 | error = xfs_attr_rmtval_remove(args); |
1138 | if (error) | 1160 | if (error) |
diff --git a/fs/xfs/xfs_attr_leaf.c b/fs/xfs/xfs_attr_leaf.c index fe9587fab17a..511c283459b1 100644 --- a/fs/xfs/xfs_attr_leaf.c +++ b/fs/xfs/xfs_attr_leaf.c | |||
@@ -1229,6 +1229,7 @@ xfs_attr3_leaf_add_work( | |||
1229 | name_rmt->valueblk = 0; | 1229 | name_rmt->valueblk = 0; |
1230 | args->rmtblkno = 1; | 1230 | args->rmtblkno = 1; |
1231 | args->rmtblkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen); | 1231 | args->rmtblkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen); |
1232 | args->rmtvaluelen = args->valuelen; | ||
1232 | } | 1233 | } |
1233 | xfs_trans_log_buf(args->trans, bp, | 1234 | xfs_trans_log_buf(args->trans, bp, |
1234 | XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index), | 1235 | XFS_DA_LOGRANGE(leaf, xfs_attr3_leaf_name(leaf, args->index), |
@@ -2167,11 +2168,11 @@ xfs_attr3_leaf_lookup_int( | |||
2167 | if (!xfs_attr_namesp_match(args->flags, entry->flags)) | 2168 | if (!xfs_attr_namesp_match(args->flags, entry->flags)) |
2168 | continue; | 2169 | continue; |
2169 | args->index = probe; | 2170 | args->index = probe; |
2170 | args->valuelen = be32_to_cpu(name_rmt->valuelen); | 2171 | args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen); |
2171 | args->rmtblkno = be32_to_cpu(name_rmt->valueblk); | 2172 | args->rmtblkno = be32_to_cpu(name_rmt->valueblk); |
2172 | args->rmtblkcnt = xfs_attr3_rmt_blocks( | 2173 | args->rmtblkcnt = xfs_attr3_rmt_blocks( |
2173 | args->dp->i_mount, | 2174 | args->dp->i_mount, |
2174 | args->valuelen); | 2175 | args->rmtvaluelen); |
2175 | return XFS_ERROR(EEXIST); | 2176 | return XFS_ERROR(EEXIST); |
2176 | } | 2177 | } |
2177 | } | 2178 | } |
@@ -2220,19 +2221,19 @@ xfs_attr3_leaf_getvalue( | |||
2220 | name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); | 2221 | name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); |
2221 | ASSERT(name_rmt->namelen == args->namelen); | 2222 | ASSERT(name_rmt->namelen == args->namelen); |
2222 | ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0); | 2223 | ASSERT(memcmp(args->name, name_rmt->name, args->namelen) == 0); |
2223 | valuelen = be32_to_cpu(name_rmt->valuelen); | 2224 | args->rmtvaluelen = be32_to_cpu(name_rmt->valuelen); |
2224 | args->rmtblkno = be32_to_cpu(name_rmt->valueblk); | 2225 | args->rmtblkno = be32_to_cpu(name_rmt->valueblk); |
2225 | args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount, | 2226 | args->rmtblkcnt = xfs_attr3_rmt_blocks(args->dp->i_mount, |
2226 | valuelen); | 2227 | args->rmtvaluelen); |
2227 | if (args->flags & ATTR_KERNOVAL) { | 2228 | if (args->flags & ATTR_KERNOVAL) { |
2228 | args->valuelen = valuelen; | 2229 | args->valuelen = args->rmtvaluelen; |
2229 | return 0; | 2230 | return 0; |
2230 | } | 2231 | } |
2231 | if (args->valuelen < valuelen) { | 2232 | if (args->valuelen < args->rmtvaluelen) { |
2232 | args->valuelen = valuelen; | 2233 | args->valuelen = args->rmtvaluelen; |
2233 | return XFS_ERROR(ERANGE); | 2234 | return XFS_ERROR(ERANGE); |
2234 | } | 2235 | } |
2235 | args->valuelen = valuelen; | 2236 | args->valuelen = args->rmtvaluelen; |
2236 | } | 2237 | } |
2237 | return 0; | 2238 | return 0; |
2238 | } | 2239 | } |
@@ -2519,7 +2520,7 @@ xfs_attr3_leaf_clearflag( | |||
2519 | ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0); | 2520 | ASSERT((entry->flags & XFS_ATTR_LOCAL) == 0); |
2520 | name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); | 2521 | name_rmt = xfs_attr3_leaf_name_remote(leaf, args->index); |
2521 | name_rmt->valueblk = cpu_to_be32(args->rmtblkno); | 2522 | name_rmt->valueblk = cpu_to_be32(args->rmtblkno); |
2522 | name_rmt->valuelen = cpu_to_be32(args->valuelen); | 2523 | name_rmt->valuelen = cpu_to_be32(args->rmtvaluelen); |
2523 | xfs_trans_log_buf(args->trans, bp, | 2524 | xfs_trans_log_buf(args->trans, bp, |
2524 | XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); | 2525 | XFS_DA_LOGRANGE(leaf, name_rmt, sizeof(*name_rmt))); |
2525 | } | 2526 | } |
@@ -2677,7 +2678,7 @@ xfs_attr3_leaf_flipflags( | |||
2677 | ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0); | 2678 | ASSERT((entry1->flags & XFS_ATTR_LOCAL) == 0); |
2678 | name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index); | 2679 | name_rmt = xfs_attr3_leaf_name_remote(leaf1, args->index); |
2679 | name_rmt->valueblk = cpu_to_be32(args->rmtblkno); | 2680 | name_rmt->valueblk = cpu_to_be32(args->rmtblkno); |
2680 | name_rmt->valuelen = cpu_to_be32(args->valuelen); | 2681 | name_rmt->valuelen = cpu_to_be32(args->rmtvaluelen); |
2681 | xfs_trans_log_buf(args->trans, bp1, | 2682 | xfs_trans_log_buf(args->trans, bp1, |
2682 | XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt))); | 2683 | XFS_DA_LOGRANGE(leaf1, name_rmt, sizeof(*name_rmt))); |
2683 | } | 2684 | } |
diff --git a/fs/xfs/xfs_attr_list.c b/fs/xfs/xfs_attr_list.c index 01db96f60cf0..833fe5d98d80 100644 --- a/fs/xfs/xfs_attr_list.c +++ b/fs/xfs/xfs_attr_list.c | |||
@@ -447,6 +447,7 @@ xfs_attr3_leaf_list_int( | |||
447 | args.dp = context->dp; | 447 | args.dp = context->dp; |
448 | args.whichfork = XFS_ATTR_FORK; | 448 | args.whichfork = XFS_ATTR_FORK; |
449 | args.valuelen = valuelen; | 449 | args.valuelen = valuelen; |
450 | args.rmtvaluelen = valuelen; | ||
450 | args.value = kmem_alloc(valuelen, KM_SLEEP | KM_NOFS); | 451 | args.value = kmem_alloc(valuelen, KM_SLEEP | KM_NOFS); |
451 | args.rmtblkno = be32_to_cpu(name_rmt->valueblk); | 452 | args.rmtblkno = be32_to_cpu(name_rmt->valueblk); |
452 | args.rmtblkcnt = xfs_attr3_rmt_blocks( | 453 | args.rmtblkcnt = xfs_attr3_rmt_blocks( |
diff --git a/fs/xfs/xfs_attr_remote.c b/fs/xfs/xfs_attr_remote.c index 6e37823e2932..d2e6e948cec7 100644 --- a/fs/xfs/xfs_attr_remote.c +++ b/fs/xfs/xfs_attr_remote.c | |||
@@ -337,7 +337,7 @@ xfs_attr_rmtval_get( | |||
337 | struct xfs_buf *bp; | 337 | struct xfs_buf *bp; |
338 | xfs_dablk_t lblkno = args->rmtblkno; | 338 | xfs_dablk_t lblkno = args->rmtblkno; |
339 | __uint8_t *dst = args->value; | 339 | __uint8_t *dst = args->value; |
340 | int valuelen = args->valuelen; | 340 | int valuelen; |
341 | int nmap; | 341 | int nmap; |
342 | int error; | 342 | int error; |
343 | int blkcnt = args->rmtblkcnt; | 343 | int blkcnt = args->rmtblkcnt; |
@@ -347,7 +347,9 @@ xfs_attr_rmtval_get( | |||
347 | trace_xfs_attr_rmtval_get(args); | 347 | trace_xfs_attr_rmtval_get(args); |
348 | 348 | ||
349 | ASSERT(!(args->flags & ATTR_KERNOVAL)); | 349 | ASSERT(!(args->flags & ATTR_KERNOVAL)); |
350 | ASSERT(args->rmtvaluelen == args->valuelen); | ||
350 | 351 | ||
352 | valuelen = args->rmtvaluelen; | ||
351 | while (valuelen > 0) { | 353 | while (valuelen > 0) { |
352 | nmap = ATTR_RMTVALUE_MAPSIZE; | 354 | nmap = ATTR_RMTVALUE_MAPSIZE; |
353 | error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno, | 355 | error = xfs_bmapi_read(args->dp, (xfs_fileoff_t)lblkno, |
@@ -415,7 +417,7 @@ xfs_attr_rmtval_set( | |||
415 | * attributes have headers, we can't just do a straight byte to FSB | 417 | * attributes have headers, we can't just do a straight byte to FSB |
416 | * conversion and have to take the header space into account. | 418 | * conversion and have to take the header space into account. |
417 | */ | 419 | */ |
418 | blkcnt = xfs_attr3_rmt_blocks(mp, args->valuelen); | 420 | blkcnt = xfs_attr3_rmt_blocks(mp, args->rmtvaluelen); |
419 | error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff, | 421 | error = xfs_bmap_first_unused(args->trans, args->dp, blkcnt, &lfileoff, |
420 | XFS_ATTR_FORK); | 422 | XFS_ATTR_FORK); |
421 | if (error) | 423 | if (error) |
@@ -480,7 +482,7 @@ xfs_attr_rmtval_set( | |||
480 | */ | 482 | */ |
481 | lblkno = args->rmtblkno; | 483 | lblkno = args->rmtblkno; |
482 | blkcnt = args->rmtblkcnt; | 484 | blkcnt = args->rmtblkcnt; |
483 | valuelen = args->valuelen; | 485 | valuelen = args->rmtvaluelen; |
484 | while (valuelen > 0) { | 486 | while (valuelen > 0) { |
485 | struct xfs_buf *bp; | 487 | struct xfs_buf *bp; |
486 | xfs_daddr_t dblkno; | 488 | xfs_daddr_t dblkno; |
diff --git a/fs/xfs/xfs_da_btree.h b/fs/xfs/xfs_da_btree.h index 6e95ea79f5d7..201c6091d26a 100644 --- a/fs/xfs/xfs_da_btree.h +++ b/fs/xfs/xfs_da_btree.h | |||
@@ -60,10 +60,12 @@ typedef struct xfs_da_args { | |||
60 | int index; /* index of attr of interest in blk */ | 60 | int index; /* index of attr of interest in blk */ |
61 | xfs_dablk_t rmtblkno; /* remote attr value starting blkno */ | 61 | xfs_dablk_t rmtblkno; /* remote attr value starting blkno */ |
62 | int rmtblkcnt; /* remote attr value block count */ | 62 | int rmtblkcnt; /* remote attr value block count */ |
63 | int rmtvaluelen; /* remote attr value length in bytes */ | ||
63 | xfs_dablk_t blkno2; /* blkno of 2nd attr leaf of interest */ | 64 | xfs_dablk_t blkno2; /* blkno of 2nd attr leaf of interest */ |
64 | int index2; /* index of 2nd attr in blk */ | 65 | int index2; /* index of 2nd attr in blk */ |
65 | xfs_dablk_t rmtblkno2; /* remote attr value starting blkno */ | 66 | xfs_dablk_t rmtblkno2; /* remote attr value starting blkno */ |
66 | int rmtblkcnt2; /* remote attr value block count */ | 67 | int rmtblkcnt2; /* remote attr value block count */ |
68 | int rmtvaluelen2; /* remote attr value length in bytes */ | ||
67 | int op_flags; /* operation flags */ | 69 | int op_flags; /* operation flags */ |
68 | enum xfs_dacmp cmpresult; /* name compare result for lookups */ | 70 | enum xfs_dacmp cmpresult; /* name compare result for lookups */ |
69 | } xfs_da_args_t; | 71 | } xfs_da_args_t; |
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c index ef1ca010f417..301ecbfcc0be 100644 --- a/fs/xfs/xfs_iops.c +++ b/fs/xfs/xfs_iops.c | |||
@@ -124,15 +124,15 @@ xfs_cleanup_inode( | |||
124 | xfs_dentry_to_name(&teardown, dentry, 0); | 124 | xfs_dentry_to_name(&teardown, dentry, 0); |
125 | 125 | ||
126 | xfs_remove(XFS_I(dir), &teardown, XFS_I(inode)); | 126 | xfs_remove(XFS_I(dir), &teardown, XFS_I(inode)); |
127 | iput(inode); | ||
128 | } | 127 | } |
129 | 128 | ||
130 | STATIC int | 129 | STATIC int |
131 | xfs_vn_mknod( | 130 | xfs_generic_create( |
132 | struct inode *dir, | 131 | struct inode *dir, |
133 | struct dentry *dentry, | 132 | struct dentry *dentry, |
134 | umode_t mode, | 133 | umode_t mode, |
135 | dev_t rdev) | 134 | dev_t rdev, |
135 | bool tmpfile) /* unnamed file */ | ||
136 | { | 136 | { |
137 | struct inode *inode; | 137 | struct inode *inode; |
138 | struct xfs_inode *ip = NULL; | 138 | struct xfs_inode *ip = NULL; |
@@ -156,8 +156,12 @@ xfs_vn_mknod( | |||
156 | if (error) | 156 | if (error) |
157 | return error; | 157 | return error; |
158 | 158 | ||
159 | xfs_dentry_to_name(&name, dentry, mode); | 159 | if (!tmpfile) { |
160 | error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip); | 160 | xfs_dentry_to_name(&name, dentry, mode); |
161 | error = xfs_create(XFS_I(dir), &name, mode, rdev, &ip); | ||
162 | } else { | ||
163 | error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip); | ||
164 | } | ||
161 | if (unlikely(error)) | 165 | if (unlikely(error)) |
162 | goto out_free_acl; | 166 | goto out_free_acl; |
163 | 167 | ||
@@ -180,7 +184,11 @@ xfs_vn_mknod( | |||
180 | } | 184 | } |
181 | #endif | 185 | #endif |
182 | 186 | ||
183 | d_instantiate(dentry, inode); | 187 | if (tmpfile) |
188 | d_tmpfile(dentry, inode); | ||
189 | else | ||
190 | d_instantiate(dentry, inode); | ||
191 | |||
184 | out_free_acl: | 192 | out_free_acl: |
185 | if (default_acl) | 193 | if (default_acl) |
186 | posix_acl_release(default_acl); | 194 | posix_acl_release(default_acl); |
@@ -189,11 +197,23 @@ xfs_vn_mknod( | |||
189 | return -error; | 197 | return -error; |
190 | 198 | ||
191 | out_cleanup_inode: | 199 | out_cleanup_inode: |
192 | xfs_cleanup_inode(dir, inode, dentry); | 200 | if (!tmpfile) |
201 | xfs_cleanup_inode(dir, inode, dentry); | ||
202 | iput(inode); | ||
193 | goto out_free_acl; | 203 | goto out_free_acl; |
194 | } | 204 | } |
195 | 205 | ||
196 | STATIC int | 206 | STATIC int |
207 | xfs_vn_mknod( | ||
208 | struct inode *dir, | ||
209 | struct dentry *dentry, | ||
210 | umode_t mode, | ||
211 | dev_t rdev) | ||
212 | { | ||
213 | return xfs_generic_create(dir, dentry, mode, rdev, false); | ||
214 | } | ||
215 | |||
216 | STATIC int | ||
197 | xfs_vn_create( | 217 | xfs_vn_create( |
198 | struct inode *dir, | 218 | struct inode *dir, |
199 | struct dentry *dentry, | 219 | struct dentry *dentry, |
@@ -353,6 +373,7 @@ xfs_vn_symlink( | |||
353 | 373 | ||
354 | out_cleanup_inode: | 374 | out_cleanup_inode: |
355 | xfs_cleanup_inode(dir, inode, dentry); | 375 | xfs_cleanup_inode(dir, inode, dentry); |
376 | iput(inode); | ||
356 | out: | 377 | out: |
357 | return -error; | 378 | return -error; |
358 | } | 379 | } |
@@ -1053,25 +1074,7 @@ xfs_vn_tmpfile( | |||
1053 | struct dentry *dentry, | 1074 | struct dentry *dentry, |
1054 | umode_t mode) | 1075 | umode_t mode) |
1055 | { | 1076 | { |
1056 | int error; | 1077 | return xfs_generic_create(dir, dentry, mode, 0, true); |
1057 | struct xfs_inode *ip; | ||
1058 | struct inode *inode; | ||
1059 | |||
1060 | error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip); | ||
1061 | if (unlikely(error)) | ||
1062 | return -error; | ||
1063 | |||
1064 | inode = VFS_I(ip); | ||
1065 | |||
1066 | error = xfs_init_security(inode, dir, &dentry->d_name); | ||
1067 | if (unlikely(error)) { | ||
1068 | iput(inode); | ||
1069 | return -error; | ||
1070 | } | ||
1071 | |||
1072 | d_tmpfile(dentry, inode); | ||
1073 | |||
1074 | return 0; | ||
1075 | } | 1078 | } |
1076 | 1079 | ||
1077 | static const struct inode_operations xfs_inode_operations = { | 1080 | static const struct inode_operations xfs_inode_operations = { |
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c index 08624dc67317..a5f8bd9899d3 100644 --- a/fs/xfs/xfs_log.c +++ b/fs/xfs/xfs_log.c | |||
@@ -616,11 +616,13 @@ xfs_log_mount( | |||
616 | int error = 0; | 616 | int error = 0; |
617 | int min_logfsbs; | 617 | int min_logfsbs; |
618 | 618 | ||
619 | if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) | 619 | if (!(mp->m_flags & XFS_MOUNT_NORECOVERY)) { |
620 | xfs_notice(mp, "Mounting Filesystem"); | 620 | xfs_notice(mp, "Mounting V%d Filesystem", |
621 | else { | 621 | XFS_SB_VERSION_NUM(&mp->m_sb)); |
622 | } else { | ||
622 | xfs_notice(mp, | 623 | xfs_notice(mp, |
623 | "Mounting filesystem in no-recovery mode. Filesystem will be inconsistent."); | 624 | "Mounting V%d filesystem in no-recovery mode. Filesystem will be inconsistent.", |
625 | XFS_SB_VERSION_NUM(&mp->m_sb)); | ||
624 | ASSERT(mp->m_flags & XFS_MOUNT_RDONLY); | 626 | ASSERT(mp->m_flags & XFS_MOUNT_RDONLY); |
625 | } | 627 | } |
626 | 628 | ||
diff --git a/fs/xfs/xfs_mount.c b/fs/xfs/xfs_mount.c index 993cb19e7d39..944f3d9456a8 100644 --- a/fs/xfs/xfs_mount.c +++ b/fs/xfs/xfs_mount.c | |||
@@ -743,8 +743,6 @@ xfs_mountfs( | |||
743 | new_size *= mp->m_sb.sb_inodesize / XFS_DINODE_MIN_SIZE; | 743 | new_size *= mp->m_sb.sb_inodesize / XFS_DINODE_MIN_SIZE; |
744 | if (mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, new_size)) | 744 | if (mp->m_sb.sb_inoalignmt >= XFS_B_TO_FSBT(mp, new_size)) |
745 | mp->m_inode_cluster_size = new_size; | 745 | mp->m_inode_cluster_size = new_size; |
746 | xfs_info(mp, "Using inode cluster size of %d bytes", | ||
747 | mp->m_inode_cluster_size); | ||
748 | } | 746 | } |
749 | 747 | ||
750 | /* | 748 | /* |
diff --git a/fs/xfs/xfs_sb.c b/fs/xfs/xfs_sb.c index 0c0e41bbe4e3..8baf61afae1d 100644 --- a/fs/xfs/xfs_sb.c +++ b/fs/xfs/xfs_sb.c | |||
@@ -201,10 +201,6 @@ xfs_mount_validate_sb( | |||
201 | * write validation, we don't need to check feature masks. | 201 | * write validation, we don't need to check feature masks. |
202 | */ | 202 | */ |
203 | if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) { | 203 | if (check_version && XFS_SB_VERSION_NUM(sbp) == XFS_SB_VERSION_5) { |
204 | xfs_alert(mp, | ||
205 | "Version 5 superblock detected. This kernel has EXPERIMENTAL support enabled!\n" | ||
206 | "Use of these features in this kernel is at your own risk!"); | ||
207 | |||
208 | if (xfs_sb_has_compat_feature(sbp, | 204 | if (xfs_sb_has_compat_feature(sbp, |
209 | XFS_SB_FEAT_COMPAT_UNKNOWN)) { | 205 | XFS_SB_FEAT_COMPAT_UNKNOWN)) { |
210 | xfs_warn(mp, | 206 | xfs_warn(mp, |
diff --git a/include/drm/drm_pciids.h b/include/drm/drm_pciids.h index 49376aec2fbb..6dfd64b3a604 100644 --- a/include/drm/drm_pciids.h +++ b/include/drm/drm_pciids.h | |||
@@ -637,6 +637,22 @@ | |||
637 | {0x1002, 0x983d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | 637 | {0x1002, 0x983d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ |
638 | {0x1002, 0x983e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | 638 | {0x1002, 0x983e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ |
639 | {0x1002, 0x983f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | 639 | {0x1002, 0x983f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_KABINI|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ |
640 | {0x1002, 0x9850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
641 | {0x1002, 0x9851, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
642 | {0x1002, 0x9852, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
643 | {0x1002, 0x9853, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
644 | {0x1002, 0x9854, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
645 | {0x1002, 0x9855, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
646 | {0x1002, 0x9856, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
647 | {0x1002, 0x9857, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
648 | {0x1002, 0x9858, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
649 | {0x1002, 0x9859, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
650 | {0x1002, 0x985A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
651 | {0x1002, 0x985B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
652 | {0x1002, 0x985C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
653 | {0x1002, 0x985D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
654 | {0x1002, 0x985E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
655 | {0x1002, 0x985F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_MULLINS|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | ||
640 | {0x1002, 0x9900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | 656 | {0x1002, 0x9900, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ |
641 | {0x1002, 0x9901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | 657 | {0x1002, 0x9901, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ |
642 | {0x1002, 0x9903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ | 658 | {0x1002, 0x9903, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_ARUBA|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP|RADEON_IS_IGP}, \ |
diff --git a/include/drm/i915_pciids.h b/include/drm/i915_pciids.h index 940ece4934ba..012d58fa8ff0 100644 --- a/include/drm/i915_pciids.h +++ b/include/drm/i915_pciids.h | |||
@@ -191,8 +191,8 @@ | |||
191 | INTEL_VGA_DEVICE(0x0A06, info), /* ULT GT1 mobile */ \ | 191 | INTEL_VGA_DEVICE(0x0A06, info), /* ULT GT1 mobile */ \ |
192 | INTEL_VGA_DEVICE(0x0A16, info), /* ULT GT2 mobile */ \ | 192 | INTEL_VGA_DEVICE(0x0A16, info), /* ULT GT2 mobile */ \ |
193 | INTEL_VGA_DEVICE(0x0A26, info), /* ULT GT3 mobile */ \ | 193 | INTEL_VGA_DEVICE(0x0A26, info), /* ULT GT3 mobile */ \ |
194 | INTEL_VGA_DEVICE(0x0A0E, info), /* ULT GT1 reserved */ \ | 194 | INTEL_VGA_DEVICE(0x0A0E, info), /* ULX GT1 mobile */ \ |
195 | INTEL_VGA_DEVICE(0x0A1E, info), /* ULT GT2 reserved */ \ | 195 | INTEL_VGA_DEVICE(0x0A1E, info), /* ULX GT2 mobile */ \ |
196 | INTEL_VGA_DEVICE(0x0A2E, info), /* ULT GT3 reserved */ \ | 196 | INTEL_VGA_DEVICE(0x0A2E, info), /* ULT GT3 reserved */ \ |
197 | INTEL_VGA_DEVICE(0x0D06, info), /* CRW GT1 mobile */ \ | 197 | INTEL_VGA_DEVICE(0x0D06, info), /* CRW GT1 mobile */ \ |
198 | INTEL_VGA_DEVICE(0x0D16, info), /* CRW GT2 mobile */ \ | 198 | INTEL_VGA_DEVICE(0x0D16, info), /* CRW GT2 mobile */ \ |
diff --git a/include/linux/dcache.h b/include/linux/dcache.h index 3b9bfdb83ba6..3c7ec327ebd2 100644 --- a/include/linux/dcache.h +++ b/include/linux/dcache.h | |||
@@ -221,6 +221,8 @@ struct dentry_operations { | |||
221 | #define DCACHE_SYMLINK_TYPE 0x00300000 /* Symlink */ | 221 | #define DCACHE_SYMLINK_TYPE 0x00300000 /* Symlink */ |
222 | #define DCACHE_FILE_TYPE 0x00400000 /* Other file type */ | 222 | #define DCACHE_FILE_TYPE 0x00400000 /* Other file type */ |
223 | 223 | ||
224 | #define DCACHE_MAY_FREE 0x00800000 | ||
225 | |||
224 | extern seqlock_t rename_lock; | 226 | extern seqlock_t rename_lock; |
225 | 227 | ||
226 | static inline int dname_external(const struct dentry *dentry) | 228 | static inline int dname_external(const struct dentry *dentry) |
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 5b337cf8fb86..b65166de1d9d 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h | |||
@@ -412,6 +412,16 @@ static inline spinlock_t *huge_pte_lockptr(struct hstate *h, | |||
412 | return &mm->page_table_lock; | 412 | return &mm->page_table_lock; |
413 | } | 413 | } |
414 | 414 | ||
415 | static inline bool hugepages_supported(void) | ||
416 | { | ||
417 | /* | ||
418 | * Some platform decide whether they support huge pages at boot | ||
419 | * time. On these, such as powerpc, HPAGE_SHIFT is set to 0 when | ||
420 | * there is no such support | ||
421 | */ | ||
422 | return HPAGE_SHIFT != 0; | ||
423 | } | ||
424 | |||
415 | #else /* CONFIG_HUGETLB_PAGE */ | 425 | #else /* CONFIG_HUGETLB_PAGE */ |
416 | struct hstate {}; | 426 | struct hstate {}; |
417 | #define alloc_huge_page_node(h, nid) NULL | 427 | #define alloc_huge_page_node(h, nid) NULL |
diff --git a/include/linux/linkage.h b/include/linux/linkage.h index 34a513a2727b..a6a42dd02466 100644 --- a/include/linux/linkage.h +++ b/include/linux/linkage.h | |||
@@ -12,9 +12,9 @@ | |||
12 | #endif | 12 | #endif |
13 | 13 | ||
14 | #ifdef __cplusplus | 14 | #ifdef __cplusplus |
15 | #define CPP_ASMLINKAGE extern "C" __visible | 15 | #define CPP_ASMLINKAGE extern "C" |
16 | #else | 16 | #else |
17 | #define CPP_ASMLINKAGE __visible | 17 | #define CPP_ASMLINKAGE |
18 | #endif | 18 | #endif |
19 | 19 | ||
20 | #ifndef asmlinkage | 20 | #ifndef asmlinkage |
diff --git a/include/linux/mfd/rtsx_common.h b/include/linux/mfd/rtsx_common.h index 7c36cc55d2c7..443176ee1ab0 100644 --- a/include/linux/mfd/rtsx_common.h +++ b/include/linux/mfd/rtsx_common.h | |||
@@ -45,7 +45,6 @@ struct platform_device; | |||
45 | struct rtsx_slot { | 45 | struct rtsx_slot { |
46 | struct platform_device *p_dev; | 46 | struct platform_device *p_dev; |
47 | void (*card_event)(struct platform_device *p_dev); | 47 | void (*card_event)(struct platform_device *p_dev); |
48 | void (*done_transfer)(struct platform_device *p_dev); | ||
49 | }; | 48 | }; |
50 | 49 | ||
51 | #endif | 50 | #endif |
diff --git a/include/linux/mfd/rtsx_pci.h b/include/linux/mfd/rtsx_pci.h index 8d6bbd609ad9..a3835976f7c6 100644 --- a/include/linux/mfd/rtsx_pci.h +++ b/include/linux/mfd/rtsx_pci.h | |||
@@ -943,12 +943,6 @@ void rtsx_pci_send_cmd_no_wait(struct rtsx_pcr *pcr); | |||
943 | int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout); | 943 | int rtsx_pci_send_cmd(struct rtsx_pcr *pcr, int timeout); |
944 | int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, | 944 | int rtsx_pci_transfer_data(struct rtsx_pcr *pcr, struct scatterlist *sglist, |
945 | int num_sg, bool read, int timeout); | 945 | int num_sg, bool read, int timeout); |
946 | int rtsx_pci_dma_map_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
947 | int num_sg, bool read); | ||
948 | int rtsx_pci_dma_unmap_sg(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
949 | int num_sg, bool read); | ||
950 | int rtsx_pci_dma_transfer(struct rtsx_pcr *pcr, struct scatterlist *sglist, | ||
951 | int sg_count, bool read); | ||
952 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); | 946 | int rtsx_pci_read_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); |
953 | int rtsx_pci_write_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); | 947 | int rtsx_pci_write_ppbuf(struct rtsx_pcr *pcr, u8 *buf, int buf_len); |
954 | int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card); | 948 | int rtsx_pci_card_pull_ctl_enable(struct rtsx_pcr *pcr, int card); |
diff --git a/include/linux/mm.h b/include/linux/mm.h index bf9811e1321a..d6777060449f 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h | |||
@@ -370,6 +370,8 @@ static inline int is_vmalloc_or_module_addr(const void *x) | |||
370 | } | 370 | } |
371 | #endif | 371 | #endif |
372 | 372 | ||
373 | extern void kvfree(const void *addr); | ||
374 | |||
373 | static inline void compound_lock(struct page *page) | 375 | static inline void compound_lock(struct page *page) |
374 | { | 376 | { |
375 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | 377 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE |
diff --git a/include/linux/netlink.h b/include/linux/netlink.h index aad8eeaf416d..f64b01787ddc 100644 --- a/include/linux/netlink.h +++ b/include/linux/netlink.h | |||
@@ -169,4 +169,11 @@ struct netlink_tap { | |||
169 | extern int netlink_add_tap(struct netlink_tap *nt); | 169 | extern int netlink_add_tap(struct netlink_tap *nt); |
170 | extern int netlink_remove_tap(struct netlink_tap *nt); | 170 | extern int netlink_remove_tap(struct netlink_tap *nt); |
171 | 171 | ||
172 | bool __netlink_ns_capable(const struct netlink_skb_parms *nsp, | ||
173 | struct user_namespace *ns, int cap); | ||
174 | bool netlink_ns_capable(const struct sk_buff *skb, | ||
175 | struct user_namespace *ns, int cap); | ||
176 | bool netlink_capable(const struct sk_buff *skb, int cap); | ||
177 | bool netlink_net_capable(const struct sk_buff *skb, int cap); | ||
178 | |||
172 | #endif /* __LINUX_NETLINK_H */ | 179 | #endif /* __LINUX_NETLINK_H */ |
diff --git a/include/linux/of.h b/include/linux/of.h index 3bad8d106e0e..4c50d0b78b89 100644 --- a/include/linux/of.h +++ b/include/linux/of.h | |||
@@ -130,6 +130,12 @@ static inline int of_node_check_flag(struct device_node *n, unsigned long flag) | |||
130 | return test_bit(flag, &n->_flags); | 130 | return test_bit(flag, &n->_flags); |
131 | } | 131 | } |
132 | 132 | ||
133 | static inline int of_node_test_and_set_flag(struct device_node *n, | ||
134 | unsigned long flag) | ||
135 | { | ||
136 | return test_and_set_bit(flag, &n->_flags); | ||
137 | } | ||
138 | |||
133 | static inline void of_node_set_flag(struct device_node *n, unsigned long flag) | 139 | static inline void of_node_set_flag(struct device_node *n, unsigned long flag) |
134 | { | 140 | { |
135 | set_bit(flag, &n->_flags); | 141 | set_bit(flag, &n->_flags); |
@@ -197,6 +203,7 @@ static inline unsigned long of_read_ulong(const __be32 *cell, int size) | |||
197 | /* flag descriptions */ | 203 | /* flag descriptions */ |
198 | #define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */ | 204 | #define OF_DYNAMIC 1 /* node and properties were allocated via kmalloc */ |
199 | #define OF_DETACHED 2 /* node has been detached from the device tree */ | 205 | #define OF_DETACHED 2 /* node has been detached from the device tree */ |
206 | #define OF_POPULATED 3 /* device already created for the node */ | ||
200 | 207 | ||
201 | #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags) | 208 | #define OF_IS_DYNAMIC(x) test_bit(OF_DYNAMIC, &x->_flags) |
202 | #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags) | 209 | #define OF_MARK_DYNAMIC(x) set_bit(OF_DYNAMIC, &x->_flags) |
diff --git a/include/linux/of_platform.h b/include/linux/of_platform.h index 05cb4a928252..b1010eeaac0d 100644 --- a/include/linux/of_platform.h +++ b/include/linux/of_platform.h | |||
@@ -72,6 +72,7 @@ extern int of_platform_populate(struct device_node *root, | |||
72 | const struct of_device_id *matches, | 72 | const struct of_device_id *matches, |
73 | const struct of_dev_auxdata *lookup, | 73 | const struct of_dev_auxdata *lookup, |
74 | struct device *parent); | 74 | struct device *parent); |
75 | extern int of_platform_depopulate(struct device *parent); | ||
75 | #else | 76 | #else |
76 | static inline int of_platform_populate(struct device_node *root, | 77 | static inline int of_platform_populate(struct device_node *root, |
77 | const struct of_device_id *matches, | 78 | const struct of_device_id *matches, |
@@ -80,6 +81,10 @@ static inline int of_platform_populate(struct device_node *root, | |||
80 | { | 81 | { |
81 | return -ENODEV; | 82 | return -ENODEV; |
82 | } | 83 | } |
84 | static inline int of_platform_depopulate(struct device *parent) | ||
85 | { | ||
86 | return -ENODEV; | ||
87 | } | ||
83 | #endif | 88 | #endif |
84 | 89 | ||
85 | #endif /* _LINUX_OF_PLATFORM_H */ | 90 | #endif /* _LINUX_OF_PLATFORM_H */ |
diff --git a/include/linux/platform_data/syscon.h b/include/linux/platform_data/syscon.h new file mode 100644 index 000000000000..2354c6fa3726 --- /dev/null +++ b/include/linux/platform_data/syscon.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef PLATFORM_DATA_SYSCON_H | ||
2 | #define PLATFORM_DATA_SYSCON_H | ||
3 | |||
4 | struct syscon_platform_data { | ||
5 | const char *label; | ||
6 | }; | ||
7 | |||
8 | #endif | ||
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h index f2f7398848cf..d82abd40a3c0 100644 --- a/include/linux/slub_def.h +++ b/include/linux/slub_def.h | |||
@@ -101,4 +101,13 @@ struct kmem_cache { | |||
101 | struct kmem_cache_node *node[MAX_NUMNODES]; | 101 | struct kmem_cache_node *node[MAX_NUMNODES]; |
102 | }; | 102 | }; |
103 | 103 | ||
104 | #ifdef CONFIG_SYSFS | ||
105 | #define SLAB_SUPPORTS_SYSFS | ||
106 | void sysfs_slab_remove(struct kmem_cache *); | ||
107 | #else | ||
108 | static inline void sysfs_slab_remove(struct kmem_cache *s) | ||
109 | { | ||
110 | } | ||
111 | #endif | ||
112 | |||
104 | #endif /* _LINUX_SLUB_DEF_H */ | 113 | #endif /* _LINUX_SLUB_DEF_H */ |
diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h index 54f91d35e5fd..46cca4c06848 100644 --- a/include/linux/sock_diag.h +++ b/include/linux/sock_diag.h | |||
@@ -23,7 +23,7 @@ int sock_diag_check_cookie(void *sk, __u32 *cookie); | |||
23 | void sock_diag_save_cookie(void *sk, __u32 *cookie); | 23 | void sock_diag_save_cookie(void *sk, __u32 *cookie); |
24 | 24 | ||
25 | int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr); | 25 | int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr); |
26 | int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk, | 26 | int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk, |
27 | struct sk_buff *skb, int attrtype); | 27 | struct sk_buff *skb, int attrtype); |
28 | 28 | ||
29 | #endif | 29 | #endif |
diff --git a/include/linux/tty.h b/include/linux/tty.h index 036cccd80d9f..1c3316a47d7e 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h | |||
@@ -61,7 +61,6 @@ struct tty_bufhead { | |||
61 | struct tty_buffer *head; /* Queue head */ | 61 | struct tty_buffer *head; /* Queue head */ |
62 | struct work_struct work; | 62 | struct work_struct work; |
63 | struct mutex lock; | 63 | struct mutex lock; |
64 | spinlock_t flush_lock; | ||
65 | atomic_t priority; | 64 | atomic_t priority; |
66 | struct tty_buffer sentinel; | 65 | struct tty_buffer sentinel; |
67 | struct llist_head free; /* Free queue head */ | 66 | struct llist_head free; /* Free queue head */ |
diff --git a/include/linux/vexpress.h b/include/linux/vexpress.h index 617c01b8f74a..a4c9547aae64 100644 --- a/include/linux/vexpress.h +++ b/include/linux/vexpress.h | |||
@@ -15,28 +15,15 @@ | |||
15 | #define _LINUX_VEXPRESS_H | 15 | #define _LINUX_VEXPRESS_H |
16 | 16 | ||
17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
18 | #include <linux/platform_device.h> | ||
18 | #include <linux/reboot.h> | 19 | #include <linux/reboot.h> |
20 | #include <linux/regmap.h> | ||
19 | 21 | ||
20 | #define VEXPRESS_SITE_MB 0 | 22 | #define VEXPRESS_SITE_MB 0 |
21 | #define VEXPRESS_SITE_DB1 1 | 23 | #define VEXPRESS_SITE_DB1 1 |
22 | #define VEXPRESS_SITE_DB2 2 | 24 | #define VEXPRESS_SITE_DB2 2 |
23 | #define VEXPRESS_SITE_MASTER 0xf | 25 | #define VEXPRESS_SITE_MASTER 0xf |
24 | 26 | ||
25 | #define VEXPRESS_CONFIG_STATUS_DONE 0 | ||
26 | #define VEXPRESS_CONFIG_STATUS_WAIT 1 | ||
27 | |||
28 | #define VEXPRESS_GPIO_MMC_CARDIN 0 | ||
29 | #define VEXPRESS_GPIO_MMC_WPROT 1 | ||
30 | #define VEXPRESS_GPIO_FLASH_WPn 2 | ||
31 | #define VEXPRESS_GPIO_LED0 3 | ||
32 | #define VEXPRESS_GPIO_LED1 4 | ||
33 | #define VEXPRESS_GPIO_LED2 5 | ||
34 | #define VEXPRESS_GPIO_LED3 6 | ||
35 | #define VEXPRESS_GPIO_LED4 7 | ||
36 | #define VEXPRESS_GPIO_LED5 8 | ||
37 | #define VEXPRESS_GPIO_LED6 9 | ||
38 | #define VEXPRESS_GPIO_LED7 10 | ||
39 | |||
40 | #define VEXPRESS_RES_FUNC(_site, _func) \ | 27 | #define VEXPRESS_RES_FUNC(_site, _func) \ |
41 | { \ | 28 | { \ |
42 | .start = (_site), \ | 29 | .start = (_site), \ |
@@ -44,84 +31,43 @@ | |||
44 | .flags = IORESOURCE_BUS, \ | 31 | .flags = IORESOURCE_BUS, \ |
45 | } | 32 | } |
46 | 33 | ||
47 | /* Config bridge API */ | 34 | /* Config infrastructure */ |
48 | 35 | ||
49 | /** | 36 | void vexpress_config_set_master(u32 site); |
50 | * struct vexpress_config_bridge_info - description of the platform | 37 | u32 vexpress_config_get_master(void); |
51 | * configuration infrastructure bridge. | ||
52 | * | ||
53 | * @name: Bridge name | ||
54 | * | ||
55 | * @func_get: Obtains pointer to a configuration function for a given | ||
56 | * device or a Device Tree node, to be used with @func_put | ||
57 | * and @func_exec. The node pointer should take precedence | ||
58 | * over device pointer when both are passed. | ||
59 | * | ||
60 | * @func_put: Tells the bridge that the function will not be used any | ||
61 | * more, so all allocated resources can be released. | ||
62 | * | ||
63 | * @func_exec: Executes a configuration function read or write operation. | ||
64 | * The offset selects a 32 bit word of the value accessed. | ||
65 | * Must return VEXPRESS_CONFIG_STATUS_DONE when operation | ||
66 | * is finished immediately, VEXPRESS_CONFIG_STATUS_WAIT when | ||
67 | * will be completed in some time or negative value in case | ||
68 | * of error. | ||
69 | */ | ||
70 | struct vexpress_config_bridge_info { | ||
71 | const char *name; | ||
72 | void *(*func_get)(struct device *dev, struct device_node *node); | ||
73 | void (*func_put)(void *func); | ||
74 | int (*func_exec)(void *func, int offset, bool write, u32 *data); | ||
75 | }; | ||
76 | 38 | ||
77 | struct vexpress_config_bridge; | 39 | void vexpress_config_lock(void *arg); |
40 | void vexpress_config_unlock(void *arg); | ||
78 | 41 | ||
79 | struct vexpress_config_bridge *vexpress_config_bridge_register( | 42 | int vexpress_config_get_topo(struct device_node *node, u32 *site, |
80 | struct device_node *node, | 43 | u32 *position, u32 *dcc); |
81 | struct vexpress_config_bridge_info *info); | ||
82 | void vexpress_config_bridge_unregister(struct vexpress_config_bridge *bridge); | ||
83 | 44 | ||
84 | void vexpress_config_complete(struct vexpress_config_bridge *bridge, | 45 | /* Config bridge API */ |
85 | int status); | ||
86 | 46 | ||
87 | /* Config function API */ | 47 | struct vexpress_config_bridge_ops { |
48 | struct regmap * (*regmap_init)(struct device *dev, void *context); | ||
49 | void (*regmap_exit)(struct regmap *regmap, void *context); | ||
50 | }; | ||
88 | 51 | ||
89 | struct vexpress_config_func; | 52 | struct device *vexpress_config_bridge_register(struct device *parent, |
53 | struct vexpress_config_bridge_ops *ops, void *context); | ||
90 | 54 | ||
91 | struct vexpress_config_func *__vexpress_config_func_get(struct device *dev, | 55 | /* Config regmap API */ |
92 | struct device_node *node); | ||
93 | #define vexpress_config_func_get_by_dev(dev) \ | ||
94 | __vexpress_config_func_get(dev, NULL) | ||
95 | #define vexpress_config_func_get_by_node(node) \ | ||
96 | __vexpress_config_func_get(NULL, node) | ||
97 | void vexpress_config_func_put(struct vexpress_config_func *func); | ||
98 | 56 | ||
99 | /* Both may sleep! */ | 57 | struct regmap *devm_regmap_init_vexpress_config(struct device *dev); |
100 | int vexpress_config_read(struct vexpress_config_func *func, int offset, | ||
101 | u32 *data); | ||
102 | int vexpress_config_write(struct vexpress_config_func *func, int offset, | ||
103 | u32 data); | ||
104 | 58 | ||
105 | /* Platform control */ | 59 | /* Platform control */ |
106 | 60 | ||
61 | unsigned int vexpress_get_mci_cardin(struct device *dev); | ||
107 | u32 vexpress_get_procid(int site); | 62 | u32 vexpress_get_procid(int site); |
108 | u32 vexpress_get_hbi(int site); | ||
109 | void *vexpress_get_24mhz_clock_base(void); | 63 | void *vexpress_get_24mhz_clock_base(void); |
110 | void vexpress_flags_set(u32 data); | 64 | void vexpress_flags_set(u32 data); |
111 | 65 | ||
112 | #define vexpress_get_site_by_node(node) __vexpress_get_site(NULL, node) | ||
113 | #define vexpress_get_site_by_dev(dev) __vexpress_get_site(dev, NULL) | ||
114 | unsigned __vexpress_get_site(struct device *dev, struct device_node *node); | ||
115 | |||
116 | void vexpress_sysreg_early_init(void __iomem *base); | 66 | void vexpress_sysreg_early_init(void __iomem *base); |
117 | void vexpress_sysreg_of_early_init(void); | 67 | int vexpress_syscfg_device_register(struct platform_device *pdev); |
118 | 68 | ||
119 | /* Clocks */ | 69 | /* Clocks */ |
120 | 70 | ||
121 | struct clk *vexpress_osc_setup(struct device *dev); | ||
122 | void vexpress_osc_of_setup(struct device_node *node); | ||
123 | |||
124 | void vexpress_clk_init(void __iomem *sp810_base); | 71 | void vexpress_clk_init(void __iomem *sp810_base); |
125 | void vexpress_clk_of_init(void); | ||
126 | 72 | ||
127 | #endif | 73 | #endif |
diff --git a/include/net/af_vsock.h b/include/net/af_vsock.h index 7d64d3609ec9..428277869400 100644 --- a/include/net/af_vsock.h +++ b/include/net/af_vsock.h | |||
@@ -155,7 +155,11 @@ struct vsock_transport { | |||
155 | 155 | ||
156 | /**** CORE ****/ | 156 | /**** CORE ****/ |
157 | 157 | ||
158 | int vsock_core_init(const struct vsock_transport *t); | 158 | int __vsock_core_init(const struct vsock_transport *t, struct module *owner); |
159 | static inline int vsock_core_init(const struct vsock_transport *t) | ||
160 | { | ||
161 | return __vsock_core_init(t, THIS_MODULE); | ||
162 | } | ||
159 | void vsock_core_exit(void); | 163 | void vsock_core_exit(void); |
160 | 164 | ||
161 | /**** UTILS ****/ | 165 | /**** UTILS ****/ |
diff --git a/include/net/sock.h b/include/net/sock.h index 8338a14e4805..21569cf456ed 100644 --- a/include/net/sock.h +++ b/include/net/sock.h | |||
@@ -2255,6 +2255,11 @@ int sock_get_timestampns(struct sock *, struct timespec __user *); | |||
2255 | int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len, int level, | 2255 | int sock_recv_errqueue(struct sock *sk, struct msghdr *msg, int len, int level, |
2256 | int type); | 2256 | int type); |
2257 | 2257 | ||
2258 | bool sk_ns_capable(const struct sock *sk, | ||
2259 | struct user_namespace *user_ns, int cap); | ||
2260 | bool sk_capable(const struct sock *sk, int cap); | ||
2261 | bool sk_net_capable(const struct sock *sk, int cap); | ||
2262 | |||
2258 | /* | 2263 | /* |
2259 | * Enable debug/info messages | 2264 | * Enable debug/info messages |
2260 | */ | 2265 | */ |
diff --git a/include/trace/events/module.h b/include/trace/events/module.h index ed0b2c599a64..7c5cbfe3fc49 100644 --- a/include/trace/events/module.h +++ b/include/trace/events/module.h | |||
@@ -80,7 +80,7 @@ DECLARE_EVENT_CLASS(module_refcnt, | |||
80 | 80 | ||
81 | TP_fast_assign( | 81 | TP_fast_assign( |
82 | __entry->ip = ip; | 82 | __entry->ip = ip; |
83 | __entry->refcnt = __this_cpu_read(mod->refptr->incs) + __this_cpu_read(mod->refptr->decs); | 83 | __entry->refcnt = __this_cpu_read(mod->refptr->incs) - __this_cpu_read(mod->refptr->decs); |
84 | __assign_str(name, mod->name); | 84 | __assign_str(name, mod->name); |
85 | ), | 85 | ), |
86 | 86 | ||
diff --git a/include/uapi/linux/fuse.h b/include/uapi/linux/fuse.h index cf4750e1bb49..40b5ca8a1b1f 100644 --- a/include/uapi/linux/fuse.h +++ b/include/uapi/linux/fuse.h | |||
@@ -96,6 +96,11 @@ | |||
96 | * | 96 | * |
97 | * 7.23 | 97 | * 7.23 |
98 | * - add FUSE_WRITEBACK_CACHE | 98 | * - add FUSE_WRITEBACK_CACHE |
99 | * - add time_gran to fuse_init_out | ||
100 | * - add reserved space to fuse_init_out | ||
101 | * - add FATTR_CTIME | ||
102 | * - add ctime and ctimensec to fuse_setattr_in | ||
103 | * - add FUSE_RENAME2 request | ||
99 | */ | 104 | */ |
100 | 105 | ||
101 | #ifndef _LINUX_FUSE_H | 106 | #ifndef _LINUX_FUSE_H |
@@ -191,6 +196,7 @@ struct fuse_file_lock { | |||
191 | #define FATTR_ATIME_NOW (1 << 7) | 196 | #define FATTR_ATIME_NOW (1 << 7) |
192 | #define FATTR_MTIME_NOW (1 << 8) | 197 | #define FATTR_MTIME_NOW (1 << 8) |
193 | #define FATTR_LOCKOWNER (1 << 9) | 198 | #define FATTR_LOCKOWNER (1 << 9) |
199 | #define FATTR_CTIME (1 << 10) | ||
194 | 200 | ||
195 | /** | 201 | /** |
196 | * Flags returned by the OPEN request | 202 | * Flags returned by the OPEN request |
@@ -348,6 +354,7 @@ enum fuse_opcode { | |||
348 | FUSE_BATCH_FORGET = 42, | 354 | FUSE_BATCH_FORGET = 42, |
349 | FUSE_FALLOCATE = 43, | 355 | FUSE_FALLOCATE = 43, |
350 | FUSE_READDIRPLUS = 44, | 356 | FUSE_READDIRPLUS = 44, |
357 | FUSE_RENAME2 = 45, | ||
351 | 358 | ||
352 | /* CUSE specific operations */ | 359 | /* CUSE specific operations */ |
353 | CUSE_INIT = 4096, | 360 | CUSE_INIT = 4096, |
@@ -426,6 +433,12 @@ struct fuse_rename_in { | |||
426 | uint64_t newdir; | 433 | uint64_t newdir; |
427 | }; | 434 | }; |
428 | 435 | ||
436 | struct fuse_rename2_in { | ||
437 | uint64_t newdir; | ||
438 | uint32_t flags; | ||
439 | uint32_t padding; | ||
440 | }; | ||
441 | |||
429 | struct fuse_link_in { | 442 | struct fuse_link_in { |
430 | uint64_t oldnodeid; | 443 | uint64_t oldnodeid; |
431 | }; | 444 | }; |
@@ -438,10 +451,10 @@ struct fuse_setattr_in { | |||
438 | uint64_t lock_owner; | 451 | uint64_t lock_owner; |
439 | uint64_t atime; | 452 | uint64_t atime; |
440 | uint64_t mtime; | 453 | uint64_t mtime; |
441 | uint64_t unused2; | 454 | uint64_t ctime; |
442 | uint32_t atimensec; | 455 | uint32_t atimensec; |
443 | uint32_t mtimensec; | 456 | uint32_t mtimensec; |
444 | uint32_t unused3; | 457 | uint32_t ctimensec; |
445 | uint32_t mode; | 458 | uint32_t mode; |
446 | uint32_t unused4; | 459 | uint32_t unused4; |
447 | uint32_t uid; | 460 | uint32_t uid; |
@@ -559,6 +572,9 @@ struct fuse_init_in { | |||
559 | uint32_t flags; | 572 | uint32_t flags; |
560 | }; | 573 | }; |
561 | 574 | ||
575 | #define FUSE_COMPAT_INIT_OUT_SIZE 8 | ||
576 | #define FUSE_COMPAT_22_INIT_OUT_SIZE 24 | ||
577 | |||
562 | struct fuse_init_out { | 578 | struct fuse_init_out { |
563 | uint32_t major; | 579 | uint32_t major; |
564 | uint32_t minor; | 580 | uint32_t minor; |
@@ -567,6 +583,8 @@ struct fuse_init_out { | |||
567 | uint16_t max_background; | 583 | uint16_t max_background; |
568 | uint16_t congestion_threshold; | 584 | uint16_t congestion_threshold; |
569 | uint32_t max_write; | 585 | uint32_t max_write; |
586 | uint32_t time_gran; | ||
587 | uint32_t unused[9]; | ||
570 | }; | 588 | }; |
571 | 589 | ||
572 | #define CUSE_INIT_INFO_MAX 4096 | 590 | #define CUSE_INIT_INFO_MAX 4096 |
diff --git a/init/main.c b/init/main.c index 9c7fd4c9249f..48655ceb66f4 100644 --- a/init/main.c +++ b/init/main.c | |||
@@ -476,7 +476,7 @@ static void __init mm_init(void) | |||
476 | vmalloc_init(); | 476 | vmalloc_init(); |
477 | } | 477 | } |
478 | 478 | ||
479 | asmlinkage void __init start_kernel(void) | 479 | asmlinkage __visible void __init start_kernel(void) |
480 | { | 480 | { |
481 | char * command_line; | 481 | char * command_line; |
482 | extern const struct kernel_param __start___param[], __stop___param[]; | 482 | extern const struct kernel_param __start___param[], __stop___param[]; |
diff --git a/kernel/audit.c b/kernel/audit.c index 7c2893602d06..47845c57eb19 100644 --- a/kernel/audit.c +++ b/kernel/audit.c | |||
@@ -643,13 +643,13 @@ static int audit_netlink_ok(struct sk_buff *skb, u16 msg_type) | |||
643 | if ((task_active_pid_ns(current) != &init_pid_ns)) | 643 | if ((task_active_pid_ns(current) != &init_pid_ns)) |
644 | return -EPERM; | 644 | return -EPERM; |
645 | 645 | ||
646 | if (!capable(CAP_AUDIT_CONTROL)) | 646 | if (!netlink_capable(skb, CAP_AUDIT_CONTROL)) |
647 | err = -EPERM; | 647 | err = -EPERM; |
648 | break; | 648 | break; |
649 | case AUDIT_USER: | 649 | case AUDIT_USER: |
650 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: | 650 | case AUDIT_FIRST_USER_MSG ... AUDIT_LAST_USER_MSG: |
651 | case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: | 651 | case AUDIT_FIRST_USER_MSG2 ... AUDIT_LAST_USER_MSG2: |
652 | if (!capable(CAP_AUDIT_WRITE)) | 652 | if (!netlink_capable(skb, CAP_AUDIT_WRITE)) |
653 | err = -EPERM; | 653 | err = -EPERM; |
654 | break; | 654 | break; |
655 | default: /* bad msg */ | 655 | default: /* bad msg */ |
diff --git a/kernel/context_tracking.c b/kernel/context_tracking.c index 6cb20d2e7ee0..019d45008448 100644 --- a/kernel/context_tracking.c +++ b/kernel/context_tracking.c | |||
@@ -120,7 +120,7 @@ void context_tracking_user_enter(void) | |||
120 | * instead of preempt_schedule() to exit user context if needed before | 120 | * instead of preempt_schedule() to exit user context if needed before |
121 | * calling the scheduler. | 121 | * calling the scheduler. |
122 | */ | 122 | */ |
123 | asmlinkage void __sched notrace preempt_schedule_context(void) | 123 | asmlinkage __visible void __sched notrace preempt_schedule_context(void) |
124 | { | 124 | { |
125 | enum ctx_state prev_ctx; | 125 | enum ctx_state prev_ctx; |
126 | 126 | ||
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c index b0e9467922e1..d24e4339b46d 100644 --- a/kernel/locking/lockdep.c +++ b/kernel/locking/lockdep.c | |||
@@ -4188,7 +4188,7 @@ void debug_show_held_locks(struct task_struct *task) | |||
4188 | } | 4188 | } |
4189 | EXPORT_SYMBOL_GPL(debug_show_held_locks); | 4189 | EXPORT_SYMBOL_GPL(debug_show_held_locks); |
4190 | 4190 | ||
4191 | asmlinkage void lockdep_sys_exit(void) | 4191 | asmlinkage __visible void lockdep_sys_exit(void) |
4192 | { | 4192 | { |
4193 | struct task_struct *curr = current; | 4193 | struct task_struct *curr = current; |
4194 | 4194 | ||
diff --git a/kernel/power/snapshot.c b/kernel/power/snapshot.c index 18fb7a2fb14b..1ea328aafdc9 100644 --- a/kernel/power/snapshot.c +++ b/kernel/power/snapshot.c | |||
@@ -1586,7 +1586,7 @@ swsusp_alloc(struct memory_bitmap *orig_bm, struct memory_bitmap *copy_bm, | |||
1586 | return -ENOMEM; | 1586 | return -ENOMEM; |
1587 | } | 1587 | } |
1588 | 1588 | ||
1589 | asmlinkage int swsusp_save(void) | 1589 | asmlinkage __visible int swsusp_save(void) |
1590 | { | 1590 | { |
1591 | unsigned int nr_pages, nr_highmem; | 1591 | unsigned int nr_pages, nr_highmem; |
1592 | 1592 | ||
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c index a45b50962295..7228258b85ec 100644 --- a/kernel/printk/printk.c +++ b/kernel/printk/printk.c | |||
@@ -1674,7 +1674,7 @@ EXPORT_SYMBOL(printk_emit); | |||
1674 | * | 1674 | * |
1675 | * See the vsnprintf() documentation for format string extensions over C99. | 1675 | * See the vsnprintf() documentation for format string extensions over C99. |
1676 | */ | 1676 | */ |
1677 | asmlinkage int printk(const char *fmt, ...) | 1677 | asmlinkage __visible int printk(const char *fmt, ...) |
1678 | { | 1678 | { |
1679 | va_list args; | 1679 | va_list args; |
1680 | int r; | 1680 | int r; |
@@ -1737,7 +1737,7 @@ void early_vprintk(const char *fmt, va_list ap) | |||
1737 | } | 1737 | } |
1738 | } | 1738 | } |
1739 | 1739 | ||
1740 | asmlinkage void early_printk(const char *fmt, ...) | 1740 | asmlinkage __visible void early_printk(const char *fmt, ...) |
1741 | { | 1741 | { |
1742 | va_list ap; | 1742 | va_list ap; |
1743 | 1743 | ||
diff --git a/kernel/sched/core.c b/kernel/sched/core.c index 268a45ea238c..d9d8ece46a15 100644 --- a/kernel/sched/core.c +++ b/kernel/sched/core.c | |||
@@ -2192,7 +2192,7 @@ static inline void post_schedule(struct rq *rq) | |||
2192 | * schedule_tail - first thing a freshly forked thread must call. | 2192 | * schedule_tail - first thing a freshly forked thread must call. |
2193 | * @prev: the thread we just switched away from. | 2193 | * @prev: the thread we just switched away from. |
2194 | */ | 2194 | */ |
2195 | asmlinkage void schedule_tail(struct task_struct *prev) | 2195 | asmlinkage __visible void schedule_tail(struct task_struct *prev) |
2196 | __releases(rq->lock) | 2196 | __releases(rq->lock) |
2197 | { | 2197 | { |
2198 | struct rq *rq = this_rq(); | 2198 | struct rq *rq = this_rq(); |
@@ -2741,7 +2741,7 @@ static inline void sched_submit_work(struct task_struct *tsk) | |||
2741 | blk_schedule_flush_plug(tsk); | 2741 | blk_schedule_flush_plug(tsk); |
2742 | } | 2742 | } |
2743 | 2743 | ||
2744 | asmlinkage void __sched schedule(void) | 2744 | asmlinkage __visible void __sched schedule(void) |
2745 | { | 2745 | { |
2746 | struct task_struct *tsk = current; | 2746 | struct task_struct *tsk = current; |
2747 | 2747 | ||
@@ -2751,7 +2751,7 @@ asmlinkage void __sched schedule(void) | |||
2751 | EXPORT_SYMBOL(schedule); | 2751 | EXPORT_SYMBOL(schedule); |
2752 | 2752 | ||
2753 | #ifdef CONFIG_CONTEXT_TRACKING | 2753 | #ifdef CONFIG_CONTEXT_TRACKING |
2754 | asmlinkage void __sched schedule_user(void) | 2754 | asmlinkage __visible void __sched schedule_user(void) |
2755 | { | 2755 | { |
2756 | /* | 2756 | /* |
2757 | * If we come here after a random call to set_need_resched(), | 2757 | * If we come here after a random call to set_need_resched(), |
@@ -2783,7 +2783,7 @@ void __sched schedule_preempt_disabled(void) | |||
2783 | * off of preempt_enable. Kernel preemptions off return from interrupt | 2783 | * off of preempt_enable. Kernel preemptions off return from interrupt |
2784 | * occur there and call schedule directly. | 2784 | * occur there and call schedule directly. |
2785 | */ | 2785 | */ |
2786 | asmlinkage void __sched notrace preempt_schedule(void) | 2786 | asmlinkage __visible void __sched notrace preempt_schedule(void) |
2787 | { | 2787 | { |
2788 | /* | 2788 | /* |
2789 | * If there is a non-zero preempt_count or interrupts are disabled, | 2789 | * If there is a non-zero preempt_count or interrupts are disabled, |
@@ -2813,7 +2813,7 @@ EXPORT_SYMBOL(preempt_schedule); | |||
2813 | * Note, that this is called and return with irqs disabled. This will | 2813 | * Note, that this is called and return with irqs disabled. This will |
2814 | * protect us against recursive calling from irq. | 2814 | * protect us against recursive calling from irq. |
2815 | */ | 2815 | */ |
2816 | asmlinkage void __sched preempt_schedule_irq(void) | 2816 | asmlinkage __visible void __sched preempt_schedule_irq(void) |
2817 | { | 2817 | { |
2818 | enum ctx_state prev_state; | 2818 | enum ctx_state prev_state; |
2819 | 2819 | ||
diff --git a/kernel/softirq.c b/kernel/softirq.c index 33e4648ae0e7..92f24f5e8d52 100644 --- a/kernel/softirq.c +++ b/kernel/softirq.c | |||
@@ -223,7 +223,7 @@ static inline bool lockdep_softirq_start(void) { return false; } | |||
223 | static inline void lockdep_softirq_end(bool in_hardirq) { } | 223 | static inline void lockdep_softirq_end(bool in_hardirq) { } |
224 | #endif | 224 | #endif |
225 | 225 | ||
226 | asmlinkage void __do_softirq(void) | 226 | asmlinkage __visible void __do_softirq(void) |
227 | { | 227 | { |
228 | unsigned long end = jiffies + MAX_SOFTIRQ_TIME; | 228 | unsigned long end = jiffies + MAX_SOFTIRQ_TIME; |
229 | unsigned long old_flags = current->flags; | 229 | unsigned long old_flags = current->flags; |
@@ -299,7 +299,7 @@ restart: | |||
299 | tsk_restore_flags(current, old_flags, PF_MEMALLOC); | 299 | tsk_restore_flags(current, old_flags, PF_MEMALLOC); |
300 | } | 300 | } |
301 | 301 | ||
302 | asmlinkage void do_softirq(void) | 302 | asmlinkage __visible void do_softirq(void) |
303 | { | 303 | { |
304 | __u32 pending; | 304 | __u32 pending; |
305 | unsigned long flags; | 305 | unsigned long flags; |
diff --git a/kernel/tracepoint.c b/kernel/tracepoint.c index ac5b23cf7212..6620e5837ce2 100644 --- a/kernel/tracepoint.c +++ b/kernel/tracepoint.c | |||
@@ -188,7 +188,6 @@ static int tracepoint_add_func(struct tracepoint *tp, | |||
188 | WARN_ON_ONCE(1); | 188 | WARN_ON_ONCE(1); |
189 | return PTR_ERR(old); | 189 | return PTR_ERR(old); |
190 | } | 190 | } |
191 | release_probes(old); | ||
192 | 191 | ||
193 | /* | 192 | /* |
194 | * rcu_assign_pointer has a smp_wmb() which makes sure that the new | 193 | * rcu_assign_pointer has a smp_wmb() which makes sure that the new |
@@ -200,6 +199,7 @@ static int tracepoint_add_func(struct tracepoint *tp, | |||
200 | rcu_assign_pointer(tp->funcs, tp_funcs); | 199 | rcu_assign_pointer(tp->funcs, tp_funcs); |
201 | if (!static_key_enabled(&tp->key)) | 200 | if (!static_key_enabled(&tp->key)) |
202 | static_key_slow_inc(&tp->key); | 201 | static_key_slow_inc(&tp->key); |
202 | release_probes(old); | ||
203 | return 0; | 203 | return 0; |
204 | } | 204 | } |
205 | 205 | ||
@@ -221,7 +221,6 @@ static int tracepoint_remove_func(struct tracepoint *tp, | |||
221 | WARN_ON_ONCE(1); | 221 | WARN_ON_ONCE(1); |
222 | return PTR_ERR(old); | 222 | return PTR_ERR(old); |
223 | } | 223 | } |
224 | release_probes(old); | ||
225 | 224 | ||
226 | if (!tp_funcs) { | 225 | if (!tp_funcs) { |
227 | /* Removed last function */ | 226 | /* Removed last function */ |
@@ -232,6 +231,7 @@ static int tracepoint_remove_func(struct tracepoint *tp, | |||
232 | static_key_slow_dec(&tp->key); | 231 | static_key_slow_dec(&tp->key); |
233 | } | 232 | } |
234 | rcu_assign_pointer(tp->funcs, tp_funcs); | 233 | rcu_assign_pointer(tp->funcs, tp_funcs); |
234 | release_probes(old); | ||
235 | return 0; | 235 | return 0; |
236 | } | 236 | } |
237 | 237 | ||
diff --git a/lib/dump_stack.c b/lib/dump_stack.c index f23b63f0a1c3..6745c6230db3 100644 --- a/lib/dump_stack.c +++ b/lib/dump_stack.c | |||
@@ -23,7 +23,7 @@ static void __dump_stack(void) | |||
23 | #ifdef CONFIG_SMP | 23 | #ifdef CONFIG_SMP |
24 | static atomic_t dump_lock = ATOMIC_INIT(-1); | 24 | static atomic_t dump_lock = ATOMIC_INIT(-1); |
25 | 25 | ||
26 | asmlinkage void dump_stack(void) | 26 | asmlinkage __visible void dump_stack(void) |
27 | { | 27 | { |
28 | int was_locked; | 28 | int was_locked; |
29 | int old; | 29 | int old; |
@@ -55,7 +55,7 @@ retry: | |||
55 | preempt_enable(); | 55 | preempt_enable(); |
56 | } | 56 | } |
57 | #else | 57 | #else |
58 | asmlinkage void dump_stack(void) | 58 | asmlinkage __visible void dump_stack(void) |
59 | { | 59 | { |
60 | __dump_stack(); | 60 | __dump_stack(); |
61 | } | 61 | } |
diff --git a/mm/compaction.c b/mm/compaction.c index 37f976287068..627dc2e4320f 100644 --- a/mm/compaction.c +++ b/mm/compaction.c | |||
@@ -671,16 +671,20 @@ static void isolate_freepages(struct zone *zone, | |||
671 | struct compact_control *cc) | 671 | struct compact_control *cc) |
672 | { | 672 | { |
673 | struct page *page; | 673 | struct page *page; |
674 | unsigned long high_pfn, low_pfn, pfn, z_end_pfn, end_pfn; | 674 | unsigned long high_pfn, low_pfn, pfn, z_end_pfn; |
675 | int nr_freepages = cc->nr_freepages; | 675 | int nr_freepages = cc->nr_freepages; |
676 | struct list_head *freelist = &cc->freepages; | 676 | struct list_head *freelist = &cc->freepages; |
677 | 677 | ||
678 | /* | 678 | /* |
679 | * Initialise the free scanner. The starting point is where we last | 679 | * Initialise the free scanner. The starting point is where we last |
680 | * scanned from (or the end of the zone if starting). The low point | 680 | * successfully isolated from, zone-cached value, or the end of the |
681 | * is the end of the pageblock the migration scanner is using. | 681 | * zone when isolating for the first time. We need this aligned to |
682 | * the pageblock boundary, because we do pfn -= pageblock_nr_pages | ||
683 | * in the for loop. | ||
684 | * The low boundary is the end of the pageblock the migration scanner | ||
685 | * is using. | ||
682 | */ | 686 | */ |
683 | pfn = cc->free_pfn; | 687 | pfn = cc->free_pfn & ~(pageblock_nr_pages-1); |
684 | low_pfn = ALIGN(cc->migrate_pfn + 1, pageblock_nr_pages); | 688 | low_pfn = ALIGN(cc->migrate_pfn + 1, pageblock_nr_pages); |
685 | 689 | ||
686 | /* | 690 | /* |
@@ -700,6 +704,7 @@ static void isolate_freepages(struct zone *zone, | |||
700 | for (; pfn >= low_pfn && cc->nr_migratepages > nr_freepages; | 704 | for (; pfn >= low_pfn && cc->nr_migratepages > nr_freepages; |
701 | pfn -= pageblock_nr_pages) { | 705 | pfn -= pageblock_nr_pages) { |
702 | unsigned long isolated; | 706 | unsigned long isolated; |
707 | unsigned long end_pfn; | ||
703 | 708 | ||
704 | /* | 709 | /* |
705 | * This can iterate a massively long zone without finding any | 710 | * This can iterate a massively long zone without finding any |
@@ -734,13 +739,10 @@ static void isolate_freepages(struct zone *zone, | |||
734 | isolated = 0; | 739 | isolated = 0; |
735 | 740 | ||
736 | /* | 741 | /* |
737 | * As pfn may not start aligned, pfn+pageblock_nr_page | 742 | * Take care when isolating in last pageblock of a zone which |
738 | * may cross a MAX_ORDER_NR_PAGES boundary and miss | 743 | * ends in the middle of a pageblock. |
739 | * a pfn_valid check. Ensure isolate_freepages_block() | ||
740 | * only scans within a pageblock | ||
741 | */ | 744 | */ |
742 | end_pfn = ALIGN(pfn + 1, pageblock_nr_pages); | 745 | end_pfn = min(pfn + pageblock_nr_pages, z_end_pfn); |
743 | end_pfn = min(end_pfn, z_end_pfn); | ||
744 | isolated = isolate_freepages_block(cc, pfn, end_pfn, | 746 | isolated = isolate_freepages_block(cc, pfn, end_pfn, |
745 | freelist, false); | 747 | freelist, false); |
746 | nr_freepages += isolated; | 748 | nr_freepages += isolated; |
diff --git a/mm/filemap.c b/mm/filemap.c index 5020b280a771..000a220e2a41 100644 --- a/mm/filemap.c +++ b/mm/filemap.c | |||
@@ -906,8 +906,8 @@ EXPORT_SYMBOL(page_cache_prev_hole); | |||
906 | * Looks up the page cache slot at @mapping & @offset. If there is a | 906 | * Looks up the page cache slot at @mapping & @offset. If there is a |
907 | * page cache page, it is returned with an increased refcount. | 907 | * page cache page, it is returned with an increased refcount. |
908 | * | 908 | * |
909 | * If the slot holds a shadow entry of a previously evicted page, it | 909 | * If the slot holds a shadow entry of a previously evicted page, or a |
910 | * is returned. | 910 | * swap entry from shmem/tmpfs, it is returned. |
911 | * | 911 | * |
912 | * Otherwise, %NULL is returned. | 912 | * Otherwise, %NULL is returned. |
913 | */ | 913 | */ |
@@ -928,9 +928,9 @@ repeat: | |||
928 | if (radix_tree_deref_retry(page)) | 928 | if (radix_tree_deref_retry(page)) |
929 | goto repeat; | 929 | goto repeat; |
930 | /* | 930 | /* |
931 | * Otherwise, shmem/tmpfs must be storing a swap entry | 931 | * A shadow entry of a recently evicted page, |
932 | * here as an exceptional entry: so return it without | 932 | * or a swap entry from shmem/tmpfs. Return |
933 | * attempting to raise page count. | 933 | * it without attempting to raise page count. |
934 | */ | 934 | */ |
935 | goto out; | 935 | goto out; |
936 | } | 936 | } |
@@ -983,8 +983,8 @@ EXPORT_SYMBOL(find_get_page); | |||
983 | * page cache page, it is returned locked and with an increased | 983 | * page cache page, it is returned locked and with an increased |
984 | * refcount. | 984 | * refcount. |
985 | * | 985 | * |
986 | * If the slot holds a shadow entry of a previously evicted page, it | 986 | * If the slot holds a shadow entry of a previously evicted page, or a |
987 | * is returned. | 987 | * swap entry from shmem/tmpfs, it is returned. |
988 | * | 988 | * |
989 | * Otherwise, %NULL is returned. | 989 | * Otherwise, %NULL is returned. |
990 | * | 990 | * |
@@ -1099,8 +1099,8 @@ EXPORT_SYMBOL(find_or_create_page); | |||
1099 | * with ascending indexes. There may be holes in the indices due to | 1099 | * with ascending indexes. There may be holes in the indices due to |
1100 | * not-present pages. | 1100 | * not-present pages. |
1101 | * | 1101 | * |
1102 | * Any shadow entries of evicted pages are included in the returned | 1102 | * Any shadow entries of evicted pages, or swap entries from |
1103 | * array. | 1103 | * shmem/tmpfs, are included in the returned array. |
1104 | * | 1104 | * |
1105 | * find_get_entries() returns the number of pages and shadow entries | 1105 | * find_get_entries() returns the number of pages and shadow entries |
1106 | * which were found. | 1106 | * which were found. |
@@ -1128,9 +1128,9 @@ repeat: | |||
1128 | if (radix_tree_deref_retry(page)) | 1128 | if (radix_tree_deref_retry(page)) |
1129 | goto restart; | 1129 | goto restart; |
1130 | /* | 1130 | /* |
1131 | * Otherwise, we must be storing a swap entry | 1131 | * A shadow entry of a recently evicted page, |
1132 | * here as an exceptional entry: so return it | 1132 | * or a swap entry from shmem/tmpfs. Return |
1133 | * without attempting to raise page count. | 1133 | * it without attempting to raise page count. |
1134 | */ | 1134 | */ |
1135 | goto export; | 1135 | goto export; |
1136 | } | 1136 | } |
@@ -1198,9 +1198,9 @@ repeat: | |||
1198 | goto restart; | 1198 | goto restart; |
1199 | } | 1199 | } |
1200 | /* | 1200 | /* |
1201 | * Otherwise, shmem/tmpfs must be storing a swap entry | 1201 | * A shadow entry of a recently evicted page, |
1202 | * here as an exceptional entry: so skip over it - | 1202 | * or a swap entry from shmem/tmpfs. Skip |
1203 | * we only reach this from invalidate_mapping_pages(). | 1203 | * over it. |
1204 | */ | 1204 | */ |
1205 | continue; | 1205 | continue; |
1206 | } | 1206 | } |
@@ -1265,9 +1265,9 @@ repeat: | |||
1265 | goto restart; | 1265 | goto restart; |
1266 | } | 1266 | } |
1267 | /* | 1267 | /* |
1268 | * Otherwise, shmem/tmpfs must be storing a swap entry | 1268 | * A shadow entry of a recently evicted page, |
1269 | * here as an exceptional entry: so stop looking for | 1269 | * or a swap entry from shmem/tmpfs. Stop |
1270 | * contiguous pages. | 1270 | * looking for contiguous pages. |
1271 | */ | 1271 | */ |
1272 | break; | 1272 | break; |
1273 | } | 1273 | } |
@@ -1341,10 +1341,17 @@ repeat: | |||
1341 | goto restart; | 1341 | goto restart; |
1342 | } | 1342 | } |
1343 | /* | 1343 | /* |
1344 | * This function is never used on a shmem/tmpfs | 1344 | * A shadow entry of a recently evicted page. |
1345 | * mapping, so a swap entry won't be found here. | 1345 | * |
1346 | * Those entries should never be tagged, but | ||
1347 | * this tree walk is lockless and the tags are | ||
1348 | * looked up in bulk, one radix tree node at a | ||
1349 | * time, so there is a sizable window for page | ||
1350 | * reclaim to evict a page we saw tagged. | ||
1351 | * | ||
1352 | * Skip over it. | ||
1346 | */ | 1353 | */ |
1347 | BUG(); | 1354 | continue; |
1348 | } | 1355 | } |
1349 | 1356 | ||
1350 | if (!page_cache_get_speculative(page)) | 1357 | if (!page_cache_get_speculative(page)) |
diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 246192929a2d..c82290b9c1fc 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c | |||
@@ -1981,11 +1981,7 @@ static int __init hugetlb_init(void) | |||
1981 | { | 1981 | { |
1982 | int i; | 1982 | int i; |
1983 | 1983 | ||
1984 | /* Some platform decide whether they support huge pages at boot | 1984 | if (!hugepages_supported()) |
1985 | * time. On these, such as powerpc, HPAGE_SHIFT is set to 0 when | ||
1986 | * there is no such support | ||
1987 | */ | ||
1988 | if (HPAGE_SHIFT == 0) | ||
1989 | return 0; | 1985 | return 0; |
1990 | 1986 | ||
1991 | if (!size_to_hstate(default_hstate_size)) { | 1987 | if (!size_to_hstate(default_hstate_size)) { |
@@ -2112,6 +2108,9 @@ static int hugetlb_sysctl_handler_common(bool obey_mempolicy, | |||
2112 | unsigned long tmp; | 2108 | unsigned long tmp; |
2113 | int ret; | 2109 | int ret; |
2114 | 2110 | ||
2111 | if (!hugepages_supported()) | ||
2112 | return -ENOTSUPP; | ||
2113 | |||
2115 | tmp = h->max_huge_pages; | 2114 | tmp = h->max_huge_pages; |
2116 | 2115 | ||
2117 | if (write && h->order >= MAX_ORDER) | 2116 | if (write && h->order >= MAX_ORDER) |
@@ -2165,6 +2164,9 @@ int hugetlb_overcommit_handler(struct ctl_table *table, int write, | |||
2165 | unsigned long tmp; | 2164 | unsigned long tmp; |
2166 | int ret; | 2165 | int ret; |
2167 | 2166 | ||
2167 | if (!hugepages_supported()) | ||
2168 | return -ENOTSUPP; | ||
2169 | |||
2168 | tmp = h->nr_overcommit_huge_pages; | 2170 | tmp = h->nr_overcommit_huge_pages; |
2169 | 2171 | ||
2170 | if (write && h->order >= MAX_ORDER) | 2172 | if (write && h->order >= MAX_ORDER) |
@@ -2190,6 +2192,8 @@ out: | |||
2190 | void hugetlb_report_meminfo(struct seq_file *m) | 2192 | void hugetlb_report_meminfo(struct seq_file *m) |
2191 | { | 2193 | { |
2192 | struct hstate *h = &default_hstate; | 2194 | struct hstate *h = &default_hstate; |
2195 | if (!hugepages_supported()) | ||
2196 | return; | ||
2193 | seq_printf(m, | 2197 | seq_printf(m, |
2194 | "HugePages_Total: %5lu\n" | 2198 | "HugePages_Total: %5lu\n" |
2195 | "HugePages_Free: %5lu\n" | 2199 | "HugePages_Free: %5lu\n" |
@@ -2206,6 +2210,8 @@ void hugetlb_report_meminfo(struct seq_file *m) | |||
2206 | int hugetlb_report_node_meminfo(int nid, char *buf) | 2210 | int hugetlb_report_node_meminfo(int nid, char *buf) |
2207 | { | 2211 | { |
2208 | struct hstate *h = &default_hstate; | 2212 | struct hstate *h = &default_hstate; |
2213 | if (!hugepages_supported()) | ||
2214 | return 0; | ||
2209 | return sprintf(buf, | 2215 | return sprintf(buf, |
2210 | "Node %d HugePages_Total: %5u\n" | 2216 | "Node %d HugePages_Total: %5u\n" |
2211 | "Node %d HugePages_Free: %5u\n" | 2217 | "Node %d HugePages_Free: %5u\n" |
@@ -2220,6 +2226,9 @@ void hugetlb_show_meminfo(void) | |||
2220 | struct hstate *h; | 2226 | struct hstate *h; |
2221 | int nid; | 2227 | int nid; |
2222 | 2228 | ||
2229 | if (!hugepages_supported()) | ||
2230 | return; | ||
2231 | |||
2223 | for_each_node_state(nid, N_MEMORY) | 2232 | for_each_node_state(nid, N_MEMORY) |
2224 | for_each_hstate(h) | 2233 | for_each_hstate(h) |
2225 | pr_info("Node %d hugepages_total=%u hugepages_free=%u hugepages_surp=%u hugepages_size=%lukB\n", | 2234 | pr_info("Node %d hugepages_total=%u hugepages_free=%u hugepages_surp=%u hugepages_size=%lukB\n", |
diff --git a/mm/memcontrol.c b/mm/memcontrol.c index 29501f040568..c47dffdcb246 100644 --- a/mm/memcontrol.c +++ b/mm/memcontrol.c | |||
@@ -6686,16 +6686,20 @@ static struct page *mc_handle_file_pte(struct vm_area_struct *vma, | |||
6686 | pgoff = pte_to_pgoff(ptent); | 6686 | pgoff = pte_to_pgoff(ptent); |
6687 | 6687 | ||
6688 | /* page is moved even if it's not RSS of this task(page-faulted). */ | 6688 | /* page is moved even if it's not RSS of this task(page-faulted). */ |
6689 | page = find_get_page(mapping, pgoff); | ||
6690 | |||
6691 | #ifdef CONFIG_SWAP | 6689 | #ifdef CONFIG_SWAP |
6692 | /* shmem/tmpfs may report page out on swap: account for that too. */ | 6690 | /* shmem/tmpfs may report page out on swap: account for that too. */ |
6693 | if (radix_tree_exceptional_entry(page)) { | 6691 | if (shmem_mapping(mapping)) { |
6694 | swp_entry_t swap = radix_to_swp_entry(page); | 6692 | page = find_get_entry(mapping, pgoff); |
6695 | if (do_swap_account) | 6693 | if (radix_tree_exceptional_entry(page)) { |
6696 | *entry = swap; | 6694 | swp_entry_t swp = radix_to_swp_entry(page); |
6697 | page = find_get_page(swap_address_space(swap), swap.val); | 6695 | if (do_swap_account) |
6698 | } | 6696 | *entry = swp; |
6697 | page = find_get_page(swap_address_space(swp), swp.val); | ||
6698 | } | ||
6699 | } else | ||
6700 | page = find_get_page(mapping, pgoff); | ||
6701 | #else | ||
6702 | page = find_get_page(mapping, pgoff); | ||
6699 | #endif | 6703 | #endif |
6700 | return page; | 6704 | return page; |
6701 | } | 6705 | } |
diff --git a/mm/page-writeback.c b/mm/page-writeback.c index ef413492a149..a4317da60532 100644 --- a/mm/page-writeback.c +++ b/mm/page-writeback.c | |||
@@ -593,14 +593,14 @@ unsigned long bdi_dirty_limit(struct backing_dev_info *bdi, unsigned long dirty) | |||
593 | * (5) the closer to setpoint, the smaller |df/dx| (and the reverse) | 593 | * (5) the closer to setpoint, the smaller |df/dx| (and the reverse) |
594 | * => fast response on large errors; small oscillation near setpoint | 594 | * => fast response on large errors; small oscillation near setpoint |
595 | */ | 595 | */ |
596 | static inline long long pos_ratio_polynom(unsigned long setpoint, | 596 | static long long pos_ratio_polynom(unsigned long setpoint, |
597 | unsigned long dirty, | 597 | unsigned long dirty, |
598 | unsigned long limit) | 598 | unsigned long limit) |
599 | { | 599 | { |
600 | long long pos_ratio; | 600 | long long pos_ratio; |
601 | long x; | 601 | long x; |
602 | 602 | ||
603 | x = div_s64(((s64)setpoint - (s64)dirty) << RATELIMIT_CALC_SHIFT, | 603 | x = div64_s64(((s64)setpoint - (s64)dirty) << RATELIMIT_CALC_SHIFT, |
604 | limit - setpoint + 1); | 604 | limit - setpoint + 1); |
605 | pos_ratio = x; | 605 | pos_ratio = x; |
606 | pos_ratio = pos_ratio * x >> RATELIMIT_CALC_SHIFT; | 606 | pos_ratio = pos_ratio * x >> RATELIMIT_CALC_SHIFT; |
@@ -842,7 +842,7 @@ static unsigned long bdi_position_ratio(struct backing_dev_info *bdi, | |||
842 | x_intercept = bdi_setpoint + span; | 842 | x_intercept = bdi_setpoint + span; |
843 | 843 | ||
844 | if (bdi_dirty < x_intercept - span / 4) { | 844 | if (bdi_dirty < x_intercept - span / 4) { |
845 | pos_ratio = div_u64(pos_ratio * (x_intercept - bdi_dirty), | 845 | pos_ratio = div64_u64(pos_ratio * (x_intercept - bdi_dirty), |
846 | x_intercept - bdi_setpoint + 1); | 846 | x_intercept - bdi_setpoint + 1); |
847 | } else | 847 | } else |
848 | pos_ratio /= 4; | 848 | pos_ratio /= 4; |
@@ -166,7 +166,7 @@ typedef unsigned char freelist_idx_t; | |||
166 | typedef unsigned short freelist_idx_t; | 166 | typedef unsigned short freelist_idx_t; |
167 | #endif | 167 | #endif |
168 | 168 | ||
169 | #define SLAB_OBJ_MAX_NUM (1 << sizeof(freelist_idx_t) * BITS_PER_BYTE) | 169 | #define SLAB_OBJ_MAX_NUM ((1 << sizeof(freelist_idx_t) * BITS_PER_BYTE) - 1) |
170 | 170 | ||
171 | /* | 171 | /* |
172 | * true if a page was allocated from pfmemalloc reserves for network-based | 172 | * true if a page was allocated from pfmemalloc reserves for network-based |
@@ -2572,13 +2572,13 @@ static void *alloc_slabmgmt(struct kmem_cache *cachep, | |||
2572 | return freelist; | 2572 | return freelist; |
2573 | } | 2573 | } |
2574 | 2574 | ||
2575 | static inline freelist_idx_t get_free_obj(struct page *page, unsigned char idx) | 2575 | static inline freelist_idx_t get_free_obj(struct page *page, unsigned int idx) |
2576 | { | 2576 | { |
2577 | return ((freelist_idx_t *)page->freelist)[idx]; | 2577 | return ((freelist_idx_t *)page->freelist)[idx]; |
2578 | } | 2578 | } |
2579 | 2579 | ||
2580 | static inline void set_free_obj(struct page *page, | 2580 | static inline void set_free_obj(struct page *page, |
2581 | unsigned char idx, freelist_idx_t val) | 2581 | unsigned int idx, freelist_idx_t val) |
2582 | { | 2582 | { |
2583 | ((freelist_idx_t *)(page->freelist))[idx] = val; | 2583 | ((freelist_idx_t *)(page->freelist))[idx] = val; |
2584 | } | 2584 | } |
@@ -91,6 +91,7 @@ __kmem_cache_alias(const char *name, size_t size, size_t align, | |||
91 | #define CACHE_CREATE_MASK (SLAB_CORE_FLAGS | SLAB_DEBUG_FLAGS | SLAB_CACHE_FLAGS) | 91 | #define CACHE_CREATE_MASK (SLAB_CORE_FLAGS | SLAB_DEBUG_FLAGS | SLAB_CACHE_FLAGS) |
92 | 92 | ||
93 | int __kmem_cache_shutdown(struct kmem_cache *); | 93 | int __kmem_cache_shutdown(struct kmem_cache *); |
94 | void slab_kmem_cache_release(struct kmem_cache *); | ||
94 | 95 | ||
95 | struct seq_file; | 96 | struct seq_file; |
96 | struct file; | 97 | struct file; |
diff --git a/mm/slab_common.c b/mm/slab_common.c index f3cfccf76dda..102cc6fca3d3 100644 --- a/mm/slab_common.c +++ b/mm/slab_common.c | |||
@@ -323,6 +323,12 @@ static int kmem_cache_destroy_memcg_children(struct kmem_cache *s) | |||
323 | } | 323 | } |
324 | #endif /* CONFIG_MEMCG_KMEM */ | 324 | #endif /* CONFIG_MEMCG_KMEM */ |
325 | 325 | ||
326 | void slab_kmem_cache_release(struct kmem_cache *s) | ||
327 | { | ||
328 | kfree(s->name); | ||
329 | kmem_cache_free(kmem_cache, s); | ||
330 | } | ||
331 | |||
326 | void kmem_cache_destroy(struct kmem_cache *s) | 332 | void kmem_cache_destroy(struct kmem_cache *s) |
327 | { | 333 | { |
328 | get_online_cpus(); | 334 | get_online_cpus(); |
@@ -352,8 +358,11 @@ void kmem_cache_destroy(struct kmem_cache *s) | |||
352 | rcu_barrier(); | 358 | rcu_barrier(); |
353 | 359 | ||
354 | memcg_free_cache_params(s); | 360 | memcg_free_cache_params(s); |
355 | kfree(s->name); | 361 | #ifdef SLAB_SUPPORTS_SYSFS |
356 | kmem_cache_free(kmem_cache, s); | 362 | sysfs_slab_remove(s); |
363 | #else | ||
364 | slab_kmem_cache_release(s); | ||
365 | #endif | ||
357 | goto out_put_cpus; | 366 | goto out_put_cpus; |
358 | 367 | ||
359 | out_unlock: | 368 | out_unlock: |
@@ -210,14 +210,11 @@ enum track_item { TRACK_ALLOC, TRACK_FREE }; | |||
210 | #ifdef CONFIG_SYSFS | 210 | #ifdef CONFIG_SYSFS |
211 | static int sysfs_slab_add(struct kmem_cache *); | 211 | static int sysfs_slab_add(struct kmem_cache *); |
212 | static int sysfs_slab_alias(struct kmem_cache *, const char *); | 212 | static int sysfs_slab_alias(struct kmem_cache *, const char *); |
213 | static void sysfs_slab_remove(struct kmem_cache *); | ||
214 | static void memcg_propagate_slab_attrs(struct kmem_cache *s); | 213 | static void memcg_propagate_slab_attrs(struct kmem_cache *s); |
215 | #else | 214 | #else |
216 | static inline int sysfs_slab_add(struct kmem_cache *s) { return 0; } | 215 | static inline int sysfs_slab_add(struct kmem_cache *s) { return 0; } |
217 | static inline int sysfs_slab_alias(struct kmem_cache *s, const char *p) | 216 | static inline int sysfs_slab_alias(struct kmem_cache *s, const char *p) |
218 | { return 0; } | 217 | { return 0; } |
219 | static inline void sysfs_slab_remove(struct kmem_cache *s) { } | ||
220 | |||
221 | static inline void memcg_propagate_slab_attrs(struct kmem_cache *s) { } | 218 | static inline void memcg_propagate_slab_attrs(struct kmem_cache *s) { } |
222 | #endif | 219 | #endif |
223 | 220 | ||
@@ -3238,24 +3235,7 @@ static inline int kmem_cache_close(struct kmem_cache *s) | |||
3238 | 3235 | ||
3239 | int __kmem_cache_shutdown(struct kmem_cache *s) | 3236 | int __kmem_cache_shutdown(struct kmem_cache *s) |
3240 | { | 3237 | { |
3241 | int rc = kmem_cache_close(s); | 3238 | return kmem_cache_close(s); |
3242 | |||
3243 | if (!rc) { | ||
3244 | /* | ||
3245 | * Since slab_attr_store may take the slab_mutex, we should | ||
3246 | * release the lock while removing the sysfs entry in order to | ||
3247 | * avoid a deadlock. Because this is pretty much the last | ||
3248 | * operation we do and the lock will be released shortly after | ||
3249 | * that in slab_common.c, we could just move sysfs_slab_remove | ||
3250 | * to a later point in common code. We should do that when we | ||
3251 | * have a common sysfs framework for all allocators. | ||
3252 | */ | ||
3253 | mutex_unlock(&slab_mutex); | ||
3254 | sysfs_slab_remove(s); | ||
3255 | mutex_lock(&slab_mutex); | ||
3256 | } | ||
3257 | |||
3258 | return rc; | ||
3259 | } | 3239 | } |
3260 | 3240 | ||
3261 | /******************************************************************** | 3241 | /******************************************************************** |
@@ -5071,15 +5051,18 @@ static void memcg_propagate_slab_attrs(struct kmem_cache *s) | |||
5071 | #ifdef CONFIG_MEMCG_KMEM | 5051 | #ifdef CONFIG_MEMCG_KMEM |
5072 | int i; | 5052 | int i; |
5073 | char *buffer = NULL; | 5053 | char *buffer = NULL; |
5054 | struct kmem_cache *root_cache; | ||
5074 | 5055 | ||
5075 | if (!is_root_cache(s)) | 5056 | if (is_root_cache(s)) |
5076 | return; | 5057 | return; |
5077 | 5058 | ||
5059 | root_cache = s->memcg_params->root_cache; | ||
5060 | |||
5078 | /* | 5061 | /* |
5079 | * This mean this cache had no attribute written. Therefore, no point | 5062 | * This mean this cache had no attribute written. Therefore, no point |
5080 | * in copying default values around | 5063 | * in copying default values around |
5081 | */ | 5064 | */ |
5082 | if (!s->max_attr_size) | 5065 | if (!root_cache->max_attr_size) |
5083 | return; | 5066 | return; |
5084 | 5067 | ||
5085 | for (i = 0; i < ARRAY_SIZE(slab_attrs); i++) { | 5068 | for (i = 0; i < ARRAY_SIZE(slab_attrs); i++) { |
@@ -5101,7 +5084,7 @@ static void memcg_propagate_slab_attrs(struct kmem_cache *s) | |||
5101 | */ | 5084 | */ |
5102 | if (buffer) | 5085 | if (buffer) |
5103 | buf = buffer; | 5086 | buf = buffer; |
5104 | else if (s->max_attr_size < ARRAY_SIZE(mbuf)) | 5087 | else if (root_cache->max_attr_size < ARRAY_SIZE(mbuf)) |
5105 | buf = mbuf; | 5088 | buf = mbuf; |
5106 | else { | 5089 | else { |
5107 | buffer = (char *) get_zeroed_page(GFP_KERNEL); | 5090 | buffer = (char *) get_zeroed_page(GFP_KERNEL); |
@@ -5110,7 +5093,7 @@ static void memcg_propagate_slab_attrs(struct kmem_cache *s) | |||
5110 | buf = buffer; | 5093 | buf = buffer; |
5111 | } | 5094 | } |
5112 | 5095 | ||
5113 | attr->show(s->memcg_params->root_cache, buf); | 5096 | attr->show(root_cache, buf); |
5114 | attr->store(s, buf, strlen(buf)); | 5097 | attr->store(s, buf, strlen(buf)); |
5115 | } | 5098 | } |
5116 | 5099 | ||
@@ -5119,6 +5102,11 @@ static void memcg_propagate_slab_attrs(struct kmem_cache *s) | |||
5119 | #endif | 5102 | #endif |
5120 | } | 5103 | } |
5121 | 5104 | ||
5105 | static void kmem_cache_release(struct kobject *k) | ||
5106 | { | ||
5107 | slab_kmem_cache_release(to_slab(k)); | ||
5108 | } | ||
5109 | |||
5122 | static const struct sysfs_ops slab_sysfs_ops = { | 5110 | static const struct sysfs_ops slab_sysfs_ops = { |
5123 | .show = slab_attr_show, | 5111 | .show = slab_attr_show, |
5124 | .store = slab_attr_store, | 5112 | .store = slab_attr_store, |
@@ -5126,6 +5114,7 @@ static const struct sysfs_ops slab_sysfs_ops = { | |||
5126 | 5114 | ||
5127 | static struct kobj_type slab_ktype = { | 5115 | static struct kobj_type slab_ktype = { |
5128 | .sysfs_ops = &slab_sysfs_ops, | 5116 | .sysfs_ops = &slab_sysfs_ops, |
5117 | .release = kmem_cache_release, | ||
5129 | }; | 5118 | }; |
5130 | 5119 | ||
5131 | static int uevent_filter(struct kset *kset, struct kobject *kobj) | 5120 | static int uevent_filter(struct kset *kset, struct kobject *kobj) |
@@ -5252,7 +5241,7 @@ out_put_kobj: | |||
5252 | goto out; | 5241 | goto out; |
5253 | } | 5242 | } |
5254 | 5243 | ||
5255 | static void sysfs_slab_remove(struct kmem_cache *s) | 5244 | void sysfs_slab_remove(struct kmem_cache *s) |
5256 | { | 5245 | { |
5257 | if (slab_state < FULL) | 5246 | if (slab_state < FULL) |
5258 | /* | 5247 | /* |
diff --git a/mm/truncate.c b/mm/truncate.c index e5cc39ab0751..6a78c814bebf 100644 --- a/mm/truncate.c +++ b/mm/truncate.c | |||
@@ -484,14 +484,6 @@ unsigned long invalidate_mapping_pages(struct address_space *mapping, | |||
484 | unsigned long count = 0; | 484 | unsigned long count = 0; |
485 | int i; | 485 | int i; |
486 | 486 | ||
487 | /* | ||
488 | * Note: this function may get called on a shmem/tmpfs mapping: | ||
489 | * pagevec_lookup() might then return 0 prematurely (because it | ||
490 | * got a gangful of swap entries); but it's hardly worth worrying | ||
491 | * about - it can rarely have anything to free from such a mapping | ||
492 | * (most pages are dirty), and already skips over any difficulties. | ||
493 | */ | ||
494 | |||
495 | pagevec_init(&pvec, 0); | 487 | pagevec_init(&pvec, 0); |
496 | while (index <= end && pagevec_lookup_entries(&pvec, mapping, index, | 488 | while (index <= end && pagevec_lookup_entries(&pvec, mapping, index, |
497 | min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1, | 489 | min(end - index, (pgoff_t)PAGEVEC_SIZE - 1) + 1, |
@@ -10,6 +10,7 @@ | |||
10 | #include <linux/swapops.h> | 10 | #include <linux/swapops.h> |
11 | #include <linux/mman.h> | 11 | #include <linux/mman.h> |
12 | #include <linux/hugetlb.h> | 12 | #include <linux/hugetlb.h> |
13 | #include <linux/vmalloc.h> | ||
13 | 14 | ||
14 | #include <asm/uaccess.h> | 15 | #include <asm/uaccess.h> |
15 | 16 | ||
@@ -387,6 +388,15 @@ unsigned long vm_mmap(struct file *file, unsigned long addr, | |||
387 | } | 388 | } |
388 | EXPORT_SYMBOL(vm_mmap); | 389 | EXPORT_SYMBOL(vm_mmap); |
389 | 390 | ||
391 | void kvfree(const void *addr) | ||
392 | { | ||
393 | if (is_vmalloc_addr(addr)) | ||
394 | vfree(addr); | ||
395 | else | ||
396 | kfree(addr); | ||
397 | } | ||
398 | EXPORT_SYMBOL(kvfree); | ||
399 | |||
390 | struct address_space *page_mapping(struct page *page) | 400 | struct address_space *page_mapping(struct page *page) |
391 | { | 401 | { |
392 | struct address_space *mapping = page->mapping; | 402 | struct address_space *mapping = page->mapping; |
diff --git a/mm/vmscan.c b/mm/vmscan.c index 3f56c8deb3c0..32c661d66a45 100644 --- a/mm/vmscan.c +++ b/mm/vmscan.c | |||
@@ -1916,6 +1916,24 @@ static void get_scan_count(struct lruvec *lruvec, struct scan_control *sc, | |||
1916 | get_lru_size(lruvec, LRU_INACTIVE_FILE); | 1916 | get_lru_size(lruvec, LRU_INACTIVE_FILE); |
1917 | 1917 | ||
1918 | /* | 1918 | /* |
1919 | * Prevent the reclaimer from falling into the cache trap: as | ||
1920 | * cache pages start out inactive, every cache fault will tip | ||
1921 | * the scan balance towards the file LRU. And as the file LRU | ||
1922 | * shrinks, so does the window for rotation from references. | ||
1923 | * This means we have a runaway feedback loop where a tiny | ||
1924 | * thrashing file LRU becomes infinitely more attractive than | ||
1925 | * anon pages. Try to detect this based on file LRU size. | ||
1926 | */ | ||
1927 | if (global_reclaim(sc)) { | ||
1928 | unsigned long free = zone_page_state(zone, NR_FREE_PAGES); | ||
1929 | |||
1930 | if (unlikely(file + free <= high_wmark_pages(zone))) { | ||
1931 | scan_balance = SCAN_ANON; | ||
1932 | goto out; | ||
1933 | } | ||
1934 | } | ||
1935 | |||
1936 | /* | ||
1919 | * There is enough inactive page cache, do not reclaim | 1937 | * There is enough inactive page cache, do not reclaim |
1920 | * anything from the anonymous working set right now. | 1938 | * anything from the anonymous working set right now. |
1921 | */ | 1939 | */ |
diff --git a/net/bluetooth/hci_conn.c b/net/bluetooth/hci_conn.c index d958e2dca52f..521fd4f3985e 100644 --- a/net/bluetooth/hci_conn.c +++ b/net/bluetooth/hci_conn.c | |||
@@ -819,14 +819,17 @@ static int hci_conn_auth(struct hci_conn *conn, __u8 sec_level, __u8 auth_type) | |||
819 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { | 819 | if (!test_and_set_bit(HCI_CONN_AUTH_PEND, &conn->flags)) { |
820 | struct hci_cp_auth_requested cp; | 820 | struct hci_cp_auth_requested cp; |
821 | 821 | ||
822 | /* encrypt must be pending if auth is also pending */ | ||
823 | set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); | ||
824 | |||
825 | cp.handle = cpu_to_le16(conn->handle); | 822 | cp.handle = cpu_to_le16(conn->handle); |
826 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, | 823 | hci_send_cmd(conn->hdev, HCI_OP_AUTH_REQUESTED, |
827 | sizeof(cp), &cp); | 824 | sizeof(cp), &cp); |
825 | |||
826 | /* If we're already encrypted set the REAUTH_PEND flag, | ||
827 | * otherwise set the ENCRYPT_PEND. | ||
828 | */ | ||
828 | if (conn->key_type != 0xff) | 829 | if (conn->key_type != 0xff) |
829 | set_bit(HCI_CONN_REAUTH_PEND, &conn->flags); | 830 | set_bit(HCI_CONN_REAUTH_PEND, &conn->flags); |
831 | else | ||
832 | set_bit(HCI_CONN_ENCRYPT_PEND, &conn->flags); | ||
830 | } | 833 | } |
831 | 834 | ||
832 | return 0; | 835 | return 0; |
diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c index 49774912cb01..15010a230b6d 100644 --- a/net/bluetooth/hci_event.c +++ b/net/bluetooth/hci_event.c | |||
@@ -3330,6 +3330,12 @@ static void hci_key_refresh_complete_evt(struct hci_dev *hdev, | |||
3330 | if (!conn) | 3330 | if (!conn) |
3331 | goto unlock; | 3331 | goto unlock; |
3332 | 3332 | ||
3333 | /* For BR/EDR the necessary steps are taken through the | ||
3334 | * auth_complete event. | ||
3335 | */ | ||
3336 | if (conn->type != LE_LINK) | ||
3337 | goto unlock; | ||
3338 | |||
3333 | if (!ev->status) | 3339 | if (!ev->status) |
3334 | conn->sec_level = conn->pending_sec_level; | 3340 | conn->sec_level = conn->pending_sec_level; |
3335 | 3341 | ||
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index e74b6d530cb6..e8844d975b32 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -445,6 +445,20 @@ static int br_validate(struct nlattr *tb[], struct nlattr *data[]) | |||
445 | return 0; | 445 | return 0; |
446 | } | 446 | } |
447 | 447 | ||
448 | static int br_dev_newlink(struct net *src_net, struct net_device *dev, | ||
449 | struct nlattr *tb[], struct nlattr *data[]) | ||
450 | { | ||
451 | struct net_bridge *br = netdev_priv(dev); | ||
452 | |||
453 | if (tb[IFLA_ADDRESS]) { | ||
454 | spin_lock_bh(&br->lock); | ||
455 | br_stp_change_bridge_id(br, nla_data(tb[IFLA_ADDRESS])); | ||
456 | spin_unlock_bh(&br->lock); | ||
457 | } | ||
458 | |||
459 | return register_netdevice(dev); | ||
460 | } | ||
461 | |||
448 | static size_t br_get_link_af_size(const struct net_device *dev) | 462 | static size_t br_get_link_af_size(const struct net_device *dev) |
449 | { | 463 | { |
450 | struct net_port_vlans *pv; | 464 | struct net_port_vlans *pv; |
@@ -473,6 +487,7 @@ struct rtnl_link_ops br_link_ops __read_mostly = { | |||
473 | .priv_size = sizeof(struct net_bridge), | 487 | .priv_size = sizeof(struct net_bridge), |
474 | .setup = br_dev_setup, | 488 | .setup = br_dev_setup, |
475 | .validate = br_validate, | 489 | .validate = br_validate, |
490 | .newlink = br_dev_newlink, | ||
476 | .dellink = br_dev_delete, | 491 | .dellink = br_dev_delete, |
477 | }; | 492 | }; |
478 | 493 | ||
diff --git a/net/can/gw.c b/net/can/gw.c index ac31891967da..050a2110d43f 100644 --- a/net/can/gw.c +++ b/net/can/gw.c | |||
@@ -804,7 +804,7 @@ static int cgw_create_job(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
804 | u8 limhops = 0; | 804 | u8 limhops = 0; |
805 | int err = 0; | 805 | int err = 0; |
806 | 806 | ||
807 | if (!capable(CAP_NET_ADMIN)) | 807 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
808 | return -EPERM; | 808 | return -EPERM; |
809 | 809 | ||
810 | if (nlmsg_len(nlh) < sizeof(*r)) | 810 | if (nlmsg_len(nlh) < sizeof(*r)) |
@@ -893,7 +893,7 @@ static int cgw_remove_job(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
893 | u8 limhops = 0; | 893 | u8 limhops = 0; |
894 | int err = 0; | 894 | int err = 0; |
895 | 895 | ||
896 | if (!capable(CAP_NET_ADMIN)) | 896 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
897 | return -EPERM; | 897 | return -EPERM; |
898 | 898 | ||
899 | if (nlmsg_len(nlh) < sizeof(*r)) | 899 | if (nlmsg_len(nlh) < sizeof(*r)) |
diff --git a/net/ceph/osdmap.c b/net/ceph/osdmap.c index e632b5a52f5b..8b8a5a24b223 100644 --- a/net/ceph/osdmap.c +++ b/net/ceph/osdmap.c | |||
@@ -1548,8 +1548,10 @@ static void apply_primary_affinity(struct ceph_osdmap *osdmap, u32 pps, | |||
1548 | return; | 1548 | return; |
1549 | 1549 | ||
1550 | for (i = 0; i < len; i++) { | 1550 | for (i = 0; i < len; i++) { |
1551 | if (osds[i] != CRUSH_ITEM_NONE && | 1551 | int osd = osds[i]; |
1552 | osdmap->osd_primary_affinity[i] != | 1552 | |
1553 | if (osd != CRUSH_ITEM_NONE && | ||
1554 | osdmap->osd_primary_affinity[osd] != | ||
1553 | CEPH_OSD_DEFAULT_PRIMARY_AFFINITY) { | 1555 | CEPH_OSD_DEFAULT_PRIMARY_AFFINITY) { |
1554 | break; | 1556 | break; |
1555 | } | 1557 | } |
@@ -1563,10 +1565,9 @@ static void apply_primary_affinity(struct ceph_osdmap *osdmap, u32 pps, | |||
1563 | * osd's pgs get rejected as primary. | 1565 | * osd's pgs get rejected as primary. |
1564 | */ | 1566 | */ |
1565 | for (i = 0; i < len; i++) { | 1567 | for (i = 0; i < len; i++) { |
1566 | int osd; | 1568 | int osd = osds[i]; |
1567 | u32 aff; | 1569 | u32 aff; |
1568 | 1570 | ||
1569 | osd = osds[i]; | ||
1570 | if (osd == CRUSH_ITEM_NONE) | 1571 | if (osd == CRUSH_ITEM_NONE) |
1571 | continue; | 1572 | continue; |
1572 | 1573 | ||
diff --git a/net/core/filter.c b/net/core/filter.c index cd58614660cf..9d79ca0a6e8e 100644 --- a/net/core/filter.c +++ b/net/core/filter.c | |||
@@ -122,6 +122,13 @@ noinline u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5) | |||
122 | return 0; | 122 | return 0; |
123 | } | 123 | } |
124 | 124 | ||
125 | /* Register mappings for user programs. */ | ||
126 | #define A_REG 0 | ||
127 | #define X_REG 7 | ||
128 | #define TMP_REG 8 | ||
129 | #define ARG2_REG 2 | ||
130 | #define ARG3_REG 3 | ||
131 | |||
125 | /** | 132 | /** |
126 | * __sk_run_filter - run a filter on a given context | 133 | * __sk_run_filter - run a filter on a given context |
127 | * @ctx: buffer to run the filter on | 134 | * @ctx: buffer to run the filter on |
@@ -242,6 +249,8 @@ unsigned int __sk_run_filter(void *ctx, const struct sock_filter_int *insn) | |||
242 | 249 | ||
243 | regs[FP_REG] = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)]; | 250 | regs[FP_REG] = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)]; |
244 | regs[ARG1_REG] = (u64) (unsigned long) ctx; | 251 | regs[ARG1_REG] = (u64) (unsigned long) ctx; |
252 | regs[A_REG] = 0; | ||
253 | regs[X_REG] = 0; | ||
245 | 254 | ||
246 | select_insn: | 255 | select_insn: |
247 | goto *jumptable[insn->code]; | 256 | goto *jumptable[insn->code]; |
@@ -643,13 +652,6 @@ static u64 __get_raw_cpu_id(u64 ctx, u64 A, u64 X, u64 r4, u64 r5) | |||
643 | return raw_smp_processor_id(); | 652 | return raw_smp_processor_id(); |
644 | } | 653 | } |
645 | 654 | ||
646 | /* Register mappings for user programs. */ | ||
647 | #define A_REG 0 | ||
648 | #define X_REG 7 | ||
649 | #define TMP_REG 8 | ||
650 | #define ARG2_REG 2 | ||
651 | #define ARG3_REG 3 | ||
652 | |||
653 | static bool convert_bpf_extensions(struct sock_filter *fp, | 655 | static bool convert_bpf_extensions(struct sock_filter *fp, |
654 | struct sock_filter_int **insnp) | 656 | struct sock_filter_int **insnp) |
655 | { | 657 | { |
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c index d4ff41739b0f..9837bebf93ce 100644 --- a/net/core/rtnetlink.c +++ b/net/core/rtnetlink.c | |||
@@ -774,7 +774,8 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev, | |||
774 | return 0; | 774 | return 0; |
775 | } | 775 | } |
776 | 776 | ||
777 | static size_t rtnl_port_size(const struct net_device *dev) | 777 | static size_t rtnl_port_size(const struct net_device *dev, |
778 | u32 ext_filter_mask) | ||
778 | { | 779 | { |
779 | size_t port_size = nla_total_size(4) /* PORT_VF */ | 780 | size_t port_size = nla_total_size(4) /* PORT_VF */ |
780 | + nla_total_size(PORT_PROFILE_MAX) /* PORT_PROFILE */ | 781 | + nla_total_size(PORT_PROFILE_MAX) /* PORT_PROFILE */ |
@@ -790,7 +791,8 @@ static size_t rtnl_port_size(const struct net_device *dev) | |||
790 | size_t port_self_size = nla_total_size(sizeof(struct nlattr)) | 791 | size_t port_self_size = nla_total_size(sizeof(struct nlattr)) |
791 | + port_size; | 792 | + port_size; |
792 | 793 | ||
793 | if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent) | 794 | if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent || |
795 | !(ext_filter_mask & RTEXT_FILTER_VF)) | ||
794 | return 0; | 796 | return 0; |
795 | if (dev_num_vf(dev->dev.parent)) | 797 | if (dev_num_vf(dev->dev.parent)) |
796 | return port_self_size + vf_ports_size + | 798 | return port_self_size + vf_ports_size + |
@@ -826,7 +828,7 @@ static noinline size_t if_nlmsg_size(const struct net_device *dev, | |||
826 | + nla_total_size(ext_filter_mask | 828 | + nla_total_size(ext_filter_mask |
827 | & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */ | 829 | & RTEXT_FILTER_VF ? 4 : 0) /* IFLA_NUM_VF */ |
828 | + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */ | 830 | + rtnl_vfinfo_size(dev, ext_filter_mask) /* IFLA_VFINFO_LIST */ |
829 | + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */ | 831 | + rtnl_port_size(dev, ext_filter_mask) /* IFLA_VF_PORTS + IFLA_PORT_SELF */ |
830 | + rtnl_link_get_size(dev) /* IFLA_LINKINFO */ | 832 | + rtnl_link_get_size(dev) /* IFLA_LINKINFO */ |
831 | + rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */ | 833 | + rtnl_link_get_af_size(dev) /* IFLA_AF_SPEC */ |
832 | + nla_total_size(MAX_PHYS_PORT_ID_LEN); /* IFLA_PHYS_PORT_ID */ | 834 | + nla_total_size(MAX_PHYS_PORT_ID_LEN); /* IFLA_PHYS_PORT_ID */ |
@@ -888,11 +890,13 @@ static int rtnl_port_self_fill(struct sk_buff *skb, struct net_device *dev) | |||
888 | return 0; | 890 | return 0; |
889 | } | 891 | } |
890 | 892 | ||
891 | static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev) | 893 | static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev, |
894 | u32 ext_filter_mask) | ||
892 | { | 895 | { |
893 | int err; | 896 | int err; |
894 | 897 | ||
895 | if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent) | 898 | if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent || |
899 | !(ext_filter_mask & RTEXT_FILTER_VF)) | ||
896 | return 0; | 900 | return 0; |
897 | 901 | ||
898 | err = rtnl_port_self_fill(skb, dev); | 902 | err = rtnl_port_self_fill(skb, dev); |
@@ -1079,7 +1083,7 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, | |||
1079 | nla_nest_end(skb, vfinfo); | 1083 | nla_nest_end(skb, vfinfo); |
1080 | } | 1084 | } |
1081 | 1085 | ||
1082 | if (rtnl_port_fill(skb, dev)) | 1086 | if (rtnl_port_fill(skb, dev, ext_filter_mask)) |
1083 | goto nla_put_failure; | 1087 | goto nla_put_failure; |
1084 | 1088 | ||
1085 | if (dev->rtnl_link_ops || rtnl_have_link_slave_info(dev)) { | 1089 | if (dev->rtnl_link_ops || rtnl_have_link_slave_info(dev)) { |
@@ -1198,6 +1202,7 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
1198 | struct hlist_head *head; | 1202 | struct hlist_head *head; |
1199 | struct nlattr *tb[IFLA_MAX+1]; | 1203 | struct nlattr *tb[IFLA_MAX+1]; |
1200 | u32 ext_filter_mask = 0; | 1204 | u32 ext_filter_mask = 0; |
1205 | int err; | ||
1201 | 1206 | ||
1202 | s_h = cb->args[0]; | 1207 | s_h = cb->args[0]; |
1203 | s_idx = cb->args[1]; | 1208 | s_idx = cb->args[1]; |
@@ -1218,11 +1223,17 @@ static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | |||
1218 | hlist_for_each_entry_rcu(dev, head, index_hlist) { | 1223 | hlist_for_each_entry_rcu(dev, head, index_hlist) { |
1219 | if (idx < s_idx) | 1224 | if (idx < s_idx) |
1220 | goto cont; | 1225 | goto cont; |
1221 | if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, | 1226 | err = rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK, |
1222 | NETLINK_CB(cb->skb).portid, | 1227 | NETLINK_CB(cb->skb).portid, |
1223 | cb->nlh->nlmsg_seq, 0, | 1228 | cb->nlh->nlmsg_seq, 0, |
1224 | NLM_F_MULTI, | 1229 | NLM_F_MULTI, |
1225 | ext_filter_mask) <= 0) | 1230 | ext_filter_mask); |
1231 | /* If we ran out of room on the first message, | ||
1232 | * we're in trouble | ||
1233 | */ | ||
1234 | WARN_ON((err == -EMSGSIZE) && (skb->len == 0)); | ||
1235 | |||
1236 | if (err <= 0) | ||
1226 | goto out; | 1237 | goto out; |
1227 | 1238 | ||
1228 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); | 1239 | nl_dump_check_consistent(cb, nlmsg_hdr(skb)); |
@@ -1395,7 +1406,8 @@ static int do_set_master(struct net_device *dev, int ifindex) | |||
1395 | return 0; | 1406 | return 0; |
1396 | } | 1407 | } |
1397 | 1408 | ||
1398 | static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | 1409 | static int do_setlink(const struct sk_buff *skb, |
1410 | struct net_device *dev, struct ifinfomsg *ifm, | ||
1399 | struct nlattr **tb, char *ifname, int modified) | 1411 | struct nlattr **tb, char *ifname, int modified) |
1400 | { | 1412 | { |
1401 | const struct net_device_ops *ops = dev->netdev_ops; | 1413 | const struct net_device_ops *ops = dev->netdev_ops; |
@@ -1407,7 +1419,7 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, | |||
1407 | err = PTR_ERR(net); | 1419 | err = PTR_ERR(net); |
1408 | goto errout; | 1420 | goto errout; |
1409 | } | 1421 | } |
1410 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) { | 1422 | if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) { |
1411 | err = -EPERM; | 1423 | err = -EPERM; |
1412 | goto errout; | 1424 | goto errout; |
1413 | } | 1425 | } |
@@ -1661,7 +1673,7 @@ static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1661 | if (err < 0) | 1673 | if (err < 0) |
1662 | goto errout; | 1674 | goto errout; |
1663 | 1675 | ||
1664 | err = do_setlink(dev, ifm, tb, ifname, 0); | 1676 | err = do_setlink(skb, dev, ifm, tb, ifname, 0); |
1665 | errout: | 1677 | errout: |
1666 | return err; | 1678 | return err; |
1667 | } | 1679 | } |
@@ -1778,7 +1790,8 @@ err: | |||
1778 | } | 1790 | } |
1779 | EXPORT_SYMBOL(rtnl_create_link); | 1791 | EXPORT_SYMBOL(rtnl_create_link); |
1780 | 1792 | ||
1781 | static int rtnl_group_changelink(struct net *net, int group, | 1793 | static int rtnl_group_changelink(const struct sk_buff *skb, |
1794 | struct net *net, int group, | ||
1782 | struct ifinfomsg *ifm, | 1795 | struct ifinfomsg *ifm, |
1783 | struct nlattr **tb) | 1796 | struct nlattr **tb) |
1784 | { | 1797 | { |
@@ -1787,7 +1800,7 @@ static int rtnl_group_changelink(struct net *net, int group, | |||
1787 | 1800 | ||
1788 | for_each_netdev(net, dev) { | 1801 | for_each_netdev(net, dev) { |
1789 | if (dev->group == group) { | 1802 | if (dev->group == group) { |
1790 | err = do_setlink(dev, ifm, tb, NULL, 0); | 1803 | err = do_setlink(skb, dev, ifm, tb, NULL, 0); |
1791 | if (err < 0) | 1804 | if (err < 0) |
1792 | return err; | 1805 | return err; |
1793 | } | 1806 | } |
@@ -1929,12 +1942,12 @@ replay: | |||
1929 | modified = 1; | 1942 | modified = 1; |
1930 | } | 1943 | } |
1931 | 1944 | ||
1932 | return do_setlink(dev, ifm, tb, ifname, modified); | 1945 | return do_setlink(skb, dev, ifm, tb, ifname, modified); |
1933 | } | 1946 | } |
1934 | 1947 | ||
1935 | if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { | 1948 | if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { |
1936 | if (ifm->ifi_index == 0 && tb[IFLA_GROUP]) | 1949 | if (ifm->ifi_index == 0 && tb[IFLA_GROUP]) |
1937 | return rtnl_group_changelink(net, | 1950 | return rtnl_group_changelink(skb, net, |
1938 | nla_get_u32(tb[IFLA_GROUP]), | 1951 | nla_get_u32(tb[IFLA_GROUP]), |
1939 | ifm, tb); | 1952 | ifm, tb); |
1940 | return -ENODEV; | 1953 | return -ENODEV; |
@@ -2321,7 +2334,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2321 | int err = -EINVAL; | 2334 | int err = -EINVAL; |
2322 | __u8 *addr; | 2335 | __u8 *addr; |
2323 | 2336 | ||
2324 | if (!capable(CAP_NET_ADMIN)) | 2337 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
2325 | return -EPERM; | 2338 | return -EPERM; |
2326 | 2339 | ||
2327 | err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); | 2340 | err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); |
@@ -2773,7 +2786,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2773 | sz_idx = type>>2; | 2786 | sz_idx = type>>2; |
2774 | kind = type&3; | 2787 | kind = type&3; |
2775 | 2788 | ||
2776 | if (kind != 2 && !ns_capable(net->user_ns, CAP_NET_ADMIN)) | 2789 | if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN)) |
2777 | return -EPERM; | 2790 | return -EPERM; |
2778 | 2791 | ||
2779 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { | 2792 | if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { |
diff --git a/net/core/sock.c b/net/core/sock.c index b4fff008136f..664ee4295b6f 100644 --- a/net/core/sock.c +++ b/net/core/sock.c | |||
@@ -145,6 +145,55 @@ | |||
145 | static DEFINE_MUTEX(proto_list_mutex); | 145 | static DEFINE_MUTEX(proto_list_mutex); |
146 | static LIST_HEAD(proto_list); | 146 | static LIST_HEAD(proto_list); |
147 | 147 | ||
148 | /** | ||
149 | * sk_ns_capable - General socket capability test | ||
150 | * @sk: Socket to use a capability on or through | ||
151 | * @user_ns: The user namespace of the capability to use | ||
152 | * @cap: The capability to use | ||
153 | * | ||
154 | * Test to see if the opener of the socket had when the socket was | ||
155 | * created and the current process has the capability @cap in the user | ||
156 | * namespace @user_ns. | ||
157 | */ | ||
158 | bool sk_ns_capable(const struct sock *sk, | ||
159 | struct user_namespace *user_ns, int cap) | ||
160 | { | ||
161 | return file_ns_capable(sk->sk_socket->file, user_ns, cap) && | ||
162 | ns_capable(user_ns, cap); | ||
163 | } | ||
164 | EXPORT_SYMBOL(sk_ns_capable); | ||
165 | |||
166 | /** | ||
167 | * sk_capable - Socket global capability test | ||
168 | * @sk: Socket to use a capability on or through | ||
169 | * @cap: The global capbility to use | ||
170 | * | ||
171 | * Test to see if the opener of the socket had when the socket was | ||
172 | * created and the current process has the capability @cap in all user | ||
173 | * namespaces. | ||
174 | */ | ||
175 | bool sk_capable(const struct sock *sk, int cap) | ||
176 | { | ||
177 | return sk_ns_capable(sk, &init_user_ns, cap); | ||
178 | } | ||
179 | EXPORT_SYMBOL(sk_capable); | ||
180 | |||
181 | /** | ||
182 | * sk_net_capable - Network namespace socket capability test | ||
183 | * @sk: Socket to use a capability on or through | ||
184 | * @cap: The capability to use | ||
185 | * | ||
186 | * Test to see if the opener of the socket had when the socke was created | ||
187 | * and the current process has the capability @cap over the network namespace | ||
188 | * the socket is a member of. | ||
189 | */ | ||
190 | bool sk_net_capable(const struct sock *sk, int cap) | ||
191 | { | ||
192 | return sk_ns_capable(sk, sock_net(sk)->user_ns, cap); | ||
193 | } | ||
194 | EXPORT_SYMBOL(sk_net_capable); | ||
195 | |||
196 | |||
148 | #ifdef CONFIG_MEMCG_KMEM | 197 | #ifdef CONFIG_MEMCG_KMEM |
149 | int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss) | 198 | int mem_cgroup_sockets_init(struct mem_cgroup *memcg, struct cgroup_subsys *ss) |
150 | { | 199 | { |
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c index d7af18859322..a4216a4c9572 100644 --- a/net/core/sock_diag.c +++ b/net/core/sock_diag.c | |||
@@ -49,7 +49,7 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype) | |||
49 | } | 49 | } |
50 | EXPORT_SYMBOL_GPL(sock_diag_put_meminfo); | 50 | EXPORT_SYMBOL_GPL(sock_diag_put_meminfo); |
51 | 51 | ||
52 | int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk, | 52 | int sock_diag_put_filterinfo(bool may_report_filterinfo, struct sock *sk, |
53 | struct sk_buff *skb, int attrtype) | 53 | struct sk_buff *skb, int attrtype) |
54 | { | 54 | { |
55 | struct sock_fprog_kern *fprog; | 55 | struct sock_fprog_kern *fprog; |
@@ -58,7 +58,7 @@ int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk, | |||
58 | unsigned int flen; | 58 | unsigned int flen; |
59 | int err = 0; | 59 | int err = 0; |
60 | 60 | ||
61 | if (!ns_capable(user_ns, CAP_NET_ADMIN)) { | 61 | if (!may_report_filterinfo) { |
62 | nla_reserve(skb, attrtype, 0); | 62 | nla_reserve(skb, attrtype, 0); |
63 | return 0; | 63 | return 0; |
64 | } | 64 | } |
diff --git a/net/dcb/dcbnl.c b/net/dcb/dcbnl.c index 553644402670..f8b98d89c285 100644 --- a/net/dcb/dcbnl.c +++ b/net/dcb/dcbnl.c | |||
@@ -1669,7 +1669,7 @@ static int dcb_doit(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
1669 | struct nlmsghdr *reply_nlh = NULL; | 1669 | struct nlmsghdr *reply_nlh = NULL; |
1670 | const struct reply_func *fn; | 1670 | const struct reply_func *fn; |
1671 | 1671 | ||
1672 | if ((nlh->nlmsg_type == RTM_SETDCB) && !capable(CAP_NET_ADMIN)) | 1672 | if ((nlh->nlmsg_type == RTM_SETDCB) && !netlink_capable(skb, CAP_NET_ADMIN)) |
1673 | return -EPERM; | 1673 | return -EPERM; |
1674 | 1674 | ||
1675 | ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX, | 1675 | ret = nlmsg_parse(nlh, sizeof(*dcb), tb, DCB_ATTR_MAX, |
diff --git a/net/decnet/dn_dev.c b/net/decnet/dn_dev.c index a603823a3e27..3b726f31c64c 100644 --- a/net/decnet/dn_dev.c +++ b/net/decnet/dn_dev.c | |||
@@ -574,7 +574,7 @@ static int dn_nl_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
574 | struct dn_ifaddr __rcu **ifap; | 574 | struct dn_ifaddr __rcu **ifap; |
575 | int err = -EINVAL; | 575 | int err = -EINVAL; |
576 | 576 | ||
577 | if (!capable(CAP_NET_ADMIN)) | 577 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
578 | return -EPERM; | 578 | return -EPERM; |
579 | 579 | ||
580 | if (!net_eq(net, &init_net)) | 580 | if (!net_eq(net, &init_net)) |
@@ -618,7 +618,7 @@ static int dn_nl_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
618 | struct dn_ifaddr *ifa; | 618 | struct dn_ifaddr *ifa; |
619 | int err; | 619 | int err; |
620 | 620 | ||
621 | if (!capable(CAP_NET_ADMIN)) | 621 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
622 | return -EPERM; | 622 | return -EPERM; |
623 | 623 | ||
624 | if (!net_eq(net, &init_net)) | 624 | if (!net_eq(net, &init_net)) |
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c index 57dc159245ec..d332aefb0846 100644 --- a/net/decnet/dn_fib.c +++ b/net/decnet/dn_fib.c | |||
@@ -505,7 +505,7 @@ static int dn_fib_rtm_delroute(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
505 | struct nlattr *attrs[RTA_MAX+1]; | 505 | struct nlattr *attrs[RTA_MAX+1]; |
506 | int err; | 506 | int err; |
507 | 507 | ||
508 | if (!capable(CAP_NET_ADMIN)) | 508 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
509 | return -EPERM; | 509 | return -EPERM; |
510 | 510 | ||
511 | if (!net_eq(net, &init_net)) | 511 | if (!net_eq(net, &init_net)) |
@@ -530,7 +530,7 @@ static int dn_fib_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
530 | struct nlattr *attrs[RTA_MAX+1]; | 530 | struct nlattr *attrs[RTA_MAX+1]; |
531 | int err; | 531 | int err; |
532 | 532 | ||
533 | if (!capable(CAP_NET_ADMIN)) | 533 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
534 | return -EPERM; | 534 | return -EPERM; |
535 | 535 | ||
536 | if (!net_eq(net, &init_net)) | 536 | if (!net_eq(net, &init_net)) |
diff --git a/net/decnet/netfilter/dn_rtmsg.c b/net/decnet/netfilter/dn_rtmsg.c index e83015cecfa7..e4d9560a910b 100644 --- a/net/decnet/netfilter/dn_rtmsg.c +++ b/net/decnet/netfilter/dn_rtmsg.c | |||
@@ -107,7 +107,7 @@ static inline void dnrmg_receive_user_skb(struct sk_buff *skb) | |||
107 | if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) | 107 | if (nlh->nlmsg_len < sizeof(*nlh) || skb->len < nlh->nlmsg_len) |
108 | return; | 108 | return; |
109 | 109 | ||
110 | if (!capable(CAP_NET_ADMIN)) | 110 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
111 | RCV_SKB_FAIL(-EPERM); | 111 | RCV_SKB_FAIL(-EPERM); |
112 | 112 | ||
113 | /* Eventually we might send routing messages too */ | 113 | /* Eventually we might send routing messages too */ |
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c index fa5b7519765f..b3f859731c60 100644 --- a/net/ipv4/ip_tunnel.c +++ b/net/ipv4/ip_tunnel.c | |||
@@ -442,6 +442,8 @@ int ip_tunnel_rcv(struct ip_tunnel *tunnel, struct sk_buff *skb, | |||
442 | tunnel->i_seqno = ntohl(tpi->seq) + 1; | 442 | tunnel->i_seqno = ntohl(tpi->seq) + 1; |
443 | } | 443 | } |
444 | 444 | ||
445 | skb_reset_network_header(skb); | ||
446 | |||
445 | err = IP_ECN_decapsulate(iph, skb); | 447 | err = IP_ECN_decapsulate(iph, skb); |
446 | if (unlikely(err)) { | 448 | if (unlikely(err)) { |
447 | if (log_ecn_error) | 449 | if (log_ecn_error) |
diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c index 8bf224516ba2..b4f1b29b08bd 100644 --- a/net/ipv4/tcp_cubic.c +++ b/net/ipv4/tcp_cubic.c | |||
@@ -409,7 +409,7 @@ static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us) | |||
409 | ratio -= ca->delayed_ack >> ACK_RATIO_SHIFT; | 409 | ratio -= ca->delayed_ack >> ACK_RATIO_SHIFT; |
410 | ratio += cnt; | 410 | ratio += cnt; |
411 | 411 | ||
412 | ca->delayed_ack = min(ratio, ACK_RATIO_LIMIT); | 412 | ca->delayed_ack = clamp(ratio, 1U, ACK_RATIO_LIMIT); |
413 | } | 413 | } |
414 | 414 | ||
415 | /* Some calls are for duplicates without timetamps */ | 415 | /* Some calls are for duplicates without timetamps */ |
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 025e25093984..12d6016bdd9a 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2441,8 +2441,14 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
2441 | err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); | 2441 | err = tcp_transmit_skb(sk, skb, 1, GFP_ATOMIC); |
2442 | } | 2442 | } |
2443 | 2443 | ||
2444 | if (likely(!err)) | 2444 | if (likely(!err)) { |
2445 | TCP_SKB_CB(skb)->sacked |= TCPCB_EVER_RETRANS; | 2445 | TCP_SKB_CB(skb)->sacked |= TCPCB_EVER_RETRANS; |
2446 | /* Update global TCP statistics. */ | ||
2447 | TCP_INC_STATS(sock_net(sk), TCP_MIB_RETRANSSEGS); | ||
2448 | if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN) | ||
2449 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSYNRETRANS); | ||
2450 | tp->total_retrans++; | ||
2451 | } | ||
2446 | return err; | 2452 | return err; |
2447 | } | 2453 | } |
2448 | 2454 | ||
@@ -2452,12 +2458,6 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb) | |||
2452 | int err = __tcp_retransmit_skb(sk, skb); | 2458 | int err = __tcp_retransmit_skb(sk, skb); |
2453 | 2459 | ||
2454 | if (err == 0) { | 2460 | if (err == 0) { |
2455 | /* Update global TCP statistics. */ | ||
2456 | TCP_INC_STATS(sock_net(sk), TCP_MIB_RETRANSSEGS); | ||
2457 | if (TCP_SKB_CB(skb)->tcp_flags & TCPHDR_SYN) | ||
2458 | NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSYNRETRANS); | ||
2459 | tp->total_retrans++; | ||
2460 | |||
2461 | #if FASTRETRANS_DEBUG > 0 | 2461 | #if FASTRETRANS_DEBUG > 0 |
2462 | if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) { | 2462 | if (TCP_SKB_CB(skb)->sacked & TCPCB_SACKED_RETRANS) { |
2463 | net_dbg_ratelimited("retrans_out leaked\n"); | 2463 | net_dbg_ratelimited("retrans_out leaked\n"); |
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c index 34e0ded5c14b..87891f5f57b5 100644 --- a/net/ipv6/ip6_fib.c +++ b/net/ipv6/ip6_fib.c | |||
@@ -1459,7 +1459,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w) | |||
1459 | 1459 | ||
1460 | if (w->skip) { | 1460 | if (w->skip) { |
1461 | w->skip--; | 1461 | w->skip--; |
1462 | continue; | 1462 | goto skip; |
1463 | } | 1463 | } |
1464 | 1464 | ||
1465 | err = w->func(w); | 1465 | err = w->func(w); |
@@ -1469,6 +1469,7 @@ static int fib6_walk_continue(struct fib6_walker_t *w) | |||
1469 | w->count++; | 1469 | w->count++; |
1470 | continue; | 1470 | continue; |
1471 | } | 1471 | } |
1472 | skip: | ||
1472 | w->state = FWS_U; | 1473 | w->state = FWS_U; |
1473 | case FWS_U: | 1474 | case FWS_U: |
1474 | if (fn == w->root) | 1475 | if (fn == w->root) |
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 8659067da28e..8250474ab7dc 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c | |||
@@ -1633,7 +1633,7 @@ struct sock *mroute6_socket(struct net *net, struct sk_buff *skb) | |||
1633 | { | 1633 | { |
1634 | struct mr6_table *mrt; | 1634 | struct mr6_table *mrt; |
1635 | struct flowi6 fl6 = { | 1635 | struct flowi6 fl6 = { |
1636 | .flowi6_iif = skb->skb_iif, | 1636 | .flowi6_iif = skb->skb_iif ? : LOOPBACK_IFINDEX, |
1637 | .flowi6_oif = skb->dev->ifindex, | 1637 | .flowi6_oif = skb->dev->ifindex, |
1638 | .flowi6_mark = skb->mark, | 1638 | .flowi6_mark = skb->mark, |
1639 | }; | 1639 | }; |
diff --git a/net/ipv6/netfilter/ip6t_rpfilter.c b/net/ipv6/netfilter/ip6t_rpfilter.c index e0983f3648a6..790e0c6b19e1 100644 --- a/net/ipv6/netfilter/ip6t_rpfilter.c +++ b/net/ipv6/netfilter/ip6t_rpfilter.c | |||
@@ -33,6 +33,7 @@ static bool rpfilter_lookup_reverse6(const struct sk_buff *skb, | |||
33 | struct ipv6hdr *iph = ipv6_hdr(skb); | 33 | struct ipv6hdr *iph = ipv6_hdr(skb); |
34 | bool ret = false; | 34 | bool ret = false; |
35 | struct flowi6 fl6 = { | 35 | struct flowi6 fl6 = { |
36 | .flowi6_iif = LOOPBACK_IFINDEX, | ||
36 | .flowlabel = (* (__be32 *) iph) & IPV6_FLOWINFO_MASK, | 37 | .flowlabel = (* (__be32 *) iph) & IPV6_FLOWINFO_MASK, |
37 | .flowi6_proto = iph->nexthdr, | 38 | .flowi6_proto = iph->nexthdr, |
38 | .daddr = iph->saddr, | 39 | .daddr = iph->saddr, |
diff --git a/net/ipv6/route.c b/net/ipv6/route.c index 4011617cca68..004fffb6c221 100644 --- a/net/ipv6/route.c +++ b/net/ipv6/route.c | |||
@@ -1273,6 +1273,7 @@ void ip6_redirect(struct sk_buff *skb, struct net *net, int oif, u32 mark) | |||
1273 | struct flowi6 fl6; | 1273 | struct flowi6 fl6; |
1274 | 1274 | ||
1275 | memset(&fl6, 0, sizeof(fl6)); | 1275 | memset(&fl6, 0, sizeof(fl6)); |
1276 | fl6.flowi6_iif = LOOPBACK_IFINDEX; | ||
1276 | fl6.flowi6_oif = oif; | 1277 | fl6.flowi6_oif = oif; |
1277 | fl6.flowi6_mark = mark; | 1278 | fl6.flowi6_mark = mark; |
1278 | fl6.daddr = iph->daddr; | 1279 | fl6.daddr = iph->daddr; |
@@ -1294,6 +1295,7 @@ void ip6_redirect_no_header(struct sk_buff *skb, struct net *net, int oif, | |||
1294 | struct flowi6 fl6; | 1295 | struct flowi6 fl6; |
1295 | 1296 | ||
1296 | memset(&fl6, 0, sizeof(fl6)); | 1297 | memset(&fl6, 0, sizeof(fl6)); |
1298 | fl6.flowi6_iif = LOOPBACK_IFINDEX; | ||
1297 | fl6.flowi6_oif = oif; | 1299 | fl6.flowi6_oif = oif; |
1298 | fl6.flowi6_mark = mark; | 1300 | fl6.flowi6_mark = mark; |
1299 | fl6.daddr = msg->dest; | 1301 | fl6.daddr = msg->dest; |
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c index e8138da4c14f..e009087620e3 100644 --- a/net/netfilter/nfnetlink.c +++ b/net/netfilter/nfnetlink.c | |||
@@ -368,14 +368,13 @@ done: | |||
368 | static void nfnetlink_rcv(struct sk_buff *skb) | 368 | static void nfnetlink_rcv(struct sk_buff *skb) |
369 | { | 369 | { |
370 | struct nlmsghdr *nlh = nlmsg_hdr(skb); | 370 | struct nlmsghdr *nlh = nlmsg_hdr(skb); |
371 | struct net *net = sock_net(skb->sk); | ||
372 | int msglen; | 371 | int msglen; |
373 | 372 | ||
374 | if (nlh->nlmsg_len < NLMSG_HDRLEN || | 373 | if (nlh->nlmsg_len < NLMSG_HDRLEN || |
375 | skb->len < nlh->nlmsg_len) | 374 | skb->len < nlh->nlmsg_len) |
376 | return; | 375 | return; |
377 | 376 | ||
378 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) { | 377 | if (!netlink_net_capable(skb, CAP_NET_ADMIN)) { |
379 | netlink_ack(skb, nlh, -EPERM); | 378 | netlink_ack(skb, nlh, -EPERM); |
380 | return; | 379 | return; |
381 | } | 380 | } |
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c index 894cda0206bb..81dca96d2be6 100644 --- a/net/netlink/af_netlink.c +++ b/net/netlink/af_netlink.c | |||
@@ -1360,7 +1360,72 @@ retry: | |||
1360 | return err; | 1360 | return err; |
1361 | } | 1361 | } |
1362 | 1362 | ||
1363 | static inline int netlink_capable(const struct socket *sock, unsigned int flag) | 1363 | /** |
1364 | * __netlink_ns_capable - General netlink message capability test | ||
1365 | * @nsp: NETLINK_CB of the socket buffer holding a netlink command from userspace. | ||
1366 | * @user_ns: The user namespace of the capability to use | ||
1367 | * @cap: The capability to use | ||
1368 | * | ||
1369 | * Test to see if the opener of the socket we received the message | ||
1370 | * from had when the netlink socket was created and the sender of the | ||
1371 | * message has has the capability @cap in the user namespace @user_ns. | ||
1372 | */ | ||
1373 | bool __netlink_ns_capable(const struct netlink_skb_parms *nsp, | ||
1374 | struct user_namespace *user_ns, int cap) | ||
1375 | { | ||
1376 | return sk_ns_capable(nsp->sk, user_ns, cap); | ||
1377 | } | ||
1378 | EXPORT_SYMBOL(__netlink_ns_capable); | ||
1379 | |||
1380 | /** | ||
1381 | * netlink_ns_capable - General netlink message capability test | ||
1382 | * @skb: socket buffer holding a netlink command from userspace | ||
1383 | * @user_ns: The user namespace of the capability to use | ||
1384 | * @cap: The capability to use | ||
1385 | * | ||
1386 | * Test to see if the opener of the socket we received the message | ||
1387 | * from had when the netlink socket was created and the sender of the | ||
1388 | * message has has the capability @cap in the user namespace @user_ns. | ||
1389 | */ | ||
1390 | bool netlink_ns_capable(const struct sk_buff *skb, | ||
1391 | struct user_namespace *user_ns, int cap) | ||
1392 | { | ||
1393 | return __netlink_ns_capable(&NETLINK_CB(skb), user_ns, cap); | ||
1394 | } | ||
1395 | EXPORT_SYMBOL(netlink_ns_capable); | ||
1396 | |||
1397 | /** | ||
1398 | * netlink_capable - Netlink global message capability test | ||
1399 | * @skb: socket buffer holding a netlink command from userspace | ||
1400 | * @cap: The capability to use | ||
1401 | * | ||
1402 | * Test to see if the opener of the socket we received the message | ||
1403 | * from had when the netlink socket was created and the sender of the | ||
1404 | * message has has the capability @cap in all user namespaces. | ||
1405 | */ | ||
1406 | bool netlink_capable(const struct sk_buff *skb, int cap) | ||
1407 | { | ||
1408 | return netlink_ns_capable(skb, &init_user_ns, cap); | ||
1409 | } | ||
1410 | EXPORT_SYMBOL(netlink_capable); | ||
1411 | |||
1412 | /** | ||
1413 | * netlink_net_capable - Netlink network namespace message capability test | ||
1414 | * @skb: socket buffer holding a netlink command from userspace | ||
1415 | * @cap: The capability to use | ||
1416 | * | ||
1417 | * Test to see if the opener of the socket we received the message | ||
1418 | * from had when the netlink socket was created and the sender of the | ||
1419 | * message has has the capability @cap over the network namespace of | ||
1420 | * the socket we received the message from. | ||
1421 | */ | ||
1422 | bool netlink_net_capable(const struct sk_buff *skb, int cap) | ||
1423 | { | ||
1424 | return netlink_ns_capable(skb, sock_net(skb->sk)->user_ns, cap); | ||
1425 | } | ||
1426 | EXPORT_SYMBOL(netlink_net_capable); | ||
1427 | |||
1428 | static inline int netlink_allowed(const struct socket *sock, unsigned int flag) | ||
1364 | { | 1429 | { |
1365 | return (nl_table[sock->sk->sk_protocol].flags & flag) || | 1430 | return (nl_table[sock->sk->sk_protocol].flags & flag) || |
1366 | ns_capable(sock_net(sock->sk)->user_ns, CAP_NET_ADMIN); | 1431 | ns_capable(sock_net(sock->sk)->user_ns, CAP_NET_ADMIN); |
@@ -1428,7 +1493,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr, | |||
1428 | 1493 | ||
1429 | /* Only superuser is allowed to listen multicasts */ | 1494 | /* Only superuser is allowed to listen multicasts */ |
1430 | if (nladdr->nl_groups) { | 1495 | if (nladdr->nl_groups) { |
1431 | if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV)) | 1496 | if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV)) |
1432 | return -EPERM; | 1497 | return -EPERM; |
1433 | err = netlink_realloc_groups(sk); | 1498 | err = netlink_realloc_groups(sk); |
1434 | if (err) | 1499 | if (err) |
@@ -1490,7 +1555,7 @@ static int netlink_connect(struct socket *sock, struct sockaddr *addr, | |||
1490 | return -EINVAL; | 1555 | return -EINVAL; |
1491 | 1556 | ||
1492 | if ((nladdr->nl_groups || nladdr->nl_pid) && | 1557 | if ((nladdr->nl_groups || nladdr->nl_pid) && |
1493 | !netlink_capable(sock, NL_CFG_F_NONROOT_SEND)) | 1558 | !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND)) |
1494 | return -EPERM; | 1559 | return -EPERM; |
1495 | 1560 | ||
1496 | if (!nlk->portid) | 1561 | if (!nlk->portid) |
@@ -2096,7 +2161,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname, | |||
2096 | break; | 2161 | break; |
2097 | case NETLINK_ADD_MEMBERSHIP: | 2162 | case NETLINK_ADD_MEMBERSHIP: |
2098 | case NETLINK_DROP_MEMBERSHIP: { | 2163 | case NETLINK_DROP_MEMBERSHIP: { |
2099 | if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV)) | 2164 | if (!netlink_allowed(sock, NL_CFG_F_NONROOT_RECV)) |
2100 | return -EPERM; | 2165 | return -EPERM; |
2101 | err = netlink_realloc_groups(sk); | 2166 | err = netlink_realloc_groups(sk); |
2102 | if (err) | 2167 | if (err) |
@@ -2247,7 +2312,7 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock, | |||
2247 | dst_group = ffs(addr->nl_groups); | 2312 | dst_group = ffs(addr->nl_groups); |
2248 | err = -EPERM; | 2313 | err = -EPERM; |
2249 | if ((dst_group || dst_portid) && | 2314 | if ((dst_group || dst_portid) && |
2250 | !netlink_capable(sock, NL_CFG_F_NONROOT_SEND)) | 2315 | !netlink_allowed(sock, NL_CFG_F_NONROOT_SEND)) |
2251 | goto out; | 2316 | goto out; |
2252 | } else { | 2317 | } else { |
2253 | dst_portid = nlk->dst_portid; | 2318 | dst_portid = nlk->dst_portid; |
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index b1dcdb932a86..a3ba3ca0ff92 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c | |||
@@ -561,7 +561,7 @@ static int genl_family_rcv_msg(struct genl_family *family, | |||
561 | return -EOPNOTSUPP; | 561 | return -EOPNOTSUPP; |
562 | 562 | ||
563 | if ((ops->flags & GENL_ADMIN_PERM) && | 563 | if ((ops->flags & GENL_ADMIN_PERM) && |
564 | !capable(CAP_NET_ADMIN)) | 564 | !netlink_capable(skb, CAP_NET_ADMIN)) |
565 | return -EPERM; | 565 | return -EPERM; |
566 | 566 | ||
567 | if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) { | 567 | if ((nlh->nlmsg_flags & NLM_F_DUMP) == NLM_F_DUMP) { |
diff --git a/net/packet/diag.c b/net/packet/diag.c index 533ce4ff108a..92f2c7107eec 100644 --- a/net/packet/diag.c +++ b/net/packet/diag.c | |||
@@ -128,6 +128,7 @@ static int pdiag_put_fanout(struct packet_sock *po, struct sk_buff *nlskb) | |||
128 | 128 | ||
129 | static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, | 129 | static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, |
130 | struct packet_diag_req *req, | 130 | struct packet_diag_req *req, |
131 | bool may_report_filterinfo, | ||
131 | struct user_namespace *user_ns, | 132 | struct user_namespace *user_ns, |
132 | u32 portid, u32 seq, u32 flags, int sk_ino) | 133 | u32 portid, u32 seq, u32 flags, int sk_ino) |
133 | { | 134 | { |
@@ -172,7 +173,8 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, | |||
172 | goto out_nlmsg_trim; | 173 | goto out_nlmsg_trim; |
173 | 174 | ||
174 | if ((req->pdiag_show & PACKET_SHOW_FILTER) && | 175 | if ((req->pdiag_show & PACKET_SHOW_FILTER) && |
175 | sock_diag_put_filterinfo(user_ns, sk, skb, PACKET_DIAG_FILTER)) | 176 | sock_diag_put_filterinfo(may_report_filterinfo, sk, skb, |
177 | PACKET_DIAG_FILTER)) | ||
176 | goto out_nlmsg_trim; | 178 | goto out_nlmsg_trim; |
177 | 179 | ||
178 | return nlmsg_end(skb, nlh); | 180 | return nlmsg_end(skb, nlh); |
@@ -188,9 +190,11 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
188 | struct packet_diag_req *req; | 190 | struct packet_diag_req *req; |
189 | struct net *net; | 191 | struct net *net; |
190 | struct sock *sk; | 192 | struct sock *sk; |
193 | bool may_report_filterinfo; | ||
191 | 194 | ||
192 | net = sock_net(skb->sk); | 195 | net = sock_net(skb->sk); |
193 | req = nlmsg_data(cb->nlh); | 196 | req = nlmsg_data(cb->nlh); |
197 | may_report_filterinfo = netlink_net_capable(cb->skb, CAP_NET_ADMIN); | ||
194 | 198 | ||
195 | mutex_lock(&net->packet.sklist_lock); | 199 | mutex_lock(&net->packet.sklist_lock); |
196 | sk_for_each(sk, &net->packet.sklist) { | 200 | sk_for_each(sk, &net->packet.sklist) { |
@@ -200,6 +204,7 @@ static int packet_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) | |||
200 | goto next; | 204 | goto next; |
201 | 205 | ||
202 | if (sk_diag_fill(sk, skb, req, | 206 | if (sk_diag_fill(sk, skb, req, |
207 | may_report_filterinfo, | ||
203 | sk_user_ns(NETLINK_CB(cb->skb).sk), | 208 | sk_user_ns(NETLINK_CB(cb->skb).sk), |
204 | NETLINK_CB(cb->skb).portid, | 209 | NETLINK_CB(cb->skb).portid, |
205 | cb->nlh->nlmsg_seq, NLM_F_MULTI, | 210 | cb->nlh->nlmsg_seq, NLM_F_MULTI, |
diff --git a/net/phonet/pn_netlink.c b/net/phonet/pn_netlink.c index dc15f4300808..b64151ade6b3 100644 --- a/net/phonet/pn_netlink.c +++ b/net/phonet/pn_netlink.c | |||
@@ -70,10 +70,10 @@ static int addr_doit(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
70 | int err; | 70 | int err; |
71 | u8 pnaddr; | 71 | u8 pnaddr; |
72 | 72 | ||
73 | if (!capable(CAP_NET_ADMIN)) | 73 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
74 | return -EPERM; | 74 | return -EPERM; |
75 | 75 | ||
76 | if (!capable(CAP_SYS_ADMIN)) | 76 | if (!netlink_capable(skb, CAP_SYS_ADMIN)) |
77 | return -EPERM; | 77 | return -EPERM; |
78 | 78 | ||
79 | ASSERT_RTNL(); | 79 | ASSERT_RTNL(); |
@@ -233,10 +233,10 @@ static int route_doit(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
233 | int err; | 233 | int err; |
234 | u8 dst; | 234 | u8 dst; |
235 | 235 | ||
236 | if (!capable(CAP_NET_ADMIN)) | 236 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
237 | return -EPERM; | 237 | return -EPERM; |
238 | 238 | ||
239 | if (!capable(CAP_SYS_ADMIN)) | 239 | if (!netlink_capable(skb, CAP_SYS_ADMIN)) |
240 | return -EPERM; | 240 | return -EPERM; |
241 | 241 | ||
242 | ASSERT_RTNL(); | 242 | ASSERT_RTNL(); |
diff --git a/net/sched/act_api.c b/net/sched/act_api.c index 8a5ba5add4bc..648778aef1a2 100644 --- a/net/sched/act_api.c +++ b/net/sched/act_api.c | |||
@@ -948,7 +948,7 @@ static int tc_ctl_action(struct sk_buff *skb, struct nlmsghdr *n) | |||
948 | u32 portid = skb ? NETLINK_CB(skb).portid : 0; | 948 | u32 portid = skb ? NETLINK_CB(skb).portid : 0; |
949 | int ret = 0, ovr = 0; | 949 | int ret = 0, ovr = 0; |
950 | 950 | ||
951 | if ((n->nlmsg_type != RTM_GETACTION) && !capable(CAP_NET_ADMIN)) | 951 | if ((n->nlmsg_type != RTM_GETACTION) && !netlink_capable(skb, CAP_NET_ADMIN)) |
952 | return -EPERM; | 952 | return -EPERM; |
953 | 953 | ||
954 | ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL); | 954 | ret = nlmsg_parse(n, sizeof(struct tcamsg), tca, TCA_ACT_MAX, NULL); |
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 29a30a14c315..bdbdb1a7920a 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -134,7 +134,7 @@ static int tc_ctl_tfilter(struct sk_buff *skb, struct nlmsghdr *n) | |||
134 | int err; | 134 | int err; |
135 | int tp_created = 0; | 135 | int tp_created = 0; |
136 | 136 | ||
137 | if ((n->nlmsg_type != RTM_GETTFILTER) && !capable(CAP_NET_ADMIN)) | 137 | if ((n->nlmsg_type != RTM_GETTFILTER) && !netlink_capable(skb, CAP_NET_ADMIN)) |
138 | return -EPERM; | 138 | return -EPERM; |
139 | 139 | ||
140 | replay: | 140 | replay: |
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index a0b84e0e22de..400769014bbd 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -1084,7 +1084,7 @@ static int tc_get_qdisc(struct sk_buff *skb, struct nlmsghdr *n) | |||
1084 | struct Qdisc *p = NULL; | 1084 | struct Qdisc *p = NULL; |
1085 | int err; | 1085 | int err; |
1086 | 1086 | ||
1087 | if ((n->nlmsg_type != RTM_GETQDISC) && !capable(CAP_NET_ADMIN)) | 1087 | if ((n->nlmsg_type != RTM_GETQDISC) && !netlink_capable(skb, CAP_NET_ADMIN)) |
1088 | return -EPERM; | 1088 | return -EPERM; |
1089 | 1089 | ||
1090 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); | 1090 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); |
@@ -1151,7 +1151,7 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n) | |||
1151 | struct Qdisc *q, *p; | 1151 | struct Qdisc *q, *p; |
1152 | int err; | 1152 | int err; |
1153 | 1153 | ||
1154 | if (!capable(CAP_NET_ADMIN)) | 1154 | if (!netlink_capable(skb, CAP_NET_ADMIN)) |
1155 | return -EPERM; | 1155 | return -EPERM; |
1156 | 1156 | ||
1157 | replay: | 1157 | replay: |
@@ -1490,7 +1490,7 @@ static int tc_ctl_tclass(struct sk_buff *skb, struct nlmsghdr *n) | |||
1490 | u32 qid; | 1490 | u32 qid; |
1491 | int err; | 1491 | int err; |
1492 | 1492 | ||
1493 | if ((n->nlmsg_type != RTM_GETTCLASS) && !capable(CAP_NET_ADMIN)) | 1493 | if ((n->nlmsg_type != RTM_GETTCLASS) && !netlink_capable(skb, CAP_NET_ADMIN)) |
1494 | return -EPERM; | 1494 | return -EPERM; |
1495 | 1495 | ||
1496 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); | 1496 | err = nlmsg_parse(n, sizeof(*tcm), tca, TCA_MAX, NULL); |
diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c index edee03d922e2..6e957c3b9854 100644 --- a/net/sched/sch_hhf.c +++ b/net/sched/sch_hhf.c | |||
@@ -553,11 +553,6 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt) | |||
553 | if (err < 0) | 553 | if (err < 0) |
554 | return err; | 554 | return err; |
555 | 555 | ||
556 | sch_tree_lock(sch); | ||
557 | |||
558 | if (tb[TCA_HHF_BACKLOG_LIMIT]) | ||
559 | sch->limit = nla_get_u32(tb[TCA_HHF_BACKLOG_LIMIT]); | ||
560 | |||
561 | if (tb[TCA_HHF_QUANTUM]) | 556 | if (tb[TCA_HHF_QUANTUM]) |
562 | new_quantum = nla_get_u32(tb[TCA_HHF_QUANTUM]); | 557 | new_quantum = nla_get_u32(tb[TCA_HHF_QUANTUM]); |
563 | 558 | ||
@@ -567,6 +562,12 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt) | |||
567 | non_hh_quantum = (u64)new_quantum * new_hhf_non_hh_weight; | 562 | non_hh_quantum = (u64)new_quantum * new_hhf_non_hh_weight; |
568 | if (non_hh_quantum > INT_MAX) | 563 | if (non_hh_quantum > INT_MAX) |
569 | return -EINVAL; | 564 | return -EINVAL; |
565 | |||
566 | sch_tree_lock(sch); | ||
567 | |||
568 | if (tb[TCA_HHF_BACKLOG_LIMIT]) | ||
569 | sch->limit = nla_get_u32(tb[TCA_HHF_BACKLOG_LIMIT]); | ||
570 | |||
570 | q->quantum = new_quantum; | 571 | q->quantum = new_quantum; |
571 | q->hhf_non_hh_weight = new_hhf_non_hh_weight; | 572 | q->hhf_non_hh_weight = new_hhf_non_hh_weight; |
572 | 573 | ||
diff --git a/net/sctp/protocol.c b/net/sctp/protocol.c index c09757fbf803..44cbb54c8574 100644 --- a/net/sctp/protocol.c +++ b/net/sctp/protocol.c | |||
@@ -491,8 +491,13 @@ static void sctp_v4_get_dst(struct sctp_transport *t, union sctp_addr *saddr, | |||
491 | continue; | 491 | continue; |
492 | if ((laddr->state == SCTP_ADDR_SRC) && | 492 | if ((laddr->state == SCTP_ADDR_SRC) && |
493 | (AF_INET == laddr->a.sa.sa_family)) { | 493 | (AF_INET == laddr->a.sa.sa_family)) { |
494 | fl4->saddr = laddr->a.v4.sin_addr.s_addr; | ||
495 | fl4->fl4_sport = laddr->a.v4.sin_port; | 494 | fl4->fl4_sport = laddr->a.v4.sin_port; |
495 | flowi4_update_output(fl4, | ||
496 | asoc->base.sk->sk_bound_dev_if, | ||
497 | RT_CONN_FLAGS(asoc->base.sk), | ||
498 | daddr->v4.sin_addr.s_addr, | ||
499 | laddr->a.v4.sin_addr.s_addr); | ||
500 | |||
496 | rt = ip_route_output_key(sock_net(sk), fl4); | 501 | rt = ip_route_output_key(sock_net(sk), fl4); |
497 | if (!IS_ERR(rt)) { | 502 | if (!IS_ERR(rt)) { |
498 | dst = &rt->dst; | 503 | dst = &rt->dst; |
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index 5d6883ff00c3..fef2acdf4a2e 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c | |||
@@ -496,11 +496,10 @@ static void sctp_do_8_2_transport_strike(sctp_cmd_seq_t *commands, | |||
496 | 496 | ||
497 | /* If the transport error count is greater than the pf_retrans | 497 | /* If the transport error count is greater than the pf_retrans |
498 | * threshold, and less than pathmaxrtx, and if the current state | 498 | * threshold, and less than pathmaxrtx, and if the current state |
499 | * is not SCTP_UNCONFIRMED, then mark this transport as Partially | 499 | * is SCTP_ACTIVE, then mark this transport as Partially Failed, |
500 | * Failed, see SCTP Quick Failover Draft, section 5.1 | 500 | * see SCTP Quick Failover Draft, section 5.1 |
501 | */ | 501 | */ |
502 | if ((transport->state != SCTP_PF) && | 502 | if ((transport->state == SCTP_ACTIVE) && |
503 | (transport->state != SCTP_UNCONFIRMED) && | ||
504 | (asoc->pf_retrans < transport->pathmaxrxt) && | 503 | (asoc->pf_retrans < transport->pathmaxrxt) && |
505 | (transport->error_count > asoc->pf_retrans)) { | 504 | (transport->error_count > asoc->pf_retrans)) { |
506 | 505 | ||
diff --git a/net/tipc/netlink.c b/net/tipc/netlink.c index 3aaf73de9e2d..ad844d365340 100644 --- a/net/tipc/netlink.c +++ b/net/tipc/netlink.c | |||
@@ -47,7 +47,7 @@ static int handle_cmd(struct sk_buff *skb, struct genl_info *info) | |||
47 | int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); | 47 | int hdr_space = nlmsg_total_size(GENL_HDRLEN + TIPC_GENL_HDRLEN); |
48 | u16 cmd; | 48 | u16 cmd; |
49 | 49 | ||
50 | if ((req_userhdr->cmd & 0xC000) && (!capable(CAP_NET_ADMIN))) | 50 | if ((req_userhdr->cmd & 0xC000) && (!netlink_capable(skb, CAP_NET_ADMIN))) |
51 | cmd = TIPC_CMD_NOT_NET_ADMIN; | 51 | cmd = TIPC_CMD_NOT_NET_ADMIN; |
52 | else | 52 | else |
53 | cmd = req_userhdr->cmd; | 53 | cmd = req_userhdr->cmd; |
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 5adfd94c5b85..85d232bed87d 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c | |||
@@ -1925,9 +1925,23 @@ static struct miscdevice vsock_device = { | |||
1925 | .fops = &vsock_device_ops, | 1925 | .fops = &vsock_device_ops, |
1926 | }; | 1926 | }; |
1927 | 1927 | ||
1928 | static int __vsock_core_init(void) | 1928 | int __vsock_core_init(const struct vsock_transport *t, struct module *owner) |
1929 | { | 1929 | { |
1930 | int err; | 1930 | int err = mutex_lock_interruptible(&vsock_register_mutex); |
1931 | |||
1932 | if (err) | ||
1933 | return err; | ||
1934 | |||
1935 | if (transport) { | ||
1936 | err = -EBUSY; | ||
1937 | goto err_busy; | ||
1938 | } | ||
1939 | |||
1940 | /* Transport must be the owner of the protocol so that it can't | ||
1941 | * unload while there are open sockets. | ||
1942 | */ | ||
1943 | vsock_proto.owner = owner; | ||
1944 | transport = t; | ||
1931 | 1945 | ||
1932 | vsock_init_tables(); | 1946 | vsock_init_tables(); |
1933 | 1947 | ||
@@ -1951,36 +1965,19 @@ static int __vsock_core_init(void) | |||
1951 | goto err_unregister_proto; | 1965 | goto err_unregister_proto; |
1952 | } | 1966 | } |
1953 | 1967 | ||
1968 | mutex_unlock(&vsock_register_mutex); | ||
1954 | return 0; | 1969 | return 0; |
1955 | 1970 | ||
1956 | err_unregister_proto: | 1971 | err_unregister_proto: |
1957 | proto_unregister(&vsock_proto); | 1972 | proto_unregister(&vsock_proto); |
1958 | err_misc_deregister: | 1973 | err_misc_deregister: |
1959 | misc_deregister(&vsock_device); | 1974 | misc_deregister(&vsock_device); |
1960 | return err; | 1975 | transport = NULL; |
1961 | } | 1976 | err_busy: |
1962 | |||
1963 | int vsock_core_init(const struct vsock_transport *t) | ||
1964 | { | ||
1965 | int retval = mutex_lock_interruptible(&vsock_register_mutex); | ||
1966 | if (retval) | ||
1967 | return retval; | ||
1968 | |||
1969 | if (transport) { | ||
1970 | retval = -EBUSY; | ||
1971 | goto out; | ||
1972 | } | ||
1973 | |||
1974 | transport = t; | ||
1975 | retval = __vsock_core_init(); | ||
1976 | if (retval) | ||
1977 | transport = NULL; | ||
1978 | |||
1979 | out: | ||
1980 | mutex_unlock(&vsock_register_mutex); | 1977 | mutex_unlock(&vsock_register_mutex); |
1981 | return retval; | 1978 | return err; |
1982 | } | 1979 | } |
1983 | EXPORT_SYMBOL_GPL(vsock_core_init); | 1980 | EXPORT_SYMBOL_GPL(__vsock_core_init); |
1984 | 1981 | ||
1985 | void vsock_core_exit(void) | 1982 | void vsock_core_exit(void) |
1986 | { | 1983 | { |
@@ -2000,5 +1997,5 @@ EXPORT_SYMBOL_GPL(vsock_core_exit); | |||
2000 | 1997 | ||
2001 | MODULE_AUTHOR("VMware, Inc."); | 1998 | MODULE_AUTHOR("VMware, Inc."); |
2002 | MODULE_DESCRIPTION("VMware Virtual Socket Family"); | 1999 | MODULE_DESCRIPTION("VMware Virtual Socket Family"); |
2003 | MODULE_VERSION("1.0.0.0-k"); | 2000 | MODULE_VERSION("1.0.1.0-k"); |
2004 | MODULE_LICENSE("GPL v2"); | 2001 | MODULE_LICENSE("GPL v2"); |
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 8f131c10a6f3..51398ae6cda8 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c | |||
@@ -2377,7 +2377,7 @@ static int xfrm_user_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) | |||
2377 | link = &xfrm_dispatch[type]; | 2377 | link = &xfrm_dispatch[type]; |
2378 | 2378 | ||
2379 | /* All operations require privileges, even GET */ | 2379 | /* All operations require privileges, even GET */ |
2380 | if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) | 2380 | if (!netlink_net_capable(skb, CAP_NET_ADMIN)) |
2381 | return -EPERM; | 2381 | return -EPERM; |
2382 | 2382 | ||
2383 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || | 2383 | if ((type == (XFRM_MSG_GETSA - XFRM_MSG_BASE) || |
diff --git a/scripts/sortextable.c b/scripts/sortextable.c index cc49062acdee..1052d4834a44 100644 --- a/scripts/sortextable.c +++ b/scripts/sortextable.c | |||
@@ -35,6 +35,10 @@ | |||
35 | #define EM_ARCOMPACT 93 | 35 | #define EM_ARCOMPACT 93 |
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | #ifndef EM_XTENSA | ||
39 | #define EM_XTENSA 94 | ||
40 | #endif | ||
41 | |||
38 | #ifndef EM_AARCH64 | 42 | #ifndef EM_AARCH64 |
39 | #define EM_AARCH64 183 | 43 | #define EM_AARCH64 183 |
40 | #endif | 44 | #endif |
@@ -281,6 +285,7 @@ do_file(char const *const fname) | |||
281 | case EM_AARCH64: | 285 | case EM_AARCH64: |
282 | case EM_MICROBLAZE: | 286 | case EM_MICROBLAZE: |
283 | case EM_MIPS: | 287 | case EM_MIPS: |
288 | case EM_XTENSA: | ||
284 | break; | 289 | break; |
285 | } /* end switch */ | 290 | } /* end switch */ |
286 | 291 | ||
diff --git a/security/apparmor/include/apparmor.h b/security/apparmor/include/apparmor.h index 8fb1488a3cd4..97130f88838b 100644 --- a/security/apparmor/include/apparmor.h +++ b/security/apparmor/include/apparmor.h | |||
@@ -66,7 +66,6 @@ extern int apparmor_initialized __initdata; | |||
66 | char *aa_split_fqname(char *args, char **ns_name); | 66 | char *aa_split_fqname(char *args, char **ns_name); |
67 | void aa_info_message(const char *str); | 67 | void aa_info_message(const char *str); |
68 | void *__aa_kvmalloc(size_t size, gfp_t flags); | 68 | void *__aa_kvmalloc(size_t size, gfp_t flags); |
69 | void kvfree(void *buffer); | ||
70 | 69 | ||
71 | static inline void *kvmalloc(size_t size) | 70 | static inline void *kvmalloc(size_t size) |
72 | { | 71 | { |
diff --git a/security/apparmor/lib.c b/security/apparmor/lib.c index 69689922c491..c1827e068454 100644 --- a/security/apparmor/lib.c +++ b/security/apparmor/lib.c | |||
@@ -104,17 +104,3 @@ void *__aa_kvmalloc(size_t size, gfp_t flags) | |||
104 | } | 104 | } |
105 | return buffer; | 105 | return buffer; |
106 | } | 106 | } |
107 | |||
108 | /** | ||
109 | * kvfree - free an allocation do by kvmalloc | ||
110 | * @buffer: buffer to free (MAYBE_NULL) | ||
111 | * | ||
112 | * Free a buffer allocated by kvmalloc | ||
113 | */ | ||
114 | void kvfree(void *buffer) | ||
115 | { | ||
116 | if (is_vmalloc_addr(buffer)) | ||
117 | vfree(buffer); | ||
118 | else | ||
119 | kfree(buffer); | ||
120 | } | ||
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 0cb5b89cd0c8..1edbb9c47c2d 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -1127,8 +1127,10 @@ static void hdmi_setup_audio_infoframe(struct hda_codec *codec, | |||
1127 | AMP_OUT_UNMUTE); | 1127 | AMP_OUT_UNMUTE); |
1128 | 1128 | ||
1129 | eld = &per_pin->sink_eld; | 1129 | eld = &per_pin->sink_eld; |
1130 | if (!eld->monitor_present) | 1130 | if (!eld->monitor_present) { |
1131 | hdmi_set_channel_count(codec, per_pin->cvt_nid, channels); | ||
1131 | return; | 1132 | return; |
1133 | } | ||
1132 | 1134 | ||
1133 | if (!non_pcm && per_pin->chmap_set) | 1135 | if (!non_pcm && per_pin->chmap_set) |
1134 | ca = hdmi_manual_channel_allocation(channels, per_pin->chmap); | 1136 | ca = hdmi_manual_channel_allocation(channels, per_pin->chmap); |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c1952c910339..5f7c765391f1 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -4622,6 +4622,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = { | |||
4622 | SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), | 4622 | SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), |
4623 | SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), | 4623 | SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE), |
4624 | SND_PCI_QUIRK(0x1028, 0x0674, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4624 | SND_PCI_QUIRK(0x1028, 0x0674, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4625 | SND_PCI_QUIRK(0x1028, 0x067e, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | ||
4625 | SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), | 4626 | SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE), |
4626 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4627 | SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
4627 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), | 4628 | SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), |
diff --git a/sound/usb/card.c b/sound/usb/card.c index 893d5a1afc3c..c3b5b7dca1c3 100644 --- a/sound/usb/card.c +++ b/sound/usb/card.c | |||
@@ -651,7 +651,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip) | |||
651 | int err = -ENODEV; | 651 | int err = -ENODEV; |
652 | 652 | ||
653 | down_read(&chip->shutdown_rwsem); | 653 | down_read(&chip->shutdown_rwsem); |
654 | if (chip->probing) | 654 | if (chip->probing && chip->in_pm) |
655 | err = 0; | 655 | err = 0; |
656 | else if (!chip->shutdown) | 656 | else if (!chip->shutdown) |
657 | err = usb_autopm_get_interface(chip->pm_intf); | 657 | err = usb_autopm_get_interface(chip->pm_intf); |
@@ -663,7 +663,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip) | |||
663 | void snd_usb_autosuspend(struct snd_usb_audio *chip) | 663 | void snd_usb_autosuspend(struct snd_usb_audio *chip) |
664 | { | 664 | { |
665 | down_read(&chip->shutdown_rwsem); | 665 | down_read(&chip->shutdown_rwsem); |
666 | if (!chip->shutdown && !chip->probing) | 666 | if (!chip->shutdown && !chip->probing && !chip->in_pm) |
667 | usb_autopm_put_interface(chip->pm_intf); | 667 | usb_autopm_put_interface(chip->pm_intf); |
668 | up_read(&chip->shutdown_rwsem); | 668 | up_read(&chip->shutdown_rwsem); |
669 | } | 669 | } |
@@ -695,8 +695,9 @@ static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message) | |||
695 | chip->autosuspended = 1; | 695 | chip->autosuspended = 1; |
696 | } | 696 | } |
697 | 697 | ||
698 | list_for_each_entry(mixer, &chip->mixer_list, list) | 698 | if (chip->num_suspended_intf == 1) |
699 | snd_usb_mixer_suspend(mixer); | 699 | list_for_each_entry(mixer, &chip->mixer_list, list) |
700 | snd_usb_mixer_suspend(mixer); | ||
700 | 701 | ||
701 | return 0; | 702 | return 0; |
702 | } | 703 | } |
@@ -711,6 +712,8 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume) | |||
711 | return 0; | 712 | return 0; |
712 | if (--chip->num_suspended_intf) | 713 | if (--chip->num_suspended_intf) |
713 | return 0; | 714 | return 0; |
715 | |||
716 | chip->in_pm = 1; | ||
714 | /* | 717 | /* |
715 | * ALSA leaves material resumption to user space | 718 | * ALSA leaves material resumption to user space |
716 | * we just notify and restart the mixers | 719 | * we just notify and restart the mixers |
@@ -726,6 +729,7 @@ static int __usb_audio_resume(struct usb_interface *intf, bool reset_resume) | |||
726 | chip->autosuspended = 0; | 729 | chip->autosuspended = 0; |
727 | 730 | ||
728 | err_out: | 731 | err_out: |
732 | chip->in_pm = 0; | ||
729 | return err; | 733 | return err; |
730 | } | 734 | } |
731 | 735 | ||
diff --git a/sound/usb/card.h b/sound/usb/card.h index 9867ab866857..97acb906acc2 100644 --- a/sound/usb/card.h +++ b/sound/usb/card.h | |||
@@ -92,6 +92,7 @@ struct snd_usb_endpoint { | |||
92 | unsigned int curframesize; /* current packet size in frames (for capture) */ | 92 | unsigned int curframesize; /* current packet size in frames (for capture) */ |
93 | unsigned int syncmaxsize; /* sync endpoint packet size */ | 93 | unsigned int syncmaxsize; /* sync endpoint packet size */ |
94 | unsigned int fill_max:1; /* fill max packet size always */ | 94 | unsigned int fill_max:1; /* fill max packet size always */ |
95 | unsigned int udh01_fb_quirk:1; /* corrupted feedback data */ | ||
95 | unsigned int datainterval; /* log_2 of data packet interval */ | 96 | unsigned int datainterval; /* log_2 of data packet interval */ |
96 | unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ | 97 | unsigned int syncinterval; /* P for adaptive mode, 0 otherwise */ |
97 | unsigned char silence_value; | 98 | unsigned char silence_value; |
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c index e70a87e0d9fe..289f582c9130 100644 --- a/sound/usb/endpoint.c +++ b/sound/usb/endpoint.c | |||
@@ -471,6 +471,10 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip, | |||
471 | ep->syncinterval = 3; | 471 | ep->syncinterval = 3; |
472 | 472 | ||
473 | ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize); | 473 | ep->syncmaxsize = le16_to_cpu(get_endpoint(alts, 1)->wMaxPacketSize); |
474 | |||
475 | if (chip->usb_id == USB_ID(0x0644, 0x8038) /* TEAC UD-H01 */ && | ||
476 | ep->syncmaxsize == 4) | ||
477 | ep->udh01_fb_quirk = 1; | ||
474 | } | 478 | } |
475 | 479 | ||
476 | list_add_tail(&ep->list, &chip->ep_list); | 480 | list_add_tail(&ep->list, &chip->ep_list); |
@@ -1105,7 +1109,16 @@ void snd_usb_handle_sync_urb(struct snd_usb_endpoint *ep, | |||
1105 | if (f == 0) | 1109 | if (f == 0) |
1106 | return; | 1110 | return; |
1107 | 1111 | ||
1108 | if (unlikely(ep->freqshift == INT_MIN)) { | 1112 | if (unlikely(sender->udh01_fb_quirk)) { |
1113 | /* | ||
1114 | * The TEAC UD-H01 firmware sometimes changes the feedback value | ||
1115 | * by +/- 0x1.0000. | ||
1116 | */ | ||
1117 | if (f < ep->freqn - 0x8000) | ||
1118 | f += 0x10000; | ||
1119 | else if (f > ep->freqn + 0x8000) | ||
1120 | f -= 0x10000; | ||
1121 | } else if (unlikely(ep->freqshift == INT_MIN)) { | ||
1109 | /* | 1122 | /* |
1110 | * The first time we see a feedback value, determine its format | 1123 | * The first time we see a feedback value, determine its format |
1111 | * by shifting it left or right until it matches the nominal | 1124 | * by shifting it left or right until it matches the nominal |
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c index 131336d40492..c62a1659106d 100644 --- a/sound/usb/pcm.c +++ b/sound/usb/pcm.c | |||
@@ -1501,9 +1501,8 @@ static void retire_playback_urb(struct snd_usb_substream *subs, | |||
1501 | * The error should be lower than 2ms since the estimate relies | 1501 | * The error should be lower than 2ms since the estimate relies |
1502 | * on two reads of a counter updated every ms. | 1502 | * on two reads of a counter updated every ms. |
1503 | */ | 1503 | */ |
1504 | if (printk_ratelimit() && | 1504 | if (abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2) |
1505 | abs(est_delay - subs->last_delay) * 1000 > runtime->rate * 2) | 1505 | dev_dbg_ratelimited(&subs->dev->dev, |
1506 | dev_dbg(&subs->dev->dev, | ||
1507 | "delay: estimated %d, actual %d\n", | 1506 | "delay: estimated %d, actual %d\n", |
1508 | est_delay, subs->last_delay); | 1507 | est_delay, subs->last_delay); |
1509 | 1508 | ||
diff --git a/sound/usb/usbaudio.h b/sound/usb/usbaudio.h index 25c4c7e217de..91d0380431b4 100644 --- a/sound/usb/usbaudio.h +++ b/sound/usb/usbaudio.h | |||
@@ -40,6 +40,7 @@ struct snd_usb_audio { | |||
40 | struct rw_semaphore shutdown_rwsem; | 40 | struct rw_semaphore shutdown_rwsem; |
41 | unsigned int shutdown:1; | 41 | unsigned int shutdown:1; |
42 | unsigned int probing:1; | 42 | unsigned int probing:1; |
43 | unsigned int in_pm:1; | ||
43 | unsigned int autosuspended:1; | 44 | unsigned int autosuspended:1; |
44 | unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */ | 45 | unsigned int txfr_quirk:1; /* Subframe boundaries on transfers */ |
45 | 46 | ||
diff --git a/tools/net/bpf_dbg.c b/tools/net/bpf_dbg.c index bb31813e43dd..9a287bec695a 100644 --- a/tools/net/bpf_dbg.c +++ b/tools/net/bpf_dbg.c | |||
@@ -820,7 +820,7 @@ do_div: | |||
820 | r->A &= r->X; | 820 | r->A &= r->X; |
821 | break; | 821 | break; |
822 | case BPF_ALU_AND | BPF_K: | 822 | case BPF_ALU_AND | BPF_K: |
823 | r->A &= r->X; | 823 | r->A &= K; |
824 | break; | 824 | break; |
825 | case BPF_ALU_OR | BPF_X: | 825 | case BPF_ALU_OR | BPF_X: |
826 | r->A |= r->X; | 826 | r->A |= r->X; |