1 |
commit: 23b5b031e20c79ab7455e7e41e9eaf0641343aef |
2 |
Author: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
3 |
AuthorDate: Thu Jan 27 11:36:55 2022 +0000 |
4 |
Commit: Mike Pagano <mpagano <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu Jan 27 11:36:55 2022 +0000 |
6 |
URL: https://gitweb.gentoo.org/proj/linux-patches.git/commit/?id=23b5b031 |
7 |
|
8 |
Linux patch 5.15.17 |
9 |
|
10 |
Signed-off-by: Mike Pagano <mpagano <AT> gentoo.org> |
11 |
|
12 |
0000_README | 4 + |
13 |
1016_linux-5.15.17.patch | 34359 +++++++++++++++++++++++++++++++++++++++++++++ |
14 |
2 files changed, 34363 insertions(+) |
15 |
|
16 |
diff --git a/0000_README b/0000_README |
17 |
index 7901341f..c0a48663 100644 |
18 |
--- a/0000_README |
19 |
+++ b/0000_README |
20 |
@@ -107,6 +107,10 @@ Patch: 1015_linux-5.15.16.patch |
21 |
From: http://www.kernel.org |
22 |
Desc: Linux 5.15.16 |
23 |
|
24 |
+Patch: 1016_linux-5.15.17.patch |
25 |
+From: http://www.kernel.org |
26 |
+Desc: Linux 5.15.17 |
27 |
+ |
28 |
Patch: 1500_XATTR_USER_PREFIX.patch |
29 |
From: https://bugs.gentoo.org/show_bug.cgi?id=470644 |
30 |
Desc: Support for namespace user.pax.* on tmpfs. |
31 |
|
32 |
diff --git a/1016_linux-5.15.17.patch b/1016_linux-5.15.17.patch |
33 |
new file mode 100644 |
34 |
index 00000000..43b919c4 |
35 |
--- /dev/null |
36 |
+++ b/1016_linux-5.15.17.patch |
37 |
@@ -0,0 +1,34359 @@ |
38 |
+diff --git a/Documentation/admin-guide/cifs/usage.rst b/Documentation/admin-guide/cifs/usage.rst |
39 |
+index f170d88202588..3766bf8a1c20e 100644 |
40 |
+--- a/Documentation/admin-guide/cifs/usage.rst |
41 |
++++ b/Documentation/admin-guide/cifs/usage.rst |
42 |
+@@ -734,10 +734,9 @@ SecurityFlags Flags which control security negotiation and |
43 |
+ using weaker password hashes is 0x37037 (lanman, |
44 |
+ plaintext, ntlm, ntlmv2, signing allowed). Some |
45 |
+ SecurityFlags require the corresponding menuconfig |
46 |
+- options to be enabled (lanman and plaintext require |
47 |
+- CONFIG_CIFS_WEAK_PW_HASH for example). Enabling |
48 |
+- plaintext authentication currently requires also |
49 |
+- enabling lanman authentication in the security flags |
50 |
++ options to be enabled. Enabling plaintext |
51 |
++ authentication currently requires also enabling |
52 |
++ lanman authentication in the security flags |
53 |
+ because the cifs module only supports sending |
54 |
+ laintext passwords using the older lanman dialect |
55 |
+ form of the session setup SMB. (e.g. for authentication |
56 |
+diff --git a/Documentation/admin-guide/devices.txt b/Documentation/admin-guide/devices.txt |
57 |
+index 922c23bb4372a..c07dc0ee860e7 100644 |
58 |
+--- a/Documentation/admin-guide/devices.txt |
59 |
++++ b/Documentation/admin-guide/devices.txt |
60 |
+@@ -2339,13 +2339,7 @@ |
61 |
+ disks (see major number 3) except that the limit on |
62 |
+ partitions is 31. |
63 |
+ |
64 |
+- 162 char Raw block device interface |
65 |
+- 0 = /dev/rawctl Raw I/O control device |
66 |
+- 1 = /dev/raw/raw1 First raw I/O device |
67 |
+- 2 = /dev/raw/raw2 Second raw I/O device |
68 |
+- ... |
69 |
+- max minor number of raw device is set by kernel config |
70 |
+- MAX_RAW_DEVS or raw module parameter 'max_raw_devs' |
71 |
++ 162 char Used for (now removed) raw block device interface |
72 |
+ |
73 |
+ 163 char |
74 |
+ |
75 |
+diff --git a/Documentation/admin-guide/hw-vuln/spectre.rst b/Documentation/admin-guide/hw-vuln/spectre.rst |
76 |
+index e05e581af5cfe..985181dba0bac 100644 |
77 |
+--- a/Documentation/admin-guide/hw-vuln/spectre.rst |
78 |
++++ b/Documentation/admin-guide/hw-vuln/spectre.rst |
79 |
+@@ -468,7 +468,7 @@ Spectre variant 2 |
80 |
+ before invoking any firmware code to prevent Spectre variant 2 exploits |
81 |
+ using the firmware. |
82 |
+ |
83 |
+- Using kernel address space randomization (CONFIG_RANDOMIZE_SLAB=y |
84 |
++ Using kernel address space randomization (CONFIG_RANDOMIZE_BASE=y |
85 |
+ and CONFIG_SLAB_FREELIST_RANDOM=y in the kernel configuration) makes |
86 |
+ attacks on the kernel generally more difficult. |
87 |
+ |
88 |
+diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml |
89 |
+index cf5a208f2f105..343598c9f473b 100644 |
90 |
+--- a/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml |
91 |
++++ b/Documentation/devicetree/bindings/display/amlogic,meson-dw-hdmi.yaml |
92 |
+@@ -10,6 +10,9 @@ title: Amlogic specific extensions to the Synopsys Designware HDMI Controller |
93 |
+ maintainers: |
94 |
+ - Neil Armstrong <narmstrong@××××××××.com> |
95 |
+ |
96 |
++allOf: |
97 |
++ - $ref: /schemas/sound/name-prefix.yaml# |
98 |
++ |
99 |
+ description: | |
100 |
+ The Amlogic Meson Synopsys Designware Integration is composed of |
101 |
+ - A Synopsys DesignWare HDMI Controller IP |
102 |
+@@ -99,6 +102,8 @@ properties: |
103 |
+ "#sound-dai-cells": |
104 |
+ const: 0 |
105 |
+ |
106 |
++ sound-name-prefix: true |
107 |
++ |
108 |
+ required: |
109 |
+ - compatible |
110 |
+ - reg |
111 |
+diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml |
112 |
+index 851cb07812173..047fd69e03770 100644 |
113 |
+--- a/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml |
114 |
++++ b/Documentation/devicetree/bindings/display/amlogic,meson-vpu.yaml |
115 |
+@@ -78,6 +78,10 @@ properties: |
116 |
+ interrupts: |
117 |
+ maxItems: 1 |
118 |
+ |
119 |
++ amlogic,canvas: |
120 |
++ description: should point to a canvas provider node |
121 |
++ $ref: /schemas/types.yaml#/definitions/phandle |
122 |
++ |
123 |
+ power-domains: |
124 |
+ maxItems: 1 |
125 |
+ description: phandle to the associated power domain |
126 |
+@@ -106,6 +110,7 @@ required: |
127 |
+ - port@1 |
128 |
+ - "#address-cells" |
129 |
+ - "#size-cells" |
130 |
++ - amlogic,canvas |
131 |
+ |
132 |
+ additionalProperties: false |
133 |
+ |
134 |
+@@ -118,6 +123,7 @@ examples: |
135 |
+ interrupts = <3>; |
136 |
+ #address-cells = <1>; |
137 |
+ #size-cells = <0>; |
138 |
++ amlogic,canvas = <&canvas>; |
139 |
+ |
140 |
+ /* CVBS VDAC output port */ |
141 |
+ port@0 { |
142 |
+diff --git a/Documentation/devicetree/bindings/input/hid-over-i2c.txt b/Documentation/devicetree/bindings/input/hid-over-i2c.txt |
143 |
+index c76bafaf98d2f..34c43d3bddfd1 100644 |
144 |
+--- a/Documentation/devicetree/bindings/input/hid-over-i2c.txt |
145 |
++++ b/Documentation/devicetree/bindings/input/hid-over-i2c.txt |
146 |
+@@ -32,6 +32,8 @@ device-specific compatible properties, which should be used in addition to the |
147 |
+ - vdd-supply: phandle of the regulator that provides the supply voltage. |
148 |
+ - post-power-on-delay-ms: time required by the device after enabling its regulators |
149 |
+ or powering it on, before it is ready for communication. |
150 |
++- touchscreen-inverted-x: See touchscreen.txt |
151 |
++- touchscreen-inverted-y: See touchscreen.txt |
152 |
+ |
153 |
+ Example: |
154 |
+ |
155 |
+diff --git a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml |
156 |
+index a07de5ed0ca6a..2d34f3ccb2572 100644 |
157 |
+--- a/Documentation/devicetree/bindings/thermal/thermal-zones.yaml |
158 |
++++ b/Documentation/devicetree/bindings/thermal/thermal-zones.yaml |
159 |
+@@ -199,12 +199,11 @@ patternProperties: |
160 |
+ |
161 |
+ contribution: |
162 |
+ $ref: /schemas/types.yaml#/definitions/uint32 |
163 |
+- minimum: 0 |
164 |
+- maximum: 100 |
165 |
+ description: |
166 |
+- The percentage contribution of the cooling devices at the |
167 |
+- specific trip temperature referenced in this map |
168 |
+- to this thermal zone |
169 |
++ The cooling contribution to the thermal zone of the referred |
170 |
++ cooling device at the referred trip point. The contribution is |
171 |
++ a ratio of the sum of all cooling contributions within a |
172 |
++ thermal zone. |
173 |
+ |
174 |
+ required: |
175 |
+ - trip |
176 |
+diff --git a/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml b/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml |
177 |
+index 76cb9586ee00c..93cd77a6e92c0 100644 |
178 |
+--- a/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml |
179 |
++++ b/Documentation/devicetree/bindings/watchdog/samsung-wdt.yaml |
180 |
+@@ -39,8 +39,8 @@ properties: |
181 |
+ samsung,syscon-phandle: |
182 |
+ $ref: /schemas/types.yaml#/definitions/phandle |
183 |
+ description: |
184 |
+- Phandle to the PMU system controller node (in case of Exynos5250 |
185 |
+- and Exynos5420). |
186 |
++ Phandle to the PMU system controller node (in case of Exynos5250, |
187 |
++ Exynos5420 and Exynos7). |
188 |
+ |
189 |
+ required: |
190 |
+ - compatible |
191 |
+@@ -58,6 +58,7 @@ allOf: |
192 |
+ enum: |
193 |
+ - samsung,exynos5250-wdt |
194 |
+ - samsung,exynos5420-wdt |
195 |
++ - samsung,exynos7-wdt |
196 |
+ then: |
197 |
+ required: |
198 |
+ - samsung,syscon-phandle |
199 |
+diff --git a/Documentation/driver-api/dmaengine/dmatest.rst b/Documentation/driver-api/dmaengine/dmatest.rst |
200 |
+index ee268d445d38b..d2e1d8b58e7dc 100644 |
201 |
+--- a/Documentation/driver-api/dmaengine/dmatest.rst |
202 |
++++ b/Documentation/driver-api/dmaengine/dmatest.rst |
203 |
+@@ -143,13 +143,14 @@ Part 5 - Handling channel allocation |
204 |
+ Allocating Channels |
205 |
+ ------------------- |
206 |
+ |
207 |
+-Channels are required to be configured prior to starting the test run. |
208 |
+-Attempting to run the test without configuring the channels will fail. |
209 |
++Channels do not need to be configured prior to starting a test run. Attempting |
210 |
++to run the test without configuring the channels will result in testing any |
211 |
++channels that are available. |
212 |
+ |
213 |
+ Example:: |
214 |
+ |
215 |
+ % echo 1 > /sys/module/dmatest/parameters/run |
216 |
+- dmatest: Could not start test, no channels configured |
217 |
++ dmatest: No channels configured, continue with any |
218 |
+ |
219 |
+ Channels are registered using the "channel" parameter. Channels can be requested by their |
220 |
+ name, once requested, the channel is registered and a pending thread is added to the test list. |
221 |
+diff --git a/Documentation/driver-api/firewire.rst b/Documentation/driver-api/firewire.rst |
222 |
+index 94a2d7f01d999..d3cfa73cbb2b4 100644 |
223 |
+--- a/Documentation/driver-api/firewire.rst |
224 |
++++ b/Documentation/driver-api/firewire.rst |
225 |
+@@ -19,7 +19,7 @@ of kernel interfaces is available via exported symbols in `firewire-core` module |
226 |
+ Firewire char device data structures |
227 |
+ ==================================== |
228 |
+ |
229 |
+-.. include:: /ABI/stable/firewire-cdev |
230 |
++.. include:: ../ABI/stable/firewire-cdev |
231 |
+ :literal: |
232 |
+ |
233 |
+ .. kernel-doc:: include/uapi/linux/firewire-cdev.h |
234 |
+@@ -28,7 +28,7 @@ Firewire char device data structures |
235 |
+ Firewire device probing and sysfs interfaces |
236 |
+ ============================================ |
237 |
+ |
238 |
+-.. include:: /ABI/stable/sysfs-bus-firewire |
239 |
++.. include:: ../ABI/stable/sysfs-bus-firewire |
240 |
+ :literal: |
241 |
+ |
242 |
+ .. kernel-doc:: drivers/firewire/core-device.c |
243 |
+diff --git a/Documentation/firmware-guide/acpi/dsd/data-node-references.rst b/Documentation/firmware-guide/acpi/dsd/data-node-references.rst |
244 |
+index b7ad47df49de0..8b65b32e6e40e 100644 |
245 |
+--- a/Documentation/firmware-guide/acpi/dsd/data-node-references.rst |
246 |
++++ b/Documentation/firmware-guide/acpi/dsd/data-node-references.rst |
247 |
+@@ -5,7 +5,7 @@ |
248 |
+ Referencing hierarchical data nodes |
249 |
+ =================================== |
250 |
+ |
251 |
+-:Copyright: |copy| 2018 Intel Corporation |
252 |
++:Copyright: |copy| 2018, 2021 Intel Corporation |
253 |
+ :Author: Sakari Ailus <sakari.ailus@×××××××××××.com> |
254 |
+ |
255 |
+ ACPI in general allows referring to device objects in the tree only. |
256 |
+@@ -52,12 +52,14 @@ the ANOD object which is also the final target node of the reference. |
257 |
+ Name (NOD0, Package() { |
258 |
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), |
259 |
+ Package () { |
260 |
++ Package () { "reg", 0 }, |
261 |
+ Package () { "random-property", 3 }, |
262 |
+ } |
263 |
+ }) |
264 |
+ Name (NOD1, Package() { |
265 |
+ ToUUID("dbb8e3e6-5886-4ba6-8795-1319f52a966b"), |
266 |
+ Package () { |
267 |
++ Package () { "reg", 1 }, |
268 |
+ Package () { "anothernode", "ANOD" }, |
269 |
+ } |
270 |
+ }) |
271 |
+@@ -74,7 +76,11 @@ the ANOD object which is also the final target node of the reference. |
272 |
+ Name (_DSD, Package () { |
273 |
+ ToUUID("daffd814-6eba-4d8c-8a91-bc9bbf4aa301"), |
274 |
+ Package () { |
275 |
+- Package () { "reference", ^DEV0, "node@1", "anothernode" }, |
276 |
++ Package () { |
277 |
++ "reference", Package () { |
278 |
++ ^DEV0, "node@1", "anothernode" |
279 |
++ } |
280 |
++ }, |
281 |
+ } |
282 |
+ }) |
283 |
+ } |
284 |
+diff --git a/Documentation/trace/coresight/coresight-config.rst b/Documentation/trace/coresight/coresight-config.rst |
285 |
+index a4e3ef2952401..6ed13398ca2ce 100644 |
286 |
+--- a/Documentation/trace/coresight/coresight-config.rst |
287 |
++++ b/Documentation/trace/coresight/coresight-config.rst |
288 |
+@@ -211,19 +211,13 @@ also declared in the perf 'cs_etm' event infrastructure so that they can |
289 |
+ be selected when running trace under perf:: |
290 |
+ |
291 |
+ $ ls /sys/devices/cs_etm |
292 |
+- configurations format perf_event_mux_interval_ms sinks type |
293 |
+- events nr_addr_filters power |
294 |
++ cpu0 cpu2 events nr_addr_filters power subsystem uevent |
295 |
++ cpu1 cpu3 format perf_event_mux_interval_ms sinks type |
296 |
+ |
297 |
+-Key directories here are 'configurations' - which lists the loaded |
298 |
+-configurations, and 'events' - a generic perf directory which allows |
299 |
+-selection on the perf command line.:: |
300 |
++The key directory here is 'events' - a generic perf directory which allows |
301 |
++selection on the perf command line. As with the sinks entries, this provides |
302 |
++a hash of the configuration name. |
303 |
+ |
304 |
+- $ ls configurations/ |
305 |
+- autofdo |
306 |
+- $ cat configurations/autofdo |
307 |
+- 0xa7c3dddd |
308 |
+- |
309 |
+-As with the sinks entries, this provides a hash of the configuration name. |
310 |
+ The entry in the 'events' directory uses perfs built in syntax generator |
311 |
+ to substitute the syntax for the name when evaluating the command:: |
312 |
+ |
313 |
+diff --git a/Makefile b/Makefile |
314 |
+index af173c9df9422..088197ed3f66c 100644 |
315 |
+--- a/Makefile |
316 |
++++ b/Makefile |
317 |
+@@ -1,7 +1,7 @@ |
318 |
+ # SPDX-License-Identifier: GPL-2.0 |
319 |
+ VERSION = 5 |
320 |
+ PATCHLEVEL = 15 |
321 |
+-SUBLEVEL = 16 |
322 |
++SUBLEVEL = 17 |
323 |
+ EXTRAVERSION = |
324 |
+ NAME = Trick or Treat |
325 |
+ |
326 |
+diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug |
327 |
+index 98436702e0c7e..644875d73ba15 100644 |
328 |
+--- a/arch/arm/Kconfig.debug |
329 |
++++ b/arch/arm/Kconfig.debug |
330 |
+@@ -410,12 +410,12 @@ choice |
331 |
+ Say Y here if you want kernel low-level debugging support |
332 |
+ on i.MX25. |
333 |
+ |
334 |
+- config DEBUG_IMX21_IMX27_UART |
335 |
+- bool "i.MX21 and i.MX27 Debug UART" |
336 |
+- depends on SOC_IMX21 || SOC_IMX27 |
337 |
++ config DEBUG_IMX27_UART |
338 |
++ bool "i.MX27 Debug UART" |
339 |
++ depends on SOC_IMX27 |
340 |
+ help |
341 |
+ Say Y here if you want kernel low-level debugging support |
342 |
+- on i.MX21 or i.MX27. |
343 |
++ on i.MX27. |
344 |
+ |
345 |
+ config DEBUG_IMX28_UART |
346 |
+ bool "i.MX28 Debug UART" |
347 |
+@@ -1481,7 +1481,7 @@ config DEBUG_IMX_UART_PORT |
348 |
+ int "i.MX Debug UART Port Selection" |
349 |
+ depends on DEBUG_IMX1_UART || \ |
350 |
+ DEBUG_IMX25_UART || \ |
351 |
+- DEBUG_IMX21_IMX27_UART || \ |
352 |
++ DEBUG_IMX27_UART || \ |
353 |
+ DEBUG_IMX31_UART || \ |
354 |
+ DEBUG_IMX35_UART || \ |
355 |
+ DEBUG_IMX50_UART || \ |
356 |
+@@ -1540,12 +1540,12 @@ config DEBUG_LL_INCLUDE |
357 |
+ default "debug/icedcc.S" if DEBUG_ICEDCC |
358 |
+ default "debug/imx.S" if DEBUG_IMX1_UART || \ |
359 |
+ DEBUG_IMX25_UART || \ |
360 |
+- DEBUG_IMX21_IMX27_UART || \ |
361 |
++ DEBUG_IMX27_UART || \ |
362 |
+ DEBUG_IMX31_UART || \ |
363 |
+ DEBUG_IMX35_UART || \ |
364 |
+ DEBUG_IMX50_UART || \ |
365 |
+ DEBUG_IMX51_UART || \ |
366 |
+- DEBUG_IMX53_UART ||\ |
367 |
++ DEBUG_IMX53_UART || \ |
368 |
+ DEBUG_IMX6Q_UART || \ |
369 |
+ DEBUG_IMX6SL_UART || \ |
370 |
+ DEBUG_IMX6SX_UART || \ |
371 |
+diff --git a/arch/arm/boot/compressed/efi-header.S b/arch/arm/boot/compressed/efi-header.S |
372 |
+index c0e7a745103e2..230030c130853 100644 |
373 |
+--- a/arch/arm/boot/compressed/efi-header.S |
374 |
++++ b/arch/arm/boot/compressed/efi-header.S |
375 |
+@@ -9,16 +9,22 @@ |
376 |
+ #include <linux/sizes.h> |
377 |
+ |
378 |
+ .macro __nop |
379 |
+-#ifdef CONFIG_EFI_STUB |
380 |
+- @ This is almost but not quite a NOP, since it does clobber the |
381 |
+- @ condition flags. But it is the best we can do for EFI, since |
382 |
+- @ PE/COFF expects the magic string "MZ" at offset 0, while the |
383 |
+- @ ARM/Linux boot protocol expects an executable instruction |
384 |
+- @ there. |
385 |
+- .inst MZ_MAGIC | (0x1310 << 16) @ tstne r0, #0x4d000 |
386 |
+-#else |
387 |
+ AR_CLASS( mov r0, r0 ) |
388 |
+ M_CLASS( nop.w ) |
389 |
++ .endm |
390 |
++ |
391 |
++ .macro __initial_nops |
392 |
++#ifdef CONFIG_EFI_STUB |
393 |
++ @ This is a two-instruction NOP, which happens to bear the |
394 |
++ @ PE/COFF signature "MZ" in the first two bytes, so the kernel |
395 |
++ @ is accepted as an EFI binary. Booting via the UEFI stub |
396 |
++ @ will not execute those instructions, but the ARM/Linux |
397 |
++ @ boot protocol does, so we need some NOPs here. |
398 |
++ .inst MZ_MAGIC | (0xe225 << 16) @ eor r5, r5, 0x4d000 |
399 |
++ eor r5, r5, 0x4d000 @ undo previous insn |
400 |
++#else |
401 |
++ __nop |
402 |
++ __nop |
403 |
+ #endif |
404 |
+ .endm |
405 |
+ |
406 |
+diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S |
407 |
+index b1cb1972361b8..bf79f2f78d232 100644 |
408 |
+--- a/arch/arm/boot/compressed/head.S |
409 |
++++ b/arch/arm/boot/compressed/head.S |
410 |
+@@ -203,7 +203,8 @@ start: |
411 |
+ * were patching the initial instructions of the kernel, i.e |
412 |
+ * had started to exploit this "patch area". |
413 |
+ */ |
414 |
+- .rept 7 |
415 |
++ __initial_nops |
416 |
++ .rept 5 |
417 |
+ __nop |
418 |
+ .endr |
419 |
+ #ifndef CONFIG_THUMB2_KERNEL |
420 |
+diff --git a/arch/arm/boot/dts/armada-38x.dtsi b/arch/arm/boot/dts/armada-38x.dtsi |
421 |
+index 9b1a24cc5e91f..df3c8d1d8f641 100644 |
422 |
+--- a/arch/arm/boot/dts/armada-38x.dtsi |
423 |
++++ b/arch/arm/boot/dts/armada-38x.dtsi |
424 |
+@@ -168,7 +168,7 @@ |
425 |
+ }; |
426 |
+ |
427 |
+ uart0: serial@12000 { |
428 |
+- compatible = "marvell,armada-38x-uart"; |
429 |
++ compatible = "marvell,armada-38x-uart", "ns16550a"; |
430 |
+ reg = <0x12000 0x100>; |
431 |
+ reg-shift = <2>; |
432 |
+ interrupts = <GIC_SPI 12 IRQ_TYPE_LEVEL_HIGH>; |
433 |
+@@ -178,7 +178,7 @@ |
434 |
+ }; |
435 |
+ |
436 |
+ uart1: serial@12100 { |
437 |
+- compatible = "marvell,armada-38x-uart"; |
438 |
++ compatible = "marvell,armada-38x-uart", "ns16550a"; |
439 |
+ reg = <0x12100 0x100>; |
440 |
+ reg-shift = <2>; |
441 |
+ interrupts = <GIC_SPI 13 IRQ_TYPE_LEVEL_HIGH>; |
442 |
+diff --git a/arch/arm/boot/dts/gemini-nas4220b.dts b/arch/arm/boot/dts/gemini-nas4220b.dts |
443 |
+index 13112a8a5dd88..6544c730340fa 100644 |
444 |
+--- a/arch/arm/boot/dts/gemini-nas4220b.dts |
445 |
++++ b/arch/arm/boot/dts/gemini-nas4220b.dts |
446 |
+@@ -84,7 +84,7 @@ |
447 |
+ partitions { |
448 |
+ compatible = "redboot-fis"; |
449 |
+ /* Eraseblock at 0xfe0000 */ |
450 |
+- fis-index-block = <0x1fc>; |
451 |
++ fis-index-block = <0x7f>; |
452 |
+ }; |
453 |
+ }; |
454 |
+ |
455 |
+diff --git a/arch/arm/boot/dts/omap3-n900.dts b/arch/arm/boot/dts/omap3-n900.dts |
456 |
+index 32335d4ce478b..d40c3d2c4914e 100644 |
457 |
+--- a/arch/arm/boot/dts/omap3-n900.dts |
458 |
++++ b/arch/arm/boot/dts/omap3-n900.dts |
459 |
+@@ -8,6 +8,7 @@ |
460 |
+ |
461 |
+ #include "omap34xx.dtsi" |
462 |
+ #include <dt-bindings/input/input.h> |
463 |
++#include <dt-bindings/leds/common.h> |
464 |
+ |
465 |
+ /* |
466 |
+ * Default secure signed bootloader (Nokia X-Loader) does not enable L3 firewall |
467 |
+@@ -630,63 +631,92 @@ |
468 |
+ }; |
469 |
+ |
470 |
+ lp5523: lp5523@32 { |
471 |
++ #address-cells = <1>; |
472 |
++ #size-cells = <0>; |
473 |
+ compatible = "national,lp5523"; |
474 |
+ reg = <0x32>; |
475 |
+ clock-mode = /bits/ 8 <0>; /* LP55XX_CLOCK_AUTO */ |
476 |
+- enable-gpio = <&gpio2 9 GPIO_ACTIVE_HIGH>; /* 41 */ |
477 |
++ enable-gpios = <&gpio2 9 GPIO_ACTIVE_HIGH>; /* 41 */ |
478 |
+ |
479 |
+- chan0 { |
480 |
++ led@0 { |
481 |
++ reg = <0>; |
482 |
+ chan-name = "lp5523:kb1"; |
483 |
+ led-cur = /bits/ 8 <50>; |
484 |
+ max-cur = /bits/ 8 <100>; |
485 |
++ color = <LED_COLOR_ID_WHITE>; |
486 |
++ function = LED_FUNCTION_KBD_BACKLIGHT; |
487 |
+ }; |
488 |
+ |
489 |
+- chan1 { |
490 |
++ led@1 { |
491 |
++ reg = <1>; |
492 |
+ chan-name = "lp5523:kb2"; |
493 |
+ led-cur = /bits/ 8 <50>; |
494 |
+ max-cur = /bits/ 8 <100>; |
495 |
++ color = <LED_COLOR_ID_WHITE>; |
496 |
++ function = LED_FUNCTION_KBD_BACKLIGHT; |
497 |
+ }; |
498 |
+ |
499 |
+- chan2 { |
500 |
++ led@2 { |
501 |
++ reg = <2>; |
502 |
+ chan-name = "lp5523:kb3"; |
503 |
+ led-cur = /bits/ 8 <50>; |
504 |
+ max-cur = /bits/ 8 <100>; |
505 |
++ color = <LED_COLOR_ID_WHITE>; |
506 |
++ function = LED_FUNCTION_KBD_BACKLIGHT; |
507 |
+ }; |
508 |
+ |
509 |
+- chan3 { |
510 |
++ led@3 { |
511 |
++ reg = <3>; |
512 |
+ chan-name = "lp5523:kb4"; |
513 |
+ led-cur = /bits/ 8 <50>; |
514 |
+ max-cur = /bits/ 8 <100>; |
515 |
++ color = <LED_COLOR_ID_WHITE>; |
516 |
++ function = LED_FUNCTION_KBD_BACKLIGHT; |
517 |
+ }; |
518 |
+ |
519 |
+- chan4 { |
520 |
++ led@4 { |
521 |
++ reg = <4>; |
522 |
+ chan-name = "lp5523:b"; |
523 |
+ led-cur = /bits/ 8 <50>; |
524 |
+ max-cur = /bits/ 8 <100>; |
525 |
++ color = <LED_COLOR_ID_BLUE>; |
526 |
++ function = LED_FUNCTION_STATUS; |
527 |
+ }; |
528 |
+ |
529 |
+- chan5 { |
530 |
++ led@5 { |
531 |
++ reg = <5>; |
532 |
+ chan-name = "lp5523:g"; |
533 |
+ led-cur = /bits/ 8 <50>; |
534 |
+ max-cur = /bits/ 8 <100>; |
535 |
++ color = <LED_COLOR_ID_GREEN>; |
536 |
++ function = LED_FUNCTION_STATUS; |
537 |
+ }; |
538 |
+ |
539 |
+- chan6 { |
540 |
++ led@6 { |
541 |
++ reg = <6>; |
542 |
+ chan-name = "lp5523:r"; |
543 |
+ led-cur = /bits/ 8 <50>; |
544 |
+ max-cur = /bits/ 8 <100>; |
545 |
++ color = <LED_COLOR_ID_RED>; |
546 |
++ function = LED_FUNCTION_STATUS; |
547 |
+ }; |
548 |
+ |
549 |
+- chan7 { |
550 |
++ led@7 { |
551 |
++ reg = <7>; |
552 |
+ chan-name = "lp5523:kb5"; |
553 |
+ led-cur = /bits/ 8 <50>; |
554 |
+ max-cur = /bits/ 8 <100>; |
555 |
++ color = <LED_COLOR_ID_WHITE>; |
556 |
++ function = LED_FUNCTION_KBD_BACKLIGHT; |
557 |
+ }; |
558 |
+ |
559 |
+- chan8 { |
560 |
++ led@8 { |
561 |
++ reg = <8>; |
562 |
+ chan-name = "lp5523:kb6"; |
563 |
+ led-cur = /bits/ 8 <50>; |
564 |
+ max-cur = /bits/ 8 <100>; |
565 |
++ color = <LED_COLOR_ID_WHITE>; |
566 |
++ function = LED_FUNCTION_KBD_BACKLIGHT; |
567 |
+ }; |
568 |
+ }; |
569 |
+ |
570 |
+diff --git a/arch/arm/boot/dts/qcom-sdx55.dtsi b/arch/arm/boot/dts/qcom-sdx55.dtsi |
571 |
+index 1e6ce035f76a9..b5b784c5c65e4 100644 |
572 |
+--- a/arch/arm/boot/dts/qcom-sdx55.dtsi |
573 |
++++ b/arch/arm/boot/dts/qcom-sdx55.dtsi |
574 |
+@@ -334,12 +334,10 @@ |
575 |
+ clocks = <&rpmhcc RPMH_IPA_CLK>; |
576 |
+ clock-names = "core"; |
577 |
+ |
578 |
+- interconnects = <&system_noc MASTER_IPA &system_noc SLAVE_SNOC_MEM_NOC_GC>, |
579 |
+- <&mem_noc MASTER_SNOC_GC_MEM_NOC &mc_virt SLAVE_EBI_CH0>, |
580 |
++ interconnects = <&system_noc MASTER_IPA &mc_virt SLAVE_EBI_CH0>, |
581 |
+ <&system_noc MASTER_IPA &system_noc SLAVE_OCIMEM>, |
582 |
+ <&mem_noc MASTER_AMPSS_M0 &system_noc SLAVE_IPA_CFG>; |
583 |
+- interconnect-names = "memory-a", |
584 |
+- "memory-b", |
585 |
++ interconnect-names = "memory", |
586 |
+ "imem", |
587 |
+ "config"; |
588 |
+ |
589 |
+diff --git a/arch/arm/boot/dts/sama7g5-pinfunc.h b/arch/arm/boot/dts/sama7g5-pinfunc.h |
590 |
+index 22fe9e522a97b..4eb30445d2057 100644 |
591 |
+--- a/arch/arm/boot/dts/sama7g5-pinfunc.h |
592 |
++++ b/arch/arm/boot/dts/sama7g5-pinfunc.h |
593 |
+@@ -765,7 +765,7 @@ |
594 |
+ #define PIN_PD20__PCK0 PINMUX_PIN(PIN_PD20, 1, 3) |
595 |
+ #define PIN_PD20__FLEXCOM2_IO3 PINMUX_PIN(PIN_PD20, 2, 2) |
596 |
+ #define PIN_PD20__PWMH3 PINMUX_PIN(PIN_PD20, 3, 4) |
597 |
+-#define PIN_PD20__CANTX4 PINMUX_PIN(PIN_PD20, 5, 2) |
598 |
++#define PIN_PD20__CANTX4 PINMUX_PIN(PIN_PD20, 4, 2) |
599 |
+ #define PIN_PD20__FLEXCOM5_IO0 PINMUX_PIN(PIN_PD20, 6, 5) |
600 |
+ #define PIN_PD21 117 |
601 |
+ #define PIN_PD21__GPIO PINMUX_PIN(PIN_PD21, 0, 0) |
602 |
+diff --git a/arch/arm/boot/dts/stm32f429-disco.dts b/arch/arm/boot/dts/stm32f429-disco.dts |
603 |
+index 075ac57d0bf4a..6435e099c6326 100644 |
604 |
+--- a/arch/arm/boot/dts/stm32f429-disco.dts |
605 |
++++ b/arch/arm/boot/dts/stm32f429-disco.dts |
606 |
+@@ -192,7 +192,7 @@ |
607 |
+ |
608 |
+ display: display@1{ |
609 |
+ /* Connect panel-ilitek-9341 to ltdc */ |
610 |
+- compatible = "st,sf-tc240t-9370-t"; |
611 |
++ compatible = "st,sf-tc240t-9370-t", "ilitek,ili9341"; |
612 |
+ reg = <1>; |
613 |
+ spi-3wire; |
614 |
+ spi-max-frequency = <10000000>; |
615 |
+diff --git a/arch/arm/configs/cm_x300_defconfig b/arch/arm/configs/cm_x300_defconfig |
616 |
+index 502a9d870ca44..45769d0ddd4ef 100644 |
617 |
+--- a/arch/arm/configs/cm_x300_defconfig |
618 |
++++ b/arch/arm/configs/cm_x300_defconfig |
619 |
+@@ -146,7 +146,6 @@ CONFIG_NFS_V3_ACL=y |
620 |
+ CONFIG_NFS_V4=y |
621 |
+ CONFIG_ROOT_NFS=y |
622 |
+ CONFIG_CIFS=m |
623 |
+-CONFIG_CIFS_WEAK_PW_HASH=y |
624 |
+ CONFIG_PARTITION_ADVANCED=y |
625 |
+ CONFIG_NLS_CODEPAGE_437=m |
626 |
+ CONFIG_NLS_ISO8859_1=m |
627 |
+diff --git a/arch/arm/configs/ezx_defconfig b/arch/arm/configs/ezx_defconfig |
628 |
+index a49e699e52de3..ec84d80096b1c 100644 |
629 |
+--- a/arch/arm/configs/ezx_defconfig |
630 |
++++ b/arch/arm/configs/ezx_defconfig |
631 |
+@@ -314,7 +314,6 @@ CONFIG_NFSD_V3_ACL=y |
632 |
+ CONFIG_SMB_FS=m |
633 |
+ CONFIG_CIFS=m |
634 |
+ CONFIG_CIFS_STATS=y |
635 |
+-CONFIG_CIFS_WEAK_PW_HASH=y |
636 |
+ CONFIG_CIFS_XATTR=y |
637 |
+ CONFIG_CIFS_POSIX=y |
638 |
+ CONFIG_NLS_CODEPAGE_437=m |
639 |
+diff --git a/arch/arm/configs/imote2_defconfig b/arch/arm/configs/imote2_defconfig |
640 |
+index 118c4c927f264..6db871d4e0775 100644 |
641 |
+--- a/arch/arm/configs/imote2_defconfig |
642 |
++++ b/arch/arm/configs/imote2_defconfig |
643 |
+@@ -288,7 +288,6 @@ CONFIG_NFSD_V3_ACL=y |
644 |
+ CONFIG_SMB_FS=m |
645 |
+ CONFIG_CIFS=m |
646 |
+ CONFIG_CIFS_STATS=y |
647 |
+-CONFIG_CIFS_WEAK_PW_HASH=y |
648 |
+ CONFIG_CIFS_XATTR=y |
649 |
+ CONFIG_CIFS_POSIX=y |
650 |
+ CONFIG_NLS_CODEPAGE_437=m |
651 |
+diff --git a/arch/arm/configs/nhk8815_defconfig b/arch/arm/configs/nhk8815_defconfig |
652 |
+index 23595fc5a29a9..907d6512821ad 100644 |
653 |
+--- a/arch/arm/configs/nhk8815_defconfig |
654 |
++++ b/arch/arm/configs/nhk8815_defconfig |
655 |
+@@ -127,7 +127,6 @@ CONFIG_NFS_FS=y |
656 |
+ CONFIG_NFS_V3_ACL=y |
657 |
+ CONFIG_ROOT_NFS=y |
658 |
+ CONFIG_CIFS=m |
659 |
+-CONFIG_CIFS_WEAK_PW_HASH=y |
660 |
+ CONFIG_NLS_CODEPAGE_437=y |
661 |
+ CONFIG_NLS_ASCII=y |
662 |
+ CONFIG_NLS_ISO8859_1=y |
663 |
+diff --git a/arch/arm/configs/pxa_defconfig b/arch/arm/configs/pxa_defconfig |
664 |
+index 58f4834289e63..dedaaae3d0d8a 100644 |
665 |
+--- a/arch/arm/configs/pxa_defconfig |
666 |
++++ b/arch/arm/configs/pxa_defconfig |
667 |
+@@ -699,7 +699,6 @@ CONFIG_NFSD_V3_ACL=y |
668 |
+ CONFIG_NFSD_V4=y |
669 |
+ CONFIG_CIFS=m |
670 |
+ CONFIG_CIFS_STATS=y |
671 |
+-CONFIG_CIFS_WEAK_PW_HASH=y |
672 |
+ CONFIG_CIFS_XATTR=y |
673 |
+ CONFIG_CIFS_POSIX=y |
674 |
+ CONFIG_NLS_DEFAULT="utf8" |
675 |
+diff --git a/arch/arm/configs/spear13xx_defconfig b/arch/arm/configs/spear13xx_defconfig |
676 |
+index 3b206a31902ff..065553326b391 100644 |
677 |
+--- a/arch/arm/configs/spear13xx_defconfig |
678 |
++++ b/arch/arm/configs/spear13xx_defconfig |
679 |
+@@ -61,7 +61,6 @@ CONFIG_SERIAL_AMBA_PL011=y |
680 |
+ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y |
681 |
+ # CONFIG_HW_RANDOM is not set |
682 |
+ CONFIG_RAW_DRIVER=y |
683 |
+-CONFIG_MAX_RAW_DEVS=8192 |
684 |
+ CONFIG_I2C=y |
685 |
+ CONFIG_I2C_DESIGNWARE_PLATFORM=y |
686 |
+ CONFIG_SPI=y |
687 |
+diff --git a/arch/arm/configs/spear3xx_defconfig b/arch/arm/configs/spear3xx_defconfig |
688 |
+index fc5f71c765edc..afca722d6605c 100644 |
689 |
+--- a/arch/arm/configs/spear3xx_defconfig |
690 |
++++ b/arch/arm/configs/spear3xx_defconfig |
691 |
+@@ -41,7 +41,6 @@ CONFIG_SERIAL_AMBA_PL011=y |
692 |
+ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y |
693 |
+ # CONFIG_HW_RANDOM is not set |
694 |
+ CONFIG_RAW_DRIVER=y |
695 |
+-CONFIG_MAX_RAW_DEVS=8192 |
696 |
+ CONFIG_I2C=y |
697 |
+ CONFIG_I2C_DESIGNWARE_PLATFORM=y |
698 |
+ CONFIG_SPI=y |
699 |
+diff --git a/arch/arm/configs/spear6xx_defconfig b/arch/arm/configs/spear6xx_defconfig |
700 |
+index 52a56b8ce6a71..bc32c02cb86b1 100644 |
701 |
+--- a/arch/arm/configs/spear6xx_defconfig |
702 |
++++ b/arch/arm/configs/spear6xx_defconfig |
703 |
+@@ -36,7 +36,6 @@ CONFIG_INPUT_FF_MEMLESS=y |
704 |
+ CONFIG_SERIAL_AMBA_PL011=y |
705 |
+ CONFIG_SERIAL_AMBA_PL011_CONSOLE=y |
706 |
+ CONFIG_RAW_DRIVER=y |
707 |
+-CONFIG_MAX_RAW_DEVS=8192 |
708 |
+ CONFIG_I2C=y |
709 |
+ CONFIG_I2C_DESIGNWARE_PLATFORM=y |
710 |
+ CONFIG_SPI=y |
711 |
+diff --git a/arch/arm/include/debug/imx-uart.h b/arch/arm/include/debug/imx-uart.h |
712 |
+index c8eb83d4b8964..3edbb3c5b42bf 100644 |
713 |
+--- a/arch/arm/include/debug/imx-uart.h |
714 |
++++ b/arch/arm/include/debug/imx-uart.h |
715 |
+@@ -11,13 +11,6 @@ |
716 |
+ #define IMX1_UART_BASE_ADDR(n) IMX1_UART##n##_BASE_ADDR |
717 |
+ #define IMX1_UART_BASE(n) IMX1_UART_BASE_ADDR(n) |
718 |
+ |
719 |
+-#define IMX21_UART1_BASE_ADDR 0x1000a000 |
720 |
+-#define IMX21_UART2_BASE_ADDR 0x1000b000 |
721 |
+-#define IMX21_UART3_BASE_ADDR 0x1000c000 |
722 |
+-#define IMX21_UART4_BASE_ADDR 0x1000d000 |
723 |
+-#define IMX21_UART_BASE_ADDR(n) IMX21_UART##n##_BASE_ADDR |
724 |
+-#define IMX21_UART_BASE(n) IMX21_UART_BASE_ADDR(n) |
725 |
+- |
726 |
+ #define IMX25_UART1_BASE_ADDR 0x43f90000 |
727 |
+ #define IMX25_UART2_BASE_ADDR 0x43f94000 |
728 |
+ #define IMX25_UART3_BASE_ADDR 0x5000c000 |
729 |
+@@ -26,6 +19,13 @@ |
730 |
+ #define IMX25_UART_BASE_ADDR(n) IMX25_UART##n##_BASE_ADDR |
731 |
+ #define IMX25_UART_BASE(n) IMX25_UART_BASE_ADDR(n) |
732 |
+ |
733 |
++#define IMX27_UART1_BASE_ADDR 0x1000a000 |
734 |
++#define IMX27_UART2_BASE_ADDR 0x1000b000 |
735 |
++#define IMX27_UART3_BASE_ADDR 0x1000c000 |
736 |
++#define IMX27_UART4_BASE_ADDR 0x1000d000 |
737 |
++#define IMX27_UART_BASE_ADDR(n) IMX27_UART##n##_BASE_ADDR |
738 |
++#define IMX27_UART_BASE(n) IMX27_UART_BASE_ADDR(n) |
739 |
++ |
740 |
+ #define IMX31_UART1_BASE_ADDR 0x43f90000 |
741 |
+ #define IMX31_UART2_BASE_ADDR 0x43f94000 |
742 |
+ #define IMX31_UART3_BASE_ADDR 0x5000c000 |
743 |
+@@ -112,10 +112,10 @@ |
744 |
+ |
745 |
+ #ifdef CONFIG_DEBUG_IMX1_UART |
746 |
+ #define UART_PADDR IMX_DEBUG_UART_BASE(IMX1) |
747 |
+-#elif defined(CONFIG_DEBUG_IMX21_IMX27_UART) |
748 |
+-#define UART_PADDR IMX_DEBUG_UART_BASE(IMX21) |
749 |
+ #elif defined(CONFIG_DEBUG_IMX25_UART) |
750 |
+ #define UART_PADDR IMX_DEBUG_UART_BASE(IMX25) |
751 |
++#elif defined(CONFIG_DEBUG_IMX27_UART) |
752 |
++#define UART_PADDR IMX_DEBUG_UART_BASE(IMX27) |
753 |
+ #elif defined(CONFIG_DEBUG_IMX31_UART) |
754 |
+ #define UART_PADDR IMX_DEBUG_UART_BASE(IMX31) |
755 |
+ #elif defined(CONFIG_DEBUG_IMX35_UART) |
756 |
+diff --git a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c |
757 |
+index ee949255ced3f..09ef73b99dd86 100644 |
758 |
+--- a/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c |
759 |
++++ b/arch/arm/mach-shmobile/regulator-quirk-rcar-gen2.c |
760 |
+@@ -154,8 +154,10 @@ static int __init rcar_gen2_regulator_quirk(void) |
761 |
+ return -ENODEV; |
762 |
+ |
763 |
+ for_each_matching_node_and_match(np, rcar_gen2_quirk_match, &id) { |
764 |
+- if (!of_device_is_available(np)) |
765 |
++ if (!of_device_is_available(np)) { |
766 |
++ of_node_put(np); |
767 |
+ break; |
768 |
++ } |
769 |
+ |
770 |
+ ret = of_property_read_u32(np, "reg", &addr); |
771 |
+ if (ret) /* Skip invalid entry and continue */ |
772 |
+@@ -164,6 +166,7 @@ static int __init rcar_gen2_regulator_quirk(void) |
773 |
+ quirk = kzalloc(sizeof(*quirk), GFP_KERNEL); |
774 |
+ if (!quirk) { |
775 |
+ ret = -ENOMEM; |
776 |
++ of_node_put(np); |
777 |
+ goto err_mem; |
778 |
+ } |
779 |
+ |
780 |
+diff --git a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi |
781 |
+index 00c6f53290d43..428449d98c0ae 100644 |
782 |
+--- a/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi |
783 |
++++ b/arch/arm64/boot/dts/amlogic/meson-g12-common.dtsi |
784 |
+@@ -58,7 +58,7 @@ |
785 |
+ secure-monitor = <&sm>; |
786 |
+ }; |
787 |
+ |
788 |
+- gpu_opp_table: gpu-opp-table { |
789 |
++ gpu_opp_table: opp-table-gpu { |
790 |
+ compatible = "operating-points-v2"; |
791 |
+ |
792 |
+ opp-124999998 { |
793 |
+diff --git a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi |
794 |
+index 4f33820aba1f1..a84ed3578425e 100644 |
795 |
+--- a/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi |
796 |
++++ b/arch/arm64/boot/dts/amlogic/meson-g12b-odroid-n2.dtsi |
797 |
+@@ -607,7 +607,7 @@ |
798 |
+ pinctrl-0 = <&nor_pins>; |
799 |
+ pinctrl-names = "default"; |
800 |
+ |
801 |
+- mx25u64: spi-flash@0 { |
802 |
++ mx25u64: flash@0 { |
803 |
+ #address-cells = <1>; |
804 |
+ #size-cells = <1>; |
805 |
+ compatible = "mxicy,mx25u6435f", "jedec,spi-nor"; |
806 |
+diff --git a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi |
807 |
+index a350fee1264d7..a4d34398da358 100644 |
808 |
+--- a/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi |
809 |
++++ b/arch/arm64/boot/dts/amlogic/meson-gxbb-wetek.dtsi |
810 |
+@@ -6,6 +6,7 @@ |
811 |
+ */ |
812 |
+ |
813 |
+ #include "meson-gxbb.dtsi" |
814 |
++#include <dt-bindings/gpio/gpio.h> |
815 |
+ |
816 |
+ / { |
817 |
+ aliases { |
818 |
+@@ -64,6 +65,7 @@ |
819 |
+ regulator-name = "VDDIO_AO18"; |
820 |
+ regulator-min-microvolt = <1800000>; |
821 |
+ regulator-max-microvolt = <1800000>; |
822 |
++ regulator-always-on; |
823 |
+ }; |
824 |
+ |
825 |
+ vcc_3v3: regulator-vcc_3v3 { |
826 |
+@@ -161,6 +163,7 @@ |
827 |
+ status = "okay"; |
828 |
+ pinctrl-0 = <&hdmi_hpd_pins>, <&hdmi_i2c_pins>; |
829 |
+ pinctrl-names = "default"; |
830 |
++ hdmi-supply = <&vddio_ao18>; |
831 |
+ }; |
832 |
+ |
833 |
+ &hdmi_tx_tmds_port { |
834 |
+diff --git a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts |
835 |
+index bfd14b64567e4..2f92e62ecafe9 100644 |
836 |
+--- a/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts |
837 |
++++ b/arch/arm64/boot/dts/freescale/fsl-ls1028a-qds.dts |
838 |
+@@ -272,11 +272,6 @@ |
839 |
+ vcc-supply = <&sb_3v3>; |
840 |
+ }; |
841 |
+ |
842 |
+- rtc@51 { |
843 |
+- compatible = "nxp,pcf2129"; |
844 |
+- reg = <0x51>; |
845 |
+- }; |
846 |
+- |
847 |
+ eeprom@56 { |
848 |
+ compatible = "atmel,24c512"; |
849 |
+ reg = <0x56>; |
850 |
+@@ -318,6 +313,15 @@ |
851 |
+ |
852 |
+ }; |
853 |
+ |
854 |
++&i2c1 { |
855 |
++ status = "okay"; |
856 |
++ |
857 |
++ rtc@51 { |
858 |
++ compatible = "nxp,pcf2129"; |
859 |
++ reg = <0x51>; |
860 |
++ }; |
861 |
++}; |
862 |
++ |
863 |
+ &enetc_port1 { |
864 |
+ phy-handle = <&qds_phy1>; |
865 |
+ phy-connection-type = "rgmii-id"; |
866 |
+diff --git a/arch/arm64/boot/dts/marvell/cn9130.dtsi b/arch/arm64/boot/dts/marvell/cn9130.dtsi |
867 |
+index a2b7e5ec979d3..327b04134134f 100644 |
868 |
+--- a/arch/arm64/boot/dts/marvell/cn9130.dtsi |
869 |
++++ b/arch/arm64/boot/dts/marvell/cn9130.dtsi |
870 |
+@@ -11,6 +11,13 @@ |
871 |
+ model = "Marvell Armada CN9130 SoC"; |
872 |
+ compatible = "marvell,cn9130", "marvell,armada-ap807-quad", |
873 |
+ "marvell,armada-ap807"; |
874 |
++ |
875 |
++ aliases { |
876 |
++ gpio1 = &cp0_gpio1; |
877 |
++ gpio2 = &cp0_gpio2; |
878 |
++ spi1 = &cp0_spi0; |
879 |
++ spi2 = &cp0_spi1; |
880 |
++ }; |
881 |
+ }; |
882 |
+ |
883 |
+ /* |
884 |
+@@ -35,3 +42,11 @@ |
885 |
+ #undef CP11X_PCIE0_BASE |
886 |
+ #undef CP11X_PCIE1_BASE |
887 |
+ #undef CP11X_PCIE2_BASE |
888 |
++ |
889 |
++&cp0_gpio1 { |
890 |
++ status = "okay"; |
891 |
++}; |
892 |
++ |
893 |
++&cp0_gpio2 { |
894 |
++ status = "okay"; |
895 |
++}; |
896 |
+diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi |
897 |
+index e94f8add1a400..062e87e893316 100644 |
898 |
+--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi |
899 |
++++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi |
900 |
+@@ -1079,7 +1079,7 @@ |
901 |
+ |
902 |
+ ccplex@e000000 { |
903 |
+ compatible = "nvidia,tegra186-ccplex-cluster"; |
904 |
+- reg = <0x0 0x0e000000 0x0 0x3fffff>; |
905 |
++ reg = <0x0 0x0e000000 0x0 0x400000>; |
906 |
+ |
907 |
+ nvidia,bpmp = <&bpmp>; |
908 |
+ }; |
909 |
+diff --git a/arch/arm64/boot/dts/nvidia/tegra194.dtsi b/arch/arm64/boot/dts/nvidia/tegra194.dtsi |
910 |
+index c8250a3f7891f..510d2974470cd 100644 |
911 |
+--- a/arch/arm64/boot/dts/nvidia/tegra194.dtsi |
912 |
++++ b/arch/arm64/boot/dts/nvidia/tegra194.dtsi |
913 |
+@@ -818,9 +818,8 @@ |
914 |
+ <&bpmp TEGRA194_CLK_HDA2CODEC_2X>; |
915 |
+ clock-names = "hda", "hda2hdmi", "hda2codec_2x"; |
916 |
+ resets = <&bpmp TEGRA194_RESET_HDA>, |
917 |
+- <&bpmp TEGRA194_RESET_HDA2HDMICODEC>, |
918 |
+- <&bpmp TEGRA194_RESET_HDA2CODEC_2X>; |
919 |
+- reset-names = "hda", "hda2hdmi", "hda2codec_2x"; |
920 |
++ <&bpmp TEGRA194_RESET_HDA2HDMICODEC>; |
921 |
++ reset-names = "hda", "hda2hdmi"; |
922 |
+ power-domains = <&bpmp TEGRA194_POWER_DOMAIN_DISP>; |
923 |
+ interconnects = <&mc TEGRA194_MEMORY_CLIENT_HDAR &emc>, |
924 |
+ <&mc TEGRA194_MEMORY_CLIENT_HDAW &emc>; |
925 |
+diff --git a/arch/arm64/boot/dts/qcom/ipq6018.dtsi b/arch/arm64/boot/dts/qcom/ipq6018.dtsi |
926 |
+index 7b6205c180df1..ce4c2b4a5fc07 100644 |
927 |
+--- a/arch/arm64/boot/dts/qcom/ipq6018.dtsi |
928 |
++++ b/arch/arm64/boot/dts/qcom/ipq6018.dtsi |
929 |
+@@ -221,7 +221,7 @@ |
930 |
+ interrupts = <GIC_SPI 208 IRQ_TYPE_LEVEL_HIGH>; |
931 |
+ gpio-controller; |
932 |
+ #gpio-cells = <2>; |
933 |
+- gpio-ranges = <&tlmm 0 80>; |
934 |
++ gpio-ranges = <&tlmm 0 0 80>; |
935 |
+ interrupt-controller; |
936 |
+ #interrupt-cells = <2>; |
937 |
+ |
938 |
+diff --git a/arch/arm64/boot/dts/qcom/msm8916.dtsi b/arch/arm64/boot/dts/qcom/msm8916.dtsi |
939 |
+index 427bb20626549..8b27242724641 100644 |
940 |
+--- a/arch/arm64/boot/dts/qcom/msm8916.dtsi |
941 |
++++ b/arch/arm64/boot/dts/qcom/msm8916.dtsi |
942 |
+@@ -19,8 +19,8 @@ |
943 |
+ #size-cells = <2>; |
944 |
+ |
945 |
+ aliases { |
946 |
+- sdhc1 = &sdhc_1; /* SDC1 eMMC slot */ |
947 |
+- sdhc2 = &sdhc_2; /* SDC2 SD card slot */ |
948 |
++ mmc0 = &sdhc_1; /* SDC1 eMMC slot */ |
949 |
++ mmc1 = &sdhc_2; /* SDC2 SD card slot */ |
950 |
+ }; |
951 |
+ |
952 |
+ chosen { }; |
953 |
+diff --git a/arch/arm64/boot/dts/qcom/msm8996.dtsi b/arch/arm64/boot/dts/qcom/msm8996.dtsi |
954 |
+index f8d28dd76cfa8..6077c36019514 100644 |
955 |
+--- a/arch/arm64/boot/dts/qcom/msm8996.dtsi |
956 |
++++ b/arch/arm64/boot/dts/qcom/msm8996.dtsi |
957 |
+@@ -965,9 +965,6 @@ |
958 |
+ nvmem-cells = <&speedbin_efuse>; |
959 |
+ nvmem-cell-names = "speed_bin"; |
960 |
+ |
961 |
+- qcom,gpu-quirk-two-pass-use-wfi; |
962 |
+- qcom,gpu-quirk-fault-detect-mask; |
963 |
+- |
964 |
+ operating-points-v2 = <&gpu_opp_table>; |
965 |
+ |
966 |
+ status = "disabled"; |
967 |
+diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi |
968 |
+index f58336536a92a..692973c4f4344 100644 |
969 |
+--- a/arch/arm64/boot/dts/qcom/sc7280.dtsi |
970 |
++++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi |
971 |
+@@ -429,7 +429,7 @@ |
972 |
+ <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>, |
973 |
+ <0>, <0>, <0>, <0>, <0>, <0>; |
974 |
+ clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk", |
975 |
+- "pcie_0_pipe_clk", "pcie_1_pipe-clk", |
976 |
++ "pcie_0_pipe_clk", "pcie_1_pipe_clk", |
977 |
+ "ufs_phy_rx_symbol_0_clk", "ufs_phy_rx_symbol_1_clk", |
978 |
+ "ufs_phy_tx_symbol_0_clk", |
979 |
+ "usb3_phy_wrapper_gcc_usb30_pipe_clk"; |
980 |
+diff --git a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts |
981 |
+index 2ba23aa582a18..617a634ac9051 100644 |
982 |
+--- a/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts |
983 |
++++ b/arch/arm64/boot/dts/qcom/sdm850-lenovo-yoga-c630.dts |
984 |
+@@ -518,6 +518,10 @@ |
985 |
+ dai@1 { |
986 |
+ reg = <1>; |
987 |
+ }; |
988 |
++ |
989 |
++ dai@2 { |
990 |
++ reg = <2>; |
991 |
++ }; |
992 |
+ }; |
993 |
+ |
994 |
+ &sound { |
995 |
+@@ -530,6 +534,7 @@ |
996 |
+ "SpkrLeft IN", "SPK1 OUT", |
997 |
+ "SpkrRight IN", "SPK2 OUT", |
998 |
+ "MM_DL1", "MultiMedia1 Playback", |
999 |
++ "MM_DL3", "MultiMedia3 Playback", |
1000 |
+ "MultiMedia2 Capture", "MM_UL2"; |
1001 |
+ |
1002 |
+ mm1-dai-link { |
1003 |
+@@ -546,6 +551,13 @@ |
1004 |
+ }; |
1005 |
+ }; |
1006 |
+ |
1007 |
++ mm3-dai-link { |
1008 |
++ link-name = "MultiMedia3"; |
1009 |
++ cpu { |
1010 |
++ sound-dai = <&q6asmdai MSM_FRONTEND_DAI_MULTIMEDIA3>; |
1011 |
++ }; |
1012 |
++ }; |
1013 |
++ |
1014 |
+ slim-dai-link { |
1015 |
+ link-name = "SLIM Playback"; |
1016 |
+ cpu { |
1017 |
+@@ -575,6 +587,21 @@ |
1018 |
+ sound-dai = <&wcd9340 1>; |
1019 |
+ }; |
1020 |
+ }; |
1021 |
++ |
1022 |
++ slim-wcd-dai-link { |
1023 |
++ link-name = "SLIM WCD Playback"; |
1024 |
++ cpu { |
1025 |
++ sound-dai = <&q6afedai SLIMBUS_1_RX>; |
1026 |
++ }; |
1027 |
++ |
1028 |
++ platform { |
1029 |
++ sound-dai = <&q6routing>; |
1030 |
++ }; |
1031 |
++ |
1032 |
++ codec { |
1033 |
++ sound-dai = <&wcd9340 2>; |
1034 |
++ }; |
1035 |
++ }; |
1036 |
+ }; |
1037 |
+ |
1038 |
+ &tlmm { |
1039 |
+diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi |
1040 |
+index e91cd8a5e5356..296ffb0e9888c 100644 |
1041 |
+--- a/arch/arm64/boot/dts/qcom/sm8350.dtsi |
1042 |
++++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi |
1043 |
+@@ -2185,7 +2185,7 @@ |
1044 |
+ }; |
1045 |
+ }; |
1046 |
+ |
1047 |
+- camera-thermal-bottom { |
1048 |
++ cam-thermal-bottom { |
1049 |
+ polling-delay-passive = <250>; |
1050 |
+ polling-delay = <1000>; |
1051 |
+ |
1052 |
+diff --git a/arch/arm64/boot/dts/renesas/cat875.dtsi b/arch/arm64/boot/dts/renesas/cat875.dtsi |
1053 |
+index 801ea54b027c4..20f8adc635e72 100644 |
1054 |
+--- a/arch/arm64/boot/dts/renesas/cat875.dtsi |
1055 |
++++ b/arch/arm64/boot/dts/renesas/cat875.dtsi |
1056 |
+@@ -18,6 +18,7 @@ |
1057 |
+ pinctrl-names = "default"; |
1058 |
+ renesas,no-ether-link; |
1059 |
+ phy-handle = <&phy0>; |
1060 |
++ phy-mode = "rgmii-id"; |
1061 |
+ status = "okay"; |
1062 |
+ |
1063 |
+ phy0: ethernet-phy@0 { |
1064 |
+diff --git a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi |
1065 |
+index 6f4fffacfca21..e70aa5a087402 100644 |
1066 |
+--- a/arch/arm64/boot/dts/renesas/r8a774a1.dtsi |
1067 |
++++ b/arch/arm64/boot/dts/renesas/r8a774a1.dtsi |
1068 |
+@@ -2784,7 +2784,7 @@ |
1069 |
+ }; |
1070 |
+ |
1071 |
+ thermal-zones { |
1072 |
+- sensor_thermal1: sensor-thermal1 { |
1073 |
++ sensor1_thermal: sensor1-thermal { |
1074 |
+ polling-delay-passive = <250>; |
1075 |
+ polling-delay = <1000>; |
1076 |
+ thermal-sensors = <&tsc 0>; |
1077 |
+@@ -2799,7 +2799,7 @@ |
1078 |
+ }; |
1079 |
+ }; |
1080 |
+ |
1081 |
+- sensor_thermal2: sensor-thermal2 { |
1082 |
++ sensor2_thermal: sensor2-thermal { |
1083 |
+ polling-delay-passive = <250>; |
1084 |
+ polling-delay = <1000>; |
1085 |
+ thermal-sensors = <&tsc 1>; |
1086 |
+@@ -2814,7 +2814,7 @@ |
1087 |
+ }; |
1088 |
+ }; |
1089 |
+ |
1090 |
+- sensor_thermal3: sensor-thermal3 { |
1091 |
++ sensor3_thermal: sensor3-thermal { |
1092 |
+ polling-delay-passive = <250>; |
1093 |
+ polling-delay = <1000>; |
1094 |
+ thermal-sensors = <&tsc 2>; |
1095 |
+diff --git a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi |
1096 |
+index 0f7bdfc90a0dc..6c5694fa66900 100644 |
1097 |
+--- a/arch/arm64/boot/dts/renesas/r8a774b1.dtsi |
1098 |
++++ b/arch/arm64/boot/dts/renesas/r8a774b1.dtsi |
1099 |
+@@ -2629,7 +2629,7 @@ |
1100 |
+ }; |
1101 |
+ |
1102 |
+ thermal-zones { |
1103 |
+- sensor_thermal1: sensor-thermal1 { |
1104 |
++ sensor1_thermal: sensor1-thermal { |
1105 |
+ polling-delay-passive = <250>; |
1106 |
+ polling-delay = <1000>; |
1107 |
+ thermal-sensors = <&tsc 0>; |
1108 |
+@@ -2644,7 +2644,7 @@ |
1109 |
+ }; |
1110 |
+ }; |
1111 |
+ |
1112 |
+- sensor_thermal2: sensor-thermal2 { |
1113 |
++ sensor2_thermal: sensor2-thermal { |
1114 |
+ polling-delay-passive = <250>; |
1115 |
+ polling-delay = <1000>; |
1116 |
+ thermal-sensors = <&tsc 1>; |
1117 |
+@@ -2659,7 +2659,7 @@ |
1118 |
+ }; |
1119 |
+ }; |
1120 |
+ |
1121 |
+- sensor_thermal3: sensor-thermal3 { |
1122 |
++ sensor3_thermal: sensor3-thermal { |
1123 |
+ polling-delay-passive = <250>; |
1124 |
+ polling-delay = <1000>; |
1125 |
+ thermal-sensors = <&tsc 2>; |
1126 |
+diff --git a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi |
1127 |
+index 379a1300272ba..62209ab6deb9a 100644 |
1128 |
+--- a/arch/arm64/boot/dts/renesas/r8a774e1.dtsi |
1129 |
++++ b/arch/arm64/boot/dts/renesas/r8a774e1.dtsi |
1130 |
+@@ -2904,7 +2904,7 @@ |
1131 |
+ }; |
1132 |
+ |
1133 |
+ thermal-zones { |
1134 |
+- sensor_thermal1: sensor-thermal1 { |
1135 |
++ sensor1_thermal: sensor1-thermal { |
1136 |
+ polling-delay-passive = <250>; |
1137 |
+ polling-delay = <1000>; |
1138 |
+ thermal-sensors = <&tsc 0>; |
1139 |
+@@ -2919,7 +2919,7 @@ |
1140 |
+ }; |
1141 |
+ }; |
1142 |
+ |
1143 |
+- sensor_thermal2: sensor-thermal2 { |
1144 |
++ sensor2_thermal: sensor2-thermal { |
1145 |
+ polling-delay-passive = <250>; |
1146 |
+ polling-delay = <1000>; |
1147 |
+ thermal-sensors = <&tsc 1>; |
1148 |
+@@ -2934,7 +2934,7 @@ |
1149 |
+ }; |
1150 |
+ }; |
1151 |
+ |
1152 |
+- sensor_thermal3: sensor-thermal3 { |
1153 |
++ sensor3_thermal: sensor3-thermal { |
1154 |
+ polling-delay-passive = <250>; |
1155 |
+ polling-delay = <1000>; |
1156 |
+ thermal-sensors = <&tsc 2>; |
1157 |
+diff --git a/arch/arm64/boot/dts/renesas/r8a77951.dtsi b/arch/arm64/boot/dts/renesas/r8a77951.dtsi |
1158 |
+index 1768a3e6bb8da..193d81be40fc4 100644 |
1159 |
+--- a/arch/arm64/boot/dts/renesas/r8a77951.dtsi |
1160 |
++++ b/arch/arm64/boot/dts/renesas/r8a77951.dtsi |
1161 |
+@@ -3375,7 +3375,7 @@ |
1162 |
+ }; |
1163 |
+ |
1164 |
+ thermal-zones { |
1165 |
+- sensor_thermal1: sensor-thermal1 { |
1166 |
++ sensor1_thermal: sensor1-thermal { |
1167 |
+ polling-delay-passive = <250>; |
1168 |
+ polling-delay = <1000>; |
1169 |
+ thermal-sensors = <&tsc 0>; |
1170 |
+@@ -3390,7 +3390,7 @@ |
1171 |
+ }; |
1172 |
+ }; |
1173 |
+ |
1174 |
+- sensor_thermal2: sensor-thermal2 { |
1175 |
++ sensor2_thermal: sensor2-thermal { |
1176 |
+ polling-delay-passive = <250>; |
1177 |
+ polling-delay = <1000>; |
1178 |
+ thermal-sensors = <&tsc 1>; |
1179 |
+@@ -3405,7 +3405,7 @@ |
1180 |
+ }; |
1181 |
+ }; |
1182 |
+ |
1183 |
+- sensor_thermal3: sensor-thermal3 { |
1184 |
++ sensor3_thermal: sensor3-thermal { |
1185 |
+ polling-delay-passive = <250>; |
1186 |
+ polling-delay = <1000>; |
1187 |
+ thermal-sensors = <&tsc 2>; |
1188 |
+diff --git a/arch/arm64/boot/dts/renesas/r8a77960.dtsi b/arch/arm64/boot/dts/renesas/r8a77960.dtsi |
1189 |
+index 2bd8169735d35..b526e4f0ee6a8 100644 |
1190 |
+--- a/arch/arm64/boot/dts/renesas/r8a77960.dtsi |
1191 |
++++ b/arch/arm64/boot/dts/renesas/r8a77960.dtsi |
1192 |
+@@ -2972,7 +2972,7 @@ |
1193 |
+ }; |
1194 |
+ |
1195 |
+ thermal-zones { |
1196 |
+- sensor_thermal1: sensor-thermal1 { |
1197 |
++ sensor1_thermal: sensor1-thermal { |
1198 |
+ polling-delay-passive = <250>; |
1199 |
+ polling-delay = <1000>; |
1200 |
+ thermal-sensors = <&tsc 0>; |
1201 |
+@@ -2987,7 +2987,7 @@ |
1202 |
+ }; |
1203 |
+ }; |
1204 |
+ |
1205 |
+- sensor_thermal2: sensor-thermal2 { |
1206 |
++ sensor2_thermal: sensor2-thermal { |
1207 |
+ polling-delay-passive = <250>; |
1208 |
+ polling-delay = <1000>; |
1209 |
+ thermal-sensors = <&tsc 1>; |
1210 |
+@@ -3002,7 +3002,7 @@ |
1211 |
+ }; |
1212 |
+ }; |
1213 |
+ |
1214 |
+- sensor_thermal3: sensor-thermal3 { |
1215 |
++ sensor3_thermal: sensor3-thermal { |
1216 |
+ polling-delay-passive = <250>; |
1217 |
+ polling-delay = <1000>; |
1218 |
+ thermal-sensors = <&tsc 2>; |
1219 |
+diff --git a/arch/arm64/boot/dts/renesas/r8a77961.dtsi b/arch/arm64/boot/dts/renesas/r8a77961.dtsi |
1220 |
+index 041473aa5cd09..21fc95397c3c2 100644 |
1221 |
+--- a/arch/arm64/boot/dts/renesas/r8a77961.dtsi |
1222 |
++++ b/arch/arm64/boot/dts/renesas/r8a77961.dtsi |
1223 |
+@@ -2719,7 +2719,7 @@ |
1224 |
+ }; |
1225 |
+ |
1226 |
+ thermal-zones { |
1227 |
+- sensor_thermal1: sensor-thermal1 { |
1228 |
++ sensor1_thermal: sensor1-thermal { |
1229 |
+ polling-delay-passive = <250>; |
1230 |
+ polling-delay = <1000>; |
1231 |
+ thermal-sensors = <&tsc 0>; |
1232 |
+@@ -2734,7 +2734,7 @@ |
1233 |
+ }; |
1234 |
+ }; |
1235 |
+ |
1236 |
+- sensor_thermal2: sensor-thermal2 { |
1237 |
++ sensor2_thermal: sensor2-thermal { |
1238 |
+ polling-delay-passive = <250>; |
1239 |
+ polling-delay = <1000>; |
1240 |
+ thermal-sensors = <&tsc 1>; |
1241 |
+@@ -2749,7 +2749,7 @@ |
1242 |
+ }; |
1243 |
+ }; |
1244 |
+ |
1245 |
+- sensor_thermal3: sensor-thermal3 { |
1246 |
++ sensor3_thermal: sensor3-thermal { |
1247 |
+ polling-delay-passive = <250>; |
1248 |
+ polling-delay = <1000>; |
1249 |
+ thermal-sensors = <&tsc 2>; |
1250 |
+diff --git a/arch/arm64/boot/dts/renesas/r8a77965.dtsi b/arch/arm64/boot/dts/renesas/r8a77965.dtsi |
1251 |
+index 08df75606430b..f9679a4dd85fa 100644 |
1252 |
+--- a/arch/arm64/boot/dts/renesas/r8a77965.dtsi |
1253 |
++++ b/arch/arm64/boot/dts/renesas/r8a77965.dtsi |
1254 |
+@@ -2784,7 +2784,7 @@ |
1255 |
+ }; |
1256 |
+ |
1257 |
+ thermal-zones { |
1258 |
+- sensor_thermal1: sensor-thermal1 { |
1259 |
++ sensor1_thermal: sensor1-thermal { |
1260 |
+ polling-delay-passive = <250>; |
1261 |
+ polling-delay = <1000>; |
1262 |
+ thermal-sensors = <&tsc 0>; |
1263 |
+@@ -2799,7 +2799,7 @@ |
1264 |
+ }; |
1265 |
+ }; |
1266 |
+ |
1267 |
+- sensor_thermal2: sensor-thermal2 { |
1268 |
++ sensor2_thermal: sensor2-thermal { |
1269 |
+ polling-delay-passive = <250>; |
1270 |
+ polling-delay = <1000>; |
1271 |
+ thermal-sensors = <&tsc 1>; |
1272 |
+@@ -2814,7 +2814,7 @@ |
1273 |
+ }; |
1274 |
+ }; |
1275 |
+ |
1276 |
+- sensor_thermal3: sensor-thermal3 { |
1277 |
++ sensor3_thermal: sensor3-thermal { |
1278 |
+ polling-delay-passive = <250>; |
1279 |
+ polling-delay = <1000>; |
1280 |
+ thermal-sensors = <&tsc 2>; |
1281 |
+diff --git a/arch/arm64/boot/dts/renesas/r8a77980.dtsi b/arch/arm64/boot/dts/renesas/r8a77980.dtsi |
1282 |
+index 6347d15e66b64..21fe602bd25af 100644 |
1283 |
+--- a/arch/arm64/boot/dts/renesas/r8a77980.dtsi |
1284 |
++++ b/arch/arm64/boot/dts/renesas/r8a77980.dtsi |
1285 |
+@@ -1580,7 +1580,7 @@ |
1286 |
+ }; |
1287 |
+ |
1288 |
+ thermal-zones { |
1289 |
+- thermal-sensor-1 { |
1290 |
++ sensor1_thermal: sensor1-thermal { |
1291 |
+ polling-delay-passive = <250>; |
1292 |
+ polling-delay = <1000>; |
1293 |
+ thermal-sensors = <&tsc 0>; |
1294 |
+@@ -1599,7 +1599,7 @@ |
1295 |
+ }; |
1296 |
+ }; |
1297 |
+ |
1298 |
+- thermal-sensor-2 { |
1299 |
++ sensor2_thermal: sensor2-thermal { |
1300 |
+ polling-delay-passive = <250>; |
1301 |
+ polling-delay = <1000>; |
1302 |
+ thermal-sensors = <&tsc 1>; |
1303 |
+diff --git a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi |
1304 |
+index 631d520cebee5..26899fb768a73 100644 |
1305 |
+--- a/arch/arm64/boot/dts/renesas/r8a779a0.dtsi |
1306 |
++++ b/arch/arm64/boot/dts/renesas/r8a779a0.dtsi |
1307 |
+@@ -1149,7 +1149,7 @@ |
1308 |
+ }; |
1309 |
+ |
1310 |
+ thermal-zones { |
1311 |
+- sensor_thermal1: sensor-thermal1 { |
1312 |
++ sensor1_thermal: sensor1-thermal { |
1313 |
+ polling-delay-passive = <250>; |
1314 |
+ polling-delay = <1000>; |
1315 |
+ thermal-sensors = <&tsc 0>; |
1316 |
+@@ -1163,7 +1163,7 @@ |
1317 |
+ }; |
1318 |
+ }; |
1319 |
+ |
1320 |
+- sensor_thermal2: sensor-thermal2 { |
1321 |
++ sensor2_thermal: sensor2-thermal { |
1322 |
+ polling-delay-passive = <250>; |
1323 |
+ polling-delay = <1000>; |
1324 |
+ thermal-sensors = <&tsc 1>; |
1325 |
+@@ -1177,7 +1177,7 @@ |
1326 |
+ }; |
1327 |
+ }; |
1328 |
+ |
1329 |
+- sensor_thermal3: sensor-thermal3 { |
1330 |
++ sensor3_thermal: sensor3-thermal { |
1331 |
+ polling-delay-passive = <250>; |
1332 |
+ polling-delay = <1000>; |
1333 |
+ thermal-sensors = <&tsc 2>; |
1334 |
+@@ -1191,7 +1191,7 @@ |
1335 |
+ }; |
1336 |
+ }; |
1337 |
+ |
1338 |
+- sensor_thermal4: sensor-thermal4 { |
1339 |
++ sensor4_thermal: sensor4-thermal { |
1340 |
+ polling-delay-passive = <250>; |
1341 |
+ polling-delay = <1000>; |
1342 |
+ thermal-sensors = <&tsc 3>; |
1343 |
+@@ -1205,7 +1205,7 @@ |
1344 |
+ }; |
1345 |
+ }; |
1346 |
+ |
1347 |
+- sensor_thermal5: sensor-thermal5 { |
1348 |
++ sensor5_thermal: sensor5-thermal { |
1349 |
+ polling-delay-passive = <250>; |
1350 |
+ polling-delay = <1000>; |
1351 |
+ thermal-sensors = <&tsc 4>; |
1352 |
+diff --git a/arch/arm64/boot/dts/ti/k3-am642.dtsi b/arch/arm64/boot/dts/ti/k3-am642.dtsi |
1353 |
+index e2b397c884018..8a76f4821b11b 100644 |
1354 |
+--- a/arch/arm64/boot/dts/ti/k3-am642.dtsi |
1355 |
++++ b/arch/arm64/boot/dts/ti/k3-am642.dtsi |
1356 |
+@@ -60,6 +60,6 @@ |
1357 |
+ cache-level = <2>; |
1358 |
+ cache-size = <0x40000>; |
1359 |
+ cache-line-size = <64>; |
1360 |
+- cache-sets = <512>; |
1361 |
++ cache-sets = <256>; |
1362 |
+ }; |
1363 |
+ }; |
1364 |
+diff --git a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi |
1365 |
+index 874cba75e9a5a..7daa280220442 100644 |
1366 |
+--- a/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi |
1367 |
++++ b/arch/arm64/boot/dts/ti/k3-j7200-main.dtsi |
1368 |
+@@ -32,7 +32,7 @@ |
1369 |
+ #size-cells = <1>; |
1370 |
+ ranges = <0x00 0x00 0x00100000 0x1c000>; |
1371 |
+ |
1372 |
+- serdes_ln_ctrl: serdes-ln-ctrl@4080 { |
1373 |
++ serdes_ln_ctrl: mux-controller@4080 { |
1374 |
+ compatible = "mmio-mux"; |
1375 |
+ #mux-control-cells = <1>; |
1376 |
+ mux-reg-masks = <0x4080 0x3>, <0x4084 0x3>, /* SERDES0 lane0/1 select */ |
1377 |
+diff --git a/arch/arm64/boot/dts/ti/k3-j7200.dtsi b/arch/arm64/boot/dts/ti/k3-j7200.dtsi |
1378 |
+index b7005b8031495..7586b5aea446f 100644 |
1379 |
+--- a/arch/arm64/boot/dts/ti/k3-j7200.dtsi |
1380 |
++++ b/arch/arm64/boot/dts/ti/k3-j7200.dtsi |
1381 |
+@@ -60,7 +60,7 @@ |
1382 |
+ i-cache-sets = <256>; |
1383 |
+ d-cache-size = <0x8000>; |
1384 |
+ d-cache-line-size = <64>; |
1385 |
+- d-cache-sets = <128>; |
1386 |
++ d-cache-sets = <256>; |
1387 |
+ next-level-cache = <&L2_0>; |
1388 |
+ }; |
1389 |
+ |
1390 |
+@@ -74,7 +74,7 @@ |
1391 |
+ i-cache-sets = <256>; |
1392 |
+ d-cache-size = <0x8000>; |
1393 |
+ d-cache-line-size = <64>; |
1394 |
+- d-cache-sets = <128>; |
1395 |
++ d-cache-sets = <256>; |
1396 |
+ next-level-cache = <&L2_0>; |
1397 |
+ }; |
1398 |
+ }; |
1399 |
+@@ -84,7 +84,7 @@ |
1400 |
+ cache-level = <2>; |
1401 |
+ cache-size = <0x100000>; |
1402 |
+ cache-line-size = <64>; |
1403 |
+- cache-sets = <2048>; |
1404 |
++ cache-sets = <1024>; |
1405 |
+ next-level-cache = <&msmc_l3>; |
1406 |
+ }; |
1407 |
+ |
1408 |
+diff --git a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi |
1409 |
+index 08c8d1b47dcd9..e85c89eebfa31 100644 |
1410 |
+--- a/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi |
1411 |
++++ b/arch/arm64/boot/dts/ti/k3-j721e-main.dtsi |
1412 |
+@@ -42,7 +42,7 @@ |
1413 |
+ #size-cells = <1>; |
1414 |
+ ranges = <0x0 0x0 0x00100000 0x1c000>; |
1415 |
+ |
1416 |
+- serdes_ln_ctrl: mux@4080 { |
1417 |
++ serdes_ln_ctrl: mux-controller@4080 { |
1418 |
+ compatible = "mmio-mux"; |
1419 |
+ reg = <0x00004080 0x50>; |
1420 |
+ #mux-control-cells = <1>; |
1421 |
+diff --git a/arch/arm64/boot/dts/ti/k3-j721e.dtsi b/arch/arm64/boot/dts/ti/k3-j721e.dtsi |
1422 |
+index f0587fde147e6..69ce048a2136e 100644 |
1423 |
+--- a/arch/arm64/boot/dts/ti/k3-j721e.dtsi |
1424 |
++++ b/arch/arm64/boot/dts/ti/k3-j721e.dtsi |
1425 |
+@@ -61,7 +61,7 @@ |
1426 |
+ i-cache-sets = <256>; |
1427 |
+ d-cache-size = <0x8000>; |
1428 |
+ d-cache-line-size = <64>; |
1429 |
+- d-cache-sets = <128>; |
1430 |
++ d-cache-sets = <256>; |
1431 |
+ next-level-cache = <&L2_0>; |
1432 |
+ }; |
1433 |
+ |
1434 |
+@@ -75,7 +75,7 @@ |
1435 |
+ i-cache-sets = <256>; |
1436 |
+ d-cache-size = <0x8000>; |
1437 |
+ d-cache-line-size = <64>; |
1438 |
+- d-cache-sets = <128>; |
1439 |
++ d-cache-sets = <256>; |
1440 |
+ next-level-cache = <&L2_0>; |
1441 |
+ }; |
1442 |
+ }; |
1443 |
+@@ -85,7 +85,7 @@ |
1444 |
+ cache-level = <2>; |
1445 |
+ cache-size = <0x100000>; |
1446 |
+ cache-line-size = <64>; |
1447 |
+- cache-sets = <2048>; |
1448 |
++ cache-sets = <1024>; |
1449 |
+ next-level-cache = <&msmc_l3>; |
1450 |
+ }; |
1451 |
+ |
1452 |
+diff --git a/arch/arm64/include/asm/mte-kasan.h b/arch/arm64/include/asm/mte-kasan.h |
1453 |
+index 22420e1f8c037..26e013e540ae2 100644 |
1454 |
+--- a/arch/arm64/include/asm/mte-kasan.h |
1455 |
++++ b/arch/arm64/include/asm/mte-kasan.h |
1456 |
+@@ -84,10 +84,12 @@ static inline void __dc_gzva(u64 p) |
1457 |
+ static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag, |
1458 |
+ bool init) |
1459 |
+ { |
1460 |
+- u64 curr, mask, dczid_bs, end1, end2, end3; |
1461 |
++ u64 curr, mask, dczid, dczid_bs, dczid_dzp, end1, end2, end3; |
1462 |
+ |
1463 |
+ /* Read DC G(Z)VA block size from the system register. */ |
1464 |
+- dczid_bs = 4ul << (read_cpuid(DCZID_EL0) & 0xf); |
1465 |
++ dczid = read_cpuid(DCZID_EL0); |
1466 |
++ dczid_bs = 4ul << (dczid & 0xf); |
1467 |
++ dczid_dzp = (dczid >> 4) & 1; |
1468 |
+ |
1469 |
+ curr = (u64)__tag_set(addr, tag); |
1470 |
+ mask = dczid_bs - 1; |
1471 |
+@@ -106,7 +108,7 @@ static inline void mte_set_mem_tag_range(void *addr, size_t size, u8 tag, |
1472 |
+ */ |
1473 |
+ #define SET_MEMTAG_RANGE(stg_post, dc_gva) \ |
1474 |
+ do { \ |
1475 |
+- if (size >= 2 * dczid_bs) { \ |
1476 |
++ if (!dczid_dzp && size >= 2 * dczid_bs) {\ |
1477 |
+ do { \ |
1478 |
+ curr = stg_post(curr); \ |
1479 |
+ } while (curr < end1); \ |
1480 |
+diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c |
1481 |
+index 40adb8cdbf5af..23efabcb00b85 100644 |
1482 |
+--- a/arch/arm64/kernel/process.c |
1483 |
++++ b/arch/arm64/kernel/process.c |
1484 |
+@@ -439,34 +439,26 @@ static void entry_task_switch(struct task_struct *next) |
1485 |
+ |
1486 |
+ /* |
1487 |
+ * ARM erratum 1418040 handling, affecting the 32bit view of CNTVCT. |
1488 |
+- * Assuming the virtual counter is enabled at the beginning of times: |
1489 |
+- * |
1490 |
+- * - disable access when switching from a 64bit task to a 32bit task |
1491 |
+- * - enable access when switching from a 32bit task to a 64bit task |
1492 |
++ * Ensure access is disabled when switching to a 32bit task, ensure |
1493 |
++ * access is enabled when switching to a 64bit task. |
1494 |
+ */ |
1495 |
+-static void erratum_1418040_thread_switch(struct task_struct *prev, |
1496 |
+- struct task_struct *next) |
1497 |
++static void erratum_1418040_thread_switch(struct task_struct *next) |
1498 |
+ { |
1499 |
+- bool prev32, next32; |
1500 |
+- u64 val; |
1501 |
+- |
1502 |
+- if (!IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040)) |
1503 |
+- return; |
1504 |
+- |
1505 |
+- prev32 = is_compat_thread(task_thread_info(prev)); |
1506 |
+- next32 = is_compat_thread(task_thread_info(next)); |
1507 |
+- |
1508 |
+- if (prev32 == next32 || !this_cpu_has_cap(ARM64_WORKAROUND_1418040)) |
1509 |
++ if (!IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040) || |
1510 |
++ !this_cpu_has_cap(ARM64_WORKAROUND_1418040)) |
1511 |
+ return; |
1512 |
+ |
1513 |
+- val = read_sysreg(cntkctl_el1); |
1514 |
+- |
1515 |
+- if (!next32) |
1516 |
+- val |= ARCH_TIMER_USR_VCT_ACCESS_EN; |
1517 |
++ if (is_compat_thread(task_thread_info(next))) |
1518 |
++ sysreg_clear_set(cntkctl_el1, ARCH_TIMER_USR_VCT_ACCESS_EN, 0); |
1519 |
+ else |
1520 |
+- val &= ~ARCH_TIMER_USR_VCT_ACCESS_EN; |
1521 |
++ sysreg_clear_set(cntkctl_el1, 0, ARCH_TIMER_USR_VCT_ACCESS_EN); |
1522 |
++} |
1523 |
+ |
1524 |
+- write_sysreg(val, cntkctl_el1); |
1525 |
++static void erratum_1418040_new_exec(void) |
1526 |
++{ |
1527 |
++ preempt_disable(); |
1528 |
++ erratum_1418040_thread_switch(current); |
1529 |
++ preempt_enable(); |
1530 |
+ } |
1531 |
+ |
1532 |
+ /* |
1533 |
+@@ -501,7 +493,7 @@ __notrace_funcgraph struct task_struct *__switch_to(struct task_struct *prev, |
1534 |
+ contextidr_thread_switch(next); |
1535 |
+ entry_task_switch(next); |
1536 |
+ ssbs_thread_switch(next); |
1537 |
+- erratum_1418040_thread_switch(prev, next); |
1538 |
++ erratum_1418040_thread_switch(next); |
1539 |
+ ptrauth_thread_switch_user(next); |
1540 |
+ |
1541 |
+ /* |
1542 |
+@@ -613,6 +605,7 @@ void arch_setup_new_exec(void) |
1543 |
+ current->mm->context.flags = mmflags; |
1544 |
+ ptrauth_thread_init_user(); |
1545 |
+ mte_thread_init_user(); |
1546 |
++ erratum_1418040_new_exec(); |
1547 |
+ |
1548 |
+ if (task_spec_ssb_noexec(current)) { |
1549 |
+ arch_prctl_spec_ctrl_set(current, PR_SPEC_STORE_BYPASS, |
1550 |
+diff --git a/arch/arm64/lib/clear_page.S b/arch/arm64/lib/clear_page.S |
1551 |
+index b84b179edba3a..1fd5d790ab800 100644 |
1552 |
+--- a/arch/arm64/lib/clear_page.S |
1553 |
++++ b/arch/arm64/lib/clear_page.S |
1554 |
+@@ -16,6 +16,7 @@ |
1555 |
+ */ |
1556 |
+ SYM_FUNC_START_PI(clear_page) |
1557 |
+ mrs x1, dczid_el0 |
1558 |
++ tbnz x1, #4, 2f /* Branch if DC ZVA is prohibited */ |
1559 |
+ and w1, w1, #0xf |
1560 |
+ mov x2, #4 |
1561 |
+ lsl x1, x2, x1 |
1562 |
+@@ -25,5 +26,14 @@ SYM_FUNC_START_PI(clear_page) |
1563 |
+ tst x0, #(PAGE_SIZE - 1) |
1564 |
+ b.ne 1b |
1565 |
+ ret |
1566 |
++ |
1567 |
++2: stnp xzr, xzr, [x0] |
1568 |
++ stnp xzr, xzr, [x0, #16] |
1569 |
++ stnp xzr, xzr, [x0, #32] |
1570 |
++ stnp xzr, xzr, [x0, #48] |
1571 |
++ add x0, x0, #64 |
1572 |
++ tst x0, #(PAGE_SIZE - 1) |
1573 |
++ b.ne 2b |
1574 |
++ ret |
1575 |
+ SYM_FUNC_END_PI(clear_page) |
1576 |
+ EXPORT_SYMBOL(clear_page) |
1577 |
+diff --git a/arch/arm64/lib/mte.S b/arch/arm64/lib/mte.S |
1578 |
+index e83643b3995f4..f531dcb95174a 100644 |
1579 |
+--- a/arch/arm64/lib/mte.S |
1580 |
++++ b/arch/arm64/lib/mte.S |
1581 |
+@@ -43,17 +43,23 @@ SYM_FUNC_END(mte_clear_page_tags) |
1582 |
+ * x0 - address to the beginning of the page |
1583 |
+ */ |
1584 |
+ SYM_FUNC_START(mte_zero_clear_page_tags) |
1585 |
++ and x0, x0, #(1 << MTE_TAG_SHIFT) - 1 // clear the tag |
1586 |
+ mrs x1, dczid_el0 |
1587 |
++ tbnz x1, #4, 2f // Branch if DC GZVA is prohibited |
1588 |
+ and w1, w1, #0xf |
1589 |
+ mov x2, #4 |
1590 |
+ lsl x1, x2, x1 |
1591 |
+- and x0, x0, #(1 << MTE_TAG_SHIFT) - 1 // clear the tag |
1592 |
+ |
1593 |
+ 1: dc gzva, x0 |
1594 |
+ add x0, x0, x1 |
1595 |
+ tst x0, #(PAGE_SIZE - 1) |
1596 |
+ b.ne 1b |
1597 |
+ ret |
1598 |
++ |
1599 |
++2: stz2g x0, [x0], #(MTE_GRANULE_SIZE * 2) |
1600 |
++ tst x0, #(PAGE_SIZE - 1) |
1601 |
++ b.ne 2b |
1602 |
++ ret |
1603 |
+ SYM_FUNC_END(mte_zero_clear_page_tags) |
1604 |
+ |
1605 |
+ /* |
1606 |
+diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig |
1607 |
+index 23654ccdbfb12..393eb2133243f 100644 |
1608 |
+--- a/arch/mips/Kconfig |
1609 |
++++ b/arch/mips/Kconfig |
1610 |
+@@ -1993,6 +1993,10 @@ config SYS_HAS_CPU_MIPS64_R1 |
1611 |
+ config SYS_HAS_CPU_MIPS64_R2 |
1612 |
+ bool |
1613 |
+ |
1614 |
++config SYS_HAS_CPU_MIPS64_R5 |
1615 |
++ bool |
1616 |
++ select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT |
1617 |
++ |
1618 |
+ config SYS_HAS_CPU_MIPS64_R6 |
1619 |
+ bool |
1620 |
+ select ARCH_HAS_SYNC_DMA_FOR_CPU if DMA_NONCOHERENT |
1621 |
+@@ -2157,7 +2161,7 @@ config CPU_SUPPORTS_ADDRWINCFG |
1622 |
+ bool |
1623 |
+ config CPU_SUPPORTS_HUGEPAGES |
1624 |
+ bool |
1625 |
+- depends on !(32BIT && (ARCH_PHYS_ADDR_T_64BIT || EVA)) |
1626 |
++ depends on !(32BIT && (PHYS_ADDR_T_64BIT || EVA)) |
1627 |
+ config MIPS_PGD_C0_CONTEXT |
1628 |
+ bool |
1629 |
+ depends on 64BIT |
1630 |
+diff --git a/arch/mips/bcm63xx/clk.c b/arch/mips/bcm63xx/clk.c |
1631 |
+index 1c91064cb448b..6e6756e8fa0a9 100644 |
1632 |
+--- a/arch/mips/bcm63xx/clk.c |
1633 |
++++ b/arch/mips/bcm63xx/clk.c |
1634 |
+@@ -387,6 +387,12 @@ struct clk *clk_get_parent(struct clk *clk) |
1635 |
+ } |
1636 |
+ EXPORT_SYMBOL(clk_get_parent); |
1637 |
+ |
1638 |
++int clk_set_parent(struct clk *clk, struct clk *parent) |
1639 |
++{ |
1640 |
++ return 0; |
1641 |
++} |
1642 |
++EXPORT_SYMBOL(clk_set_parent); |
1643 |
++ |
1644 |
+ unsigned long clk_get_rate(struct clk *clk) |
1645 |
+ { |
1646 |
+ if (!clk) |
1647 |
+diff --git a/arch/mips/boot/compressed/Makefile b/arch/mips/boot/compressed/Makefile |
1648 |
+index 9112bdb86be45..705b9e7f8035a 100644 |
1649 |
+--- a/arch/mips/boot/compressed/Makefile |
1650 |
++++ b/arch/mips/boot/compressed/Makefile |
1651 |
+@@ -56,7 +56,7 @@ $(obj)/uart-ath79.c: $(srctree)/arch/mips/ath79/early_printk.c |
1652 |
+ |
1653 |
+ vmlinuzobjs-$(CONFIG_KERNEL_XZ) += $(obj)/ashldi3.o |
1654 |
+ |
1655 |
+-vmlinuzobjs-$(CONFIG_KERNEL_ZSTD) += $(obj)/bswapdi.o |
1656 |
++vmlinuzobjs-$(CONFIG_KERNEL_ZSTD) += $(obj)/bswapdi.o $(obj)/ashldi3.o $(obj)/clz_ctz.o |
1657 |
+ |
1658 |
+ extra-y += ashldi3.c |
1659 |
+ $(obj)/ashldi3.c: $(obj)/%.c: $(srctree)/lib/%.c FORCE |
1660 |
+diff --git a/arch/mips/boot/compressed/clz_ctz.c b/arch/mips/boot/compressed/clz_ctz.c |
1661 |
+new file mode 100644 |
1662 |
+index 0000000000000..b4a1b6eb2f8ad |
1663 |
+--- /dev/null |
1664 |
++++ b/arch/mips/boot/compressed/clz_ctz.c |
1665 |
+@@ -0,0 +1,2 @@ |
1666 |
++// SPDX-License-Identifier: GPL-2.0-only |
1667 |
++#include "../../../../lib/clz_ctz.c" |
1668 |
+diff --git a/arch/mips/cavium-octeon/octeon-platform.c b/arch/mips/cavium-octeon/octeon-platform.c |
1669 |
+index d56e9b9d2e434..a994022e32c9f 100644 |
1670 |
+--- a/arch/mips/cavium-octeon/octeon-platform.c |
1671 |
++++ b/arch/mips/cavium-octeon/octeon-platform.c |
1672 |
+@@ -328,6 +328,7 @@ static int __init octeon_ehci_device_init(void) |
1673 |
+ |
1674 |
+ pd->dev.platform_data = &octeon_ehci_pdata; |
1675 |
+ octeon_ehci_hw_start(&pd->dev); |
1676 |
++ put_device(&pd->dev); |
1677 |
+ |
1678 |
+ return ret; |
1679 |
+ } |
1680 |
+@@ -391,6 +392,7 @@ static int __init octeon_ohci_device_init(void) |
1681 |
+ |
1682 |
+ pd->dev.platform_data = &octeon_ohci_pdata; |
1683 |
+ octeon_ohci_hw_start(&pd->dev); |
1684 |
++ put_device(&pd->dev); |
1685 |
+ |
1686 |
+ return ret; |
1687 |
+ } |
1688 |
+diff --git a/arch/mips/cavium-octeon/octeon-usb.c b/arch/mips/cavium-octeon/octeon-usb.c |
1689 |
+index 6e4d3619137af..4df919d26b082 100644 |
1690 |
+--- a/arch/mips/cavium-octeon/octeon-usb.c |
1691 |
++++ b/arch/mips/cavium-octeon/octeon-usb.c |
1692 |
+@@ -537,6 +537,7 @@ static int __init dwc3_octeon_device_init(void) |
1693 |
+ devm_iounmap(&pdev->dev, base); |
1694 |
+ devm_release_mem_region(&pdev->dev, res->start, |
1695 |
+ resource_size(res)); |
1696 |
++ put_device(&pdev->dev); |
1697 |
+ } |
1698 |
+ } while (node != NULL); |
1699 |
+ |
1700 |
+diff --git a/arch/mips/configs/fuloong2e_defconfig b/arch/mips/configs/fuloong2e_defconfig |
1701 |
+index 5c24ac7fdf56d..ba47c5e929b7f 100644 |
1702 |
+--- a/arch/mips/configs/fuloong2e_defconfig |
1703 |
++++ b/arch/mips/configs/fuloong2e_defconfig |
1704 |
+@@ -206,7 +206,6 @@ CONFIG_NFSD_V3_ACL=y |
1705 |
+ CONFIG_NFSD_V4=y |
1706 |
+ CONFIG_CIFS=m |
1707 |
+ CONFIG_CIFS_STATS2=y |
1708 |
+-CONFIG_CIFS_WEAK_PW_HASH=y |
1709 |
+ CONFIG_CIFS_XATTR=y |
1710 |
+ CONFIG_CIFS_POSIX=y |
1711 |
+ CONFIG_CIFS_DEBUG2=y |
1712 |
+diff --git a/arch/mips/configs/malta_qemu_32r6_defconfig b/arch/mips/configs/malta_qemu_32r6_defconfig |
1713 |
+index 614af02d83e6e..6fb9bc29f4a03 100644 |
1714 |
+--- a/arch/mips/configs/malta_qemu_32r6_defconfig |
1715 |
++++ b/arch/mips/configs/malta_qemu_32r6_defconfig |
1716 |
+@@ -165,7 +165,6 @@ CONFIG_TMPFS=y |
1717 |
+ CONFIG_NFS_FS=y |
1718 |
+ CONFIG_ROOT_NFS=y |
1719 |
+ CONFIG_CIFS=m |
1720 |
+-CONFIG_CIFS_WEAK_PW_HASH=y |
1721 |
+ CONFIG_CIFS_XATTR=y |
1722 |
+ CONFIG_CIFS_POSIX=y |
1723 |
+ CONFIG_NLS_CODEPAGE_437=m |
1724 |
+diff --git a/arch/mips/configs/maltaaprp_defconfig b/arch/mips/configs/maltaaprp_defconfig |
1725 |
+index 9c051f8fd3300..eb72df528243a 100644 |
1726 |
+--- a/arch/mips/configs/maltaaprp_defconfig |
1727 |
++++ b/arch/mips/configs/maltaaprp_defconfig |
1728 |
+@@ -166,7 +166,6 @@ CONFIG_TMPFS=y |
1729 |
+ CONFIG_NFS_FS=y |
1730 |
+ CONFIG_ROOT_NFS=y |
1731 |
+ CONFIG_CIFS=m |
1732 |
+-CONFIG_CIFS_WEAK_PW_HASH=y |
1733 |
+ CONFIG_CIFS_XATTR=y |
1734 |
+ CONFIG_CIFS_POSIX=y |
1735 |
+ CONFIG_NLS_CODEPAGE_437=m |
1736 |
+diff --git a/arch/mips/configs/maltasmvp_defconfig b/arch/mips/configs/maltasmvp_defconfig |
1737 |
+index 2e90d97551d6f..1fb40d310f49c 100644 |
1738 |
+--- a/arch/mips/configs/maltasmvp_defconfig |
1739 |
++++ b/arch/mips/configs/maltasmvp_defconfig |
1740 |
+@@ -167,7 +167,6 @@ CONFIG_TMPFS=y |
1741 |
+ CONFIG_NFS_FS=y |
1742 |
+ CONFIG_ROOT_NFS=y |
1743 |
+ CONFIG_CIFS=m |
1744 |
+-CONFIG_CIFS_WEAK_PW_HASH=y |
1745 |
+ CONFIG_CIFS_XATTR=y |
1746 |
+ CONFIG_CIFS_POSIX=y |
1747 |
+ CONFIG_NLS_CODEPAGE_437=m |
1748 |
+diff --git a/arch/mips/configs/maltasmvp_eva_defconfig b/arch/mips/configs/maltasmvp_eva_defconfig |
1749 |
+index d1f7fdb27284b..75cb778c61496 100644 |
1750 |
+--- a/arch/mips/configs/maltasmvp_eva_defconfig |
1751 |
++++ b/arch/mips/configs/maltasmvp_eva_defconfig |
1752 |
+@@ -169,7 +169,6 @@ CONFIG_TMPFS=y |
1753 |
+ CONFIG_NFS_FS=y |
1754 |
+ CONFIG_ROOT_NFS=y |
1755 |
+ CONFIG_CIFS=m |
1756 |
+-CONFIG_CIFS_WEAK_PW_HASH=y |
1757 |
+ CONFIG_CIFS_XATTR=y |
1758 |
+ CONFIG_CIFS_POSIX=y |
1759 |
+ CONFIG_NLS_CODEPAGE_437=m |
1760 |
+diff --git a/arch/mips/configs/maltaup_defconfig b/arch/mips/configs/maltaup_defconfig |
1761 |
+index 48e5bd4924522..7b4f247dc60cc 100644 |
1762 |
+--- a/arch/mips/configs/maltaup_defconfig |
1763 |
++++ b/arch/mips/configs/maltaup_defconfig |
1764 |
+@@ -165,7 +165,6 @@ CONFIG_TMPFS=y |
1765 |
+ CONFIG_NFS_FS=y |
1766 |
+ CONFIG_ROOT_NFS=y |
1767 |
+ CONFIG_CIFS=m |
1768 |
+-CONFIG_CIFS_WEAK_PW_HASH=y |
1769 |
+ CONFIG_CIFS_XATTR=y |
1770 |
+ CONFIG_CIFS_POSIX=y |
1771 |
+ CONFIG_NLS_CODEPAGE_437=m |
1772 |
+diff --git a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h |
1773 |
+index 13373c5144f89..efb41b3519747 100644 |
1774 |
+--- a/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h |
1775 |
++++ b/arch/mips/include/asm/mach-loongson64/kernel-entry-init.h |
1776 |
+@@ -32,7 +32,7 @@ |
1777 |
+ nop |
1778 |
+ /* Loongson-3A R2/R3 */ |
1779 |
+ andi t0, (PRID_IMP_MASK | PRID_REV_MASK) |
1780 |
+- slti t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0) |
1781 |
++ slti t0, t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0) |
1782 |
+ bnez t0, 2f |
1783 |
+ nop |
1784 |
+ 1: |
1785 |
+@@ -63,7 +63,7 @@ |
1786 |
+ nop |
1787 |
+ /* Loongson-3A R2/R3 */ |
1788 |
+ andi t0, (PRID_IMP_MASK | PRID_REV_MASK) |
1789 |
+- slti t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0) |
1790 |
++ slti t0, t0, (PRID_IMP_LOONGSON_64C | PRID_REV_LOONGSON3A_R2_0) |
1791 |
+ bnez t0, 2f |
1792 |
+ nop |
1793 |
+ 1: |
1794 |
+diff --git a/arch/mips/include/asm/octeon/cvmx-bootinfo.h b/arch/mips/include/asm/octeon/cvmx-bootinfo.h |
1795 |
+index 0e6bf220db618..6c61e0a639249 100644 |
1796 |
+--- a/arch/mips/include/asm/octeon/cvmx-bootinfo.h |
1797 |
++++ b/arch/mips/include/asm/octeon/cvmx-bootinfo.h |
1798 |
+@@ -318,7 +318,7 @@ enum cvmx_chip_types_enum { |
1799 |
+ |
1800 |
+ /* Functions to return string based on type */ |
1801 |
+ #define ENUM_BRD_TYPE_CASE(x) \ |
1802 |
+- case x: return(#x + 16); /* Skip CVMX_BOARD_TYPE_ */ |
1803 |
++ case x: return (&#x[16]); /* Skip CVMX_BOARD_TYPE_ */ |
1804 |
+ static inline const char *cvmx_board_type_to_string(enum |
1805 |
+ cvmx_board_types_enum type) |
1806 |
+ { |
1807 |
+@@ -410,7 +410,7 @@ static inline const char *cvmx_board_type_to_string(enum |
1808 |
+ } |
1809 |
+ |
1810 |
+ #define ENUM_CHIP_TYPE_CASE(x) \ |
1811 |
+- case x: return(#x + 15); /* Skip CVMX_CHIP_TYPE */ |
1812 |
++ case x: return (&#x[15]); /* Skip CVMX_CHIP_TYPE */ |
1813 |
+ static inline const char *cvmx_chip_type_to_string(enum |
1814 |
+ cvmx_chip_types_enum type) |
1815 |
+ { |
1816 |
+diff --git a/arch/mips/lantiq/clk.c b/arch/mips/lantiq/clk.c |
1817 |
+index 4916cccf378fd..7a623684d9b5e 100644 |
1818 |
+--- a/arch/mips/lantiq/clk.c |
1819 |
++++ b/arch/mips/lantiq/clk.c |
1820 |
+@@ -164,6 +164,12 @@ struct clk *clk_get_parent(struct clk *clk) |
1821 |
+ } |
1822 |
+ EXPORT_SYMBOL(clk_get_parent); |
1823 |
+ |
1824 |
++int clk_set_parent(struct clk *clk, struct clk *parent) |
1825 |
++{ |
1826 |
++ return 0; |
1827 |
++} |
1828 |
++EXPORT_SYMBOL(clk_set_parent); |
1829 |
++ |
1830 |
+ static inline u32 get_counter_resolution(void) |
1831 |
+ { |
1832 |
+ u32 res; |
1833 |
+diff --git a/arch/openrisc/include/asm/syscalls.h b/arch/openrisc/include/asm/syscalls.h |
1834 |
+index 3a7eeae6f56a8..aa1c7e98722e3 100644 |
1835 |
+--- a/arch/openrisc/include/asm/syscalls.h |
1836 |
++++ b/arch/openrisc/include/asm/syscalls.h |
1837 |
+@@ -22,9 +22,11 @@ asmlinkage long sys_or1k_atomic(unsigned long type, unsigned long *v1, |
1838 |
+ |
1839 |
+ asmlinkage long __sys_clone(unsigned long clone_flags, unsigned long newsp, |
1840 |
+ void __user *parent_tid, void __user *child_tid, int tls); |
1841 |
++asmlinkage long __sys_clone3(struct clone_args __user *uargs, size_t size); |
1842 |
+ asmlinkage long __sys_fork(void); |
1843 |
+ |
1844 |
+ #define sys_clone __sys_clone |
1845 |
++#define sys_clone3 __sys_clone3 |
1846 |
+ #define sys_fork __sys_fork |
1847 |
+ |
1848 |
+ #endif /* __ASM_OPENRISC_SYSCALLS_H */ |
1849 |
+diff --git a/arch/openrisc/kernel/entry.S b/arch/openrisc/kernel/entry.S |
1850 |
+index edaa775a648e6..c68f3349c1741 100644 |
1851 |
+--- a/arch/openrisc/kernel/entry.S |
1852 |
++++ b/arch/openrisc/kernel/entry.S |
1853 |
+@@ -1170,6 +1170,11 @@ ENTRY(__sys_clone) |
1854 |
+ l.j _fork_save_extra_regs_and_call |
1855 |
+ l.nop |
1856 |
+ |
1857 |
++ENTRY(__sys_clone3) |
1858 |
++ l.movhi r29,hi(sys_clone3) |
1859 |
++ l.j _fork_save_extra_regs_and_call |
1860 |
++ l.ori r29,r29,lo(sys_clone3) |
1861 |
++ |
1862 |
+ ENTRY(__sys_fork) |
1863 |
+ l.movhi r29,hi(sys_fork) |
1864 |
+ l.ori r29,r29,lo(sys_fork) |
1865 |
+diff --git a/arch/parisc/include/asm/special_insns.h b/arch/parisc/include/asm/special_insns.h |
1866 |
+index a303ae9a77f41..16ee41e77174f 100644 |
1867 |
+--- a/arch/parisc/include/asm/special_insns.h |
1868 |
++++ b/arch/parisc/include/asm/special_insns.h |
1869 |
+@@ -2,28 +2,32 @@ |
1870 |
+ #ifndef __PARISC_SPECIAL_INSNS_H |
1871 |
+ #define __PARISC_SPECIAL_INSNS_H |
1872 |
+ |
1873 |
+-#define lpa(va) ({ \ |
1874 |
+- unsigned long pa; \ |
1875 |
+- __asm__ __volatile__( \ |
1876 |
+- "copy %%r0,%0\n\t" \ |
1877 |
+- "lpa %%r0(%1),%0" \ |
1878 |
+- : "=r" (pa) \ |
1879 |
+- : "r" (va) \ |
1880 |
+- : "memory" \ |
1881 |
+- ); \ |
1882 |
+- pa; \ |
1883 |
++#define lpa(va) ({ \ |
1884 |
++ unsigned long pa; \ |
1885 |
++ __asm__ __volatile__( \ |
1886 |
++ "copy %%r0,%0\n" \ |
1887 |
++ "8:\tlpa %%r0(%1),%0\n" \ |
1888 |
++ "9:\n" \ |
1889 |
++ ASM_EXCEPTIONTABLE_ENTRY(8b, 9b) \ |
1890 |
++ : "=&r" (pa) \ |
1891 |
++ : "r" (va) \ |
1892 |
++ : "memory" \ |
1893 |
++ ); \ |
1894 |
++ pa; \ |
1895 |
+ }) |
1896 |
+ |
1897 |
+-#define lpa_user(va) ({ \ |
1898 |
+- unsigned long pa; \ |
1899 |
+- __asm__ __volatile__( \ |
1900 |
+- "copy %%r0,%0\n\t" \ |
1901 |
+- "lpa %%r0(%%sr3,%1),%0" \ |
1902 |
+- : "=r" (pa) \ |
1903 |
+- : "r" (va) \ |
1904 |
+- : "memory" \ |
1905 |
+- ); \ |
1906 |
+- pa; \ |
1907 |
++#define lpa_user(va) ({ \ |
1908 |
++ unsigned long pa; \ |
1909 |
++ __asm__ __volatile__( \ |
1910 |
++ "copy %%r0,%0\n" \ |
1911 |
++ "8:\tlpa %%r0(%%sr3,%1),%0\n" \ |
1912 |
++ "9:\n" \ |
1913 |
++ ASM_EXCEPTIONTABLE_ENTRY(8b, 9b) \ |
1914 |
++ : "=&r" (pa) \ |
1915 |
++ : "r" (va) \ |
1916 |
++ : "memory" \ |
1917 |
++ ); \ |
1918 |
++ pa; \ |
1919 |
+ }) |
1920 |
+ |
1921 |
+ #define mfctl(reg) ({ \ |
1922 |
+diff --git a/arch/parisc/kernel/traps.c b/arch/parisc/kernel/traps.c |
1923 |
+index 197cb8480350c..afe8b902a8fc4 100644 |
1924 |
+--- a/arch/parisc/kernel/traps.c |
1925 |
++++ b/arch/parisc/kernel/traps.c |
1926 |
+@@ -784,7 +784,7 @@ void notrace handle_interruption(int code, struct pt_regs *regs) |
1927 |
+ * unless pagefault_disable() was called before. |
1928 |
+ */ |
1929 |
+ |
1930 |
+- if (fault_space == 0 && !faulthandler_disabled()) |
1931 |
++ if (faulthandler_disabled() || fault_space == 0) |
1932 |
+ { |
1933 |
+ /* Clean up and return if in exception table. */ |
1934 |
+ if (fixup_exception(regs)) |
1935 |
+diff --git a/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi |
1936 |
+index c90702b04a530..48e5cd61599c6 100644 |
1937 |
+--- a/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi |
1938 |
++++ b/arch/powerpc/boot/dts/fsl/qoriq-fman3l-0.dtsi |
1939 |
+@@ -79,6 +79,7 @@ fman0: fman@400000 { |
1940 |
+ #size-cells = <0>; |
1941 |
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
1942 |
+ reg = <0xfc000 0x1000>; |
1943 |
++ fsl,erratum-a009885; |
1944 |
+ }; |
1945 |
+ |
1946 |
+ xmdio0: mdio@fd000 { |
1947 |
+@@ -86,6 +87,7 @@ fman0: fman@400000 { |
1948 |
+ #size-cells = <0>; |
1949 |
+ compatible = "fsl,fman-memac-mdio", "fsl,fman-xmdio"; |
1950 |
+ reg = <0xfd000 0x1000>; |
1951 |
++ fsl,erratum-a009885; |
1952 |
+ }; |
1953 |
+ }; |
1954 |
+ |
1955 |
+diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig |
1956 |
+index 6697c5e6682f1..bb549cb1c3e33 100644 |
1957 |
+--- a/arch/powerpc/configs/ppc6xx_defconfig |
1958 |
++++ b/arch/powerpc/configs/ppc6xx_defconfig |
1959 |
+@@ -1022,7 +1022,6 @@ CONFIG_NFSD=m |
1960 |
+ CONFIG_NFSD_V3_ACL=y |
1961 |
+ CONFIG_NFSD_V4=y |
1962 |
+ CONFIG_CIFS=m |
1963 |
+-CONFIG_CIFS_WEAK_PW_HASH=y |
1964 |
+ CONFIG_CIFS_UPCALL=y |
1965 |
+ CONFIG_CIFS_XATTR=y |
1966 |
+ CONFIG_CIFS_POSIX=y |
1967 |
+diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig |
1968 |
+index b183629f1bcfb..d0494fbb49617 100644 |
1969 |
+--- a/arch/powerpc/configs/pseries_defconfig |
1970 |
++++ b/arch/powerpc/configs/pseries_defconfig |
1971 |
+@@ -190,7 +190,6 @@ CONFIG_HVCS=m |
1972 |
+ CONFIG_VIRTIO_CONSOLE=m |
1973 |
+ CONFIG_IBM_BSR=m |
1974 |
+ CONFIG_RAW_DRIVER=y |
1975 |
+-CONFIG_MAX_RAW_DEVS=1024 |
1976 |
+ CONFIG_I2C_CHARDEV=y |
1977 |
+ CONFIG_FB=y |
1978 |
+ CONFIG_FIRMWARE_EDID=y |
1979 |
+diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h |
1980 |
+index 21cc571ea9c2d..5c98a950eca0d 100644 |
1981 |
+--- a/arch/powerpc/include/asm/hw_irq.h |
1982 |
++++ b/arch/powerpc/include/asm/hw_irq.h |
1983 |
+@@ -224,6 +224,42 @@ static inline bool arch_irqs_disabled(void) |
1984 |
+ return arch_irqs_disabled_flags(arch_local_save_flags()); |
1985 |
+ } |
1986 |
+ |
1987 |
++static inline void set_pmi_irq_pending(void) |
1988 |
++{ |
1989 |
++ /* |
1990 |
++ * Invoked from PMU callback functions to set PMI bit in the paca. |
1991 |
++ * This has to be called with irq's disabled (via hard_irq_disable()). |
1992 |
++ */ |
1993 |
++ if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) |
1994 |
++ WARN_ON_ONCE(mfmsr() & MSR_EE); |
1995 |
++ |
1996 |
++ get_paca()->irq_happened |= PACA_IRQ_PMI; |
1997 |
++} |
1998 |
++ |
1999 |
++static inline void clear_pmi_irq_pending(void) |
2000 |
++{ |
2001 |
++ /* |
2002 |
++ * Invoked from PMU callback functions to clear the pending PMI bit |
2003 |
++ * in the paca. |
2004 |
++ */ |
2005 |
++ if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) |
2006 |
++ WARN_ON_ONCE(mfmsr() & MSR_EE); |
2007 |
++ |
2008 |
++ get_paca()->irq_happened &= ~PACA_IRQ_PMI; |
2009 |
++} |
2010 |
++ |
2011 |
++static inline bool pmi_irq_pending(void) |
2012 |
++{ |
2013 |
++ /* |
2014 |
++ * Invoked from PMU callback functions to check if there is a pending |
2015 |
++ * PMI bit in the paca. |
2016 |
++ */ |
2017 |
++ if (get_paca()->irq_happened & PACA_IRQ_PMI) |
2018 |
++ return true; |
2019 |
++ |
2020 |
++ return false; |
2021 |
++} |
2022 |
++ |
2023 |
+ #ifdef CONFIG_PPC_BOOK3S |
2024 |
+ /* |
2025 |
+ * To support disabling and enabling of irq with PMI, set of |
2026 |
+@@ -408,6 +444,10 @@ static inline void do_hard_irq_enable(void) |
2027 |
+ BUILD_BUG(); |
2028 |
+ } |
2029 |
+ |
2030 |
++static inline void clear_pmi_irq_pending(void) { } |
2031 |
++static inline void set_pmi_irq_pending(void) { } |
2032 |
++static inline bool pmi_irq_pending(void) { return false; } |
2033 |
++ |
2034 |
+ static inline void irq_soft_mask_regs_set_state(struct pt_regs *regs, unsigned long val) |
2035 |
+ { |
2036 |
+ } |
2037 |
+diff --git a/arch/powerpc/kernel/btext.c b/arch/powerpc/kernel/btext.c |
2038 |
+index 803c2a45b22ac..1cffb5e7c38d6 100644 |
2039 |
+--- a/arch/powerpc/kernel/btext.c |
2040 |
++++ b/arch/powerpc/kernel/btext.c |
2041 |
+@@ -241,8 +241,10 @@ int __init btext_find_display(int allow_nonstdout) |
2042 |
+ rc = btext_initialize(np); |
2043 |
+ printk("result: %d\n", rc); |
2044 |
+ } |
2045 |
+- if (rc == 0) |
2046 |
++ if (rc == 0) { |
2047 |
++ of_node_put(np); |
2048 |
+ break; |
2049 |
++ } |
2050 |
+ } |
2051 |
+ return rc; |
2052 |
+ } |
2053 |
+diff --git a/arch/powerpc/kernel/fadump.c b/arch/powerpc/kernel/fadump.c |
2054 |
+index b7ceb041743c9..60f5fc14aa235 100644 |
2055 |
+--- a/arch/powerpc/kernel/fadump.c |
2056 |
++++ b/arch/powerpc/kernel/fadump.c |
2057 |
+@@ -1641,6 +1641,14 @@ int __init setup_fadump(void) |
2058 |
+ else if (fw_dump.reserve_dump_area_size) |
2059 |
+ fw_dump.ops->fadump_init_mem_struct(&fw_dump); |
2060 |
+ |
2061 |
++ /* |
2062 |
++ * In case of panic, fadump is triggered via ppc_panic_event() |
2063 |
++ * panic notifier. Setting crash_kexec_post_notifiers to 'true' |
2064 |
++ * lets panic() function take crash friendly path before panic |
2065 |
++ * notifiers are invoked. |
2066 |
++ */ |
2067 |
++ crash_kexec_post_notifiers = true; |
2068 |
++ |
2069 |
+ return 1; |
2070 |
+ } |
2071 |
+ subsys_initcall(setup_fadump); |
2072 |
+diff --git a/arch/powerpc/kernel/head_40x.S b/arch/powerpc/kernel/head_40x.S |
2073 |
+index 7d72ee5ab387c..e783860bea838 100644 |
2074 |
+--- a/arch/powerpc/kernel/head_40x.S |
2075 |
++++ b/arch/powerpc/kernel/head_40x.S |
2076 |
+@@ -27,6 +27,7 @@ |
2077 |
+ |
2078 |
+ #include <linux/init.h> |
2079 |
+ #include <linux/pgtable.h> |
2080 |
++#include <linux/sizes.h> |
2081 |
+ #include <asm/processor.h> |
2082 |
+ #include <asm/page.h> |
2083 |
+ #include <asm/mmu.h> |
2084 |
+@@ -650,7 +651,7 @@ start_here: |
2085 |
+ b . /* prevent prefetch past rfi */ |
2086 |
+ |
2087 |
+ /* Set up the initial MMU state so we can do the first level of |
2088 |
+- * kernel initialization. This maps the first 16 MBytes of memory 1:1 |
2089 |
++ * kernel initialization. This maps the first 32 MBytes of memory 1:1 |
2090 |
+ * virtual to physical and more importantly sets the cache mode. |
2091 |
+ */ |
2092 |
+ initial_mmu: |
2093 |
+@@ -687,6 +688,12 @@ initial_mmu: |
2094 |
+ tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */ |
2095 |
+ tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */ |
2096 |
+ |
2097 |
++ li r0,62 /* TLB slot 62 */ |
2098 |
++ addis r4,r4,SZ_16M@h |
2099 |
++ addis r3,r3,SZ_16M@h |
2100 |
++ tlbwe r4,r0,TLB_DATA /* Load the data portion of the entry */ |
2101 |
++ tlbwe r3,r0,TLB_TAG /* Load the tag portion of the entry */ |
2102 |
++ |
2103 |
+ isync |
2104 |
+ |
2105 |
+ /* Establish the exception vector base |
2106 |
+diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c |
2107 |
+index 835b626cd4760..df048e331cbfe 100644 |
2108 |
+--- a/arch/powerpc/kernel/interrupt.c |
2109 |
++++ b/arch/powerpc/kernel/interrupt.c |
2110 |
+@@ -148,7 +148,7 @@ notrace long system_call_exception(long r3, long r4, long r5, |
2111 |
+ */ |
2112 |
+ if (IS_ENABLED(CONFIG_PPC_TRANSACTIONAL_MEM) && |
2113 |
+ unlikely(MSR_TM_TRANSACTIONAL(regs->msr))) |
2114 |
+- current_thread_info()->flags |= _TIF_RESTOREALL; |
2115 |
++ set_bits(_TIF_RESTOREALL, ¤t_thread_info()->flags); |
2116 |
+ |
2117 |
+ /* |
2118 |
+ * If the system call was made with a transaction active, doom it and |
2119 |
+diff --git a/arch/powerpc/kernel/interrupt_64.S b/arch/powerpc/kernel/interrupt_64.S |
2120 |
+index ec950b08a8dcc..4b1ff94e67eb4 100644 |
2121 |
+--- a/arch/powerpc/kernel/interrupt_64.S |
2122 |
++++ b/arch/powerpc/kernel/interrupt_64.S |
2123 |
+@@ -30,21 +30,23 @@ COMPAT_SYS_CALL_TABLE: |
2124 |
+ .ifc \srr,srr |
2125 |
+ mfspr r11,SPRN_SRR0 |
2126 |
+ ld r12,_NIP(r1) |
2127 |
++ clrrdi r12,r12,2 |
2128 |
+ 100: tdne r11,r12 |
2129 |
+- EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) |
2130 |
++ EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) |
2131 |
+ mfspr r11,SPRN_SRR1 |
2132 |
+ ld r12,_MSR(r1) |
2133 |
+ 100: tdne r11,r12 |
2134 |
+- EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) |
2135 |
++ EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) |
2136 |
+ .else |
2137 |
+ mfspr r11,SPRN_HSRR0 |
2138 |
+ ld r12,_NIP(r1) |
2139 |
++ clrrdi r12,r12,2 |
2140 |
+ 100: tdne r11,r12 |
2141 |
+- EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) |
2142 |
++ EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) |
2143 |
+ mfspr r11,SPRN_HSRR1 |
2144 |
+ ld r12,_MSR(r1) |
2145 |
+ 100: tdne r11,r12 |
2146 |
+- EMIT_BUG_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) |
2147 |
++ EMIT_WARN_ENTRY 100b,__FILE__,__LINE__,(BUGFLAG_WARNING | BUGFLAG_ONCE) |
2148 |
+ .endif |
2149 |
+ #endif |
2150 |
+ .endm |
2151 |
+diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c |
2152 |
+index ed04a3ba66fe8..40a583e9d3c70 100644 |
2153 |
+--- a/arch/powerpc/kernel/module.c |
2154 |
++++ b/arch/powerpc/kernel/module.c |
2155 |
+@@ -90,16 +90,17 @@ int module_finalize(const Elf_Ehdr *hdr, |
2156 |
+ } |
2157 |
+ |
2158 |
+ static __always_inline void * |
2159 |
+-__module_alloc(unsigned long size, unsigned long start, unsigned long end) |
2160 |
++__module_alloc(unsigned long size, unsigned long start, unsigned long end, bool nowarn) |
2161 |
+ { |
2162 |
+ pgprot_t prot = strict_module_rwx_enabled() ? PAGE_KERNEL : PAGE_KERNEL_EXEC; |
2163 |
++ gfp_t gfp = GFP_KERNEL | (nowarn ? __GFP_NOWARN : 0); |
2164 |
+ |
2165 |
+ /* |
2166 |
+ * Don't do huge page allocations for modules yet until more testing |
2167 |
+ * is done. STRICT_MODULE_RWX may require extra work to support this |
2168 |
+ * too. |
2169 |
+ */ |
2170 |
+- return __vmalloc_node_range(size, 1, start, end, GFP_KERNEL, prot, |
2171 |
++ return __vmalloc_node_range(size, 1, start, end, gfp, prot, |
2172 |
+ VM_FLUSH_RESET_PERMS | VM_NO_HUGE_VMAP, |
2173 |
+ NUMA_NO_NODE, __builtin_return_address(0)); |
2174 |
+ } |
2175 |
+@@ -114,13 +115,13 @@ void *module_alloc(unsigned long size) |
2176 |
+ |
2177 |
+ /* First try within 32M limit from _etext to avoid branch trampolines */ |
2178 |
+ if (MODULES_VADDR < PAGE_OFFSET && MODULES_END > limit) |
2179 |
+- ptr = __module_alloc(size, limit, MODULES_END); |
2180 |
++ ptr = __module_alloc(size, limit, MODULES_END, true); |
2181 |
+ |
2182 |
+ if (!ptr) |
2183 |
+- ptr = __module_alloc(size, MODULES_VADDR, MODULES_END); |
2184 |
++ ptr = __module_alloc(size, MODULES_VADDR, MODULES_END, false); |
2185 |
+ |
2186 |
+ return ptr; |
2187 |
+ #else |
2188 |
+- return __module_alloc(size, VMALLOC_START, VMALLOC_END); |
2189 |
++ return __module_alloc(size, VMALLOC_START, VMALLOC_END, false); |
2190 |
+ #endif |
2191 |
+ } |
2192 |
+diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c |
2193 |
+index 18b04b08b9833..f845065c860e3 100644 |
2194 |
+--- a/arch/powerpc/kernel/prom_init.c |
2195 |
++++ b/arch/powerpc/kernel/prom_init.c |
2196 |
+@@ -2991,7 +2991,7 @@ static void __init fixup_device_tree_efika_add_phy(void) |
2197 |
+ |
2198 |
+ /* Check if the phy-handle property exists - bail if it does */ |
2199 |
+ rv = prom_getprop(node, "phy-handle", prop, sizeof(prop)); |
2200 |
+- if (!rv) |
2201 |
++ if (rv <= 0) |
2202 |
+ return; |
2203 |
+ |
2204 |
+ /* |
2205 |
+diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c |
2206 |
+index 605bab448f847..fb95f92dcfac6 100644 |
2207 |
+--- a/arch/powerpc/kernel/smp.c |
2208 |
++++ b/arch/powerpc/kernel/smp.c |
2209 |
+@@ -61,6 +61,7 @@ |
2210 |
+ #include <asm/cpu_has_feature.h> |
2211 |
+ #include <asm/ftrace.h> |
2212 |
+ #include <asm/kup.h> |
2213 |
++#include <asm/fadump.h> |
2214 |
+ |
2215 |
+ #ifdef DEBUG |
2216 |
+ #include <asm/udbg.h> |
2217 |
+@@ -620,6 +621,45 @@ void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *)) |
2218 |
+ } |
2219 |
+ #endif |
2220 |
+ |
2221 |
++#ifdef CONFIG_NMI_IPI |
2222 |
++static void crash_stop_this_cpu(struct pt_regs *regs) |
2223 |
++#else |
2224 |
++static void crash_stop_this_cpu(void *dummy) |
2225 |
++#endif |
2226 |
++{ |
2227 |
++ /* |
2228 |
++ * Just busy wait here and avoid marking CPU as offline to ensure |
2229 |
++ * register data is captured appropriately. |
2230 |
++ */ |
2231 |
++ while (1) |
2232 |
++ cpu_relax(); |
2233 |
++} |
2234 |
++ |
2235 |
++void crash_smp_send_stop(void) |
2236 |
++{ |
2237 |
++ static bool stopped = false; |
2238 |
++ |
2239 |
++ /* |
2240 |
++ * In case of fadump, register data for all CPUs is captured by f/w |
2241 |
++ * on ibm,os-term rtas call. Skip IPI callbacks to other CPUs before |
2242 |
++ * this rtas call to avoid tricky post processing of those CPUs' |
2243 |
++ * backtraces. |
2244 |
++ */ |
2245 |
++ if (should_fadump_crash()) |
2246 |
++ return; |
2247 |
++ |
2248 |
++ if (stopped) |
2249 |
++ return; |
2250 |
++ |
2251 |
++ stopped = true; |
2252 |
++ |
2253 |
++#ifdef CONFIG_NMI_IPI |
2254 |
++ smp_send_nmi_ipi(NMI_IPI_ALL_OTHERS, crash_stop_this_cpu, 1000000); |
2255 |
++#else |
2256 |
++ smp_call_function(crash_stop_this_cpu, NULL, 0); |
2257 |
++#endif /* CONFIG_NMI_IPI */ |
2258 |
++} |
2259 |
++ |
2260 |
+ #ifdef CONFIG_NMI_IPI |
2261 |
+ static void nmi_stop_this_cpu(struct pt_regs *regs) |
2262 |
+ { |
2263 |
+@@ -1640,10 +1680,12 @@ void start_secondary(void *unused) |
2264 |
+ BUG(); |
2265 |
+ } |
2266 |
+ |
2267 |
++#ifdef CONFIG_PROFILING |
2268 |
+ int setup_profiling_timer(unsigned int multiplier) |
2269 |
+ { |
2270 |
+ return 0; |
2271 |
+ } |
2272 |
++#endif |
2273 |
+ |
2274 |
+ static void fixup_topology(void) |
2275 |
+ { |
2276 |
+diff --git a/arch/powerpc/kernel/watchdog.c b/arch/powerpc/kernel/watchdog.c |
2277 |
+index 3fa6d240bade2..ad94a2c6b7337 100644 |
2278 |
+--- a/arch/powerpc/kernel/watchdog.c |
2279 |
++++ b/arch/powerpc/kernel/watchdog.c |
2280 |
+@@ -135,6 +135,10 @@ static void set_cpumask_stuck(const struct cpumask *cpumask, u64 tb) |
2281 |
+ { |
2282 |
+ cpumask_or(&wd_smp_cpus_stuck, &wd_smp_cpus_stuck, cpumask); |
2283 |
+ cpumask_andnot(&wd_smp_cpus_pending, &wd_smp_cpus_pending, cpumask); |
2284 |
++ /* |
2285 |
++ * See wd_smp_clear_cpu_pending() |
2286 |
++ */ |
2287 |
++ smp_mb(); |
2288 |
+ if (cpumask_empty(&wd_smp_cpus_pending)) { |
2289 |
+ wd_smp_last_reset_tb = tb; |
2290 |
+ cpumask_andnot(&wd_smp_cpus_pending, |
2291 |
+@@ -221,13 +225,44 @@ static void wd_smp_clear_cpu_pending(int cpu, u64 tb) |
2292 |
+ |
2293 |
+ cpumask_clear_cpu(cpu, &wd_smp_cpus_stuck); |
2294 |
+ wd_smp_unlock(&flags); |
2295 |
++ } else { |
2296 |
++ /* |
2297 |
++ * The last CPU to clear pending should have reset the |
2298 |
++ * watchdog so we generally should not find it empty |
2299 |
++ * here if our CPU was clear. However it could happen |
2300 |
++ * due to a rare race with another CPU taking the |
2301 |
++ * last CPU out of the mask concurrently. |
2302 |
++ * |
2303 |
++ * We can't add a warning for it. But just in case |
2304 |
++ * there is a problem with the watchdog that is causing |
2305 |
++ * the mask to not be reset, try to kick it along here. |
2306 |
++ */ |
2307 |
++ if (unlikely(cpumask_empty(&wd_smp_cpus_pending))) |
2308 |
++ goto none_pending; |
2309 |
+ } |
2310 |
+ return; |
2311 |
+ } |
2312 |
++ |
2313 |
+ cpumask_clear_cpu(cpu, &wd_smp_cpus_pending); |
2314 |
++ |
2315 |
++ /* |
2316 |
++ * Order the store to clear pending with the load(s) to check all |
2317 |
++ * words in the pending mask to check they are all empty. This orders |
2318 |
++ * with the same barrier on another CPU. This prevents two CPUs |
2319 |
++ * clearing the last 2 pending bits, but neither seeing the other's |
2320 |
++ * store when checking if the mask is empty, and missing an empty |
2321 |
++ * mask, which ends with a false positive. |
2322 |
++ */ |
2323 |
++ smp_mb(); |
2324 |
+ if (cpumask_empty(&wd_smp_cpus_pending)) { |
2325 |
+ unsigned long flags; |
2326 |
+ |
2327 |
++none_pending: |
2328 |
++ /* |
2329 |
++ * Double check under lock because more than one CPU could see |
2330 |
++ * a clear mask with the lockless check after clearing their |
2331 |
++ * pending bits. |
2332 |
++ */ |
2333 |
+ wd_smp_lock(&flags); |
2334 |
+ if (cpumask_empty(&wd_smp_cpus_pending)) { |
2335 |
+ wd_smp_last_reset_tb = tb; |
2336 |
+@@ -318,8 +353,12 @@ void arch_touch_nmi_watchdog(void) |
2337 |
+ { |
2338 |
+ unsigned long ticks = tb_ticks_per_usec * wd_timer_period_ms * 1000; |
2339 |
+ int cpu = smp_processor_id(); |
2340 |
+- u64 tb = get_tb(); |
2341 |
++ u64 tb; |
2342 |
+ |
2343 |
++ if (!cpumask_test_cpu(cpu, &watchdog_cpumask)) |
2344 |
++ return; |
2345 |
++ |
2346 |
++ tb = get_tb(); |
2347 |
+ if (tb - per_cpu(wd_timer_tb, cpu) >= ticks) { |
2348 |
+ per_cpu(wd_timer_tb, cpu) = tb; |
2349 |
+ wd_smp_clear_cpu_pending(cpu, tb); |
2350 |
+diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c |
2351 |
+index 7b74fc0a986b8..94da0d25eb125 100644 |
2352 |
+--- a/arch/powerpc/kvm/book3s_hv.c |
2353 |
++++ b/arch/powerpc/kvm/book3s_hv.c |
2354 |
+@@ -4861,8 +4861,12 @@ static int kvmppc_core_prepare_memory_region_hv(struct kvm *kvm, |
2355 |
+ unsigned long npages = mem->memory_size >> PAGE_SHIFT; |
2356 |
+ |
2357 |
+ if (change == KVM_MR_CREATE) { |
2358 |
+- slot->arch.rmap = vzalloc(array_size(npages, |
2359 |
+- sizeof(*slot->arch.rmap))); |
2360 |
++ unsigned long size = array_size(npages, sizeof(*slot->arch.rmap)); |
2361 |
++ |
2362 |
++ if ((size >> PAGE_SHIFT) > totalram_pages()) |
2363 |
++ return -ENOMEM; |
2364 |
++ |
2365 |
++ slot->arch.rmap = vzalloc(size); |
2366 |
+ if (!slot->arch.rmap) |
2367 |
+ return -ENOMEM; |
2368 |
+ } |
2369 |
+diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c |
2370 |
+index ed8a2c9f56299..89295b52a97c3 100644 |
2371 |
+--- a/arch/powerpc/kvm/book3s_hv_nested.c |
2372 |
++++ b/arch/powerpc/kvm/book3s_hv_nested.c |
2373 |
+@@ -582,7 +582,7 @@ long kvmhv_copy_tofrom_guest_nested(struct kvm_vcpu *vcpu) |
2374 |
+ if (eaddr & (0xFFFUL << 52)) |
2375 |
+ return H_PARAMETER; |
2376 |
+ |
2377 |
+- buf = kzalloc(n, GFP_KERNEL); |
2378 |
++ buf = kzalloc(n, GFP_KERNEL | __GFP_NOWARN); |
2379 |
+ if (!buf) |
2380 |
+ return H_NO_MEM; |
2381 |
+ |
2382 |
+diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c |
2383 |
+index ae20add7954a0..795d18a84f556 100644 |
2384 |
+--- a/arch/powerpc/mm/book3s64/radix_pgtable.c |
2385 |
++++ b/arch/powerpc/mm/book3s64/radix_pgtable.c |
2386 |
+@@ -1093,7 +1093,7 @@ int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot) |
2387 |
+ |
2388 |
+ int pud_clear_huge(pud_t *pud) |
2389 |
+ { |
2390 |
+- if (pud_huge(*pud)) { |
2391 |
++ if (pud_is_leaf(*pud)) { |
2392 |
+ pud_clear(pud); |
2393 |
+ return 1; |
2394 |
+ } |
2395 |
+@@ -1140,7 +1140,7 @@ int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot) |
2396 |
+ |
2397 |
+ int pmd_clear_huge(pmd_t *pmd) |
2398 |
+ { |
2399 |
+- if (pmd_huge(*pmd)) { |
2400 |
++ if (pmd_is_leaf(*pmd)) { |
2401 |
+ pmd_clear(pmd); |
2402 |
+ return 1; |
2403 |
+ } |
2404 |
+diff --git a/arch/powerpc/mm/kasan/book3s_32.c b/arch/powerpc/mm/kasan/book3s_32.c |
2405 |
+index 202bd260a0095..35b287b0a8da4 100644 |
2406 |
+--- a/arch/powerpc/mm/kasan/book3s_32.c |
2407 |
++++ b/arch/powerpc/mm/kasan/book3s_32.c |
2408 |
+@@ -19,7 +19,8 @@ int __init kasan_init_region(void *start, size_t size) |
2409 |
+ block = memblock_alloc(k_size, k_size_base); |
2410 |
+ |
2411 |
+ if (block && k_size_base >= SZ_128K && k_start == ALIGN(k_start, k_size_base)) { |
2412 |
+- int k_size_more = 1 << (ffs(k_size - k_size_base) - 1); |
2413 |
++ int shift = ffs(k_size - k_size_base); |
2414 |
++ int k_size_more = shift ? 1 << (shift - 1) : 0; |
2415 |
+ |
2416 |
+ setbat(-1, k_start, __pa(block), k_size_base, PAGE_KERNEL); |
2417 |
+ if (k_size_more >= SZ_128K) |
2418 |
+diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c |
2419 |
+index 78c8cf01db5f9..175aabf101e87 100644 |
2420 |
+--- a/arch/powerpc/mm/pgtable_64.c |
2421 |
++++ b/arch/powerpc/mm/pgtable_64.c |
2422 |
+@@ -102,7 +102,8 @@ EXPORT_SYMBOL(__pte_frag_size_shift); |
2423 |
+ struct page *p4d_page(p4d_t p4d) |
2424 |
+ { |
2425 |
+ if (p4d_is_leaf(p4d)) { |
2426 |
+- VM_WARN_ON(!p4d_huge(p4d)); |
2427 |
++ if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP)) |
2428 |
++ VM_WARN_ON(!p4d_huge(p4d)); |
2429 |
+ return pte_page(p4d_pte(p4d)); |
2430 |
+ } |
2431 |
+ return virt_to_page(p4d_pgtable(p4d)); |
2432 |
+@@ -112,7 +113,8 @@ struct page *p4d_page(p4d_t p4d) |
2433 |
+ struct page *pud_page(pud_t pud) |
2434 |
+ { |
2435 |
+ if (pud_is_leaf(pud)) { |
2436 |
+- VM_WARN_ON(!pud_huge(pud)); |
2437 |
++ if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP)) |
2438 |
++ VM_WARN_ON(!pud_huge(pud)); |
2439 |
+ return pte_page(pud_pte(pud)); |
2440 |
+ } |
2441 |
+ return virt_to_page(pud_pgtable(pud)); |
2442 |
+@@ -125,7 +127,13 @@ struct page *pud_page(pud_t pud) |
2443 |
+ struct page *pmd_page(pmd_t pmd) |
2444 |
+ { |
2445 |
+ if (pmd_is_leaf(pmd)) { |
2446 |
+- VM_WARN_ON(!(pmd_large(pmd) || pmd_huge(pmd))); |
2447 |
++ /* |
2448 |
++ * vmalloc_to_page may be called on any vmap address (not only |
2449 |
++ * vmalloc), and it uses pmd_page() etc., when huge vmap is |
2450 |
++ * enabled so these checks can't be used. |
2451 |
++ */ |
2452 |
++ if (!IS_ENABLED(CONFIG_HAVE_ARCH_HUGE_VMAP)) |
2453 |
++ VM_WARN_ON(!(pmd_large(pmd) || pmd_huge(pmd))); |
2454 |
+ return pte_page(pmd_pte(pmd)); |
2455 |
+ } |
2456 |
+ return virt_to_page(pmd_page_vaddr(pmd)); |
2457 |
+diff --git a/arch/powerpc/perf/core-book3s.c b/arch/powerpc/perf/core-book3s.c |
2458 |
+index 73e62e9b179bc..bef6b1abce702 100644 |
2459 |
+--- a/arch/powerpc/perf/core-book3s.c |
2460 |
++++ b/arch/powerpc/perf/core-book3s.c |
2461 |
+@@ -857,6 +857,19 @@ static void write_pmc(int idx, unsigned long val) |
2462 |
+ } |
2463 |
+ } |
2464 |
+ |
2465 |
++static int any_pmc_overflown(struct cpu_hw_events *cpuhw) |
2466 |
++{ |
2467 |
++ int i, idx; |
2468 |
++ |
2469 |
++ for (i = 0; i < cpuhw->n_events; i++) { |
2470 |
++ idx = cpuhw->event[i]->hw.idx; |
2471 |
++ if ((idx) && ((int)read_pmc(idx) < 0)) |
2472 |
++ return idx; |
2473 |
++ } |
2474 |
++ |
2475 |
++ return 0; |
2476 |
++} |
2477 |
++ |
2478 |
+ /* Called from sysrq_handle_showregs() */ |
2479 |
+ void perf_event_print_debug(void) |
2480 |
+ { |
2481 |
+@@ -1281,11 +1294,13 @@ static void power_pmu_disable(struct pmu *pmu) |
2482 |
+ |
2483 |
+ /* |
2484 |
+ * Set the 'freeze counters' bit, clear EBE/BHRBA/PMCC/PMAO/FC56 |
2485 |
++ * Also clear PMXE to disable PMI's getting triggered in some |
2486 |
++ * corner cases during PMU disable. |
2487 |
+ */ |
2488 |
+ val = mmcr0 = mfspr(SPRN_MMCR0); |
2489 |
+ val |= MMCR0_FC; |
2490 |
+ val &= ~(MMCR0_EBE | MMCR0_BHRBA | MMCR0_PMCC | MMCR0_PMAO | |
2491 |
+- MMCR0_FC56); |
2492 |
++ MMCR0_PMXE | MMCR0_FC56); |
2493 |
+ /* Set mmcr0 PMCCEXT for p10 */ |
2494 |
+ if (ppmu->flags & PPMU_ARCH_31) |
2495 |
+ val |= MMCR0_PMCCEXT; |
2496 |
+@@ -1299,6 +1314,23 @@ static void power_pmu_disable(struct pmu *pmu) |
2497 |
+ mb(); |
2498 |
+ isync(); |
2499 |
+ |
2500 |
++ /* |
2501 |
++ * Some corner cases could clear the PMU counter overflow |
2502 |
++ * while a masked PMI is pending. One such case is when |
2503 |
++ * a PMI happens during interrupt replay and perf counter |
2504 |
++ * values are cleared by PMU callbacks before replay. |
2505 |
++ * |
2506 |
++ * If any PMC corresponding to the active PMU events are |
2507 |
++ * overflown, disable the interrupt by clearing the paca |
2508 |
++ * bit for PMI since we are disabling the PMU now. |
2509 |
++ * Otherwise provide a warning if there is PMI pending, but |
2510 |
++ * no counter is found overflown. |
2511 |
++ */ |
2512 |
++ if (any_pmc_overflown(cpuhw)) |
2513 |
++ clear_pmi_irq_pending(); |
2514 |
++ else |
2515 |
++ WARN_ON(pmi_irq_pending()); |
2516 |
++ |
2517 |
+ val = mmcra = cpuhw->mmcr.mmcra; |
2518 |
+ |
2519 |
+ /* |
2520 |
+@@ -1390,6 +1422,15 @@ static void power_pmu_enable(struct pmu *pmu) |
2521 |
+ * (possibly updated for removal of events). |
2522 |
+ */ |
2523 |
+ if (!cpuhw->n_added) { |
2524 |
++ /* |
2525 |
++ * If there is any active event with an overflown PMC |
2526 |
++ * value, set back PACA_IRQ_PMI which would have been |
2527 |
++ * cleared in power_pmu_disable(). |
2528 |
++ */ |
2529 |
++ hard_irq_disable(); |
2530 |
++ if (any_pmc_overflown(cpuhw)) |
2531 |
++ set_pmi_irq_pending(); |
2532 |
++ |
2533 |
+ mtspr(SPRN_MMCRA, cpuhw->mmcr.mmcra & ~MMCRA_SAMPLE_ENABLE); |
2534 |
+ mtspr(SPRN_MMCR1, cpuhw->mmcr.mmcr1); |
2535 |
+ if (ppmu->flags & PPMU_ARCH_31) |
2536 |
+@@ -2337,6 +2378,14 @@ static void __perf_event_interrupt(struct pt_regs *regs) |
2537 |
+ break; |
2538 |
+ } |
2539 |
+ } |
2540 |
++ |
2541 |
++ /* |
2542 |
++ * Clear PACA_IRQ_PMI in case it was set by |
2543 |
++ * set_pmi_irq_pending() when PMU was enabled |
2544 |
++ * after accounting for interrupts. |
2545 |
++ */ |
2546 |
++ clear_pmi_irq_pending(); |
2547 |
++ |
2548 |
+ if (!active) |
2549 |
+ /* reset non active counters that have overflowed */ |
2550 |
+ write_pmc(i + 1, 0); |
2551 |
+@@ -2356,6 +2405,13 @@ static void __perf_event_interrupt(struct pt_regs *regs) |
2552 |
+ } |
2553 |
+ } |
2554 |
+ } |
2555 |
++ |
2556 |
++ /* |
2557 |
++ * During system wide profling or while specific CPU is monitored for an |
2558 |
++ * event, some corner cases could cause PMC to overflow in idle path. This |
2559 |
++ * will trigger a PMI after waking up from idle. Since counter values are _not_ |
2560 |
++ * saved/restored in idle path, can lead to below "Can't find PMC" message. |
2561 |
++ */ |
2562 |
+ if (unlikely(!found) && !arch_irq_disabled_regs(regs)) |
2563 |
+ printk_ratelimited(KERN_WARNING "Can't find PMC that caused IRQ\n"); |
2564 |
+ |
2565 |
+diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c |
2566 |
+index fa08699aedeb8..d32f24de84798 100644 |
2567 |
+--- a/arch/powerpc/platforms/cell/iommu.c |
2568 |
++++ b/arch/powerpc/platforms/cell/iommu.c |
2569 |
+@@ -977,6 +977,7 @@ static int __init cell_iommu_fixed_mapping_init(void) |
2570 |
+ if (hbase < dbase || (hend > (dbase + dsize))) { |
2571 |
+ pr_debug("iommu: hash window doesn't fit in" |
2572 |
+ "real DMA window\n"); |
2573 |
++ of_node_put(np); |
2574 |
+ return -1; |
2575 |
+ } |
2576 |
+ } |
2577 |
+diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c |
2578 |
+index 5b9a7e9f144b3..dff8d5e7ab82b 100644 |
2579 |
+--- a/arch/powerpc/platforms/cell/pervasive.c |
2580 |
++++ b/arch/powerpc/platforms/cell/pervasive.c |
2581 |
+@@ -78,6 +78,7 @@ static int cbe_system_reset_exception(struct pt_regs *regs) |
2582 |
+ switch (regs->msr & SRR1_WAKEMASK) { |
2583 |
+ case SRR1_WAKEDEC: |
2584 |
+ set_dec(1); |
2585 |
++ break; |
2586 |
+ case SRR1_WAKEEE: |
2587 |
+ /* |
2588 |
+ * Handle these when interrupts get re-enabled and we take |
2589 |
+diff --git a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c |
2590 |
+index 15396333a90bd..a4b020e4b6af0 100644 |
2591 |
+--- a/arch/powerpc/platforms/embedded6xx/hlwd-pic.c |
2592 |
++++ b/arch/powerpc/platforms/embedded6xx/hlwd-pic.c |
2593 |
+@@ -214,6 +214,7 @@ void hlwd_pic_probe(void) |
2594 |
+ irq_set_chained_handler(cascade_virq, |
2595 |
+ hlwd_pic_irq_cascade); |
2596 |
+ hlwd_irq_host = host; |
2597 |
++ of_node_put(np); |
2598 |
+ break; |
2599 |
+ } |
2600 |
+ } |
2601 |
+diff --git a/arch/powerpc/platforms/powermac/low_i2c.c b/arch/powerpc/platforms/powermac/low_i2c.c |
2602 |
+index f77a59b5c2e1a..df89d916236d9 100644 |
2603 |
+--- a/arch/powerpc/platforms/powermac/low_i2c.c |
2604 |
++++ b/arch/powerpc/platforms/powermac/low_i2c.c |
2605 |
+@@ -582,6 +582,7 @@ static void __init kw_i2c_add(struct pmac_i2c_host_kw *host, |
2606 |
+ bus->close = kw_i2c_close; |
2607 |
+ bus->xfer = kw_i2c_xfer; |
2608 |
+ mutex_init(&bus->mutex); |
2609 |
++ lockdep_register_key(&bus->lock_key); |
2610 |
+ lockdep_set_class(&bus->mutex, &bus->lock_key); |
2611 |
+ if (controller == busnode) |
2612 |
+ bus->flags = pmac_i2c_multibus; |
2613 |
+@@ -810,6 +811,7 @@ static void __init pmu_i2c_probe(void) |
2614 |
+ bus->hostdata = bus + 1; |
2615 |
+ bus->xfer = pmu_i2c_xfer; |
2616 |
+ mutex_init(&bus->mutex); |
2617 |
++ lockdep_register_key(&bus->lock_key); |
2618 |
+ lockdep_set_class(&bus->mutex, &bus->lock_key); |
2619 |
+ bus->flags = pmac_i2c_multibus; |
2620 |
+ list_add(&bus->link, &pmac_i2c_busses); |
2621 |
+@@ -933,6 +935,7 @@ static void __init smu_i2c_probe(void) |
2622 |
+ bus->hostdata = bus + 1; |
2623 |
+ bus->xfer = smu_i2c_xfer; |
2624 |
+ mutex_init(&bus->mutex); |
2625 |
++ lockdep_register_key(&bus->lock_key); |
2626 |
+ lockdep_set_class(&bus->mutex, &bus->lock_key); |
2627 |
+ bus->flags = 0; |
2628 |
+ list_add(&bus->link, &pmac_i2c_busses); |
2629 |
+diff --git a/arch/powerpc/platforms/powernv/opal-lpc.c b/arch/powerpc/platforms/powernv/opal-lpc.c |
2630 |
+index 1e5d51db40f84..5390c888db162 100644 |
2631 |
+--- a/arch/powerpc/platforms/powernv/opal-lpc.c |
2632 |
++++ b/arch/powerpc/platforms/powernv/opal-lpc.c |
2633 |
+@@ -396,6 +396,7 @@ void __init opal_lpc_init(void) |
2634 |
+ if (!of_get_property(np, "primary", NULL)) |
2635 |
+ continue; |
2636 |
+ opal_lpc_chip_id = of_get_ibm_chip_id(np); |
2637 |
++ of_node_put(np); |
2638 |
+ break; |
2639 |
+ } |
2640 |
+ if (opal_lpc_chip_id < 0) |
2641 |
+diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c |
2642 |
+index f143b6f111ac0..1179632560b8d 100644 |
2643 |
+--- a/arch/powerpc/sysdev/xive/spapr.c |
2644 |
++++ b/arch/powerpc/sysdev/xive/spapr.c |
2645 |
+@@ -653,6 +653,9 @@ static int xive_spapr_debug_show(struct seq_file *m, void *private) |
2646 |
+ struct xive_irq_bitmap *xibm; |
2647 |
+ char *buf = kmalloc(PAGE_SIZE, GFP_KERNEL); |
2648 |
+ |
2649 |
++ if (!buf) |
2650 |
++ return -ENOMEM; |
2651 |
++ |
2652 |
+ list_for_each_entry(xibm, &xive_irq_bitmaps, list) { |
2653 |
+ memset(buf, 0, PAGE_SIZE); |
2654 |
+ bitmap_print_to_pagebuf(true, buf, xibm->bitmap, xibm->count); |
2655 |
+diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig |
2656 |
+index f076cee11af69..20bc4b8c13b92 100644 |
2657 |
+--- a/arch/riscv/Kconfig |
2658 |
++++ b/arch/riscv/Kconfig |
2659 |
+@@ -158,10 +158,9 @@ config PA_BITS |
2660 |
+ |
2661 |
+ config PAGE_OFFSET |
2662 |
+ hex |
2663 |
+- default 0xC0000000 if 32BIT && MAXPHYSMEM_1GB |
2664 |
++ default 0xC0000000 if 32BIT |
2665 |
+ default 0x80000000 if 64BIT && !MMU |
2666 |
+- default 0xffffffff80000000 if 64BIT && MAXPHYSMEM_2GB |
2667 |
+- default 0xffffffe000000000 if 64BIT && MAXPHYSMEM_128GB |
2668 |
++ default 0xffffffe000000000 if 64BIT |
2669 |
+ |
2670 |
+ config KASAN_SHADOW_OFFSET |
2671 |
+ hex |
2672 |
+@@ -270,24 +269,6 @@ config MODULE_SECTIONS |
2673 |
+ bool |
2674 |
+ select HAVE_MOD_ARCH_SPECIFIC |
2675 |
+ |
2676 |
+-choice |
2677 |
+- prompt "Maximum Physical Memory" |
2678 |
+- default MAXPHYSMEM_1GB if 32BIT |
2679 |
+- default MAXPHYSMEM_2GB if 64BIT && CMODEL_MEDLOW |
2680 |
+- default MAXPHYSMEM_128GB if 64BIT && CMODEL_MEDANY |
2681 |
+- |
2682 |
+- config MAXPHYSMEM_1GB |
2683 |
+- depends on 32BIT |
2684 |
+- bool "1GiB" |
2685 |
+- config MAXPHYSMEM_2GB |
2686 |
+- depends on 64BIT && CMODEL_MEDLOW |
2687 |
+- bool "2GiB" |
2688 |
+- config MAXPHYSMEM_128GB |
2689 |
+- depends on 64BIT && CMODEL_MEDANY |
2690 |
+- bool "128GiB" |
2691 |
+-endchoice |
2692 |
+- |
2693 |
+- |
2694 |
+ config SMP |
2695 |
+ bool "Symmetric Multi-Processing" |
2696 |
+ help |
2697 |
+diff --git a/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi b/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi |
2698 |
+index b12fd594e7172..4ef4bcb748729 100644 |
2699 |
+--- a/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi |
2700 |
++++ b/arch/riscv/boot/dts/microchip/microchip-mpfs.dtsi |
2701 |
+@@ -9,9 +9,6 @@ |
2702 |
+ model = "Microchip PolarFire SoC"; |
2703 |
+ compatible = "microchip,mpfs"; |
2704 |
+ |
2705 |
+- chosen { |
2706 |
+- }; |
2707 |
+- |
2708 |
+ cpus { |
2709 |
+ #address-cells = <1>; |
2710 |
+ #size-cells = <0>; |
2711 |
+diff --git a/arch/riscv/configs/nommu_k210_defconfig b/arch/riscv/configs/nommu_k210_defconfig |
2712 |
+index b16a2a12c82a8..3b9f83221f9c2 100644 |
2713 |
+--- a/arch/riscv/configs/nommu_k210_defconfig |
2714 |
++++ b/arch/riscv/configs/nommu_k210_defconfig |
2715 |
+@@ -29,8 +29,6 @@ CONFIG_EMBEDDED=y |
2716 |
+ CONFIG_SLOB=y |
2717 |
+ # CONFIG_MMU is not set |
2718 |
+ CONFIG_SOC_CANAAN=y |
2719 |
+-CONFIG_SOC_CANAAN_K210_DTB_SOURCE="k210_generic" |
2720 |
+-CONFIG_MAXPHYSMEM_2GB=y |
2721 |
+ CONFIG_SMP=y |
2722 |
+ CONFIG_NR_CPUS=2 |
2723 |
+ CONFIG_CMDLINE="earlycon console=ttySIF0" |
2724 |
+diff --git a/arch/riscv/configs/nommu_k210_sdcard_defconfig b/arch/riscv/configs/nommu_k210_sdcard_defconfig |
2725 |
+index 61f887f654199..d68b743d580f8 100644 |
2726 |
+--- a/arch/riscv/configs/nommu_k210_sdcard_defconfig |
2727 |
++++ b/arch/riscv/configs/nommu_k210_sdcard_defconfig |
2728 |
+@@ -21,8 +21,6 @@ CONFIG_EMBEDDED=y |
2729 |
+ CONFIG_SLOB=y |
2730 |
+ # CONFIG_MMU is not set |
2731 |
+ CONFIG_SOC_CANAAN=y |
2732 |
+-CONFIG_SOC_CANAAN_K210_DTB_SOURCE="k210_generic" |
2733 |
+-CONFIG_MAXPHYSMEM_2GB=y |
2734 |
+ CONFIG_SMP=y |
2735 |
+ CONFIG_NR_CPUS=2 |
2736 |
+ CONFIG_CMDLINE="earlycon console=ttySIF0 rootdelay=2 root=/dev/mmcblk0p1 ro" |
2737 |
+diff --git a/arch/riscv/configs/nommu_virt_defconfig b/arch/riscv/configs/nommu_virt_defconfig |
2738 |
+index e046a0babde43..f224be697785f 100644 |
2739 |
+--- a/arch/riscv/configs/nommu_virt_defconfig |
2740 |
++++ b/arch/riscv/configs/nommu_virt_defconfig |
2741 |
+@@ -27,7 +27,6 @@ CONFIG_SLOB=y |
2742 |
+ # CONFIG_SLAB_MERGE_DEFAULT is not set |
2743 |
+ # CONFIG_MMU is not set |
2744 |
+ CONFIG_SOC_VIRT=y |
2745 |
+-CONFIG_MAXPHYSMEM_2GB=y |
2746 |
+ CONFIG_SMP=y |
2747 |
+ CONFIG_CMDLINE="root=/dev/vda rw earlycon=uart8250,mmio,0x10000000,115200n8 console=ttyS0" |
2748 |
+ CONFIG_CMDLINE_FORCE=y |
2749 |
+diff --git a/arch/riscv/include/asm/smp.h b/arch/riscv/include/asm/smp.h |
2750 |
+index a7d2811f35365..62d0e6e61da83 100644 |
2751 |
+--- a/arch/riscv/include/asm/smp.h |
2752 |
++++ b/arch/riscv/include/asm/smp.h |
2753 |
+@@ -43,7 +43,6 @@ void arch_send_call_function_ipi_mask(struct cpumask *mask); |
2754 |
+ void arch_send_call_function_single_ipi(int cpu); |
2755 |
+ |
2756 |
+ int riscv_hartid_to_cpuid(int hartid); |
2757 |
+-void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out); |
2758 |
+ |
2759 |
+ /* Set custom IPI operations */ |
2760 |
+ void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops); |
2761 |
+@@ -85,13 +84,6 @@ static inline unsigned long cpuid_to_hartid_map(int cpu) |
2762 |
+ return boot_cpu_hartid; |
2763 |
+ } |
2764 |
+ |
2765 |
+-static inline void riscv_cpuid_to_hartid_mask(const struct cpumask *in, |
2766 |
+- struct cpumask *out) |
2767 |
+-{ |
2768 |
+- cpumask_clear(out); |
2769 |
+- cpumask_set_cpu(boot_cpu_hartid, out); |
2770 |
+-} |
2771 |
+- |
2772 |
+ static inline void riscv_set_ipi_ops(const struct riscv_ipi_ops *ops) |
2773 |
+ { |
2774 |
+ } |
2775 |
+@@ -102,6 +94,8 @@ static inline void riscv_clear_ipi(void) |
2776 |
+ |
2777 |
+ #endif /* CONFIG_SMP */ |
2778 |
+ |
2779 |
++void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out); |
2780 |
++ |
2781 |
+ #if defined(CONFIG_HOTPLUG_CPU) && (CONFIG_SMP) |
2782 |
+ bool cpu_has_hotplug(unsigned int cpu); |
2783 |
+ #else |
2784 |
+diff --git a/arch/riscv/kernel/kexec_relocate.S b/arch/riscv/kernel/kexec_relocate.S |
2785 |
+index a80b52a74f58c..059c5e216ae75 100644 |
2786 |
+--- a/arch/riscv/kernel/kexec_relocate.S |
2787 |
++++ b/arch/riscv/kernel/kexec_relocate.S |
2788 |
+@@ -159,25 +159,15 @@ SYM_CODE_START(riscv_kexec_norelocate) |
2789 |
+ * s0: (const) Phys address to jump to |
2790 |
+ * s1: (const) Phys address of the FDT image |
2791 |
+ * s2: (const) The hartid of the current hart |
2792 |
+- * s3: (const) kernel_map.va_pa_offset, used when switching MMU off |
2793 |
+ */ |
2794 |
+ mv s0, a1 |
2795 |
+ mv s1, a2 |
2796 |
+ mv s2, a3 |
2797 |
+- mv s3, a4 |
2798 |
+ |
2799 |
+ /* Disable / cleanup interrupts */ |
2800 |
+ csrw CSR_SIE, zero |
2801 |
+ csrw CSR_SIP, zero |
2802 |
+ |
2803 |
+- /* Switch to physical addressing */ |
2804 |
+- la s4, 1f |
2805 |
+- sub s4, s4, s3 |
2806 |
+- csrw CSR_STVEC, s4 |
2807 |
+- csrw CSR_SATP, zero |
2808 |
+- |
2809 |
+-.align 2 |
2810 |
+-1: |
2811 |
+ /* Pass the arguments to the next kernel / Cleanup*/ |
2812 |
+ mv a0, s2 |
2813 |
+ mv a1, s1 |
2814 |
+@@ -214,7 +204,15 @@ SYM_CODE_START(riscv_kexec_norelocate) |
2815 |
+ csrw CSR_SCAUSE, zero |
2816 |
+ csrw CSR_SSCRATCH, zero |
2817 |
+ |
2818 |
+- jalr zero, a2, 0 |
2819 |
++ /* |
2820 |
++ * Switch to physical addressing |
2821 |
++ * This will also trigger a jump to CSR_STVEC |
2822 |
++ * which in this case is the address of the new |
2823 |
++ * kernel. |
2824 |
++ */ |
2825 |
++ csrw CSR_STVEC, a2 |
2826 |
++ csrw CSR_SATP, zero |
2827 |
++ |
2828 |
+ SYM_CODE_END(riscv_kexec_norelocate) |
2829 |
+ |
2830 |
+ .section ".rodata" |
2831 |
+diff --git a/arch/riscv/kernel/machine_kexec.c b/arch/riscv/kernel/machine_kexec.c |
2832 |
+index e6eca271a4d60..cbef0fc73afa8 100644 |
2833 |
+--- a/arch/riscv/kernel/machine_kexec.c |
2834 |
++++ b/arch/riscv/kernel/machine_kexec.c |
2835 |
+@@ -169,7 +169,8 @@ machine_kexec(struct kimage *image) |
2836 |
+ struct kimage_arch *internal = &image->arch; |
2837 |
+ unsigned long jump_addr = (unsigned long) image->start; |
2838 |
+ unsigned long first_ind_entry = (unsigned long) &image->head; |
2839 |
+- unsigned long this_hart_id = raw_smp_processor_id(); |
2840 |
++ unsigned long this_cpu_id = smp_processor_id(); |
2841 |
++ unsigned long this_hart_id = cpuid_to_hartid_map(this_cpu_id); |
2842 |
+ unsigned long fdt_addr = internal->fdt_addr; |
2843 |
+ void *control_code_buffer = page_address(image->control_code_page); |
2844 |
+ riscv_kexec_method kexec_method = NULL; |
2845 |
+diff --git a/arch/riscv/kernel/setup.c b/arch/riscv/kernel/setup.c |
2846 |
+index b9620e5f00baf..6c5caf5eb9061 100644 |
2847 |
+--- a/arch/riscv/kernel/setup.c |
2848 |
++++ b/arch/riscv/kernel/setup.c |
2849 |
+@@ -59,6 +59,16 @@ atomic_t hart_lottery __section(".sdata") |
2850 |
+ unsigned long boot_cpu_hartid; |
2851 |
+ static DEFINE_PER_CPU(struct cpu, cpu_devices); |
2852 |
+ |
2853 |
++void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out) |
2854 |
++{ |
2855 |
++ int cpu; |
2856 |
++ |
2857 |
++ cpumask_clear(out); |
2858 |
++ for_each_cpu(cpu, in) |
2859 |
++ cpumask_set_cpu(cpuid_to_hartid_map(cpu), out); |
2860 |
++} |
2861 |
++EXPORT_SYMBOL_GPL(riscv_cpuid_to_hartid_mask); |
2862 |
++ |
2863 |
+ /* |
2864 |
+ * Place kernel memory regions on the resource tree so that |
2865 |
+ * kexec-tools can retrieve them from /proc/iomem. While there |
2866 |
+diff --git a/arch/riscv/kernel/smp.c b/arch/riscv/kernel/smp.c |
2867 |
+index 921d9d7df4001..d0147294691d9 100644 |
2868 |
+--- a/arch/riscv/kernel/smp.c |
2869 |
++++ b/arch/riscv/kernel/smp.c |
2870 |
+@@ -59,16 +59,6 @@ int riscv_hartid_to_cpuid(int hartid) |
2871 |
+ return -ENOENT; |
2872 |
+ } |
2873 |
+ |
2874 |
+-void riscv_cpuid_to_hartid_mask(const struct cpumask *in, struct cpumask *out) |
2875 |
+-{ |
2876 |
+- int cpu; |
2877 |
+- |
2878 |
+- cpumask_clear(out); |
2879 |
+- for_each_cpu(cpu, in) |
2880 |
+- cpumask_set_cpu(cpuid_to_hartid_map(cpu), out); |
2881 |
+-} |
2882 |
+-EXPORT_SYMBOL_GPL(riscv_cpuid_to_hartid_mask); |
2883 |
+- |
2884 |
+ bool arch_match_cpu_phys_id(int cpu, u64 phys_id) |
2885 |
+ { |
2886 |
+ return phys_id == cpuid_to_hartid_map(cpu); |
2887 |
+diff --git a/arch/riscv/mm/init.c b/arch/riscv/mm/init.c |
2888 |
+index c0cddf0fc22db..5e7decd875258 100644 |
2889 |
+--- a/arch/riscv/mm/init.c |
2890 |
++++ b/arch/riscv/mm/init.c |
2891 |
+@@ -187,10 +187,10 @@ static void __init setup_bootmem(void) |
2892 |
+ |
2893 |
+ |
2894 |
+ phys_ram_end = memblock_end_of_DRAM(); |
2895 |
+-#ifndef CONFIG_64BIT |
2896 |
+ #ifndef CONFIG_XIP_KERNEL |
2897 |
+ phys_ram_base = memblock_start_of_DRAM(); |
2898 |
+ #endif |
2899 |
++#ifndef CONFIG_64BIT |
2900 |
+ /* |
2901 |
+ * memblock allocator is not aware of the fact that last 4K bytes of |
2902 |
+ * the addressable memory can not be mapped because of IS_ERR_VALUE |
2903 |
+@@ -813,13 +813,22 @@ static void __init reserve_crashkernel(void) |
2904 |
+ /* |
2905 |
+ * Current riscv boot protocol requires 2MB alignment for |
2906 |
+ * RV64 and 4MB alignment for RV32 (hugepage size) |
2907 |
++ * |
2908 |
++ * Try to alloc from 32bit addressible physical memory so that |
2909 |
++ * swiotlb can work on the crash kernel. |
2910 |
+ */ |
2911 |
+ crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE, |
2912 |
+- search_start, search_end); |
2913 |
++ search_start, |
2914 |
++ min(search_end, (unsigned long) SZ_4G)); |
2915 |
+ if (crash_base == 0) { |
2916 |
+- pr_warn("crashkernel: couldn't allocate %lldKB\n", |
2917 |
+- crash_size >> 10); |
2918 |
+- return; |
2919 |
++ /* Try again without restricting region to 32bit addressible memory */ |
2920 |
++ crash_base = memblock_phys_alloc_range(crash_size, PMD_SIZE, |
2921 |
++ search_start, search_end); |
2922 |
++ if (crash_base == 0) { |
2923 |
++ pr_warn("crashkernel: couldn't allocate %lldKB\n", |
2924 |
++ crash_size >> 10); |
2925 |
++ return; |
2926 |
++ } |
2927 |
+ } |
2928 |
+ |
2929 |
+ pr_info("crashkernel: reserved 0x%016llx - 0x%016llx (%lld MB)\n", |
2930 |
+diff --git a/arch/s390/mm/pgalloc.c b/arch/s390/mm/pgalloc.c |
2931 |
+index 781965f7210eb..91e478e09b54b 100644 |
2932 |
+--- a/arch/s390/mm/pgalloc.c |
2933 |
++++ b/arch/s390/mm/pgalloc.c |
2934 |
+@@ -244,13 +244,15 @@ void page_table_free(struct mm_struct *mm, unsigned long *table) |
2935 |
+ /* Free 2K page table fragment of a 4K page */ |
2936 |
+ bit = ((unsigned long) table & ~PAGE_MASK)/(PTRS_PER_PTE*sizeof(pte_t)); |
2937 |
+ spin_lock_bh(&mm->context.lock); |
2938 |
+- mask = atomic_xor_bits(&page->_refcount, 1U << (bit + 24)); |
2939 |
++ mask = atomic_xor_bits(&page->_refcount, 0x11U << (bit + 24)); |
2940 |
+ mask >>= 24; |
2941 |
+ if (mask & 3) |
2942 |
+ list_add(&page->lru, &mm->context.pgtable_list); |
2943 |
+ else |
2944 |
+ list_del(&page->lru); |
2945 |
+ spin_unlock_bh(&mm->context.lock); |
2946 |
++ mask = atomic_xor_bits(&page->_refcount, 0x10U << (bit + 24)); |
2947 |
++ mask >>= 24; |
2948 |
+ if (mask != 0) |
2949 |
+ return; |
2950 |
+ } else { |
2951 |
+diff --git a/arch/sh/configs/titan_defconfig b/arch/sh/configs/titan_defconfig |
2952 |
+index ba887f1351be6..cd5c58916c65a 100644 |
2953 |
+--- a/arch/sh/configs/titan_defconfig |
2954 |
++++ b/arch/sh/configs/titan_defconfig |
2955 |
+@@ -242,7 +242,6 @@ CONFIG_NFSD=y |
2956 |
+ CONFIG_NFSD_V3=y |
2957 |
+ CONFIG_SMB_FS=m |
2958 |
+ CONFIG_CIFS=m |
2959 |
+-CONFIG_CIFS_WEAK_PW_HASH=y |
2960 |
+ CONFIG_PARTITION_ADVANCED=y |
2961 |
+ CONFIG_NLS_CODEPAGE_437=m |
2962 |
+ CONFIG_NLS_ASCII=m |
2963 |
+diff --git a/arch/um/.gitignore b/arch/um/.gitignore |
2964 |
+index 6323e5571887e..d69ea5b562cee 100644 |
2965 |
+--- a/arch/um/.gitignore |
2966 |
++++ b/arch/um/.gitignore |
2967 |
+@@ -2,3 +2,4 @@ |
2968 |
+ kernel/config.c |
2969 |
+ kernel/config.tmp |
2970 |
+ kernel/vmlinux.lds |
2971 |
++kernel/capflags.c |
2972 |
+diff --git a/arch/um/drivers/virt-pci.c b/arch/um/drivers/virt-pci.c |
2973 |
+index c080666330234..0ab58016db22f 100644 |
2974 |
+--- a/arch/um/drivers/virt-pci.c |
2975 |
++++ b/arch/um/drivers/virt-pci.c |
2976 |
+@@ -181,15 +181,15 @@ static unsigned long um_pci_cfgspace_read(void *priv, unsigned int offset, |
2977 |
+ /* buf->data is maximum size - we may only use parts of it */ |
2978 |
+ struct um_pci_message_buffer *buf; |
2979 |
+ u8 *data; |
2980 |
+- unsigned long ret = ~0ULL; |
2981 |
++ unsigned long ret = ULONG_MAX; |
2982 |
+ |
2983 |
+ if (!dev) |
2984 |
+- return ~0ULL; |
2985 |
++ return ULONG_MAX; |
2986 |
+ |
2987 |
+ buf = get_cpu_var(um_pci_msg_bufs); |
2988 |
+ data = buf->data; |
2989 |
+ |
2990 |
+- memset(data, 0xff, sizeof(data)); |
2991 |
++ memset(buf->data, 0xff, sizeof(buf->data)); |
2992 |
+ |
2993 |
+ switch (size) { |
2994 |
+ case 1: |
2995 |
+@@ -304,7 +304,7 @@ static unsigned long um_pci_bar_read(void *priv, unsigned int offset, |
2996 |
+ /* buf->data is maximum size - we may only use parts of it */ |
2997 |
+ struct um_pci_message_buffer *buf; |
2998 |
+ u8 *data; |
2999 |
+- unsigned long ret = ~0ULL; |
3000 |
++ unsigned long ret = ULONG_MAX; |
3001 |
+ |
3002 |
+ buf = get_cpu_var(um_pci_msg_bufs); |
3003 |
+ data = buf->data; |
3004 |
+diff --git a/arch/um/drivers/virtio_uml.c b/arch/um/drivers/virtio_uml.c |
3005 |
+index d51e445df7976..7755cb4ff9fc6 100644 |
3006 |
+--- a/arch/um/drivers/virtio_uml.c |
3007 |
++++ b/arch/um/drivers/virtio_uml.c |
3008 |
+@@ -1090,6 +1090,8 @@ static void virtio_uml_release_dev(struct device *d) |
3009 |
+ container_of(d, struct virtio_device, dev); |
3010 |
+ struct virtio_uml_device *vu_dev = to_virtio_uml_device(vdev); |
3011 |
+ |
3012 |
++ time_travel_propagate_time(); |
3013 |
++ |
3014 |
+ /* might not have been opened due to not negotiating the feature */ |
3015 |
+ if (vu_dev->req_fd >= 0) { |
3016 |
+ um_free_irq(vu_dev->irq, vu_dev); |
3017 |
+@@ -1136,6 +1138,8 @@ static int virtio_uml_probe(struct platform_device *pdev) |
3018 |
+ vu_dev->pdev = pdev; |
3019 |
+ vu_dev->req_fd = -1; |
3020 |
+ |
3021 |
++ time_travel_propagate_time(); |
3022 |
++ |
3023 |
+ do { |
3024 |
+ rc = os_connect_socket(pdata->socket_path); |
3025 |
+ } while (rc == -EINTR); |
3026 |
+diff --git a/arch/um/include/asm/delay.h b/arch/um/include/asm/delay.h |
3027 |
+index 56fc2b8f2dd01..e79b2ab6f40c8 100644 |
3028 |
+--- a/arch/um/include/asm/delay.h |
3029 |
++++ b/arch/um/include/asm/delay.h |
3030 |
+@@ -14,7 +14,7 @@ static inline void um_ndelay(unsigned long nsecs) |
3031 |
+ ndelay(nsecs); |
3032 |
+ } |
3033 |
+ #undef ndelay |
3034 |
+-#define ndelay um_ndelay |
3035 |
++#define ndelay(n) um_ndelay(n) |
3036 |
+ |
3037 |
+ static inline void um_udelay(unsigned long usecs) |
3038 |
+ { |
3039 |
+@@ -26,5 +26,5 @@ static inline void um_udelay(unsigned long usecs) |
3040 |
+ udelay(usecs); |
3041 |
+ } |
3042 |
+ #undef udelay |
3043 |
+-#define udelay um_udelay |
3044 |
++#define udelay(n) um_udelay(n) |
3045 |
+ #endif /* __UM_DELAY_H */ |
3046 |
+diff --git a/arch/um/include/asm/irqflags.h b/arch/um/include/asm/irqflags.h |
3047 |
+index dab5744e9253d..1e69ef5bc35e0 100644 |
3048 |
+--- a/arch/um/include/asm/irqflags.h |
3049 |
++++ b/arch/um/include/asm/irqflags.h |
3050 |
+@@ -3,7 +3,7 @@ |
3051 |
+ #define __UM_IRQFLAGS_H |
3052 |
+ |
3053 |
+ extern int signals_enabled; |
3054 |
+-int set_signals(int enable); |
3055 |
++int um_set_signals(int enable); |
3056 |
+ void block_signals(void); |
3057 |
+ void unblock_signals(void); |
3058 |
+ |
3059 |
+@@ -16,7 +16,7 @@ static inline unsigned long arch_local_save_flags(void) |
3060 |
+ #define arch_local_irq_restore arch_local_irq_restore |
3061 |
+ static inline void arch_local_irq_restore(unsigned long flags) |
3062 |
+ { |
3063 |
+- set_signals(flags); |
3064 |
++ um_set_signals(flags); |
3065 |
+ } |
3066 |
+ |
3067 |
+ #define arch_local_irq_enable arch_local_irq_enable |
3068 |
+diff --git a/arch/um/include/shared/longjmp.h b/arch/um/include/shared/longjmp.h |
3069 |
+index bdb2869b72b31..8863319039f3d 100644 |
3070 |
+--- a/arch/um/include/shared/longjmp.h |
3071 |
++++ b/arch/um/include/shared/longjmp.h |
3072 |
+@@ -18,7 +18,7 @@ extern void longjmp(jmp_buf, int); |
3073 |
+ enable = *(volatile int *)&signals_enabled; \ |
3074 |
+ n = setjmp(*buf); \ |
3075 |
+ if(n != 0) \ |
3076 |
+- set_signals_trace(enable); \ |
3077 |
++ um_set_signals_trace(enable); \ |
3078 |
+ n; }) |
3079 |
+ |
3080 |
+ #endif |
3081 |
+diff --git a/arch/um/include/shared/os.h b/arch/um/include/shared/os.h |
3082 |
+index 96d400387c93e..03ffbdddcc480 100644 |
3083 |
+--- a/arch/um/include/shared/os.h |
3084 |
++++ b/arch/um/include/shared/os.h |
3085 |
+@@ -238,8 +238,8 @@ extern void send_sigio_to_self(void); |
3086 |
+ extern int change_sig(int signal, int on); |
3087 |
+ extern void block_signals(void); |
3088 |
+ extern void unblock_signals(void); |
3089 |
+-extern int set_signals(int enable); |
3090 |
+-extern int set_signals_trace(int enable); |
3091 |
++extern int um_set_signals(int enable); |
3092 |
++extern int um_set_signals_trace(int enable); |
3093 |
+ extern int os_is_signal_stack(void); |
3094 |
+ extern void deliver_alarm(void); |
3095 |
+ extern void register_pm_wake_signal(void); |
3096 |
+diff --git a/arch/um/include/shared/registers.h b/arch/um/include/shared/registers.h |
3097 |
+index 0c50fa6e8a55b..fbb709a222839 100644 |
3098 |
+--- a/arch/um/include/shared/registers.h |
3099 |
++++ b/arch/um/include/shared/registers.h |
3100 |
+@@ -16,8 +16,8 @@ extern int restore_fp_registers(int pid, unsigned long *fp_regs); |
3101 |
+ extern int save_fpx_registers(int pid, unsigned long *fp_regs); |
3102 |
+ extern int restore_fpx_registers(int pid, unsigned long *fp_regs); |
3103 |
+ extern int save_registers(int pid, struct uml_pt_regs *regs); |
3104 |
+-extern int restore_registers(int pid, struct uml_pt_regs *regs); |
3105 |
+-extern int init_registers(int pid); |
3106 |
++extern int restore_pid_registers(int pid, struct uml_pt_regs *regs); |
3107 |
++extern int init_pid_registers(int pid); |
3108 |
+ extern void get_safe_registers(unsigned long *regs, unsigned long *fp_regs); |
3109 |
+ extern unsigned long get_thread_reg(int reg, jmp_buf *buf); |
3110 |
+ extern int get_fp_registers(int pid, unsigned long *regs); |
3111 |
+diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c |
3112 |
+index b1e5634398d09..3a85bde3e1734 100644 |
3113 |
+--- a/arch/um/kernel/ksyms.c |
3114 |
++++ b/arch/um/kernel/ksyms.c |
3115 |
+@@ -6,7 +6,7 @@ |
3116 |
+ #include <linux/module.h> |
3117 |
+ #include <os.h> |
3118 |
+ |
3119 |
+-EXPORT_SYMBOL(set_signals); |
3120 |
++EXPORT_SYMBOL(um_set_signals); |
3121 |
+ EXPORT_SYMBOL(signals_enabled); |
3122 |
+ |
3123 |
+ EXPORT_SYMBOL(os_stat_fd); |
3124 |
+diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c |
3125 |
+index 2d9270508e156..b123955be7acc 100644 |
3126 |
+--- a/arch/um/os-Linux/registers.c |
3127 |
++++ b/arch/um/os-Linux/registers.c |
3128 |
+@@ -21,7 +21,7 @@ int save_registers(int pid, struct uml_pt_regs *regs) |
3129 |
+ return 0; |
3130 |
+ } |
3131 |
+ |
3132 |
+-int restore_registers(int pid, struct uml_pt_regs *regs) |
3133 |
++int restore_pid_registers(int pid, struct uml_pt_regs *regs) |
3134 |
+ { |
3135 |
+ int err; |
3136 |
+ |
3137 |
+@@ -36,7 +36,7 @@ int restore_registers(int pid, struct uml_pt_regs *regs) |
3138 |
+ static unsigned long exec_regs[MAX_REG_NR]; |
3139 |
+ static unsigned long exec_fp_regs[FP_SIZE]; |
3140 |
+ |
3141 |
+-int init_registers(int pid) |
3142 |
++int init_pid_registers(int pid) |
3143 |
+ { |
3144 |
+ int err; |
3145 |
+ |
3146 |
+diff --git a/arch/um/os-Linux/sigio.c b/arch/um/os-Linux/sigio.c |
3147 |
+index 6597ea1986ffa..9e71794839e87 100644 |
3148 |
+--- a/arch/um/os-Linux/sigio.c |
3149 |
++++ b/arch/um/os-Linux/sigio.c |
3150 |
+@@ -132,7 +132,7 @@ static void update_thread(void) |
3151 |
+ int n; |
3152 |
+ char c; |
3153 |
+ |
3154 |
+- flags = set_signals_trace(0); |
3155 |
++ flags = um_set_signals_trace(0); |
3156 |
+ CATCH_EINTR(n = write(sigio_private[0], &c, sizeof(c))); |
3157 |
+ if (n != sizeof(c)) { |
3158 |
+ printk(UM_KERN_ERR "update_thread : write failed, err = %d\n", |
3159 |
+@@ -147,7 +147,7 @@ static void update_thread(void) |
3160 |
+ goto fail; |
3161 |
+ } |
3162 |
+ |
3163 |
+- set_signals_trace(flags); |
3164 |
++ um_set_signals_trace(flags); |
3165 |
+ return; |
3166 |
+ fail: |
3167 |
+ /* Critical section start */ |
3168 |
+@@ -161,7 +161,7 @@ static void update_thread(void) |
3169 |
+ close(write_sigio_fds[0]); |
3170 |
+ close(write_sigio_fds[1]); |
3171 |
+ /* Critical section end */ |
3172 |
+- set_signals_trace(flags); |
3173 |
++ um_set_signals_trace(flags); |
3174 |
+ } |
3175 |
+ |
3176 |
+ int __add_sigio_fd(int fd) |
3177 |
+diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c |
3178 |
+index 6cf098c23a394..24a403a70a020 100644 |
3179 |
+--- a/arch/um/os-Linux/signal.c |
3180 |
++++ b/arch/um/os-Linux/signal.c |
3181 |
+@@ -94,7 +94,7 @@ void sig_handler(int sig, struct siginfo *si, mcontext_t *mc) |
3182 |
+ |
3183 |
+ sig_handler_common(sig, si, mc); |
3184 |
+ |
3185 |
+- set_signals_trace(enabled); |
3186 |
++ um_set_signals_trace(enabled); |
3187 |
+ } |
3188 |
+ |
3189 |
+ static void timer_real_alarm_handler(mcontext_t *mc) |
3190 |
+@@ -126,7 +126,7 @@ void timer_alarm_handler(int sig, struct siginfo *unused_si, mcontext_t *mc) |
3191 |
+ |
3192 |
+ signals_active &= ~SIGALRM_MASK; |
3193 |
+ |
3194 |
+- set_signals_trace(enabled); |
3195 |
++ um_set_signals_trace(enabled); |
3196 |
+ } |
3197 |
+ |
3198 |
+ void deliver_alarm(void) { |
3199 |
+@@ -348,7 +348,7 @@ void unblock_signals(void) |
3200 |
+ } |
3201 |
+ } |
3202 |
+ |
3203 |
+-int set_signals(int enable) |
3204 |
++int um_set_signals(int enable) |
3205 |
+ { |
3206 |
+ int ret; |
3207 |
+ if (signals_enabled == enable) |
3208 |
+@@ -362,7 +362,7 @@ int set_signals(int enable) |
3209 |
+ return ret; |
3210 |
+ } |
3211 |
+ |
3212 |
+-int set_signals_trace(int enable) |
3213 |
++int um_set_signals_trace(int enable) |
3214 |
+ { |
3215 |
+ int ret; |
3216 |
+ if (signals_enabled == enable) |
3217 |
+diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c |
3218 |
+index 8a72c99994eb1..e3ee4db58b40d 100644 |
3219 |
+--- a/arch/um/os-Linux/start_up.c |
3220 |
++++ b/arch/um/os-Linux/start_up.c |
3221 |
+@@ -368,7 +368,7 @@ void __init os_early_checks(void) |
3222 |
+ check_tmpexec(); |
3223 |
+ |
3224 |
+ pid = start_ptraced_child(); |
3225 |
+- if (init_registers(pid)) |
3226 |
++ if (init_pid_registers(pid)) |
3227 |
+ fatal("Failed to initialize default registers"); |
3228 |
+ stop_ptraced_child(pid, 1, 1); |
3229 |
+ } |
3230 |
+diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile |
3231 |
+index 431bf7f846c3c..e118136460518 100644 |
3232 |
+--- a/arch/x86/boot/compressed/Makefile |
3233 |
++++ b/arch/x86/boot/compressed/Makefile |
3234 |
+@@ -28,7 +28,11 @@ KCOV_INSTRUMENT := n |
3235 |
+ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ |
3236 |
+ vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4 vmlinux.bin.zst |
3237 |
+ |
3238 |
+-KBUILD_CFLAGS := -m$(BITS) -O2 |
3239 |
++# CLANG_FLAGS must come before any cc-disable-warning or cc-option calls in |
3240 |
++# case of cross compiling, as it has the '--target=' flag, which is needed to |
3241 |
++# avoid errors with '-march=i386', and future flags may depend on the target to |
3242 |
++# be valid. |
3243 |
++KBUILD_CFLAGS := -m$(BITS) -O2 $(CLANG_FLAGS) |
3244 |
+ KBUILD_CFLAGS += -fno-strict-aliasing -fPIE |
3245 |
+ KBUILD_CFLAGS += -Wundef |
3246 |
+ KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING |
3247 |
+@@ -47,7 +51,6 @@ KBUILD_CFLAGS += -D__DISABLE_EXPORTS |
3248 |
+ # Disable relocation relaxation in case the link is not PIE. |
3249 |
+ KBUILD_CFLAGS += $(call as-option,-Wa$(comma)-mrelax-relocations=no) |
3250 |
+ KBUILD_CFLAGS += -include $(srctree)/include/linux/hidden.h |
3251 |
+-KBUILD_CFLAGS += $(CLANG_FLAGS) |
3252 |
+ |
3253 |
+ # sev.c indirectly inludes inat-table.h which is generated during |
3254 |
+ # compilation and stored in $(objtree). Add the directory to the includes so |
3255 |
+diff --git a/arch/x86/configs/i386_defconfig b/arch/x86/configs/i386_defconfig |
3256 |
+index e81885384f604..99398cbdae434 100644 |
3257 |
+--- a/arch/x86/configs/i386_defconfig |
3258 |
++++ b/arch/x86/configs/i386_defconfig |
3259 |
+@@ -262,3 +262,4 @@ CONFIG_BLK_DEV_IO_TRACE=y |
3260 |
+ CONFIG_PROVIDE_OHCI1394_DMA_INIT=y |
3261 |
+ CONFIG_EARLY_PRINTK_DBGP=y |
3262 |
+ CONFIG_DEBUG_BOOT_PARAMS=y |
3263 |
++CONFIG_KALLSYMS_ALL=y |
3264 |
+diff --git a/arch/x86/configs/x86_64_defconfig b/arch/x86/configs/x86_64_defconfig |
3265 |
+index e8a7a0af2bdaa..d7298b104a456 100644 |
3266 |
+--- a/arch/x86/configs/x86_64_defconfig |
3267 |
++++ b/arch/x86/configs/x86_64_defconfig |
3268 |
+@@ -258,3 +258,4 @@ CONFIG_BLK_DEV_IO_TRACE=y |
3269 |
+ CONFIG_PROVIDE_OHCI1394_DMA_INIT=y |
3270 |
+ CONFIG_EARLY_PRINTK_DBGP=y |
3271 |
+ CONFIG_DEBUG_BOOT_PARAMS=y |
3272 |
++CONFIG_KALLSYMS_ALL=y |
3273 |
+diff --git a/arch/x86/crypto/aesni-intel_glue.c b/arch/x86/crypto/aesni-intel_glue.c |
3274 |
+index e09f4672dd382..41901ba9d3a2c 100644 |
3275 |
+--- a/arch/x86/crypto/aesni-intel_glue.c |
3276 |
++++ b/arch/x86/crypto/aesni-intel_glue.c |
3277 |
+@@ -1107,7 +1107,7 @@ static struct aead_alg aesni_aeads[] = { { |
3278 |
+ .cra_flags = CRYPTO_ALG_INTERNAL, |
3279 |
+ .cra_blocksize = 1, |
3280 |
+ .cra_ctxsize = sizeof(struct aesni_rfc4106_gcm_ctx), |
3281 |
+- .cra_alignmask = AESNI_ALIGN - 1, |
3282 |
++ .cra_alignmask = 0, |
3283 |
+ .cra_module = THIS_MODULE, |
3284 |
+ }, |
3285 |
+ }, { |
3286 |
+@@ -1124,7 +1124,7 @@ static struct aead_alg aesni_aeads[] = { { |
3287 |
+ .cra_flags = CRYPTO_ALG_INTERNAL, |
3288 |
+ .cra_blocksize = 1, |
3289 |
+ .cra_ctxsize = sizeof(struct generic_gcmaes_ctx), |
3290 |
+- .cra_alignmask = AESNI_ALIGN - 1, |
3291 |
++ .cra_alignmask = 0, |
3292 |
+ .cra_module = THIS_MODULE, |
3293 |
+ }, |
3294 |
+ } }; |
3295 |
+diff --git a/arch/x86/include/asm/realmode.h b/arch/x86/include/asm/realmode.h |
3296 |
+index 5db5d083c8732..331474b150f16 100644 |
3297 |
+--- a/arch/x86/include/asm/realmode.h |
3298 |
++++ b/arch/x86/include/asm/realmode.h |
3299 |
+@@ -89,6 +89,7 @@ static inline void set_real_mode_mem(phys_addr_t mem) |
3300 |
+ } |
3301 |
+ |
3302 |
+ void reserve_real_mode(void); |
3303 |
++void load_trampoline_pgtable(void); |
3304 |
+ |
3305 |
+ #endif /* __ASSEMBLY__ */ |
3306 |
+ |
3307 |
+diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h |
3308 |
+index 9239399e54914..55160445ea78b 100644 |
3309 |
+--- a/arch/x86/include/asm/topology.h |
3310 |
++++ b/arch/x86/include/asm/topology.h |
3311 |
+@@ -218,7 +218,7 @@ static inline void arch_set_max_freq_ratio(bool turbo_disabled) |
3312 |
+ } |
3313 |
+ #endif |
3314 |
+ |
3315 |
+-#ifdef CONFIG_ACPI_CPPC_LIB |
3316 |
++#if defined(CONFIG_ACPI_CPPC_LIB) && defined(CONFIG_SMP) |
3317 |
+ void init_freq_invariance_cppc(void); |
3318 |
+ #define init_freq_invariance_cppc init_freq_invariance_cppc |
3319 |
+ #endif |
3320 |
+diff --git a/arch/x86/include/asm/uaccess.h b/arch/x86/include/asm/uaccess.h |
3321 |
+index 5c95d242f38d7..bb1430283c726 100644 |
3322 |
+--- a/arch/x86/include/asm/uaccess.h |
3323 |
++++ b/arch/x86/include/asm/uaccess.h |
3324 |
+@@ -314,11 +314,12 @@ do { \ |
3325 |
+ do { \ |
3326 |
+ __chk_user_ptr(ptr); \ |
3327 |
+ switch (size) { \ |
3328 |
+- unsigned char x_u8__; \ |
3329 |
+- case 1: \ |
3330 |
++ case 1: { \ |
3331 |
++ unsigned char x_u8__; \ |
3332 |
+ __get_user_asm(x_u8__, ptr, "b", "=q", label); \ |
3333 |
+ (x) = x_u8__; \ |
3334 |
+ break; \ |
3335 |
++ } \ |
3336 |
+ case 2: \ |
3337 |
+ __get_user_asm(x, ptr, "w", "=r", label); \ |
3338 |
+ break; \ |
3339 |
+diff --git a/arch/x86/kernel/cpu/mce/core.c b/arch/x86/kernel/cpu/mce/core.c |
3340 |
+index 193204aee8801..e23e74e2f928d 100644 |
3341 |
+--- a/arch/x86/kernel/cpu/mce/core.c |
3342 |
++++ b/arch/x86/kernel/cpu/mce/core.c |
3343 |
+@@ -295,11 +295,17 @@ static void wait_for_panic(void) |
3344 |
+ panic("Panicing machine check CPU died"); |
3345 |
+ } |
3346 |
+ |
3347 |
+-static void mce_panic(const char *msg, struct mce *final, char *exp) |
3348 |
++static noinstr void mce_panic(const char *msg, struct mce *final, char *exp) |
3349 |
+ { |
3350 |
+- int apei_err = 0; |
3351 |
+ struct llist_node *pending; |
3352 |
+ struct mce_evt_llist *l; |
3353 |
++ int apei_err = 0; |
3354 |
++ |
3355 |
++ /* |
3356 |
++ * Allow instrumentation around external facilities usage. Not that it |
3357 |
++ * matters a whole lot since the machine is going to panic anyway. |
3358 |
++ */ |
3359 |
++ instrumentation_begin(); |
3360 |
+ |
3361 |
+ if (!fake_panic) { |
3362 |
+ /* |
3363 |
+@@ -314,7 +320,7 @@ static void mce_panic(const char *msg, struct mce *final, char *exp) |
3364 |
+ } else { |
3365 |
+ /* Don't log too much for fake panic */ |
3366 |
+ if (atomic_inc_return(&mce_fake_panicked) > 1) |
3367 |
+- return; |
3368 |
++ goto out; |
3369 |
+ } |
3370 |
+ pending = mce_gen_pool_prepare_records(); |
3371 |
+ /* First print corrected ones that are still unlogged */ |
3372 |
+@@ -352,6 +358,9 @@ static void mce_panic(const char *msg, struct mce *final, char *exp) |
3373 |
+ panic(msg); |
3374 |
+ } else |
3375 |
+ pr_emerg(HW_ERR "Fake kernel panic: %s\n", msg); |
3376 |
++ |
3377 |
++out: |
3378 |
++ instrumentation_end(); |
3379 |
+ } |
3380 |
+ |
3381 |
+ /* Support code for software error injection */ |
3382 |
+@@ -682,7 +691,7 @@ static struct notifier_block mce_default_nb = { |
3383 |
+ /* |
3384 |
+ * Read ADDR and MISC registers. |
3385 |
+ */ |
3386 |
+-static void mce_read_aux(struct mce *m, int i) |
3387 |
++static noinstr void mce_read_aux(struct mce *m, int i) |
3388 |
+ { |
3389 |
+ if (m->status & MCI_STATUS_MISCV) |
3390 |
+ m->misc = mce_rdmsrl(msr_ops.misc(i)); |
3391 |
+@@ -1072,10 +1081,13 @@ static int mce_start(int *no_way_out) |
3392 |
+ * Synchronize between CPUs after main scanning loop. |
3393 |
+ * This invokes the bulk of the Monarch processing. |
3394 |
+ */ |
3395 |
+-static int mce_end(int order) |
3396 |
++static noinstr int mce_end(int order) |
3397 |
+ { |
3398 |
+- int ret = -1; |
3399 |
+ u64 timeout = (u64)mca_cfg.monarch_timeout * NSEC_PER_USEC; |
3400 |
++ int ret = -1; |
3401 |
++ |
3402 |
++ /* Allow instrumentation around external facilities. */ |
3403 |
++ instrumentation_begin(); |
3404 |
+ |
3405 |
+ if (!timeout) |
3406 |
+ goto reset; |
3407 |
+@@ -1119,7 +1131,8 @@ static int mce_end(int order) |
3408 |
+ /* |
3409 |
+ * Don't reset anything. That's done by the Monarch. |
3410 |
+ */ |
3411 |
+- return 0; |
3412 |
++ ret = 0; |
3413 |
++ goto out; |
3414 |
+ } |
3415 |
+ |
3416 |
+ /* |
3417 |
+@@ -1135,6 +1148,10 @@ reset: |
3418 |
+ * Let others run again. |
3419 |
+ */ |
3420 |
+ atomic_set(&mce_executing, 0); |
3421 |
++ |
3422 |
++out: |
3423 |
++ instrumentation_end(); |
3424 |
++ |
3425 |
+ return ret; |
3426 |
+ } |
3427 |
+ |
3428 |
+@@ -1454,6 +1471,14 @@ noinstr void do_machine_check(struct pt_regs *regs) |
3429 |
+ if (worst != MCE_AR_SEVERITY && !kill_current_task) |
3430 |
+ goto out; |
3431 |
+ |
3432 |
++ /* |
3433 |
++ * Enable instrumentation around the external facilities like |
3434 |
++ * task_work_add() (via queue_task_work()), fixup_exception() etc. |
3435 |
++ * For now, that is. Fixing this properly would need a lot more involved |
3436 |
++ * reorganization. |
3437 |
++ */ |
3438 |
++ instrumentation_begin(); |
3439 |
++ |
3440 |
+ /* Fault was in user mode and we need to take some action */ |
3441 |
+ if ((m.cs & 3) == 3) { |
3442 |
+ /* If this triggers there is no way to recover. Die hard. */ |
3443 |
+@@ -1479,6 +1504,9 @@ noinstr void do_machine_check(struct pt_regs *regs) |
3444 |
+ if (m.kflags & MCE_IN_KERNEL_COPYIN) |
3445 |
+ queue_task_work(&m, msg, kill_current_task); |
3446 |
+ } |
3447 |
++ |
3448 |
++ instrumentation_end(); |
3449 |
++ |
3450 |
+ out: |
3451 |
+ mce_wrmsrl(MSR_IA32_MCG_STATUS, 0); |
3452 |
+ } |
3453 |
+diff --git a/arch/x86/kernel/cpu/mce/inject.c b/arch/x86/kernel/cpu/mce/inject.c |
3454 |
+index 0bfc14041bbb4..b63b548497c14 100644 |
3455 |
+--- a/arch/x86/kernel/cpu/mce/inject.c |
3456 |
++++ b/arch/x86/kernel/cpu/mce/inject.c |
3457 |
+@@ -350,7 +350,7 @@ static ssize_t flags_write(struct file *filp, const char __user *ubuf, |
3458 |
+ char buf[MAX_FLAG_OPT_SIZE], *__buf; |
3459 |
+ int err; |
3460 |
+ |
3461 |
+- if (cnt > MAX_FLAG_OPT_SIZE) |
3462 |
++ if (!cnt || cnt > MAX_FLAG_OPT_SIZE) |
3463 |
+ return -EINVAL; |
3464 |
+ |
3465 |
+ if (copy_from_user(&buf, ubuf, cnt)) |
3466 |
+diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c |
3467 |
+index 391a4e2b86049..8690fab95ae4b 100644 |
3468 |
+--- a/arch/x86/kernel/early-quirks.c |
3469 |
++++ b/arch/x86/kernel/early-quirks.c |
3470 |
+@@ -515,6 +515,7 @@ static const struct intel_early_ops gen11_early_ops __initconst = { |
3471 |
+ .stolen_size = gen9_stolen_size, |
3472 |
+ }; |
3473 |
+ |
3474 |
++/* Intel integrated GPUs for which we need to reserve "stolen memory" */ |
3475 |
+ static const struct pci_device_id intel_early_ids[] __initconst = { |
3476 |
+ INTEL_I830_IDS(&i830_early_ops), |
3477 |
+ INTEL_I845G_IDS(&i845_early_ops), |
3478 |
+@@ -591,6 +592,13 @@ static void __init intel_graphics_quirks(int num, int slot, int func) |
3479 |
+ u16 device; |
3480 |
+ int i; |
3481 |
+ |
3482 |
++ /* |
3483 |
++ * Reserve "stolen memory" for an integrated GPU. If we've already |
3484 |
++ * found one, there's nothing to do for other (discrete) GPUs. |
3485 |
++ */ |
3486 |
++ if (resource_size(&intel_graphics_stolen_res)) |
3487 |
++ return; |
3488 |
++ |
3489 |
+ device = read_pci_config_16(num, slot, func, PCI_DEVICE_ID); |
3490 |
+ |
3491 |
+ for (i = 0; i < ARRAY_SIZE(intel_early_ids); i++) { |
3492 |
+@@ -703,7 +711,7 @@ static struct chipset early_qrk[] __initdata = { |
3493 |
+ { PCI_VENDOR_ID_INTEL, 0x3406, PCI_CLASS_BRIDGE_HOST, |
3494 |
+ PCI_BASE_CLASS_BRIDGE, 0, intel_remapping_check }, |
3495 |
+ { PCI_VENDOR_ID_INTEL, PCI_ANY_ID, PCI_CLASS_DISPLAY_VGA, PCI_ANY_ID, |
3496 |
+- QFLAG_APPLY_ONCE, intel_graphics_quirks }, |
3497 |
++ 0, intel_graphics_quirks }, |
3498 |
+ /* |
3499 |
+ * HPET on the current version of the Baytrail platform has accuracy |
3500 |
+ * problems: it will halt in deep idle state - so we disable it. |
3501 |
+diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c |
3502 |
+index 0a40df66a40de..fa700b46588e0 100644 |
3503 |
+--- a/arch/x86/kernel/reboot.c |
3504 |
++++ b/arch/x86/kernel/reboot.c |
3505 |
+@@ -113,17 +113,9 @@ void __noreturn machine_real_restart(unsigned int type) |
3506 |
+ spin_unlock(&rtc_lock); |
3507 |
+ |
3508 |
+ /* |
3509 |
+- * Switch back to the initial page table. |
3510 |
++ * Switch to the trampoline page table. |
3511 |
+ */ |
3512 |
+-#ifdef CONFIG_X86_32 |
3513 |
+- load_cr3(initial_page_table); |
3514 |
+-#else |
3515 |
+- write_cr3(real_mode_header->trampoline_pgd); |
3516 |
+- |
3517 |
+- /* Exiting long mode will fail if CR4.PCIDE is set. */ |
3518 |
+- if (boot_cpu_has(X86_FEATURE_PCID)) |
3519 |
+- cr4_clear_bits(X86_CR4_PCIDE); |
3520 |
+-#endif |
3521 |
++ load_trampoline_pgtable(); |
3522 |
+ |
3523 |
+ /* Jump to the identity-mapped low memory code */ |
3524 |
+ #ifdef CONFIG_X86_32 |
3525 |
+diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c |
3526 |
+index 4954cd01c1f0e..d479b2b121259 100644 |
3527 |
+--- a/arch/x86/kvm/mmu/tdp_mmu.c |
3528 |
++++ b/arch/x86/kvm/mmu/tdp_mmu.c |
3529 |
+@@ -1493,12 +1493,12 @@ static bool write_protect_gfn(struct kvm *kvm, struct kvm_mmu_page *root, |
3530 |
+ !is_last_spte(iter.old_spte, iter.level)) |
3531 |
+ continue; |
3532 |
+ |
3533 |
+- if (!is_writable_pte(iter.old_spte)) |
3534 |
+- break; |
3535 |
+- |
3536 |
+ new_spte = iter.old_spte & |
3537 |
+ ~(PT_WRITABLE_MASK | shadow_mmu_writable_mask); |
3538 |
+ |
3539 |
++ if (new_spte == iter.old_spte) |
3540 |
++ break; |
3541 |
++ |
3542 |
+ tdp_mmu_set_spte(kvm, &iter, new_spte); |
3543 |
+ spte_set = true; |
3544 |
+ } |
3545 |
+diff --git a/arch/x86/kvm/vmx/posted_intr.c b/arch/x86/kvm/vmx/posted_intr.c |
3546 |
+index 1c94783b5a54c..21ea58d25771f 100644 |
3547 |
+--- a/arch/x86/kvm/vmx/posted_intr.c |
3548 |
++++ b/arch/x86/kvm/vmx/posted_intr.c |
3549 |
+@@ -15,7 +15,7 @@ |
3550 |
+ * can find which vCPU should be waken up. |
3551 |
+ */ |
3552 |
+ static DEFINE_PER_CPU(struct list_head, blocked_vcpu_on_cpu); |
3553 |
+-static DEFINE_PER_CPU(spinlock_t, blocked_vcpu_on_cpu_lock); |
3554 |
++static DEFINE_PER_CPU(raw_spinlock_t, blocked_vcpu_on_cpu_lock); |
3555 |
+ |
3556 |
+ static inline struct pi_desc *vcpu_to_pi_desc(struct kvm_vcpu *vcpu) |
3557 |
+ { |
3558 |
+@@ -121,9 +121,9 @@ static void __pi_post_block(struct kvm_vcpu *vcpu) |
3559 |
+ new.control) != old.control); |
3560 |
+ |
3561 |
+ if (!WARN_ON_ONCE(vcpu->pre_pcpu == -1)) { |
3562 |
+- spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); |
3563 |
++ raw_spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); |
3564 |
+ list_del(&vcpu->blocked_vcpu_list); |
3565 |
+- spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); |
3566 |
++ raw_spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); |
3567 |
+ vcpu->pre_pcpu = -1; |
3568 |
+ } |
3569 |
+ } |
3570 |
+@@ -154,11 +154,11 @@ int pi_pre_block(struct kvm_vcpu *vcpu) |
3571 |
+ local_irq_disable(); |
3572 |
+ if (!WARN_ON_ONCE(vcpu->pre_pcpu != -1)) { |
3573 |
+ vcpu->pre_pcpu = vcpu->cpu; |
3574 |
+- spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); |
3575 |
++ raw_spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); |
3576 |
+ list_add_tail(&vcpu->blocked_vcpu_list, |
3577 |
+ &per_cpu(blocked_vcpu_on_cpu, |
3578 |
+ vcpu->pre_pcpu)); |
3579 |
+- spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); |
3580 |
++ raw_spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, vcpu->pre_pcpu)); |
3581 |
+ } |
3582 |
+ |
3583 |
+ do { |
3584 |
+@@ -215,7 +215,7 @@ void pi_wakeup_handler(void) |
3585 |
+ struct kvm_vcpu *vcpu; |
3586 |
+ int cpu = smp_processor_id(); |
3587 |
+ |
3588 |
+- spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); |
3589 |
++ raw_spin_lock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); |
3590 |
+ list_for_each_entry(vcpu, &per_cpu(blocked_vcpu_on_cpu, cpu), |
3591 |
+ blocked_vcpu_list) { |
3592 |
+ struct pi_desc *pi_desc = vcpu_to_pi_desc(vcpu); |
3593 |
+@@ -223,13 +223,13 @@ void pi_wakeup_handler(void) |
3594 |
+ if (pi_test_on(pi_desc) == 1) |
3595 |
+ kvm_vcpu_kick(vcpu); |
3596 |
+ } |
3597 |
+- spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); |
3598 |
++ raw_spin_unlock(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); |
3599 |
+ } |
3600 |
+ |
3601 |
+ void __init pi_init_cpu(int cpu) |
3602 |
+ { |
3603 |
+ INIT_LIST_HEAD(&per_cpu(blocked_vcpu_on_cpu, cpu)); |
3604 |
+- spin_lock_init(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); |
3605 |
++ raw_spin_lock_init(&per_cpu(blocked_vcpu_on_cpu_lock, cpu)); |
3606 |
+ } |
3607 |
+ |
3608 |
+ bool pi_has_pending_interrupt(struct kvm_vcpu *vcpu) |
3609 |
+diff --git a/arch/x86/realmode/init.c b/arch/x86/realmode/init.c |
3610 |
+index d3eee1ebcf1d5..1d20ed4b28729 100644 |
3611 |
+--- a/arch/x86/realmode/init.c |
3612 |
++++ b/arch/x86/realmode/init.c |
3613 |
+@@ -17,6 +17,32 @@ u32 *trampoline_cr4_features; |
3614 |
+ /* Hold the pgd entry used on booting additional CPUs */ |
3615 |
+ pgd_t trampoline_pgd_entry; |
3616 |
+ |
3617 |
++void load_trampoline_pgtable(void) |
3618 |
++{ |
3619 |
++#ifdef CONFIG_X86_32 |
3620 |
++ load_cr3(initial_page_table); |
3621 |
++#else |
3622 |
++ /* |
3623 |
++ * This function is called before exiting to real-mode and that will |
3624 |
++ * fail with CR4.PCIDE still set. |
3625 |
++ */ |
3626 |
++ if (boot_cpu_has(X86_FEATURE_PCID)) |
3627 |
++ cr4_clear_bits(X86_CR4_PCIDE); |
3628 |
++ |
3629 |
++ write_cr3(real_mode_header->trampoline_pgd); |
3630 |
++#endif |
3631 |
++ |
3632 |
++ /* |
3633 |
++ * The CR3 write above will not flush global TLB entries. |
3634 |
++ * Stale, global entries from previous page tables may still be |
3635 |
++ * present. Flush those stale entries. |
3636 |
++ * |
3637 |
++ * This ensures that memory accessed while running with |
3638 |
++ * trampoline_pgd is *actually* mapped into trampoline_pgd. |
3639 |
++ */ |
3640 |
++ __flush_tlb_all(); |
3641 |
++} |
3642 |
++ |
3643 |
+ void __init reserve_real_mode(void) |
3644 |
+ { |
3645 |
+ phys_addr_t mem; |
3646 |
+diff --git a/arch/x86/um/syscalls_64.c b/arch/x86/um/syscalls_64.c |
3647 |
+index 58f51667e2e4b..8249685b40960 100644 |
3648 |
+--- a/arch/x86/um/syscalls_64.c |
3649 |
++++ b/arch/x86/um/syscalls_64.c |
3650 |
+@@ -11,6 +11,7 @@ |
3651 |
+ #include <linux/uaccess.h> |
3652 |
+ #include <asm/prctl.h> /* XXX This should get the constants from libc */ |
3653 |
+ #include <os.h> |
3654 |
++#include <registers.h> |
3655 |
+ |
3656 |
+ long arch_prctl(struct task_struct *task, int option, |
3657 |
+ unsigned long __user *arg2) |
3658 |
+@@ -35,7 +36,7 @@ long arch_prctl(struct task_struct *task, int option, |
3659 |
+ switch (option) { |
3660 |
+ case ARCH_SET_FS: |
3661 |
+ case ARCH_SET_GS: |
3662 |
+- ret = restore_registers(pid, ¤t->thread.regs.regs); |
3663 |
++ ret = restore_pid_registers(pid, ¤t->thread.regs.regs); |
3664 |
+ if (ret) |
3665 |
+ return ret; |
3666 |
+ break; |
3667 |
+diff --git a/block/bfq-iosched.c b/block/bfq-iosched.c |
3668 |
+index 480e1a1348596..ea9a086d0498f 100644 |
3669 |
+--- a/block/bfq-iosched.c |
3670 |
++++ b/block/bfq-iosched.c |
3671 |
+@@ -5991,48 +5991,7 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, |
3672 |
+ |
3673 |
+ spin_lock_irq(&bfqd->lock); |
3674 |
+ bfqq = bfq_init_rq(rq); |
3675 |
+- |
3676 |
+- /* |
3677 |
+- * Reqs with at_head or passthrough flags set are to be put |
3678 |
+- * directly into dispatch list. Additional case for putting rq |
3679 |
+- * directly into the dispatch queue: the only active |
3680 |
+- * bfq_queues are bfqq and either its waker bfq_queue or one |
3681 |
+- * of its woken bfq_queues. The rationale behind this |
3682 |
+- * additional condition is as follows: |
3683 |
+- * - consider a bfq_queue, say Q1, detected as a waker of |
3684 |
+- * another bfq_queue, say Q2 |
3685 |
+- * - by definition of a waker, Q1 blocks the I/O of Q2, i.e., |
3686 |
+- * some I/O of Q1 needs to be completed for new I/O of Q2 |
3687 |
+- * to arrive. A notable example of waker is journald |
3688 |
+- * - so, Q1 and Q2 are in any respect the queues of two |
3689 |
+- * cooperating processes (or of two cooperating sets of |
3690 |
+- * processes): the goal of Q1's I/O is doing what needs to |
3691 |
+- * be done so that new Q2's I/O can finally be |
3692 |
+- * issued. Therefore, if the service of Q1's I/O is delayed, |
3693 |
+- * then Q2's I/O is delayed too. Conversely, if Q2's I/O is |
3694 |
+- * delayed, the goal of Q1's I/O is hindered. |
3695 |
+- * - as a consequence, if some I/O of Q1/Q2 arrives while |
3696 |
+- * Q2/Q1 is the only queue in service, there is absolutely |
3697 |
+- * no point in delaying the service of such an I/O. The |
3698 |
+- * only possible result is a throughput loss |
3699 |
+- * - so, when the above condition holds, the best option is to |
3700 |
+- * have the new I/O dispatched as soon as possible |
3701 |
+- * - the most effective and efficient way to attain the above |
3702 |
+- * goal is to put the new I/O directly in the dispatch |
3703 |
+- * list |
3704 |
+- * - as an additional restriction, Q1 and Q2 must be the only |
3705 |
+- * busy queues for this commit to put the I/O of Q2/Q1 in |
3706 |
+- * the dispatch list. This is necessary, because, if also |
3707 |
+- * other queues are waiting for service, then putting new |
3708 |
+- * I/O directly in the dispatch list may evidently cause a |
3709 |
+- * violation of service guarantees for the other queues |
3710 |
+- */ |
3711 |
+- if (!bfqq || |
3712 |
+- (bfqq != bfqd->in_service_queue && |
3713 |
+- bfqd->in_service_queue != NULL && |
3714 |
+- bfq_tot_busy_queues(bfqd) == 1 + bfq_bfqq_busy(bfqq) && |
3715 |
+- (bfqq->waker_bfqq == bfqd->in_service_queue || |
3716 |
+- bfqd->in_service_queue->waker_bfqq == bfqq)) || at_head) { |
3717 |
++ if (!bfqq || at_head) { |
3718 |
+ if (at_head) |
3719 |
+ list_add(&rq->queuelist, &bfqd->dispatch); |
3720 |
+ else |
3721 |
+@@ -6059,7 +6018,6 @@ static void bfq_insert_request(struct blk_mq_hw_ctx *hctx, struct request *rq, |
3722 |
+ * merge). |
3723 |
+ */ |
3724 |
+ cmd_flags = rq->cmd_flags; |
3725 |
+- |
3726 |
+ spin_unlock_irq(&bfqd->lock); |
3727 |
+ |
3728 |
+ bfq_update_insert_stats(q, bfqq, idle_timer_disabled, |
3729 |
+diff --git a/block/blk-flush.c b/block/blk-flush.c |
3730 |
+index 4201728bf3a5a..94a86acbb7f67 100644 |
3731 |
+--- a/block/blk-flush.c |
3732 |
++++ b/block/blk-flush.c |
3733 |
+@@ -235,8 +235,10 @@ static void flush_end_io(struct request *flush_rq, blk_status_t error) |
3734 |
+ * avoiding use-after-free. |
3735 |
+ */ |
3736 |
+ WRITE_ONCE(flush_rq->state, MQ_RQ_IDLE); |
3737 |
+- if (fq->rq_status != BLK_STS_OK) |
3738 |
++ if (fq->rq_status != BLK_STS_OK) { |
3739 |
+ error = fq->rq_status; |
3740 |
++ fq->rq_status = BLK_STS_OK; |
3741 |
++ } |
3742 |
+ |
3743 |
+ if (!q->elevator) { |
3744 |
+ flush_rq->tag = BLK_MQ_NO_TAG; |
3745 |
+diff --git a/block/blk-pm.c b/block/blk-pm.c |
3746 |
+index 17bd020268d42..2dad62cc15727 100644 |
3747 |
+--- a/block/blk-pm.c |
3748 |
++++ b/block/blk-pm.c |
3749 |
+@@ -163,27 +163,19 @@ EXPORT_SYMBOL(blk_pre_runtime_resume); |
3750 |
+ /** |
3751 |
+ * blk_post_runtime_resume - Post runtime resume processing |
3752 |
+ * @q: the queue of the device |
3753 |
+- * @err: return value of the device's runtime_resume function |
3754 |
+ * |
3755 |
+ * Description: |
3756 |
+- * Update the queue's runtime status according to the return value of the |
3757 |
+- * device's runtime_resume function. If the resume was successful, call |
3758 |
+- * blk_set_runtime_active() to do the real work of restarting the queue. |
3759 |
++ * For historical reasons, this routine merely calls blk_set_runtime_active() |
3760 |
++ * to do the real work of restarting the queue. It does this regardless of |
3761 |
++ * whether the device's runtime-resume succeeded; even if it failed the |
3762 |
++ * driver or error handler will need to communicate with the device. |
3763 |
+ * |
3764 |
+ * This function should be called near the end of the device's |
3765 |
+ * runtime_resume callback. |
3766 |
+ */ |
3767 |
+-void blk_post_runtime_resume(struct request_queue *q, int err) |
3768 |
++void blk_post_runtime_resume(struct request_queue *q) |
3769 |
+ { |
3770 |
+- if (!q->dev) |
3771 |
+- return; |
3772 |
+- if (!err) { |
3773 |
+- blk_set_runtime_active(q); |
3774 |
+- } else { |
3775 |
+- spin_lock_irq(&q->queue_lock); |
3776 |
+- q->rpm_status = RPM_SUSPENDED; |
3777 |
+- spin_unlock_irq(&q->queue_lock); |
3778 |
+- } |
3779 |
++ blk_set_runtime_active(q); |
3780 |
+ } |
3781 |
+ EXPORT_SYMBOL(blk_post_runtime_resume); |
3782 |
+ |
3783 |
+@@ -201,7 +193,7 @@ EXPORT_SYMBOL(blk_post_runtime_resume); |
3784 |
+ * runtime PM status and re-enable peeking requests from the queue. It |
3785 |
+ * should be called before first request is added to the queue. |
3786 |
+ * |
3787 |
+- * This function is also called by blk_post_runtime_resume() for successful |
3788 |
++ * This function is also called by blk_post_runtime_resume() for |
3789 |
+ * runtime resumes. It does everything necessary to restart the queue. |
3790 |
+ */ |
3791 |
+ void blk_set_runtime_active(struct request_queue *q) |
3792 |
+diff --git a/block/genhd.c b/block/genhd.c |
3793 |
+index f091a60dcf1ea..de789d1a1e3d2 100644 |
3794 |
+--- a/block/genhd.c |
3795 |
++++ b/block/genhd.c |
3796 |
+@@ -420,6 +420,8 @@ int device_add_disk(struct device *parent, struct gendisk *disk, |
3797 |
+ DISK_MAX_PARTS); |
3798 |
+ disk->minors = DISK_MAX_PARTS; |
3799 |
+ } |
3800 |
++ if (disk->first_minor + disk->minors > MINORMASK + 1) |
3801 |
++ return -EINVAL; |
3802 |
+ } else { |
3803 |
+ if (WARN_ON(disk->minors)) |
3804 |
+ return -EINVAL; |
3805 |
+@@ -432,10 +434,6 @@ int device_add_disk(struct device *parent, struct gendisk *disk, |
3806 |
+ disk->flags |= GENHD_FL_EXT_DEVT; |
3807 |
+ } |
3808 |
+ |
3809 |
+- ret = disk_alloc_events(disk); |
3810 |
+- if (ret) |
3811 |
+- goto out_free_ext_minor; |
3812 |
+- |
3813 |
+ /* delay uevents, until we scanned partition table */ |
3814 |
+ dev_set_uevent_suppress(ddev, 1); |
3815 |
+ |
3816 |
+@@ -446,7 +444,12 @@ int device_add_disk(struct device *parent, struct gendisk *disk, |
3817 |
+ ddev->devt = MKDEV(disk->major, disk->first_minor); |
3818 |
+ ret = device_add(ddev); |
3819 |
+ if (ret) |
3820 |
+- goto out_disk_release_events; |
3821 |
++ goto out_free_ext_minor; |
3822 |
++ |
3823 |
++ ret = disk_alloc_events(disk); |
3824 |
++ if (ret) |
3825 |
++ goto out_device_del; |
3826 |
++ |
3827 |
+ if (!sysfs_deprecated) { |
3828 |
+ ret = sysfs_create_link(block_depr, &ddev->kobj, |
3829 |
+ kobject_name(&ddev->kobj)); |
3830 |
+@@ -534,8 +537,6 @@ out_del_block_link: |
3831 |
+ sysfs_remove_link(block_depr, dev_name(ddev)); |
3832 |
+ out_device_del: |
3833 |
+ device_del(ddev); |
3834 |
+-out_disk_release_events: |
3835 |
+- disk_release_events(disk); |
3836 |
+ out_free_ext_minor: |
3837 |
+ if (disk->major == BLOCK_EXT_MAJOR) |
3838 |
+ blk_free_ext_minor(disk->first_minor); |
3839 |
+diff --git a/block/mq-deadline.c b/block/mq-deadline.c |
3840 |
+index 7f3c3932b723e..cd2342d297048 100644 |
3841 |
+--- a/block/mq-deadline.c |
3842 |
++++ b/block/mq-deadline.c |
3843 |
+@@ -811,7 +811,7 @@ SHOW_JIFFIES(deadline_read_expire_show, dd->fifo_expire[DD_READ]); |
3844 |
+ SHOW_JIFFIES(deadline_write_expire_show, dd->fifo_expire[DD_WRITE]); |
3845 |
+ SHOW_INT(deadline_writes_starved_show, dd->writes_starved); |
3846 |
+ SHOW_INT(deadline_front_merges_show, dd->front_merges); |
3847 |
+-SHOW_INT(deadline_async_depth_show, dd->front_merges); |
3848 |
++SHOW_INT(deadline_async_depth_show, dd->async_depth); |
3849 |
+ SHOW_INT(deadline_fifo_batch_show, dd->fifo_batch); |
3850 |
+ #undef SHOW_INT |
3851 |
+ #undef SHOW_JIFFIES |
3852 |
+@@ -840,7 +840,7 @@ STORE_JIFFIES(deadline_read_expire_store, &dd->fifo_expire[DD_READ], 0, INT_MAX) |
3853 |
+ STORE_JIFFIES(deadline_write_expire_store, &dd->fifo_expire[DD_WRITE], 0, INT_MAX); |
3854 |
+ STORE_INT(deadline_writes_starved_store, &dd->writes_starved, INT_MIN, INT_MAX); |
3855 |
+ STORE_INT(deadline_front_merges_store, &dd->front_merges, 0, 1); |
3856 |
+-STORE_INT(deadline_async_depth_store, &dd->front_merges, 1, INT_MAX); |
3857 |
++STORE_INT(deadline_async_depth_store, &dd->async_depth, 1, INT_MAX); |
3858 |
+ STORE_INT(deadline_fifo_batch_store, &dd->fifo_batch, 0, INT_MAX); |
3859 |
+ #undef STORE_FUNCTION |
3860 |
+ #undef STORE_INT |
3861 |
+diff --git a/crypto/jitterentropy.c b/crypto/jitterentropy.c |
3862 |
+index a11b3208760f3..f6d3a84e3c214 100644 |
3863 |
+--- a/crypto/jitterentropy.c |
3864 |
++++ b/crypto/jitterentropy.c |
3865 |
+@@ -265,7 +265,6 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta) |
3866 |
+ { |
3867 |
+ __u64 delta2 = jent_delta(ec->last_delta, current_delta); |
3868 |
+ __u64 delta3 = jent_delta(ec->last_delta2, delta2); |
3869 |
+- unsigned int delta_masked = current_delta & JENT_APT_WORD_MASK; |
3870 |
+ |
3871 |
+ ec->last_delta = current_delta; |
3872 |
+ ec->last_delta2 = delta2; |
3873 |
+@@ -274,7 +273,7 @@ static int jent_stuck(struct rand_data *ec, __u64 current_delta) |
3874 |
+ * Insert the result of the comparison of two back-to-back time |
3875 |
+ * deltas. |
3876 |
+ */ |
3877 |
+- jent_apt_insert(ec, delta_masked); |
3878 |
++ jent_apt_insert(ec, current_delta); |
3879 |
+ |
3880 |
+ if (!current_delta || !delta2 || !delta3) { |
3881 |
+ /* RCT with a stuck bit */ |
3882 |
+diff --git a/drivers/acpi/acpica/exfield.c b/drivers/acpi/acpica/exfield.c |
3883 |
+index 06f3c9df1e22d..8618500f23b39 100644 |
3884 |
+--- a/drivers/acpi/acpica/exfield.c |
3885 |
++++ b/drivers/acpi/acpica/exfield.c |
3886 |
+@@ -330,12 +330,7 @@ acpi_ex_write_data_to_field(union acpi_operand_object *source_desc, |
3887 |
+ obj_desc->field.base_byte_offset, |
3888 |
+ source_desc->buffer.pointer, data_length); |
3889 |
+ |
3890 |
+- if ((obj_desc->field.region_obj->region.address == |
3891 |
+- PCC_MASTER_SUBSPACE |
3892 |
+- && MASTER_SUBSPACE_COMMAND(obj_desc->field. |
3893 |
+- base_byte_offset)) |
3894 |
+- || GENERIC_SUBSPACE_COMMAND(obj_desc->field. |
3895 |
+- base_byte_offset)) { |
3896 |
++ if (MASTER_SUBSPACE_COMMAND(obj_desc->field.base_byte_offset)) { |
3897 |
+ |
3898 |
+ /* Perform the write */ |
3899 |
+ |
3900 |
+diff --git a/drivers/acpi/acpica/exoparg1.c b/drivers/acpi/acpica/exoparg1.c |
3901 |
+index b639e930d6429..44b7c350ed5ca 100644 |
3902 |
+--- a/drivers/acpi/acpica/exoparg1.c |
3903 |
++++ b/drivers/acpi/acpica/exoparg1.c |
3904 |
+@@ -1007,7 +1007,8 @@ acpi_status acpi_ex_opcode_1A_0T_1R(struct acpi_walk_state *walk_state) |
3905 |
+ (walk_state, return_desc, |
3906 |
+ &temp_desc); |
3907 |
+ if (ACPI_FAILURE(status)) { |
3908 |
+- goto cleanup; |
3909 |
++ return_ACPI_STATUS |
3910 |
++ (status); |
3911 |
+ } |
3912 |
+ |
3913 |
+ return_desc = temp_desc; |
3914 |
+diff --git a/drivers/acpi/acpica/hwesleep.c b/drivers/acpi/acpica/hwesleep.c |
3915 |
+index 808fdf54aeebf..7ee2939c08cd4 100644 |
3916 |
+--- a/drivers/acpi/acpica/hwesleep.c |
3917 |
++++ b/drivers/acpi/acpica/hwesleep.c |
3918 |
+@@ -104,7 +104,9 @@ acpi_status acpi_hw_extended_sleep(u8 sleep_state) |
3919 |
+ |
3920 |
+ /* Flush caches, as per ACPI specification */ |
3921 |
+ |
3922 |
+- ACPI_FLUSH_CPU_CACHE(); |
3923 |
++ if (sleep_state < ACPI_STATE_S4) { |
3924 |
++ ACPI_FLUSH_CPU_CACHE(); |
3925 |
++ } |
3926 |
+ |
3927 |
+ status = acpi_os_enter_sleep(sleep_state, sleep_control, 0); |
3928 |
+ if (status == AE_CTRL_TERMINATE) { |
3929 |
+diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c |
3930 |
+index 34a3825f25d37..5efa3d8e483e0 100644 |
3931 |
+--- a/drivers/acpi/acpica/hwsleep.c |
3932 |
++++ b/drivers/acpi/acpica/hwsleep.c |
3933 |
+@@ -110,7 +110,9 @@ acpi_status acpi_hw_legacy_sleep(u8 sleep_state) |
3934 |
+ |
3935 |
+ /* Flush caches, as per ACPI specification */ |
3936 |
+ |
3937 |
+- ACPI_FLUSH_CPU_CACHE(); |
3938 |
++ if (sleep_state < ACPI_STATE_S4) { |
3939 |
++ ACPI_FLUSH_CPU_CACHE(); |
3940 |
++ } |
3941 |
+ |
3942 |
+ status = acpi_os_enter_sleep(sleep_state, pm1a_control, pm1b_control); |
3943 |
+ if (status == AE_CTRL_TERMINATE) { |
3944 |
+diff --git a/drivers/acpi/acpica/hwxfsleep.c b/drivers/acpi/acpica/hwxfsleep.c |
3945 |
+index e4cde23a29061..ba77598ee43e8 100644 |
3946 |
+--- a/drivers/acpi/acpica/hwxfsleep.c |
3947 |
++++ b/drivers/acpi/acpica/hwxfsleep.c |
3948 |
+@@ -162,8 +162,6 @@ acpi_status acpi_enter_sleep_state_s4bios(void) |
3949 |
+ return_ACPI_STATUS(status); |
3950 |
+ } |
3951 |
+ |
3952 |
+- ACPI_FLUSH_CPU_CACHE(); |
3953 |
+- |
3954 |
+ status = acpi_hw_write_port(acpi_gbl_FADT.smi_command, |
3955 |
+ (u32)acpi_gbl_FADT.s4_bios_request, 8); |
3956 |
+ if (ACPI_FAILURE(status)) { |
3957 |
+diff --git a/drivers/acpi/acpica/utdelete.c b/drivers/acpi/acpica/utdelete.c |
3958 |
+index e5ba9795ec696..8d7736d2d2699 100644 |
3959 |
+--- a/drivers/acpi/acpica/utdelete.c |
3960 |
++++ b/drivers/acpi/acpica/utdelete.c |
3961 |
+@@ -422,6 +422,7 @@ acpi_ut_update_ref_count(union acpi_operand_object *object, u32 action) |
3962 |
+ ACPI_WARNING((AE_INFO, |
3963 |
+ "Obj %p, Reference Count is already zero, cannot decrement\n", |
3964 |
+ object)); |
3965 |
++ return; |
3966 |
+ } |
3967 |
+ |
3968 |
+ ACPI_DEBUG_PRINT_RAW((ACPI_DB_ALLOCATIONS, |
3969 |
+diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c |
3970 |
+index 8afa85d6eb6a7..ead0114f27c9f 100644 |
3971 |
+--- a/drivers/acpi/battery.c |
3972 |
++++ b/drivers/acpi/battery.c |
3973 |
+@@ -53,6 +53,7 @@ static int battery_bix_broken_package; |
3974 |
+ static int battery_notification_delay_ms; |
3975 |
+ static int battery_ac_is_broken; |
3976 |
+ static int battery_check_pmic = 1; |
3977 |
++static int battery_quirk_notcharging; |
3978 |
+ static unsigned int cache_time = 1000; |
3979 |
+ module_param(cache_time, uint, 0644); |
3980 |
+ MODULE_PARM_DESC(cache_time, "cache time in milliseconds"); |
3981 |
+@@ -217,6 +218,8 @@ static int acpi_battery_get_property(struct power_supply *psy, |
3982 |
+ val->intval = POWER_SUPPLY_STATUS_CHARGING; |
3983 |
+ else if (acpi_battery_is_charged(battery)) |
3984 |
+ val->intval = POWER_SUPPLY_STATUS_FULL; |
3985 |
++ else if (battery_quirk_notcharging) |
3986 |
++ val->intval = POWER_SUPPLY_STATUS_NOT_CHARGING; |
3987 |
+ else |
3988 |
+ val->intval = POWER_SUPPLY_STATUS_UNKNOWN; |
3989 |
+ break; |
3990 |
+@@ -1111,6 +1114,12 @@ battery_do_not_check_pmic_quirk(const struct dmi_system_id *d) |
3991 |
+ return 0; |
3992 |
+ } |
3993 |
+ |
3994 |
++static int __init battery_quirk_not_charging(const struct dmi_system_id *d) |
3995 |
++{ |
3996 |
++ battery_quirk_notcharging = 1; |
3997 |
++ return 0; |
3998 |
++} |
3999 |
++ |
4000 |
+ static const struct dmi_system_id bat_dmi_table[] __initconst = { |
4001 |
+ { |
4002 |
+ /* NEC LZ750/LS */ |
4003 |
+@@ -1155,6 +1164,19 @@ static const struct dmi_system_id bat_dmi_table[] __initconst = { |
4004 |
+ DMI_MATCH(DMI_PRODUCT_VERSION, "Lenovo MIIX 320-10ICR"), |
4005 |
+ }, |
4006 |
+ }, |
4007 |
++ { |
4008 |
++ /* |
4009 |
++ * On Lenovo ThinkPads the BIOS specification defines |
4010 |
++ * a state when the bits for charging and discharging |
4011 |
++ * are both set to 0. That state is "Not Charging". |
4012 |
++ */ |
4013 |
++ .callback = battery_quirk_not_charging, |
4014 |
++ .ident = "Lenovo ThinkPad", |
4015 |
++ .matches = { |
4016 |
++ DMI_MATCH(DMI_SYS_VENDOR, "LENOVO"), |
4017 |
++ DMI_MATCH(DMI_PRODUCT_VERSION, "ThinkPad"), |
4018 |
++ }, |
4019 |
++ }, |
4020 |
+ {}, |
4021 |
+ }; |
4022 |
+ |
4023 |
+diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c |
4024 |
+index fa923a9292244..dd535b4b9a160 100644 |
4025 |
+--- a/drivers/acpi/bus.c |
4026 |
++++ b/drivers/acpi/bus.c |
4027 |
+@@ -98,8 +98,8 @@ int acpi_bus_get_status(struct acpi_device *device) |
4028 |
+ acpi_status status; |
4029 |
+ unsigned long long sta; |
4030 |
+ |
4031 |
+- if (acpi_device_always_present(device)) { |
4032 |
+- acpi_set_device_status(device, ACPI_STA_DEFAULT); |
4033 |
++ if (acpi_device_override_status(device, &sta)) { |
4034 |
++ acpi_set_device_status(device, sta); |
4035 |
+ return 0; |
4036 |
+ } |
4037 |
+ |
4038 |
+diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c |
4039 |
+index 3fbb17ecce2d5..6fe28a2d387bd 100644 |
4040 |
+--- a/drivers/acpi/cppc_acpi.c |
4041 |
++++ b/drivers/acpi/cppc_acpi.c |
4042 |
+@@ -411,7 +411,7 @@ bool acpi_cpc_valid(void) |
4043 |
+ struct cpc_desc *cpc_ptr; |
4044 |
+ int cpu; |
4045 |
+ |
4046 |
+- for_each_possible_cpu(cpu) { |
4047 |
++ for_each_present_cpu(cpu) { |
4048 |
+ cpc_ptr = per_cpu(cpc_desc_ptr, cpu); |
4049 |
+ if (!cpc_ptr) |
4050 |
+ return false; |
4051 |
+diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c |
4052 |
+index e629e891d1bb3..9b859ff976e89 100644 |
4053 |
+--- a/drivers/acpi/ec.c |
4054 |
++++ b/drivers/acpi/ec.c |
4055 |
+@@ -166,6 +166,7 @@ struct acpi_ec_query { |
4056 |
+ struct transaction transaction; |
4057 |
+ struct work_struct work; |
4058 |
+ struct acpi_ec_query_handler *handler; |
4059 |
++ struct acpi_ec *ec; |
4060 |
+ }; |
4061 |
+ |
4062 |
+ static int acpi_ec_query(struct acpi_ec *ec, u8 *data); |
4063 |
+@@ -452,6 +453,7 @@ static void acpi_ec_submit_query(struct acpi_ec *ec) |
4064 |
+ ec_dbg_evt("Command(%s) submitted/blocked", |
4065 |
+ acpi_ec_cmd_string(ACPI_EC_COMMAND_QUERY)); |
4066 |
+ ec->nr_pending_queries++; |
4067 |
++ ec->events_in_progress++; |
4068 |
+ queue_work(ec_wq, &ec->work); |
4069 |
+ } |
4070 |
+ } |
4071 |
+@@ -518,7 +520,7 @@ static void acpi_ec_enable_event(struct acpi_ec *ec) |
4072 |
+ #ifdef CONFIG_PM_SLEEP |
4073 |
+ static void __acpi_ec_flush_work(void) |
4074 |
+ { |
4075 |
+- drain_workqueue(ec_wq); /* flush ec->work */ |
4076 |
++ flush_workqueue(ec_wq); /* flush ec->work */ |
4077 |
+ flush_workqueue(ec_query_wq); /* flush queries */ |
4078 |
+ } |
4079 |
+ |
4080 |
+@@ -1103,7 +1105,7 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) |
4081 |
+ } |
4082 |
+ EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); |
4083 |
+ |
4084 |
+-static struct acpi_ec_query *acpi_ec_create_query(u8 *pval) |
4085 |
++static struct acpi_ec_query *acpi_ec_create_query(struct acpi_ec *ec, u8 *pval) |
4086 |
+ { |
4087 |
+ struct acpi_ec_query *q; |
4088 |
+ struct transaction *t; |
4089 |
+@@ -1111,11 +1113,13 @@ static struct acpi_ec_query *acpi_ec_create_query(u8 *pval) |
4090 |
+ q = kzalloc(sizeof (struct acpi_ec_query), GFP_KERNEL); |
4091 |
+ if (!q) |
4092 |
+ return NULL; |
4093 |
++ |
4094 |
+ INIT_WORK(&q->work, acpi_ec_event_processor); |
4095 |
+ t = &q->transaction; |
4096 |
+ t->command = ACPI_EC_COMMAND_QUERY; |
4097 |
+ t->rdata = pval; |
4098 |
+ t->rlen = 1; |
4099 |
++ q->ec = ec; |
4100 |
+ return q; |
4101 |
+ } |
4102 |
+ |
4103 |
+@@ -1132,13 +1136,21 @@ static void acpi_ec_event_processor(struct work_struct *work) |
4104 |
+ { |
4105 |
+ struct acpi_ec_query *q = container_of(work, struct acpi_ec_query, work); |
4106 |
+ struct acpi_ec_query_handler *handler = q->handler; |
4107 |
++ struct acpi_ec *ec = q->ec; |
4108 |
+ |
4109 |
+ ec_dbg_evt("Query(0x%02x) started", handler->query_bit); |
4110 |
++ |
4111 |
+ if (handler->func) |
4112 |
+ handler->func(handler->data); |
4113 |
+ else if (handler->handle) |
4114 |
+ acpi_evaluate_object(handler->handle, NULL, NULL, NULL); |
4115 |
++ |
4116 |
+ ec_dbg_evt("Query(0x%02x) stopped", handler->query_bit); |
4117 |
++ |
4118 |
++ spin_lock_irq(&ec->lock); |
4119 |
++ ec->queries_in_progress--; |
4120 |
++ spin_unlock_irq(&ec->lock); |
4121 |
++ |
4122 |
+ acpi_ec_delete_query(q); |
4123 |
+ } |
4124 |
+ |
4125 |
+@@ -1148,7 +1160,7 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 *data) |
4126 |
+ int result; |
4127 |
+ struct acpi_ec_query *q; |
4128 |
+ |
4129 |
+- q = acpi_ec_create_query(&value); |
4130 |
++ q = acpi_ec_create_query(ec, &value); |
4131 |
+ if (!q) |
4132 |
+ return -ENOMEM; |
4133 |
+ |
4134 |
+@@ -1170,19 +1182,20 @@ static int acpi_ec_query(struct acpi_ec *ec, u8 *data) |
4135 |
+ } |
4136 |
+ |
4137 |
+ /* |
4138 |
+- * It is reported that _Qxx are evaluated in a parallel way on |
4139 |
+- * Windows: |
4140 |
++ * It is reported that _Qxx are evaluated in a parallel way on Windows: |
4141 |
+ * https://bugzilla.kernel.org/show_bug.cgi?id=94411 |
4142 |
+ * |
4143 |
+- * Put this log entry before schedule_work() in order to make |
4144 |
+- * it appearing before any other log entries occurred during the |
4145 |
+- * work queue execution. |
4146 |
++ * Put this log entry before queue_work() to make it appear in the log |
4147 |
++ * before any other messages emitted during workqueue handling. |
4148 |
+ */ |
4149 |
+ ec_dbg_evt("Query(0x%02x) scheduled", value); |
4150 |
+- if (!queue_work(ec_query_wq, &q->work)) { |
4151 |
+- ec_dbg_evt("Query(0x%02x) overlapped", value); |
4152 |
+- result = -EBUSY; |
4153 |
+- } |
4154 |
++ |
4155 |
++ spin_lock_irq(&ec->lock); |
4156 |
++ |
4157 |
++ ec->queries_in_progress++; |
4158 |
++ queue_work(ec_query_wq, &q->work); |
4159 |
++ |
4160 |
++ spin_unlock_irq(&ec->lock); |
4161 |
+ |
4162 |
+ err_exit: |
4163 |
+ if (result) |
4164 |
+@@ -1240,6 +1253,10 @@ static void acpi_ec_event_handler(struct work_struct *work) |
4165 |
+ ec_dbg_evt("Event stopped"); |
4166 |
+ |
4167 |
+ acpi_ec_check_event(ec); |
4168 |
++ |
4169 |
++ spin_lock_irqsave(&ec->lock, flags); |
4170 |
++ ec->events_in_progress--; |
4171 |
++ spin_unlock_irqrestore(&ec->lock, flags); |
4172 |
+ } |
4173 |
+ |
4174 |
+ static void acpi_ec_handle_interrupt(struct acpi_ec *ec) |
4175 |
+@@ -2021,6 +2038,7 @@ void acpi_ec_set_gpe_wake_mask(u8 action) |
4176 |
+ |
4177 |
+ bool acpi_ec_dispatch_gpe(void) |
4178 |
+ { |
4179 |
++ bool work_in_progress; |
4180 |
+ u32 ret; |
4181 |
+ |
4182 |
+ if (!first_ec) |
4183 |
+@@ -2041,8 +2059,19 @@ bool acpi_ec_dispatch_gpe(void) |
4184 |
+ if (ret == ACPI_INTERRUPT_HANDLED) |
4185 |
+ pm_pr_dbg("ACPI EC GPE dispatched\n"); |
4186 |
+ |
4187 |
+- /* Flush the event and query workqueues. */ |
4188 |
+- acpi_ec_flush_work(); |
4189 |
++ /* Drain EC work. */ |
4190 |
++ do { |
4191 |
++ acpi_ec_flush_work(); |
4192 |
++ |
4193 |
++ pm_pr_dbg("ACPI EC work flushed\n"); |
4194 |
++ |
4195 |
++ spin_lock_irq(&first_ec->lock); |
4196 |
++ |
4197 |
++ work_in_progress = first_ec->events_in_progress + |
4198 |
++ first_ec->queries_in_progress > 0; |
4199 |
++ |
4200 |
++ spin_unlock_irq(&first_ec->lock); |
4201 |
++ } while (work_in_progress && !pm_wakeup_pending()); |
4202 |
+ |
4203 |
+ return false; |
4204 |
+ } |
4205 |
+diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h |
4206 |
+index d91b560e88674..54b2be94d23dc 100644 |
4207 |
+--- a/drivers/acpi/internal.h |
4208 |
++++ b/drivers/acpi/internal.h |
4209 |
+@@ -183,6 +183,8 @@ struct acpi_ec { |
4210 |
+ struct work_struct work; |
4211 |
+ unsigned long timestamp; |
4212 |
+ unsigned long nr_pending_queries; |
4213 |
++ unsigned int events_in_progress; |
4214 |
++ unsigned int queries_in_progress; |
4215 |
+ bool busy_polling; |
4216 |
+ unsigned int polling_guard; |
4217 |
+ }; |
4218 |
+diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c |
4219 |
+index 5b54c80b9d32a..6e9cd41c5f9b1 100644 |
4220 |
+--- a/drivers/acpi/scan.c |
4221 |
++++ b/drivers/acpi/scan.c |
4222 |
+@@ -1690,6 +1690,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) |
4223 |
+ { |
4224 |
+ struct list_head resource_list; |
4225 |
+ bool is_serial_bus_slave = false; |
4226 |
++ static const struct acpi_device_id ignore_serial_bus_ids[] = { |
4227 |
+ /* |
4228 |
+ * These devices have multiple I2cSerialBus resources and an i2c-client |
4229 |
+ * must be instantiated for each, each with its own i2c_device_id. |
4230 |
+@@ -1698,11 +1699,18 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) |
4231 |
+ * drivers/platform/x86/i2c-multi-instantiate.c driver, which knows |
4232 |
+ * which i2c_device_id to use for each resource. |
4233 |
+ */ |
4234 |
+- static const struct acpi_device_id i2c_multi_instantiate_ids[] = { |
4235 |
+ {"BSG1160", }, |
4236 |
+ {"BSG2150", }, |
4237 |
+ {"INT33FE", }, |
4238 |
+ {"INT3515", }, |
4239 |
++ /* |
4240 |
++ * HIDs of device with an UartSerialBusV2 resource for which userspace |
4241 |
++ * expects a regular tty cdev to be created (instead of the in kernel |
4242 |
++ * serdev) and which have a kernel driver which expects a platform_dev |
4243 |
++ * such as the rfkill-gpio driver. |
4244 |
++ */ |
4245 |
++ {"BCM4752", }, |
4246 |
++ {"LNV4752", }, |
4247 |
+ {} |
4248 |
+ }; |
4249 |
+ |
4250 |
+@@ -1716,8 +1724,7 @@ static bool acpi_device_enumeration_by_parent(struct acpi_device *device) |
4251 |
+ fwnode_property_present(&device->fwnode, "baud"))) |
4252 |
+ return true; |
4253 |
+ |
4254 |
+- /* Instantiate a pdev for the i2c-multi-instantiate drv to bind to */ |
4255 |
+- if (!acpi_match_device_ids(device, i2c_multi_instantiate_ids)) |
4256 |
++ if (!acpi_match_device_ids(device, ignore_serial_bus_ids)) |
4257 |
+ return false; |
4258 |
+ |
4259 |
+ INIT_LIST_HEAD(&resource_list); |
4260 |
+diff --git a/drivers/acpi/x86/utils.c b/drivers/acpi/x86/utils.c |
4261 |
+index f22f23933063b..b3fb428461c6f 100644 |
4262 |
+--- a/drivers/acpi/x86/utils.c |
4263 |
++++ b/drivers/acpi/x86/utils.c |
4264 |
+@@ -22,58 +22,71 @@ |
4265 |
+ * Some BIOS-es (temporarily) hide specific APCI devices to work around Windows |
4266 |
+ * driver bugs. We use DMI matching to match known cases of this. |
4267 |
+ * |
4268 |
+- * We work around this by always reporting ACPI_STA_DEFAULT for these |
4269 |
+- * devices. Note this MUST only be done for devices where this is safe. |
4270 |
++ * Likewise sometimes some not-actually present devices are sometimes |
4271 |
++ * reported as present, which may cause issues. |
4272 |
+ * |
4273 |
+- * This forcing of devices to be present is limited to specific CPU (SoC) |
4274 |
+- * models both to avoid potentially causing trouble on other models and |
4275 |
+- * because some HIDs are re-used on different SoCs for completely |
4276 |
+- * different devices. |
4277 |
++ * We work around this by using the below quirk list to override the status |
4278 |
++ * reported by the _STA method with a fixed value (ACPI_STA_DEFAULT or 0). |
4279 |
++ * Note this MUST only be done for devices where this is safe. |
4280 |
++ * |
4281 |
++ * This status overriding is limited to specific CPU (SoC) models both to |
4282 |
++ * avoid potentially causing trouble on other models and because some HIDs |
4283 |
++ * are re-used on different SoCs for completely different devices. |
4284 |
+ */ |
4285 |
+-struct always_present_id { |
4286 |
++struct override_status_id { |
4287 |
+ struct acpi_device_id hid[2]; |
4288 |
+ struct x86_cpu_id cpu_ids[2]; |
4289 |
+ struct dmi_system_id dmi_ids[2]; /* Optional */ |
4290 |
+ const char *uid; |
4291 |
++ const char *path; |
4292 |
++ unsigned long long status; |
4293 |
+ }; |
4294 |
+ |
4295 |
+-#define X86_MATCH(model) X86_MATCH_INTEL_FAM6_MODEL(model, NULL) |
4296 |
+- |
4297 |
+-#define ENTRY(hid, uid, cpu_models, dmi...) { \ |
4298 |
++#define ENTRY(status, hid, uid, path, cpu_model, dmi...) { \ |
4299 |
+ { { hid, }, {} }, \ |
4300 |
+- { cpu_models, {} }, \ |
4301 |
++ { X86_MATCH_INTEL_FAM6_MODEL(cpu_model, NULL), {} }, \ |
4302 |
+ { { .matches = dmi }, {} }, \ |
4303 |
+ uid, \ |
4304 |
++ path, \ |
4305 |
++ status, \ |
4306 |
+ } |
4307 |
+ |
4308 |
+-static const struct always_present_id always_present_ids[] = { |
4309 |
++#define PRESENT_ENTRY_HID(hid, uid, cpu_model, dmi...) \ |
4310 |
++ ENTRY(ACPI_STA_DEFAULT, hid, uid, NULL, cpu_model, dmi) |
4311 |
++ |
4312 |
++#define NOT_PRESENT_ENTRY_HID(hid, uid, cpu_model, dmi...) \ |
4313 |
++ ENTRY(0, hid, uid, NULL, cpu_model, dmi) |
4314 |
++ |
4315 |
++#define PRESENT_ENTRY_PATH(path, cpu_model, dmi...) \ |
4316 |
++ ENTRY(ACPI_STA_DEFAULT, "", NULL, path, cpu_model, dmi) |
4317 |
++ |
4318 |
++#define NOT_PRESENT_ENTRY_PATH(path, cpu_model, dmi...) \ |
4319 |
++ ENTRY(0, "", NULL, path, cpu_model, dmi) |
4320 |
++ |
4321 |
++static const struct override_status_id override_status_ids[] = { |
4322 |
+ /* |
4323 |
+ * Bay / Cherry Trail PWM directly poked by GPU driver in win10, |
4324 |
+ * but Linux uses a separate PWM driver, harmless if not used. |
4325 |
+ */ |
4326 |
+- ENTRY("80860F09", "1", X86_MATCH(ATOM_SILVERMONT), {}), |
4327 |
+- ENTRY("80862288", "1", X86_MATCH(ATOM_AIRMONT), {}), |
4328 |
++ PRESENT_ENTRY_HID("80860F09", "1", ATOM_SILVERMONT, {}), |
4329 |
++ PRESENT_ENTRY_HID("80862288", "1", ATOM_AIRMONT, {}), |
4330 |
+ |
4331 |
+- /* Lenovo Yoga Book uses PWM2 for keyboard backlight control */ |
4332 |
+- ENTRY("80862289", "2", X86_MATCH(ATOM_AIRMONT), { |
4333 |
+- DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"), |
4334 |
+- }), |
4335 |
+ /* |
4336 |
+ * The INT0002 device is necessary to clear wakeup interrupt sources |
4337 |
+ * on Cherry Trail devices, without it we get nobody cared IRQ msgs. |
4338 |
+ */ |
4339 |
+- ENTRY("INT0002", "1", X86_MATCH(ATOM_AIRMONT), {}), |
4340 |
++ PRESENT_ENTRY_HID("INT0002", "1", ATOM_AIRMONT, {}), |
4341 |
+ /* |
4342 |
+ * On the Dell Venue 11 Pro 7130 and 7139, the DSDT hides |
4343 |
+ * the touchscreen ACPI device until a certain time |
4344 |
+ * after _SB.PCI0.GFX0.LCD.LCD1._ON gets called has passed |
4345 |
+ * *and* _STA has been called at least 3 times since. |
4346 |
+ */ |
4347 |
+- ENTRY("SYNA7500", "1", X86_MATCH(HASWELL_L), { |
4348 |
++ PRESENT_ENTRY_HID("SYNA7500", "1", HASWELL_L, { |
4349 |
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
4350 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7130"), |
4351 |
+ }), |
4352 |
+- ENTRY("SYNA7500", "1", X86_MATCH(HASWELL_L), { |
4353 |
++ PRESENT_ENTRY_HID("SYNA7500", "1", HASWELL_L, { |
4354 |
+ DMI_MATCH(DMI_SYS_VENDOR, "Dell Inc."), |
4355 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "Venue 11 Pro 7139"), |
4356 |
+ }), |
4357 |
+@@ -81,54 +94,83 @@ static const struct always_present_id always_present_ids[] = { |
4358 |
+ /* |
4359 |
+ * The GPD win BIOS dated 20170221 has disabled the accelerometer, the |
4360 |
+ * drivers sometimes cause crashes under Windows and this is how the |
4361 |
+- * manufacturer has solved this :| Note that the the DMI data is less |
4362 |
+- * generic then it seems, a board_vendor of "AMI Corporation" is quite |
4363 |
+- * rare and a board_name of "Default String" also is rare. |
4364 |
++ * manufacturer has solved this :| The DMI match may not seem unique, |
4365 |
++ * but it is. In the 67000+ DMI decode dumps from linux-hardware.org |
4366 |
++ * only 116 have board_vendor set to "AMI Corporation" and of those 116 |
4367 |
++ * only the GPD win and pocket entries' board_name is "Default string". |
4368 |
+ * |
4369 |
+ * Unfortunately the GPD pocket also uses these strings and its BIOS |
4370 |
+ * was copy-pasted from the GPD win, so it has a disabled KIOX000A |
4371 |
+ * node which we should not enable, thus we also check the BIOS date. |
4372 |
+ */ |
4373 |
+- ENTRY("KIOX000A", "1", X86_MATCH(ATOM_AIRMONT), { |
4374 |
++ PRESENT_ENTRY_HID("KIOX000A", "1", ATOM_AIRMONT, { |
4375 |
+ DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), |
4376 |
+ DMI_MATCH(DMI_BOARD_NAME, "Default string"), |
4377 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), |
4378 |
+ DMI_MATCH(DMI_BIOS_DATE, "02/21/2017") |
4379 |
+ }), |
4380 |
+- ENTRY("KIOX000A", "1", X86_MATCH(ATOM_AIRMONT), { |
4381 |
++ PRESENT_ENTRY_HID("KIOX000A", "1", ATOM_AIRMONT, { |
4382 |
+ DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), |
4383 |
+ DMI_MATCH(DMI_BOARD_NAME, "Default string"), |
4384 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), |
4385 |
+ DMI_MATCH(DMI_BIOS_DATE, "03/20/2017") |
4386 |
+ }), |
4387 |
+- ENTRY("KIOX000A", "1", X86_MATCH(ATOM_AIRMONT), { |
4388 |
++ PRESENT_ENTRY_HID("KIOX000A", "1", ATOM_AIRMONT, { |
4389 |
+ DMI_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), |
4390 |
+ DMI_MATCH(DMI_BOARD_NAME, "Default string"), |
4391 |
+ DMI_MATCH(DMI_PRODUCT_NAME, "Default string"), |
4392 |
+ DMI_MATCH(DMI_BIOS_DATE, "05/25/2017") |
4393 |
+ }), |
4394 |
++ |
4395 |
++ /* |
4396 |
++ * The GPD win/pocket have a PCI wifi card, but its DSDT has the SDIO |
4397 |
++ * mmc controller enabled and that has a child-device which _PS3 |
4398 |
++ * method sets a GPIO causing the PCI wifi card to turn off. |
4399 |
++ * See above remark about uniqueness of the DMI match. |
4400 |
++ */ |
4401 |
++ NOT_PRESENT_ENTRY_PATH("\\_SB_.PCI0.SDHB.BRC1", ATOM_AIRMONT, { |
4402 |
++ DMI_EXACT_MATCH(DMI_BOARD_VENDOR, "AMI Corporation"), |
4403 |
++ DMI_EXACT_MATCH(DMI_BOARD_NAME, "Default string"), |
4404 |
++ DMI_EXACT_MATCH(DMI_BOARD_SERIAL, "Default string"), |
4405 |
++ DMI_EXACT_MATCH(DMI_PRODUCT_NAME, "Default string"), |
4406 |
++ }), |
4407 |
+ }; |
4408 |
+ |
4409 |
+-bool acpi_device_always_present(struct acpi_device *adev) |
4410 |
++bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *status) |
4411 |
+ { |
4412 |
+ bool ret = false; |
4413 |
+ unsigned int i; |
4414 |
+ |
4415 |
+- for (i = 0; i < ARRAY_SIZE(always_present_ids); i++) { |
4416 |
+- if (acpi_match_device_ids(adev, always_present_ids[i].hid)) |
4417 |
++ for (i = 0; i < ARRAY_SIZE(override_status_ids); i++) { |
4418 |
++ if (!x86_match_cpu(override_status_ids[i].cpu_ids)) |
4419 |
+ continue; |
4420 |
+ |
4421 |
+- if (!adev->pnp.unique_id || |
4422 |
+- strcmp(adev->pnp.unique_id, always_present_ids[i].uid)) |
4423 |
++ if (override_status_ids[i].dmi_ids[0].matches[0].slot && |
4424 |
++ !dmi_check_system(override_status_ids[i].dmi_ids)) |
4425 |
+ continue; |
4426 |
+ |
4427 |
+- if (!x86_match_cpu(always_present_ids[i].cpu_ids)) |
4428 |
+- continue; |
4429 |
++ if (override_status_ids[i].path) { |
4430 |
++ struct acpi_buffer path = { ACPI_ALLOCATE_BUFFER, NULL }; |
4431 |
++ bool match; |
4432 |
+ |
4433 |
+- if (always_present_ids[i].dmi_ids[0].matches[0].slot && |
4434 |
+- !dmi_check_system(always_present_ids[i].dmi_ids)) |
4435 |
+- continue; |
4436 |
++ if (acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &path)) |
4437 |
++ continue; |
4438 |
++ |
4439 |
++ match = strcmp((char *)path.pointer, override_status_ids[i].path) == 0; |
4440 |
++ kfree(path.pointer); |
4441 |
++ |
4442 |
++ if (!match) |
4443 |
++ continue; |
4444 |
++ } else { |
4445 |
++ if (acpi_match_device_ids(adev, override_status_ids[i].hid)) |
4446 |
++ continue; |
4447 |
++ |
4448 |
++ if (!adev->pnp.unique_id || |
4449 |
++ strcmp(adev->pnp.unique_id, override_status_ids[i].uid)) |
4450 |
++ continue; |
4451 |
++ } |
4452 |
+ |
4453 |
++ *status = override_status_ids[i].status; |
4454 |
+ ret = true; |
4455 |
+ break; |
4456 |
+ } |
4457 |
+diff --git a/drivers/android/binder.c b/drivers/android/binder.c |
4458 |
+index c75fb600740cc..99ae919255f4d 100644 |
4459 |
+--- a/drivers/android/binder.c |
4460 |
++++ b/drivers/android/binder.c |
4461 |
+@@ -1608,15 +1608,21 @@ static void binder_cleanup_transaction(struct binder_transaction *t, |
4462 |
+ /** |
4463 |
+ * binder_get_object() - gets object and checks for valid metadata |
4464 |
+ * @proc: binder_proc owning the buffer |
4465 |
++ * @u: sender's user pointer to base of buffer |
4466 |
+ * @buffer: binder_buffer that we're parsing. |
4467 |
+ * @offset: offset in the @buffer at which to validate an object. |
4468 |
+ * @object: struct binder_object to read into |
4469 |
+ * |
4470 |
+- * Return: If there's a valid metadata object at @offset in @buffer, the |
4471 |
++ * Copy the binder object at the given offset into @object. If @u is |
4472 |
++ * provided then the copy is from the sender's buffer. If not, then |
4473 |
++ * it is copied from the target's @buffer. |
4474 |
++ * |
4475 |
++ * Return: If there's a valid metadata object at @offset, the |
4476 |
+ * size of that object. Otherwise, it returns zero. The object |
4477 |
+ * is read into the struct binder_object pointed to by @object. |
4478 |
+ */ |
4479 |
+ static size_t binder_get_object(struct binder_proc *proc, |
4480 |
++ const void __user *u, |
4481 |
+ struct binder_buffer *buffer, |
4482 |
+ unsigned long offset, |
4483 |
+ struct binder_object *object) |
4484 |
+@@ -1626,10 +1632,16 @@ static size_t binder_get_object(struct binder_proc *proc, |
4485 |
+ size_t object_size = 0; |
4486 |
+ |
4487 |
+ read_size = min_t(size_t, sizeof(*object), buffer->data_size - offset); |
4488 |
+- if (offset > buffer->data_size || read_size < sizeof(*hdr) || |
4489 |
+- binder_alloc_copy_from_buffer(&proc->alloc, object, buffer, |
4490 |
+- offset, read_size)) |
4491 |
++ if (offset > buffer->data_size || read_size < sizeof(*hdr)) |
4492 |
+ return 0; |
4493 |
++ if (u) { |
4494 |
++ if (copy_from_user(object, u + offset, read_size)) |
4495 |
++ return 0; |
4496 |
++ } else { |
4497 |
++ if (binder_alloc_copy_from_buffer(&proc->alloc, object, buffer, |
4498 |
++ offset, read_size)) |
4499 |
++ return 0; |
4500 |
++ } |
4501 |
+ |
4502 |
+ /* Ok, now see if we read a complete object. */ |
4503 |
+ hdr = &object->hdr; |
4504 |
+@@ -1702,7 +1714,7 @@ static struct binder_buffer_object *binder_validate_ptr( |
4505 |
+ b, buffer_offset, |
4506 |
+ sizeof(object_offset))) |
4507 |
+ return NULL; |
4508 |
+- object_size = binder_get_object(proc, b, object_offset, object); |
4509 |
++ object_size = binder_get_object(proc, NULL, b, object_offset, object); |
4510 |
+ if (!object_size || object->hdr.type != BINDER_TYPE_PTR) |
4511 |
+ return NULL; |
4512 |
+ if (object_offsetp) |
4513 |
+@@ -1767,7 +1779,8 @@ static bool binder_validate_fixup(struct binder_proc *proc, |
4514 |
+ unsigned long buffer_offset; |
4515 |
+ struct binder_object last_object; |
4516 |
+ struct binder_buffer_object *last_bbo; |
4517 |
+- size_t object_size = binder_get_object(proc, b, last_obj_offset, |
4518 |
++ size_t object_size = binder_get_object(proc, NULL, b, |
4519 |
++ last_obj_offset, |
4520 |
+ &last_object); |
4521 |
+ if (object_size != sizeof(*last_bbo)) |
4522 |
+ return false; |
4523 |
+@@ -1882,7 +1895,7 @@ static void binder_transaction_buffer_release(struct binder_proc *proc, |
4524 |
+ if (!binder_alloc_copy_from_buffer(&proc->alloc, &object_offset, |
4525 |
+ buffer, buffer_offset, |
4526 |
+ sizeof(object_offset))) |
4527 |
+- object_size = binder_get_object(proc, buffer, |
4528 |
++ object_size = binder_get_object(proc, NULL, buffer, |
4529 |
+ object_offset, &object); |
4530 |
+ if (object_size == 0) { |
4531 |
+ pr_err("transaction release %d bad object at offset %lld, size %zd\n", |
4532 |
+@@ -2269,8 +2282,8 @@ static int binder_translate_fd_array(struct binder_fd_array_object *fda, |
4533 |
+ if (!ret) |
4534 |
+ ret = binder_translate_fd(fd, offset, t, thread, |
4535 |
+ in_reply_to); |
4536 |
+- if (ret < 0) |
4537 |
+- return ret; |
4538 |
++ if (ret) |
4539 |
++ return ret > 0 ? -EINVAL : ret; |
4540 |
+ } |
4541 |
+ return 0; |
4542 |
+ } |
4543 |
+@@ -2455,6 +2468,7 @@ static void binder_transaction(struct binder_proc *proc, |
4544 |
+ binder_size_t off_start_offset, off_end_offset; |
4545 |
+ binder_size_t off_min; |
4546 |
+ binder_size_t sg_buf_offset, sg_buf_end_offset; |
4547 |
++ binder_size_t user_offset = 0; |
4548 |
+ struct binder_proc *target_proc = NULL; |
4549 |
+ struct binder_thread *target_thread = NULL; |
4550 |
+ struct binder_node *target_node = NULL; |
4551 |
+@@ -2469,6 +2483,8 @@ static void binder_transaction(struct binder_proc *proc, |
4552 |
+ int t_debug_id = atomic_inc_return(&binder_last_id); |
4553 |
+ char *secctx = NULL; |
4554 |
+ u32 secctx_sz = 0; |
4555 |
++ const void __user *user_buffer = (const void __user *) |
4556 |
++ (uintptr_t)tr->data.ptr.buffer; |
4557 |
+ |
4558 |
+ e = binder_transaction_log_add(&binder_transaction_log); |
4559 |
+ e->debug_id = t_debug_id; |
4560 |
+@@ -2780,19 +2796,6 @@ static void binder_transaction(struct binder_proc *proc, |
4561 |
+ t->buffer->clear_on_free = !!(t->flags & TF_CLEAR_BUF); |
4562 |
+ trace_binder_transaction_alloc_buf(t->buffer); |
4563 |
+ |
4564 |
+- if (binder_alloc_copy_user_to_buffer( |
4565 |
+- &target_proc->alloc, |
4566 |
+- t->buffer, 0, |
4567 |
+- (const void __user *) |
4568 |
+- (uintptr_t)tr->data.ptr.buffer, |
4569 |
+- tr->data_size)) { |
4570 |
+- binder_user_error("%d:%d got transaction with invalid data ptr\n", |
4571 |
+- proc->pid, thread->pid); |
4572 |
+- return_error = BR_FAILED_REPLY; |
4573 |
+- return_error_param = -EFAULT; |
4574 |
+- return_error_line = __LINE__; |
4575 |
+- goto err_copy_data_failed; |
4576 |
+- } |
4577 |
+ if (binder_alloc_copy_user_to_buffer( |
4578 |
+ &target_proc->alloc, |
4579 |
+ t->buffer, |
4580 |
+@@ -2837,6 +2840,7 @@ static void binder_transaction(struct binder_proc *proc, |
4581 |
+ size_t object_size; |
4582 |
+ struct binder_object object; |
4583 |
+ binder_size_t object_offset; |
4584 |
++ binder_size_t copy_size; |
4585 |
+ |
4586 |
+ if (binder_alloc_copy_from_buffer(&target_proc->alloc, |
4587 |
+ &object_offset, |
4588 |
+@@ -2848,8 +2852,27 @@ static void binder_transaction(struct binder_proc *proc, |
4589 |
+ return_error_line = __LINE__; |
4590 |
+ goto err_bad_offset; |
4591 |
+ } |
4592 |
+- object_size = binder_get_object(target_proc, t->buffer, |
4593 |
+- object_offset, &object); |
4594 |
++ |
4595 |
++ /* |
4596 |
++ * Copy the source user buffer up to the next object |
4597 |
++ * that will be processed. |
4598 |
++ */ |
4599 |
++ copy_size = object_offset - user_offset; |
4600 |
++ if (copy_size && (user_offset > object_offset || |
4601 |
++ binder_alloc_copy_user_to_buffer( |
4602 |
++ &target_proc->alloc, |
4603 |
++ t->buffer, user_offset, |
4604 |
++ user_buffer + user_offset, |
4605 |
++ copy_size))) { |
4606 |
++ binder_user_error("%d:%d got transaction with invalid data ptr\n", |
4607 |
++ proc->pid, thread->pid); |
4608 |
++ return_error = BR_FAILED_REPLY; |
4609 |
++ return_error_param = -EFAULT; |
4610 |
++ return_error_line = __LINE__; |
4611 |
++ goto err_copy_data_failed; |
4612 |
++ } |
4613 |
++ object_size = binder_get_object(target_proc, user_buffer, |
4614 |
++ t->buffer, object_offset, &object); |
4615 |
+ if (object_size == 0 || object_offset < off_min) { |
4616 |
+ binder_user_error("%d:%d got transaction with invalid offset (%lld, min %lld max %lld) or object.\n", |
4617 |
+ proc->pid, thread->pid, |
4618 |
+@@ -2861,6 +2884,11 @@ static void binder_transaction(struct binder_proc *proc, |
4619 |
+ return_error_line = __LINE__; |
4620 |
+ goto err_bad_offset; |
4621 |
+ } |
4622 |
++ /* |
4623 |
++ * Set offset to the next buffer fragment to be |
4624 |
++ * copied |
4625 |
++ */ |
4626 |
++ user_offset = object_offset + object_size; |
4627 |
+ |
4628 |
+ hdr = &object.hdr; |
4629 |
+ off_min = object_offset + object_size; |
4630 |
+@@ -2956,9 +2984,14 @@ static void binder_transaction(struct binder_proc *proc, |
4631 |
+ } |
4632 |
+ ret = binder_translate_fd_array(fda, parent, t, thread, |
4633 |
+ in_reply_to); |
4634 |
+- if (ret < 0) { |
4635 |
++ if (!ret) |
4636 |
++ ret = binder_alloc_copy_to_buffer(&target_proc->alloc, |
4637 |
++ t->buffer, |
4638 |
++ object_offset, |
4639 |
++ fda, sizeof(*fda)); |
4640 |
++ if (ret) { |
4641 |
+ return_error = BR_FAILED_REPLY; |
4642 |
+- return_error_param = ret; |
4643 |
++ return_error_param = ret > 0 ? -EINVAL : ret; |
4644 |
+ return_error_line = __LINE__; |
4645 |
+ goto err_translate_failed; |
4646 |
+ } |
4647 |
+@@ -3028,6 +3061,19 @@ static void binder_transaction(struct binder_proc *proc, |
4648 |
+ goto err_bad_object_type; |
4649 |
+ } |
4650 |
+ } |
4651 |
++ /* Done processing objects, copy the rest of the buffer */ |
4652 |
++ if (binder_alloc_copy_user_to_buffer( |
4653 |
++ &target_proc->alloc, |
4654 |
++ t->buffer, user_offset, |
4655 |
++ user_buffer + user_offset, |
4656 |
++ tr->data_size - user_offset)) { |
4657 |
++ binder_user_error("%d:%d got transaction with invalid data ptr\n", |
4658 |
++ proc->pid, thread->pid); |
4659 |
++ return_error = BR_FAILED_REPLY; |
4660 |
++ return_error_param = -EFAULT; |
4661 |
++ return_error_line = __LINE__; |
4662 |
++ goto err_copy_data_failed; |
4663 |
++ } |
4664 |
+ if (t->buffer->oneway_spam_suspect) |
4665 |
+ tcomplete->type = BINDER_WORK_TRANSACTION_ONEWAY_SPAM_SUSPECT; |
4666 |
+ else |
4667 |
+diff --git a/drivers/base/core.c b/drivers/base/core.c |
4668 |
+index 63577de268565..8e73a34e10055 100644 |
4669 |
+--- a/drivers/base/core.c |
4670 |
++++ b/drivers/base/core.c |
4671 |
+@@ -485,8 +485,7 @@ static void device_link_release_fn(struct work_struct *work) |
4672 |
+ /* Ensure that all references to the link object have been dropped. */ |
4673 |
+ device_link_synchronize_removal(); |
4674 |
+ |
4675 |
+- while (refcount_dec_not_one(&link->rpm_active)) |
4676 |
+- pm_runtime_put(link->supplier); |
4677 |
++ pm_runtime_release_supplier(link, true); |
4678 |
+ |
4679 |
+ put_device(link->consumer); |
4680 |
+ put_device(link->supplier); |
4681 |
+diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c |
4682 |
+index ec94049442b99..44ae3909e64bb 100644 |
4683 |
+--- a/drivers/base/power/runtime.c |
4684 |
++++ b/drivers/base/power/runtime.c |
4685 |
+@@ -305,19 +305,40 @@ static int rpm_get_suppliers(struct device *dev) |
4686 |
+ return 0; |
4687 |
+ } |
4688 |
+ |
4689 |
++/** |
4690 |
++ * pm_runtime_release_supplier - Drop references to device link's supplier. |
4691 |
++ * @link: Target device link. |
4692 |
++ * @check_idle: Whether or not to check if the supplier device is idle. |
4693 |
++ * |
4694 |
++ * Drop all runtime PM references associated with @link to its supplier device |
4695 |
++ * and if @check_idle is set, check if that device is idle (and so it can be |
4696 |
++ * suspended). |
4697 |
++ */ |
4698 |
++void pm_runtime_release_supplier(struct device_link *link, bool check_idle) |
4699 |
++{ |
4700 |
++ struct device *supplier = link->supplier; |
4701 |
++ |
4702 |
++ /* |
4703 |
++ * The additional power.usage_count check is a safety net in case |
4704 |
++ * the rpm_active refcount becomes saturated, in which case |
4705 |
++ * refcount_dec_not_one() would return true forever, but it is not |
4706 |
++ * strictly necessary. |
4707 |
++ */ |
4708 |
++ while (refcount_dec_not_one(&link->rpm_active) && |
4709 |
++ atomic_read(&supplier->power.usage_count) > 0) |
4710 |
++ pm_runtime_put_noidle(supplier); |
4711 |
++ |
4712 |
++ if (check_idle) |
4713 |
++ pm_request_idle(supplier); |
4714 |
++} |
4715 |
++ |
4716 |
+ static void __rpm_put_suppliers(struct device *dev, bool try_to_suspend) |
4717 |
+ { |
4718 |
+ struct device_link *link; |
4719 |
+ |
4720 |
+ list_for_each_entry_rcu(link, &dev->links.suppliers, c_node, |
4721 |
+- device_links_read_lock_held()) { |
4722 |
+- |
4723 |
+- while (refcount_dec_not_one(&link->rpm_active)) |
4724 |
+- pm_runtime_put_noidle(link->supplier); |
4725 |
+- |
4726 |
+- if (try_to_suspend) |
4727 |
+- pm_request_idle(link->supplier); |
4728 |
+- } |
4729 |
++ device_links_read_lock_held()) |
4730 |
++ pm_runtime_release_supplier(link, try_to_suspend); |
4731 |
+ } |
4732 |
+ |
4733 |
+ static void rpm_put_suppliers(struct device *dev) |
4734 |
+@@ -1770,9 +1791,7 @@ void pm_runtime_drop_link(struct device_link *link) |
4735 |
+ return; |
4736 |
+ |
4737 |
+ pm_runtime_drop_link_count(link->consumer); |
4738 |
+- |
4739 |
+- while (refcount_dec_not_one(&link->rpm_active)) |
4740 |
+- pm_runtime_put(link->supplier); |
4741 |
++ pm_runtime_release_supplier(link, true); |
4742 |
+ } |
4743 |
+ |
4744 |
+ static bool pm_runtime_need_not_resume(struct device *dev) |
4745 |
+diff --git a/drivers/base/property.c b/drivers/base/property.c |
4746 |
+index 453918eb7390c..4c77837769c6e 100644 |
4747 |
+--- a/drivers/base/property.c |
4748 |
++++ b/drivers/base/property.c |
4749 |
+@@ -1269,8 +1269,10 @@ fwnode_graph_devcon_match(struct fwnode_handle *fwnode, const char *con_id, |
4750 |
+ |
4751 |
+ fwnode_graph_for_each_endpoint(fwnode, ep) { |
4752 |
+ node = fwnode_graph_get_remote_port_parent(ep); |
4753 |
+- if (!fwnode_device_is_available(node)) |
4754 |
++ if (!fwnode_device_is_available(node)) { |
4755 |
++ fwnode_handle_put(node); |
4756 |
+ continue; |
4757 |
++ } |
4758 |
+ |
4759 |
+ ret = match(node, con_id, data); |
4760 |
+ fwnode_handle_put(node); |
4761 |
+diff --git a/drivers/base/regmap/regmap.c b/drivers/base/regmap/regmap.c |
4762 |
+index 21a0c2562ec06..f7811641ed5ae 100644 |
4763 |
+--- a/drivers/base/regmap/regmap.c |
4764 |
++++ b/drivers/base/regmap/regmap.c |
4765 |
+@@ -647,6 +647,7 @@ int regmap_attach_dev(struct device *dev, struct regmap *map, |
4766 |
+ if (ret) |
4767 |
+ return ret; |
4768 |
+ |
4769 |
++ regmap_debugfs_exit(map); |
4770 |
+ regmap_debugfs_init(map); |
4771 |
+ |
4772 |
+ /* Add a devres resource for dev_get_regmap() */ |
4773 |
+diff --git a/drivers/base/swnode.c b/drivers/base/swnode.c |
4774 |
+index c46f6a8e14d23..3ba1232ce8451 100644 |
4775 |
+--- a/drivers/base/swnode.c |
4776 |
++++ b/drivers/base/swnode.c |
4777 |
+@@ -535,7 +535,7 @@ software_node_get_reference_args(const struct fwnode_handle *fwnode, |
4778 |
+ return -ENOENT; |
4779 |
+ |
4780 |
+ if (nargs_prop) { |
4781 |
+- error = property_entry_read_int_array(swnode->node->properties, |
4782 |
++ error = property_entry_read_int_array(ref->node->properties, |
4783 |
+ nargs_prop, sizeof(u32), |
4784 |
+ &nargs_prop_val, 1); |
4785 |
+ if (error) |
4786 |
+diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c |
4787 |
+index fb2aafabfebc1..4a6a74177b3c9 100644 |
4788 |
+--- a/drivers/block/floppy.c |
4789 |
++++ b/drivers/block/floppy.c |
4790 |
+@@ -1014,7 +1014,7 @@ static DECLARE_DELAYED_WORK(fd_timer, fd_timer_workfn); |
4791 |
+ static void cancel_activity(void) |
4792 |
+ { |
4793 |
+ do_floppy = NULL; |
4794 |
+- cancel_delayed_work_sync(&fd_timer); |
4795 |
++ cancel_delayed_work(&fd_timer); |
4796 |
+ cancel_work_sync(&floppy_work); |
4797 |
+ } |
4798 |
+ |
4799 |
+@@ -3080,6 +3080,8 @@ static void raw_cmd_free(struct floppy_raw_cmd **ptr) |
4800 |
+ } |
4801 |
+ } |
4802 |
+ |
4803 |
++#define MAX_LEN (1UL << MAX_ORDER << PAGE_SHIFT) |
4804 |
++ |
4805 |
+ static int raw_cmd_copyin(int cmd, void __user *param, |
4806 |
+ struct floppy_raw_cmd **rcmd) |
4807 |
+ { |
4808 |
+@@ -3107,7 +3109,7 @@ loop: |
4809 |
+ ptr->resultcode = 0; |
4810 |
+ |
4811 |
+ if (ptr->flags & (FD_RAW_READ | FD_RAW_WRITE)) { |
4812 |
+- if (ptr->length <= 0) |
4813 |
++ if (ptr->length <= 0 || ptr->length >= MAX_LEN) |
4814 |
+ return -EINVAL; |
4815 |
+ ptr->kernel_data = (char *)fd_dma_mem_alloc(ptr->length); |
4816 |
+ fallback_on_nodma_alloc(&ptr->kernel_data, ptr->length); |
4817 |
+diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c |
4818 |
+index 525be2e1fbb25..e73d4c719b0ad 100644 |
4819 |
+--- a/drivers/bluetooth/btintel.c |
4820 |
++++ b/drivers/bluetooth/btintel.c |
4821 |
+@@ -2330,10 +2330,14 @@ static int btintel_setup_combined(struct hci_dev *hdev) |
4822 |
+ case 0x12: /* ThP */ |
4823 |
+ case 0x13: /* HrP */ |
4824 |
+ case 0x14: /* CcP */ |
4825 |
+- /* Some legacy bootloader devices from JfP supports both old |
4826 |
+- * and TLV based HCI_Intel_Read_Version command. But we don't |
4827 |
+- * want to use the TLV based setup routines for those legacy |
4828 |
+- * bootloader device. |
4829 |
++ /* Some legacy bootloader devices starting from JfP, |
4830 |
++ * the operational firmware supports both old and TLV based |
4831 |
++ * HCI_Intel_Read_Version command based on the command |
4832 |
++ * parameter. |
4833 |
++ * |
4834 |
++ * For upgrading firmware case, the TLV based version cannot |
4835 |
++ * be used because the firmware filename for legacy bootloader |
4836 |
++ * is based on the old format. |
4837 |
+ * |
4838 |
+ * Also, it is not easy to convert TLV based version from the |
4839 |
+ * legacy version format. |
4840 |
+@@ -2345,6 +2349,20 @@ static int btintel_setup_combined(struct hci_dev *hdev) |
4841 |
+ err = btintel_read_version(hdev, &ver); |
4842 |
+ if (err) |
4843 |
+ return err; |
4844 |
++ |
4845 |
++ /* Apply the device specific HCI quirks |
4846 |
++ * |
4847 |
++ * All Legacy bootloader devices support WBS |
4848 |
++ */ |
4849 |
++ set_bit(HCI_QUIRK_WIDEBAND_SPEECH_SUPPORTED, &hdev->quirks); |
4850 |
++ |
4851 |
++ /* Valid LE States quirk for JfP/ThP familiy */ |
4852 |
++ if (ver.hw_variant == 0x11 || ver.hw_variant == 0x12) |
4853 |
++ set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); |
4854 |
++ |
4855 |
++ /* Setup MSFT Extension support */ |
4856 |
++ btintel_set_msft_opcode(hdev, ver.hw_variant); |
4857 |
++ |
4858 |
+ err = btintel_bootloader_setup(hdev, &ver); |
4859 |
+ break; |
4860 |
+ case 0x17: |
4861 |
+diff --git a/drivers/bluetooth/btmtksdio.c b/drivers/bluetooth/btmtksdio.c |
4862 |
+index 9872ef18f9fea..1cbdeca1fdc4a 100644 |
4863 |
+--- a/drivers/bluetooth/btmtksdio.c |
4864 |
++++ b/drivers/bluetooth/btmtksdio.c |
4865 |
+@@ -1042,6 +1042,8 @@ static int btmtksdio_runtime_suspend(struct device *dev) |
4866 |
+ if (!bdev) |
4867 |
+ return 0; |
4868 |
+ |
4869 |
++ sdio_set_host_pm_flags(func, MMC_PM_KEEP_POWER); |
4870 |
++ |
4871 |
+ sdio_claim_host(bdev->func); |
4872 |
+ |
4873 |
+ sdio_writel(bdev->func, C_FW_OWN_REQ_SET, MTK_REG_CHLPCR, &err); |
4874 |
+diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c |
4875 |
+index fa44828562d32..ac90392cce339 100644 |
4876 |
+--- a/drivers/bluetooth/btusb.c |
4877 |
++++ b/drivers/bluetooth/btusb.c |
4878 |
+@@ -2561,6 +2561,7 @@ static int btusb_mtk_setup_firmware_79xx(struct hci_dev *hdev, const char *fwnam |
4879 |
+ } else { |
4880 |
+ bt_dev_err(hdev, "Failed wmt patch dwnld status (%d)", |
4881 |
+ status); |
4882 |
++ err = -EIO; |
4883 |
+ goto err_release_fw; |
4884 |
+ } |
4885 |
+ } |
4886 |
+@@ -2856,6 +2857,10 @@ static int btusb_mtk_setup(struct hci_dev *hdev) |
4887 |
+ "mediatek/BT_RAM_CODE_MT%04x_1_%x_hdr.bin", |
4888 |
+ dev_id & 0xffff, (fw_version & 0xff) + 1); |
4889 |
+ err = btusb_mtk_setup_firmware_79xx(hdev, fw_bin_name); |
4890 |
++ if (err < 0) { |
4891 |
++ bt_dev_err(hdev, "Failed to set up firmware (%d)", err); |
4892 |
++ return err; |
4893 |
++ } |
4894 |
+ |
4895 |
+ /* It's Device EndPoint Reset Option Register */ |
4896 |
+ btusb_mtk_uhw_reg_write(data, MTK_EP_RST_OPT, MTK_EP_RST_IN_OUT_OPT); |
4897 |
+diff --git a/drivers/bluetooth/hci_bcm.c b/drivers/bluetooth/hci_bcm.c |
4898 |
+index ef54afa293574..7abf99f0ee399 100644 |
4899 |
+--- a/drivers/bluetooth/hci_bcm.c |
4900 |
++++ b/drivers/bluetooth/hci_bcm.c |
4901 |
+@@ -1188,7 +1188,12 @@ static int bcm_probe(struct platform_device *pdev) |
4902 |
+ return -ENOMEM; |
4903 |
+ |
4904 |
+ dev->dev = &pdev->dev; |
4905 |
+- dev->irq = platform_get_irq(pdev, 0); |
4906 |
++ |
4907 |
++ ret = platform_get_irq(pdev, 0); |
4908 |
++ if (ret < 0) |
4909 |
++ return ret; |
4910 |
++ |
4911 |
++ dev->irq = ret; |
4912 |
+ |
4913 |
+ /* Initialize routing field to an unused value */ |
4914 |
+ dev->pcm_int_params[0] = 0xff; |
4915 |
+diff --git a/drivers/bluetooth/hci_qca.c b/drivers/bluetooth/hci_qca.c |
4916 |
+index 53deea2eb7b4d..8eb7fddfb9300 100644 |
4917 |
+--- a/drivers/bluetooth/hci_qca.c |
4918 |
++++ b/drivers/bluetooth/hci_qca.c |
4919 |
+@@ -1927,6 +1927,9 @@ static int qca_power_off(struct hci_dev *hdev) |
4920 |
+ hu->hdev->hw_error = NULL; |
4921 |
+ hu->hdev->cmd_timeout = NULL; |
4922 |
+ |
4923 |
++ del_timer_sync(&qca->wake_retrans_timer); |
4924 |
++ del_timer_sync(&qca->tx_idle_timer); |
4925 |
++ |
4926 |
+ /* Stop sending shutdown command if soc crashes. */ |
4927 |
+ if (soc_type != QCA_ROME |
4928 |
+ && qca->memdump_state == QCA_MEMDUMP_IDLE) { |
4929 |
+@@ -2055,14 +2058,14 @@ static int qca_serdev_probe(struct serdev_device *serdev) |
4930 |
+ |
4931 |
+ qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", |
4932 |
+ GPIOD_OUT_LOW); |
4933 |
+- if (!qcadev->bt_en && data->soc_type == QCA_WCN6750) { |
4934 |
++ if (IS_ERR_OR_NULL(qcadev->bt_en) && data->soc_type == QCA_WCN6750) { |
4935 |
+ dev_err(&serdev->dev, "failed to acquire BT_EN gpio\n"); |
4936 |
+ power_ctrl_enabled = false; |
4937 |
+ } |
4938 |
+ |
4939 |
+ qcadev->sw_ctrl = devm_gpiod_get_optional(&serdev->dev, "swctrl", |
4940 |
+ GPIOD_IN); |
4941 |
+- if (!qcadev->sw_ctrl && data->soc_type == QCA_WCN6750) |
4942 |
++ if (IS_ERR_OR_NULL(qcadev->sw_ctrl) && data->soc_type == QCA_WCN6750) |
4943 |
+ dev_warn(&serdev->dev, "failed to acquire SW_CTRL gpio\n"); |
4944 |
+ |
4945 |
+ qcadev->susclk = devm_clk_get_optional(&serdev->dev, NULL); |
4946 |
+@@ -2084,7 +2087,7 @@ static int qca_serdev_probe(struct serdev_device *serdev) |
4947 |
+ |
4948 |
+ qcadev->bt_en = devm_gpiod_get_optional(&serdev->dev, "enable", |
4949 |
+ GPIOD_OUT_LOW); |
4950 |
+- if (!qcadev->bt_en) { |
4951 |
++ if (IS_ERR_OR_NULL(qcadev->bt_en)) { |
4952 |
+ dev_warn(&serdev->dev, "failed to acquire enable gpio\n"); |
4953 |
+ power_ctrl_enabled = false; |
4954 |
+ } |
4955 |
+diff --git a/drivers/bluetooth/hci_vhci.c b/drivers/bluetooth/hci_vhci.c |
4956 |
+index 8ab26dec5f6e8..8469f9876dd26 100644 |
4957 |
+--- a/drivers/bluetooth/hci_vhci.c |
4958 |
++++ b/drivers/bluetooth/hci_vhci.c |
4959 |
+@@ -121,6 +121,8 @@ static int __vhci_create_device(struct vhci_data *data, __u8 opcode) |
4960 |
+ if (opcode & 0x80) |
4961 |
+ set_bit(HCI_QUIRK_RAW_DEVICE, &hdev->quirks); |
4962 |
+ |
4963 |
++ set_bit(HCI_QUIRK_VALID_LE_STATES, &hdev->quirks); |
4964 |
++ |
4965 |
+ if (hci_register_dev(hdev) < 0) { |
4966 |
+ BT_ERR("Can't register HCI device"); |
4967 |
+ hci_free_dev(hdev); |
4968 |
+diff --git a/drivers/bluetooth/virtio_bt.c b/drivers/bluetooth/virtio_bt.c |
4969 |
+index 57908ce4fae85..076e4942a3f0e 100644 |
4970 |
+--- a/drivers/bluetooth/virtio_bt.c |
4971 |
++++ b/drivers/bluetooth/virtio_bt.c |
4972 |
+@@ -202,6 +202,9 @@ static void virtbt_rx_handle(struct virtio_bluetooth *vbt, struct sk_buff *skb) |
4973 |
+ hci_skb_pkt_type(skb) = pkt_type; |
4974 |
+ hci_recv_frame(vbt->hdev, skb); |
4975 |
+ break; |
4976 |
++ default: |
4977 |
++ kfree_skb(skb); |
4978 |
++ break; |
4979 |
+ } |
4980 |
+ } |
4981 |
+ |
4982 |
+diff --git a/drivers/bus/mhi/core/init.c b/drivers/bus/mhi/core/init.c |
4983 |
+index 5aaca6d0f52b2..f1ec344175928 100644 |
4984 |
+--- a/drivers/bus/mhi/core/init.c |
4985 |
++++ b/drivers/bus/mhi/core/init.c |
4986 |
+@@ -788,6 +788,7 @@ static int parse_ch_cfg(struct mhi_controller *mhi_cntrl, |
4987 |
+ mhi_chan->offload_ch = ch_cfg->offload_channel; |
4988 |
+ mhi_chan->db_cfg.reset_req = ch_cfg->doorbell_mode_switch; |
4989 |
+ mhi_chan->pre_alloc = ch_cfg->auto_queue; |
4990 |
++ mhi_chan->wake_capable = ch_cfg->wake_capable; |
4991 |
+ |
4992 |
+ /* |
4993 |
+ * If MHI host allocates buffers, then the channel direction |
4994 |
+diff --git a/drivers/bus/mhi/core/pm.c b/drivers/bus/mhi/core/pm.c |
4995 |
+index 547e6e769546a..bb9a2043f3a20 100644 |
4996 |
+--- a/drivers/bus/mhi/core/pm.c |
4997 |
++++ b/drivers/bus/mhi/core/pm.c |
4998 |
+@@ -1053,7 +1053,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) |
4999 |
+ enum mhi_ee_type current_ee; |
5000 |
+ enum dev_st_transition next_state; |
5001 |
+ struct device *dev = &mhi_cntrl->mhi_dev->dev; |
5002 |
+- u32 val; |
5003 |
++ u32 interval_us = 25000; /* poll register field every 25 milliseconds */ |
5004 |
+ int ret; |
5005 |
+ |
5006 |
+ dev_info(dev, "Requested to power ON\n"); |
5007 |
+@@ -1070,10 +1070,6 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) |
5008 |
+ mutex_lock(&mhi_cntrl->pm_mutex); |
5009 |
+ mhi_cntrl->pm_state = MHI_PM_DISABLE; |
5010 |
+ |
5011 |
+- ret = mhi_init_irq_setup(mhi_cntrl); |
5012 |
+- if (ret) |
5013 |
+- goto error_setup_irq; |
5014 |
+- |
5015 |
+ /* Setup BHI INTVEC */ |
5016 |
+ write_lock_irq(&mhi_cntrl->pm_lock); |
5017 |
+ mhi_write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); |
5018 |
+@@ -1087,7 +1083,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) |
5019 |
+ dev_err(dev, "%s is not a valid EE for power on\n", |
5020 |
+ TO_MHI_EXEC_STR(current_ee)); |
5021 |
+ ret = -EIO; |
5022 |
+- goto error_async_power_up; |
5023 |
++ goto error_exit; |
5024 |
+ } |
5025 |
+ |
5026 |
+ state = mhi_get_mhi_state(mhi_cntrl); |
5027 |
+@@ -1096,20 +1092,12 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) |
5028 |
+ |
5029 |
+ if (state == MHI_STATE_SYS_ERR) { |
5030 |
+ mhi_set_mhi_state(mhi_cntrl, MHI_STATE_RESET); |
5031 |
+- ret = wait_event_timeout(mhi_cntrl->state_event, |
5032 |
+- MHI_PM_IN_FATAL_STATE(mhi_cntrl->pm_state) || |
5033 |
+- mhi_read_reg_field(mhi_cntrl, |
5034 |
+- mhi_cntrl->regs, |
5035 |
+- MHICTRL, |
5036 |
+- MHICTRL_RESET_MASK, |
5037 |
+- MHICTRL_RESET_SHIFT, |
5038 |
+- &val) || |
5039 |
+- !val, |
5040 |
+- msecs_to_jiffies(mhi_cntrl->timeout_ms)); |
5041 |
+- if (!ret) { |
5042 |
+- ret = -EIO; |
5043 |
++ ret = mhi_poll_reg_field(mhi_cntrl, mhi_cntrl->regs, MHICTRL, |
5044 |
++ MHICTRL_RESET_MASK, MHICTRL_RESET_SHIFT, 0, |
5045 |
++ interval_us); |
5046 |
++ if (ret) { |
5047 |
+ dev_info(dev, "Failed to reset MHI due to syserr state\n"); |
5048 |
+- goto error_async_power_up; |
5049 |
++ goto error_exit; |
5050 |
+ } |
5051 |
+ |
5052 |
+ /* |
5053 |
+@@ -1119,6 +1107,10 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) |
5054 |
+ mhi_write_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_INTVEC, 0); |
5055 |
+ } |
5056 |
+ |
5057 |
++ ret = mhi_init_irq_setup(mhi_cntrl); |
5058 |
++ if (ret) |
5059 |
++ goto error_exit; |
5060 |
++ |
5061 |
+ /* Transition to next state */ |
5062 |
+ next_state = MHI_IN_PBL(current_ee) ? |
5063 |
+ DEV_ST_TRANSITION_PBL : DEV_ST_TRANSITION_READY; |
5064 |
+@@ -1131,10 +1123,7 @@ int mhi_async_power_up(struct mhi_controller *mhi_cntrl) |
5065 |
+ |
5066 |
+ return 0; |
5067 |
+ |
5068 |
+-error_async_power_up: |
5069 |
+- mhi_deinit_free_irq(mhi_cntrl); |
5070 |
+- |
5071 |
+-error_setup_irq: |
5072 |
++error_exit: |
5073 |
+ mhi_cntrl->pm_state = MHI_PM_DISABLE; |
5074 |
+ mutex_unlock(&mhi_cntrl->pm_mutex); |
5075 |
+ |
5076 |
+diff --git a/drivers/bus/mhi/pci_generic.c b/drivers/bus/mhi/pci_generic.c |
5077 |
+index 4c577a7317091..b8b2811c7c0a9 100644 |
5078 |
+--- a/drivers/bus/mhi/pci_generic.c |
5079 |
++++ b/drivers/bus/mhi/pci_generic.c |
5080 |
+@@ -1018,7 +1018,7 @@ static int __maybe_unused mhi_pci_freeze(struct device *dev) |
5081 |
+ * context. |
5082 |
+ */ |
5083 |
+ if (test_and_clear_bit(MHI_PCI_DEV_STARTED, &mhi_pdev->status)) { |
5084 |
+- mhi_power_down(mhi_cntrl, false); |
5085 |
++ mhi_power_down(mhi_cntrl, true); |
5086 |
+ mhi_unprepare_after_power_down(mhi_cntrl); |
5087 |
+ } |
5088 |
+ |
5089 |
+diff --git a/drivers/char/mwave/3780i.h b/drivers/char/mwave/3780i.h |
5090 |
+index 9ccb6b270b071..95164246afd1a 100644 |
5091 |
+--- a/drivers/char/mwave/3780i.h |
5092 |
++++ b/drivers/char/mwave/3780i.h |
5093 |
+@@ -68,7 +68,7 @@ typedef struct { |
5094 |
+ unsigned char ClockControl:1; /* RW: Clock control: 0=normal, 1=stop 3780i clocks */ |
5095 |
+ unsigned char SoftReset:1; /* RW: Soft reset 0=normal, 1=soft reset active */ |
5096 |
+ unsigned char ConfigMode:1; /* RW: Configuration mode, 0=normal, 1=config mode */ |
5097 |
+- unsigned char Reserved:5; /* 0: Reserved */ |
5098 |
++ unsigned short Reserved:13; /* 0: Reserved */ |
5099 |
+ } DSP_ISA_SLAVE_CONTROL; |
5100 |
+ |
5101 |
+ |
5102 |
+diff --git a/drivers/char/random.c b/drivers/char/random.c |
5103 |
+index 7470ee24db2f9..a27ae3999ff32 100644 |
5104 |
+--- a/drivers/char/random.c |
5105 |
++++ b/drivers/char/random.c |
5106 |
+@@ -912,12 +912,14 @@ static struct crng_state *select_crng(void) |
5107 |
+ |
5108 |
+ /* |
5109 |
+ * crng_fast_load() can be called by code in the interrupt service |
5110 |
+- * path. So we can't afford to dilly-dally. |
5111 |
++ * path. So we can't afford to dilly-dally. Returns the number of |
5112 |
++ * bytes processed from cp. |
5113 |
+ */ |
5114 |
+-static int crng_fast_load(const char *cp, size_t len) |
5115 |
++static size_t crng_fast_load(const char *cp, size_t len) |
5116 |
+ { |
5117 |
+ unsigned long flags; |
5118 |
+ char *p; |
5119 |
++ size_t ret = 0; |
5120 |
+ |
5121 |
+ if (!spin_trylock_irqsave(&primary_crng.lock, flags)) |
5122 |
+ return 0; |
5123 |
+@@ -928,7 +930,7 @@ static int crng_fast_load(const char *cp, size_t len) |
5124 |
+ p = (unsigned char *) &primary_crng.state[4]; |
5125 |
+ while (len > 0 && crng_init_cnt < CRNG_INIT_CNT_THRESH) { |
5126 |
+ p[crng_init_cnt % CHACHA_KEY_SIZE] ^= *cp; |
5127 |
+- cp++; crng_init_cnt++; len--; |
5128 |
++ cp++; crng_init_cnt++; len--; ret++; |
5129 |
+ } |
5130 |
+ spin_unlock_irqrestore(&primary_crng.lock, flags); |
5131 |
+ if (crng_init_cnt >= CRNG_INIT_CNT_THRESH) { |
5132 |
+@@ -936,7 +938,7 @@ static int crng_fast_load(const char *cp, size_t len) |
5133 |
+ crng_init = 1; |
5134 |
+ pr_notice("fast init done\n"); |
5135 |
+ } |
5136 |
+- return 1; |
5137 |
++ return ret; |
5138 |
+ } |
5139 |
+ |
5140 |
+ /* |
5141 |
+@@ -1287,7 +1289,7 @@ void add_interrupt_randomness(int irq, int irq_flags) |
5142 |
+ if (unlikely(crng_init == 0)) { |
5143 |
+ if ((fast_pool->count >= 64) && |
5144 |
+ crng_fast_load((char *) fast_pool->pool, |
5145 |
+- sizeof(fast_pool->pool))) { |
5146 |
++ sizeof(fast_pool->pool)) > 0) { |
5147 |
+ fast_pool->count = 0; |
5148 |
+ fast_pool->last = now; |
5149 |
+ } |
5150 |
+@@ -2295,8 +2297,11 @@ void add_hwgenerator_randomness(const char *buffer, size_t count, |
5151 |
+ struct entropy_store *poolp = &input_pool; |
5152 |
+ |
5153 |
+ if (unlikely(crng_init == 0)) { |
5154 |
+- crng_fast_load(buffer, count); |
5155 |
+- return; |
5156 |
++ size_t ret = crng_fast_load(buffer, count); |
5157 |
++ count -= ret; |
5158 |
++ buffer += ret; |
5159 |
++ if (!count || crng_init == 0) |
5160 |
++ return; |
5161 |
+ } |
5162 |
+ |
5163 |
+ /* Suspend writing if we're above the trickle threshold. |
5164 |
+diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c |
5165 |
+index ddaeceb7e1091..df37e7b6a10a5 100644 |
5166 |
+--- a/drivers/char/tpm/tpm-chip.c |
5167 |
++++ b/drivers/char/tpm/tpm-chip.c |
5168 |
+@@ -474,13 +474,21 @@ static void tpm_del_char_device(struct tpm_chip *chip) |
5169 |
+ |
5170 |
+ /* Make the driver uncallable. */ |
5171 |
+ down_write(&chip->ops_sem); |
5172 |
+- if (chip->flags & TPM_CHIP_FLAG_TPM2) { |
5173 |
+- if (!tpm_chip_start(chip)) { |
5174 |
+- tpm2_shutdown(chip, TPM2_SU_CLEAR); |
5175 |
+- tpm_chip_stop(chip); |
5176 |
++ |
5177 |
++ /* |
5178 |
++ * Check if chip->ops is still valid: In case that the controller |
5179 |
++ * drivers shutdown handler unregisters the controller in its |
5180 |
++ * shutdown handler we are called twice and chip->ops to NULL. |
5181 |
++ */ |
5182 |
++ if (chip->ops) { |
5183 |
++ if (chip->flags & TPM_CHIP_FLAG_TPM2) { |
5184 |
++ if (!tpm_chip_start(chip)) { |
5185 |
++ tpm2_shutdown(chip, TPM2_SU_CLEAR); |
5186 |
++ tpm_chip_stop(chip); |
5187 |
++ } |
5188 |
+ } |
5189 |
++ chip->ops = NULL; |
5190 |
+ } |
5191 |
+- chip->ops = NULL; |
5192 |
+ up_write(&chip->ops_sem); |
5193 |
+ } |
5194 |
+ |
5195 |
+diff --git a/drivers/char/tpm/tpm_tis_core.c b/drivers/char/tpm/tpm_tis_core.c |
5196 |
+index b2659a4c40168..dc56b976d8162 100644 |
5197 |
+--- a/drivers/char/tpm/tpm_tis_core.c |
5198 |
++++ b/drivers/char/tpm/tpm_tis_core.c |
5199 |
+@@ -950,9 +950,11 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, |
5200 |
+ priv->timeout_max = TPM_TIMEOUT_USECS_MAX; |
5201 |
+ priv->phy_ops = phy_ops; |
5202 |
+ |
5203 |
++ dev_set_drvdata(&chip->dev, priv); |
5204 |
++ |
5205 |
+ rc = tpm_tis_read32(priv, TPM_DID_VID(0), &vendor); |
5206 |
+ if (rc < 0) |
5207 |
+- goto out_err; |
5208 |
++ return rc; |
5209 |
+ |
5210 |
+ priv->manufacturer_id = vendor; |
5211 |
+ |
5212 |
+@@ -962,8 +964,6 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, |
5213 |
+ priv->timeout_max = TIS_TIMEOUT_MAX_ATML; |
5214 |
+ } |
5215 |
+ |
5216 |
+- dev_set_drvdata(&chip->dev, priv); |
5217 |
+- |
5218 |
+ if (is_bsw()) { |
5219 |
+ priv->ilb_base_addr = ioremap(INTEL_LEGACY_BLK_BASE_ADDR, |
5220 |
+ ILB_REMAP_SIZE); |
5221 |
+@@ -994,7 +994,15 @@ int tpm_tis_core_init(struct device *dev, struct tpm_tis_data *priv, int irq, |
5222 |
+ intmask |= TPM_INTF_CMD_READY_INT | TPM_INTF_LOCALITY_CHANGE_INT | |
5223 |
+ TPM_INTF_DATA_AVAIL_INT | TPM_INTF_STS_VALID_INT; |
5224 |
+ intmask &= ~TPM_GLOBAL_INT_ENABLE; |
5225 |
++ |
5226 |
++ rc = request_locality(chip, 0); |
5227 |
++ if (rc < 0) { |
5228 |
++ rc = -ENODEV; |
5229 |
++ goto out_err; |
5230 |
++ } |
5231 |
++ |
5232 |
+ tpm_tis_write32(priv, TPM_INT_ENABLE(priv->locality), intmask); |
5233 |
++ release_locality(chip, 0); |
5234 |
+ |
5235 |
+ rc = tpm_chip_start(chip); |
5236 |
+ if (rc) |
5237 |
+diff --git a/drivers/clk/bcm/clk-bcm2835.c b/drivers/clk/bcm/clk-bcm2835.c |
5238 |
+index a254512965eb8..3667b4d731e71 100644 |
5239 |
+--- a/drivers/clk/bcm/clk-bcm2835.c |
5240 |
++++ b/drivers/clk/bcm/clk-bcm2835.c |
5241 |
+@@ -932,8 +932,7 @@ static int bcm2835_clock_is_on(struct clk_hw *hw) |
5242 |
+ |
5243 |
+ static u32 bcm2835_clock_choose_div(struct clk_hw *hw, |
5244 |
+ unsigned long rate, |
5245 |
+- unsigned long parent_rate, |
5246 |
+- bool round_up) |
5247 |
++ unsigned long parent_rate) |
5248 |
+ { |
5249 |
+ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); |
5250 |
+ const struct bcm2835_clock_data *data = clock->data; |
5251 |
+@@ -945,10 +944,6 @@ static u32 bcm2835_clock_choose_div(struct clk_hw *hw, |
5252 |
+ |
5253 |
+ rem = do_div(temp, rate); |
5254 |
+ div = temp; |
5255 |
+- |
5256 |
+- /* Round up and mask off the unused bits */ |
5257 |
+- if (round_up && ((div & unused_frac_mask) != 0 || rem != 0)) |
5258 |
+- div += unused_frac_mask + 1; |
5259 |
+ div &= ~unused_frac_mask; |
5260 |
+ |
5261 |
+ /* different clamping limits apply for a mash clock */ |
5262 |
+@@ -1079,7 +1074,7 @@ static int bcm2835_clock_set_rate(struct clk_hw *hw, |
5263 |
+ struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw); |
5264 |
+ struct bcm2835_cprman *cprman = clock->cprman; |
5265 |
+ const struct bcm2835_clock_data *data = clock->data; |
5266 |
+- u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate, false); |
5267 |
++ u32 div = bcm2835_clock_choose_div(hw, rate, parent_rate); |
5268 |
+ u32 ctl; |
5269 |
+ |
5270 |
+ spin_lock(&cprman->regs_lock); |
5271 |
+@@ -1130,7 +1125,7 @@ static unsigned long bcm2835_clock_choose_div_and_prate(struct clk_hw *hw, |
5272 |
+ |
5273 |
+ if (!(BIT(parent_idx) & data->set_rate_parent)) { |
5274 |
+ *prate = clk_hw_get_rate(parent); |
5275 |
+- *div = bcm2835_clock_choose_div(hw, rate, *prate, true); |
5276 |
++ *div = bcm2835_clock_choose_div(hw, rate, *prate); |
5277 |
+ |
5278 |
+ *avgrate = bcm2835_clock_rate_from_divisor(clock, *prate, *div); |
5279 |
+ |
5280 |
+@@ -1216,7 +1211,7 @@ static int bcm2835_clock_determine_rate(struct clk_hw *hw, |
5281 |
+ rate = bcm2835_clock_choose_div_and_prate(hw, i, req->rate, |
5282 |
+ &div, &prate, |
5283 |
+ &avgrate); |
5284 |
+- if (rate > best_rate && rate <= req->rate) { |
5285 |
++ if (abs(req->rate - rate) < abs(req->rate - best_rate)) { |
5286 |
+ best_parent = parent; |
5287 |
+ best_prate = prate; |
5288 |
+ best_rate = rate; |
5289 |
+diff --git a/drivers/clk/clk-bm1880.c b/drivers/clk/clk-bm1880.c |
5290 |
+index e6d6599d310a1..fad78a22218e8 100644 |
5291 |
+--- a/drivers/clk/clk-bm1880.c |
5292 |
++++ b/drivers/clk/clk-bm1880.c |
5293 |
+@@ -522,14 +522,6 @@ static struct clk_hw *bm1880_clk_register_pll(struct bm1880_pll_hw_clock *pll_cl |
5294 |
+ return hw; |
5295 |
+ } |
5296 |
+ |
5297 |
+-static void bm1880_clk_unregister_pll(struct clk_hw *hw) |
5298 |
+-{ |
5299 |
+- struct bm1880_pll_hw_clock *pll_hw = to_bm1880_pll_clk(hw); |
5300 |
+- |
5301 |
+- clk_hw_unregister(hw); |
5302 |
+- kfree(pll_hw); |
5303 |
+-} |
5304 |
+- |
5305 |
+ static int bm1880_clk_register_plls(struct bm1880_pll_hw_clock *clks, |
5306 |
+ int num_clks, |
5307 |
+ struct bm1880_clock_data *data) |
5308 |
+@@ -555,7 +547,7 @@ static int bm1880_clk_register_plls(struct bm1880_pll_hw_clock *clks, |
5309 |
+ |
5310 |
+ err_clk: |
5311 |
+ while (i--) |
5312 |
+- bm1880_clk_unregister_pll(data->hw_data.hws[clks[i].pll.id]); |
5313 |
++ clk_hw_unregister(data->hw_data.hws[clks[i].pll.id]); |
5314 |
+ |
5315 |
+ return PTR_ERR(hw); |
5316 |
+ } |
5317 |
+@@ -695,14 +687,6 @@ static struct clk_hw *bm1880_clk_register_div(struct bm1880_div_hw_clock *div_cl |
5318 |
+ return hw; |
5319 |
+ } |
5320 |
+ |
5321 |
+-static void bm1880_clk_unregister_div(struct clk_hw *hw) |
5322 |
+-{ |
5323 |
+- struct bm1880_div_hw_clock *div_hw = to_bm1880_div_clk(hw); |
5324 |
+- |
5325 |
+- clk_hw_unregister(hw); |
5326 |
+- kfree(div_hw); |
5327 |
+-} |
5328 |
+- |
5329 |
+ static int bm1880_clk_register_divs(struct bm1880_div_hw_clock *clks, |
5330 |
+ int num_clks, |
5331 |
+ struct bm1880_clock_data *data) |
5332 |
+@@ -729,7 +713,7 @@ static int bm1880_clk_register_divs(struct bm1880_div_hw_clock *clks, |
5333 |
+ |
5334 |
+ err_clk: |
5335 |
+ while (i--) |
5336 |
+- bm1880_clk_unregister_div(data->hw_data.hws[clks[i].div.id]); |
5337 |
++ clk_hw_unregister(data->hw_data.hws[clks[i].div.id]); |
5338 |
+ |
5339 |
+ return PTR_ERR(hw); |
5340 |
+ } |
5341 |
+diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c |
5342 |
+index 57ae183982d8c..f7b41366666e5 100644 |
5343 |
+--- a/drivers/clk/clk-si5341.c |
5344 |
++++ b/drivers/clk/clk-si5341.c |
5345 |
+@@ -1740,7 +1740,7 @@ static int si5341_probe(struct i2c_client *client, |
5346 |
+ clk_prepare(data->clk[i].hw.clk); |
5347 |
+ } |
5348 |
+ |
5349 |
+- err = of_clk_add_hw_provider(client->dev.of_node, of_clk_si5341_get, |
5350 |
++ err = devm_of_clk_add_hw_provider(&client->dev, of_clk_si5341_get, |
5351 |
+ data); |
5352 |
+ if (err) { |
5353 |
+ dev_err(&client->dev, "unable to add clk provider\n"); |
5354 |
+diff --git a/drivers/clk/clk-stm32f4.c b/drivers/clk/clk-stm32f4.c |
5355 |
+index af46176ad0539..473dfe632cc57 100644 |
5356 |
+--- a/drivers/clk/clk-stm32f4.c |
5357 |
++++ b/drivers/clk/clk-stm32f4.c |
5358 |
+@@ -129,7 +129,6 @@ static const struct stm32f4_gate_data stm32f429_gates[] __initconst = { |
5359 |
+ { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, |
5360 |
+ { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, |
5361 |
+ { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, |
5362 |
+- { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, |
5363 |
+ }; |
5364 |
+ |
5365 |
+ static const struct stm32f4_gate_data stm32f469_gates[] __initconst = { |
5366 |
+@@ -211,7 +210,6 @@ static const struct stm32f4_gate_data stm32f469_gates[] __initconst = { |
5367 |
+ { STM32F4_RCC_APB2ENR, 20, "spi5", "apb2_div" }, |
5368 |
+ { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, |
5369 |
+ { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, |
5370 |
+- { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, |
5371 |
+ }; |
5372 |
+ |
5373 |
+ static const struct stm32f4_gate_data stm32f746_gates[] __initconst = { |
5374 |
+@@ -286,7 +284,6 @@ static const struct stm32f4_gate_data stm32f746_gates[] __initconst = { |
5375 |
+ { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, |
5376 |
+ { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, |
5377 |
+ { STM32F4_RCC_APB2ENR, 23, "sai2", "apb2_div" }, |
5378 |
+- { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, |
5379 |
+ }; |
5380 |
+ |
5381 |
+ static const struct stm32f4_gate_data stm32f769_gates[] __initconst = { |
5382 |
+@@ -364,7 +361,6 @@ static const struct stm32f4_gate_data stm32f769_gates[] __initconst = { |
5383 |
+ { STM32F4_RCC_APB2ENR, 21, "spi6", "apb2_div" }, |
5384 |
+ { STM32F4_RCC_APB2ENR, 22, "sai1", "apb2_div" }, |
5385 |
+ { STM32F4_RCC_APB2ENR, 23, "sai2", "apb2_div" }, |
5386 |
+- { STM32F4_RCC_APB2ENR, 26, "ltdc", "apb2_div" }, |
5387 |
+ { STM32F4_RCC_APB2ENR, 30, "mdio", "apb2_div" }, |
5388 |
+ }; |
5389 |
+ |
5390 |
+diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c |
5391 |
+index a277fd4f2f0a6..ac11cefc31911 100644 |
5392 |
+--- a/drivers/clk/clk.c |
5393 |
++++ b/drivers/clk/clk.c |
5394 |
+@@ -3340,6 +3340,24 @@ static int __init clk_debug_init(void) |
5395 |
+ { |
5396 |
+ struct clk_core *core; |
5397 |
+ |
5398 |
++#ifdef CLOCK_ALLOW_WRITE_DEBUGFS |
5399 |
++ pr_warn("\n"); |
5400 |
++ pr_warn("********************************************************************\n"); |
5401 |
++ pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n"); |
5402 |
++ pr_warn("** **\n"); |
5403 |
++ pr_warn("** WRITEABLE clk DebugFS SUPPORT HAS BEEN ENABLED IN THIS KERNEL **\n"); |
5404 |
++ pr_warn("** **\n"); |
5405 |
++ pr_warn("** This means that this kernel is built to expose clk operations **\n"); |
5406 |
++ pr_warn("** such as parent or rate setting, enabling, disabling, etc. **\n"); |
5407 |
++ pr_warn("** to userspace, which may compromise security on your system. **\n"); |
5408 |
++ pr_warn("** **\n"); |
5409 |
++ pr_warn("** If you see this message and you are not debugging the **\n"); |
5410 |
++ pr_warn("** kernel, report this immediately to your vendor! **\n"); |
5411 |
++ pr_warn("** **\n"); |
5412 |
++ pr_warn("** NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE NOTICE **\n"); |
5413 |
++ pr_warn("********************************************************************\n"); |
5414 |
++#endif |
5415 |
++ |
5416 |
+ rootdir = debugfs_create_dir("clk", NULL); |
5417 |
+ |
5418 |
+ debugfs_create_file("clk_summary", 0444, rootdir, &all_lists, |
5419 |
+diff --git a/drivers/clk/imx/clk-imx8mn.c b/drivers/clk/imx/clk-imx8mn.c |
5420 |
+index c55577604e16a..021355a247081 100644 |
5421 |
+--- a/drivers/clk/imx/clk-imx8mn.c |
5422 |
++++ b/drivers/clk/imx/clk-imx8mn.c |
5423 |
+@@ -277,9 +277,9 @@ static const char * const imx8mn_pdm_sels[] = {"osc_24m", "sys_pll2_100m", "audi |
5424 |
+ |
5425 |
+ static const char * const imx8mn_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; |
5426 |
+ |
5427 |
+-static const char * const imx8mn_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "osc_27m", |
5428 |
+- "sys_pll1_200m", "audio_pll2_out", "vpu_pll", |
5429 |
+- "sys_pll1_80m", }; |
5430 |
++static const char * const imx8mn_clko1_sels[] = {"osc_24m", "sys_pll1_800m", "dummy", |
5431 |
++ "sys_pll1_200m", "audio_pll2_out", "sys_pll2_500m", |
5432 |
++ "dummy", "sys_pll1_80m", }; |
5433 |
+ static const char * const imx8mn_clko2_sels[] = {"osc_24m", "sys_pll2_200m", "sys_pll1_400m", |
5434 |
+ "sys_pll2_166m", "sys_pll3_out", "audio_pll1_out", |
5435 |
+ "video_pll1_out", "osc_32k", }; |
5436 |
+diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c |
5437 |
+index d6eed760327d0..608e0e8ca49a8 100644 |
5438 |
+--- a/drivers/clk/meson/gxbb.c |
5439 |
++++ b/drivers/clk/meson/gxbb.c |
5440 |
+@@ -713,6 +713,35 @@ static struct clk_regmap gxbb_mpll_prediv = { |
5441 |
+ }; |
5442 |
+ |
5443 |
+ static struct clk_regmap gxbb_mpll0_div = { |
5444 |
++ .data = &(struct meson_clk_mpll_data){ |
5445 |
++ .sdm = { |
5446 |
++ .reg_off = HHI_MPLL_CNTL7, |
5447 |
++ .shift = 0, |
5448 |
++ .width = 14, |
5449 |
++ }, |
5450 |
++ .sdm_en = { |
5451 |
++ .reg_off = HHI_MPLL_CNTL, |
5452 |
++ .shift = 25, |
5453 |
++ .width = 1, |
5454 |
++ }, |
5455 |
++ .n2 = { |
5456 |
++ .reg_off = HHI_MPLL_CNTL7, |
5457 |
++ .shift = 16, |
5458 |
++ .width = 9, |
5459 |
++ }, |
5460 |
++ .lock = &meson_clk_lock, |
5461 |
++ }, |
5462 |
++ .hw.init = &(struct clk_init_data){ |
5463 |
++ .name = "mpll0_div", |
5464 |
++ .ops = &meson_clk_mpll_ops, |
5465 |
++ .parent_hws = (const struct clk_hw *[]) { |
5466 |
++ &gxbb_mpll_prediv.hw |
5467 |
++ }, |
5468 |
++ .num_parents = 1, |
5469 |
++ }, |
5470 |
++}; |
5471 |
++ |
5472 |
++static struct clk_regmap gxl_mpll0_div = { |
5473 |
+ .data = &(struct meson_clk_mpll_data){ |
5474 |
+ .sdm = { |
5475 |
+ .reg_off = HHI_MPLL_CNTL7, |
5476 |
+@@ -749,7 +778,16 @@ static struct clk_regmap gxbb_mpll0 = { |
5477 |
+ .hw.init = &(struct clk_init_data){ |
5478 |
+ .name = "mpll0", |
5479 |
+ .ops = &clk_regmap_gate_ops, |
5480 |
+- .parent_hws = (const struct clk_hw *[]) { &gxbb_mpll0_div.hw }, |
5481 |
++ .parent_data = &(const struct clk_parent_data) { |
5482 |
++ /* |
5483 |
++ * Note: |
5484 |
++ * GXL and GXBB have different SDM_EN registers. We |
5485 |
++ * fallback to the global naming string mechanism so |
5486 |
++ * mpll0_div picks up the appropriate one. |
5487 |
++ */ |
5488 |
++ .name = "mpll0_div", |
5489 |
++ .index = -1, |
5490 |
++ }, |
5491 |
+ .num_parents = 1, |
5492 |
+ .flags = CLK_SET_RATE_PARENT, |
5493 |
+ }, |
5494 |
+@@ -3044,7 +3082,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { |
5495 |
+ [CLKID_VAPB_1] = &gxbb_vapb_1.hw, |
5496 |
+ [CLKID_VAPB_SEL] = &gxbb_vapb_sel.hw, |
5497 |
+ [CLKID_VAPB] = &gxbb_vapb.hw, |
5498 |
+- [CLKID_MPLL0_DIV] = &gxbb_mpll0_div.hw, |
5499 |
++ [CLKID_MPLL0_DIV] = &gxl_mpll0_div.hw, |
5500 |
+ [CLKID_MPLL1_DIV] = &gxbb_mpll1_div.hw, |
5501 |
+ [CLKID_MPLL2_DIV] = &gxbb_mpll2_div.hw, |
5502 |
+ [CLKID_MPLL_PREDIV] = &gxbb_mpll_prediv.hw, |
5503 |
+@@ -3439,7 +3477,7 @@ static struct clk_regmap *const gxl_clk_regmaps[] = { |
5504 |
+ &gxbb_mpll0, |
5505 |
+ &gxbb_mpll1, |
5506 |
+ &gxbb_mpll2, |
5507 |
+- &gxbb_mpll0_div, |
5508 |
++ &gxl_mpll0_div, |
5509 |
+ &gxbb_mpll1_div, |
5510 |
+ &gxbb_mpll2_div, |
5511 |
+ &gxbb_cts_amclk_div, |
5512 |
+diff --git a/drivers/clk/qcom/gcc-sc7280.c b/drivers/clk/qcom/gcc-sc7280.c |
5513 |
+index 6cefcdc869905..ce7c5ba2b9b7a 100644 |
5514 |
+--- a/drivers/clk/qcom/gcc-sc7280.c |
5515 |
++++ b/drivers/clk/qcom/gcc-sc7280.c |
5516 |
+@@ -2998,7 +2998,7 @@ static struct clk_branch gcc_cfg_noc_lpass_clk = { |
5517 |
+ .enable_mask = BIT(0), |
5518 |
+ .hw.init = &(struct clk_init_data){ |
5519 |
+ .name = "gcc_cfg_noc_lpass_clk", |
5520 |
+- .ops = &clk_branch2_ops, |
5521 |
++ .ops = &clk_branch2_aon_ops, |
5522 |
+ }, |
5523 |
+ }, |
5524 |
+ }; |
5525 |
+diff --git a/drivers/clk/renesas/rzg2l-cpg.c b/drivers/clk/renesas/rzg2l-cpg.c |
5526 |
+index 761922ea5db76..1c92e73cd2b8c 100644 |
5527 |
+--- a/drivers/clk/renesas/rzg2l-cpg.c |
5528 |
++++ b/drivers/clk/renesas/rzg2l-cpg.c |
5529 |
+@@ -638,10 +638,16 @@ static void rzg2l_cpg_detach_dev(struct generic_pm_domain *unused, struct device |
5530 |
+ pm_clk_destroy(dev); |
5531 |
+ } |
5532 |
+ |
5533 |
++static void rzg2l_cpg_genpd_remove(void *data) |
5534 |
++{ |
5535 |
++ pm_genpd_remove(data); |
5536 |
++} |
5537 |
++ |
5538 |
+ static int __init rzg2l_cpg_add_clk_domain(struct device *dev) |
5539 |
+ { |
5540 |
+ struct device_node *np = dev->of_node; |
5541 |
+ struct generic_pm_domain *genpd; |
5542 |
++ int ret; |
5543 |
+ |
5544 |
+ genpd = devm_kzalloc(dev, sizeof(*genpd), GFP_KERNEL); |
5545 |
+ if (!genpd) |
5546 |
+@@ -652,10 +658,15 @@ static int __init rzg2l_cpg_add_clk_domain(struct device *dev) |
5547 |
+ GENPD_FLAG_ACTIVE_WAKEUP; |
5548 |
+ genpd->attach_dev = rzg2l_cpg_attach_dev; |
5549 |
+ genpd->detach_dev = rzg2l_cpg_detach_dev; |
5550 |
+- pm_genpd_init(genpd, &pm_domain_always_on_gov, false); |
5551 |
++ ret = pm_genpd_init(genpd, &pm_domain_always_on_gov, false); |
5552 |
++ if (ret) |
5553 |
++ return ret; |
5554 |
+ |
5555 |
+- of_genpd_add_provider_simple(np, genpd); |
5556 |
+- return 0; |
5557 |
++ ret = devm_add_action_or_reset(dev, rzg2l_cpg_genpd_remove, genpd); |
5558 |
++ if (ret) |
5559 |
++ return ret; |
5560 |
++ |
5561 |
++ return of_genpd_add_provider_simple(np, genpd); |
5562 |
+ } |
5563 |
+ |
5564 |
+ static int __init rzg2l_cpg_probe(struct platform_device *pdev) |
5565 |
+diff --git a/drivers/cpufreq/cpufreq.c b/drivers/cpufreq/cpufreq.c |
5566 |
+index fcb44352623ee..eeac6d8092298 100644 |
5567 |
+--- a/drivers/cpufreq/cpufreq.c |
5568 |
++++ b/drivers/cpufreq/cpufreq.c |
5569 |
+@@ -1402,7 +1402,7 @@ static int cpufreq_online(unsigned int cpu) |
5570 |
+ |
5571 |
+ ret = freq_qos_add_request(&policy->constraints, |
5572 |
+ policy->min_freq_req, FREQ_QOS_MIN, |
5573 |
+- policy->min); |
5574 |
++ FREQ_QOS_MIN_DEFAULT_VALUE); |
5575 |
+ if (ret < 0) { |
5576 |
+ /* |
5577 |
+ * So we don't call freq_qos_remove_request() for an |
5578 |
+@@ -1422,7 +1422,7 @@ static int cpufreq_online(unsigned int cpu) |
5579 |
+ |
5580 |
+ ret = freq_qos_add_request(&policy->constraints, |
5581 |
+ policy->max_freq_req, FREQ_QOS_MAX, |
5582 |
+- policy->max); |
5583 |
++ FREQ_QOS_MAX_DEFAULT_VALUE); |
5584 |
+ if (ret < 0) { |
5585 |
+ policy->max_freq_req = NULL; |
5586 |
+ goto out_destroy_policy; |
5587 |
+diff --git a/drivers/cpufreq/qcom-cpufreq-hw.c b/drivers/cpufreq/qcom-cpufreq-hw.c |
5588 |
+index a2be0df7e1747..35d93361fda1a 100644 |
5589 |
+--- a/drivers/cpufreq/qcom-cpufreq-hw.c |
5590 |
++++ b/drivers/cpufreq/qcom-cpufreq-hw.c |
5591 |
+@@ -304,7 +304,8 @@ static void qcom_lmh_dcvs_notify(struct qcom_cpufreq_data *data) |
5592 |
+ if (capacity > max_capacity) |
5593 |
+ capacity = max_capacity; |
5594 |
+ |
5595 |
+- arch_set_thermal_pressure(policy->cpus, max_capacity - capacity); |
5596 |
++ arch_set_thermal_pressure(policy->related_cpus, |
5597 |
++ max_capacity - capacity); |
5598 |
+ |
5599 |
+ /* |
5600 |
+ * In the unlikely case policy is unregistered do not enable |
5601 |
+@@ -342,9 +343,9 @@ static irqreturn_t qcom_lmh_dcvs_handle_irq(int irq, void *data) |
5602 |
+ |
5603 |
+ /* Disable interrupt and enable polling */ |
5604 |
+ disable_irq_nosync(c_data->throttle_irq); |
5605 |
+- qcom_lmh_dcvs_notify(c_data); |
5606 |
++ schedule_delayed_work(&c_data->throttle_work, 0); |
5607 |
+ |
5608 |
+- return 0; |
5609 |
++ return IRQ_HANDLED; |
5610 |
+ } |
5611 |
+ |
5612 |
+ static const struct qcom_cpufreq_soc_data qcom_soc_data = { |
5613 |
+diff --git a/drivers/crypto/atmel-aes.c b/drivers/crypto/atmel-aes.c |
5614 |
+index 9391ccc03382d..fe05584031914 100644 |
5615 |
+--- a/drivers/crypto/atmel-aes.c |
5616 |
++++ b/drivers/crypto/atmel-aes.c |
5617 |
+@@ -960,6 +960,7 @@ static int atmel_aes_handle_queue(struct atmel_aes_dev *dd, |
5618 |
+ ctx = crypto_tfm_ctx(areq->tfm); |
5619 |
+ |
5620 |
+ dd->areq = areq; |
5621 |
++ dd->ctx = ctx; |
5622 |
+ start_async = (areq != new_areq); |
5623 |
+ dd->is_async = start_async; |
5624 |
+ |
5625 |
+@@ -1274,7 +1275,6 @@ static int atmel_aes_init_tfm(struct crypto_skcipher *tfm) |
5626 |
+ |
5627 |
+ crypto_skcipher_set_reqsize(tfm, sizeof(struct atmel_aes_reqctx)); |
5628 |
+ ctx->base.dd = dd; |
5629 |
+- ctx->base.dd->ctx = &ctx->base; |
5630 |
+ ctx->base.start = atmel_aes_start; |
5631 |
+ |
5632 |
+ return 0; |
5633 |
+@@ -1291,7 +1291,6 @@ static int atmel_aes_ctr_init_tfm(struct crypto_skcipher *tfm) |
5634 |
+ |
5635 |
+ crypto_skcipher_set_reqsize(tfm, sizeof(struct atmel_aes_reqctx)); |
5636 |
+ ctx->base.dd = dd; |
5637 |
+- ctx->base.dd->ctx = &ctx->base; |
5638 |
+ ctx->base.start = atmel_aes_ctr_start; |
5639 |
+ |
5640 |
+ return 0; |
5641 |
+@@ -1783,7 +1782,6 @@ static int atmel_aes_gcm_init(struct crypto_aead *tfm) |
5642 |
+ |
5643 |
+ crypto_aead_set_reqsize(tfm, sizeof(struct atmel_aes_reqctx)); |
5644 |
+ ctx->base.dd = dd; |
5645 |
+- ctx->base.dd->ctx = &ctx->base; |
5646 |
+ ctx->base.start = atmel_aes_gcm_start; |
5647 |
+ |
5648 |
+ return 0; |
5649 |
+@@ -1927,7 +1925,6 @@ static int atmel_aes_xts_init_tfm(struct crypto_skcipher *tfm) |
5650 |
+ crypto_skcipher_set_reqsize(tfm, sizeof(struct atmel_aes_reqctx) + |
5651 |
+ crypto_skcipher_reqsize(ctx->fallback_tfm)); |
5652 |
+ ctx->base.dd = dd; |
5653 |
+- ctx->base.dd->ctx = &ctx->base; |
5654 |
+ ctx->base.start = atmel_aes_xts_start; |
5655 |
+ |
5656 |
+ return 0; |
5657 |
+@@ -2154,7 +2151,6 @@ static int atmel_aes_authenc_init_tfm(struct crypto_aead *tfm, |
5658 |
+ crypto_aead_set_reqsize(tfm, (sizeof(struct atmel_aes_authenc_reqctx) + |
5659 |
+ auth_reqsize)); |
5660 |
+ ctx->base.dd = dd; |
5661 |
+- ctx->base.dd->ctx = &ctx->base; |
5662 |
+ ctx->base.start = atmel_aes_authenc_start; |
5663 |
+ |
5664 |
+ return 0; |
5665 |
+diff --git a/drivers/crypto/caam/caamalg.c b/drivers/crypto/caam/caamalg.c |
5666 |
+index 8697ae53b0633..d3d8bb0a69900 100644 |
5667 |
+--- a/drivers/crypto/caam/caamalg.c |
5668 |
++++ b/drivers/crypto/caam/caamalg.c |
5669 |
+@@ -1533,6 +1533,9 @@ static int aead_do_one_req(struct crypto_engine *engine, void *areq) |
5670 |
+ |
5671 |
+ ret = caam_jr_enqueue(ctx->jrdev, desc, aead_crypt_done, req); |
5672 |
+ |
5673 |
++ if (ret == -ENOSPC && engine->retry_support) |
5674 |
++ return ret; |
5675 |
++ |
5676 |
+ if (ret != -EINPROGRESS) { |
5677 |
+ aead_unmap(ctx->jrdev, rctx->edesc, req); |
5678 |
+ kfree(rctx->edesc); |
5679 |
+@@ -1762,6 +1765,9 @@ static int skcipher_do_one_req(struct crypto_engine *engine, void *areq) |
5680 |
+ |
5681 |
+ ret = caam_jr_enqueue(ctx->jrdev, desc, skcipher_crypt_done, req); |
5682 |
+ |
5683 |
++ if (ret == -ENOSPC && engine->retry_support) |
5684 |
++ return ret; |
5685 |
++ |
5686 |
+ if (ret != -EINPROGRESS) { |
5687 |
+ skcipher_unmap(ctx->jrdev, rctx->edesc, req); |
5688 |
+ kfree(rctx->edesc); |
5689 |
+diff --git a/drivers/crypto/caam/caamalg_qi2.c b/drivers/crypto/caam/caamalg_qi2.c |
5690 |
+index 8b8ed77d8715d..6753f0e6e55d1 100644 |
5691 |
+--- a/drivers/crypto/caam/caamalg_qi2.c |
5692 |
++++ b/drivers/crypto/caam/caamalg_qi2.c |
5693 |
+@@ -5470,7 +5470,7 @@ int dpaa2_caam_enqueue(struct device *dev, struct caam_request *req) |
5694 |
+ dpaa2_fd_set_len(&fd, dpaa2_fl_get_len(&req->fd_flt[1])); |
5695 |
+ dpaa2_fd_set_flc(&fd, req->flc_dma); |
5696 |
+ |
5697 |
+- ppriv = this_cpu_ptr(priv->ppriv); |
5698 |
++ ppriv = raw_cpu_ptr(priv->ppriv); |
5699 |
+ for (i = 0; i < (priv->dpseci_attr.num_tx_queues << 1); i++) { |
5700 |
+ err = dpaa2_io_service_enqueue_fq(ppriv->dpio, ppriv->req_fqid, |
5701 |
+ &fd); |
5702 |
+diff --git a/drivers/crypto/caam/caamhash.c b/drivers/crypto/caam/caamhash.c |
5703 |
+index e8a6d8bc43b5d..36ef738e4a181 100644 |
5704 |
+--- a/drivers/crypto/caam/caamhash.c |
5705 |
++++ b/drivers/crypto/caam/caamhash.c |
5706 |
+@@ -765,6 +765,9 @@ static int ahash_do_one_req(struct crypto_engine *engine, void *areq) |
5707 |
+ |
5708 |
+ ret = caam_jr_enqueue(jrdev, desc, state->ahash_op_done, req); |
5709 |
+ |
5710 |
++ if (ret == -ENOSPC && engine->retry_support) |
5711 |
++ return ret; |
5712 |
++ |
5713 |
+ if (ret != -EINPROGRESS) { |
5714 |
+ ahash_unmap(jrdev, state->edesc, req, 0); |
5715 |
+ kfree(state->edesc); |
5716 |
+diff --git a/drivers/crypto/caam/caampkc.c b/drivers/crypto/caam/caampkc.c |
5717 |
+index bf6275ffc4aad..8867275767101 100644 |
5718 |
+--- a/drivers/crypto/caam/caampkc.c |
5719 |
++++ b/drivers/crypto/caam/caampkc.c |
5720 |
+@@ -380,6 +380,9 @@ static int akcipher_do_one_req(struct crypto_engine *engine, void *areq) |
5721 |
+ |
5722 |
+ ret = caam_jr_enqueue(jrdev, desc, req_ctx->akcipher_op_done, req); |
5723 |
+ |
5724 |
++ if (ret == -ENOSPC && engine->retry_support) |
5725 |
++ return ret; |
5726 |
++ |
5727 |
+ if (ret != -EINPROGRESS) { |
5728 |
+ rsa_pub_unmap(jrdev, req_ctx->edesc, req); |
5729 |
+ rsa_io_unmap(jrdev, req_ctx->edesc, req); |
5730 |
+diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c |
5731 |
+index 2ecb0e1f65d8d..e2806ca3300a8 100644 |
5732 |
+--- a/drivers/crypto/ccp/sev-dev.c |
5733 |
++++ b/drivers/crypto/ccp/sev-dev.c |
5734 |
+@@ -241,7 +241,7 @@ static int __sev_platform_init_locked(int *error) |
5735 |
+ struct psp_device *psp = psp_master; |
5736 |
+ struct sev_data_init data; |
5737 |
+ struct sev_device *sev; |
5738 |
+- int rc = 0; |
5739 |
++ int psp_ret, rc = 0; |
5740 |
+ |
5741 |
+ if (!psp || !psp->sev_data) |
5742 |
+ return -ENODEV; |
5743 |
+@@ -266,7 +266,21 @@ static int __sev_platform_init_locked(int *error) |
5744 |
+ data.tmr_len = SEV_ES_TMR_SIZE; |
5745 |
+ } |
5746 |
+ |
5747 |
+- rc = __sev_do_cmd_locked(SEV_CMD_INIT, &data, error); |
5748 |
++ rc = __sev_do_cmd_locked(SEV_CMD_INIT, &data, &psp_ret); |
5749 |
++ if (rc && psp_ret == SEV_RET_SECURE_DATA_INVALID) { |
5750 |
++ /* |
5751 |
++ * Initialization command returned an integrity check failure |
5752 |
++ * status code, meaning that firmware load and validation of SEV |
5753 |
++ * related persistent data has failed. Retrying the |
5754 |
++ * initialization function should succeed by replacing the state |
5755 |
++ * with a reset state. |
5756 |
++ */ |
5757 |
++ dev_dbg(sev->dev, "SEV: retrying INIT command"); |
5758 |
++ rc = __sev_do_cmd_locked(SEV_CMD_INIT, &data, &psp_ret); |
5759 |
++ } |
5760 |
++ if (error) |
5761 |
++ *error = psp_ret; |
5762 |
++ |
5763 |
+ if (rc) |
5764 |
+ return rc; |
5765 |
+ |
5766 |
+@@ -1091,18 +1105,6 @@ void sev_pci_init(void) |
5767 |
+ |
5768 |
+ /* Initialize the platform */ |
5769 |
+ rc = sev_platform_init(&error); |
5770 |
+- if (rc && (error == SEV_RET_SECURE_DATA_INVALID)) { |
5771 |
+- /* |
5772 |
+- * INIT command returned an integrity check failure |
5773 |
+- * status code, meaning that firmware load and |
5774 |
+- * validation of SEV related persistent data has |
5775 |
+- * failed and persistent state has been erased. |
5776 |
+- * Retrying INIT command here should succeed. |
5777 |
+- */ |
5778 |
+- dev_dbg(sev->dev, "SEV: retrying INIT command"); |
5779 |
+- rc = sev_platform_init(&error); |
5780 |
+- } |
5781 |
+- |
5782 |
+ if (rc) { |
5783 |
+ dev_err(sev->dev, "SEV: failed to INIT error %#x\n", error); |
5784 |
+ return; |
5785 |
+diff --git a/drivers/crypto/hisilicon/hpre/hpre_crypto.c b/drivers/crypto/hisilicon/hpre/hpre_crypto.c |
5786 |
+index a032c192ef1d6..7ba7641723a0b 100644 |
5787 |
+--- a/drivers/crypto/hisilicon/hpre/hpre_crypto.c |
5788 |
++++ b/drivers/crypto/hisilicon/hpre/hpre_crypto.c |
5789 |
+@@ -1865,7 +1865,7 @@ static int hpre_curve25519_src_init(struct hpre_asym_request *hpre_req, |
5790 |
+ */ |
5791 |
+ if (memcmp(ptr, p, ctx->key_sz) == 0) { |
5792 |
+ dev_err(dev, "gx is p!\n"); |
5793 |
+- return -EINVAL; |
5794 |
++ goto err; |
5795 |
+ } else if (memcmp(ptr, p, ctx->key_sz) > 0) { |
5796 |
+ hpre_curve25519_src_modulo_p(ptr); |
5797 |
+ } |
5798 |
+diff --git a/drivers/crypto/hisilicon/qm.c b/drivers/crypto/hisilicon/qm.c |
5799 |
+index 369562d34d66a..ff1122153fbec 100644 |
5800 |
+--- a/drivers/crypto/hisilicon/qm.c |
5801 |
++++ b/drivers/crypto/hisilicon/qm.c |
5802 |
+@@ -5986,7 +5986,7 @@ int hisi_qm_resume(struct device *dev) |
5803 |
+ if (ret) |
5804 |
+ pci_err(pdev, "failed to start qm(%d)\n", ret); |
5805 |
+ |
5806 |
+- return 0; |
5807 |
++ return ret; |
5808 |
+ } |
5809 |
+ EXPORT_SYMBOL_GPL(hisi_qm_resume); |
5810 |
+ |
5811 |
+diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c |
5812 |
+index 146a55ac4b9b0..be1ad55a208f6 100644 |
5813 |
+--- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c |
5814 |
++++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_main.c |
5815 |
+@@ -494,12 +494,11 @@ static ssize_t kvf_limits_store(struct device *dev, |
5816 |
+ { |
5817 |
+ struct otx2_cptpf_dev *cptpf = dev_get_drvdata(dev); |
5818 |
+ int lfs_num; |
5819 |
++ int ret; |
5820 |
+ |
5821 |
+- if (kstrtoint(buf, 0, &lfs_num)) { |
5822 |
+- dev_err(dev, "lfs count %d must be in range [1 - %d]\n", |
5823 |
+- lfs_num, num_online_cpus()); |
5824 |
+- return -EINVAL; |
5825 |
+- } |
5826 |
++ ret = kstrtoint(buf, 0, &lfs_num); |
5827 |
++ if (ret) |
5828 |
++ return ret; |
5829 |
+ if (lfs_num < 1 || lfs_num > num_online_cpus()) { |
5830 |
+ dev_err(dev, "lfs count %d must be in range [1 - %d]\n", |
5831 |
+ lfs_num, num_online_cpus()); |
5832 |
+diff --git a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c |
5833 |
+index dff34b3ec09e1..7c1b92aaab398 100644 |
5834 |
+--- a/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c |
5835 |
++++ b/drivers/crypto/marvell/octeontx2/otx2_cptpf_ucode.c |
5836 |
+@@ -29,7 +29,8 @@ static struct otx2_cpt_bitmap get_cores_bmap(struct device *dev, |
5837 |
+ bool found = false; |
5838 |
+ int i; |
5839 |
+ |
5840 |
+- if (eng_grp->g->engs_num > OTX2_CPT_MAX_ENGINES) { |
5841 |
++ if (eng_grp->g->engs_num < 0 || |
5842 |
++ eng_grp->g->engs_num > OTX2_CPT_MAX_ENGINES) { |
5843 |
+ dev_err(dev, "unsupported number of engines %d on octeontx2\n", |
5844 |
+ eng_grp->g->engs_num); |
5845 |
+ return bmap; |
5846 |
+diff --git a/drivers/crypto/omap-aes.c b/drivers/crypto/omap-aes.c |
5847 |
+index 9b968ac4ee7b6..a196bb8b17010 100644 |
5848 |
+--- a/drivers/crypto/omap-aes.c |
5849 |
++++ b/drivers/crypto/omap-aes.c |
5850 |
+@@ -1302,7 +1302,7 @@ static int omap_aes_suspend(struct device *dev) |
5851 |
+ |
5852 |
+ static int omap_aes_resume(struct device *dev) |
5853 |
+ { |
5854 |
+- pm_runtime_resume_and_get(dev); |
5855 |
++ pm_runtime_get_sync(dev); |
5856 |
+ return 0; |
5857 |
+ } |
5858 |
+ #endif |
5859 |
+diff --git a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c |
5860 |
+index 5a41beb8f20f6..7ec81989beb03 100644 |
5861 |
+--- a/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c |
5862 |
++++ b/drivers/crypto/qat/qat_common/adf_pf2vf_msg.c |
5863 |
+@@ -117,37 +117,19 @@ static int __adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr) |
5864 |
+ |
5865 |
+ mutex_lock(lock); |
5866 |
+ |
5867 |
+- /* Check if PF2VF CSR is in use by remote function */ |
5868 |
++ /* Check if the PFVF CSR is in use by remote function */ |
5869 |
+ val = ADF_CSR_RD(pmisc_bar_addr, pf2vf_offset); |
5870 |
+ if ((val & remote_in_use_mask) == remote_in_use_pattern) { |
5871 |
+ dev_dbg(&GET_DEV(accel_dev), |
5872 |
+- "PF2VF CSR in use by remote function\n"); |
5873 |
++ "PFVF CSR in use by remote function\n"); |
5874 |
+ ret = -EBUSY; |
5875 |
+ goto out; |
5876 |
+ } |
5877 |
+ |
5878 |
+- /* Attempt to get ownership of PF2VF CSR */ |
5879 |
+ msg &= ~local_in_use_mask; |
5880 |
+ msg |= local_in_use_pattern; |
5881 |
+- ADF_CSR_WR(pmisc_bar_addr, pf2vf_offset, msg); |
5882 |
+ |
5883 |
+- /* Wait in case remote func also attempting to get ownership */ |
5884 |
+- msleep(ADF_IOV_MSG_COLLISION_DETECT_DELAY); |
5885 |
+- |
5886 |
+- val = ADF_CSR_RD(pmisc_bar_addr, pf2vf_offset); |
5887 |
+- if ((val & local_in_use_mask) != local_in_use_pattern) { |
5888 |
+- dev_dbg(&GET_DEV(accel_dev), |
5889 |
+- "PF2VF CSR in use by remote - collision detected\n"); |
5890 |
+- ret = -EBUSY; |
5891 |
+- goto out; |
5892 |
+- } |
5893 |
+- |
5894 |
+- /* |
5895 |
+- * This function now owns the PV2VF CSR. The IN_USE_BY pattern must |
5896 |
+- * remain in the PF2VF CSR for all writes including ACK from remote |
5897 |
+- * until this local function relinquishes the CSR. Send the message |
5898 |
+- * by interrupting the remote. |
5899 |
+- */ |
5900 |
++ /* Attempt to get ownership of the PFVF CSR */ |
5901 |
+ ADF_CSR_WR(pmisc_bar_addr, pf2vf_offset, msg | int_bit); |
5902 |
+ |
5903 |
+ /* Wait for confirmation from remote func it received the message */ |
5904 |
+@@ -156,6 +138,12 @@ static int __adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr) |
5905 |
+ val = ADF_CSR_RD(pmisc_bar_addr, pf2vf_offset); |
5906 |
+ } while ((val & int_bit) && (count++ < ADF_IOV_MSG_ACK_MAX_RETRY)); |
5907 |
+ |
5908 |
++ if (val & int_bit) { |
5909 |
++ dev_dbg(&GET_DEV(accel_dev), "ACK not received from remote\n"); |
5910 |
++ val &= ~int_bit; |
5911 |
++ ret = -EIO; |
5912 |
++ } |
5913 |
++ |
5914 |
+ if (val != msg) { |
5915 |
+ dev_dbg(&GET_DEV(accel_dev), |
5916 |
+ "Collision - PFVF CSR overwritten by remote function\n"); |
5917 |
+@@ -163,13 +151,7 @@ static int __adf_iov_putmsg(struct adf_accel_dev *accel_dev, u32 msg, u8 vf_nr) |
5918 |
+ goto out; |
5919 |
+ } |
5920 |
+ |
5921 |
+- if (val & int_bit) { |
5922 |
+- dev_dbg(&GET_DEV(accel_dev), "ACK not received from remote\n"); |
5923 |
+- val &= ~int_bit; |
5924 |
+- ret = -EIO; |
5925 |
+- } |
5926 |
+- |
5927 |
+- /* Finished with PF2VF CSR; relinquish it and leave msg in CSR */ |
5928 |
++ /* Finished with the PFVF CSR; relinquish it and leave msg in CSR */ |
5929 |
+ ADF_CSR_WR(pmisc_bar_addr, pf2vf_offset, val & ~local_in_use_mask); |
5930 |
+ out: |
5931 |
+ mutex_unlock(lock); |
5932 |
+@@ -177,12 +159,13 @@ out: |
5933 |
+ } |
5934 |
+ |
5935 |
+ /** |
5936 |
+- * adf_iov_putmsg() - send PF2VF message |
5937 |
++ * adf_iov_putmsg() - send PFVF message |
5938 |
+ * @accel_dev: Pointer to acceleration device. |
5939 |
+ * @msg: Message to send |
5940 |
+- * @vf_nr: VF number to which the message will be sent |
5941 |
++ * @vf_nr: VF number to which the message will be sent if on PF, ignored |
5942 |
++ * otherwise |
5943 |
+ * |
5944 |
+- * Function sends a message from the PF to a VF |
5945 |
++ * Function sends a message through the PFVF channel |
5946 |
+ * |
5947 |
+ * Return: 0 on success, error code otherwise. |
5948 |
+ */ |
5949 |
+diff --git a/drivers/crypto/qce/aead.c b/drivers/crypto/qce/aead.c |
5950 |
+index 290e2446a2f35..97a530171f07a 100644 |
5951 |
+--- a/drivers/crypto/qce/aead.c |
5952 |
++++ b/drivers/crypto/qce/aead.c |
5953 |
+@@ -802,8 +802,8 @@ static int qce_aead_register_one(const struct qce_aead_def *def, struct qce_devi |
5954 |
+ |
5955 |
+ ret = crypto_register_aead(alg); |
5956 |
+ if (ret) { |
5957 |
+- kfree(tmpl); |
5958 |
+ dev_err(qce->dev, "%s registration failed\n", alg->base.cra_name); |
5959 |
++ kfree(tmpl); |
5960 |
+ return ret; |
5961 |
+ } |
5962 |
+ |
5963 |
+diff --git a/drivers/crypto/qce/sha.c b/drivers/crypto/qce/sha.c |
5964 |
+index 8e6fcf2c21cc0..59159f5e64e52 100644 |
5965 |
+--- a/drivers/crypto/qce/sha.c |
5966 |
++++ b/drivers/crypto/qce/sha.c |
5967 |
+@@ -498,8 +498,8 @@ static int qce_ahash_register_one(const struct qce_ahash_def *def, |
5968 |
+ |
5969 |
+ ret = crypto_register_ahash(alg); |
5970 |
+ if (ret) { |
5971 |
+- kfree(tmpl); |
5972 |
+ dev_err(qce->dev, "%s registration failed\n", base->cra_name); |
5973 |
++ kfree(tmpl); |
5974 |
+ return ret; |
5975 |
+ } |
5976 |
+ |
5977 |
+diff --git a/drivers/crypto/qce/skcipher.c b/drivers/crypto/qce/skcipher.c |
5978 |
+index 8ff10928f581d..3d27cd5210ef5 100644 |
5979 |
+--- a/drivers/crypto/qce/skcipher.c |
5980 |
++++ b/drivers/crypto/qce/skcipher.c |
5981 |
+@@ -484,8 +484,8 @@ static int qce_skcipher_register_one(const struct qce_skcipher_def *def, |
5982 |
+ |
5983 |
+ ret = crypto_register_skcipher(alg); |
5984 |
+ if (ret) { |
5985 |
+- kfree(tmpl); |
5986 |
+ dev_err(qce->dev, "%s registration failed\n", alg->base.cra_name); |
5987 |
++ kfree(tmpl); |
5988 |
+ return ret; |
5989 |
+ } |
5990 |
+ |
5991 |
+diff --git a/drivers/crypto/stm32/stm32-crc32.c b/drivers/crypto/stm32/stm32-crc32.c |
5992 |
+index 75867c0b00172..be1bf39a317de 100644 |
5993 |
+--- a/drivers/crypto/stm32/stm32-crc32.c |
5994 |
++++ b/drivers/crypto/stm32/stm32-crc32.c |
5995 |
+@@ -279,7 +279,7 @@ static struct shash_alg algs[] = { |
5996 |
+ .digestsize = CHKSUM_DIGEST_SIZE, |
5997 |
+ .base = { |
5998 |
+ .cra_name = "crc32", |
5999 |
+- .cra_driver_name = DRIVER_NAME, |
6000 |
++ .cra_driver_name = "stm32-crc32-crc32", |
6001 |
+ .cra_priority = 200, |
6002 |
+ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, |
6003 |
+ .cra_blocksize = CHKSUM_BLOCK_SIZE, |
6004 |
+@@ -301,7 +301,7 @@ static struct shash_alg algs[] = { |
6005 |
+ .digestsize = CHKSUM_DIGEST_SIZE, |
6006 |
+ .base = { |
6007 |
+ .cra_name = "crc32c", |
6008 |
+- .cra_driver_name = DRIVER_NAME, |
6009 |
++ .cra_driver_name = "stm32-crc32-crc32c", |
6010 |
+ .cra_priority = 200, |
6011 |
+ .cra_flags = CRYPTO_ALG_OPTIONAL_KEY, |
6012 |
+ .cra_blocksize = CHKSUM_BLOCK_SIZE, |
6013 |
+diff --git a/drivers/crypto/stm32/stm32-cryp.c b/drivers/crypto/stm32/stm32-cryp.c |
6014 |
+index 7389a0536ff02..81eb136b6c11d 100644 |
6015 |
+--- a/drivers/crypto/stm32/stm32-cryp.c |
6016 |
++++ b/drivers/crypto/stm32/stm32-cryp.c |
6017 |
+@@ -37,7 +37,6 @@ |
6018 |
+ /* Mode mask = bits [15..0] */ |
6019 |
+ #define FLG_MODE_MASK GENMASK(15, 0) |
6020 |
+ /* Bit [31..16] status */ |
6021 |
+-#define FLG_CCM_PADDED_WA BIT(16) |
6022 |
+ |
6023 |
+ /* Registers */ |
6024 |
+ #define CRYP_CR 0x00000000 |
6025 |
+@@ -105,8 +104,6 @@ |
6026 |
+ /* Misc */ |
6027 |
+ #define AES_BLOCK_32 (AES_BLOCK_SIZE / sizeof(u32)) |
6028 |
+ #define GCM_CTR_INIT 2 |
6029 |
+-#define _walked_in (cryp->in_walk.offset - cryp->in_sg->offset) |
6030 |
+-#define _walked_out (cryp->out_walk.offset - cryp->out_sg->offset) |
6031 |
+ #define CRYP_AUTOSUSPEND_DELAY 50 |
6032 |
+ |
6033 |
+ struct stm32_cryp_caps { |
6034 |
+@@ -144,26 +141,16 @@ struct stm32_cryp { |
6035 |
+ size_t authsize; |
6036 |
+ size_t hw_blocksize; |
6037 |
+ |
6038 |
+- size_t total_in; |
6039 |
+- size_t total_in_save; |
6040 |
+- size_t total_out; |
6041 |
+- size_t total_out_save; |
6042 |
++ size_t payload_in; |
6043 |
++ size_t header_in; |
6044 |
++ size_t payload_out; |
6045 |
+ |
6046 |
+- struct scatterlist *in_sg; |
6047 |
+ struct scatterlist *out_sg; |
6048 |
+- struct scatterlist *out_sg_save; |
6049 |
+- |
6050 |
+- struct scatterlist in_sgl; |
6051 |
+- struct scatterlist out_sgl; |
6052 |
+- bool sgs_copied; |
6053 |
+- |
6054 |
+- int in_sg_len; |
6055 |
+- int out_sg_len; |
6056 |
+ |
6057 |
+ struct scatter_walk in_walk; |
6058 |
+ struct scatter_walk out_walk; |
6059 |
+ |
6060 |
+- u32 last_ctr[4]; |
6061 |
++ __be32 last_ctr[4]; |
6062 |
+ u32 gcm_ctr; |
6063 |
+ }; |
6064 |
+ |
6065 |
+@@ -262,6 +249,7 @@ static inline int stm32_cryp_wait_output(struct stm32_cryp *cryp) |
6066 |
+ } |
6067 |
+ |
6068 |
+ static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp); |
6069 |
++static void stm32_cryp_finish_req(struct stm32_cryp *cryp, int err); |
6070 |
+ |
6071 |
+ static struct stm32_cryp *stm32_cryp_find_dev(struct stm32_cryp_ctx *ctx) |
6072 |
+ { |
6073 |
+@@ -283,103 +271,6 @@ static struct stm32_cryp *stm32_cryp_find_dev(struct stm32_cryp_ctx *ctx) |
6074 |
+ return cryp; |
6075 |
+ } |
6076 |
+ |
6077 |
+-static int stm32_cryp_check_aligned(struct scatterlist *sg, size_t total, |
6078 |
+- size_t align) |
6079 |
+-{ |
6080 |
+- int len = 0; |
6081 |
+- |
6082 |
+- if (!total) |
6083 |
+- return 0; |
6084 |
+- |
6085 |
+- if (!IS_ALIGNED(total, align)) |
6086 |
+- return -EINVAL; |
6087 |
+- |
6088 |
+- while (sg) { |
6089 |
+- if (!IS_ALIGNED(sg->offset, sizeof(u32))) |
6090 |
+- return -EINVAL; |
6091 |
+- |
6092 |
+- if (!IS_ALIGNED(sg->length, align)) |
6093 |
+- return -EINVAL; |
6094 |
+- |
6095 |
+- len += sg->length; |
6096 |
+- sg = sg_next(sg); |
6097 |
+- } |
6098 |
+- |
6099 |
+- if (len != total) |
6100 |
+- return -EINVAL; |
6101 |
+- |
6102 |
+- return 0; |
6103 |
+-} |
6104 |
+- |
6105 |
+-static int stm32_cryp_check_io_aligned(struct stm32_cryp *cryp) |
6106 |
+-{ |
6107 |
+- int ret; |
6108 |
+- |
6109 |
+- ret = stm32_cryp_check_aligned(cryp->in_sg, cryp->total_in, |
6110 |
+- cryp->hw_blocksize); |
6111 |
+- if (ret) |
6112 |
+- return ret; |
6113 |
+- |
6114 |
+- ret = stm32_cryp_check_aligned(cryp->out_sg, cryp->total_out, |
6115 |
+- cryp->hw_blocksize); |
6116 |
+- |
6117 |
+- return ret; |
6118 |
+-} |
6119 |
+- |
6120 |
+-static void sg_copy_buf(void *buf, struct scatterlist *sg, |
6121 |
+- unsigned int start, unsigned int nbytes, int out) |
6122 |
+-{ |
6123 |
+- struct scatter_walk walk; |
6124 |
+- |
6125 |
+- if (!nbytes) |
6126 |
+- return; |
6127 |
+- |
6128 |
+- scatterwalk_start(&walk, sg); |
6129 |
+- scatterwalk_advance(&walk, start); |
6130 |
+- scatterwalk_copychunks(buf, &walk, nbytes, out); |
6131 |
+- scatterwalk_done(&walk, out, 0); |
6132 |
+-} |
6133 |
+- |
6134 |
+-static int stm32_cryp_copy_sgs(struct stm32_cryp *cryp) |
6135 |
+-{ |
6136 |
+- void *buf_in, *buf_out; |
6137 |
+- int pages, total_in, total_out; |
6138 |
+- |
6139 |
+- if (!stm32_cryp_check_io_aligned(cryp)) { |
6140 |
+- cryp->sgs_copied = 0; |
6141 |
+- return 0; |
6142 |
+- } |
6143 |
+- |
6144 |
+- total_in = ALIGN(cryp->total_in, cryp->hw_blocksize); |
6145 |
+- pages = total_in ? get_order(total_in) : 1; |
6146 |
+- buf_in = (void *)__get_free_pages(GFP_ATOMIC, pages); |
6147 |
+- |
6148 |
+- total_out = ALIGN(cryp->total_out, cryp->hw_blocksize); |
6149 |
+- pages = total_out ? get_order(total_out) : 1; |
6150 |
+- buf_out = (void *)__get_free_pages(GFP_ATOMIC, pages); |
6151 |
+- |
6152 |
+- if (!buf_in || !buf_out) { |
6153 |
+- dev_err(cryp->dev, "Can't allocate pages when unaligned\n"); |
6154 |
+- cryp->sgs_copied = 0; |
6155 |
+- return -EFAULT; |
6156 |
+- } |
6157 |
+- |
6158 |
+- sg_copy_buf(buf_in, cryp->in_sg, 0, cryp->total_in, 0); |
6159 |
+- |
6160 |
+- sg_init_one(&cryp->in_sgl, buf_in, total_in); |
6161 |
+- cryp->in_sg = &cryp->in_sgl; |
6162 |
+- cryp->in_sg_len = 1; |
6163 |
+- |
6164 |
+- sg_init_one(&cryp->out_sgl, buf_out, total_out); |
6165 |
+- cryp->out_sg_save = cryp->out_sg; |
6166 |
+- cryp->out_sg = &cryp->out_sgl; |
6167 |
+- cryp->out_sg_len = 1; |
6168 |
+- |
6169 |
+- cryp->sgs_copied = 1; |
6170 |
+- |
6171 |
+- return 0; |
6172 |
+-} |
6173 |
+- |
6174 |
+ static void stm32_cryp_hw_write_iv(struct stm32_cryp *cryp, __be32 *iv) |
6175 |
+ { |
6176 |
+ if (!iv) |
6177 |
+@@ -481,16 +372,99 @@ static int stm32_cryp_gcm_init(struct stm32_cryp *cryp, u32 cfg) |
6178 |
+ |
6179 |
+ /* Wait for end of processing */ |
6180 |
+ ret = stm32_cryp_wait_enable(cryp); |
6181 |
+- if (ret) |
6182 |
++ if (ret) { |
6183 |
+ dev_err(cryp->dev, "Timeout (gcm init)\n"); |
6184 |
++ return ret; |
6185 |
++ } |
6186 |
+ |
6187 |
+- return ret; |
6188 |
++ /* Prepare next phase */ |
6189 |
++ if (cryp->areq->assoclen) { |
6190 |
++ cfg |= CR_PH_HEADER; |
6191 |
++ stm32_cryp_write(cryp, CRYP_CR, cfg); |
6192 |
++ } else if (stm32_cryp_get_input_text_len(cryp)) { |
6193 |
++ cfg |= CR_PH_PAYLOAD; |
6194 |
++ stm32_cryp_write(cryp, CRYP_CR, cfg); |
6195 |
++ } |
6196 |
++ |
6197 |
++ return 0; |
6198 |
++} |
6199 |
++ |
6200 |
++static void stm32_crypt_gcmccm_end_header(struct stm32_cryp *cryp) |
6201 |
++{ |
6202 |
++ u32 cfg; |
6203 |
++ int err; |
6204 |
++ |
6205 |
++ /* Check if whole header written */ |
6206 |
++ if (!cryp->header_in) { |
6207 |
++ /* Wait for completion */ |
6208 |
++ err = stm32_cryp_wait_busy(cryp); |
6209 |
++ if (err) { |
6210 |
++ dev_err(cryp->dev, "Timeout (gcm/ccm header)\n"); |
6211 |
++ stm32_cryp_write(cryp, CRYP_IMSCR, 0); |
6212 |
++ stm32_cryp_finish_req(cryp, err); |
6213 |
++ return; |
6214 |
++ } |
6215 |
++ |
6216 |
++ if (stm32_cryp_get_input_text_len(cryp)) { |
6217 |
++ /* Phase 3 : payload */ |
6218 |
++ cfg = stm32_cryp_read(cryp, CRYP_CR); |
6219 |
++ cfg &= ~CR_CRYPEN; |
6220 |
++ stm32_cryp_write(cryp, CRYP_CR, cfg); |
6221 |
++ |
6222 |
++ cfg &= ~CR_PH_MASK; |
6223 |
++ cfg |= CR_PH_PAYLOAD | CR_CRYPEN; |
6224 |
++ stm32_cryp_write(cryp, CRYP_CR, cfg); |
6225 |
++ } else { |
6226 |
++ /* |
6227 |
++ * Phase 4 : tag. |
6228 |
++ * Nothing to read, nothing to write, caller have to |
6229 |
++ * end request |
6230 |
++ */ |
6231 |
++ } |
6232 |
++ } |
6233 |
++} |
6234 |
++ |
6235 |
++static void stm32_cryp_write_ccm_first_header(struct stm32_cryp *cryp) |
6236 |
++{ |
6237 |
++ unsigned int i; |
6238 |
++ size_t written; |
6239 |
++ size_t len; |
6240 |
++ u32 alen = cryp->areq->assoclen; |
6241 |
++ u32 block[AES_BLOCK_32] = {0}; |
6242 |
++ u8 *b8 = (u8 *)block; |
6243 |
++ |
6244 |
++ if (alen <= 65280) { |
6245 |
++ /* Write first u32 of B1 */ |
6246 |
++ b8[0] = (alen >> 8) & 0xFF; |
6247 |
++ b8[1] = alen & 0xFF; |
6248 |
++ len = 2; |
6249 |
++ } else { |
6250 |
++ /* Build the two first u32 of B1 */ |
6251 |
++ b8[0] = 0xFF; |
6252 |
++ b8[1] = 0xFE; |
6253 |
++ b8[2] = (alen & 0xFF000000) >> 24; |
6254 |
++ b8[3] = (alen & 0x00FF0000) >> 16; |
6255 |
++ b8[4] = (alen & 0x0000FF00) >> 8; |
6256 |
++ b8[5] = alen & 0x000000FF; |
6257 |
++ len = 6; |
6258 |
++ } |
6259 |
++ |
6260 |
++ written = min_t(size_t, AES_BLOCK_SIZE - len, alen); |
6261 |
++ |
6262 |
++ scatterwalk_copychunks((char *)block + len, &cryp->in_walk, written, 0); |
6263 |
++ for (i = 0; i < AES_BLOCK_32; i++) |
6264 |
++ stm32_cryp_write(cryp, CRYP_DIN, block[i]); |
6265 |
++ |
6266 |
++ cryp->header_in -= written; |
6267 |
++ |
6268 |
++ stm32_crypt_gcmccm_end_header(cryp); |
6269 |
+ } |
6270 |
+ |
6271 |
+ static int stm32_cryp_ccm_init(struct stm32_cryp *cryp, u32 cfg) |
6272 |
+ { |
6273 |
+ int ret; |
6274 |
+- u8 iv[AES_BLOCK_SIZE], b0[AES_BLOCK_SIZE]; |
6275 |
++ u32 iv_32[AES_BLOCK_32], b0_32[AES_BLOCK_32]; |
6276 |
++ u8 *iv = (u8 *)iv_32, *b0 = (u8 *)b0_32; |
6277 |
+ __be32 *bd; |
6278 |
+ u32 *d; |
6279 |
+ unsigned int i, textlen; |
6280 |
+@@ -531,10 +505,24 @@ static int stm32_cryp_ccm_init(struct stm32_cryp *cryp, u32 cfg) |
6281 |
+ |
6282 |
+ /* Wait for end of processing */ |
6283 |
+ ret = stm32_cryp_wait_enable(cryp); |
6284 |
+- if (ret) |
6285 |
++ if (ret) { |
6286 |
+ dev_err(cryp->dev, "Timeout (ccm init)\n"); |
6287 |
++ return ret; |
6288 |
++ } |
6289 |
+ |
6290 |
+- return ret; |
6291 |
++ /* Prepare next phase */ |
6292 |
++ if (cryp->areq->assoclen) { |
6293 |
++ cfg |= CR_PH_HEADER | CR_CRYPEN; |
6294 |
++ stm32_cryp_write(cryp, CRYP_CR, cfg); |
6295 |
++ |
6296 |
++ /* Write first (special) block (may move to next phase [payload]) */ |
6297 |
++ stm32_cryp_write_ccm_first_header(cryp); |
6298 |
++ } else if (stm32_cryp_get_input_text_len(cryp)) { |
6299 |
++ cfg |= CR_PH_PAYLOAD; |
6300 |
++ stm32_cryp_write(cryp, CRYP_CR, cfg); |
6301 |
++ } |
6302 |
++ |
6303 |
++ return 0; |
6304 |
+ } |
6305 |
+ |
6306 |
+ static int stm32_cryp_hw_init(struct stm32_cryp *cryp) |
6307 |
+@@ -542,7 +530,7 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp) |
6308 |
+ int ret; |
6309 |
+ u32 cfg, hw_mode; |
6310 |
+ |
6311 |
+- pm_runtime_resume_and_get(cryp->dev); |
6312 |
++ pm_runtime_get_sync(cryp->dev); |
6313 |
+ |
6314 |
+ /* Disable interrupt */ |
6315 |
+ stm32_cryp_write(cryp, CRYP_IMSCR, 0); |
6316 |
+@@ -605,16 +593,6 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp) |
6317 |
+ if (ret) |
6318 |
+ return ret; |
6319 |
+ |
6320 |
+- /* Phase 2 : header (authenticated data) */ |
6321 |
+- if (cryp->areq->assoclen) { |
6322 |
+- cfg |= CR_PH_HEADER; |
6323 |
+- } else if (stm32_cryp_get_input_text_len(cryp)) { |
6324 |
+- cfg |= CR_PH_PAYLOAD; |
6325 |
+- stm32_cryp_write(cryp, CRYP_CR, cfg); |
6326 |
+- } else { |
6327 |
+- cfg |= CR_PH_INIT; |
6328 |
+- } |
6329 |
+- |
6330 |
+ break; |
6331 |
+ |
6332 |
+ case CR_DES_CBC: |
6333 |
+@@ -633,8 +611,6 @@ static int stm32_cryp_hw_init(struct stm32_cryp *cryp) |
6334 |
+ |
6335 |
+ stm32_cryp_write(cryp, CRYP_CR, cfg); |
6336 |
+ |
6337 |
+- cryp->flags &= ~FLG_CCM_PADDED_WA; |
6338 |
+- |
6339 |
+ return 0; |
6340 |
+ } |
6341 |
+ |
6342 |
+@@ -644,28 +620,9 @@ static void stm32_cryp_finish_req(struct stm32_cryp *cryp, int err) |
6343 |
+ /* Phase 4 : output tag */ |
6344 |
+ err = stm32_cryp_read_auth_tag(cryp); |
6345 |
+ |
6346 |
+- if (!err && (!(is_gcm(cryp) || is_ccm(cryp)))) |
6347 |
++ if (!err && (!(is_gcm(cryp) || is_ccm(cryp) || is_ecb(cryp)))) |
6348 |
+ stm32_cryp_get_iv(cryp); |
6349 |
+ |
6350 |
+- if (cryp->sgs_copied) { |
6351 |
+- void *buf_in, *buf_out; |
6352 |
+- int pages, len; |
6353 |
+- |
6354 |
+- buf_in = sg_virt(&cryp->in_sgl); |
6355 |
+- buf_out = sg_virt(&cryp->out_sgl); |
6356 |
+- |
6357 |
+- sg_copy_buf(buf_out, cryp->out_sg_save, 0, |
6358 |
+- cryp->total_out_save, 1); |
6359 |
+- |
6360 |
+- len = ALIGN(cryp->total_in_save, cryp->hw_blocksize); |
6361 |
+- pages = len ? get_order(len) : 1; |
6362 |
+- free_pages((unsigned long)buf_in, pages); |
6363 |
+- |
6364 |
+- len = ALIGN(cryp->total_out_save, cryp->hw_blocksize); |
6365 |
+- pages = len ? get_order(len) : 1; |
6366 |
+- free_pages((unsigned long)buf_out, pages); |
6367 |
+- } |
6368 |
+- |
6369 |
+ pm_runtime_mark_last_busy(cryp->dev); |
6370 |
+ pm_runtime_put_autosuspend(cryp->dev); |
6371 |
+ |
6372 |
+@@ -674,8 +631,6 @@ static void stm32_cryp_finish_req(struct stm32_cryp *cryp, int err) |
6373 |
+ else |
6374 |
+ crypto_finalize_skcipher_request(cryp->engine, cryp->req, |
6375 |
+ err); |
6376 |
+- |
6377 |
+- memset(cryp->ctx->key, 0, cryp->ctx->keylen); |
6378 |
+ } |
6379 |
+ |
6380 |
+ static int stm32_cryp_cpu_start(struct stm32_cryp *cryp) |
6381 |
+@@ -801,7 +756,20 @@ static int stm32_cryp_aes_aead_setkey(struct crypto_aead *tfm, const u8 *key, |
6382 |
+ static int stm32_cryp_aes_gcm_setauthsize(struct crypto_aead *tfm, |
6383 |
+ unsigned int authsize) |
6384 |
+ { |
6385 |
+- return authsize == AES_BLOCK_SIZE ? 0 : -EINVAL; |
6386 |
++ switch (authsize) { |
6387 |
++ case 4: |
6388 |
++ case 8: |
6389 |
++ case 12: |
6390 |
++ case 13: |
6391 |
++ case 14: |
6392 |
++ case 15: |
6393 |
++ case 16: |
6394 |
++ break; |
6395 |
++ default: |
6396 |
++ return -EINVAL; |
6397 |
++ } |
6398 |
++ |
6399 |
++ return 0; |
6400 |
+ } |
6401 |
+ |
6402 |
+ static int stm32_cryp_aes_ccm_setauthsize(struct crypto_aead *tfm, |
6403 |
+@@ -825,31 +793,61 @@ static int stm32_cryp_aes_ccm_setauthsize(struct crypto_aead *tfm, |
6404 |
+ |
6405 |
+ static int stm32_cryp_aes_ecb_encrypt(struct skcipher_request *req) |
6406 |
+ { |
6407 |
++ if (req->cryptlen % AES_BLOCK_SIZE) |
6408 |
++ return -EINVAL; |
6409 |
++ |
6410 |
++ if (req->cryptlen == 0) |
6411 |
++ return 0; |
6412 |
++ |
6413 |
+ return stm32_cryp_crypt(req, FLG_AES | FLG_ECB | FLG_ENCRYPT); |
6414 |
+ } |
6415 |
+ |
6416 |
+ static int stm32_cryp_aes_ecb_decrypt(struct skcipher_request *req) |
6417 |
+ { |
6418 |
++ if (req->cryptlen % AES_BLOCK_SIZE) |
6419 |
++ return -EINVAL; |
6420 |
++ |
6421 |
++ if (req->cryptlen == 0) |
6422 |
++ return 0; |
6423 |
++ |
6424 |
+ return stm32_cryp_crypt(req, FLG_AES | FLG_ECB); |
6425 |
+ } |
6426 |
+ |
6427 |
+ static int stm32_cryp_aes_cbc_encrypt(struct skcipher_request *req) |
6428 |
+ { |
6429 |
++ if (req->cryptlen % AES_BLOCK_SIZE) |
6430 |
++ return -EINVAL; |
6431 |
++ |
6432 |
++ if (req->cryptlen == 0) |
6433 |
++ return 0; |
6434 |
++ |
6435 |
+ return stm32_cryp_crypt(req, FLG_AES | FLG_CBC | FLG_ENCRYPT); |
6436 |
+ } |
6437 |
+ |
6438 |
+ static int stm32_cryp_aes_cbc_decrypt(struct skcipher_request *req) |
6439 |
+ { |
6440 |
++ if (req->cryptlen % AES_BLOCK_SIZE) |
6441 |
++ return -EINVAL; |
6442 |
++ |
6443 |
++ if (req->cryptlen == 0) |
6444 |
++ return 0; |
6445 |
++ |
6446 |
+ return stm32_cryp_crypt(req, FLG_AES | FLG_CBC); |
6447 |
+ } |
6448 |
+ |
6449 |
+ static int stm32_cryp_aes_ctr_encrypt(struct skcipher_request *req) |
6450 |
+ { |
6451 |
++ if (req->cryptlen == 0) |
6452 |
++ return 0; |
6453 |
++ |
6454 |
+ return stm32_cryp_crypt(req, FLG_AES | FLG_CTR | FLG_ENCRYPT); |
6455 |
+ } |
6456 |
+ |
6457 |
+ static int stm32_cryp_aes_ctr_decrypt(struct skcipher_request *req) |
6458 |
+ { |
6459 |
++ if (req->cryptlen == 0) |
6460 |
++ return 0; |
6461 |
++ |
6462 |
+ return stm32_cryp_crypt(req, FLG_AES | FLG_CTR); |
6463 |
+ } |
6464 |
+ |
6465 |
+@@ -863,53 +861,122 @@ static int stm32_cryp_aes_gcm_decrypt(struct aead_request *req) |
6466 |
+ return stm32_cryp_aead_crypt(req, FLG_AES | FLG_GCM); |
6467 |
+ } |
6468 |
+ |
6469 |
++static inline int crypto_ccm_check_iv(const u8 *iv) |
6470 |
++{ |
6471 |
++ /* 2 <= L <= 8, so 1 <= L' <= 7. */ |
6472 |
++ if (iv[0] < 1 || iv[0] > 7) |
6473 |
++ return -EINVAL; |
6474 |
++ |
6475 |
++ return 0; |
6476 |
++} |
6477 |
++ |
6478 |
+ static int stm32_cryp_aes_ccm_encrypt(struct aead_request *req) |
6479 |
+ { |
6480 |
++ int err; |
6481 |
++ |
6482 |
++ err = crypto_ccm_check_iv(req->iv); |
6483 |
++ if (err) |
6484 |
++ return err; |
6485 |
++ |
6486 |
+ return stm32_cryp_aead_crypt(req, FLG_AES | FLG_CCM | FLG_ENCRYPT); |
6487 |
+ } |
6488 |
+ |
6489 |
+ static int stm32_cryp_aes_ccm_decrypt(struct aead_request *req) |
6490 |
+ { |
6491 |
++ int err; |
6492 |
++ |
6493 |
++ err = crypto_ccm_check_iv(req->iv); |
6494 |
++ if (err) |
6495 |
++ return err; |
6496 |
++ |
6497 |
+ return stm32_cryp_aead_crypt(req, FLG_AES | FLG_CCM); |
6498 |
+ } |
6499 |
+ |
6500 |
+ static int stm32_cryp_des_ecb_encrypt(struct skcipher_request *req) |
6501 |
+ { |
6502 |
++ if (req->cryptlen % DES_BLOCK_SIZE) |
6503 |
++ return -EINVAL; |
6504 |
++ |
6505 |
++ if (req->cryptlen == 0) |
6506 |
++ return 0; |
6507 |
++ |
6508 |
+ return stm32_cryp_crypt(req, FLG_DES | FLG_ECB | FLG_ENCRYPT); |
6509 |
+ } |
6510 |
+ |
6511 |
+ static int stm32_cryp_des_ecb_decrypt(struct skcipher_request *req) |
6512 |
+ { |
6513 |
++ if (req->cryptlen % DES_BLOCK_SIZE) |
6514 |
++ return -EINVAL; |
6515 |
++ |
6516 |
++ if (req->cryptlen == 0) |
6517 |
++ return 0; |
6518 |
++ |
6519 |
+ return stm32_cryp_crypt(req, FLG_DES | FLG_ECB); |
6520 |
+ } |
6521 |
+ |
6522 |
+ static int stm32_cryp_des_cbc_encrypt(struct skcipher_request *req) |
6523 |
+ { |
6524 |
++ if (req->cryptlen % DES_BLOCK_SIZE) |
6525 |
++ return -EINVAL; |
6526 |
++ |
6527 |
++ if (req->cryptlen == 0) |
6528 |
++ return 0; |
6529 |
++ |
6530 |
+ return stm32_cryp_crypt(req, FLG_DES | FLG_CBC | FLG_ENCRYPT); |
6531 |
+ } |
6532 |
+ |
6533 |
+ static int stm32_cryp_des_cbc_decrypt(struct skcipher_request *req) |
6534 |
+ { |
6535 |
++ if (req->cryptlen % DES_BLOCK_SIZE) |
6536 |
++ return -EINVAL; |
6537 |
++ |
6538 |
++ if (req->cryptlen == 0) |
6539 |
++ return 0; |
6540 |
++ |
6541 |
+ return stm32_cryp_crypt(req, FLG_DES | FLG_CBC); |
6542 |
+ } |
6543 |
+ |
6544 |
+ static int stm32_cryp_tdes_ecb_encrypt(struct skcipher_request *req) |
6545 |
+ { |
6546 |
++ if (req->cryptlen % DES_BLOCK_SIZE) |
6547 |
++ return -EINVAL; |
6548 |
++ |
6549 |
++ if (req->cryptlen == 0) |
6550 |
++ return 0; |
6551 |
++ |
6552 |
+ return stm32_cryp_crypt(req, FLG_TDES | FLG_ECB | FLG_ENCRYPT); |
6553 |
+ } |
6554 |
+ |
6555 |
+ static int stm32_cryp_tdes_ecb_decrypt(struct skcipher_request *req) |
6556 |
+ { |
6557 |
++ if (req->cryptlen % DES_BLOCK_SIZE) |
6558 |
++ return -EINVAL; |
6559 |
++ |
6560 |
++ if (req->cryptlen == 0) |
6561 |
++ return 0; |
6562 |
++ |
6563 |
+ return stm32_cryp_crypt(req, FLG_TDES | FLG_ECB); |
6564 |
+ } |
6565 |
+ |
6566 |
+ static int stm32_cryp_tdes_cbc_encrypt(struct skcipher_request *req) |
6567 |
+ { |
6568 |
++ if (req->cryptlen % DES_BLOCK_SIZE) |
6569 |
++ return -EINVAL; |
6570 |
++ |
6571 |
++ if (req->cryptlen == 0) |
6572 |
++ return 0; |
6573 |
++ |
6574 |
+ return stm32_cryp_crypt(req, FLG_TDES | FLG_CBC | FLG_ENCRYPT); |
6575 |
+ } |
6576 |
+ |
6577 |
+ static int stm32_cryp_tdes_cbc_decrypt(struct skcipher_request *req) |
6578 |
+ { |
6579 |
++ if (req->cryptlen % DES_BLOCK_SIZE) |
6580 |
++ return -EINVAL; |
6581 |
++ |
6582 |
++ if (req->cryptlen == 0) |
6583 |
++ return 0; |
6584 |
++ |
6585 |
+ return stm32_cryp_crypt(req, FLG_TDES | FLG_CBC); |
6586 |
+ } |
6587 |
+ |
6588 |
+@@ -919,6 +986,7 @@ static int stm32_cryp_prepare_req(struct skcipher_request *req, |
6589 |
+ struct stm32_cryp_ctx *ctx; |
6590 |
+ struct stm32_cryp *cryp; |
6591 |
+ struct stm32_cryp_reqctx *rctx; |
6592 |
++ struct scatterlist *in_sg; |
6593 |
+ int ret; |
6594 |
+ |
6595 |
+ if (!req && !areq) |
6596 |
+@@ -944,76 +1012,55 @@ static int stm32_cryp_prepare_req(struct skcipher_request *req, |
6597 |
+ if (req) { |
6598 |
+ cryp->req = req; |
6599 |
+ cryp->areq = NULL; |
6600 |
+- cryp->total_in = req->cryptlen; |
6601 |
+- cryp->total_out = cryp->total_in; |
6602 |
++ cryp->header_in = 0; |
6603 |
++ cryp->payload_in = req->cryptlen; |
6604 |
++ cryp->payload_out = req->cryptlen; |
6605 |
++ cryp->authsize = 0; |
6606 |
+ } else { |
6607 |
+ /* |
6608 |
+ * Length of input and output data: |
6609 |
+ * Encryption case: |
6610 |
+- * INPUT = AssocData || PlainText |
6611 |
++ * INPUT = AssocData || PlainText |
6612 |
+ * <- assoclen -> <- cryptlen -> |
6613 |
+- * <------- total_in -----------> |
6614 |
+ * |
6615 |
+- * OUTPUT = AssocData || CipherText || AuthTag |
6616 |
+- * <- assoclen -> <- cryptlen -> <- authsize -> |
6617 |
+- * <---------------- total_out -----------------> |
6618 |
++ * OUTPUT = AssocData || CipherText || AuthTag |
6619 |
++ * <- assoclen -> <-- cryptlen --> <- authsize -> |
6620 |
+ * |
6621 |
+ * Decryption case: |
6622 |
+- * INPUT = AssocData || CipherText || AuthTag |
6623 |
+- * <- assoclen -> <--------- cryptlen ---------> |
6624 |
+- * <- authsize -> |
6625 |
+- * <---------------- total_in ------------------> |
6626 |
++ * INPUT = AssocData || CipherTex || AuthTag |
6627 |
++ * <- assoclen ---> <---------- cryptlen ----------> |
6628 |
+ * |
6629 |
+- * OUTPUT = AssocData || PlainText |
6630 |
+- * <- assoclen -> <- crypten - authsize -> |
6631 |
+- * <---------- total_out -----------------> |
6632 |
++ * OUTPUT = AssocData || PlainText |
6633 |
++ * <- assoclen -> <- cryptlen - authsize -> |
6634 |
+ */ |
6635 |
+ cryp->areq = areq; |
6636 |
+ cryp->req = NULL; |
6637 |
+ cryp->authsize = crypto_aead_authsize(crypto_aead_reqtfm(areq)); |
6638 |
+- cryp->total_in = areq->assoclen + areq->cryptlen; |
6639 |
+- if (is_encrypt(cryp)) |
6640 |
+- /* Append auth tag to output */ |
6641 |
+- cryp->total_out = cryp->total_in + cryp->authsize; |
6642 |
+- else |
6643 |
+- /* No auth tag in output */ |
6644 |
+- cryp->total_out = cryp->total_in - cryp->authsize; |
6645 |
++ if (is_encrypt(cryp)) { |
6646 |
++ cryp->payload_in = areq->cryptlen; |
6647 |
++ cryp->header_in = areq->assoclen; |
6648 |
++ cryp->payload_out = areq->cryptlen; |
6649 |
++ } else { |
6650 |
++ cryp->payload_in = areq->cryptlen - cryp->authsize; |
6651 |
++ cryp->header_in = areq->assoclen; |
6652 |
++ cryp->payload_out = cryp->payload_in; |
6653 |
++ } |
6654 |
+ } |
6655 |
+ |
6656 |
+- cryp->total_in_save = cryp->total_in; |
6657 |
+- cryp->total_out_save = cryp->total_out; |
6658 |
++ in_sg = req ? req->src : areq->src; |
6659 |
++ scatterwalk_start(&cryp->in_walk, in_sg); |
6660 |
+ |
6661 |
+- cryp->in_sg = req ? req->src : areq->src; |
6662 |
+ cryp->out_sg = req ? req->dst : areq->dst; |
6663 |
+- cryp->out_sg_save = cryp->out_sg; |
6664 |
+- |
6665 |
+- cryp->in_sg_len = sg_nents_for_len(cryp->in_sg, cryp->total_in); |
6666 |
+- if (cryp->in_sg_len < 0) { |
6667 |
+- dev_err(cryp->dev, "Cannot get in_sg_len\n"); |
6668 |
+- ret = cryp->in_sg_len; |
6669 |
+- return ret; |
6670 |
+- } |
6671 |
+- |
6672 |
+- cryp->out_sg_len = sg_nents_for_len(cryp->out_sg, cryp->total_out); |
6673 |
+- if (cryp->out_sg_len < 0) { |
6674 |
+- dev_err(cryp->dev, "Cannot get out_sg_len\n"); |
6675 |
+- ret = cryp->out_sg_len; |
6676 |
+- return ret; |
6677 |
+- } |
6678 |
+- |
6679 |
+- ret = stm32_cryp_copy_sgs(cryp); |
6680 |
+- if (ret) |
6681 |
+- return ret; |
6682 |
+- |
6683 |
+- scatterwalk_start(&cryp->in_walk, cryp->in_sg); |
6684 |
+ scatterwalk_start(&cryp->out_walk, cryp->out_sg); |
6685 |
+ |
6686 |
+ if (is_gcm(cryp) || is_ccm(cryp)) { |
6687 |
+ /* In output, jump after assoc data */ |
6688 |
+- scatterwalk_advance(&cryp->out_walk, cryp->areq->assoclen); |
6689 |
+- cryp->total_out -= cryp->areq->assoclen; |
6690 |
++ scatterwalk_copychunks(NULL, &cryp->out_walk, cryp->areq->assoclen, 2); |
6691 |
+ } |
6692 |
+ |
6693 |
++ if (is_ctr(cryp)) |
6694 |
++ memset(cryp->last_ctr, 0, sizeof(cryp->last_ctr)); |
6695 |
++ |
6696 |
+ ret = stm32_cryp_hw_init(cryp); |
6697 |
+ return ret; |
6698 |
+ } |
6699 |
+@@ -1061,8 +1108,7 @@ static int stm32_cryp_aead_one_req(struct crypto_engine *engine, void *areq) |
6700 |
+ if (!cryp) |
6701 |
+ return -ENODEV; |
6702 |
+ |
6703 |
+- if (unlikely(!cryp->areq->assoclen && |
6704 |
+- !stm32_cryp_get_input_text_len(cryp))) { |
6705 |
++ if (unlikely(!cryp->payload_in && !cryp->header_in)) { |
6706 |
+ /* No input data to process: get tag and finish */ |
6707 |
+ stm32_cryp_finish_req(cryp, 0); |
6708 |
+ return 0; |
6709 |
+@@ -1071,43 +1117,10 @@ static int stm32_cryp_aead_one_req(struct crypto_engine *engine, void *areq) |
6710 |
+ return stm32_cryp_cpu_start(cryp); |
6711 |
+ } |
6712 |
+ |
6713 |
+-static u32 *stm32_cryp_next_out(struct stm32_cryp *cryp, u32 *dst, |
6714 |
+- unsigned int n) |
6715 |
+-{ |
6716 |
+- scatterwalk_advance(&cryp->out_walk, n); |
6717 |
+- |
6718 |
+- if (unlikely(cryp->out_sg->length == _walked_out)) { |
6719 |
+- cryp->out_sg = sg_next(cryp->out_sg); |
6720 |
+- if (cryp->out_sg) { |
6721 |
+- scatterwalk_start(&cryp->out_walk, cryp->out_sg); |
6722 |
+- return (sg_virt(cryp->out_sg) + _walked_out); |
6723 |
+- } |
6724 |
+- } |
6725 |
+- |
6726 |
+- return (u32 *)((u8 *)dst + n); |
6727 |
+-} |
6728 |
+- |
6729 |
+-static u32 *stm32_cryp_next_in(struct stm32_cryp *cryp, u32 *src, |
6730 |
+- unsigned int n) |
6731 |
+-{ |
6732 |
+- scatterwalk_advance(&cryp->in_walk, n); |
6733 |
+- |
6734 |
+- if (unlikely(cryp->in_sg->length == _walked_in)) { |
6735 |
+- cryp->in_sg = sg_next(cryp->in_sg); |
6736 |
+- if (cryp->in_sg) { |
6737 |
+- scatterwalk_start(&cryp->in_walk, cryp->in_sg); |
6738 |
+- return (sg_virt(cryp->in_sg) + _walked_in); |
6739 |
+- } |
6740 |
+- } |
6741 |
+- |
6742 |
+- return (u32 *)((u8 *)src + n); |
6743 |
+-} |
6744 |
+- |
6745 |
+ static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp) |
6746 |
+ { |
6747 |
+- u32 cfg, size_bit, *dst, d32; |
6748 |
+- u8 *d8; |
6749 |
+- unsigned int i, j; |
6750 |
++ u32 cfg, size_bit; |
6751 |
++ unsigned int i; |
6752 |
+ int ret = 0; |
6753 |
+ |
6754 |
+ /* Update Config */ |
6755 |
+@@ -1130,7 +1143,7 @@ static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp) |
6756 |
+ stm32_cryp_write(cryp, CRYP_DIN, size_bit); |
6757 |
+ |
6758 |
+ size_bit = is_encrypt(cryp) ? cryp->areq->cryptlen : |
6759 |
+- cryp->areq->cryptlen - AES_BLOCK_SIZE; |
6760 |
++ cryp->areq->cryptlen - cryp->authsize; |
6761 |
+ size_bit *= 8; |
6762 |
+ if (cryp->caps->swap_final) |
6763 |
+ size_bit = (__force u32)cpu_to_be32(size_bit); |
6764 |
+@@ -1139,11 +1152,9 @@ static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp) |
6765 |
+ stm32_cryp_write(cryp, CRYP_DIN, size_bit); |
6766 |
+ } else { |
6767 |
+ /* CCM: write CTR0 */ |
6768 |
+- u8 iv[AES_BLOCK_SIZE]; |
6769 |
+- u32 *iv32 = (u32 *)iv; |
6770 |
+- __be32 *biv; |
6771 |
+- |
6772 |
+- biv = (void *)iv; |
6773 |
++ u32 iv32[AES_BLOCK_32]; |
6774 |
++ u8 *iv = (u8 *)iv32; |
6775 |
++ __be32 *biv = (__be32 *)iv32; |
6776 |
+ |
6777 |
+ memcpy(iv, cryp->areq->iv, AES_BLOCK_SIZE); |
6778 |
+ memset(iv + AES_BLOCK_SIZE - 1 - iv[0], 0, iv[0] + 1); |
6779 |
+@@ -1165,39 +1176,18 @@ static int stm32_cryp_read_auth_tag(struct stm32_cryp *cryp) |
6780 |
+ } |
6781 |
+ |
6782 |
+ if (is_encrypt(cryp)) { |
6783 |
++ u32 out_tag[AES_BLOCK_32]; |
6784 |
++ |
6785 |
+ /* Get and write tag */ |
6786 |
+- dst = sg_virt(cryp->out_sg) + _walked_out; |
6787 |
++ for (i = 0; i < AES_BLOCK_32; i++) |
6788 |
++ out_tag[i] = stm32_cryp_read(cryp, CRYP_DOUT); |
6789 |
+ |
6790 |
+- for (i = 0; i < AES_BLOCK_32; i++) { |
6791 |
+- if (cryp->total_out >= sizeof(u32)) { |
6792 |
+- /* Read a full u32 */ |
6793 |
+- *dst = stm32_cryp_read(cryp, CRYP_DOUT); |
6794 |
+- |
6795 |
+- dst = stm32_cryp_next_out(cryp, dst, |
6796 |
+- sizeof(u32)); |
6797 |
+- cryp->total_out -= sizeof(u32); |
6798 |
+- } else if (!cryp->total_out) { |
6799 |
+- /* Empty fifo out (data from input padding) */ |
6800 |
+- stm32_cryp_read(cryp, CRYP_DOUT); |
6801 |
+- } else { |
6802 |
+- /* Read less than an u32 */ |
6803 |
+- d32 = stm32_cryp_read(cryp, CRYP_DOUT); |
6804 |
+- d8 = (u8 *)&d32; |
6805 |
+- |
6806 |
+- for (j = 0; j < cryp->total_out; j++) { |
6807 |
+- *((u8 *)dst) = *(d8++); |
6808 |
+- dst = stm32_cryp_next_out(cryp, dst, 1); |
6809 |
+- } |
6810 |
+- cryp->total_out = 0; |
6811 |
+- } |
6812 |
+- } |
6813 |
++ scatterwalk_copychunks(out_tag, &cryp->out_walk, cryp->authsize, 1); |
6814 |
+ } else { |
6815 |
+ /* Get and check tag */ |
6816 |
+ u32 in_tag[AES_BLOCK_32], out_tag[AES_BLOCK_32]; |
6817 |
+ |
6818 |
+- scatterwalk_map_and_copy(in_tag, cryp->in_sg, |
6819 |
+- cryp->total_in_save - cryp->authsize, |
6820 |
+- cryp->authsize, 0); |
6821 |
++ scatterwalk_copychunks(in_tag, &cryp->in_walk, cryp->authsize, 0); |
6822 |
+ |
6823 |
+ for (i = 0; i < AES_BLOCK_32; i++) |
6824 |
+ out_tag[i] = stm32_cryp_read(cryp, CRYP_DOUT); |
6825 |
+@@ -1217,115 +1207,59 @@ static void stm32_cryp_check_ctr_counter(struct stm32_cryp *cryp) |
6826 |
+ { |
6827 |
+ u32 cr; |
6828 |
+ |
6829 |
+- if (unlikely(cryp->last_ctr[3] == 0xFFFFFFFF)) { |
6830 |
+- cryp->last_ctr[3] = 0; |
6831 |
+- cryp->last_ctr[2]++; |
6832 |
+- if (!cryp->last_ctr[2]) { |
6833 |
+- cryp->last_ctr[1]++; |
6834 |
+- if (!cryp->last_ctr[1]) |
6835 |
+- cryp->last_ctr[0]++; |
6836 |
+- } |
6837 |
++ if (unlikely(cryp->last_ctr[3] == cpu_to_be32(0xFFFFFFFF))) { |
6838 |
++ /* |
6839 |
++ * In this case, we need to increment manually the ctr counter, |
6840 |
++ * as HW doesn't handle the U32 carry. |
6841 |
++ */ |
6842 |
++ crypto_inc((u8 *)cryp->last_ctr, sizeof(cryp->last_ctr)); |
6843 |
+ |
6844 |
+ cr = stm32_cryp_read(cryp, CRYP_CR); |
6845 |
+ stm32_cryp_write(cryp, CRYP_CR, cr & ~CR_CRYPEN); |
6846 |
+ |
6847 |
+- stm32_cryp_hw_write_iv(cryp, (__be32 *)cryp->last_ctr); |
6848 |
++ stm32_cryp_hw_write_iv(cryp, cryp->last_ctr); |
6849 |
+ |
6850 |
+ stm32_cryp_write(cryp, CRYP_CR, cr); |
6851 |
+ } |
6852 |
+ |
6853 |
+- cryp->last_ctr[0] = stm32_cryp_read(cryp, CRYP_IV0LR); |
6854 |
+- cryp->last_ctr[1] = stm32_cryp_read(cryp, CRYP_IV0RR); |
6855 |
+- cryp->last_ctr[2] = stm32_cryp_read(cryp, CRYP_IV1LR); |
6856 |
+- cryp->last_ctr[3] = stm32_cryp_read(cryp, CRYP_IV1RR); |
6857 |
++ /* The IV registers are BE */ |
6858 |
++ cryp->last_ctr[0] = cpu_to_be32(stm32_cryp_read(cryp, CRYP_IV0LR)); |
6859 |
++ cryp->last_ctr[1] = cpu_to_be32(stm32_cryp_read(cryp, CRYP_IV0RR)); |
6860 |
++ cryp->last_ctr[2] = cpu_to_be32(stm32_cryp_read(cryp, CRYP_IV1LR)); |
6861 |
++ cryp->last_ctr[3] = cpu_to_be32(stm32_cryp_read(cryp, CRYP_IV1RR)); |
6862 |
+ } |
6863 |
+ |
6864 |
+-static bool stm32_cryp_irq_read_data(struct stm32_cryp *cryp) |
6865 |
++static void stm32_cryp_irq_read_data(struct stm32_cryp *cryp) |
6866 |
+ { |
6867 |
+- unsigned int i, j; |
6868 |
+- u32 d32, *dst; |
6869 |
+- u8 *d8; |
6870 |
+- size_t tag_size; |
6871 |
+- |
6872 |
+- /* Do no read tag now (if any) */ |
6873 |
+- if (is_encrypt(cryp) && (is_gcm(cryp) || is_ccm(cryp))) |
6874 |
+- tag_size = cryp->authsize; |
6875 |
+- else |
6876 |
+- tag_size = 0; |
6877 |
+- |
6878 |
+- dst = sg_virt(cryp->out_sg) + _walked_out; |
6879 |
++ unsigned int i; |
6880 |
++ u32 block[AES_BLOCK_32]; |
6881 |
+ |
6882 |
+- for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) { |
6883 |
+- if (likely(cryp->total_out - tag_size >= sizeof(u32))) { |
6884 |
+- /* Read a full u32 */ |
6885 |
+- *dst = stm32_cryp_read(cryp, CRYP_DOUT); |
6886 |
++ for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) |
6887 |
++ block[i] = stm32_cryp_read(cryp, CRYP_DOUT); |
6888 |
+ |
6889 |
+- dst = stm32_cryp_next_out(cryp, dst, sizeof(u32)); |
6890 |
+- cryp->total_out -= sizeof(u32); |
6891 |
+- } else if (cryp->total_out == tag_size) { |
6892 |
+- /* Empty fifo out (data from input padding) */ |
6893 |
+- d32 = stm32_cryp_read(cryp, CRYP_DOUT); |
6894 |
+- } else { |
6895 |
+- /* Read less than an u32 */ |
6896 |
+- d32 = stm32_cryp_read(cryp, CRYP_DOUT); |
6897 |
+- d8 = (u8 *)&d32; |
6898 |
+- |
6899 |
+- for (j = 0; j < cryp->total_out - tag_size; j++) { |
6900 |
+- *((u8 *)dst) = *(d8++); |
6901 |
+- dst = stm32_cryp_next_out(cryp, dst, 1); |
6902 |
+- } |
6903 |
+- cryp->total_out = tag_size; |
6904 |
+- } |
6905 |
+- } |
6906 |
+- |
6907 |
+- return !(cryp->total_out - tag_size) || !cryp->total_in; |
6908 |
++ scatterwalk_copychunks(block, &cryp->out_walk, min_t(size_t, cryp->hw_blocksize, |
6909 |
++ cryp->payload_out), 1); |
6910 |
++ cryp->payload_out -= min_t(size_t, cryp->hw_blocksize, |
6911 |
++ cryp->payload_out); |
6912 |
+ } |
6913 |
+ |
6914 |
+ static void stm32_cryp_irq_write_block(struct stm32_cryp *cryp) |
6915 |
+ { |
6916 |
+- unsigned int i, j; |
6917 |
+- u32 *src; |
6918 |
+- u8 d8[4]; |
6919 |
+- size_t tag_size; |
6920 |
+- |
6921 |
+- /* Do no write tag (if any) */ |
6922 |
+- if (is_decrypt(cryp) && (is_gcm(cryp) || is_ccm(cryp))) |
6923 |
+- tag_size = cryp->authsize; |
6924 |
+- else |
6925 |
+- tag_size = 0; |
6926 |
+- |
6927 |
+- src = sg_virt(cryp->in_sg) + _walked_in; |
6928 |
++ unsigned int i; |
6929 |
++ u32 block[AES_BLOCK_32] = {0}; |
6930 |
+ |
6931 |
+- for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) { |
6932 |
+- if (likely(cryp->total_in - tag_size >= sizeof(u32))) { |
6933 |
+- /* Write a full u32 */ |
6934 |
+- stm32_cryp_write(cryp, CRYP_DIN, *src); |
6935 |
++ scatterwalk_copychunks(block, &cryp->in_walk, min_t(size_t, cryp->hw_blocksize, |
6936 |
++ cryp->payload_in), 0); |
6937 |
++ for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) |
6938 |
++ stm32_cryp_write(cryp, CRYP_DIN, block[i]); |
6939 |
+ |
6940 |
+- src = stm32_cryp_next_in(cryp, src, sizeof(u32)); |
6941 |
+- cryp->total_in -= sizeof(u32); |
6942 |
+- } else if (cryp->total_in == tag_size) { |
6943 |
+- /* Write padding data */ |
6944 |
+- stm32_cryp_write(cryp, CRYP_DIN, 0); |
6945 |
+- } else { |
6946 |
+- /* Write less than an u32 */ |
6947 |
+- memset(d8, 0, sizeof(u32)); |
6948 |
+- for (j = 0; j < cryp->total_in - tag_size; j++) { |
6949 |
+- d8[j] = *((u8 *)src); |
6950 |
+- src = stm32_cryp_next_in(cryp, src, 1); |
6951 |
+- } |
6952 |
+- |
6953 |
+- stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); |
6954 |
+- cryp->total_in = tag_size; |
6955 |
+- } |
6956 |
+- } |
6957 |
++ cryp->payload_in -= min_t(size_t, cryp->hw_blocksize, cryp->payload_in); |
6958 |
+ } |
6959 |
+ |
6960 |
+ static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp) |
6961 |
+ { |
6962 |
+ int err; |
6963 |
+- u32 cfg, tmp[AES_BLOCK_32]; |
6964 |
+- size_t total_in_ori = cryp->total_in; |
6965 |
+- struct scatterlist *out_sg_ori = cryp->out_sg; |
6966 |
++ u32 cfg, block[AES_BLOCK_32] = {0}; |
6967 |
+ unsigned int i; |
6968 |
+ |
6969 |
+ /* 'Special workaround' procedure described in the datasheet */ |
6970 |
+@@ -1350,18 +1284,25 @@ static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp) |
6971 |
+ |
6972 |
+ /* b) pad and write the last block */ |
6973 |
+ stm32_cryp_irq_write_block(cryp); |
6974 |
+- cryp->total_in = total_in_ori; |
6975 |
++ /* wait end of process */ |
6976 |
+ err = stm32_cryp_wait_output(cryp); |
6977 |
+ if (err) { |
6978 |
+- dev_err(cryp->dev, "Timeout (write gcm header)\n"); |
6979 |
++ dev_err(cryp->dev, "Timeout (write gcm last data)\n"); |
6980 |
+ return stm32_cryp_finish_req(cryp, err); |
6981 |
+ } |
6982 |
+ |
6983 |
+ /* c) get and store encrypted data */ |
6984 |
+- stm32_cryp_irq_read_data(cryp); |
6985 |
+- scatterwalk_map_and_copy(tmp, out_sg_ori, |
6986 |
+- cryp->total_in_save - total_in_ori, |
6987 |
+- total_in_ori, 0); |
6988 |
++ /* |
6989 |
++ * Same code as stm32_cryp_irq_read_data(), but we want to store |
6990 |
++ * block value |
6991 |
++ */ |
6992 |
++ for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) |
6993 |
++ block[i] = stm32_cryp_read(cryp, CRYP_DOUT); |
6994 |
++ |
6995 |
++ scatterwalk_copychunks(block, &cryp->out_walk, min_t(size_t, cryp->hw_blocksize, |
6996 |
++ cryp->payload_out), 1); |
6997 |
++ cryp->payload_out -= min_t(size_t, cryp->hw_blocksize, |
6998 |
++ cryp->payload_out); |
6999 |
+ |
7000 |
+ /* d) change mode back to AES GCM */ |
7001 |
+ cfg &= ~CR_ALGO_MASK; |
7002 |
+@@ -1374,19 +1315,13 @@ static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp) |
7003 |
+ stm32_cryp_write(cryp, CRYP_CR, cfg); |
7004 |
+ |
7005 |
+ /* f) write padded data */ |
7006 |
+- for (i = 0; i < AES_BLOCK_32; i++) { |
7007 |
+- if (cryp->total_in) |
7008 |
+- stm32_cryp_write(cryp, CRYP_DIN, tmp[i]); |
7009 |
+- else |
7010 |
+- stm32_cryp_write(cryp, CRYP_DIN, 0); |
7011 |
+- |
7012 |
+- cryp->total_in -= min_t(size_t, sizeof(u32), cryp->total_in); |
7013 |
+- } |
7014 |
++ for (i = 0; i < AES_BLOCK_32; i++) |
7015 |
++ stm32_cryp_write(cryp, CRYP_DIN, block[i]); |
7016 |
+ |
7017 |
+ /* g) Empty fifo out */ |
7018 |
+ err = stm32_cryp_wait_output(cryp); |
7019 |
+ if (err) { |
7020 |
+- dev_err(cryp->dev, "Timeout (write gcm header)\n"); |
7021 |
++ dev_err(cryp->dev, "Timeout (write gcm padded data)\n"); |
7022 |
+ return stm32_cryp_finish_req(cryp, err); |
7023 |
+ } |
7024 |
+ |
7025 |
+@@ -1399,16 +1334,14 @@ static void stm32_cryp_irq_write_gcm_padded_data(struct stm32_cryp *cryp) |
7026 |
+ |
7027 |
+ static void stm32_cryp_irq_set_npblb(struct stm32_cryp *cryp) |
7028 |
+ { |
7029 |
+- u32 cfg, payload_bytes; |
7030 |
++ u32 cfg; |
7031 |
+ |
7032 |
+ /* disable ip, set NPBLB and reneable ip */ |
7033 |
+ cfg = stm32_cryp_read(cryp, CRYP_CR); |
7034 |
+ cfg &= ~CR_CRYPEN; |
7035 |
+ stm32_cryp_write(cryp, CRYP_CR, cfg); |
7036 |
+ |
7037 |
+- payload_bytes = is_decrypt(cryp) ? cryp->total_in - cryp->authsize : |
7038 |
+- cryp->total_in; |
7039 |
+- cfg |= (cryp->hw_blocksize - payload_bytes) << CR_NBPBL_SHIFT; |
7040 |
++ cfg |= (cryp->hw_blocksize - cryp->payload_in) << CR_NBPBL_SHIFT; |
7041 |
+ cfg |= CR_CRYPEN; |
7042 |
+ stm32_cryp_write(cryp, CRYP_CR, cfg); |
7043 |
+ } |
7044 |
+@@ -1417,13 +1350,11 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) |
7045 |
+ { |
7046 |
+ int err = 0; |
7047 |
+ u32 cfg, iv1tmp; |
7048 |
+- u32 cstmp1[AES_BLOCK_32], cstmp2[AES_BLOCK_32], tmp[AES_BLOCK_32]; |
7049 |
+- size_t last_total_out, total_in_ori = cryp->total_in; |
7050 |
+- struct scatterlist *out_sg_ori = cryp->out_sg; |
7051 |
++ u32 cstmp1[AES_BLOCK_32], cstmp2[AES_BLOCK_32]; |
7052 |
++ u32 block[AES_BLOCK_32] = {0}; |
7053 |
+ unsigned int i; |
7054 |
+ |
7055 |
+ /* 'Special workaround' procedure described in the datasheet */ |
7056 |
+- cryp->flags |= FLG_CCM_PADDED_WA; |
7057 |
+ |
7058 |
+ /* a) disable ip */ |
7059 |
+ stm32_cryp_write(cryp, CRYP_IMSCR, 0); |
7060 |
+@@ -1453,7 +1384,7 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) |
7061 |
+ |
7062 |
+ /* b) pad and write the last block */ |
7063 |
+ stm32_cryp_irq_write_block(cryp); |
7064 |
+- cryp->total_in = total_in_ori; |
7065 |
++ /* wait end of process */ |
7066 |
+ err = stm32_cryp_wait_output(cryp); |
7067 |
+ if (err) { |
7068 |
+ dev_err(cryp->dev, "Timeout (wite ccm padded data)\n"); |
7069 |
+@@ -1461,13 +1392,16 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) |
7070 |
+ } |
7071 |
+ |
7072 |
+ /* c) get and store decrypted data */ |
7073 |
+- last_total_out = cryp->total_out; |
7074 |
+- stm32_cryp_irq_read_data(cryp); |
7075 |
++ /* |
7076 |
++ * Same code as stm32_cryp_irq_read_data(), but we want to store |
7077 |
++ * block value |
7078 |
++ */ |
7079 |
++ for (i = 0; i < cryp->hw_blocksize / sizeof(u32); i++) |
7080 |
++ block[i] = stm32_cryp_read(cryp, CRYP_DOUT); |
7081 |
+ |
7082 |
+- memset(tmp, 0, sizeof(tmp)); |
7083 |
+- scatterwalk_map_and_copy(tmp, out_sg_ori, |
7084 |
+- cryp->total_out_save - last_total_out, |
7085 |
+- last_total_out, 0); |
7086 |
++ scatterwalk_copychunks(block, &cryp->out_walk, min_t(size_t, cryp->hw_blocksize, |
7087 |
++ cryp->payload_out), 1); |
7088 |
++ cryp->payload_out -= min_t(size_t, cryp->hw_blocksize, cryp->payload_out); |
7089 |
+ |
7090 |
+ /* d) Load again CRYP_CSGCMCCMxR */ |
7091 |
+ for (i = 0; i < ARRAY_SIZE(cstmp2); i++) |
7092 |
+@@ -1484,10 +1418,10 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) |
7093 |
+ stm32_cryp_write(cryp, CRYP_CR, cfg); |
7094 |
+ |
7095 |
+ /* g) XOR and write padded data */ |
7096 |
+- for (i = 0; i < ARRAY_SIZE(tmp); i++) { |
7097 |
+- tmp[i] ^= cstmp1[i]; |
7098 |
+- tmp[i] ^= cstmp2[i]; |
7099 |
+- stm32_cryp_write(cryp, CRYP_DIN, tmp[i]); |
7100 |
++ for (i = 0; i < ARRAY_SIZE(block); i++) { |
7101 |
++ block[i] ^= cstmp1[i]; |
7102 |
++ block[i] ^= cstmp2[i]; |
7103 |
++ stm32_cryp_write(cryp, CRYP_DIN, block[i]); |
7104 |
+ } |
7105 |
+ |
7106 |
+ /* h) wait for completion */ |
7107 |
+@@ -1501,30 +1435,34 @@ static void stm32_cryp_irq_write_ccm_padded_data(struct stm32_cryp *cryp) |
7108 |
+ |
7109 |
+ static void stm32_cryp_irq_write_data(struct stm32_cryp *cryp) |
7110 |
+ { |
7111 |
+- if (unlikely(!cryp->total_in)) { |
7112 |
++ if (unlikely(!cryp->payload_in)) { |
7113 |
+ dev_warn(cryp->dev, "No more data to process\n"); |
7114 |
+ return; |
7115 |
+ } |
7116 |
+ |
7117 |
+- if (unlikely(cryp->total_in < AES_BLOCK_SIZE && |
7118 |
++ if (unlikely(cryp->payload_in < AES_BLOCK_SIZE && |
7119 |
+ (stm32_cryp_get_hw_mode(cryp) == CR_AES_GCM) && |
7120 |
+ is_encrypt(cryp))) { |
7121 |
+ /* Padding for AES GCM encryption */ |
7122 |
+- if (cryp->caps->padding_wa) |
7123 |
++ if (cryp->caps->padding_wa) { |
7124 |
+ /* Special case 1 */ |
7125 |
+- return stm32_cryp_irq_write_gcm_padded_data(cryp); |
7126 |
++ stm32_cryp_irq_write_gcm_padded_data(cryp); |
7127 |
++ return; |
7128 |
++ } |
7129 |
+ |
7130 |
+ /* Setting padding bytes (NBBLB) */ |
7131 |
+ stm32_cryp_irq_set_npblb(cryp); |
7132 |
+ } |
7133 |
+ |
7134 |
+- if (unlikely((cryp->total_in - cryp->authsize < AES_BLOCK_SIZE) && |
7135 |
++ if (unlikely((cryp->payload_in < AES_BLOCK_SIZE) && |
7136 |
+ (stm32_cryp_get_hw_mode(cryp) == CR_AES_CCM) && |
7137 |
+ is_decrypt(cryp))) { |
7138 |
+ /* Padding for AES CCM decryption */ |
7139 |
+- if (cryp->caps->padding_wa) |
7140 |
++ if (cryp->caps->padding_wa) { |
7141 |
+ /* Special case 2 */ |
7142 |
+- return stm32_cryp_irq_write_ccm_padded_data(cryp); |
7143 |
++ stm32_cryp_irq_write_ccm_padded_data(cryp); |
7144 |
++ return; |
7145 |
++ } |
7146 |
+ |
7147 |
+ /* Setting padding bytes (NBBLB) */ |
7148 |
+ stm32_cryp_irq_set_npblb(cryp); |
7149 |
+@@ -1536,192 +1474,60 @@ static void stm32_cryp_irq_write_data(struct stm32_cryp *cryp) |
7150 |
+ stm32_cryp_irq_write_block(cryp); |
7151 |
+ } |
7152 |
+ |
7153 |
+-static void stm32_cryp_irq_write_gcm_header(struct stm32_cryp *cryp) |
7154 |
++static void stm32_cryp_irq_write_gcmccm_header(struct stm32_cryp *cryp) |
7155 |
+ { |
7156 |
+- int err; |
7157 |
+- unsigned int i, j; |
7158 |
+- u32 cfg, *src; |
7159 |
+- |
7160 |
+- src = sg_virt(cryp->in_sg) + _walked_in; |
7161 |
+- |
7162 |
+- for (i = 0; i < AES_BLOCK_32; i++) { |
7163 |
+- stm32_cryp_write(cryp, CRYP_DIN, *src); |
7164 |
+- |
7165 |
+- src = stm32_cryp_next_in(cryp, src, sizeof(u32)); |
7166 |
+- cryp->total_in -= min_t(size_t, sizeof(u32), cryp->total_in); |
7167 |
+- |
7168 |
+- /* Check if whole header written */ |
7169 |
+- if ((cryp->total_in_save - cryp->total_in) == |
7170 |
+- cryp->areq->assoclen) { |
7171 |
+- /* Write padding if needed */ |
7172 |
+- for (j = i + 1; j < AES_BLOCK_32; j++) |
7173 |
+- stm32_cryp_write(cryp, CRYP_DIN, 0); |
7174 |
+- |
7175 |
+- /* Wait for completion */ |
7176 |
+- err = stm32_cryp_wait_busy(cryp); |
7177 |
+- if (err) { |
7178 |
+- dev_err(cryp->dev, "Timeout (gcm header)\n"); |
7179 |
+- return stm32_cryp_finish_req(cryp, err); |
7180 |
+- } |
7181 |
+- |
7182 |
+- if (stm32_cryp_get_input_text_len(cryp)) { |
7183 |
+- /* Phase 3 : payload */ |
7184 |
+- cfg = stm32_cryp_read(cryp, CRYP_CR); |
7185 |
+- cfg &= ~CR_CRYPEN; |
7186 |
+- stm32_cryp_write(cryp, CRYP_CR, cfg); |
7187 |
+- |
7188 |
+- cfg &= ~CR_PH_MASK; |
7189 |
+- cfg |= CR_PH_PAYLOAD; |
7190 |
+- cfg |= CR_CRYPEN; |
7191 |
+- stm32_cryp_write(cryp, CRYP_CR, cfg); |
7192 |
+- } else { |
7193 |
+- /* Phase 4 : tag */ |
7194 |
+- stm32_cryp_write(cryp, CRYP_IMSCR, 0); |
7195 |
+- stm32_cryp_finish_req(cryp, 0); |
7196 |
+- } |
7197 |
+- |
7198 |
+- break; |
7199 |
+- } |
7200 |
+- |
7201 |
+- if (!cryp->total_in) |
7202 |
+- break; |
7203 |
+- } |
7204 |
+-} |
7205 |
++ unsigned int i; |
7206 |
++ u32 block[AES_BLOCK_32] = {0}; |
7207 |
++ size_t written; |
7208 |
+ |
7209 |
+-static void stm32_cryp_irq_write_ccm_header(struct stm32_cryp *cryp) |
7210 |
+-{ |
7211 |
+- int err; |
7212 |
+- unsigned int i = 0, j, k; |
7213 |
+- u32 alen, cfg, *src; |
7214 |
+- u8 d8[4]; |
7215 |
+- |
7216 |
+- src = sg_virt(cryp->in_sg) + _walked_in; |
7217 |
+- alen = cryp->areq->assoclen; |
7218 |
+- |
7219 |
+- if (!_walked_in) { |
7220 |
+- if (cryp->areq->assoclen <= 65280) { |
7221 |
+- /* Write first u32 of B1 */ |
7222 |
+- d8[0] = (alen >> 8) & 0xFF; |
7223 |
+- d8[1] = alen & 0xFF; |
7224 |
+- d8[2] = *((u8 *)src); |
7225 |
+- src = stm32_cryp_next_in(cryp, src, 1); |
7226 |
+- d8[3] = *((u8 *)src); |
7227 |
+- src = stm32_cryp_next_in(cryp, src, 1); |
7228 |
+- |
7229 |
+- stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); |
7230 |
+- i++; |
7231 |
+- |
7232 |
+- cryp->total_in -= min_t(size_t, 2, cryp->total_in); |
7233 |
+- } else { |
7234 |
+- /* Build the two first u32 of B1 */ |
7235 |
+- d8[0] = 0xFF; |
7236 |
+- d8[1] = 0xFE; |
7237 |
+- d8[2] = alen & 0xFF000000; |
7238 |
+- d8[3] = alen & 0x00FF0000; |
7239 |
+- |
7240 |
+- stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); |
7241 |
+- i++; |
7242 |
+- |
7243 |
+- d8[0] = alen & 0x0000FF00; |
7244 |
+- d8[1] = alen & 0x000000FF; |
7245 |
+- d8[2] = *((u8 *)src); |
7246 |
+- src = stm32_cryp_next_in(cryp, src, 1); |
7247 |
+- d8[3] = *((u8 *)src); |
7248 |
+- src = stm32_cryp_next_in(cryp, src, 1); |
7249 |
+- |
7250 |
+- stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); |
7251 |
+- i++; |
7252 |
+- |
7253 |
+- cryp->total_in -= min_t(size_t, 2, cryp->total_in); |
7254 |
+- } |
7255 |
+- } |
7256 |
++ written = min_t(size_t, AES_BLOCK_SIZE, cryp->header_in); |
7257 |
+ |
7258 |
+- /* Write next u32 */ |
7259 |
+- for (; i < AES_BLOCK_32; i++) { |
7260 |
+- /* Build an u32 */ |
7261 |
+- memset(d8, 0, sizeof(u32)); |
7262 |
+- for (k = 0; k < sizeof(u32); k++) { |
7263 |
+- d8[k] = *((u8 *)src); |
7264 |
+- src = stm32_cryp_next_in(cryp, src, 1); |
7265 |
+- |
7266 |
+- cryp->total_in -= min_t(size_t, 1, cryp->total_in); |
7267 |
+- if ((cryp->total_in_save - cryp->total_in) == alen) |
7268 |
+- break; |
7269 |
+- } |
7270 |
++ scatterwalk_copychunks(block, &cryp->in_walk, written, 0); |
7271 |
++ for (i = 0; i < AES_BLOCK_32; i++) |
7272 |
++ stm32_cryp_write(cryp, CRYP_DIN, block[i]); |
7273 |
+ |
7274 |
+- stm32_cryp_write(cryp, CRYP_DIN, *(u32 *)d8); |
7275 |
+- |
7276 |
+- if ((cryp->total_in_save - cryp->total_in) == alen) { |
7277 |
+- /* Write padding if needed */ |
7278 |
+- for (j = i + 1; j < AES_BLOCK_32; j++) |
7279 |
+- stm32_cryp_write(cryp, CRYP_DIN, 0); |
7280 |
+- |
7281 |
+- /* Wait for completion */ |
7282 |
+- err = stm32_cryp_wait_busy(cryp); |
7283 |
+- if (err) { |
7284 |
+- dev_err(cryp->dev, "Timeout (ccm header)\n"); |
7285 |
+- return stm32_cryp_finish_req(cryp, err); |
7286 |
+- } |
7287 |
+- |
7288 |
+- if (stm32_cryp_get_input_text_len(cryp)) { |
7289 |
+- /* Phase 3 : payload */ |
7290 |
+- cfg = stm32_cryp_read(cryp, CRYP_CR); |
7291 |
+- cfg &= ~CR_CRYPEN; |
7292 |
+- stm32_cryp_write(cryp, CRYP_CR, cfg); |
7293 |
+- |
7294 |
+- cfg &= ~CR_PH_MASK; |
7295 |
+- cfg |= CR_PH_PAYLOAD; |
7296 |
+- cfg |= CR_CRYPEN; |
7297 |
+- stm32_cryp_write(cryp, CRYP_CR, cfg); |
7298 |
+- } else { |
7299 |
+- /* Phase 4 : tag */ |
7300 |
+- stm32_cryp_write(cryp, CRYP_IMSCR, 0); |
7301 |
+- stm32_cryp_finish_req(cryp, 0); |
7302 |
+- } |
7303 |
++ cryp->header_in -= written; |
7304 |
+ |
7305 |
+- break; |
7306 |
+- } |
7307 |
+- } |
7308 |
++ stm32_crypt_gcmccm_end_header(cryp); |
7309 |
+ } |
7310 |
+ |
7311 |
+ static irqreturn_t stm32_cryp_irq_thread(int irq, void *arg) |
7312 |
+ { |
7313 |
+ struct stm32_cryp *cryp = arg; |
7314 |
+ u32 ph; |
7315 |
++ u32 it_mask = stm32_cryp_read(cryp, CRYP_IMSCR); |
7316 |
+ |
7317 |
+ if (cryp->irq_status & MISR_OUT) |
7318 |
+ /* Output FIFO IRQ: read data */ |
7319 |
+- if (unlikely(stm32_cryp_irq_read_data(cryp))) { |
7320 |
+- /* All bytes processed, finish */ |
7321 |
+- stm32_cryp_write(cryp, CRYP_IMSCR, 0); |
7322 |
+- stm32_cryp_finish_req(cryp, 0); |
7323 |
+- return IRQ_HANDLED; |
7324 |
+- } |
7325 |
++ stm32_cryp_irq_read_data(cryp); |
7326 |
+ |
7327 |
+ if (cryp->irq_status & MISR_IN) { |
7328 |
+- if (is_gcm(cryp)) { |
7329 |
++ if (is_gcm(cryp) || is_ccm(cryp)) { |
7330 |
+ ph = stm32_cryp_read(cryp, CRYP_CR) & CR_PH_MASK; |
7331 |
+ if (unlikely(ph == CR_PH_HEADER)) |
7332 |
+ /* Write Header */ |
7333 |
+- stm32_cryp_irq_write_gcm_header(cryp); |
7334 |
+- else |
7335 |
+- /* Input FIFO IRQ: write data */ |
7336 |
+- stm32_cryp_irq_write_data(cryp); |
7337 |
+- cryp->gcm_ctr++; |
7338 |
+- } else if (is_ccm(cryp)) { |
7339 |
+- ph = stm32_cryp_read(cryp, CRYP_CR) & CR_PH_MASK; |
7340 |
+- if (unlikely(ph == CR_PH_HEADER)) |
7341 |
+- /* Write Header */ |
7342 |
+- stm32_cryp_irq_write_ccm_header(cryp); |
7343 |
++ stm32_cryp_irq_write_gcmccm_header(cryp); |
7344 |
+ else |
7345 |
+ /* Input FIFO IRQ: write data */ |
7346 |
+ stm32_cryp_irq_write_data(cryp); |
7347 |
++ if (is_gcm(cryp)) |
7348 |
++ cryp->gcm_ctr++; |
7349 |
+ } else { |
7350 |
+ /* Input FIFO IRQ: write data */ |
7351 |
+ stm32_cryp_irq_write_data(cryp); |
7352 |
+ } |
7353 |
+ } |
7354 |
+ |
7355 |
++ /* Mask useless interrupts */ |
7356 |
++ if (!cryp->payload_in && !cryp->header_in) |
7357 |
++ it_mask &= ~IMSCR_IN; |
7358 |
++ if (!cryp->payload_out) |
7359 |
++ it_mask &= ~IMSCR_OUT; |
7360 |
++ stm32_cryp_write(cryp, CRYP_IMSCR, it_mask); |
7361 |
++ |
7362 |
++ if (!cryp->payload_in && !cryp->header_in && !cryp->payload_out) |
7363 |
++ stm32_cryp_finish_req(cryp, 0); |
7364 |
++ |
7365 |
+ return IRQ_HANDLED; |
7366 |
+ } |
7367 |
+ |
7368 |
+@@ -1742,7 +1548,7 @@ static struct skcipher_alg crypto_algs[] = { |
7369 |
+ .base.cra_flags = CRYPTO_ALG_ASYNC, |
7370 |
+ .base.cra_blocksize = AES_BLOCK_SIZE, |
7371 |
+ .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), |
7372 |
+- .base.cra_alignmask = 0xf, |
7373 |
++ .base.cra_alignmask = 0, |
7374 |
+ .base.cra_module = THIS_MODULE, |
7375 |
+ |
7376 |
+ .init = stm32_cryp_init_tfm, |
7377 |
+@@ -1759,7 +1565,7 @@ static struct skcipher_alg crypto_algs[] = { |
7378 |
+ .base.cra_flags = CRYPTO_ALG_ASYNC, |
7379 |
+ .base.cra_blocksize = AES_BLOCK_SIZE, |
7380 |
+ .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), |
7381 |
+- .base.cra_alignmask = 0xf, |
7382 |
++ .base.cra_alignmask = 0, |
7383 |
+ .base.cra_module = THIS_MODULE, |
7384 |
+ |
7385 |
+ .init = stm32_cryp_init_tfm, |
7386 |
+@@ -1777,7 +1583,7 @@ static struct skcipher_alg crypto_algs[] = { |
7387 |
+ .base.cra_flags = CRYPTO_ALG_ASYNC, |
7388 |
+ .base.cra_blocksize = 1, |
7389 |
+ .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), |
7390 |
+- .base.cra_alignmask = 0xf, |
7391 |
++ .base.cra_alignmask = 0, |
7392 |
+ .base.cra_module = THIS_MODULE, |
7393 |
+ |
7394 |
+ .init = stm32_cryp_init_tfm, |
7395 |
+@@ -1795,7 +1601,7 @@ static struct skcipher_alg crypto_algs[] = { |
7396 |
+ .base.cra_flags = CRYPTO_ALG_ASYNC, |
7397 |
+ .base.cra_blocksize = DES_BLOCK_SIZE, |
7398 |
+ .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), |
7399 |
+- .base.cra_alignmask = 0xf, |
7400 |
++ .base.cra_alignmask = 0, |
7401 |
+ .base.cra_module = THIS_MODULE, |
7402 |
+ |
7403 |
+ .init = stm32_cryp_init_tfm, |
7404 |
+@@ -1812,7 +1618,7 @@ static struct skcipher_alg crypto_algs[] = { |
7405 |
+ .base.cra_flags = CRYPTO_ALG_ASYNC, |
7406 |
+ .base.cra_blocksize = DES_BLOCK_SIZE, |
7407 |
+ .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), |
7408 |
+- .base.cra_alignmask = 0xf, |
7409 |
++ .base.cra_alignmask = 0, |
7410 |
+ .base.cra_module = THIS_MODULE, |
7411 |
+ |
7412 |
+ .init = stm32_cryp_init_tfm, |
7413 |
+@@ -1830,7 +1636,7 @@ static struct skcipher_alg crypto_algs[] = { |
7414 |
+ .base.cra_flags = CRYPTO_ALG_ASYNC, |
7415 |
+ .base.cra_blocksize = DES_BLOCK_SIZE, |
7416 |
+ .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), |
7417 |
+- .base.cra_alignmask = 0xf, |
7418 |
++ .base.cra_alignmask = 0, |
7419 |
+ .base.cra_module = THIS_MODULE, |
7420 |
+ |
7421 |
+ .init = stm32_cryp_init_tfm, |
7422 |
+@@ -1847,7 +1653,7 @@ static struct skcipher_alg crypto_algs[] = { |
7423 |
+ .base.cra_flags = CRYPTO_ALG_ASYNC, |
7424 |
+ .base.cra_blocksize = DES_BLOCK_SIZE, |
7425 |
+ .base.cra_ctxsize = sizeof(struct stm32_cryp_ctx), |
7426 |
+- .base.cra_alignmask = 0xf, |
7427 |
++ .base.cra_alignmask = 0, |
7428 |
+ .base.cra_module = THIS_MODULE, |
7429 |
+ |
7430 |
+ .init = stm32_cryp_init_tfm, |
7431 |
+@@ -1877,7 +1683,7 @@ static struct aead_alg aead_algs[] = { |
7432 |
+ .cra_flags = CRYPTO_ALG_ASYNC, |
7433 |
+ .cra_blocksize = 1, |
7434 |
+ .cra_ctxsize = sizeof(struct stm32_cryp_ctx), |
7435 |
+- .cra_alignmask = 0xf, |
7436 |
++ .cra_alignmask = 0, |
7437 |
+ .cra_module = THIS_MODULE, |
7438 |
+ }, |
7439 |
+ }, |
7440 |
+@@ -1897,7 +1703,7 @@ static struct aead_alg aead_algs[] = { |
7441 |
+ .cra_flags = CRYPTO_ALG_ASYNC, |
7442 |
+ .cra_blocksize = 1, |
7443 |
+ .cra_ctxsize = sizeof(struct stm32_cryp_ctx), |
7444 |
+- .cra_alignmask = 0xf, |
7445 |
++ .cra_alignmask = 0, |
7446 |
+ .cra_module = THIS_MODULE, |
7447 |
+ }, |
7448 |
+ }, |
7449 |
+@@ -2025,8 +1831,6 @@ err_engine1: |
7450 |
+ list_del(&cryp->list); |
7451 |
+ spin_unlock(&cryp_list.lock); |
7452 |
+ |
7453 |
+- pm_runtime_disable(dev); |
7454 |
+- pm_runtime_put_noidle(dev); |
7455 |
+ pm_runtime_disable(dev); |
7456 |
+ pm_runtime_put_noidle(dev); |
7457 |
+ |
7458 |
+diff --git a/drivers/crypto/stm32/stm32-hash.c b/drivers/crypto/stm32/stm32-hash.c |
7459 |
+index 389de9e3302d5..d33006d43f761 100644 |
7460 |
+--- a/drivers/crypto/stm32/stm32-hash.c |
7461 |
++++ b/drivers/crypto/stm32/stm32-hash.c |
7462 |
+@@ -813,7 +813,7 @@ static void stm32_hash_finish_req(struct ahash_request *req, int err) |
7463 |
+ static int stm32_hash_hw_init(struct stm32_hash_dev *hdev, |
7464 |
+ struct stm32_hash_request_ctx *rctx) |
7465 |
+ { |
7466 |
+- pm_runtime_resume_and_get(hdev->dev); |
7467 |
++ pm_runtime_get_sync(hdev->dev); |
7468 |
+ |
7469 |
+ if (!(HASH_FLAGS_INIT & hdev->flags)) { |
7470 |
+ stm32_hash_write(hdev, HASH_CR, HASH_CR_INIT); |
7471 |
+@@ -962,7 +962,7 @@ static int stm32_hash_export(struct ahash_request *req, void *out) |
7472 |
+ u32 *preg; |
7473 |
+ unsigned int i; |
7474 |
+ |
7475 |
+- pm_runtime_resume_and_get(hdev->dev); |
7476 |
++ pm_runtime_get_sync(hdev->dev); |
7477 |
+ |
7478 |
+ while ((stm32_hash_read(hdev, HASH_SR) & HASH_SR_BUSY)) |
7479 |
+ cpu_relax(); |
7480 |
+@@ -1000,7 +1000,7 @@ static int stm32_hash_import(struct ahash_request *req, const void *in) |
7481 |
+ |
7482 |
+ preg = rctx->hw_context; |
7483 |
+ |
7484 |
+- pm_runtime_resume_and_get(hdev->dev); |
7485 |
++ pm_runtime_get_sync(hdev->dev); |
7486 |
+ |
7487 |
+ stm32_hash_write(hdev, HASH_IMR, *preg++); |
7488 |
+ stm32_hash_write(hdev, HASH_STR, *preg++); |
7489 |
+diff --git a/drivers/cxl/pmem.c b/drivers/cxl/pmem.c |
7490 |
+index 9652c3ee41e7f..2bb2f9a0499f7 100644 |
7491 |
+--- a/drivers/cxl/pmem.c |
7492 |
++++ b/drivers/cxl/pmem.c |
7493 |
+@@ -149,14 +149,24 @@ static void cxl_nvb_update_state(struct work_struct *work) |
7494 |
+ put_device(&cxl_nvb->dev); |
7495 |
+ } |
7496 |
+ |
7497 |
++static void cxl_nvdimm_bridge_state_work(struct cxl_nvdimm_bridge *cxl_nvb) |
7498 |
++{ |
7499 |
++ /* |
7500 |
++ * Take a reference that the workqueue will drop if new work |
7501 |
++ * gets queued. |
7502 |
++ */ |
7503 |
++ get_device(&cxl_nvb->dev); |
7504 |
++ if (!queue_work(cxl_pmem_wq, &cxl_nvb->state_work)) |
7505 |
++ put_device(&cxl_nvb->dev); |
7506 |
++} |
7507 |
++ |
7508 |
+ static void cxl_nvdimm_bridge_remove(struct device *dev) |
7509 |
+ { |
7510 |
+ struct cxl_nvdimm_bridge *cxl_nvb = to_cxl_nvdimm_bridge(dev); |
7511 |
+ |
7512 |
+ if (cxl_nvb->state == CXL_NVB_ONLINE) |
7513 |
+ cxl_nvb->state = CXL_NVB_OFFLINE; |
7514 |
+- if (queue_work(cxl_pmem_wq, &cxl_nvb->state_work)) |
7515 |
+- get_device(&cxl_nvb->dev); |
7516 |
++ cxl_nvdimm_bridge_state_work(cxl_nvb); |
7517 |
+ } |
7518 |
+ |
7519 |
+ static int cxl_nvdimm_bridge_probe(struct device *dev) |
7520 |
+@@ -177,8 +187,7 @@ static int cxl_nvdimm_bridge_probe(struct device *dev) |
7521 |
+ } |
7522 |
+ |
7523 |
+ cxl_nvb->state = CXL_NVB_ONLINE; |
7524 |
+- if (queue_work(cxl_pmem_wq, &cxl_nvb->state_work)) |
7525 |
+- get_device(&cxl_nvb->dev); |
7526 |
++ cxl_nvdimm_bridge_state_work(cxl_nvb); |
7527 |
+ |
7528 |
+ return 0; |
7529 |
+ } |
7530 |
+diff --git a/drivers/dma-buf/dma-fence-array.c b/drivers/dma-buf/dma-fence-array.c |
7531 |
+index d3fbd950be944..3e07f961e2f3d 100644 |
7532 |
+--- a/drivers/dma-buf/dma-fence-array.c |
7533 |
++++ b/drivers/dma-buf/dma-fence-array.c |
7534 |
+@@ -104,7 +104,11 @@ static bool dma_fence_array_signaled(struct dma_fence *fence) |
7535 |
+ { |
7536 |
+ struct dma_fence_array *array = to_dma_fence_array(fence); |
7537 |
+ |
7538 |
+- return atomic_read(&array->num_pending) <= 0; |
7539 |
++ if (atomic_read(&array->num_pending) > 0) |
7540 |
++ return false; |
7541 |
++ |
7542 |
++ dma_fence_array_clear_pending_error(array); |
7543 |
++ return true; |
7544 |
+ } |
7545 |
+ |
7546 |
+ static void dma_fence_array_release(struct dma_fence *fence) |
7547 |
+diff --git a/drivers/dma/at_xdmac.c b/drivers/dma/at_xdmac.c |
7548 |
+index e18abbd56fb51..8177aed160060 100644 |
7549 |
+--- a/drivers/dma/at_xdmac.c |
7550 |
++++ b/drivers/dma/at_xdmac.c |
7551 |
+@@ -99,6 +99,7 @@ |
7552 |
+ #define AT_XDMAC_CNDC_NDE (0x1 << 0) /* Channel x Next Descriptor Enable */ |
7553 |
+ #define AT_XDMAC_CNDC_NDSUP (0x1 << 1) /* Channel x Next Descriptor Source Update */ |
7554 |
+ #define AT_XDMAC_CNDC_NDDUP (0x1 << 2) /* Channel x Next Descriptor Destination Update */ |
7555 |
++#define AT_XDMAC_CNDC_NDVIEW_MASK GENMASK(28, 27) |
7556 |
+ #define AT_XDMAC_CNDC_NDVIEW_NDV0 (0x0 << 3) /* Channel x Next Descriptor View 0 */ |
7557 |
+ #define AT_XDMAC_CNDC_NDVIEW_NDV1 (0x1 << 3) /* Channel x Next Descriptor View 1 */ |
7558 |
+ #define AT_XDMAC_CNDC_NDVIEW_NDV2 (0x2 << 3) /* Channel x Next Descriptor View 2 */ |
7559 |
+@@ -252,15 +253,15 @@ struct at_xdmac { |
7560 |
+ |
7561 |
+ /* Linked List Descriptor */ |
7562 |
+ struct at_xdmac_lld { |
7563 |
+- dma_addr_t mbr_nda; /* Next Descriptor Member */ |
7564 |
+- u32 mbr_ubc; /* Microblock Control Member */ |
7565 |
+- dma_addr_t mbr_sa; /* Source Address Member */ |
7566 |
+- dma_addr_t mbr_da; /* Destination Address Member */ |
7567 |
+- u32 mbr_cfg; /* Configuration Register */ |
7568 |
+- u32 mbr_bc; /* Block Control Register */ |
7569 |
+- u32 mbr_ds; /* Data Stride Register */ |
7570 |
+- u32 mbr_sus; /* Source Microblock Stride Register */ |
7571 |
+- u32 mbr_dus; /* Destination Microblock Stride Register */ |
7572 |
++ u32 mbr_nda; /* Next Descriptor Member */ |
7573 |
++ u32 mbr_ubc; /* Microblock Control Member */ |
7574 |
++ u32 mbr_sa; /* Source Address Member */ |
7575 |
++ u32 mbr_da; /* Destination Address Member */ |
7576 |
++ u32 mbr_cfg; /* Configuration Register */ |
7577 |
++ u32 mbr_bc; /* Block Control Register */ |
7578 |
++ u32 mbr_ds; /* Data Stride Register */ |
7579 |
++ u32 mbr_sus; /* Source Microblock Stride Register */ |
7580 |
++ u32 mbr_dus; /* Destination Microblock Stride Register */ |
7581 |
+ }; |
7582 |
+ |
7583 |
+ /* 64-bit alignment needed to update CNDA and CUBC registers in an atomic way. */ |
7584 |
+@@ -385,9 +386,6 @@ static void at_xdmac_start_xfer(struct at_xdmac_chan *atchan, |
7585 |
+ |
7586 |
+ dev_vdbg(chan2dev(&atchan->chan), "%s: desc 0x%p\n", __func__, first); |
7587 |
+ |
7588 |
+- if (at_xdmac_chan_is_enabled(atchan)) |
7589 |
+- return; |
7590 |
+- |
7591 |
+ /* Set transfer as active to not try to start it again. */ |
7592 |
+ first->active_xfer = true; |
7593 |
+ |
7594 |
+@@ -405,7 +403,8 @@ static void at_xdmac_start_xfer(struct at_xdmac_chan *atchan, |
7595 |
+ */ |
7596 |
+ if (at_xdmac_chan_is_cyclic(atchan)) |
7597 |
+ reg = AT_XDMAC_CNDC_NDVIEW_NDV1; |
7598 |
+- else if (first->lld.mbr_ubc & AT_XDMAC_MBR_UBC_NDV3) |
7599 |
++ else if ((first->lld.mbr_ubc & |
7600 |
++ AT_XDMAC_CNDC_NDVIEW_MASK) == AT_XDMAC_MBR_UBC_NDV3) |
7601 |
+ reg = AT_XDMAC_CNDC_NDVIEW_NDV3; |
7602 |
+ else |
7603 |
+ reg = AT_XDMAC_CNDC_NDVIEW_NDV2; |
7604 |
+@@ -476,13 +475,12 @@ static dma_cookie_t at_xdmac_tx_submit(struct dma_async_tx_descriptor *tx) |
7605 |
+ spin_lock_irqsave(&atchan->lock, irqflags); |
7606 |
+ cookie = dma_cookie_assign(tx); |
7607 |
+ |
7608 |
++ list_add_tail(&desc->xfer_node, &atchan->xfers_list); |
7609 |
++ spin_unlock_irqrestore(&atchan->lock, irqflags); |
7610 |
++ |
7611 |
+ dev_vdbg(chan2dev(tx->chan), "%s: atchan 0x%p, add desc 0x%p to xfers_list\n", |
7612 |
+ __func__, atchan, desc); |
7613 |
+- list_add_tail(&desc->xfer_node, &atchan->xfers_list); |
7614 |
+- if (list_is_singular(&atchan->xfers_list)) |
7615 |
+- at_xdmac_start_xfer(atchan, desc); |
7616 |
+ |
7617 |
+- spin_unlock_irqrestore(&atchan->lock, irqflags); |
7618 |
+ return cookie; |
7619 |
+ } |
7620 |
+ |
7621 |
+@@ -1623,14 +1621,17 @@ static void at_xdmac_handle_cyclic(struct at_xdmac_chan *atchan) |
7622 |
+ struct at_xdmac_desc *desc; |
7623 |
+ struct dma_async_tx_descriptor *txd; |
7624 |
+ |
7625 |
+- if (!list_empty(&atchan->xfers_list)) { |
7626 |
+- desc = list_first_entry(&atchan->xfers_list, |
7627 |
+- struct at_xdmac_desc, xfer_node); |
7628 |
+- txd = &desc->tx_dma_desc; |
7629 |
+- |
7630 |
+- if (txd->flags & DMA_PREP_INTERRUPT) |
7631 |
+- dmaengine_desc_get_callback_invoke(txd, NULL); |
7632 |
++ spin_lock_irq(&atchan->lock); |
7633 |
++ if (list_empty(&atchan->xfers_list)) { |
7634 |
++ spin_unlock_irq(&atchan->lock); |
7635 |
++ return; |
7636 |
+ } |
7637 |
++ desc = list_first_entry(&atchan->xfers_list, struct at_xdmac_desc, |
7638 |
++ xfer_node); |
7639 |
++ spin_unlock_irq(&atchan->lock); |
7640 |
++ txd = &desc->tx_dma_desc; |
7641 |
++ if (txd->flags & DMA_PREP_INTERRUPT) |
7642 |
++ dmaengine_desc_get_callback_invoke(txd, NULL); |
7643 |
+ } |
7644 |
+ |
7645 |
+ static void at_xdmac_handle_error(struct at_xdmac_chan *atchan) |
7646 |
+@@ -1784,11 +1785,9 @@ static void at_xdmac_issue_pending(struct dma_chan *chan) |
7647 |
+ |
7648 |
+ dev_dbg(chan2dev(&atchan->chan), "%s\n", __func__); |
7649 |
+ |
7650 |
+- if (!at_xdmac_chan_is_cyclic(atchan)) { |
7651 |
+- spin_lock_irqsave(&atchan->lock, flags); |
7652 |
+- at_xdmac_advance_work(atchan); |
7653 |
+- spin_unlock_irqrestore(&atchan->lock, flags); |
7654 |
+- } |
7655 |
++ spin_lock_irqsave(&atchan->lock, flags); |
7656 |
++ at_xdmac_advance_work(atchan); |
7657 |
++ spin_unlock_irqrestore(&atchan->lock, flags); |
7658 |
+ |
7659 |
+ return; |
7660 |
+ } |
7661 |
+diff --git a/drivers/dma/idxd/device.c b/drivers/dma/idxd/device.c |
7662 |
+index 419b206f8a42d..b468ca36d3a01 100644 |
7663 |
+--- a/drivers/dma/idxd/device.c |
7664 |
++++ b/drivers/dma/idxd/device.c |
7665 |
+@@ -394,8 +394,6 @@ static void idxd_wq_disable_cleanup(struct idxd_wq *wq) |
7666 |
+ lockdep_assert_held(&wq->wq_lock); |
7667 |
+ memset(wq->wqcfg, 0, idxd->wqcfg_size); |
7668 |
+ wq->type = IDXD_WQT_NONE; |
7669 |
+- wq->size = 0; |
7670 |
+- wq->group = NULL; |
7671 |
+ wq->threshold = 0; |
7672 |
+ wq->priority = 0; |
7673 |
+ wq->ats_dis = 0; |
7674 |
+@@ -404,6 +402,15 @@ static void idxd_wq_disable_cleanup(struct idxd_wq *wq) |
7675 |
+ memset(wq->name, 0, WQ_NAME_SIZE); |
7676 |
+ } |
7677 |
+ |
7678 |
++static void idxd_wq_device_reset_cleanup(struct idxd_wq *wq) |
7679 |
++{ |
7680 |
++ lockdep_assert_held(&wq->wq_lock); |
7681 |
++ |
7682 |
++ idxd_wq_disable_cleanup(wq); |
7683 |
++ wq->size = 0; |
7684 |
++ wq->group = NULL; |
7685 |
++} |
7686 |
++ |
7687 |
+ static void idxd_wq_ref_release(struct percpu_ref *ref) |
7688 |
+ { |
7689 |
+ struct idxd_wq *wq = container_of(ref, struct idxd_wq, wq_active); |
7690 |
+@@ -711,6 +718,7 @@ static void idxd_device_wqs_clear_state(struct idxd_device *idxd) |
7691 |
+ |
7692 |
+ if (wq->state == IDXD_WQ_ENABLED) { |
7693 |
+ idxd_wq_disable_cleanup(wq); |
7694 |
++ idxd_wq_device_reset_cleanup(wq); |
7695 |
+ wq->state = IDXD_WQ_DISABLED; |
7696 |
+ } |
7697 |
+ } |
7698 |
+diff --git a/drivers/dma/mmp_pdma.c b/drivers/dma/mmp_pdma.c |
7699 |
+index 89f1814ff27a0..26d11885c50ec 100644 |
7700 |
+--- a/drivers/dma/mmp_pdma.c |
7701 |
++++ b/drivers/dma/mmp_pdma.c |
7702 |
+@@ -727,12 +727,6 @@ static int mmp_pdma_config_write(struct dma_chan *dchan, |
7703 |
+ |
7704 |
+ chan->dir = direction; |
7705 |
+ chan->dev_addr = addr; |
7706 |
+- /* FIXME: drivers should be ported over to use the filter |
7707 |
+- * function. Once that's done, the following two lines can |
7708 |
+- * be removed. |
7709 |
+- */ |
7710 |
+- if (cfg->slave_id) |
7711 |
+- chan->drcmr = cfg->slave_id; |
7712 |
+ |
7713 |
+ return 0; |
7714 |
+ } |
7715 |
+diff --git a/drivers/dma/pxa_dma.c b/drivers/dma/pxa_dma.c |
7716 |
+index 4a2a796e348c1..aa6e552249ab9 100644 |
7717 |
+--- a/drivers/dma/pxa_dma.c |
7718 |
++++ b/drivers/dma/pxa_dma.c |
7719 |
+@@ -910,13 +910,6 @@ static void pxad_get_config(struct pxad_chan *chan, |
7720 |
+ *dcmd |= PXA_DCMD_BURST16; |
7721 |
+ else if (maxburst == 32) |
7722 |
+ *dcmd |= PXA_DCMD_BURST32; |
7723 |
+- |
7724 |
+- /* FIXME: drivers should be ported over to use the filter |
7725 |
+- * function. Once that's done, the following two lines can |
7726 |
+- * be removed. |
7727 |
+- */ |
7728 |
+- if (chan->cfg.slave_id) |
7729 |
+- chan->drcmr = chan->cfg.slave_id; |
7730 |
+ } |
7731 |
+ |
7732 |
+ static struct dma_async_tx_descriptor * |
7733 |
+diff --git a/drivers/dma/stm32-mdma.c b/drivers/dma/stm32-mdma.c |
7734 |
+index 18cbd1e43c2e8..f17a9ffcd00da 100644 |
7735 |
+--- a/drivers/dma/stm32-mdma.c |
7736 |
++++ b/drivers/dma/stm32-mdma.c |
7737 |
+@@ -184,7 +184,7 @@ |
7738 |
+ #define STM32_MDMA_CTBR(x) (0x68 + 0x40 * (x)) |
7739 |
+ #define STM32_MDMA_CTBR_DBUS BIT(17) |
7740 |
+ #define STM32_MDMA_CTBR_SBUS BIT(16) |
7741 |
+-#define STM32_MDMA_CTBR_TSEL_MASK GENMASK(7, 0) |
7742 |
++#define STM32_MDMA_CTBR_TSEL_MASK GENMASK(5, 0) |
7743 |
+ #define STM32_MDMA_CTBR_TSEL(n) STM32_MDMA_SET(n, \ |
7744 |
+ STM32_MDMA_CTBR_TSEL_MASK) |
7745 |
+ |
7746 |
+diff --git a/drivers/dma/uniphier-xdmac.c b/drivers/dma/uniphier-xdmac.c |
7747 |
+index d6b8a202474f4..290836b7e1be2 100644 |
7748 |
+--- a/drivers/dma/uniphier-xdmac.c |
7749 |
++++ b/drivers/dma/uniphier-xdmac.c |
7750 |
+@@ -131,8 +131,9 @@ uniphier_xdmac_next_desc(struct uniphier_xdmac_chan *xc) |
7751 |
+ static void uniphier_xdmac_chan_start(struct uniphier_xdmac_chan *xc, |
7752 |
+ struct uniphier_xdmac_desc *xd) |
7753 |
+ { |
7754 |
+- u32 src_mode, src_addr, src_width; |
7755 |
+- u32 dst_mode, dst_addr, dst_width; |
7756 |
++ u32 src_mode, src_width; |
7757 |
++ u32 dst_mode, dst_width; |
7758 |
++ dma_addr_t src_addr, dst_addr; |
7759 |
+ u32 val, its, tnum; |
7760 |
+ enum dma_slave_buswidth buswidth; |
7761 |
+ |
7762 |
+diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c |
7763 |
+index 7d08627e738b3..a5486d86fdd2f 100644 |
7764 |
+--- a/drivers/edac/synopsys_edac.c |
7765 |
++++ b/drivers/edac/synopsys_edac.c |
7766 |
+@@ -1352,8 +1352,7 @@ static int mc_probe(struct platform_device *pdev) |
7767 |
+ } |
7768 |
+ } |
7769 |
+ |
7770 |
+- if (of_device_is_compatible(pdev->dev.of_node, |
7771 |
+- "xlnx,zynqmp-ddrc-2.40a")) |
7772 |
++ if (priv->p_data->quirks & DDR_ECC_INTR_SUPPORT) |
7773 |
+ setup_address_map(priv); |
7774 |
+ #endif |
7775 |
+ |
7776 |
+diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c |
7777 |
+index b19ce1a83f91a..b2c829e95bd14 100644 |
7778 |
+--- a/drivers/firmware/efi/efi-init.c |
7779 |
++++ b/drivers/firmware/efi/efi-init.c |
7780 |
+@@ -235,6 +235,11 @@ void __init efi_init(void) |
7781 |
+ } |
7782 |
+ |
7783 |
+ reserve_regions(); |
7784 |
++ /* |
7785 |
++ * For memblock manipulation, the cap should come after the memblock_add(). |
7786 |
++ * And now, memblock is fully populated, it is time to do capping. |
7787 |
++ */ |
7788 |
++ early_init_dt_check_for_usable_mem_range(); |
7789 |
+ efi_esrt_init(); |
7790 |
+ efi_mokvar_table_init(); |
7791 |
+ |
7792 |
+diff --git a/drivers/firmware/google/Kconfig b/drivers/firmware/google/Kconfig |
7793 |
+index 97968aece54f8..931544c9f63d4 100644 |
7794 |
+--- a/drivers/firmware/google/Kconfig |
7795 |
++++ b/drivers/firmware/google/Kconfig |
7796 |
+@@ -3,9 +3,9 @@ menuconfig GOOGLE_FIRMWARE |
7797 |
+ bool "Google Firmware Drivers" |
7798 |
+ default n |
7799 |
+ help |
7800 |
+- These firmware drivers are used by Google's servers. They are |
7801 |
+- only useful if you are working directly on one of their |
7802 |
+- proprietary servers. If in doubt, say "N". |
7803 |
++ These firmware drivers are used by Google servers, |
7804 |
++ Chromebooks and other devices using coreboot firmware. |
7805 |
++ If in doubt, say "N". |
7806 |
+ |
7807 |
+ if GOOGLE_FIRMWARE |
7808 |
+ |
7809 |
+diff --git a/drivers/firmware/sysfb_simplefb.c b/drivers/firmware/sysfb_simplefb.c |
7810 |
+index b86761904949c..303a491e520d1 100644 |
7811 |
+--- a/drivers/firmware/sysfb_simplefb.c |
7812 |
++++ b/drivers/firmware/sysfb_simplefb.c |
7813 |
+@@ -113,12 +113,16 @@ __init int sysfb_create_simplefb(const struct screen_info *si, |
7814 |
+ sysfb_apply_efi_quirks(pd); |
7815 |
+ |
7816 |
+ ret = platform_device_add_resources(pd, &res, 1); |
7817 |
+- if (ret) |
7818 |
++ if (ret) { |
7819 |
++ platform_device_put(pd); |
7820 |
+ return ret; |
7821 |
++ } |
7822 |
+ |
7823 |
+ ret = platform_device_add_data(pd, mode, sizeof(*mode)); |
7824 |
+- if (ret) |
7825 |
++ if (ret) { |
7826 |
++ platform_device_put(pd); |
7827 |
+ return ret; |
7828 |
++ } |
7829 |
+ |
7830 |
+ return platform_device_add(pd); |
7831 |
+ } |
7832 |
+diff --git a/drivers/gpio/gpio-aspeed-sgpio.c b/drivers/gpio/gpio-aspeed-sgpio.c |
7833 |
+index b3a9b8488f11d..454cefbeecf0e 100644 |
7834 |
+--- a/drivers/gpio/gpio-aspeed-sgpio.c |
7835 |
++++ b/drivers/gpio/gpio-aspeed-sgpio.c |
7836 |
+@@ -31,7 +31,7 @@ struct aspeed_sgpio { |
7837 |
+ struct gpio_chip chip; |
7838 |
+ struct irq_chip intc; |
7839 |
+ struct clk *pclk; |
7840 |
+- spinlock_t lock; |
7841 |
++ raw_spinlock_t lock; |
7842 |
+ void __iomem *base; |
7843 |
+ int irq; |
7844 |
+ }; |
7845 |
+@@ -173,12 +173,12 @@ static int aspeed_sgpio_get(struct gpio_chip *gc, unsigned int offset) |
7846 |
+ enum aspeed_sgpio_reg reg; |
7847 |
+ int rc = 0; |
7848 |
+ |
7849 |
+- spin_lock_irqsave(&gpio->lock, flags); |
7850 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
7851 |
+ |
7852 |
+ reg = aspeed_sgpio_is_input(offset) ? reg_val : reg_rdata; |
7853 |
+ rc = !!(ioread32(bank_reg(gpio, bank, reg)) & GPIO_BIT(offset)); |
7854 |
+ |
7855 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
7856 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
7857 |
+ |
7858 |
+ return rc; |
7859 |
+ } |
7860 |
+@@ -215,11 +215,11 @@ static void aspeed_sgpio_set(struct gpio_chip *gc, unsigned int offset, int val) |
7861 |
+ struct aspeed_sgpio *gpio = gpiochip_get_data(gc); |
7862 |
+ unsigned long flags; |
7863 |
+ |
7864 |
+- spin_lock_irqsave(&gpio->lock, flags); |
7865 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
7866 |
+ |
7867 |
+ sgpio_set_value(gc, offset, val); |
7868 |
+ |
7869 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
7870 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
7871 |
+ } |
7872 |
+ |
7873 |
+ static int aspeed_sgpio_dir_in(struct gpio_chip *gc, unsigned int offset) |
7874 |
+@@ -236,9 +236,9 @@ static int aspeed_sgpio_dir_out(struct gpio_chip *gc, unsigned int offset, int v |
7875 |
+ /* No special action is required for setting the direction; we'll |
7876 |
+ * error-out in sgpio_set_value if this isn't an output GPIO */ |
7877 |
+ |
7878 |
+- spin_lock_irqsave(&gpio->lock, flags); |
7879 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
7880 |
+ rc = sgpio_set_value(gc, offset, val); |
7881 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
7882 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
7883 |
+ |
7884 |
+ return rc; |
7885 |
+ } |
7886 |
+@@ -277,11 +277,11 @@ static void aspeed_sgpio_irq_ack(struct irq_data *d) |
7887 |
+ |
7888 |
+ status_addr = bank_reg(gpio, bank, reg_irq_status); |
7889 |
+ |
7890 |
+- spin_lock_irqsave(&gpio->lock, flags); |
7891 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
7892 |
+ |
7893 |
+ iowrite32(bit, status_addr); |
7894 |
+ |
7895 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
7896 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
7897 |
+ } |
7898 |
+ |
7899 |
+ static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set) |
7900 |
+@@ -296,7 +296,7 @@ static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set) |
7901 |
+ irqd_to_aspeed_sgpio_data(d, &gpio, &bank, &bit, &offset); |
7902 |
+ addr = bank_reg(gpio, bank, reg_irq_enable); |
7903 |
+ |
7904 |
+- spin_lock_irqsave(&gpio->lock, flags); |
7905 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
7906 |
+ |
7907 |
+ reg = ioread32(addr); |
7908 |
+ if (set) |
7909 |
+@@ -306,7 +306,7 @@ static void aspeed_sgpio_irq_set_mask(struct irq_data *d, bool set) |
7910 |
+ |
7911 |
+ iowrite32(reg, addr); |
7912 |
+ |
7913 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
7914 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
7915 |
+ } |
7916 |
+ |
7917 |
+ static void aspeed_sgpio_irq_mask(struct irq_data *d) |
7918 |
+@@ -355,7 +355,7 @@ static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type) |
7919 |
+ return -EINVAL; |
7920 |
+ } |
7921 |
+ |
7922 |
+- spin_lock_irqsave(&gpio->lock, flags); |
7923 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
7924 |
+ |
7925 |
+ addr = bank_reg(gpio, bank, reg_irq_type0); |
7926 |
+ reg = ioread32(addr); |
7927 |
+@@ -372,7 +372,7 @@ static int aspeed_sgpio_set_type(struct irq_data *d, unsigned int type) |
7928 |
+ reg = (reg & ~bit) | type2; |
7929 |
+ iowrite32(reg, addr); |
7930 |
+ |
7931 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
7932 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
7933 |
+ |
7934 |
+ irq_set_handler_locked(d, handler); |
7935 |
+ |
7936 |
+@@ -467,7 +467,7 @@ static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip, |
7937 |
+ |
7938 |
+ reg = bank_reg(gpio, to_bank(offset), reg_tolerance); |
7939 |
+ |
7940 |
+- spin_lock_irqsave(&gpio->lock, flags); |
7941 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
7942 |
+ |
7943 |
+ val = readl(reg); |
7944 |
+ |
7945 |
+@@ -478,7 +478,7 @@ static int aspeed_sgpio_reset_tolerance(struct gpio_chip *chip, |
7946 |
+ |
7947 |
+ writel(val, reg); |
7948 |
+ |
7949 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
7950 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
7951 |
+ |
7952 |
+ return 0; |
7953 |
+ } |
7954 |
+@@ -575,7 +575,7 @@ static int __init aspeed_sgpio_probe(struct platform_device *pdev) |
7955 |
+ iowrite32(FIELD_PREP(ASPEED_SGPIO_CLK_DIV_MASK, sgpio_clk_div) | gpio_cnt_regval | |
7956 |
+ ASPEED_SGPIO_ENABLE, gpio->base + ASPEED_SGPIO_CTRL); |
7957 |
+ |
7958 |
+- spin_lock_init(&gpio->lock); |
7959 |
++ raw_spin_lock_init(&gpio->lock); |
7960 |
+ |
7961 |
+ gpio->chip.parent = &pdev->dev; |
7962 |
+ gpio->chip.ngpio = nr_gpios * 2; |
7963 |
+diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c |
7964 |
+index 3c8f20c57695f..318a7d95a1a8b 100644 |
7965 |
+--- a/drivers/gpio/gpio-aspeed.c |
7966 |
++++ b/drivers/gpio/gpio-aspeed.c |
7967 |
+@@ -53,7 +53,7 @@ struct aspeed_gpio_config { |
7968 |
+ struct aspeed_gpio { |
7969 |
+ struct gpio_chip chip; |
7970 |
+ struct irq_chip irqc; |
7971 |
+- spinlock_t lock; |
7972 |
++ raw_spinlock_t lock; |
7973 |
+ void __iomem *base; |
7974 |
+ int irq; |
7975 |
+ const struct aspeed_gpio_config *config; |
7976 |
+@@ -413,14 +413,14 @@ static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, |
7977 |
+ unsigned long flags; |
7978 |
+ bool copro; |
7979 |
+ |
7980 |
+- spin_lock_irqsave(&gpio->lock, flags); |
7981 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
7982 |
+ copro = aspeed_gpio_copro_request(gpio, offset); |
7983 |
+ |
7984 |
+ __aspeed_gpio_set(gc, offset, val); |
7985 |
+ |
7986 |
+ if (copro) |
7987 |
+ aspeed_gpio_copro_release(gpio, offset); |
7988 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
7989 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
7990 |
+ } |
7991 |
+ |
7992 |
+ static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset) |
7993 |
+@@ -435,7 +435,7 @@ static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset) |
7994 |
+ if (!have_input(gpio, offset)) |
7995 |
+ return -ENOTSUPP; |
7996 |
+ |
7997 |
+- spin_lock_irqsave(&gpio->lock, flags); |
7998 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
7999 |
+ |
8000 |
+ reg = ioread32(addr); |
8001 |
+ reg &= ~GPIO_BIT(offset); |
8002 |
+@@ -445,7 +445,7 @@ static int aspeed_gpio_dir_in(struct gpio_chip *gc, unsigned int offset) |
8003 |
+ if (copro) |
8004 |
+ aspeed_gpio_copro_release(gpio, offset); |
8005 |
+ |
8006 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
8007 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
8008 |
+ |
8009 |
+ return 0; |
8010 |
+ } |
8011 |
+@@ -463,7 +463,7 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc, |
8012 |
+ if (!have_output(gpio, offset)) |
8013 |
+ return -ENOTSUPP; |
8014 |
+ |
8015 |
+- spin_lock_irqsave(&gpio->lock, flags); |
8016 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
8017 |
+ |
8018 |
+ reg = ioread32(addr); |
8019 |
+ reg |= GPIO_BIT(offset); |
8020 |
+@@ -474,7 +474,7 @@ static int aspeed_gpio_dir_out(struct gpio_chip *gc, |
8021 |
+ |
8022 |
+ if (copro) |
8023 |
+ aspeed_gpio_copro_release(gpio, offset); |
8024 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
8025 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
8026 |
+ |
8027 |
+ return 0; |
8028 |
+ } |
8029 |
+@@ -492,11 +492,11 @@ static int aspeed_gpio_get_direction(struct gpio_chip *gc, unsigned int offset) |
8030 |
+ if (!have_output(gpio, offset)) |
8031 |
+ return GPIO_LINE_DIRECTION_IN; |
8032 |
+ |
8033 |
+- spin_lock_irqsave(&gpio->lock, flags); |
8034 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
8035 |
+ |
8036 |
+ val = ioread32(bank_reg(gpio, bank, reg_dir)) & GPIO_BIT(offset); |
8037 |
+ |
8038 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
8039 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
8040 |
+ |
8041 |
+ return val ? GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN; |
8042 |
+ } |
8043 |
+@@ -539,14 +539,14 @@ static void aspeed_gpio_irq_ack(struct irq_data *d) |
8044 |
+ |
8045 |
+ status_addr = bank_reg(gpio, bank, reg_irq_status); |
8046 |
+ |
8047 |
+- spin_lock_irqsave(&gpio->lock, flags); |
8048 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
8049 |
+ copro = aspeed_gpio_copro_request(gpio, offset); |
8050 |
+ |
8051 |
+ iowrite32(bit, status_addr); |
8052 |
+ |
8053 |
+ if (copro) |
8054 |
+ aspeed_gpio_copro_release(gpio, offset); |
8055 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
8056 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
8057 |
+ } |
8058 |
+ |
8059 |
+ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set) |
8060 |
+@@ -565,7 +565,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set) |
8061 |
+ |
8062 |
+ addr = bank_reg(gpio, bank, reg_irq_enable); |
8063 |
+ |
8064 |
+- spin_lock_irqsave(&gpio->lock, flags); |
8065 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
8066 |
+ copro = aspeed_gpio_copro_request(gpio, offset); |
8067 |
+ |
8068 |
+ reg = ioread32(addr); |
8069 |
+@@ -577,7 +577,7 @@ static void aspeed_gpio_irq_set_mask(struct irq_data *d, bool set) |
8070 |
+ |
8071 |
+ if (copro) |
8072 |
+ aspeed_gpio_copro_release(gpio, offset); |
8073 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
8074 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
8075 |
+ } |
8076 |
+ |
8077 |
+ static void aspeed_gpio_irq_mask(struct irq_data *d) |
8078 |
+@@ -629,7 +629,7 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type) |
8079 |
+ return -EINVAL; |
8080 |
+ } |
8081 |
+ |
8082 |
+- spin_lock_irqsave(&gpio->lock, flags); |
8083 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
8084 |
+ copro = aspeed_gpio_copro_request(gpio, offset); |
8085 |
+ |
8086 |
+ addr = bank_reg(gpio, bank, reg_irq_type0); |
8087 |
+@@ -649,7 +649,7 @@ static int aspeed_gpio_set_type(struct irq_data *d, unsigned int type) |
8088 |
+ |
8089 |
+ if (copro) |
8090 |
+ aspeed_gpio_copro_release(gpio, offset); |
8091 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
8092 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
8093 |
+ |
8094 |
+ irq_set_handler_locked(d, handler); |
8095 |
+ |
8096 |
+@@ -716,7 +716,7 @@ static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip, |
8097 |
+ |
8098 |
+ treg = bank_reg(gpio, to_bank(offset), reg_tolerance); |
8099 |
+ |
8100 |
+- spin_lock_irqsave(&gpio->lock, flags); |
8101 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
8102 |
+ copro = aspeed_gpio_copro_request(gpio, offset); |
8103 |
+ |
8104 |
+ val = readl(treg); |
8105 |
+@@ -730,7 +730,7 @@ static int aspeed_gpio_reset_tolerance(struct gpio_chip *chip, |
8106 |
+ |
8107 |
+ if (copro) |
8108 |
+ aspeed_gpio_copro_release(gpio, offset); |
8109 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
8110 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
8111 |
+ |
8112 |
+ return 0; |
8113 |
+ } |
8114 |
+@@ -856,7 +856,7 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset, |
8115 |
+ return rc; |
8116 |
+ } |
8117 |
+ |
8118 |
+- spin_lock_irqsave(&gpio->lock, flags); |
8119 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
8120 |
+ |
8121 |
+ if (timer_allocation_registered(gpio, offset)) { |
8122 |
+ rc = unregister_allocated_timer(gpio, offset); |
8123 |
+@@ -916,7 +916,7 @@ static int enable_debounce(struct gpio_chip *chip, unsigned int offset, |
8124 |
+ configure_timer(gpio, offset, i); |
8125 |
+ |
8126 |
+ out: |
8127 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
8128 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
8129 |
+ |
8130 |
+ return rc; |
8131 |
+ } |
8132 |
+@@ -927,13 +927,13 @@ static int disable_debounce(struct gpio_chip *chip, unsigned int offset) |
8133 |
+ unsigned long flags; |
8134 |
+ int rc; |
8135 |
+ |
8136 |
+- spin_lock_irqsave(&gpio->lock, flags); |
8137 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
8138 |
+ |
8139 |
+ rc = unregister_allocated_timer(gpio, offset); |
8140 |
+ if (!rc) |
8141 |
+ configure_timer(gpio, offset, 0); |
8142 |
+ |
8143 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
8144 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
8145 |
+ |
8146 |
+ return rc; |
8147 |
+ } |
8148 |
+@@ -1015,7 +1015,7 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc, |
8149 |
+ return -EINVAL; |
8150 |
+ bindex = offset >> 3; |
8151 |
+ |
8152 |
+- spin_lock_irqsave(&gpio->lock, flags); |
8153 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
8154 |
+ |
8155 |
+ /* Sanity check, this shouldn't happen */ |
8156 |
+ if (gpio->cf_copro_bankmap[bindex] == 0xff) { |
8157 |
+@@ -1036,7 +1036,7 @@ int aspeed_gpio_copro_grab_gpio(struct gpio_desc *desc, |
8158 |
+ if (bit) |
8159 |
+ *bit = GPIO_OFFSET(offset); |
8160 |
+ bail: |
8161 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
8162 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
8163 |
+ return rc; |
8164 |
+ } |
8165 |
+ EXPORT_SYMBOL_GPL(aspeed_gpio_copro_grab_gpio); |
8166 |
+@@ -1060,7 +1060,7 @@ int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc) |
8167 |
+ return -EINVAL; |
8168 |
+ bindex = offset >> 3; |
8169 |
+ |
8170 |
+- spin_lock_irqsave(&gpio->lock, flags); |
8171 |
++ raw_spin_lock_irqsave(&gpio->lock, flags); |
8172 |
+ |
8173 |
+ /* Sanity check, this shouldn't happen */ |
8174 |
+ if (gpio->cf_copro_bankmap[bindex] == 0) { |
8175 |
+@@ -1074,7 +1074,7 @@ int aspeed_gpio_copro_release_gpio(struct gpio_desc *desc) |
8176 |
+ aspeed_gpio_change_cmd_source(gpio, bank, bindex, |
8177 |
+ GPIO_CMDSRC_ARM); |
8178 |
+ bail: |
8179 |
+- spin_unlock_irqrestore(&gpio->lock, flags); |
8180 |
++ raw_spin_unlock_irqrestore(&gpio->lock, flags); |
8181 |
+ return rc; |
8182 |
+ } |
8183 |
+ EXPORT_SYMBOL_GPL(aspeed_gpio_copro_release_gpio); |
8184 |
+@@ -1148,7 +1148,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev) |
8185 |
+ if (IS_ERR(gpio->base)) |
8186 |
+ return PTR_ERR(gpio->base); |
8187 |
+ |
8188 |
+- spin_lock_init(&gpio->lock); |
8189 |
++ raw_spin_lock_init(&gpio->lock); |
8190 |
+ |
8191 |
+ gpio_id = of_match_node(aspeed_gpio_of_table, pdev->dev.of_node); |
8192 |
+ if (!gpio_id) |
8193 |
+diff --git a/drivers/gpio/gpio-idt3243x.c b/drivers/gpio/gpio-idt3243x.c |
8194 |
+index 50003ad2e5898..08493b05be2da 100644 |
8195 |
+--- a/drivers/gpio/gpio-idt3243x.c |
8196 |
++++ b/drivers/gpio/gpio-idt3243x.c |
8197 |
+@@ -164,8 +164,8 @@ static int idt_gpio_probe(struct platform_device *pdev) |
8198 |
+ return PTR_ERR(ctrl->pic); |
8199 |
+ |
8200 |
+ parent_irq = platform_get_irq(pdev, 0); |
8201 |
+- if (!parent_irq) |
8202 |
+- return -EINVAL; |
8203 |
++ if (parent_irq < 0) |
8204 |
++ return parent_irq; |
8205 |
+ |
8206 |
+ girq = &ctrl->gc.irq; |
8207 |
+ girq->chip = &idt_gpio_irqchip; |
8208 |
+diff --git a/drivers/gpio/gpio-mpc8xxx.c b/drivers/gpio/gpio-mpc8xxx.c |
8209 |
+index 70d6ae20b1da5..01634c8d27b38 100644 |
8210 |
+--- a/drivers/gpio/gpio-mpc8xxx.c |
8211 |
++++ b/drivers/gpio/gpio-mpc8xxx.c |
8212 |
+@@ -388,8 +388,8 @@ static int mpc8xxx_probe(struct platform_device *pdev) |
8213 |
+ } |
8214 |
+ |
8215 |
+ mpc8xxx_gc->irqn = platform_get_irq(pdev, 0); |
8216 |
+- if (!mpc8xxx_gc->irqn) |
8217 |
+- return 0; |
8218 |
++ if (mpc8xxx_gc->irqn < 0) |
8219 |
++ return mpc8xxx_gc->irqn; |
8220 |
+ |
8221 |
+ mpc8xxx_gc->irq = irq_domain_create_linear(fwnode, |
8222 |
+ MPC8XXX_GPIO_PINS, |
8223 |
+diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c |
8224 |
+index 47712b6903b51..d040c72fea582 100644 |
8225 |
+--- a/drivers/gpio/gpiolib-acpi.c |
8226 |
++++ b/drivers/gpio/gpiolib-acpi.c |
8227 |
+@@ -1059,10 +1059,17 @@ int acpi_dev_gpio_irq_get_by(struct acpi_device *adev, const char *name, int ind |
8228 |
+ irq_flags = acpi_dev_get_irq_type(info.triggering, |
8229 |
+ info.polarity); |
8230 |
+ |
8231 |
+- /* Set type if specified and different than the current one */ |
8232 |
+- if (irq_flags != IRQ_TYPE_NONE && |
8233 |
+- irq_flags != irq_get_trigger_type(irq)) |
8234 |
+- irq_set_irq_type(irq, irq_flags); |
8235 |
++ /* |
8236 |
++ * If the IRQ is not already in use then set type |
8237 |
++ * if specified and different than the current one. |
8238 |
++ */ |
8239 |
++ if (can_request_irq(irq, irq_flags)) { |
8240 |
++ if (irq_flags != IRQ_TYPE_NONE && |
8241 |
++ irq_flags != irq_get_trigger_type(irq)) |
8242 |
++ irq_set_irq_type(irq, irq_flags); |
8243 |
++ } else { |
8244 |
++ dev_dbg(&adev->dev, "IRQ %d already in use\n", irq); |
8245 |
++ } |
8246 |
+ |
8247 |
+ return irq; |
8248 |
+ } |
8249 |
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c |
8250 |
+index 0de66f59adb8a..df1f9b88a53f9 100644 |
8251 |
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c |
8252 |
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_connectors.c |
8253 |
+@@ -387,6 +387,9 @@ amdgpu_connector_lcd_native_mode(struct drm_encoder *encoder) |
8254 |
+ native_mode->vdisplay != 0 && |
8255 |
+ native_mode->clock != 0) { |
8256 |
+ mode = drm_mode_duplicate(dev, native_mode); |
8257 |
++ if (!mode) |
8258 |
++ return NULL; |
8259 |
++ |
8260 |
+ mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; |
8261 |
+ drm_mode_set_name(mode); |
8262 |
+ |
8263 |
+@@ -401,6 +404,9 @@ amdgpu_connector_lcd_native_mode(struct drm_encoder *encoder) |
8264 |
+ * simpler. |
8265 |
+ */ |
8266 |
+ mode = drm_cvt_mode(dev, native_mode->hdisplay, native_mode->vdisplay, 60, true, false, false); |
8267 |
++ if (!mode) |
8268 |
++ return NULL; |
8269 |
++ |
8270 |
+ mode->type = DRM_MODE_TYPE_PREFERRED | DRM_MODE_TYPE_DRIVER; |
8271 |
+ DRM_DEBUG_KMS("Adding cvt approximation of native panel mode %s\n", mode->name); |
8272 |
+ } |
8273 |
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c |
8274 |
+index cc2e0c9cfe0a1..4f3c62adccbde 100644 |
8275 |
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c |
8276 |
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_irq.c |
8277 |
+@@ -333,7 +333,6 @@ int amdgpu_irq_init(struct amdgpu_device *adev) |
8278 |
+ if (!amdgpu_device_has_dc_support(adev)) { |
8279 |
+ if (!adev->enable_virtual_display) |
8280 |
+ /* Disable vblank IRQs aggressively for power-saving */ |
8281 |
+- /* XXX: can this be enabled for DC? */ |
8282 |
+ adev_to_drm(adev)->vblank_disable_immediate = true; |
8283 |
+ |
8284 |
+ r = drm_vblank_init(adev_to_drm(adev), adev->mode_info.num_crtc); |
8285 |
+diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c |
8286 |
+index 9b41cb8c3de54..86e2090bbd6e0 100644 |
8287 |
+--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c |
8288 |
++++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c |
8289 |
+@@ -2207,12 +2207,16 @@ static int psp_hw_start(struct psp_context *psp) |
8290 |
+ return ret; |
8291 |
+ } |
8292 |
+ |
8293 |
++ if (amdgpu_sriov_vf(adev) && amdgpu_in_reset(adev)) |
8294 |
++ goto skip_pin_bo; |
8295 |
++ |
8296 |
+ ret = psp_tmr_init(psp); |
8297 |
+ if (ret) { |
8298 |
+ DRM_ERROR("PSP tmr init failed!\n"); |
8299 |
+ return ret; |
8300 |
+ } |
8301 |
+ |
8302 |
++skip_pin_bo: |
8303 |
+ /* |
8304 |
+ * For ASICs with DF Cstate management centralized |
8305 |
+ * to PMFW, TMR setup should be performed after PMFW |
8306 |
+diff --git a/drivers/gpu/drm/amd/amdgpu/cik.c b/drivers/gpu/drm/amd/amdgpu/cik.c |
8307 |
+index 54f28c075f214..f10ce740a29cc 100644 |
8308 |
+--- a/drivers/gpu/drm/amd/amdgpu/cik.c |
8309 |
++++ b/drivers/gpu/drm/amd/amdgpu/cik.c |
8310 |
+@@ -1428,6 +1428,10 @@ static int cik_asic_reset(struct amdgpu_device *adev) |
8311 |
+ { |
8312 |
+ int r; |
8313 |
+ |
8314 |
++ /* APUs don't have full asic reset */ |
8315 |
++ if (adev->flags & AMD_IS_APU) |
8316 |
++ return 0; |
8317 |
++ |
8318 |
+ if (cik_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) { |
8319 |
+ dev_info(adev->dev, "BACO reset\n"); |
8320 |
+ r = amdgpu_dpm_baco_reset(adev); |
8321 |
+diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c |
8322 |
+index e47104a1f5596..3c01be6610144 100644 |
8323 |
+--- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c |
8324 |
++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c |
8325 |
+@@ -1021,10 +1021,14 @@ static int gmc_v10_0_gart_enable(struct amdgpu_device *adev) |
8326 |
+ return -EINVAL; |
8327 |
+ } |
8328 |
+ |
8329 |
++ if (amdgpu_sriov_vf(adev) && amdgpu_in_reset(adev)) |
8330 |
++ goto skip_pin_bo; |
8331 |
++ |
8332 |
+ r = amdgpu_gart_table_vram_pin(adev); |
8333 |
+ if (r) |
8334 |
+ return r; |
8335 |
+ |
8336 |
++skip_pin_bo: |
8337 |
+ r = adev->gfxhub.funcs->gart_enable(adev); |
8338 |
+ if (r) |
8339 |
+ return r; |
8340 |
+diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c |
8341 |
+index 492ebed2915be..63b890f1e8afb 100644 |
8342 |
+--- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c |
8343 |
++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c |
8344 |
+@@ -515,10 +515,10 @@ static void gmc_v8_0_mc_program(struct amdgpu_device *adev) |
8345 |
+ static int gmc_v8_0_mc_init(struct amdgpu_device *adev) |
8346 |
+ { |
8347 |
+ int r; |
8348 |
++ u32 tmp; |
8349 |
+ |
8350 |
+ adev->gmc.vram_width = amdgpu_atombios_get_vram_width(adev); |
8351 |
+ if (!adev->gmc.vram_width) { |
8352 |
+- u32 tmp; |
8353 |
+ int chansize, numchan; |
8354 |
+ |
8355 |
+ /* Get VRAM informations */ |
8356 |
+@@ -562,8 +562,15 @@ static int gmc_v8_0_mc_init(struct amdgpu_device *adev) |
8357 |
+ adev->gmc.vram_width = numchan * chansize; |
8358 |
+ } |
8359 |
+ /* size in MB on si */ |
8360 |
+- adev->gmc.mc_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; |
8361 |
+- adev->gmc.real_vram_size = RREG32(mmCONFIG_MEMSIZE) * 1024ULL * 1024ULL; |
8362 |
++ tmp = RREG32(mmCONFIG_MEMSIZE); |
8363 |
++ /* some boards may have garbage in the upper 16 bits */ |
8364 |
++ if (tmp & 0xffff0000) { |
8365 |
++ DRM_INFO("Probable bad vram size: 0x%08x\n", tmp); |
8366 |
++ if (tmp & 0xffff) |
8367 |
++ tmp &= 0xffff; |
8368 |
++ } |
8369 |
++ adev->gmc.mc_vram_size = tmp * 1024ULL * 1024ULL; |
8370 |
++ adev->gmc.real_vram_size = adev->gmc.mc_vram_size; |
8371 |
+ |
8372 |
+ if (!(adev->flags & AMD_IS_APU)) { |
8373 |
+ r = amdgpu_device_resize_fb_bar(adev); |
8374 |
+diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c |
8375 |
+index 5551359d5dfdc..b5d93247237b1 100644 |
8376 |
+--- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c |
8377 |
++++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c |
8378 |
+@@ -1708,10 +1708,14 @@ static int gmc_v9_0_gart_enable(struct amdgpu_device *adev) |
8379 |
+ return -EINVAL; |
8380 |
+ } |
8381 |
+ |
8382 |
++ if (amdgpu_sriov_vf(adev) && amdgpu_in_reset(adev)) |
8383 |
++ goto skip_pin_bo; |
8384 |
++ |
8385 |
+ r = amdgpu_gart_table_vram_pin(adev); |
8386 |
+ if (r) |
8387 |
+ return r; |
8388 |
+ |
8389 |
++skip_pin_bo: |
8390 |
+ r = adev->gfxhub.funcs->gart_enable(adev); |
8391 |
+ if (r) |
8392 |
+ return r; |
8393 |
+diff --git a/drivers/gpu/drm/amd/amdgpu/vi.c b/drivers/gpu/drm/amd/amdgpu/vi.c |
8394 |
+index fe9a7cc8d9eb0..6645ebbd2696c 100644 |
8395 |
+--- a/drivers/gpu/drm/amd/amdgpu/vi.c |
8396 |
++++ b/drivers/gpu/drm/amd/amdgpu/vi.c |
8397 |
+@@ -956,6 +956,10 @@ static int vi_asic_reset(struct amdgpu_device *adev) |
8398 |
+ { |
8399 |
+ int r; |
8400 |
+ |
8401 |
++ /* APUs don't have full asic reset */ |
8402 |
++ if (adev->flags & AMD_IS_APU) |
8403 |
++ return 0; |
8404 |
++ |
8405 |
+ if (vi_asic_reset_method(adev) == AMD_RESET_METHOD_BACO) { |
8406 |
+ dev_info(adev->dev, "BACO reset\n"); |
8407 |
+ r = amdgpu_dpm_baco_reset(adev); |
8408 |
+diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c |
8409 |
+index 5a674235ae41a..830809b694dd9 100644 |
8410 |
+--- a/drivers/gpu/drm/amd/amdkfd/kfd_svm.c |
8411 |
++++ b/drivers/gpu/drm/amd/amdkfd/kfd_svm.c |
8412 |
+@@ -936,7 +936,7 @@ svm_range_split(struct svm_range *prange, uint64_t start, uint64_t last, |
8413 |
+ } |
8414 |
+ |
8415 |
+ static int |
8416 |
+-svm_range_split_tail(struct svm_range *prange, struct svm_range *new, |
8417 |
++svm_range_split_tail(struct svm_range *prange, |
8418 |
+ uint64_t new_last, struct list_head *insert_list) |
8419 |
+ { |
8420 |
+ struct svm_range *tail; |
8421 |
+@@ -948,7 +948,7 @@ svm_range_split_tail(struct svm_range *prange, struct svm_range *new, |
8422 |
+ } |
8423 |
+ |
8424 |
+ static int |
8425 |
+-svm_range_split_head(struct svm_range *prange, struct svm_range *new, |
8426 |
++svm_range_split_head(struct svm_range *prange, |
8427 |
+ uint64_t new_start, struct list_head *insert_list) |
8428 |
+ { |
8429 |
+ struct svm_range *head; |
8430 |
+@@ -1755,49 +1755,54 @@ static struct svm_range *svm_range_clone(struct svm_range *old) |
8431 |
+ } |
8432 |
+ |
8433 |
+ /** |
8434 |
+- * svm_range_handle_overlap - split overlap ranges |
8435 |
+- * @svms: svm range list header |
8436 |
+- * @new: range added with this attributes |
8437 |
+- * @start: range added start address, in pages |
8438 |
+- * @last: range last address, in pages |
8439 |
+- * @update_list: output, the ranges attributes are updated. For set_attr, this |
8440 |
+- * will do validation and map to GPUs. For unmap, this will be |
8441 |
+- * removed and unmap from GPUs |
8442 |
+- * @insert_list: output, the ranges will be inserted into svms, attributes are |
8443 |
+- * not changes. For set_attr, this will add into svms. |
8444 |
+- * @remove_list:output, the ranges will be removed from svms |
8445 |
+- * @left: the remaining range after overlap, For set_attr, this will be added |
8446 |
+- * as new range. |
8447 |
++ * svm_range_add - add svm range and handle overlap |
8448 |
++ * @p: the range add to this process svms |
8449 |
++ * @start: page size aligned |
8450 |
++ * @size: page size aligned |
8451 |
++ * @nattr: number of attributes |
8452 |
++ * @attrs: array of attributes |
8453 |
++ * @update_list: output, the ranges need validate and update GPU mapping |
8454 |
++ * @insert_list: output, the ranges need insert to svms |
8455 |
++ * @remove_list: output, the ranges are replaced and need remove from svms |
8456 |
+ * |
8457 |
+- * Total have 5 overlap cases. |
8458 |
++ * Check if the virtual address range has overlap with any existing ranges, |
8459 |
++ * split partly overlapping ranges and add new ranges in the gaps. All changes |
8460 |
++ * should be applied to the range_list and interval tree transactionally. If |
8461 |
++ * any range split or allocation fails, the entire update fails. Therefore any |
8462 |
++ * existing overlapping svm_ranges are cloned and the original svm_ranges left |
8463 |
++ * unchanged. |
8464 |
+ * |
8465 |
+- * This function handles overlap of an address interval with existing |
8466 |
+- * struct svm_ranges for applying new attributes. This may require |
8467 |
+- * splitting existing struct svm_ranges. All changes should be applied to |
8468 |
+- * the range_list and interval tree transactionally. If any split operation |
8469 |
+- * fails, the entire update fails. Therefore the existing overlapping |
8470 |
+- * svm_ranges are cloned and the original svm_ranges left unchanged. If the |
8471 |
+- * transaction succeeds, the modified clones are added and the originals |
8472 |
+- * freed. Otherwise the clones are removed and the old svm_ranges remain. |
8473 |
++ * If the transaction succeeds, the caller can update and insert clones and |
8474 |
++ * new ranges, then free the originals. |
8475 |
+ * |
8476 |
+- * Context: The caller must hold svms->lock |
8477 |
++ * Otherwise the caller can free the clones and new ranges, while the old |
8478 |
++ * svm_ranges remain unchanged. |
8479 |
++ * |
8480 |
++ * Context: Process context, caller must hold svms->lock |
8481 |
++ * |
8482 |
++ * Return: |
8483 |
++ * 0 - OK, otherwise error code |
8484 |
+ */ |
8485 |
+ static int |
8486 |
+-svm_range_handle_overlap(struct svm_range_list *svms, struct svm_range *new, |
8487 |
+- unsigned long start, unsigned long last, |
8488 |
+- struct list_head *update_list, |
8489 |
+- struct list_head *insert_list, |
8490 |
+- struct list_head *remove_list, |
8491 |
+- unsigned long *left) |
8492 |
++svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size, |
8493 |
++ uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs, |
8494 |
++ struct list_head *update_list, struct list_head *insert_list, |
8495 |
++ struct list_head *remove_list) |
8496 |
+ { |
8497 |
++ unsigned long last = start + size - 1UL; |
8498 |
++ struct svm_range_list *svms = &p->svms; |
8499 |
+ struct interval_tree_node *node; |
8500 |
++ struct svm_range new = {0}; |
8501 |
+ struct svm_range *prange; |
8502 |
+ struct svm_range *tmp; |
8503 |
+ int r = 0; |
8504 |
+ |
8505 |
++ pr_debug("svms 0x%p [0x%llx 0x%lx]\n", &p->svms, start, last); |
8506 |
++ |
8507 |
+ INIT_LIST_HEAD(update_list); |
8508 |
+ INIT_LIST_HEAD(insert_list); |
8509 |
+ INIT_LIST_HEAD(remove_list); |
8510 |
++ svm_range_apply_attrs(p, &new, nattr, attrs); |
8511 |
+ |
8512 |
+ node = interval_tree_iter_first(&svms->objects, start, last); |
8513 |
+ while (node) { |
8514 |
+@@ -1825,14 +1830,14 @@ svm_range_handle_overlap(struct svm_range_list *svms, struct svm_range *new, |
8515 |
+ |
8516 |
+ if (node->start < start) { |
8517 |
+ pr_debug("change old range start\n"); |
8518 |
+- r = svm_range_split_head(prange, new, start, |
8519 |
++ r = svm_range_split_head(prange, start, |
8520 |
+ insert_list); |
8521 |
+ if (r) |
8522 |
+ goto out; |
8523 |
+ } |
8524 |
+ if (node->last > last) { |
8525 |
+ pr_debug("change old range last\n"); |
8526 |
+- r = svm_range_split_tail(prange, new, last, |
8527 |
++ r = svm_range_split_tail(prange, last, |
8528 |
+ insert_list); |
8529 |
+ if (r) |
8530 |
+ goto out; |
8531 |
+@@ -1844,7 +1849,7 @@ svm_range_handle_overlap(struct svm_range_list *svms, struct svm_range *new, |
8532 |
+ prange = old; |
8533 |
+ } |
8534 |
+ |
8535 |
+- if (!svm_range_is_same_attrs(prange, new)) |
8536 |
++ if (!svm_range_is_same_attrs(prange, &new)) |
8537 |
+ list_add(&prange->update_list, update_list); |
8538 |
+ |
8539 |
+ /* insert a new node if needed */ |
8540 |
+@@ -1864,8 +1869,16 @@ svm_range_handle_overlap(struct svm_range_list *svms, struct svm_range *new, |
8541 |
+ start = next_start; |
8542 |
+ } |
8543 |
+ |
8544 |
+- if (left && start <= last) |
8545 |
+- *left = last - start + 1; |
8546 |
++ /* add a final range at the end if needed */ |
8547 |
++ if (start <= last) { |
8548 |
++ prange = svm_range_new(svms, start, last); |
8549 |
++ if (!prange) { |
8550 |
++ r = -ENOMEM; |
8551 |
++ goto out; |
8552 |
++ } |
8553 |
++ list_add(&prange->insert_list, insert_list); |
8554 |
++ list_add(&prange->update_list, update_list); |
8555 |
++ } |
8556 |
+ |
8557 |
+ out: |
8558 |
+ if (r) |
8559 |
+@@ -2693,59 +2706,6 @@ svm_range_is_valid(struct mm_struct *mm, uint64_t start, uint64_t size) |
8560 |
+ return true; |
8561 |
+ } |
8562 |
+ |
8563 |
+-/** |
8564 |
+- * svm_range_add - add svm range and handle overlap |
8565 |
+- * @p: the range add to this process svms |
8566 |
+- * @start: page size aligned |
8567 |
+- * @size: page size aligned |
8568 |
+- * @nattr: number of attributes |
8569 |
+- * @attrs: array of attributes |
8570 |
+- * @update_list: output, the ranges need validate and update GPU mapping |
8571 |
+- * @insert_list: output, the ranges need insert to svms |
8572 |
+- * @remove_list: output, the ranges are replaced and need remove from svms |
8573 |
+- * |
8574 |
+- * Check if the virtual address range has overlap with the registered ranges, |
8575 |
+- * split the overlapped range, copy and adjust pages address and vram nodes in |
8576 |
+- * old and new ranges. |
8577 |
+- * |
8578 |
+- * Context: Process context, caller must hold svms->lock |
8579 |
+- * |
8580 |
+- * Return: |
8581 |
+- * 0 - OK, otherwise error code |
8582 |
+- */ |
8583 |
+-static int |
8584 |
+-svm_range_add(struct kfd_process *p, uint64_t start, uint64_t size, |
8585 |
+- uint32_t nattr, struct kfd_ioctl_svm_attribute *attrs, |
8586 |
+- struct list_head *update_list, struct list_head *insert_list, |
8587 |
+- struct list_head *remove_list) |
8588 |
+-{ |
8589 |
+- uint64_t last = start + size - 1UL; |
8590 |
+- struct svm_range_list *svms; |
8591 |
+- struct svm_range new = {0}; |
8592 |
+- struct svm_range *prange; |
8593 |
+- unsigned long left = 0; |
8594 |
+- int r = 0; |
8595 |
+- |
8596 |
+- pr_debug("svms 0x%p [0x%llx 0x%llx]\n", &p->svms, start, last); |
8597 |
+- |
8598 |
+- svm_range_apply_attrs(p, &new, nattr, attrs); |
8599 |
+- |
8600 |
+- svms = &p->svms; |
8601 |
+- |
8602 |
+- r = svm_range_handle_overlap(svms, &new, start, last, update_list, |
8603 |
+- insert_list, remove_list, &left); |
8604 |
+- if (r) |
8605 |
+- return r; |
8606 |
+- |
8607 |
+- if (left) { |
8608 |
+- prange = svm_range_new(svms, last - left + 1, last); |
8609 |
+- list_add(&prange->insert_list, insert_list); |
8610 |
+- list_add(&prange->update_list, update_list); |
8611 |
+- } |
8612 |
+- |
8613 |
+- return 0; |
8614 |
+-} |
8615 |
+- |
8616 |
+ /** |
8617 |
+ * svm_range_best_prefetch_location - decide the best prefetch location |
8618 |
+ * @prange: svm range structure |
8619 |
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |
8620 |
+index 2fbaf6f869bfb..16556ae892d4a 100644 |
8621 |
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |
8622 |
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |
8623 |
+@@ -1279,6 +1279,9 @@ static int amdgpu_dm_init(struct amdgpu_device *adev) |
8624 |
+ adev_to_drm(adev)->mode_config.cursor_width = adev->dm.dc->caps.max_cursor_size; |
8625 |
+ adev_to_drm(adev)->mode_config.cursor_height = adev->dm.dc->caps.max_cursor_size; |
8626 |
+ |
8627 |
++ /* Disable vblank IRQs aggressively for power-saving */ |
8628 |
++ adev_to_drm(adev)->vblank_disable_immediate = true; |
8629 |
++ |
8630 |
+ if (drm_vblank_init(adev_to_drm(adev), adev->dm.display_indexes_num)) { |
8631 |
+ DRM_ERROR( |
8632 |
+ "amdgpu: failed to initialize sw for display support.\n"); |
8633 |
+diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |
8634 |
+index de9ec5ddb6c72..e94ddd5e7b638 100644 |
8635 |
+--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |
8636 |
++++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c |
8637 |
+@@ -2908,10 +2908,13 @@ static int crc_win_update_set(void *data, u64 val) |
8638 |
+ struct amdgpu_device *adev = drm_to_adev(new_crtc->dev); |
8639 |
+ struct crc_rd_work *crc_rd_wrk = adev->dm.crc_rd_wrk; |
8640 |
+ |
8641 |
++ if (!crc_rd_wrk) |
8642 |
++ return 0; |
8643 |
++ |
8644 |
+ if (val) { |
8645 |
+ spin_lock_irq(&adev_to_drm(adev)->event_lock); |
8646 |
+ spin_lock_irq(&crc_rd_wrk->crc_rd_work_lock); |
8647 |
+- if (crc_rd_wrk && crc_rd_wrk->crtc) { |
8648 |
++ if (crc_rd_wrk->crtc) { |
8649 |
+ old_crtc = crc_rd_wrk->crtc; |
8650 |
+ old_acrtc = to_amdgpu_crtc(old_crtc); |
8651 |
+ } |
8652 |
+diff --git a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c |
8653 |
+index bb31541f80723..6420527fe476c 100644 |
8654 |
+--- a/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c |
8655 |
++++ b/drivers/gpu/drm/amd/display/dc/clk_mgr/clk_mgr.c |
8656 |
+@@ -306,8 +306,7 @@ void dc_destroy_clk_mgr(struct clk_mgr *clk_mgr_base) |
8657 |
+ case FAMILY_NV: |
8658 |
+ if (ASICREV_IS_SIENNA_CICHLID_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { |
8659 |
+ dcn3_clk_mgr_destroy(clk_mgr); |
8660 |
+- } |
8661 |
+- if (ASICREV_IS_DIMGREY_CAVEFISH_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { |
8662 |
++ } else if (ASICREV_IS_DIMGREY_CAVEFISH_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { |
8663 |
+ dcn3_clk_mgr_destroy(clk_mgr); |
8664 |
+ } |
8665 |
+ if (ASICREV_IS_BEIGE_GOBY_P(clk_mgr_base->ctx->asic_id.hw_internal_rev)) { |
8666 |
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc.c b/drivers/gpu/drm/amd/display/dc/core/dc.c |
8667 |
+index c798c65d42765..1860ccc3f4f2c 100644 |
8668 |
+--- a/drivers/gpu/drm/amd/display/dc/core/dc.c |
8669 |
++++ b/drivers/gpu/drm/amd/display/dc/core/dc.c |
8670 |
+@@ -2703,7 +2703,8 @@ static void commit_planes_for_stream(struct dc *dc, |
8671 |
+ #endif |
8672 |
+ |
8673 |
+ if ((update_type != UPDATE_TYPE_FAST) && stream->update_flags.bits.dsc_changed) |
8674 |
+- if (top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { |
8675 |
++ if (top_pipe_to_program && |
8676 |
++ top_pipe_to_program->stream_res.tg->funcs->lock_doublebuffer_enable) { |
8677 |
+ if (should_use_dmub_lock(stream->link)) { |
8678 |
+ union dmub_hw_lock_flags hw_locks = { 0 }; |
8679 |
+ struct dmub_hw_lock_inst_flags inst_flags = { 0 }; |
8680 |
+diff --git a/drivers/gpu/drm/amd/display/dc/core/dc_link.c b/drivers/gpu/drm/amd/display/dc/core/dc_link.c |
8681 |
+index 1e44b13c1c7de..3c4205248efc2 100644 |
8682 |
+--- a/drivers/gpu/drm/amd/display/dc/core/dc_link.c |
8683 |
++++ b/drivers/gpu/drm/amd/display/dc/core/dc_link.c |
8684 |
+@@ -1696,6 +1696,8 @@ static void enable_stream_features(struct pipe_ctx *pipe_ctx) |
8685 |
+ union down_spread_ctrl old_downspread; |
8686 |
+ union down_spread_ctrl new_downspread; |
8687 |
+ |
8688 |
++ memset(&old_downspread, 0, sizeof(old_downspread)); |
8689 |
++ |
8690 |
+ core_link_read_dpcd(link, DP_DOWNSPREAD_CTRL, |
8691 |
+ &old_downspread.raw, sizeof(old_downspread)); |
8692 |
+ |
8693 |
+diff --git a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c |
8694 |
+index 0fe570717ba01..d4fe5352421fc 100644 |
8695 |
+--- a/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c |
8696 |
++++ b/drivers/gpu/drm/amd/display/dc/dcn31/dcn31_resource.c |
8697 |
+@@ -470,7 +470,8 @@ static const struct dcn30_afmt_mask afmt_mask = { |
8698 |
+ SE_DCN3_REG_LIST(id)\ |
8699 |
+ } |
8700 |
+ |
8701 |
+-static const struct dcn10_stream_enc_registers stream_enc_regs[] = { |
8702 |
++/* Some encoders won't be initialized here - but they're logical, not physical. */ |
8703 |
++static const struct dcn10_stream_enc_registers stream_enc_regs[ENGINE_ID_COUNT] = { |
8704 |
+ stream_enc_regs(0), |
8705 |
+ stream_enc_regs(1), |
8706 |
+ stream_enc_regs(2), |
8707 |
+diff --git a/drivers/gpu/drm/amd/pm/amdgpu_pm.c b/drivers/gpu/drm/amd/pm/amdgpu_pm.c |
8708 |
+index 249cb0aeb5ae4..32a0fd5e84b73 100644 |
8709 |
+--- a/drivers/gpu/drm/amd/pm/amdgpu_pm.c |
8710 |
++++ b/drivers/gpu/drm/amd/pm/amdgpu_pm.c |
8711 |
+@@ -2117,6 +2117,12 @@ static int default_attr_update(struct amdgpu_device *adev, struct amdgpu_device_ |
8712 |
+ } |
8713 |
+ } |
8714 |
+ |
8715 |
++ /* setting should not be allowed from VF */ |
8716 |
++ if (amdgpu_sriov_vf(adev)) { |
8717 |
++ dev_attr->attr.mode &= ~S_IWUGO; |
8718 |
++ dev_attr->store = NULL; |
8719 |
++ } |
8720 |
++ |
8721 |
+ #undef DEVICE_ATTR_IS |
8722 |
+ |
8723 |
+ return 0; |
8724 |
+diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c |
8725 |
+index cab6c8b92efd4..6a4f20fccf841 100644 |
8726 |
+--- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c |
8727 |
++++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c |
8728 |
+@@ -998,11 +998,21 @@ int analogix_dp_send_psr_spd(struct analogix_dp_device *dp, |
8729 |
+ if (!blocking) |
8730 |
+ return 0; |
8731 |
+ |
8732 |
++ /* |
8733 |
++ * db[1]!=0: entering PSR, wait for fully active remote frame buffer. |
8734 |
++ * db[1]==0: exiting PSR, wait for either |
8735 |
++ * (a) ACTIVE_RESYNC - the sink "must display the |
8736 |
++ * incoming active frames from the Source device with no visible |
8737 |
++ * glitches and/or artifacts", even though timings may still be |
8738 |
++ * re-synchronizing; or |
8739 |
++ * (b) INACTIVE - the transition is fully complete. |
8740 |
++ */ |
8741 |
+ ret = readx_poll_timeout(analogix_dp_get_psr_status, dp, psr_status, |
8742 |
+ psr_status >= 0 && |
8743 |
+ ((vsc->db[1] && psr_status == DP_PSR_SINK_ACTIVE_RFB) || |
8744 |
+- (!vsc->db[1] && psr_status == DP_PSR_SINK_INACTIVE)), 1500, |
8745 |
+- DP_TIMEOUT_PSR_LOOP_MS * 1000); |
8746 |
++ (!vsc->db[1] && (psr_status == DP_PSR_SINK_ACTIVE_RESYNC || |
8747 |
++ psr_status == DP_PSR_SINK_INACTIVE))), |
8748 |
++ 1500, DP_TIMEOUT_PSR_LOOP_MS * 1000); |
8749 |
+ if (ret) { |
8750 |
+ dev_warn(dp->dev, "Failed to apply PSR %d\n", ret); |
8751 |
+ return ret; |
8752 |
+diff --git a/drivers/gpu/drm/bridge/display-connector.c b/drivers/gpu/drm/bridge/display-connector.c |
8753 |
+index 05eb759da6fc6..847a0dce7f1d3 100644 |
8754 |
+--- a/drivers/gpu/drm/bridge/display-connector.c |
8755 |
++++ b/drivers/gpu/drm/bridge/display-connector.c |
8756 |
+@@ -107,7 +107,7 @@ static int display_connector_probe(struct platform_device *pdev) |
8757 |
+ { |
8758 |
+ struct display_connector *conn; |
8759 |
+ unsigned int type; |
8760 |
+- const char *label; |
8761 |
++ const char *label = NULL; |
8762 |
+ int ret; |
8763 |
+ |
8764 |
+ conn = devm_kzalloc(&pdev->dev, sizeof(*conn), GFP_KERNEL); |
8765 |
+diff --git a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c |
8766 |
+index d2808c4a6fb1c..cce98bf2a4e73 100644 |
8767 |
+--- a/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c |
8768 |
++++ b/drivers/gpu/drm/bridge/megachips-stdpxxxx-ge-b850v3-fw.c |
8769 |
+@@ -306,19 +306,10 @@ out: |
8770 |
+ mutex_unlock(&ge_b850v3_lvds_dev_mutex); |
8771 |
+ } |
8772 |
+ |
8773 |
+-static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c, |
8774 |
+- const struct i2c_device_id *id) |
8775 |
++static int ge_b850v3_register(void) |
8776 |
+ { |
8777 |
++ struct i2c_client *stdp4028_i2c = ge_b850v3_lvds_ptr->stdp4028_i2c; |
8778 |
+ struct device *dev = &stdp4028_i2c->dev; |
8779 |
+- int ret; |
8780 |
+- |
8781 |
+- ret = ge_b850v3_lvds_init(dev); |
8782 |
+- |
8783 |
+- if (ret) |
8784 |
+- return ret; |
8785 |
+- |
8786 |
+- ge_b850v3_lvds_ptr->stdp4028_i2c = stdp4028_i2c; |
8787 |
+- i2c_set_clientdata(stdp4028_i2c, ge_b850v3_lvds_ptr); |
8788 |
+ |
8789 |
+ /* drm bridge initialization */ |
8790 |
+ ge_b850v3_lvds_ptr->bridge.funcs = &ge_b850v3_lvds_funcs; |
8791 |
+@@ -343,6 +334,27 @@ static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c, |
8792 |
+ "ge-b850v3-lvds-dp", ge_b850v3_lvds_ptr); |
8793 |
+ } |
8794 |
+ |
8795 |
++static int stdp4028_ge_b850v3_fw_probe(struct i2c_client *stdp4028_i2c, |
8796 |
++ const struct i2c_device_id *id) |
8797 |
++{ |
8798 |
++ struct device *dev = &stdp4028_i2c->dev; |
8799 |
++ int ret; |
8800 |
++ |
8801 |
++ ret = ge_b850v3_lvds_init(dev); |
8802 |
++ |
8803 |
++ if (ret) |
8804 |
++ return ret; |
8805 |
++ |
8806 |
++ ge_b850v3_lvds_ptr->stdp4028_i2c = stdp4028_i2c; |
8807 |
++ i2c_set_clientdata(stdp4028_i2c, ge_b850v3_lvds_ptr); |
8808 |
++ |
8809 |
++ /* Only register after both bridges are probed */ |
8810 |
++ if (!ge_b850v3_lvds_ptr->stdp2690_i2c) |
8811 |
++ return 0; |
8812 |
++ |
8813 |
++ return ge_b850v3_register(); |
8814 |
++} |
8815 |
++ |
8816 |
+ static int stdp4028_ge_b850v3_fw_remove(struct i2c_client *stdp4028_i2c) |
8817 |
+ { |
8818 |
+ ge_b850v3_lvds_remove(); |
8819 |
+@@ -386,7 +398,11 @@ static int stdp2690_ge_b850v3_fw_probe(struct i2c_client *stdp2690_i2c, |
8820 |
+ ge_b850v3_lvds_ptr->stdp2690_i2c = stdp2690_i2c; |
8821 |
+ i2c_set_clientdata(stdp2690_i2c, ge_b850v3_lvds_ptr); |
8822 |
+ |
8823 |
+- return 0; |
8824 |
++ /* Only register after both bridges are probed */ |
8825 |
++ if (!ge_b850v3_lvds_ptr->stdp4028_i2c) |
8826 |
++ return 0; |
8827 |
++ |
8828 |
++ return ge_b850v3_register(); |
8829 |
+ } |
8830 |
+ |
8831 |
+ static int stdp2690_ge_b850v3_fw_remove(struct i2c_client *stdp2690_i2c) |
8832 |
+diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c |
8833 |
+index d0db1acf11d73..7d2ed0ed2fe26 100644 |
8834 |
+--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c |
8835 |
++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-ahb-audio.c |
8836 |
+@@ -320,13 +320,17 @@ static int dw_hdmi_open(struct snd_pcm_substream *substream) |
8837 |
+ struct snd_pcm_runtime *runtime = substream->runtime; |
8838 |
+ struct snd_dw_hdmi *dw = substream->private_data; |
8839 |
+ void __iomem *base = dw->data.base; |
8840 |
++ u8 *eld; |
8841 |
+ int ret; |
8842 |
+ |
8843 |
+ runtime->hw = dw_hdmi_hw; |
8844 |
+ |
8845 |
+- ret = snd_pcm_hw_constraint_eld(runtime, dw->data.eld); |
8846 |
+- if (ret < 0) |
8847 |
+- return ret; |
8848 |
++ eld = dw->data.get_eld(dw->data.hdmi); |
8849 |
++ if (eld) { |
8850 |
++ ret = snd_pcm_hw_constraint_eld(runtime, eld); |
8851 |
++ if (ret < 0) |
8852 |
++ return ret; |
8853 |
++ } |
8854 |
+ |
8855 |
+ ret = snd_pcm_limit_hw_rates(runtime); |
8856 |
+ if (ret < 0) |
8857 |
+diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h |
8858 |
+index cb07dc0da5a70..f72d27208ebef 100644 |
8859 |
+--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h |
8860 |
++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-audio.h |
8861 |
+@@ -9,15 +9,15 @@ struct dw_hdmi_audio_data { |
8862 |
+ void __iomem *base; |
8863 |
+ int irq; |
8864 |
+ struct dw_hdmi *hdmi; |
8865 |
+- u8 *eld; |
8866 |
++ u8 *(*get_eld)(struct dw_hdmi *hdmi); |
8867 |
+ }; |
8868 |
+ |
8869 |
+ struct dw_hdmi_i2s_audio_data { |
8870 |
+ struct dw_hdmi *hdmi; |
8871 |
+- u8 *eld; |
8872 |
+ |
8873 |
+ void (*write)(struct dw_hdmi *hdmi, u8 val, int offset); |
8874 |
+ u8 (*read)(struct dw_hdmi *hdmi, int offset); |
8875 |
++ u8 *(*get_eld)(struct dw_hdmi *hdmi); |
8876 |
+ }; |
8877 |
+ |
8878 |
+ #endif |
8879 |
+diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c |
8880 |
+index feb04f127b550..f50b47ac11a82 100644 |
8881 |
+--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c |
8882 |
++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi-i2s-audio.c |
8883 |
+@@ -135,8 +135,15 @@ static int dw_hdmi_i2s_get_eld(struct device *dev, void *data, uint8_t *buf, |
8884 |
+ size_t len) |
8885 |
+ { |
8886 |
+ struct dw_hdmi_i2s_audio_data *audio = data; |
8887 |
++ u8 *eld; |
8888 |
++ |
8889 |
++ eld = audio->get_eld(audio->hdmi); |
8890 |
++ if (eld) |
8891 |
++ memcpy(buf, eld, min_t(size_t, MAX_ELD_BYTES, len)); |
8892 |
++ else |
8893 |
++ /* Pass en empty ELD if connector not available */ |
8894 |
++ memset(buf, 0, len); |
8895 |
+ |
8896 |
+- memcpy(buf, audio->eld, min_t(size_t, MAX_ELD_BYTES, len)); |
8897 |
+ return 0; |
8898 |
+ } |
8899 |
+ |
8900 |
+diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c |
8901 |
+index f08d0fded61f7..e1211a5b334ba 100644 |
8902 |
+--- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c |
8903 |
++++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c |
8904 |
+@@ -757,6 +757,14 @@ static void hdmi_enable_audio_clk(struct dw_hdmi *hdmi, bool enable) |
8905 |
+ hdmi_writeb(hdmi, hdmi->mc_clkdis, HDMI_MC_CLKDIS); |
8906 |
+ } |
8907 |
+ |
8908 |
++static u8 *hdmi_audio_get_eld(struct dw_hdmi *hdmi) |
8909 |
++{ |
8910 |
++ if (!hdmi->curr_conn) |
8911 |
++ return NULL; |
8912 |
++ |
8913 |
++ return hdmi->curr_conn->eld; |
8914 |
++} |
8915 |
++ |
8916 |
+ static void dw_hdmi_ahb_audio_enable(struct dw_hdmi *hdmi) |
8917 |
+ { |
8918 |
+ hdmi_set_cts_n(hdmi, hdmi->audio_cts, hdmi->audio_n); |
8919 |
+@@ -3431,7 +3439,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, |
8920 |
+ audio.base = hdmi->regs; |
8921 |
+ audio.irq = irq; |
8922 |
+ audio.hdmi = hdmi; |
8923 |
+- audio.eld = hdmi->connector.eld; |
8924 |
++ audio.get_eld = hdmi_audio_get_eld; |
8925 |
+ hdmi->enable_audio = dw_hdmi_ahb_audio_enable; |
8926 |
+ hdmi->disable_audio = dw_hdmi_ahb_audio_disable; |
8927 |
+ |
8928 |
+@@ -3444,7 +3452,7 @@ struct dw_hdmi *dw_hdmi_probe(struct platform_device *pdev, |
8929 |
+ struct dw_hdmi_i2s_audio_data audio; |
8930 |
+ |
8931 |
+ audio.hdmi = hdmi; |
8932 |
+- audio.eld = hdmi->connector.eld; |
8933 |
++ audio.get_eld = hdmi_audio_get_eld; |
8934 |
+ audio.write = hdmi_writeb; |
8935 |
+ audio.read = hdmi_readb; |
8936 |
+ hdmi->enable_audio = dw_hdmi_i2s_audio_enable; |
8937 |
+diff --git a/drivers/gpu/drm/bridge/ti-sn65dsi86.c b/drivers/gpu/drm/bridge/ti-sn65dsi86.c |
8938 |
+index 41d48a393e7f5..4d08246f930c3 100644 |
8939 |
+--- a/drivers/gpu/drm/bridge/ti-sn65dsi86.c |
8940 |
++++ b/drivers/gpu/drm/bridge/ti-sn65dsi86.c |
8941 |
+@@ -188,6 +188,7 @@ static const struct regmap_config ti_sn65dsi86_regmap_config = { |
8942 |
+ .val_bits = 8, |
8943 |
+ .volatile_table = &ti_sn_bridge_volatile_table, |
8944 |
+ .cache_type = REGCACHE_NONE, |
8945 |
++ .max_register = 0xFF, |
8946 |
+ }; |
8947 |
+ |
8948 |
+ static void ti_sn65dsi86_write_u16(struct ti_sn65dsi86 *pdata, |
8949 |
+diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c |
8950 |
+index 6d0f2c447f3b9..7bb24523a7493 100644 |
8951 |
+--- a/drivers/gpu/drm/drm_dp_helper.c |
8952 |
++++ b/drivers/gpu/drm/drm_dp_helper.c |
8953 |
+@@ -3214,27 +3214,13 @@ int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backli |
8954 |
+ const u16 level) |
8955 |
+ { |
8956 |
+ int ret; |
8957 |
+- u8 dpcd_buf, new_dpcd_buf; |
8958 |
++ u8 dpcd_buf = DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD; |
8959 |
+ |
8960 |
+- ret = drm_dp_dpcd_readb(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, &dpcd_buf); |
8961 |
+- if (ret != 1) { |
8962 |
+- drm_dbg_kms(aux->drm_dev, |
8963 |
+- "%s: Failed to read backlight mode: %d\n", aux->name, ret); |
8964 |
+- return ret < 0 ? ret : -EIO; |
8965 |
+- } |
8966 |
+- |
8967 |
+- new_dpcd_buf = dpcd_buf; |
8968 |
+- |
8969 |
+- if ((dpcd_buf & DP_EDP_BACKLIGHT_CONTROL_MODE_MASK) != DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD) { |
8970 |
+- new_dpcd_buf &= ~DP_EDP_BACKLIGHT_CONTROL_MODE_MASK; |
8971 |
+- new_dpcd_buf |= DP_EDP_BACKLIGHT_CONTROL_MODE_DPCD; |
8972 |
+- |
8973 |
+- if (bl->pwmgen_bit_count) { |
8974 |
+- ret = drm_dp_dpcd_writeb(aux, DP_EDP_PWMGEN_BIT_COUNT, bl->pwmgen_bit_count); |
8975 |
+- if (ret != 1) |
8976 |
+- drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux pwmgen bit count: %d\n", |
8977 |
+- aux->name, ret); |
8978 |
+- } |
8979 |
++ if (bl->pwmgen_bit_count) { |
8980 |
++ ret = drm_dp_dpcd_writeb(aux, DP_EDP_PWMGEN_BIT_COUNT, bl->pwmgen_bit_count); |
8981 |
++ if (ret != 1) |
8982 |
++ drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux pwmgen bit count: %d\n", |
8983 |
++ aux->name, ret); |
8984 |
+ } |
8985 |
+ |
8986 |
+ if (bl->pwm_freq_pre_divider) { |
8987 |
+@@ -3244,16 +3230,14 @@ int drm_edp_backlight_enable(struct drm_dp_aux *aux, const struct drm_edp_backli |
8988 |
+ "%s: Failed to write aux backlight frequency: %d\n", |
8989 |
+ aux->name, ret); |
8990 |
+ else |
8991 |
+- new_dpcd_buf |= DP_EDP_BACKLIGHT_FREQ_AUX_SET_ENABLE; |
8992 |
++ dpcd_buf |= DP_EDP_BACKLIGHT_FREQ_AUX_SET_ENABLE; |
8993 |
+ } |
8994 |
+ |
8995 |
+- if (new_dpcd_buf != dpcd_buf) { |
8996 |
+- ret = drm_dp_dpcd_writeb(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, new_dpcd_buf); |
8997 |
+- if (ret != 1) { |
8998 |
+- drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux backlight mode: %d\n", |
8999 |
+- aux->name, ret); |
9000 |
+- return ret < 0 ? ret : -EIO; |
9001 |
+- } |
9002 |
++ ret = drm_dp_dpcd_writeb(aux, DP_EDP_BACKLIGHT_MODE_SET_REGISTER, dpcd_buf); |
9003 |
++ if (ret != 1) { |
9004 |
++ drm_dbg_kms(aux->drm_dev, "%s: Failed to write aux backlight mode: %d\n", |
9005 |
++ aux->name, ret); |
9006 |
++ return ret < 0 ? ret : -EIO; |
9007 |
+ } |
9008 |
+ |
9009 |
+ ret = drm_edp_backlight_set_level(aux, bl, level); |
9010 |
+diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c |
9011 |
+index 7a5097467ba5c..b3a1636d1b984 100644 |
9012 |
+--- a/drivers/gpu/drm/drm_drv.c |
9013 |
++++ b/drivers/gpu/drm/drm_drv.c |
9014 |
+@@ -581,6 +581,7 @@ static int drm_dev_init(struct drm_device *dev, |
9015 |
+ const struct drm_driver *driver, |
9016 |
+ struct device *parent) |
9017 |
+ { |
9018 |
++ struct inode *inode; |
9019 |
+ int ret; |
9020 |
+ |
9021 |
+ if (!drm_core_init_complete) { |
9022 |
+@@ -617,13 +618,15 @@ static int drm_dev_init(struct drm_device *dev, |
9023 |
+ if (ret) |
9024 |
+ return ret; |
9025 |
+ |
9026 |
+- dev->anon_inode = drm_fs_inode_new(); |
9027 |
+- if (IS_ERR(dev->anon_inode)) { |
9028 |
+- ret = PTR_ERR(dev->anon_inode); |
9029 |
++ inode = drm_fs_inode_new(); |
9030 |
++ if (IS_ERR(inode)) { |
9031 |
++ ret = PTR_ERR(inode); |
9032 |
+ DRM_ERROR("Cannot allocate anonymous inode: %d\n", ret); |
9033 |
+ goto err; |
9034 |
+ } |
9035 |
+ |
9036 |
++ dev->anon_inode = inode; |
9037 |
++ |
9038 |
+ if (drm_core_check_feature(dev, DRIVER_RENDER)) { |
9039 |
+ ret = drm_minor_alloc(dev, DRM_MINOR_RENDER); |
9040 |
+ if (ret) |
9041 |
+diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c |
9042 |
+index a950d5db211c5..9d1bd8f491ad7 100644 |
9043 |
+--- a/drivers/gpu/drm/drm_panel_orientation_quirks.c |
9044 |
++++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c |
9045 |
+@@ -248,6 +248,12 @@ static const struct dmi_system_id orientation_data[] = { |
9046 |
+ DMI_EXACT_MATCH(DMI_PRODUCT_VERSION, "Lenovo ideapad D330-10IGM"), |
9047 |
+ }, |
9048 |
+ .driver_data = (void *)&lcd1200x1920_rightside_up, |
9049 |
++ }, { /* Lenovo Yoga Book X90F / X91F / X91L */ |
9050 |
++ .matches = { |
9051 |
++ /* Non exact match to match all versions */ |
9052 |
++ DMI_MATCH(DMI_PRODUCT_NAME, "Lenovo YB1-X9"), |
9053 |
++ }, |
9054 |
++ .driver_data = (void *)&lcd1200x1920_rightside_up, |
9055 |
+ }, { /* OneGX1 Pro */ |
9056 |
+ .matches = { |
9057 |
+ DMI_EXACT_MATCH(DMI_SYS_VENDOR, "SYSTEM_MANUFACTURER"), |
9058 |
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c |
9059 |
+index 486259e154aff..225fa5879ebd9 100644 |
9060 |
+--- a/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c |
9061 |
++++ b/drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c |
9062 |
+@@ -469,6 +469,12 @@ int etnaviv_ioctl_gem_submit(struct drm_device *dev, void *data, |
9063 |
+ return -EINVAL; |
9064 |
+ } |
9065 |
+ |
9066 |
++ if (args->stream_size > SZ_64K || args->nr_relocs > SZ_64K || |
9067 |
++ args->nr_bos > SZ_64K || args->nr_pmrs > 128) { |
9068 |
++ DRM_ERROR("submit arguments out of size limits\n"); |
9069 |
++ return -EINVAL; |
9070 |
++ } |
9071 |
++ |
9072 |
+ /* |
9073 |
+ * Copy the command submission and bo array to kernel space in |
9074 |
+ * one go, and do this outside of any locks. |
9075 |
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h |
9076 |
+index 1c75c8ed5bcea..85eddd492774d 100644 |
9077 |
+--- a/drivers/gpu/drm/etnaviv/etnaviv_gpu.h |
9078 |
++++ b/drivers/gpu/drm/etnaviv/etnaviv_gpu.h |
9079 |
+@@ -130,6 +130,7 @@ struct etnaviv_gpu { |
9080 |
+ |
9081 |
+ /* hang detection */ |
9082 |
+ u32 hangcheck_dma_addr; |
9083 |
++ u32 hangcheck_fence; |
9084 |
+ |
9085 |
+ void __iomem *mmio; |
9086 |
+ int irq; |
9087 |
+diff --git a/drivers/gpu/drm/etnaviv/etnaviv_sched.c b/drivers/gpu/drm/etnaviv/etnaviv_sched.c |
9088 |
+index feb6da1b6cebc..bbf391f48f949 100644 |
9089 |
+--- a/drivers/gpu/drm/etnaviv/etnaviv_sched.c |
9090 |
++++ b/drivers/gpu/drm/etnaviv/etnaviv_sched.c |
9091 |
+@@ -107,8 +107,10 @@ static enum drm_gpu_sched_stat etnaviv_sched_timedout_job(struct drm_sched_job |
9092 |
+ */ |
9093 |
+ dma_addr = gpu_read(gpu, VIVS_FE_DMA_ADDRESS); |
9094 |
+ change = dma_addr - gpu->hangcheck_dma_addr; |
9095 |
+- if (change < 0 || change > 16) { |
9096 |
++ if (gpu->completed_fence != gpu->hangcheck_fence || |
9097 |
++ change < 0 || change > 16) { |
9098 |
+ gpu->hangcheck_dma_addr = dma_addr; |
9099 |
++ gpu->hangcheck_fence = gpu->completed_fence; |
9100 |
+ goto out_no_timeout; |
9101 |
+ } |
9102 |
+ |
9103 |
+diff --git a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c |
9104 |
+index ba2c08f1a797c..876620455ed31 100644 |
9105 |
+--- a/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c |
9106 |
++++ b/drivers/gpu/drm/i915/display/intel_ddi_buf_trans.c |
9107 |
+@@ -476,14 +476,14 @@ static const struct intel_ddi_buf_trans icl_combo_phy_ddi_translations_hdmi = { |
9108 |
+ static const union intel_ddi_buf_trans_entry _ehl_combo_phy_ddi_translations_dp[] = { |
9109 |
+ /* NT mV Trans mV db */ |
9110 |
+ { .icl = { 0xA, 0x33, 0x3F, 0x00, 0x00 } }, /* 350 350 0.0 */ |
9111 |
+- { .icl = { 0xA, 0x47, 0x36, 0x00, 0x09 } }, /* 350 500 3.1 */ |
9112 |
+- { .icl = { 0xC, 0x64, 0x34, 0x00, 0x0B } }, /* 350 700 6.0 */ |
9113 |
+- { .icl = { 0x6, 0x7F, 0x30, 0x00, 0x0F } }, /* 350 900 8.2 */ |
9114 |
++ { .icl = { 0xA, 0x47, 0x38, 0x00, 0x07 } }, /* 350 500 3.1 */ |
9115 |
++ { .icl = { 0xC, 0x64, 0x33, 0x00, 0x0C } }, /* 350 700 6.0 */ |
9116 |
++ { .icl = { 0x6, 0x7F, 0x2F, 0x00, 0x10 } }, /* 350 900 8.2 */ |
9117 |
+ { .icl = { 0xA, 0x46, 0x3F, 0x00, 0x00 } }, /* 500 500 0.0 */ |
9118 |
+- { .icl = { 0xC, 0x64, 0x38, 0x00, 0x07 } }, /* 500 700 2.9 */ |
9119 |
++ { .icl = { 0xC, 0x64, 0x37, 0x00, 0x08 } }, /* 500 700 2.9 */ |
9120 |
+ { .icl = { 0x6, 0x7F, 0x32, 0x00, 0x0D } }, /* 500 900 5.1 */ |
9121 |
+ { .icl = { 0xC, 0x61, 0x3F, 0x00, 0x00 } }, /* 650 700 0.6 */ |
9122 |
+- { .icl = { 0x6, 0x7F, 0x38, 0x00, 0x07 } }, /* 600 900 3.5 */ |
9123 |
++ { .icl = { 0x6, 0x7F, 0x37, 0x00, 0x08 } }, /* 600 900 3.5 */ |
9124 |
+ { .icl = { 0x6, 0x7F, 0x3F, 0x00, 0x00 } }, /* 900 900 0.0 */ |
9125 |
+ }; |
9126 |
+ |
9127 |
+diff --git a/drivers/gpu/drm/lima/lima_device.c b/drivers/gpu/drm/lima/lima_device.c |
9128 |
+index 65fdca366e41f..36c9905894278 100644 |
9129 |
+--- a/drivers/gpu/drm/lima/lima_device.c |
9130 |
++++ b/drivers/gpu/drm/lima/lima_device.c |
9131 |
+@@ -357,6 +357,7 @@ int lima_device_init(struct lima_device *ldev) |
9132 |
+ int err, i; |
9133 |
+ |
9134 |
+ dma_set_coherent_mask(ldev->dev, DMA_BIT_MASK(32)); |
9135 |
++ dma_set_max_seg_size(ldev->dev, UINT_MAX); |
9136 |
+ |
9137 |
+ err = lima_clk_init(ldev); |
9138 |
+ if (err) |
9139 |
+diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig |
9140 |
+index 3ddf739a6f9b8..c49b239231190 100644 |
9141 |
+--- a/drivers/gpu/drm/msm/Kconfig |
9142 |
++++ b/drivers/gpu/drm/msm/Kconfig |
9143 |
+@@ -63,6 +63,7 @@ config DRM_MSM_HDMI_HDCP |
9144 |
+ config DRM_MSM_DP |
9145 |
+ bool "Enable DisplayPort support in MSM DRM driver" |
9146 |
+ depends on DRM_MSM |
9147 |
++ select RATIONAL |
9148 |
+ default y |
9149 |
+ help |
9150 |
+ Compile in support for DP driver in MSM DRM driver. DP external |
9151 |
+diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |
9152 |
+index ad247c06e198f..93d916858d5ad 100644 |
9153 |
+--- a/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |
9154 |
++++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c |
9155 |
+@@ -73,8 +73,8 @@ static int _dpu_danger_signal_status(struct seq_file *s, |
9156 |
+ &status); |
9157 |
+ } else { |
9158 |
+ seq_puts(s, "\nSafe signal status:\n"); |
9159 |
+- if (kms->hw_mdp->ops.get_danger_status) |
9160 |
+- kms->hw_mdp->ops.get_danger_status(kms->hw_mdp, |
9161 |
++ if (kms->hw_mdp->ops.get_safe_status) |
9162 |
++ kms->hw_mdp->ops.get_safe_status(kms->hw_mdp, |
9163 |
+ &status); |
9164 |
+ } |
9165 |
+ pm_runtime_put_sync(&kms->pdev->dev); |
9166 |
+diff --git a/drivers/gpu/drm/msm/dsi/dsi.c b/drivers/gpu/drm/msm/dsi/dsi.c |
9167 |
+index 75ae3008b68f4..fc280cc434943 100644 |
9168 |
+--- a/drivers/gpu/drm/msm/dsi/dsi.c |
9169 |
++++ b/drivers/gpu/drm/msm/dsi/dsi.c |
9170 |
+@@ -215,9 +215,13 @@ int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev, |
9171 |
+ goto fail; |
9172 |
+ } |
9173 |
+ |
9174 |
+- if (!msm_dsi_manager_validate_current_config(msm_dsi->id)) { |
9175 |
+- ret = -EINVAL; |
9176 |
+- goto fail; |
9177 |
++ if (msm_dsi_is_bonded_dsi(msm_dsi) && |
9178 |
++ !msm_dsi_is_master_dsi(msm_dsi)) { |
9179 |
++ /* |
9180 |
++ * Do not return an eror here, |
9181 |
++ * Just skip creating encoder/connector for the slave-DSI. |
9182 |
++ */ |
9183 |
++ return 0; |
9184 |
+ } |
9185 |
+ |
9186 |
+ msm_dsi->encoder = encoder; |
9187 |
+diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h |
9188 |
+index 569c8ff062ba4..a63666e59d19e 100644 |
9189 |
+--- a/drivers/gpu/drm/msm/dsi/dsi.h |
9190 |
++++ b/drivers/gpu/drm/msm/dsi/dsi.h |
9191 |
+@@ -82,7 +82,6 @@ int msm_dsi_manager_cmd_xfer(int id, const struct mipi_dsi_msg *msg); |
9192 |
+ bool msm_dsi_manager_cmd_xfer_trigger(int id, u32 dma_base, u32 len); |
9193 |
+ int msm_dsi_manager_register(struct msm_dsi *msm_dsi); |
9194 |
+ void msm_dsi_manager_unregister(struct msm_dsi *msm_dsi); |
9195 |
+-bool msm_dsi_manager_validate_current_config(u8 id); |
9196 |
+ void msm_dsi_manager_tpg_enable(void); |
9197 |
+ |
9198 |
+ /* msm dsi */ |
9199 |
+diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c |
9200 |
+index fb4ccffdcfe13..fa4c396df6a92 100644 |
9201 |
+--- a/drivers/gpu/drm/msm/dsi/dsi_manager.c |
9202 |
++++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c |
9203 |
+@@ -647,23 +647,6 @@ fail: |
9204 |
+ return ERR_PTR(ret); |
9205 |
+ } |
9206 |
+ |
9207 |
+-bool msm_dsi_manager_validate_current_config(u8 id) |
9208 |
+-{ |
9209 |
+- bool is_bonded_dsi = IS_BONDED_DSI(); |
9210 |
+- |
9211 |
+- /* |
9212 |
+- * For bonded DSI, we only have one drm panel. For this |
9213 |
+- * use case, we register only one bridge/connector. |
9214 |
+- * Skip bridge/connector initialisation if it is |
9215 |
+- * slave-DSI for bonded DSI configuration. |
9216 |
+- */ |
9217 |
+- if (is_bonded_dsi && !IS_MASTER_DSI_LINK(id)) { |
9218 |
+- DBG("Skip bridge registration for slave DSI->id: %d\n", id); |
9219 |
+- return false; |
9220 |
+- } |
9221 |
+- return true; |
9222 |
+-} |
9223 |
+- |
9224 |
+ /* initialize bridge */ |
9225 |
+ struct drm_bridge *msm_dsi_manager_bridge_init(u8 id) |
9226 |
+ { |
9227 |
+diff --git a/drivers/gpu/drm/msm/msm_gem_submit.c b/drivers/gpu/drm/msm/msm_gem_submit.c |
9228 |
+index d9aef97eb93ad..7fb7ff043bcd7 100644 |
9229 |
+--- a/drivers/gpu/drm/msm/msm_gem_submit.c |
9230 |
++++ b/drivers/gpu/drm/msm/msm_gem_submit.c |
9231 |
+@@ -887,7 +887,7 @@ int msm_ioctl_gem_submit(struct drm_device *dev, void *data, |
9232 |
+ * to the underlying fence. |
9233 |
+ */ |
9234 |
+ submit->fence_id = idr_alloc_cyclic(&queue->fence_idr, |
9235 |
+- submit->user_fence, 0, INT_MAX, GFP_KERNEL); |
9236 |
++ submit->user_fence, 1, INT_MAX, GFP_KERNEL); |
9237 |
+ if (submit->fence_id < 0) { |
9238 |
+ ret = submit->fence_id = 0; |
9239 |
+ submit->fence_id = 0; |
9240 |
+diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c |
9241 |
+index 7739f46470d3e..99fee4d8cd318 100644 |
9242 |
+--- a/drivers/gpu/drm/nouveau/dispnv04/disp.c |
9243 |
++++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c |
9244 |
+@@ -205,7 +205,7 @@ nv04_display_destroy(struct drm_device *dev) |
9245 |
+ nvif_notify_dtor(&disp->flip); |
9246 |
+ |
9247 |
+ nouveau_display(dev)->priv = NULL; |
9248 |
+- kfree(disp); |
9249 |
++ vfree(disp); |
9250 |
+ |
9251 |
+ nvif_object_unmap(&drm->client.device.object); |
9252 |
+ } |
9253 |
+@@ -223,7 +223,7 @@ nv04_display_create(struct drm_device *dev) |
9254 |
+ struct nv04_display *disp; |
9255 |
+ int i, ret; |
9256 |
+ |
9257 |
+- disp = kzalloc(sizeof(*disp), GFP_KERNEL); |
9258 |
++ disp = vzalloc(sizeof(*disp)); |
9259 |
+ if (!disp) |
9260 |
+ return -ENOMEM; |
9261 |
+ |
9262 |
+diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c |
9263 |
+index 24382875fb4f3..455e95a89259f 100644 |
9264 |
+--- a/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c |
9265 |
++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/pmu/base.c |
9266 |
+@@ -94,20 +94,13 @@ nvkm_pmu_fini(struct nvkm_subdev *subdev, bool suspend) |
9267 |
+ return 0; |
9268 |
+ } |
9269 |
+ |
9270 |
+-static int |
9271 |
++static void |
9272 |
+ nvkm_pmu_reset(struct nvkm_pmu *pmu) |
9273 |
+ { |
9274 |
+ struct nvkm_device *device = pmu->subdev.device; |
9275 |
+ |
9276 |
+ if (!pmu->func->enabled(pmu)) |
9277 |
+- return 0; |
9278 |
+- |
9279 |
+- /* Inhibit interrupts, and wait for idle. */ |
9280 |
+- nvkm_wr32(device, 0x10a014, 0x0000ffff); |
9281 |
+- nvkm_msec(device, 2000, |
9282 |
+- if (!nvkm_rd32(device, 0x10a04c)) |
9283 |
+- break; |
9284 |
+- ); |
9285 |
++ return; |
9286 |
+ |
9287 |
+ /* Reset. */ |
9288 |
+ if (pmu->func->reset) |
9289 |
+@@ -118,25 +111,37 @@ nvkm_pmu_reset(struct nvkm_pmu *pmu) |
9290 |
+ if (!(nvkm_rd32(device, 0x10a10c) & 0x00000006)) |
9291 |
+ break; |
9292 |
+ ); |
9293 |
+- |
9294 |
+- return 0; |
9295 |
+ } |
9296 |
+ |
9297 |
+ static int |
9298 |
+ nvkm_pmu_preinit(struct nvkm_subdev *subdev) |
9299 |
+ { |
9300 |
+ struct nvkm_pmu *pmu = nvkm_pmu(subdev); |
9301 |
+- return nvkm_pmu_reset(pmu); |
9302 |
++ nvkm_pmu_reset(pmu); |
9303 |
++ return 0; |
9304 |
+ } |
9305 |
+ |
9306 |
+ static int |
9307 |
+ nvkm_pmu_init(struct nvkm_subdev *subdev) |
9308 |
+ { |
9309 |
+ struct nvkm_pmu *pmu = nvkm_pmu(subdev); |
9310 |
+- int ret = nvkm_pmu_reset(pmu); |
9311 |
+- if (ret == 0 && pmu->func->init) |
9312 |
+- ret = pmu->func->init(pmu); |
9313 |
+- return ret; |
9314 |
++ struct nvkm_device *device = pmu->subdev.device; |
9315 |
++ |
9316 |
++ if (!pmu->func->init) |
9317 |
++ return 0; |
9318 |
++ |
9319 |
++ if (pmu->func->enabled(pmu)) { |
9320 |
++ /* Inhibit interrupts, and wait for idle. */ |
9321 |
++ nvkm_wr32(device, 0x10a014, 0x0000ffff); |
9322 |
++ nvkm_msec(device, 2000, |
9323 |
++ if (!nvkm_rd32(device, 0x10a04c)) |
9324 |
++ break; |
9325 |
++ ); |
9326 |
++ |
9327 |
++ nvkm_pmu_reset(pmu); |
9328 |
++ } |
9329 |
++ |
9330 |
++ return pmu->func->init(pmu); |
9331 |
+ } |
9332 |
+ |
9333 |
+ static void * |
9334 |
+diff --git a/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c |
9335 |
+index 581661b506f81..f9c1f7bc8218c 100644 |
9336 |
+--- a/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c |
9337 |
++++ b/drivers/gpu/drm/panel/panel-feiyang-fy07024di26a30d.c |
9338 |
+@@ -227,7 +227,13 @@ static int feiyang_dsi_probe(struct mipi_dsi_device *dsi) |
9339 |
+ dsi->format = MIPI_DSI_FMT_RGB888; |
9340 |
+ dsi->lanes = 4; |
9341 |
+ |
9342 |
+- return mipi_dsi_attach(dsi); |
9343 |
++ ret = mipi_dsi_attach(dsi); |
9344 |
++ if (ret < 0) { |
9345 |
++ drm_panel_remove(&ctx->panel); |
9346 |
++ return ret; |
9347 |
++ } |
9348 |
++ |
9349 |
++ return 0; |
9350 |
+ } |
9351 |
+ |
9352 |
+ static int feiyang_dsi_remove(struct mipi_dsi_device *dsi) |
9353 |
+diff --git a/drivers/gpu/drm/panel/panel-innolux-p079zca.c b/drivers/gpu/drm/panel/panel-innolux-p079zca.c |
9354 |
+index aea3162253914..f194b62e290ca 100644 |
9355 |
+--- a/drivers/gpu/drm/panel/panel-innolux-p079zca.c |
9356 |
++++ b/drivers/gpu/drm/panel/panel-innolux-p079zca.c |
9357 |
+@@ -484,6 +484,7 @@ static void innolux_panel_del(struct innolux_panel *innolux) |
9358 |
+ static int innolux_panel_probe(struct mipi_dsi_device *dsi) |
9359 |
+ { |
9360 |
+ const struct panel_desc *desc; |
9361 |
++ struct innolux_panel *innolux; |
9362 |
+ int err; |
9363 |
+ |
9364 |
+ desc = of_device_get_match_data(&dsi->dev); |
9365 |
+@@ -495,7 +496,14 @@ static int innolux_panel_probe(struct mipi_dsi_device *dsi) |
9366 |
+ if (err < 0) |
9367 |
+ return err; |
9368 |
+ |
9369 |
+- return mipi_dsi_attach(dsi); |
9370 |
++ err = mipi_dsi_attach(dsi); |
9371 |
++ if (err < 0) { |
9372 |
++ innolux = mipi_dsi_get_drvdata(dsi); |
9373 |
++ innolux_panel_del(innolux); |
9374 |
++ return err; |
9375 |
++ } |
9376 |
++ |
9377 |
++ return 0; |
9378 |
+ } |
9379 |
+ |
9380 |
+ static int innolux_panel_remove(struct mipi_dsi_device *dsi) |
9381 |
+diff --git a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c |
9382 |
+index 733010b5e4f53..3c86ad262d5e0 100644 |
9383 |
+--- a/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c |
9384 |
++++ b/drivers/gpu/drm/panel/panel-jdi-lt070me05000.c |
9385 |
+@@ -473,7 +473,13 @@ static int jdi_panel_probe(struct mipi_dsi_device *dsi) |
9386 |
+ if (ret < 0) |
9387 |
+ return ret; |
9388 |
+ |
9389 |
+- return mipi_dsi_attach(dsi); |
9390 |
++ ret = mipi_dsi_attach(dsi); |
9391 |
++ if (ret < 0) { |
9392 |
++ jdi_panel_del(jdi); |
9393 |
++ return ret; |
9394 |
++ } |
9395 |
++ |
9396 |
++ return 0; |
9397 |
+ } |
9398 |
+ |
9399 |
+ static int jdi_panel_remove(struct mipi_dsi_device *dsi) |
9400 |
+diff --git a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c |
9401 |
+index 86e4213e8bb13..daccb1fd5fdad 100644 |
9402 |
+--- a/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c |
9403 |
++++ b/drivers/gpu/drm/panel/panel-kingdisplay-kd097d04.c |
9404 |
+@@ -406,7 +406,13 @@ static int kingdisplay_panel_probe(struct mipi_dsi_device *dsi) |
9405 |
+ if (err < 0) |
9406 |
+ return err; |
9407 |
+ |
9408 |
+- return mipi_dsi_attach(dsi); |
9409 |
++ err = mipi_dsi_attach(dsi); |
9410 |
++ if (err < 0) { |
9411 |
++ kingdisplay_panel_del(kingdisplay); |
9412 |
++ return err; |
9413 |
++ } |
9414 |
++ |
9415 |
++ return 0; |
9416 |
+ } |
9417 |
+ |
9418 |
+ static int kingdisplay_panel_remove(struct mipi_dsi_device *dsi) |
9419 |
+diff --git a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c |
9420 |
+index 533cd3934b8b7..839b263fb3c0f 100644 |
9421 |
+--- a/drivers/gpu/drm/panel/panel-novatek-nt36672a.c |
9422 |
++++ b/drivers/gpu/drm/panel/panel-novatek-nt36672a.c |
9423 |
+@@ -656,7 +656,13 @@ static int nt36672a_panel_probe(struct mipi_dsi_device *dsi) |
9424 |
+ if (err < 0) |
9425 |
+ return err; |
9426 |
+ |
9427 |
+- return mipi_dsi_attach(dsi); |
9428 |
++ err = mipi_dsi_attach(dsi); |
9429 |
++ if (err < 0) { |
9430 |
++ drm_panel_remove(&pinfo->base); |
9431 |
++ return err; |
9432 |
++ } |
9433 |
++ |
9434 |
++ return 0; |
9435 |
+ } |
9436 |
+ |
9437 |
+ static int nt36672a_panel_remove(struct mipi_dsi_device *dsi) |
9438 |
+diff --git a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c |
9439 |
+index 3c20beeb17819..3991f5d950af4 100644 |
9440 |
+--- a/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c |
9441 |
++++ b/drivers/gpu/drm/panel/panel-panasonic-vvx10f034n00.c |
9442 |
+@@ -241,7 +241,13 @@ static int wuxga_nt_panel_probe(struct mipi_dsi_device *dsi) |
9443 |
+ if (ret < 0) |
9444 |
+ return ret; |
9445 |
+ |
9446 |
+- return mipi_dsi_attach(dsi); |
9447 |
++ ret = mipi_dsi_attach(dsi); |
9448 |
++ if (ret < 0) { |
9449 |
++ wuxga_nt_panel_del(wuxga_nt); |
9450 |
++ return ret; |
9451 |
++ } |
9452 |
++ |
9453 |
++ return 0; |
9454 |
+ } |
9455 |
+ |
9456 |
+ static int wuxga_nt_panel_remove(struct mipi_dsi_device *dsi) |
9457 |
+diff --git a/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c b/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c |
9458 |
+index a3782830ae3c4..1fb579a574d9f 100644 |
9459 |
+--- a/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c |
9460 |
++++ b/drivers/gpu/drm/panel/panel-ronbo-rb070d30.c |
9461 |
+@@ -199,7 +199,13 @@ static int rb070d30_panel_dsi_probe(struct mipi_dsi_device *dsi) |
9462 |
+ dsi->format = MIPI_DSI_FMT_RGB888; |
9463 |
+ dsi->lanes = 4; |
9464 |
+ |
9465 |
+- return mipi_dsi_attach(dsi); |
9466 |
++ ret = mipi_dsi_attach(dsi); |
9467 |
++ if (ret < 0) { |
9468 |
++ drm_panel_remove(&ctx->panel); |
9469 |
++ return ret; |
9470 |
++ } |
9471 |
++ |
9472 |
++ return 0; |
9473 |
+ } |
9474 |
+ |
9475 |
+ static int rb070d30_panel_dsi_remove(struct mipi_dsi_device *dsi) |
9476 |
+diff --git a/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c b/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c |
9477 |
+index ea63799ff2a1e..29fde3823212b 100644 |
9478 |
+--- a/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c |
9479 |
++++ b/drivers/gpu/drm/panel/panel-samsung-s6e88a0-ams452ef01.c |
9480 |
+@@ -247,6 +247,7 @@ static int s6e88a0_ams452ef01_probe(struct mipi_dsi_device *dsi) |
9481 |
+ ret = mipi_dsi_attach(dsi); |
9482 |
+ if (ret < 0) { |
9483 |
+ dev_err(dev, "Failed to attach to DSI host: %d\n", ret); |
9484 |
++ drm_panel_remove(&ctx->panel); |
9485 |
+ return ret; |
9486 |
+ } |
9487 |
+ |
9488 |
+diff --git a/drivers/gpu/drm/panel/panel-samsung-sofef00.c b/drivers/gpu/drm/panel/panel-samsung-sofef00.c |
9489 |
+index 8cb1853574bb8..6d107e14fcc55 100644 |
9490 |
+--- a/drivers/gpu/drm/panel/panel-samsung-sofef00.c |
9491 |
++++ b/drivers/gpu/drm/panel/panel-samsung-sofef00.c |
9492 |
+@@ -302,6 +302,7 @@ static int sofef00_panel_probe(struct mipi_dsi_device *dsi) |
9493 |
+ ret = mipi_dsi_attach(dsi); |
9494 |
+ if (ret < 0) { |
9495 |
+ dev_err(dev, "Failed to attach to DSI host: %d\n", ret); |
9496 |
++ drm_panel_remove(&ctx->panel); |
9497 |
+ return ret; |
9498 |
+ } |
9499 |
+ |
9500 |
+diff --git a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c |
9501 |
+index b937e24dac8e0..25829a0a8e801 100644 |
9502 |
+--- a/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c |
9503 |
++++ b/drivers/gpu/drm/panel/panel-sharp-ls043t1le01.c |
9504 |
+@@ -296,7 +296,13 @@ static int sharp_nt_panel_probe(struct mipi_dsi_device *dsi) |
9505 |
+ if (ret < 0) |
9506 |
+ return ret; |
9507 |
+ |
9508 |
+- return mipi_dsi_attach(dsi); |
9509 |
++ ret = mipi_dsi_attach(dsi); |
9510 |
++ if (ret < 0) { |
9511 |
++ sharp_nt_panel_del(sharp_nt); |
9512 |
++ return ret; |
9513 |
++ } |
9514 |
++ |
9515 |
++ return 0; |
9516 |
+ } |
9517 |
+ |
9518 |
+ static int sharp_nt_panel_remove(struct mipi_dsi_device *dsi) |
9519 |
+diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c |
9520 |
+index 482fb0ae6cb5d..0e14907f2043e 100644 |
9521 |
+--- a/drivers/gpu/drm/radeon/radeon_kms.c |
9522 |
++++ b/drivers/gpu/drm/radeon/radeon_kms.c |
9523 |
+@@ -648,6 +648,8 @@ void radeon_driver_lastclose_kms(struct drm_device *dev) |
9524 |
+ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) |
9525 |
+ { |
9526 |
+ struct radeon_device *rdev = dev->dev_private; |
9527 |
++ struct radeon_fpriv *fpriv; |
9528 |
++ struct radeon_vm *vm; |
9529 |
+ int r; |
9530 |
+ |
9531 |
+ file_priv->driver_priv = NULL; |
9532 |
+@@ -660,48 +662,52 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv) |
9533 |
+ |
9534 |
+ /* new gpu have virtual address space support */ |
9535 |
+ if (rdev->family >= CHIP_CAYMAN) { |
9536 |
+- struct radeon_fpriv *fpriv; |
9537 |
+- struct radeon_vm *vm; |
9538 |
+ |
9539 |
+ fpriv = kzalloc(sizeof(*fpriv), GFP_KERNEL); |
9540 |
+ if (unlikely(!fpriv)) { |
9541 |
+ r = -ENOMEM; |
9542 |
+- goto out_suspend; |
9543 |
++ goto err_suspend; |
9544 |
+ } |
9545 |
+ |
9546 |
+ if (rdev->accel_working) { |
9547 |
+ vm = &fpriv->vm; |
9548 |
+ r = radeon_vm_init(rdev, vm); |
9549 |
+- if (r) { |
9550 |
+- kfree(fpriv); |
9551 |
+- goto out_suspend; |
9552 |
+- } |
9553 |
++ if (r) |
9554 |
++ goto err_fpriv; |
9555 |
+ |
9556 |
+ r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false); |
9557 |
+- if (r) { |
9558 |
+- radeon_vm_fini(rdev, vm); |
9559 |
+- kfree(fpriv); |
9560 |
+- goto out_suspend; |
9561 |
+- } |
9562 |
++ if (r) |
9563 |
++ goto err_vm_fini; |
9564 |
+ |
9565 |
+ /* map the ib pool buffer read only into |
9566 |
+ * virtual address space */ |
9567 |
+ vm->ib_bo_va = radeon_vm_bo_add(rdev, vm, |
9568 |
+ rdev->ring_tmp_bo.bo); |
9569 |
++ if (!vm->ib_bo_va) { |
9570 |
++ r = -ENOMEM; |
9571 |
++ goto err_vm_fini; |
9572 |
++ } |
9573 |
++ |
9574 |
+ r = radeon_vm_bo_set_addr(rdev, vm->ib_bo_va, |
9575 |
+ RADEON_VA_IB_OFFSET, |
9576 |
+ RADEON_VM_PAGE_READABLE | |
9577 |
+ RADEON_VM_PAGE_SNOOPED); |
9578 |
+- if (r) { |
9579 |
+- radeon_vm_fini(rdev, vm); |
9580 |
+- kfree(fpriv); |
9581 |
+- goto out_suspend; |
9582 |
+- } |
9583 |
++ if (r) |
9584 |
++ goto err_vm_fini; |
9585 |
+ } |
9586 |
+ file_priv->driver_priv = fpriv; |
9587 |
+ } |
9588 |
+ |
9589 |
+-out_suspend: |
9590 |
++ pm_runtime_mark_last_busy(dev->dev); |
9591 |
++ pm_runtime_put_autosuspend(dev->dev); |
9592 |
++ return 0; |
9593 |
++ |
9594 |
++err_vm_fini: |
9595 |
++ radeon_vm_fini(rdev, vm); |
9596 |
++err_fpriv: |
9597 |
++ kfree(fpriv); |
9598 |
++ |
9599 |
++err_suspend: |
9600 |
+ pm_runtime_mark_last_busy(dev->dev); |
9601 |
+ pm_runtime_put_autosuspend(dev->dev); |
9602 |
+ return r; |
9603 |
+diff --git a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c |
9604 |
+index ea7e39d035457..ee7e375ee6724 100644 |
9605 |
+--- a/drivers/gpu/drm/rcar-du/rcar_du_crtc.c |
9606 |
++++ b/drivers/gpu/drm/rcar-du/rcar_du_crtc.c |
9607 |
+@@ -215,6 +215,7 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) |
9608 |
+ const struct drm_display_mode *mode = &rcrtc->crtc.state->adjusted_mode; |
9609 |
+ struct rcar_du_device *rcdu = rcrtc->dev; |
9610 |
+ unsigned long mode_clock = mode->clock * 1000; |
9611 |
++ unsigned int hdse_offset; |
9612 |
+ u32 dsmr; |
9613 |
+ u32 escr; |
9614 |
+ |
9615 |
+@@ -298,10 +299,15 @@ static void rcar_du_crtc_set_display_timing(struct rcar_du_crtc *rcrtc) |
9616 |
+ | DSMR_DIPM_DISP | DSMR_CSPM; |
9617 |
+ rcar_du_crtc_write(rcrtc, DSMR, dsmr); |
9618 |
+ |
9619 |
++ hdse_offset = 19; |
9620 |
++ if (rcrtc->group->cmms_mask & BIT(rcrtc->index % 2)) |
9621 |
++ hdse_offset += 25; |
9622 |
++ |
9623 |
+ /* Display timings */ |
9624 |
+- rcar_du_crtc_write(rcrtc, HDSR, mode->htotal - mode->hsync_start - 19); |
9625 |
++ rcar_du_crtc_write(rcrtc, HDSR, mode->htotal - mode->hsync_start - |
9626 |
++ hdse_offset); |
9627 |
+ rcar_du_crtc_write(rcrtc, HDER, mode->htotal - mode->hsync_start + |
9628 |
+- mode->hdisplay - 19); |
9629 |
++ mode->hdisplay - hdse_offset); |
9630 |
+ rcar_du_crtc_write(rcrtc, HSWR, mode->hsync_end - |
9631 |
+ mode->hsync_start - 1); |
9632 |
+ rcar_du_crtc_write(rcrtc, HCR, mode->htotal - 1); |
9633 |
+@@ -836,6 +842,7 @@ rcar_du_crtc_mode_valid(struct drm_crtc *crtc, |
9634 |
+ struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc); |
9635 |
+ struct rcar_du_device *rcdu = rcrtc->dev; |
9636 |
+ bool interlaced = mode->flags & DRM_MODE_FLAG_INTERLACE; |
9637 |
++ unsigned int min_sync_porch; |
9638 |
+ unsigned int vbp; |
9639 |
+ |
9640 |
+ if (interlaced && !rcar_du_has(rcdu, RCAR_DU_FEATURE_INTERLACED)) |
9641 |
+@@ -843,9 +850,14 @@ rcar_du_crtc_mode_valid(struct drm_crtc *crtc, |
9642 |
+ |
9643 |
+ /* |
9644 |
+ * The hardware requires a minimum combined horizontal sync and back |
9645 |
+- * porch of 20 pixels and a minimum vertical back porch of 3 lines. |
9646 |
++ * porch of 20 pixels (when CMM isn't used) or 45 pixels (when CMM is |
9647 |
++ * used), and a minimum vertical back porch of 3 lines. |
9648 |
+ */ |
9649 |
+- if (mode->htotal - mode->hsync_start < 20) |
9650 |
++ min_sync_porch = 20; |
9651 |
++ if (rcrtc->group->cmms_mask & BIT(rcrtc->index % 2)) |
9652 |
++ min_sync_porch += 25; |
9653 |
++ |
9654 |
++ if (mode->htotal - mode->hsync_start < min_sync_porch) |
9655 |
+ return MODE_HBLANK_NARROW; |
9656 |
+ |
9657 |
+ vbp = (mode->vtotal - mode->vsync_end) / (interlaced ? 2 : 1); |
9658 |
+diff --git a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c |
9659 |
+index a2262bee5aa47..59c3d8ef6bf9a 100644 |
9660 |
+--- a/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c |
9661 |
++++ b/drivers/gpu/drm/rockchip/dw-mipi-dsi-rockchip.c |
9662 |
+@@ -268,6 +268,8 @@ struct dw_mipi_dsi_rockchip { |
9663 |
+ struct dw_mipi_dsi *dmd; |
9664 |
+ const struct rockchip_dw_dsi_chip_data *cdata; |
9665 |
+ struct dw_mipi_dsi_plat_data pdata; |
9666 |
++ |
9667 |
++ bool dsi_bound; |
9668 |
+ }; |
9669 |
+ |
9670 |
+ struct dphy_pll_parameter_map { |
9671 |
+@@ -773,10 +775,6 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder) |
9672 |
+ if (mux < 0) |
9673 |
+ return; |
9674 |
+ |
9675 |
+- pm_runtime_get_sync(dsi->dev); |
9676 |
+- if (dsi->slave) |
9677 |
+- pm_runtime_get_sync(dsi->slave->dev); |
9678 |
+- |
9679 |
+ /* |
9680 |
+ * For the RK3399, the clk of grf must be enabled before writing grf |
9681 |
+ * register. And for RK3288 or other soc, this grf_clk must be NULL, |
9682 |
+@@ -795,20 +793,10 @@ static void dw_mipi_dsi_encoder_enable(struct drm_encoder *encoder) |
9683 |
+ clk_disable_unprepare(dsi->grf_clk); |
9684 |
+ } |
9685 |
+ |
9686 |
+-static void dw_mipi_dsi_encoder_disable(struct drm_encoder *encoder) |
9687 |
+-{ |
9688 |
+- struct dw_mipi_dsi_rockchip *dsi = to_dsi(encoder); |
9689 |
+- |
9690 |
+- if (dsi->slave) |
9691 |
+- pm_runtime_put(dsi->slave->dev); |
9692 |
+- pm_runtime_put(dsi->dev); |
9693 |
+-} |
9694 |
+- |
9695 |
+ static const struct drm_encoder_helper_funcs |
9696 |
+ dw_mipi_dsi_encoder_helper_funcs = { |
9697 |
+ .atomic_check = dw_mipi_dsi_encoder_atomic_check, |
9698 |
+ .enable = dw_mipi_dsi_encoder_enable, |
9699 |
+- .disable = dw_mipi_dsi_encoder_disable, |
9700 |
+ }; |
9701 |
+ |
9702 |
+ static int rockchip_dsi_drm_create_encoder(struct dw_mipi_dsi_rockchip *dsi, |
9703 |
+@@ -938,10 +926,14 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev, |
9704 |
+ put_device(second); |
9705 |
+ } |
9706 |
+ |
9707 |
++ pm_runtime_get_sync(dsi->dev); |
9708 |
++ if (dsi->slave) |
9709 |
++ pm_runtime_get_sync(dsi->slave->dev); |
9710 |
++ |
9711 |
+ ret = clk_prepare_enable(dsi->pllref_clk); |
9712 |
+ if (ret) { |
9713 |
+ DRM_DEV_ERROR(dev, "Failed to enable pllref_clk: %d\n", ret); |
9714 |
+- return ret; |
9715 |
++ goto out_pm_runtime; |
9716 |
+ } |
9717 |
+ |
9718 |
+ /* |
9719 |
+@@ -953,7 +945,7 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev, |
9720 |
+ ret = clk_prepare_enable(dsi->grf_clk); |
9721 |
+ if (ret) { |
9722 |
+ DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret); |
9723 |
+- return ret; |
9724 |
++ goto out_pll_clk; |
9725 |
+ } |
9726 |
+ |
9727 |
+ dw_mipi_dsi_rockchip_config(dsi); |
9728 |
+@@ -965,16 +957,27 @@ static int dw_mipi_dsi_rockchip_bind(struct device *dev, |
9729 |
+ ret = rockchip_dsi_drm_create_encoder(dsi, drm_dev); |
9730 |
+ if (ret) { |
9731 |
+ DRM_DEV_ERROR(dev, "Failed to create drm encoder\n"); |
9732 |
+- return ret; |
9733 |
++ goto out_pll_clk; |
9734 |
+ } |
9735 |
+ |
9736 |
+ ret = dw_mipi_dsi_bind(dsi->dmd, &dsi->encoder); |
9737 |
+ if (ret) { |
9738 |
+ DRM_DEV_ERROR(dev, "Failed to bind: %d\n", ret); |
9739 |
+- return ret; |
9740 |
++ goto out_pll_clk; |
9741 |
+ } |
9742 |
+ |
9743 |
++ dsi->dsi_bound = true; |
9744 |
++ |
9745 |
+ return 0; |
9746 |
++ |
9747 |
++out_pll_clk: |
9748 |
++ clk_disable_unprepare(dsi->pllref_clk); |
9749 |
++out_pm_runtime: |
9750 |
++ pm_runtime_put(dsi->dev); |
9751 |
++ if (dsi->slave) |
9752 |
++ pm_runtime_put(dsi->slave->dev); |
9753 |
++ |
9754 |
++ return ret; |
9755 |
+ } |
9756 |
+ |
9757 |
+ static void dw_mipi_dsi_rockchip_unbind(struct device *dev, |
9758 |
+@@ -986,9 +989,15 @@ static void dw_mipi_dsi_rockchip_unbind(struct device *dev, |
9759 |
+ if (dsi->is_slave) |
9760 |
+ return; |
9761 |
+ |
9762 |
++ dsi->dsi_bound = false; |
9763 |
++ |
9764 |
+ dw_mipi_dsi_unbind(dsi->dmd); |
9765 |
+ |
9766 |
+ clk_disable_unprepare(dsi->pllref_clk); |
9767 |
++ |
9768 |
++ pm_runtime_put(dsi->dev); |
9769 |
++ if (dsi->slave) |
9770 |
++ pm_runtime_put(dsi->slave->dev); |
9771 |
+ } |
9772 |
+ |
9773 |
+ static const struct component_ops dw_mipi_dsi_rockchip_ops = { |
9774 |
+@@ -1276,6 +1285,36 @@ static const struct phy_ops dw_mipi_dsi_dphy_ops = { |
9775 |
+ .exit = dw_mipi_dsi_dphy_exit, |
9776 |
+ }; |
9777 |
+ |
9778 |
++static int __maybe_unused dw_mipi_dsi_rockchip_resume(struct device *dev) |
9779 |
++{ |
9780 |
++ struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev); |
9781 |
++ int ret; |
9782 |
++ |
9783 |
++ /* |
9784 |
++ * Re-configure DSI state, if we were previously initialized. We need |
9785 |
++ * to do this before rockchip_drm_drv tries to re-enable() any panels. |
9786 |
++ */ |
9787 |
++ if (dsi->dsi_bound) { |
9788 |
++ ret = clk_prepare_enable(dsi->grf_clk); |
9789 |
++ if (ret) { |
9790 |
++ DRM_DEV_ERROR(dsi->dev, "Failed to enable grf_clk: %d\n", ret); |
9791 |
++ return ret; |
9792 |
++ } |
9793 |
++ |
9794 |
++ dw_mipi_dsi_rockchip_config(dsi); |
9795 |
++ if (dsi->slave) |
9796 |
++ dw_mipi_dsi_rockchip_config(dsi->slave); |
9797 |
++ |
9798 |
++ clk_disable_unprepare(dsi->grf_clk); |
9799 |
++ } |
9800 |
++ |
9801 |
++ return 0; |
9802 |
++} |
9803 |
++ |
9804 |
++static const struct dev_pm_ops dw_mipi_dsi_rockchip_pm_ops = { |
9805 |
++ SET_LATE_SYSTEM_SLEEP_PM_OPS(NULL, dw_mipi_dsi_rockchip_resume) |
9806 |
++}; |
9807 |
++ |
9808 |
+ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev) |
9809 |
+ { |
9810 |
+ struct device *dev = &pdev->dev; |
9811 |
+@@ -1397,14 +1436,10 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev) |
9812 |
+ if (ret != -EPROBE_DEFER) |
9813 |
+ DRM_DEV_ERROR(dev, |
9814 |
+ "Failed to probe dw_mipi_dsi: %d\n", ret); |
9815 |
+- goto err_clkdisable; |
9816 |
++ return ret; |
9817 |
+ } |
9818 |
+ |
9819 |
+ return 0; |
9820 |
+- |
9821 |
+-err_clkdisable: |
9822 |
+- clk_disable_unprepare(dsi->pllref_clk); |
9823 |
+- return ret; |
9824 |
+ } |
9825 |
+ |
9826 |
+ static int dw_mipi_dsi_rockchip_remove(struct platform_device *pdev) |
9827 |
+@@ -1593,6 +1628,7 @@ struct platform_driver dw_mipi_dsi_rockchip_driver = { |
9828 |
+ .remove = dw_mipi_dsi_rockchip_remove, |
9829 |
+ .driver = { |
9830 |
+ .of_match_table = dw_mipi_dsi_rockchip_dt_ids, |
9831 |
++ .pm = &dw_mipi_dsi_rockchip_pm_ops, |
9832 |
+ .name = "dw-mipi-dsi-rockchip", |
9833 |
+ }, |
9834 |
+ }; |
9835 |
+diff --git a/drivers/gpu/drm/tegra/drm.c b/drivers/gpu/drm/tegra/drm.c |
9836 |
+index 8d37d6b00562a..611cd8dad46ed 100644 |
9837 |
+--- a/drivers/gpu/drm/tegra/drm.c |
9838 |
++++ b/drivers/gpu/drm/tegra/drm.c |
9839 |
+@@ -21,6 +21,10 @@ |
9840 |
+ #include <drm/drm_prime.h> |
9841 |
+ #include <drm/drm_vblank.h> |
9842 |
+ |
9843 |
++#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) |
9844 |
++#include <asm/dma-iommu.h> |
9845 |
++#endif |
9846 |
++ |
9847 |
+ #include "dc.h" |
9848 |
+ #include "drm.h" |
9849 |
+ #include "gem.h" |
9850 |
+@@ -936,6 +940,17 @@ int host1x_client_iommu_attach(struct host1x_client *client) |
9851 |
+ struct iommu_group *group = NULL; |
9852 |
+ int err; |
9853 |
+ |
9854 |
++#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) |
9855 |
++ if (client->dev->archdata.mapping) { |
9856 |
++ struct dma_iommu_mapping *mapping = |
9857 |
++ to_dma_iommu_mapping(client->dev); |
9858 |
++ arm_iommu_detach_device(client->dev); |
9859 |
++ arm_iommu_release_mapping(mapping); |
9860 |
++ |
9861 |
++ domain = iommu_get_domain_for_dev(client->dev); |
9862 |
++ } |
9863 |
++#endif |
9864 |
++ |
9865 |
+ /* |
9866 |
+ * If the host1x client is already attached to an IOMMU domain that is |
9867 |
+ * not the shared IOMMU domain, don't try to attach it to a different |
9868 |
+diff --git a/drivers/gpu/drm/tegra/gr2d.c b/drivers/gpu/drm/tegra/gr2d.c |
9869 |
+index de288cba39055..ba3722f1b8651 100644 |
9870 |
+--- a/drivers/gpu/drm/tegra/gr2d.c |
9871 |
++++ b/drivers/gpu/drm/tegra/gr2d.c |
9872 |
+@@ -4,9 +4,11 @@ |
9873 |
+ */ |
9874 |
+ |
9875 |
+ #include <linux/clk.h> |
9876 |
++#include <linux/delay.h> |
9877 |
+ #include <linux/iommu.h> |
9878 |
+ #include <linux/module.h> |
9879 |
+ #include <linux/of_device.h> |
9880 |
++#include <linux/reset.h> |
9881 |
+ |
9882 |
+ #include "drm.h" |
9883 |
+ #include "gem.h" |
9884 |
+@@ -19,6 +21,7 @@ struct gr2d_soc { |
9885 |
+ struct gr2d { |
9886 |
+ struct tegra_drm_client client; |
9887 |
+ struct host1x_channel *channel; |
9888 |
++ struct reset_control *rst; |
9889 |
+ struct clk *clk; |
9890 |
+ |
9891 |
+ const struct gr2d_soc *soc; |
9892 |
+@@ -208,6 +211,12 @@ static int gr2d_probe(struct platform_device *pdev) |
9893 |
+ if (!syncpts) |
9894 |
+ return -ENOMEM; |
9895 |
+ |
9896 |
++ gr2d->rst = devm_reset_control_get(dev, NULL); |
9897 |
++ if (IS_ERR(gr2d->rst)) { |
9898 |
++ dev_err(dev, "cannot get reset\n"); |
9899 |
++ return PTR_ERR(gr2d->rst); |
9900 |
++ } |
9901 |
++ |
9902 |
+ gr2d->clk = devm_clk_get(dev, NULL); |
9903 |
+ if (IS_ERR(gr2d->clk)) { |
9904 |
+ dev_err(dev, "cannot get clock\n"); |
9905 |
+@@ -220,6 +229,14 @@ static int gr2d_probe(struct platform_device *pdev) |
9906 |
+ return err; |
9907 |
+ } |
9908 |
+ |
9909 |
++ usleep_range(2000, 4000); |
9910 |
++ |
9911 |
++ err = reset_control_deassert(gr2d->rst); |
9912 |
++ if (err < 0) { |
9913 |
++ dev_err(dev, "failed to deassert reset: %d\n", err); |
9914 |
++ goto disable_clk; |
9915 |
++ } |
9916 |
++ |
9917 |
+ INIT_LIST_HEAD(&gr2d->client.base.list); |
9918 |
+ gr2d->client.base.ops = &gr2d_client_ops; |
9919 |
+ gr2d->client.base.dev = dev; |
9920 |
+@@ -234,8 +251,7 @@ static int gr2d_probe(struct platform_device *pdev) |
9921 |
+ err = host1x_client_register(&gr2d->client.base); |
9922 |
+ if (err < 0) { |
9923 |
+ dev_err(dev, "failed to register host1x client: %d\n", err); |
9924 |
+- clk_disable_unprepare(gr2d->clk); |
9925 |
+- return err; |
9926 |
++ goto assert_rst; |
9927 |
+ } |
9928 |
+ |
9929 |
+ /* initialize address register map */ |
9930 |
+@@ -245,6 +261,13 @@ static int gr2d_probe(struct platform_device *pdev) |
9931 |
+ platform_set_drvdata(pdev, gr2d); |
9932 |
+ |
9933 |
+ return 0; |
9934 |
++ |
9935 |
++assert_rst: |
9936 |
++ (void)reset_control_assert(gr2d->rst); |
9937 |
++disable_clk: |
9938 |
++ clk_disable_unprepare(gr2d->clk); |
9939 |
++ |
9940 |
++ return err; |
9941 |
+ } |
9942 |
+ |
9943 |
+ static int gr2d_remove(struct platform_device *pdev) |
9944 |
+@@ -259,6 +282,12 @@ static int gr2d_remove(struct platform_device *pdev) |
9945 |
+ return err; |
9946 |
+ } |
9947 |
+ |
9948 |
++ err = reset_control_assert(gr2d->rst); |
9949 |
++ if (err < 0) |
9950 |
++ dev_err(&pdev->dev, "failed to assert reset: %d\n", err); |
9951 |
++ |
9952 |
++ usleep_range(2000, 4000); |
9953 |
++ |
9954 |
+ clk_disable_unprepare(gr2d->clk); |
9955 |
+ |
9956 |
+ return 0; |
9957 |
+diff --git a/drivers/gpu/drm/tegra/submit.c b/drivers/gpu/drm/tegra/submit.c |
9958 |
+index 776f825df52fa..aba9d0c9d9031 100644 |
9959 |
+--- a/drivers/gpu/drm/tegra/submit.c |
9960 |
++++ b/drivers/gpu/drm/tegra/submit.c |
9961 |
+@@ -475,8 +475,10 @@ static void release_job(struct host1x_job *job) |
9962 |
+ kfree(job_data->used_mappings); |
9963 |
+ kfree(job_data); |
9964 |
+ |
9965 |
+- if (pm_runtime_enabled(client->base.dev)) |
9966 |
++ if (pm_runtime_enabled(client->base.dev)) { |
9967 |
++ pm_runtime_mark_last_busy(client->base.dev); |
9968 |
+ pm_runtime_put_autosuspend(client->base.dev); |
9969 |
++ } |
9970 |
+ } |
9971 |
+ |
9972 |
+ int tegra_drm_ioctl_channel_submit(struct drm_device *drm, void *data, |
9973 |
+diff --git a/drivers/gpu/drm/tegra/vic.c b/drivers/gpu/drm/tegra/vic.c |
9974 |
+index c02010ff2b7f2..da4af53719917 100644 |
9975 |
+--- a/drivers/gpu/drm/tegra/vic.c |
9976 |
++++ b/drivers/gpu/drm/tegra/vic.c |
9977 |
+@@ -5,6 +5,7 @@ |
9978 |
+ |
9979 |
+ #include <linux/clk.h> |
9980 |
+ #include <linux/delay.h> |
9981 |
++#include <linux/dma-mapping.h> |
9982 |
+ #include <linux/host1x.h> |
9983 |
+ #include <linux/iommu.h> |
9984 |
+ #include <linux/module.h> |
9985 |
+@@ -232,10 +233,8 @@ static int vic_load_firmware(struct vic *vic) |
9986 |
+ |
9987 |
+ if (!client->group) { |
9988 |
+ virt = dma_alloc_coherent(vic->dev, size, &iova, GFP_KERNEL); |
9989 |
+- |
9990 |
+- err = dma_mapping_error(vic->dev, iova); |
9991 |
+- if (err < 0) |
9992 |
+- return err; |
9993 |
++ if (!virt) |
9994 |
++ return -ENOMEM; |
9995 |
+ } else { |
9996 |
+ virt = tegra_drm_alloc(tegra, size, &iova); |
9997 |
+ } |
9998 |
+diff --git a/drivers/gpu/drm/ttm/ttm_bo.c b/drivers/gpu/drm/ttm/ttm_bo.c |
9999 |
+index bb9e02c31946e..900edaf5d68ee 100644 |
10000 |
+--- a/drivers/gpu/drm/ttm/ttm_bo.c |
10001 |
++++ b/drivers/gpu/drm/ttm/ttm_bo.c |
10002 |
+@@ -724,6 +724,8 @@ int ttm_mem_evict_first(struct ttm_device *bdev, |
10003 |
+ ret = ttm_bo_evict(bo, ctx); |
10004 |
+ if (locked) |
10005 |
+ ttm_bo_unreserve(bo); |
10006 |
++ else |
10007 |
++ ttm_bo_move_to_lru_tail_unlocked(bo); |
10008 |
+ |
10009 |
+ ttm_bo_put(bo); |
10010 |
+ return ret; |
10011 |
+diff --git a/drivers/gpu/drm/vboxvideo/vbox_main.c b/drivers/gpu/drm/vboxvideo/vbox_main.c |
10012 |
+index f28779715ccda..c9e8b3a63c621 100644 |
10013 |
+--- a/drivers/gpu/drm/vboxvideo/vbox_main.c |
10014 |
++++ b/drivers/gpu/drm/vboxvideo/vbox_main.c |
10015 |
+@@ -127,8 +127,8 @@ int vbox_hw_init(struct vbox_private *vbox) |
10016 |
+ /* Create guest-heap mem-pool use 2^4 = 16 byte chunks */ |
10017 |
+ vbox->guest_pool = devm_gen_pool_create(vbox->ddev.dev, 4, -1, |
10018 |
+ "vboxvideo-accel"); |
10019 |
+- if (!vbox->guest_pool) |
10020 |
+- return -ENOMEM; |
10021 |
++ if (IS_ERR(vbox->guest_pool)) |
10022 |
++ return PTR_ERR(vbox->guest_pool); |
10023 |
+ |
10024 |
+ ret = gen_pool_add_virt(vbox->guest_pool, |
10025 |
+ (unsigned long)vbox->guest_heap, |
10026 |
+diff --git a/drivers/gpu/drm/vc4/vc4_crtc.c b/drivers/gpu/drm/vc4/vc4_crtc.c |
10027 |
+index 18f5009ce90e3..e3ed52d96f423 100644 |
10028 |
+--- a/drivers/gpu/drm/vc4/vc4_crtc.c |
10029 |
++++ b/drivers/gpu/drm/vc4/vc4_crtc.c |
10030 |
+@@ -32,6 +32,7 @@ |
10031 |
+ #include <linux/clk.h> |
10032 |
+ #include <linux/component.h> |
10033 |
+ #include <linux/of_device.h> |
10034 |
++#include <linux/pm_runtime.h> |
10035 |
+ |
10036 |
+ #include <drm/drm_atomic.h> |
10037 |
+ #include <drm/drm_atomic_helper.h> |
10038 |
+@@ -42,6 +43,7 @@ |
10039 |
+ #include <drm/drm_vblank.h> |
10040 |
+ |
10041 |
+ #include "vc4_drv.h" |
10042 |
++#include "vc4_hdmi.h" |
10043 |
+ #include "vc4_regs.h" |
10044 |
+ |
10045 |
+ #define HVS_FIFO_LATENCY_PIX 6 |
10046 |
+@@ -496,8 +498,10 @@ int vc4_crtc_disable_at_boot(struct drm_crtc *crtc) |
10047 |
+ enum vc4_encoder_type encoder_type; |
10048 |
+ const struct vc4_pv_data *pv_data; |
10049 |
+ struct drm_encoder *encoder; |
10050 |
++ struct vc4_hdmi *vc4_hdmi; |
10051 |
+ unsigned encoder_sel; |
10052 |
+ int channel; |
10053 |
++ int ret; |
10054 |
+ |
10055 |
+ if (!(of_device_is_compatible(vc4_crtc->pdev->dev.of_node, |
10056 |
+ "brcm,bcm2711-pixelvalve2") || |
10057 |
+@@ -525,7 +529,20 @@ int vc4_crtc_disable_at_boot(struct drm_crtc *crtc) |
10058 |
+ if (WARN_ON(!encoder)) |
10059 |
+ return 0; |
10060 |
+ |
10061 |
+- return vc4_crtc_disable(crtc, encoder, NULL, channel); |
10062 |
++ vc4_hdmi = encoder_to_vc4_hdmi(encoder); |
10063 |
++ ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev); |
10064 |
++ if (ret) |
10065 |
++ return ret; |
10066 |
++ |
10067 |
++ ret = vc4_crtc_disable(crtc, encoder, NULL, channel); |
10068 |
++ if (ret) |
10069 |
++ return ret; |
10070 |
++ |
10071 |
++ ret = pm_runtime_put(&vc4_hdmi->pdev->dev); |
10072 |
++ if (ret) |
10073 |
++ return ret; |
10074 |
++ |
10075 |
++ return 0; |
10076 |
+ } |
10077 |
+ |
10078 |
+ static void vc4_crtc_atomic_disable(struct drm_crtc *crtc, |
10079 |
+@@ -691,14 +708,14 @@ static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc) |
10080 |
+ struct drm_crtc *crtc = &vc4_crtc->base; |
10081 |
+ struct drm_device *dev = crtc->dev; |
10082 |
+ struct vc4_dev *vc4 = to_vc4_dev(dev); |
10083 |
+- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); |
10084 |
+- u32 chan = vc4_state->assigned_channel; |
10085 |
++ u32 chan = vc4_crtc->current_hvs_channel; |
10086 |
+ unsigned long flags; |
10087 |
+ |
10088 |
+ spin_lock_irqsave(&dev->event_lock, flags); |
10089 |
++ spin_lock(&vc4_crtc->irq_lock); |
10090 |
+ if (vc4_crtc->event && |
10091 |
+- (vc4_state->mm.start == HVS_READ(SCALER_DISPLACTX(chan)) || |
10092 |
+- vc4_state->feed_txp)) { |
10093 |
++ (vc4_crtc->current_dlist == HVS_READ(SCALER_DISPLACTX(chan)) || |
10094 |
++ vc4_crtc->feeds_txp)) { |
10095 |
+ drm_crtc_send_vblank_event(crtc, vc4_crtc->event); |
10096 |
+ vc4_crtc->event = NULL; |
10097 |
+ drm_crtc_vblank_put(crtc); |
10098 |
+@@ -711,6 +728,7 @@ static void vc4_crtc_handle_page_flip(struct vc4_crtc *vc4_crtc) |
10099 |
+ */ |
10100 |
+ vc4_hvs_unmask_underrun(dev, chan); |
10101 |
+ } |
10102 |
++ spin_unlock(&vc4_crtc->irq_lock); |
10103 |
+ spin_unlock_irqrestore(&dev->event_lock, flags); |
10104 |
+ } |
10105 |
+ |
10106 |
+@@ -876,7 +894,6 @@ struct drm_crtc_state *vc4_crtc_duplicate_state(struct drm_crtc *crtc) |
10107 |
+ return NULL; |
10108 |
+ |
10109 |
+ old_vc4_state = to_vc4_crtc_state(crtc->state); |
10110 |
+- vc4_state->feed_txp = old_vc4_state->feed_txp; |
10111 |
+ vc4_state->margins = old_vc4_state->margins; |
10112 |
+ vc4_state->assigned_channel = old_vc4_state->assigned_channel; |
10113 |
+ |
10114 |
+@@ -937,6 +954,7 @@ static const struct drm_crtc_funcs vc4_crtc_funcs = { |
10115 |
+ static const struct drm_crtc_helper_funcs vc4_crtc_helper_funcs = { |
10116 |
+ .mode_valid = vc4_crtc_mode_valid, |
10117 |
+ .atomic_check = vc4_crtc_atomic_check, |
10118 |
++ .atomic_begin = vc4_hvs_atomic_begin, |
10119 |
+ .atomic_flush = vc4_hvs_atomic_flush, |
10120 |
+ .atomic_enable = vc4_crtc_atomic_enable, |
10121 |
+ .atomic_disable = vc4_crtc_atomic_disable, |
10122 |
+@@ -1111,6 +1129,7 @@ int vc4_crtc_init(struct drm_device *drm, struct vc4_crtc *vc4_crtc, |
10123 |
+ return PTR_ERR(primary_plane); |
10124 |
+ } |
10125 |
+ |
10126 |
++ spin_lock_init(&vc4_crtc->irq_lock); |
10127 |
+ drm_crtc_init_with_planes(drm, crtc, primary_plane, NULL, |
10128 |
+ crtc_funcs, NULL); |
10129 |
+ drm_crtc_helper_add(crtc, crtc_helper_funcs); |
10130 |
+diff --git a/drivers/gpu/drm/vc4/vc4_drv.h b/drivers/gpu/drm/vc4/vc4_drv.h |
10131 |
+index ef73e0aaf7261..4b550ebd9572d 100644 |
10132 |
+--- a/drivers/gpu/drm/vc4/vc4_drv.h |
10133 |
++++ b/drivers/gpu/drm/vc4/vc4_drv.h |
10134 |
+@@ -495,6 +495,33 @@ struct vc4_crtc { |
10135 |
+ struct drm_pending_vblank_event *event; |
10136 |
+ |
10137 |
+ struct debugfs_regset32 regset; |
10138 |
++ |
10139 |
++ /** |
10140 |
++ * @feeds_txp: True if the CRTC feeds our writeback controller. |
10141 |
++ */ |
10142 |
++ bool feeds_txp; |
10143 |
++ |
10144 |
++ /** |
10145 |
++ * @irq_lock: Spinlock protecting the resources shared between |
10146 |
++ * the atomic code and our vblank handler. |
10147 |
++ */ |
10148 |
++ spinlock_t irq_lock; |
10149 |
++ |
10150 |
++ /** |
10151 |
++ * @current_dlist: Start offset of the display list currently |
10152 |
++ * set in the HVS for that CRTC. Protected by @irq_lock, and |
10153 |
++ * copied in vc4_hvs_update_dlist() for the CRTC interrupt |
10154 |
++ * handler to have access to that value. |
10155 |
++ */ |
10156 |
++ unsigned int current_dlist; |
10157 |
++ |
10158 |
++ /** |
10159 |
++ * @current_hvs_channel: HVS channel currently assigned to the |
10160 |
++ * CRTC. Protected by @irq_lock, and copied in |
10161 |
++ * vc4_hvs_atomic_begin() for the CRTC interrupt handler to have |
10162 |
++ * access to that value. |
10163 |
++ */ |
10164 |
++ unsigned int current_hvs_channel; |
10165 |
+ }; |
10166 |
+ |
10167 |
+ static inline struct vc4_crtc * |
10168 |
+@@ -521,7 +548,6 @@ struct vc4_crtc_state { |
10169 |
+ struct drm_crtc_state base; |
10170 |
+ /* Dlist area for this CRTC configuration. */ |
10171 |
+ struct drm_mm_node mm; |
10172 |
+- bool feed_txp; |
10173 |
+ bool txp_armed; |
10174 |
+ unsigned int assigned_channel; |
10175 |
+ |
10176 |
+@@ -908,6 +934,7 @@ extern struct platform_driver vc4_hvs_driver; |
10177 |
+ void vc4_hvs_stop_channel(struct drm_device *dev, unsigned int output); |
10178 |
+ int vc4_hvs_get_fifo_from_output(struct drm_device *dev, unsigned int output); |
10179 |
+ int vc4_hvs_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *state); |
10180 |
++void vc4_hvs_atomic_begin(struct drm_crtc *crtc, struct drm_atomic_state *state); |
10181 |
+ void vc4_hvs_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *state); |
10182 |
+ void vc4_hvs_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *state); |
10183 |
+ void vc4_hvs_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *state); |
10184 |
+diff --git a/drivers/gpu/drm/vc4/vc4_hdmi.c b/drivers/gpu/drm/vc4/vc4_hdmi.c |
10185 |
+index ed8a4b7f8b6e2..5580267fb3624 100644 |
10186 |
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c |
10187 |
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c |
10188 |
+@@ -94,6 +94,7 @@ |
10189 |
+ # define VC4_HD_M_SW_RST BIT(2) |
10190 |
+ # define VC4_HD_M_ENABLE BIT(0) |
10191 |
+ |
10192 |
++#define HSM_MIN_CLOCK_FREQ 120000000 |
10193 |
+ #define CEC_CLOCK_FREQ 40000 |
10194 |
+ |
10195 |
+ #define HDMI_14_MAX_TMDS_CLK (340 * 1000 * 1000) |
10196 |
+@@ -161,12 +162,16 @@ static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi) |
10197 |
+ static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi) {} |
10198 |
+ #endif |
10199 |
+ |
10200 |
++static void vc4_hdmi_enable_scrambling(struct drm_encoder *encoder); |
10201 |
++ |
10202 |
+ static enum drm_connector_status |
10203 |
+ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) |
10204 |
+ { |
10205 |
+ struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector); |
10206 |
+ bool connected = false; |
10207 |
+ |
10208 |
++ WARN_ON(pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev)); |
10209 |
++ |
10210 |
+ if (vc4_hdmi->hpd_gpio && |
10211 |
+ gpiod_get_value_cansleep(vc4_hdmi->hpd_gpio)) { |
10212 |
+ connected = true; |
10213 |
+@@ -187,10 +192,13 @@ vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) |
10214 |
+ } |
10215 |
+ } |
10216 |
+ |
10217 |
++ vc4_hdmi_enable_scrambling(&vc4_hdmi->encoder.base.base); |
10218 |
++ pm_runtime_put(&vc4_hdmi->pdev->dev); |
10219 |
+ return connector_status_connected; |
10220 |
+ } |
10221 |
+ |
10222 |
+ cec_phys_addr_invalidate(vc4_hdmi->cec_adap); |
10223 |
++ pm_runtime_put(&vc4_hdmi->pdev->dev); |
10224 |
+ return connector_status_disconnected; |
10225 |
+ } |
10226 |
+ |
10227 |
+@@ -627,7 +635,6 @@ static void vc4_hdmi_encoder_post_crtc_powerdown(struct drm_encoder *encoder, |
10228 |
+ vc4_hdmi->variant->phy_disable(vc4_hdmi); |
10229 |
+ |
10230 |
+ clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock); |
10231 |
+- clk_disable_unprepare(vc4_hdmi->hsm_clock); |
10232 |
+ clk_disable_unprepare(vc4_hdmi->pixel_clock); |
10233 |
+ |
10234 |
+ ret = pm_runtime_put(&vc4_hdmi->pdev->dev); |
10235 |
+@@ -893,28 +900,10 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder, |
10236 |
+ conn_state_to_vc4_hdmi_conn_state(conn_state); |
10237 |
+ struct drm_display_mode *mode = &encoder->crtc->state->adjusted_mode; |
10238 |
+ struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); |
10239 |
+- unsigned long bvb_rate, pixel_rate, hsm_rate; |
10240 |
++ unsigned long pixel_rate = vc4_conn_state->pixel_rate; |
10241 |
++ unsigned long bvb_rate, hsm_rate; |
10242 |
+ int ret; |
10243 |
+ |
10244 |
+- ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev); |
10245 |
+- if (ret < 0) { |
10246 |
+- DRM_ERROR("Failed to retain power domain: %d\n", ret); |
10247 |
+- return; |
10248 |
+- } |
10249 |
+- |
10250 |
+- pixel_rate = vc4_conn_state->pixel_rate; |
10251 |
+- ret = clk_set_rate(vc4_hdmi->pixel_clock, pixel_rate); |
10252 |
+- if (ret) { |
10253 |
+- DRM_ERROR("Failed to set pixel clock rate: %d\n", ret); |
10254 |
+- return; |
10255 |
+- } |
10256 |
+- |
10257 |
+- ret = clk_prepare_enable(vc4_hdmi->pixel_clock); |
10258 |
+- if (ret) { |
10259 |
+- DRM_ERROR("Failed to turn on pixel clock: %d\n", ret); |
10260 |
+- return; |
10261 |
+- } |
10262 |
+- |
10263 |
+ /* |
10264 |
+ * As stated in RPi's vc4 firmware "HDMI state machine (HSM) clock must |
10265 |
+ * be faster than pixel clock, infinitesimally faster, tested in |
10266 |
+@@ -938,13 +927,25 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder, |
10267 |
+ return; |
10268 |
+ } |
10269 |
+ |
10270 |
+- ret = clk_prepare_enable(vc4_hdmi->hsm_clock); |
10271 |
+- if (ret) { |
10272 |
+- DRM_ERROR("Failed to turn on HSM clock: %d\n", ret); |
10273 |
+- clk_disable_unprepare(vc4_hdmi->pixel_clock); |
10274 |
++ ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev); |
10275 |
++ if (ret < 0) { |
10276 |
++ DRM_ERROR("Failed to retain power domain: %d\n", ret); |
10277 |
+ return; |
10278 |
+ } |
10279 |
+ |
10280 |
++ ret = clk_set_rate(vc4_hdmi->pixel_clock, pixel_rate); |
10281 |
++ if (ret) { |
10282 |
++ DRM_ERROR("Failed to set pixel clock rate: %d\n", ret); |
10283 |
++ goto err_put_runtime_pm; |
10284 |
++ } |
10285 |
++ |
10286 |
++ ret = clk_prepare_enable(vc4_hdmi->pixel_clock); |
10287 |
++ if (ret) { |
10288 |
++ DRM_ERROR("Failed to turn on pixel clock: %d\n", ret); |
10289 |
++ goto err_put_runtime_pm; |
10290 |
++ } |
10291 |
++ |
10292 |
++ |
10293 |
+ vc4_hdmi_cec_update_clk_div(vc4_hdmi); |
10294 |
+ |
10295 |
+ if (pixel_rate > 297000000) |
10296 |
+@@ -957,17 +958,13 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder, |
10297 |
+ ret = clk_set_min_rate(vc4_hdmi->pixel_bvb_clock, bvb_rate); |
10298 |
+ if (ret) { |
10299 |
+ DRM_ERROR("Failed to set pixel bvb clock rate: %d\n", ret); |
10300 |
+- clk_disable_unprepare(vc4_hdmi->hsm_clock); |
10301 |
+- clk_disable_unprepare(vc4_hdmi->pixel_clock); |
10302 |
+- return; |
10303 |
++ goto err_disable_pixel_clock; |
10304 |
+ } |
10305 |
+ |
10306 |
+ ret = clk_prepare_enable(vc4_hdmi->pixel_bvb_clock); |
10307 |
+ if (ret) { |
10308 |
+ DRM_ERROR("Failed to turn on pixel bvb clock: %d\n", ret); |
10309 |
+- clk_disable_unprepare(vc4_hdmi->hsm_clock); |
10310 |
+- clk_disable_unprepare(vc4_hdmi->pixel_clock); |
10311 |
+- return; |
10312 |
++ goto err_disable_pixel_clock; |
10313 |
+ } |
10314 |
+ |
10315 |
+ if (vc4_hdmi->variant->phy_init) |
10316 |
+@@ -980,6 +977,15 @@ static void vc4_hdmi_encoder_pre_crtc_configure(struct drm_encoder *encoder, |
10317 |
+ |
10318 |
+ if (vc4_hdmi->variant->set_timings) |
10319 |
+ vc4_hdmi->variant->set_timings(vc4_hdmi, conn_state, mode); |
10320 |
++ |
10321 |
++ return; |
10322 |
++ |
10323 |
++err_disable_pixel_clock: |
10324 |
++ clk_disable_unprepare(vc4_hdmi->pixel_clock); |
10325 |
++err_put_runtime_pm: |
10326 |
++ pm_runtime_put(&vc4_hdmi->pdev->dev); |
10327 |
++ |
10328 |
++ return; |
10329 |
+ } |
10330 |
+ |
10331 |
+ static void vc4_hdmi_encoder_pre_crtc_enable(struct drm_encoder *encoder, |
10332 |
+@@ -1729,8 +1735,14 @@ static int vc4_hdmi_cec_adap_enable(struct cec_adapter *adap, bool enable) |
10333 |
+ struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap); |
10334 |
+ /* clock period in microseconds */ |
10335 |
+ const u32 usecs = 1000000 / CEC_CLOCK_FREQ; |
10336 |
+- u32 val = HDMI_READ(HDMI_CEC_CNTRL_5); |
10337 |
++ u32 val; |
10338 |
++ int ret; |
10339 |
++ |
10340 |
++ ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev); |
10341 |
++ if (ret) |
10342 |
++ return ret; |
10343 |
+ |
10344 |
++ val = HDMI_READ(HDMI_CEC_CNTRL_5); |
10345 |
+ val &= ~(VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET | |
10346 |
+ VC4_HDMI_CEC_CNT_TO_4700_US_MASK | |
10347 |
+ VC4_HDMI_CEC_CNT_TO_4500_US_MASK); |
10348 |
+@@ -1876,6 +1888,8 @@ static int vc4_hdmi_cec_init(struct vc4_hdmi *vc4_hdmi) |
10349 |
+ if (ret < 0) |
10350 |
+ goto err_remove_handlers; |
10351 |
+ |
10352 |
++ pm_runtime_put(&vc4_hdmi->pdev->dev); |
10353 |
++ |
10354 |
+ return 0; |
10355 |
+ |
10356 |
+ err_remove_handlers: |
10357 |
+@@ -2098,6 +2112,27 @@ static int vc5_hdmi_init_resources(struct vc4_hdmi *vc4_hdmi) |
10358 |
+ return 0; |
10359 |
+ } |
10360 |
+ |
10361 |
++static int __maybe_unused vc4_hdmi_runtime_suspend(struct device *dev) |
10362 |
++{ |
10363 |
++ struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); |
10364 |
++ |
10365 |
++ clk_disable_unprepare(vc4_hdmi->hsm_clock); |
10366 |
++ |
10367 |
++ return 0; |
10368 |
++} |
10369 |
++ |
10370 |
++static int vc4_hdmi_runtime_resume(struct device *dev) |
10371 |
++{ |
10372 |
++ struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev); |
10373 |
++ int ret; |
10374 |
++ |
10375 |
++ ret = clk_prepare_enable(vc4_hdmi->hsm_clock); |
10376 |
++ if (ret) |
10377 |
++ return ret; |
10378 |
++ |
10379 |
++ return 0; |
10380 |
++} |
10381 |
++ |
10382 |
+ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) |
10383 |
+ { |
10384 |
+ const struct vc4_hdmi_variant *variant = of_device_get_match_data(dev); |
10385 |
+@@ -2161,6 +2196,31 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) |
10386 |
+ vc4_hdmi->disable_4kp60 = true; |
10387 |
+ } |
10388 |
+ |
10389 |
++ /* |
10390 |
++ * If we boot without any cable connected to the HDMI connector, |
10391 |
++ * the firmware will skip the HSM initialization and leave it |
10392 |
++ * with a rate of 0, resulting in a bus lockup when we're |
10393 |
++ * accessing the registers even if it's enabled. |
10394 |
++ * |
10395 |
++ * Let's put a sensible default at runtime_resume so that we |
10396 |
++ * don't end up in this situation. |
10397 |
++ */ |
10398 |
++ ret = clk_set_min_rate(vc4_hdmi->hsm_clock, HSM_MIN_CLOCK_FREQ); |
10399 |
++ if (ret) |
10400 |
++ goto err_put_ddc; |
10401 |
++ |
10402 |
++ /* |
10403 |
++ * We need to have the device powered up at this point to call |
10404 |
++ * our reset hook and for the CEC init. |
10405 |
++ */ |
10406 |
++ ret = vc4_hdmi_runtime_resume(dev); |
10407 |
++ if (ret) |
10408 |
++ goto err_put_ddc; |
10409 |
++ |
10410 |
++ pm_runtime_get_noresume(dev); |
10411 |
++ pm_runtime_set_active(dev); |
10412 |
++ pm_runtime_enable(dev); |
10413 |
++ |
10414 |
+ if (vc4_hdmi->variant->reset) |
10415 |
+ vc4_hdmi->variant->reset(vc4_hdmi); |
10416 |
+ |
10417 |
+@@ -2172,8 +2232,6 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) |
10418 |
+ clk_prepare_enable(vc4_hdmi->pixel_bvb_clock); |
10419 |
+ } |
10420 |
+ |
10421 |
+- pm_runtime_enable(dev); |
10422 |
+- |
10423 |
+ drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); |
10424 |
+ drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs); |
10425 |
+ |
10426 |
+@@ -2197,6 +2255,8 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data) |
10427 |
+ vc4_hdmi_debugfs_regs, |
10428 |
+ vc4_hdmi); |
10429 |
+ |
10430 |
++ pm_runtime_put_sync(dev); |
10431 |
++ |
10432 |
+ return 0; |
10433 |
+ |
10434 |
+ err_free_cec: |
10435 |
+@@ -2207,6 +2267,7 @@ err_destroy_conn: |
10436 |
+ vc4_hdmi_connector_destroy(&vc4_hdmi->connector); |
10437 |
+ err_destroy_encoder: |
10438 |
+ drm_encoder_cleanup(encoder); |
10439 |
++ pm_runtime_put_sync(dev); |
10440 |
+ pm_runtime_disable(dev); |
10441 |
+ err_put_ddc: |
10442 |
+ put_device(&vc4_hdmi->ddc->dev); |
10443 |
+@@ -2352,11 +2413,18 @@ static const struct of_device_id vc4_hdmi_dt_match[] = { |
10444 |
+ {} |
10445 |
+ }; |
10446 |
+ |
10447 |
++static const struct dev_pm_ops vc4_hdmi_pm_ops = { |
10448 |
++ SET_RUNTIME_PM_OPS(vc4_hdmi_runtime_suspend, |
10449 |
++ vc4_hdmi_runtime_resume, |
10450 |
++ NULL) |
10451 |
++}; |
10452 |
++ |
10453 |
+ struct platform_driver vc4_hdmi_driver = { |
10454 |
+ .probe = vc4_hdmi_dev_probe, |
10455 |
+ .remove = vc4_hdmi_dev_remove, |
10456 |
+ .driver = { |
10457 |
+ .name = "vc4_hdmi", |
10458 |
+ .of_match_table = vc4_hdmi_dt_match, |
10459 |
++ .pm = &vc4_hdmi_pm_ops, |
10460 |
+ }, |
10461 |
+ }; |
10462 |
+diff --git a/drivers/gpu/drm/vc4/vc4_hvs.c b/drivers/gpu/drm/vc4/vc4_hvs.c |
10463 |
+index c239045e05d6f..604933e20e6a2 100644 |
10464 |
+--- a/drivers/gpu/drm/vc4/vc4_hvs.c |
10465 |
++++ b/drivers/gpu/drm/vc4/vc4_hvs.c |
10466 |
+@@ -365,17 +365,16 @@ static void vc4_hvs_update_dlist(struct drm_crtc *crtc) |
10467 |
+ struct vc4_dev *vc4 = to_vc4_dev(dev); |
10468 |
+ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
10469 |
+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); |
10470 |
++ unsigned long flags; |
10471 |
+ |
10472 |
+ if (crtc->state->event) { |
10473 |
+- unsigned long flags; |
10474 |
+- |
10475 |
+ crtc->state->event->pipe = drm_crtc_index(crtc); |
10476 |
+ |
10477 |
+ WARN_ON(drm_crtc_vblank_get(crtc) != 0); |
10478 |
+ |
10479 |
+ spin_lock_irqsave(&dev->event_lock, flags); |
10480 |
+ |
10481 |
+- if (!vc4_state->feed_txp || vc4_state->txp_armed) { |
10482 |
++ if (!vc4_crtc->feeds_txp || vc4_state->txp_armed) { |
10483 |
+ vc4_crtc->event = crtc->state->event; |
10484 |
+ crtc->state->event = NULL; |
10485 |
+ } |
10486 |
+@@ -388,6 +387,22 @@ static void vc4_hvs_update_dlist(struct drm_crtc *crtc) |
10487 |
+ HVS_WRITE(SCALER_DISPLISTX(vc4_state->assigned_channel), |
10488 |
+ vc4_state->mm.start); |
10489 |
+ } |
10490 |
++ |
10491 |
++ spin_lock_irqsave(&vc4_crtc->irq_lock, flags); |
10492 |
++ vc4_crtc->current_dlist = vc4_state->mm.start; |
10493 |
++ spin_unlock_irqrestore(&vc4_crtc->irq_lock, flags); |
10494 |
++} |
10495 |
++ |
10496 |
++void vc4_hvs_atomic_begin(struct drm_crtc *crtc, |
10497 |
++ struct drm_atomic_state *state) |
10498 |
++{ |
10499 |
++ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
10500 |
++ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc->state); |
10501 |
++ unsigned long flags; |
10502 |
++ |
10503 |
++ spin_lock_irqsave(&vc4_crtc->irq_lock, flags); |
10504 |
++ vc4_crtc->current_hvs_channel = vc4_state->assigned_channel; |
10505 |
++ spin_unlock_irqrestore(&vc4_crtc->irq_lock, flags); |
10506 |
+ } |
10507 |
+ |
10508 |
+ void vc4_hvs_atomic_enable(struct drm_crtc *crtc, |
10509 |
+@@ -395,10 +410,9 @@ void vc4_hvs_atomic_enable(struct drm_crtc *crtc, |
10510 |
+ { |
10511 |
+ struct drm_device *dev = crtc->dev; |
10512 |
+ struct vc4_dev *vc4 = to_vc4_dev(dev); |
10513 |
+- struct drm_crtc_state *new_crtc_state = drm_atomic_get_new_crtc_state(state, crtc); |
10514 |
+- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(new_crtc_state); |
10515 |
+ struct drm_display_mode *mode = &crtc->state->adjusted_mode; |
10516 |
+- bool oneshot = vc4_state->feed_txp; |
10517 |
++ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
10518 |
++ bool oneshot = vc4_crtc->feeds_txp; |
10519 |
+ |
10520 |
+ vc4_hvs_update_dlist(crtc); |
10521 |
+ vc4_hvs_init_channel(vc4, crtc, mode, oneshot); |
10522 |
+diff --git a/drivers/gpu/drm/vc4/vc4_kms.c b/drivers/gpu/drm/vc4/vc4_kms.c |
10523 |
+index b61792d2aa657..6030d4a821555 100644 |
10524 |
+--- a/drivers/gpu/drm/vc4/vc4_kms.c |
10525 |
++++ b/drivers/gpu/drm/vc4/vc4_kms.c |
10526 |
+@@ -233,6 +233,7 @@ static void vc4_hvs_pv_muxing_commit(struct vc4_dev *vc4, |
10527 |
+ unsigned int i; |
10528 |
+ |
10529 |
+ for_each_new_crtc_in_state(state, crtc, crtc_state, i) { |
10530 |
++ struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); |
10531 |
+ struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state); |
10532 |
+ u32 dispctrl; |
10533 |
+ u32 dsp3_mux; |
10534 |
+@@ -253,7 +254,7 @@ static void vc4_hvs_pv_muxing_commit(struct vc4_dev *vc4, |
10535 |
+ * TXP IP, and we need to disable the FIFO2 -> pixelvalve1 |
10536 |
+ * route. |
10537 |
+ */ |
10538 |
+- if (vc4_state->feed_txp) |
10539 |
++ if (vc4_crtc->feeds_txp) |
10540 |
+ dsp3_mux = VC4_SET_FIELD(3, SCALER_DISPCTRL_DSP3_MUX); |
10541 |
+ else |
10542 |
+ dsp3_mux = VC4_SET_FIELD(2, SCALER_DISPCTRL_DSP3_MUX); |
10543 |
+diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c |
10544 |
+index 2fc7f4b5fa098..9809ca3e29451 100644 |
10545 |
+--- a/drivers/gpu/drm/vc4/vc4_txp.c |
10546 |
++++ b/drivers/gpu/drm/vc4/vc4_txp.c |
10547 |
+@@ -391,7 +391,6 @@ static int vc4_txp_atomic_check(struct drm_crtc *crtc, |
10548 |
+ { |
10549 |
+ struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, |
10550 |
+ crtc); |
10551 |
+- struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state); |
10552 |
+ int ret; |
10553 |
+ |
10554 |
+ ret = vc4_hvs_atomic_check(crtc, state); |
10555 |
+@@ -399,7 +398,6 @@ static int vc4_txp_atomic_check(struct drm_crtc *crtc, |
10556 |
+ return ret; |
10557 |
+ |
10558 |
+ crtc_state->no_vblank = true; |
10559 |
+- vc4_state->feed_txp = true; |
10560 |
+ |
10561 |
+ return 0; |
10562 |
+ } |
10563 |
+@@ -437,6 +435,7 @@ static void vc4_txp_atomic_disable(struct drm_crtc *crtc, |
10564 |
+ |
10565 |
+ static const struct drm_crtc_helper_funcs vc4_txp_crtc_helper_funcs = { |
10566 |
+ .atomic_check = vc4_txp_atomic_check, |
10567 |
++ .atomic_begin = vc4_hvs_atomic_begin, |
10568 |
+ .atomic_flush = vc4_hvs_atomic_flush, |
10569 |
+ .atomic_enable = vc4_txp_atomic_enable, |
10570 |
+ .atomic_disable = vc4_txp_atomic_disable, |
10571 |
+@@ -482,6 +481,7 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data) |
10572 |
+ |
10573 |
+ vc4_crtc->pdev = pdev; |
10574 |
+ vc4_crtc->data = &vc4_txp_crtc_data; |
10575 |
++ vc4_crtc->feeds_txp = true; |
10576 |
+ |
10577 |
+ txp->pdev = pdev; |
10578 |
+ |
10579 |
+diff --git a/drivers/gpu/drm/vmwgfx/Makefile b/drivers/gpu/drm/vmwgfx/Makefile |
10580 |
+index bc323f7d40321..18edc7ca5b454 100644 |
10581 |
+--- a/drivers/gpu/drm/vmwgfx/Makefile |
10582 |
++++ b/drivers/gpu/drm/vmwgfx/Makefile |
10583 |
+@@ -9,9 +9,8 @@ vmwgfx-y := vmwgfx_execbuf.o vmwgfx_gmr.o vmwgfx_kms.o vmwgfx_drv.o \ |
10584 |
+ vmwgfx_cotable.o vmwgfx_so.o vmwgfx_binding.o vmwgfx_msg.o \ |
10585 |
+ vmwgfx_simple_resource.o vmwgfx_va.o vmwgfx_blit.o \ |
10586 |
+ vmwgfx_validation.o vmwgfx_page_dirty.o vmwgfx_streamoutput.o \ |
10587 |
+- vmwgfx_devcaps.o ttm_object.o ttm_memory.o |
10588 |
++ vmwgfx_devcaps.o ttm_object.o ttm_memory.o vmwgfx_system_manager.o |
10589 |
+ |
10590 |
+ vmwgfx-$(CONFIG_DRM_FBDEV_EMULATION) += vmwgfx_fb.o |
10591 |
+-vmwgfx-$(CONFIG_TRANSPARENT_HUGEPAGE) += vmwgfx_thp.o |
10592 |
+ |
10593 |
+ obj-$(CONFIG_DRM_VMWGFX) := vmwgfx.o |
10594 |
+diff --git a/drivers/gpu/drm/vmwgfx/ttm_memory.c b/drivers/gpu/drm/vmwgfx/ttm_memory.c |
10595 |
+index edd17c30d5a51..2ced4c06ca451 100644 |
10596 |
+--- a/drivers/gpu/drm/vmwgfx/ttm_memory.c |
10597 |
++++ b/drivers/gpu/drm/vmwgfx/ttm_memory.c |
10598 |
+@@ -34,7 +34,6 @@ |
10599 |
+ #include <linux/mm.h> |
10600 |
+ #include <linux/module.h> |
10601 |
+ #include <linux/slab.h> |
10602 |
+-#include <linux/swap.h> |
10603 |
+ |
10604 |
+ #include <drm/drm_device.h> |
10605 |
+ #include <drm/drm_file.h> |
10606 |
+@@ -173,69 +172,7 @@ static struct kobj_type ttm_mem_zone_kobj_type = { |
10607 |
+ .sysfs_ops = &ttm_mem_zone_ops, |
10608 |
+ .default_attrs = ttm_mem_zone_attrs, |
10609 |
+ }; |
10610 |
+- |
10611 |
+-static struct attribute ttm_mem_global_lower_mem_limit = { |
10612 |
+- .name = "lower_mem_limit", |
10613 |
+- .mode = S_IRUGO | S_IWUSR |
10614 |
+-}; |
10615 |
+- |
10616 |
+-static ssize_t ttm_mem_global_show(struct kobject *kobj, |
10617 |
+- struct attribute *attr, |
10618 |
+- char *buffer) |
10619 |
+-{ |
10620 |
+- struct ttm_mem_global *glob = |
10621 |
+- container_of(kobj, struct ttm_mem_global, kobj); |
10622 |
+- uint64_t val = 0; |
10623 |
+- |
10624 |
+- spin_lock(&glob->lock); |
10625 |
+- val = glob->lower_mem_limit; |
10626 |
+- spin_unlock(&glob->lock); |
10627 |
+- /* convert from number of pages to KB */ |
10628 |
+- val <<= (PAGE_SHIFT - 10); |
10629 |
+- return snprintf(buffer, PAGE_SIZE, "%llu\n", |
10630 |
+- (unsigned long long) val); |
10631 |
+-} |
10632 |
+- |
10633 |
+-static ssize_t ttm_mem_global_store(struct kobject *kobj, |
10634 |
+- struct attribute *attr, |
10635 |
+- const char *buffer, |
10636 |
+- size_t size) |
10637 |
+-{ |
10638 |
+- int chars; |
10639 |
+- uint64_t val64; |
10640 |
+- unsigned long val; |
10641 |
+- struct ttm_mem_global *glob = |
10642 |
+- container_of(kobj, struct ttm_mem_global, kobj); |
10643 |
+- |
10644 |
+- chars = sscanf(buffer, "%lu", &val); |
10645 |
+- if (chars == 0) |
10646 |
+- return size; |
10647 |
+- |
10648 |
+- val64 = val; |
10649 |
+- /* convert from KB to number of pages */ |
10650 |
+- val64 >>= (PAGE_SHIFT - 10); |
10651 |
+- |
10652 |
+- spin_lock(&glob->lock); |
10653 |
+- glob->lower_mem_limit = val64; |
10654 |
+- spin_unlock(&glob->lock); |
10655 |
+- |
10656 |
+- return size; |
10657 |
+-} |
10658 |
+- |
10659 |
+-static struct attribute *ttm_mem_global_attrs[] = { |
10660 |
+- &ttm_mem_global_lower_mem_limit, |
10661 |
+- NULL |
10662 |
+-}; |
10663 |
+- |
10664 |
+-static const struct sysfs_ops ttm_mem_global_ops = { |
10665 |
+- .show = &ttm_mem_global_show, |
10666 |
+- .store = &ttm_mem_global_store, |
10667 |
+-}; |
10668 |
+- |
10669 |
+-static struct kobj_type ttm_mem_glob_kobj_type = { |
10670 |
+- .sysfs_ops = &ttm_mem_global_ops, |
10671 |
+- .default_attrs = ttm_mem_global_attrs, |
10672 |
+-}; |
10673 |
++static struct kobj_type ttm_mem_glob_kobj_type = {0}; |
10674 |
+ |
10675 |
+ static bool ttm_zones_above_swap_target(struct ttm_mem_global *glob, |
10676 |
+ bool from_wq, uint64_t extra) |
10677 |
+@@ -435,11 +372,6 @@ int ttm_mem_global_init(struct ttm_mem_global *glob, struct device *dev) |
10678 |
+ |
10679 |
+ si_meminfo(&si); |
10680 |
+ |
10681 |
+- spin_lock(&glob->lock); |
10682 |
+- /* set it as 0 by default to keep original behavior of OOM */ |
10683 |
+- glob->lower_mem_limit = 0; |
10684 |
+- spin_unlock(&glob->lock); |
10685 |
+- |
10686 |
+ ret = ttm_mem_init_kernel_zone(glob, &si); |
10687 |
+ if (unlikely(ret != 0)) |
10688 |
+ goto out_no_zone; |
10689 |
+@@ -527,35 +459,6 @@ void ttm_mem_global_free(struct ttm_mem_global *glob, |
10690 |
+ } |
10691 |
+ EXPORT_SYMBOL(ttm_mem_global_free); |
10692 |
+ |
10693 |
+-/* |
10694 |
+- * check if the available mem is under lower memory limit |
10695 |
+- * |
10696 |
+- * a. if no swap disk at all or free swap space is under swap_mem_limit |
10697 |
+- * but available system mem is bigger than sys_mem_limit, allow TTM |
10698 |
+- * allocation; |
10699 |
+- * |
10700 |
+- * b. if the available system mem is less than sys_mem_limit but free |
10701 |
+- * swap disk is bigger than swap_mem_limit, allow TTM allocation. |
10702 |
+- */ |
10703 |
+-bool |
10704 |
+-ttm_check_under_lowerlimit(struct ttm_mem_global *glob, |
10705 |
+- uint64_t num_pages, |
10706 |
+- struct ttm_operation_ctx *ctx) |
10707 |
+-{ |
10708 |
+- int64_t available; |
10709 |
+- |
10710 |
+- /* We allow over commit during suspend */ |
10711 |
+- if (ctx->force_alloc) |
10712 |
+- return false; |
10713 |
+- |
10714 |
+- available = get_nr_swap_pages() + si_mem_available(); |
10715 |
+- available -= num_pages; |
10716 |
+- if (available < glob->lower_mem_limit) |
10717 |
+- return true; |
10718 |
+- |
10719 |
+- return false; |
10720 |
+-} |
10721 |
+- |
10722 |
+ static int ttm_mem_global_reserve(struct ttm_mem_global *glob, |
10723 |
+ struct ttm_mem_zone *single_zone, |
10724 |
+ uint64_t amount, bool reserve) |
10725 |
+diff --git a/drivers/gpu/drm/vmwgfx/ttm_memory.h b/drivers/gpu/drm/vmwgfx/ttm_memory.h |
10726 |
+index c50dba7744854..7b0d617ebcb1e 100644 |
10727 |
+--- a/drivers/gpu/drm/vmwgfx/ttm_memory.h |
10728 |
++++ b/drivers/gpu/drm/vmwgfx/ttm_memory.h |
10729 |
+@@ -50,8 +50,6 @@ |
10730 |
+ * @work: The workqueue callback for the shrink queue. |
10731 |
+ * @lock: Lock to protect the @shrink - and the memory accounting members, |
10732 |
+ * that is, essentially the whole structure with some exceptions. |
10733 |
+- * @lower_mem_limit: include lower limit of swap space and lower limit of |
10734 |
+- * system memory. |
10735 |
+ * @zones: Array of pointers to accounting zones. |
10736 |
+ * @num_zones: Number of populated entries in the @zones array. |
10737 |
+ * @zone_kernel: Pointer to the kernel zone. |
10738 |
+@@ -69,7 +67,6 @@ extern struct ttm_mem_global { |
10739 |
+ struct workqueue_struct *swap_queue; |
10740 |
+ struct work_struct work; |
10741 |
+ spinlock_t lock; |
10742 |
+- uint64_t lower_mem_limit; |
10743 |
+ struct ttm_mem_zone *zones[TTM_MEM_MAX_ZONES]; |
10744 |
+ unsigned int num_zones; |
10745 |
+ struct ttm_mem_zone *zone_kernel; |
10746 |
+@@ -91,6 +88,5 @@ int ttm_mem_global_alloc_page(struct ttm_mem_global *glob, |
10747 |
+ void ttm_mem_global_free_page(struct ttm_mem_global *glob, |
10748 |
+ struct page *page, uint64_t size); |
10749 |
+ size_t ttm_round_pot(size_t size); |
10750 |
+-bool ttm_check_under_lowerlimit(struct ttm_mem_global *glob, uint64_t num_pages, |
10751 |
+- struct ttm_operation_ctx *ctx); |
10752 |
++ |
10753 |
+ #endif |
10754 |
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c b/drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c |
10755 |
+index 67db472d3493c..a3bfbb6c3e14a 100644 |
10756 |
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c |
10757 |
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_cmd.c |
10758 |
+@@ -145,6 +145,13 @@ struct vmw_fifo_state *vmw_fifo_create(struct vmw_private *dev_priv) |
10759 |
+ (unsigned int) max, |
10760 |
+ (unsigned int) min, |
10761 |
+ (unsigned int) fifo->capabilities); |
10762 |
++ |
10763 |
++ if (unlikely(min >= max)) { |
10764 |
++ drm_warn(&dev_priv->drm, |
10765 |
++ "FIFO memory is not usable. Driver failed to initialize."); |
10766 |
++ return ERR_PTR(-ENXIO); |
10767 |
++ } |
10768 |
++ |
10769 |
+ return fifo; |
10770 |
+ } |
10771 |
+ |
10772 |
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c |
10773 |
+index ab9a1750e1dff..8449d09c06f7a 100644 |
10774 |
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c |
10775 |
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c |
10776 |
+@@ -707,23 +707,15 @@ static int vmw_dma_masks(struct vmw_private *dev_priv) |
10777 |
+ static int vmw_vram_manager_init(struct vmw_private *dev_priv) |
10778 |
+ { |
10779 |
+ int ret; |
10780 |
+-#ifdef CONFIG_TRANSPARENT_HUGEPAGE |
10781 |
+- ret = vmw_thp_init(dev_priv); |
10782 |
+-#else |
10783 |
+ ret = ttm_range_man_init(&dev_priv->bdev, TTM_PL_VRAM, false, |
10784 |
+ dev_priv->vram_size >> PAGE_SHIFT); |
10785 |
+-#endif |
10786 |
+ ttm_resource_manager_set_used(ttm_manager_type(&dev_priv->bdev, TTM_PL_VRAM), false); |
10787 |
+ return ret; |
10788 |
+ } |
10789 |
+ |
10790 |
+ static void vmw_vram_manager_fini(struct vmw_private *dev_priv) |
10791 |
+ { |
10792 |
+-#ifdef CONFIG_TRANSPARENT_HUGEPAGE |
10793 |
+- vmw_thp_fini(dev_priv); |
10794 |
+-#else |
10795 |
+ ttm_range_man_fini(&dev_priv->bdev, TTM_PL_VRAM); |
10796 |
+-#endif |
10797 |
+ } |
10798 |
+ |
10799 |
+ static int vmw_setup_pci_resources(struct vmw_private *dev, |
10800 |
+@@ -1071,6 +1063,12 @@ static int vmw_driver_load(struct vmw_private *dev_priv, u32 pci_id) |
10801 |
+ "3D will be disabled.\n"); |
10802 |
+ dev_priv->has_mob = false; |
10803 |
+ } |
10804 |
++ if (vmw_sys_man_init(dev_priv) != 0) { |
10805 |
++ drm_info(&dev_priv->drm, |
10806 |
++ "No MOB page table memory available. " |
10807 |
++ "3D will be disabled.\n"); |
10808 |
++ dev_priv->has_mob = false; |
10809 |
++ } |
10810 |
+ } |
10811 |
+ |
10812 |
+ if (dev_priv->has_mob && (dev_priv->capabilities & SVGA_CAP_DX)) { |
10813 |
+@@ -1121,8 +1119,10 @@ out_no_fifo: |
10814 |
+ vmw_overlay_close(dev_priv); |
10815 |
+ vmw_kms_close(dev_priv); |
10816 |
+ out_no_kms: |
10817 |
+- if (dev_priv->has_mob) |
10818 |
++ if (dev_priv->has_mob) { |
10819 |
+ vmw_gmrid_man_fini(dev_priv, VMW_PL_MOB); |
10820 |
++ vmw_sys_man_fini(dev_priv); |
10821 |
++ } |
10822 |
+ if (dev_priv->has_gmr) |
10823 |
+ vmw_gmrid_man_fini(dev_priv, VMW_PL_GMR); |
10824 |
+ vmw_devcaps_destroy(dev_priv); |
10825 |
+@@ -1172,8 +1172,10 @@ static void vmw_driver_unload(struct drm_device *dev) |
10826 |
+ vmw_gmrid_man_fini(dev_priv, VMW_PL_GMR); |
10827 |
+ |
10828 |
+ vmw_release_device_early(dev_priv); |
10829 |
+- if (dev_priv->has_mob) |
10830 |
++ if (dev_priv->has_mob) { |
10831 |
+ vmw_gmrid_man_fini(dev_priv, VMW_PL_MOB); |
10832 |
++ vmw_sys_man_fini(dev_priv); |
10833 |
++ } |
10834 |
+ vmw_devcaps_destroy(dev_priv); |
10835 |
+ vmw_vram_manager_fini(dev_priv); |
10836 |
+ ttm_device_fini(&dev_priv->bdev); |
10837 |
+@@ -1617,34 +1619,40 @@ static int vmw_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
10838 |
+ |
10839 |
+ ret = drm_aperture_remove_conflicting_pci_framebuffers(pdev, &driver); |
10840 |
+ if (ret) |
10841 |
+- return ret; |
10842 |
++ goto out_error; |
10843 |
+ |
10844 |
+ ret = pcim_enable_device(pdev); |
10845 |
+ if (ret) |
10846 |
+- return ret; |
10847 |
++ goto out_error; |
10848 |
+ |
10849 |
+ vmw = devm_drm_dev_alloc(&pdev->dev, &driver, |
10850 |
+ struct vmw_private, drm); |
10851 |
+- if (IS_ERR(vmw)) |
10852 |
+- return PTR_ERR(vmw); |
10853 |
++ if (IS_ERR(vmw)) { |
10854 |
++ ret = PTR_ERR(vmw); |
10855 |
++ goto out_error; |
10856 |
++ } |
10857 |
+ |
10858 |
+ pci_set_drvdata(pdev, &vmw->drm); |
10859 |
+ |
10860 |
+ ret = ttm_mem_global_init(&ttm_mem_glob, &pdev->dev); |
10861 |
+ if (ret) |
10862 |
+- return ret; |
10863 |
++ goto out_error; |
10864 |
+ |
10865 |
+ ret = vmw_driver_load(vmw, ent->device); |
10866 |
+ if (ret) |
10867 |
+- return ret; |
10868 |
++ goto out_release; |
10869 |
+ |
10870 |
+ ret = drm_dev_register(&vmw->drm, 0); |
10871 |
+- if (ret) { |
10872 |
+- vmw_driver_unload(&vmw->drm); |
10873 |
+- return ret; |
10874 |
+- } |
10875 |
++ if (ret) |
10876 |
++ goto out_unload; |
10877 |
+ |
10878 |
+ return 0; |
10879 |
++out_unload: |
10880 |
++ vmw_driver_unload(&vmw->drm); |
10881 |
++out_release: |
10882 |
++ ttm_mem_global_release(&ttm_mem_glob); |
10883 |
++out_error: |
10884 |
++ return ret; |
10885 |
+ } |
10886 |
+ |
10887 |
+ static int __init vmwgfx_init(void) |
10888 |
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h |
10889 |
+index 858aff99a3fe5..2a7cec4cb8a89 100644 |
10890 |
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h |
10891 |
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h |
10892 |
+@@ -59,11 +59,8 @@ |
10893 |
+ #define VMWGFX_DRIVER_MINOR 19 |
10894 |
+ #define VMWGFX_DRIVER_PATCHLEVEL 0 |
10895 |
+ #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) |
10896 |
+-#define VMWGFX_MAX_RELOCATIONS 2048 |
10897 |
+-#define VMWGFX_MAX_VALIDATIONS 2048 |
10898 |
+ #define VMWGFX_MAX_DISPLAYS 16 |
10899 |
+ #define VMWGFX_CMD_BOUNCE_INIT_SIZE 32768 |
10900 |
+-#define VMWGFX_ENABLE_SCREEN_TARGET_OTABLE 1 |
10901 |
+ |
10902 |
+ #define VMWGFX_PCI_ID_SVGA2 0x0405 |
10903 |
+ #define VMWGFX_PCI_ID_SVGA3 0x0406 |
10904 |
+@@ -82,8 +79,9 @@ |
10905 |
+ VMWGFX_NUM_GB_SURFACE +\ |
10906 |
+ VMWGFX_NUM_GB_SCREEN_TARGET) |
10907 |
+ |
10908 |
+-#define VMW_PL_GMR (TTM_PL_PRIV + 0) |
10909 |
+-#define VMW_PL_MOB (TTM_PL_PRIV + 1) |
10910 |
++#define VMW_PL_GMR (TTM_PL_PRIV + 0) |
10911 |
++#define VMW_PL_MOB (TTM_PL_PRIV + 1) |
10912 |
++#define VMW_PL_SYSTEM (TTM_PL_PRIV + 2) |
10913 |
+ |
10914 |
+ #define VMW_RES_CONTEXT ttm_driver_type0 |
10915 |
+ #define VMW_RES_SURFACE ttm_driver_type1 |
10916 |
+@@ -1039,7 +1037,6 @@ extern struct ttm_placement vmw_vram_placement; |
10917 |
+ extern struct ttm_placement vmw_vram_sys_placement; |
10918 |
+ extern struct ttm_placement vmw_vram_gmr_placement; |
10919 |
+ extern struct ttm_placement vmw_sys_placement; |
10920 |
+-extern struct ttm_placement vmw_evictable_placement; |
10921 |
+ extern struct ttm_placement vmw_srf_placement; |
10922 |
+ extern struct ttm_placement vmw_mob_placement; |
10923 |
+ extern struct ttm_placement vmw_nonfixed_placement; |
10924 |
+@@ -1251,6 +1248,12 @@ int vmw_overlay_num_free_overlays(struct vmw_private *dev_priv); |
10925 |
+ int vmw_gmrid_man_init(struct vmw_private *dev_priv, int type); |
10926 |
+ void vmw_gmrid_man_fini(struct vmw_private *dev_priv, int type); |
10927 |
+ |
10928 |
++/** |
10929 |
++ * System memory manager |
10930 |
++ */ |
10931 |
++int vmw_sys_man_init(struct vmw_private *dev_priv); |
10932 |
++void vmw_sys_man_fini(struct vmw_private *dev_priv); |
10933 |
++ |
10934 |
+ /** |
10935 |
+ * Prime - vmwgfx_prime.c |
10936 |
+ */ |
10937 |
+@@ -1551,11 +1554,6 @@ void vmw_bo_dirty_unmap(struct vmw_buffer_object *vbo, |
10938 |
+ vm_fault_t vmw_bo_vm_fault(struct vm_fault *vmf); |
10939 |
+ vm_fault_t vmw_bo_vm_mkwrite(struct vm_fault *vmf); |
10940 |
+ |
10941 |
+-/* Transparent hugepage support - vmwgfx_thp.c */ |
10942 |
+-#ifdef CONFIG_TRANSPARENT_HUGEPAGE |
10943 |
+-extern int vmw_thp_init(struct vmw_private *dev_priv); |
10944 |
+-void vmw_thp_fini(struct vmw_private *dev_priv); |
10945 |
+-#endif |
10946 |
+ |
10947 |
+ /** |
10948 |
+ * VMW_DEBUG_KMS - Debug output for kernel mode-setting |
10949 |
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c |
10950 |
+index f9394207dd3cc..632e587519722 100644 |
10951 |
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c |
10952 |
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_mob.c |
10953 |
+@@ -1,7 +1,7 @@ |
10954 |
+ // SPDX-License-Identifier: GPL-2.0 OR MIT |
10955 |
+ /************************************************************************** |
10956 |
+ * |
10957 |
+- * Copyright 2012-2015 VMware, Inc., Palo Alto, CA., USA |
10958 |
++ * Copyright 2012-2021 VMware, Inc., Palo Alto, CA., USA |
10959 |
+ * |
10960 |
+ * Permission is hereby granted, free of charge, to any person obtaining a |
10961 |
+ * copy of this software and associated documentation files (the |
10962 |
+@@ -29,12 +29,6 @@ |
10963 |
+ |
10964 |
+ #include "vmwgfx_drv.h" |
10965 |
+ |
10966 |
+-/* |
10967 |
+- * If we set up the screen target otable, screen objects stop working. |
10968 |
+- */ |
10969 |
+- |
10970 |
+-#define VMW_OTABLE_SETUP_SUB ((VMWGFX_ENABLE_SCREEN_TARGET_OTABLE ? 0 : 1)) |
10971 |
+- |
10972 |
+ #ifdef CONFIG_64BIT |
10973 |
+ #define VMW_PPN_SIZE 8 |
10974 |
+ #define VMW_MOBFMT_PTDEPTH_0 SVGA3D_MOBFMT_PT64_0 |
10975 |
+@@ -75,7 +69,7 @@ static const struct vmw_otable pre_dx_tables[] = { |
10976 |
+ {VMWGFX_NUM_GB_CONTEXT * sizeof(SVGAOTableContextEntry), NULL, true}, |
10977 |
+ {VMWGFX_NUM_GB_SHADER * sizeof(SVGAOTableShaderEntry), NULL, true}, |
10978 |
+ {VMWGFX_NUM_GB_SCREEN_TARGET * sizeof(SVGAOTableScreenTargetEntry), |
10979 |
+- NULL, VMWGFX_ENABLE_SCREEN_TARGET_OTABLE} |
10980 |
++ NULL, true} |
10981 |
+ }; |
10982 |
+ |
10983 |
+ static const struct vmw_otable dx_tables[] = { |
10984 |
+@@ -84,7 +78,7 @@ static const struct vmw_otable dx_tables[] = { |
10985 |
+ {VMWGFX_NUM_GB_CONTEXT * sizeof(SVGAOTableContextEntry), NULL, true}, |
10986 |
+ {VMWGFX_NUM_GB_SHADER * sizeof(SVGAOTableShaderEntry), NULL, true}, |
10987 |
+ {VMWGFX_NUM_GB_SCREEN_TARGET * sizeof(SVGAOTableScreenTargetEntry), |
10988 |
+- NULL, VMWGFX_ENABLE_SCREEN_TARGET_OTABLE}, |
10989 |
++ NULL, true}, |
10990 |
+ {VMWGFX_NUM_DXCONTEXT * sizeof(SVGAOTableDXContextEntry), NULL, true}, |
10991 |
+ }; |
10992 |
+ |
10993 |
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c |
10994 |
+index d85310b2608dd..f5e90d0e2d0f8 100644 |
10995 |
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c |
10996 |
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c |
10997 |
+@@ -1872,8 +1872,8 @@ int vmw_kms_stdu_init_display(struct vmw_private *dev_priv) |
10998 |
+ int i, ret; |
10999 |
+ |
11000 |
+ |
11001 |
+- /* Do nothing if Screen Target support is turned off */ |
11002 |
+- if (!VMWGFX_ENABLE_SCREEN_TARGET_OTABLE || !dev_priv->has_mob) |
11003 |
++ /* Do nothing if there's no support for MOBs */ |
11004 |
++ if (!dev_priv->has_mob) |
11005 |
+ return -ENOSYS; |
11006 |
+ |
11007 |
+ if (!(dev_priv->capabilities & SVGA_CAP_GBOBJECTS)) |
11008 |
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_system_manager.c b/drivers/gpu/drm/vmwgfx/vmwgfx_system_manager.c |
11009 |
+new file mode 100644 |
11010 |
+index 0000000000000..b0005b03a6174 |
11011 |
+--- /dev/null |
11012 |
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_system_manager.c |
11013 |
+@@ -0,0 +1,90 @@ |
11014 |
++/* SPDX-License-Identifier: GPL-2.0 OR MIT */ |
11015 |
++/* |
11016 |
++ * Copyright 2021 VMware, Inc. |
11017 |
++ * |
11018 |
++ * Permission is hereby granted, free of charge, to any person |
11019 |
++ * obtaining a copy of this software and associated documentation |
11020 |
++ * files (the "Software"), to deal in the Software without |
11021 |
++ * restriction, including without limitation the rights to use, copy, |
11022 |
++ * modify, merge, publish, distribute, sublicense, and/or sell copies |
11023 |
++ * of the Software, and to permit persons to whom the Software is |
11024 |
++ * furnished to do so, subject to the following conditions: |
11025 |
++ * |
11026 |
++ * The above copyright notice and this permission notice shall be |
11027 |
++ * included in all copies or substantial portions of the Software. |
11028 |
++ * |
11029 |
++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
11030 |
++ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
11031 |
++ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND |
11032 |
++ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS |
11033 |
++ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
11034 |
++ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN |
11035 |
++ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
11036 |
++ * SOFTWARE. |
11037 |
++ * |
11038 |
++ */ |
11039 |
++ |
11040 |
++#include "vmwgfx_drv.h" |
11041 |
++ |
11042 |
++#include <drm/ttm/ttm_bo_driver.h> |
11043 |
++#include <drm/ttm/ttm_device.h> |
11044 |
++#include <drm/ttm/ttm_placement.h> |
11045 |
++#include <drm/ttm/ttm_resource.h> |
11046 |
++#include <linux/slab.h> |
11047 |
++ |
11048 |
++ |
11049 |
++static int vmw_sys_man_alloc(struct ttm_resource_manager *man, |
11050 |
++ struct ttm_buffer_object *bo, |
11051 |
++ const struct ttm_place *place, |
11052 |
++ struct ttm_resource **res) |
11053 |
++{ |
11054 |
++ *res = kzalloc(sizeof(**res), GFP_KERNEL); |
11055 |
++ if (!*res) |
11056 |
++ return -ENOMEM; |
11057 |
++ |
11058 |
++ ttm_resource_init(bo, place, *res); |
11059 |
++ return 0; |
11060 |
++} |
11061 |
++ |
11062 |
++static void vmw_sys_man_free(struct ttm_resource_manager *man, |
11063 |
++ struct ttm_resource *res) |
11064 |
++{ |
11065 |
++ kfree(res); |
11066 |
++} |
11067 |
++ |
11068 |
++static const struct ttm_resource_manager_func vmw_sys_manager_func = { |
11069 |
++ .alloc = vmw_sys_man_alloc, |
11070 |
++ .free = vmw_sys_man_free, |
11071 |
++}; |
11072 |
++ |
11073 |
++int vmw_sys_man_init(struct vmw_private *dev_priv) |
11074 |
++{ |
11075 |
++ struct ttm_device *bdev = &dev_priv->bdev; |
11076 |
++ struct ttm_resource_manager *man = |
11077 |
++ kzalloc(sizeof(*man), GFP_KERNEL); |
11078 |
++ |
11079 |
++ if (!man) |
11080 |
++ return -ENOMEM; |
11081 |
++ |
11082 |
++ man->use_tt = true; |
11083 |
++ man->func = &vmw_sys_manager_func; |
11084 |
++ |
11085 |
++ ttm_resource_manager_init(man, 0); |
11086 |
++ ttm_set_driver_manager(bdev, VMW_PL_SYSTEM, man); |
11087 |
++ ttm_resource_manager_set_used(man, true); |
11088 |
++ return 0; |
11089 |
++} |
11090 |
++ |
11091 |
++void vmw_sys_man_fini(struct vmw_private *dev_priv) |
11092 |
++{ |
11093 |
++ struct ttm_resource_manager *man = ttm_manager_type(&dev_priv->bdev, |
11094 |
++ VMW_PL_SYSTEM); |
11095 |
++ |
11096 |
++ ttm_resource_manager_evict_all(&dev_priv->bdev, man); |
11097 |
++ |
11098 |
++ ttm_resource_manager_set_used(man, false); |
11099 |
++ ttm_resource_manager_cleanup(man); |
11100 |
++ |
11101 |
++ ttm_set_driver_manager(&dev_priv->bdev, VMW_PL_SYSTEM, NULL); |
11102 |
++ kfree(man); |
11103 |
++} |
11104 |
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_thp.c b/drivers/gpu/drm/vmwgfx/vmwgfx_thp.c |
11105 |
+deleted file mode 100644 |
11106 |
+index 2a3d3468e4e0a..0000000000000 |
11107 |
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_thp.c |
11108 |
++++ /dev/null |
11109 |
+@@ -1,184 +0,0 @@ |
11110 |
+-// SPDX-License-Identifier: GPL-2.0 OR MIT |
11111 |
+-/* |
11112 |
+- * Huge page-table-entry support for IO memory. |
11113 |
+- * |
11114 |
+- * Copyright (C) 2007-2019 Vmware, Inc. All rights reservedd. |
11115 |
+- */ |
11116 |
+-#include "vmwgfx_drv.h" |
11117 |
+-#include <drm/ttm/ttm_bo_driver.h> |
11118 |
+-#include <drm/ttm/ttm_placement.h> |
11119 |
+-#include <drm/ttm/ttm_range_manager.h> |
11120 |
+- |
11121 |
+-/** |
11122 |
+- * struct vmw_thp_manager - Range manager implementing huge page alignment |
11123 |
+- * |
11124 |
+- * @manager: TTM resource manager. |
11125 |
+- * @mm: The underlying range manager. Protected by @lock. |
11126 |
+- * @lock: Manager lock. |
11127 |
+- */ |
11128 |
+-struct vmw_thp_manager { |
11129 |
+- struct ttm_resource_manager manager; |
11130 |
+- struct drm_mm mm; |
11131 |
+- spinlock_t lock; |
11132 |
+-}; |
11133 |
+- |
11134 |
+-static struct vmw_thp_manager *to_thp_manager(struct ttm_resource_manager *man) |
11135 |
+-{ |
11136 |
+- return container_of(man, struct vmw_thp_manager, manager); |
11137 |
+-} |
11138 |
+- |
11139 |
+-static const struct ttm_resource_manager_func vmw_thp_func; |
11140 |
+- |
11141 |
+-static int vmw_thp_insert_aligned(struct ttm_buffer_object *bo, |
11142 |
+- struct drm_mm *mm, struct drm_mm_node *node, |
11143 |
+- unsigned long align_pages, |
11144 |
+- const struct ttm_place *place, |
11145 |
+- struct ttm_resource *mem, |
11146 |
+- unsigned long lpfn, |
11147 |
+- enum drm_mm_insert_mode mode) |
11148 |
+-{ |
11149 |
+- if (align_pages >= bo->page_alignment && |
11150 |
+- (!bo->page_alignment || align_pages % bo->page_alignment == 0)) { |
11151 |
+- return drm_mm_insert_node_in_range(mm, node, |
11152 |
+- mem->num_pages, |
11153 |
+- align_pages, 0, |
11154 |
+- place->fpfn, lpfn, mode); |
11155 |
+- } |
11156 |
+- |
11157 |
+- return -ENOSPC; |
11158 |
+-} |
11159 |
+- |
11160 |
+-static int vmw_thp_get_node(struct ttm_resource_manager *man, |
11161 |
+- struct ttm_buffer_object *bo, |
11162 |
+- const struct ttm_place *place, |
11163 |
+- struct ttm_resource **res) |
11164 |
+-{ |
11165 |
+- struct vmw_thp_manager *rman = to_thp_manager(man); |
11166 |
+- struct drm_mm *mm = &rman->mm; |
11167 |
+- struct ttm_range_mgr_node *node; |
11168 |
+- unsigned long align_pages; |
11169 |
+- unsigned long lpfn; |
11170 |
+- enum drm_mm_insert_mode mode = DRM_MM_INSERT_BEST; |
11171 |
+- int ret; |
11172 |
+- |
11173 |
+- node = kzalloc(struct_size(node, mm_nodes, 1), GFP_KERNEL); |
11174 |
+- if (!node) |
11175 |
+- return -ENOMEM; |
11176 |
+- |
11177 |
+- ttm_resource_init(bo, place, &node->base); |
11178 |
+- |
11179 |
+- lpfn = place->lpfn; |
11180 |
+- if (!lpfn) |
11181 |
+- lpfn = man->size; |
11182 |
+- |
11183 |
+- mode = DRM_MM_INSERT_BEST; |
11184 |
+- if (place->flags & TTM_PL_FLAG_TOPDOWN) |
11185 |
+- mode = DRM_MM_INSERT_HIGH; |
11186 |
+- |
11187 |
+- spin_lock(&rman->lock); |
11188 |
+- if (IS_ENABLED(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD)) { |
11189 |
+- align_pages = (HPAGE_PUD_SIZE >> PAGE_SHIFT); |
11190 |
+- if (node->base.num_pages >= align_pages) { |
11191 |
+- ret = vmw_thp_insert_aligned(bo, mm, &node->mm_nodes[0], |
11192 |
+- align_pages, place, |
11193 |
+- &node->base, lpfn, mode); |
11194 |
+- if (!ret) |
11195 |
+- goto found_unlock; |
11196 |
+- } |
11197 |
+- } |
11198 |
+- |
11199 |
+- align_pages = (HPAGE_PMD_SIZE >> PAGE_SHIFT); |
11200 |
+- if (node->base.num_pages >= align_pages) { |
11201 |
+- ret = vmw_thp_insert_aligned(bo, mm, &node->mm_nodes[0], |
11202 |
+- align_pages, place, &node->base, |
11203 |
+- lpfn, mode); |
11204 |
+- if (!ret) |
11205 |
+- goto found_unlock; |
11206 |
+- } |
11207 |
+- |
11208 |
+- ret = drm_mm_insert_node_in_range(mm, &node->mm_nodes[0], |
11209 |
+- node->base.num_pages, |
11210 |
+- bo->page_alignment, 0, |
11211 |
+- place->fpfn, lpfn, mode); |
11212 |
+-found_unlock: |
11213 |
+- spin_unlock(&rman->lock); |
11214 |
+- |
11215 |
+- if (unlikely(ret)) { |
11216 |
+- kfree(node); |
11217 |
+- } else { |
11218 |
+- node->base.start = node->mm_nodes[0].start; |
11219 |
+- *res = &node->base; |
11220 |
+- } |
11221 |
+- |
11222 |
+- return ret; |
11223 |
+-} |
11224 |
+- |
11225 |
+-static void vmw_thp_put_node(struct ttm_resource_manager *man, |
11226 |
+- struct ttm_resource *res) |
11227 |
+-{ |
11228 |
+- struct ttm_range_mgr_node *node = to_ttm_range_mgr_node(res); |
11229 |
+- struct vmw_thp_manager *rman = to_thp_manager(man); |
11230 |
+- |
11231 |
+- spin_lock(&rman->lock); |
11232 |
+- drm_mm_remove_node(&node->mm_nodes[0]); |
11233 |
+- spin_unlock(&rman->lock); |
11234 |
+- |
11235 |
+- kfree(node); |
11236 |
+-} |
11237 |
+- |
11238 |
+-int vmw_thp_init(struct vmw_private *dev_priv) |
11239 |
+-{ |
11240 |
+- struct vmw_thp_manager *rman; |
11241 |
+- |
11242 |
+- rman = kzalloc(sizeof(*rman), GFP_KERNEL); |
11243 |
+- if (!rman) |
11244 |
+- return -ENOMEM; |
11245 |
+- |
11246 |
+- ttm_resource_manager_init(&rman->manager, |
11247 |
+- dev_priv->vram_size >> PAGE_SHIFT); |
11248 |
+- |
11249 |
+- rman->manager.func = &vmw_thp_func; |
11250 |
+- drm_mm_init(&rman->mm, 0, rman->manager.size); |
11251 |
+- spin_lock_init(&rman->lock); |
11252 |
+- |
11253 |
+- ttm_set_driver_manager(&dev_priv->bdev, TTM_PL_VRAM, &rman->manager); |
11254 |
+- ttm_resource_manager_set_used(&rman->manager, true); |
11255 |
+- return 0; |
11256 |
+-} |
11257 |
+- |
11258 |
+-void vmw_thp_fini(struct vmw_private *dev_priv) |
11259 |
+-{ |
11260 |
+- struct ttm_resource_manager *man = ttm_manager_type(&dev_priv->bdev, TTM_PL_VRAM); |
11261 |
+- struct vmw_thp_manager *rman = to_thp_manager(man); |
11262 |
+- struct drm_mm *mm = &rman->mm; |
11263 |
+- int ret; |
11264 |
+- |
11265 |
+- ttm_resource_manager_set_used(man, false); |
11266 |
+- |
11267 |
+- ret = ttm_resource_manager_evict_all(&dev_priv->bdev, man); |
11268 |
+- if (ret) |
11269 |
+- return; |
11270 |
+- spin_lock(&rman->lock); |
11271 |
+- drm_mm_clean(mm); |
11272 |
+- drm_mm_takedown(mm); |
11273 |
+- spin_unlock(&rman->lock); |
11274 |
+- ttm_resource_manager_cleanup(man); |
11275 |
+- ttm_set_driver_manager(&dev_priv->bdev, TTM_PL_VRAM, NULL); |
11276 |
+- kfree(rman); |
11277 |
+-} |
11278 |
+- |
11279 |
+-static void vmw_thp_debug(struct ttm_resource_manager *man, |
11280 |
+- struct drm_printer *printer) |
11281 |
+-{ |
11282 |
+- struct vmw_thp_manager *rman = to_thp_manager(man); |
11283 |
+- |
11284 |
+- spin_lock(&rman->lock); |
11285 |
+- drm_mm_print(&rman->mm, printer); |
11286 |
+- spin_unlock(&rman->lock); |
11287 |
+-} |
11288 |
+- |
11289 |
+-static const struct ttm_resource_manager_func vmw_thp_func = { |
11290 |
+- .alloc = vmw_thp_get_node, |
11291 |
+- .free = vmw_thp_put_node, |
11292 |
+- .debug = vmw_thp_debug |
11293 |
+-}; |
11294 |
+diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c |
11295 |
+index 8b8991e3ed2d0..450bb1e9626f7 100644 |
11296 |
+--- a/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c |
11297 |
++++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ttm_buffer.c |
11298 |
+@@ -92,6 +92,13 @@ static const struct ttm_place gmr_vram_placement_flags[] = { |
11299 |
+ } |
11300 |
+ }; |
11301 |
+ |
11302 |
++static const struct ttm_place vmw_sys_placement_flags = { |
11303 |
++ .fpfn = 0, |
11304 |
++ .lpfn = 0, |
11305 |
++ .mem_type = VMW_PL_SYSTEM, |
11306 |
++ .flags = 0 |
11307 |
++}; |
11308 |
++ |
11309 |
+ struct ttm_placement vmw_vram_gmr_placement = { |
11310 |
+ .num_placement = 2, |
11311 |
+ .placement = vram_gmr_placement_flags, |
11312 |
+@@ -113,28 +120,11 @@ struct ttm_placement vmw_sys_placement = { |
11313 |
+ .busy_placement = &sys_placement_flags |
11314 |
+ }; |
11315 |
+ |
11316 |
+-static const struct ttm_place evictable_placement_flags[] = { |
11317 |
+- { |
11318 |
+- .fpfn = 0, |
11319 |
+- .lpfn = 0, |
11320 |
+- .mem_type = TTM_PL_SYSTEM, |
11321 |
+- .flags = 0 |
11322 |
+- }, { |
11323 |
+- .fpfn = 0, |
11324 |
+- .lpfn = 0, |
11325 |
+- .mem_type = TTM_PL_VRAM, |
11326 |
+- .flags = 0 |
11327 |
+- }, { |
11328 |
+- .fpfn = 0, |
11329 |
+- .lpfn = 0, |
11330 |
+- .mem_type = VMW_PL_GMR, |
11331 |
+- .flags = 0 |
11332 |
+- }, { |
11333 |
+- .fpfn = 0, |
11334 |
+- .lpfn = 0, |
11335 |
+- .mem_type = VMW_PL_MOB, |
11336 |
+- .flags = 0 |
11337 |
+- } |
11338 |
++struct ttm_placement vmw_pt_sys_placement = { |
11339 |
++ .num_placement = 1, |
11340 |
++ .placement = &vmw_sys_placement_flags, |
11341 |
++ .num_busy_placement = 1, |
11342 |
++ .busy_placement = &vmw_sys_placement_flags |
11343 |
+ }; |
11344 |
+ |
11345 |
+ static const struct ttm_place nonfixed_placement_flags[] = { |
11346 |
+@@ -156,13 +146,6 @@ static const struct ttm_place nonfixed_placement_flags[] = { |
11347 |
+ } |
11348 |
+ }; |
11349 |
+ |
11350 |
+-struct ttm_placement vmw_evictable_placement = { |
11351 |
+- .num_placement = 4, |
11352 |
+- .placement = evictable_placement_flags, |
11353 |
+- .num_busy_placement = 1, |
11354 |
+- .busy_placement = &sys_placement_flags |
11355 |
+-}; |
11356 |
+- |
11357 |
+ struct ttm_placement vmw_srf_placement = { |
11358 |
+ .num_placement = 1, |
11359 |
+ .num_busy_placement = 2, |
11360 |
+@@ -484,6 +467,9 @@ static int vmw_ttm_bind(struct ttm_device *bdev, |
11361 |
+ &vmw_be->vsgt, ttm->num_pages, |
11362 |
+ vmw_be->gmr_id); |
11363 |
+ break; |
11364 |
++ case VMW_PL_SYSTEM: |
11365 |
++ /* Nothing to be done for a system bind */ |
11366 |
++ break; |
11367 |
+ default: |
11368 |
+ BUG(); |
11369 |
+ } |
11370 |
+@@ -507,6 +493,8 @@ static void vmw_ttm_unbind(struct ttm_device *bdev, |
11371 |
+ case VMW_PL_MOB: |
11372 |
+ vmw_mob_unbind(vmw_be->dev_priv, vmw_be->mob); |
11373 |
+ break; |
11374 |
++ case VMW_PL_SYSTEM: |
11375 |
++ break; |
11376 |
+ default: |
11377 |
+ BUG(); |
11378 |
+ } |
11379 |
+@@ -628,6 +616,7 @@ static int vmw_ttm_io_mem_reserve(struct ttm_device *bdev, struct ttm_resource * |
11380 |
+ |
11381 |
+ switch (mem->mem_type) { |
11382 |
+ case TTM_PL_SYSTEM: |
11383 |
++ case VMW_PL_SYSTEM: |
11384 |
+ case VMW_PL_GMR: |
11385 |
+ case VMW_PL_MOB: |
11386 |
+ return 0; |
11387 |
+@@ -674,6 +663,11 @@ static void vmw_swap_notify(struct ttm_buffer_object *bo) |
11388 |
+ (void) ttm_bo_wait(bo, false, false); |
11389 |
+ } |
11390 |
+ |
11391 |
++static bool vmw_memtype_is_system(uint32_t mem_type) |
11392 |
++{ |
11393 |
++ return mem_type == TTM_PL_SYSTEM || mem_type == VMW_PL_SYSTEM; |
11394 |
++} |
11395 |
++ |
11396 |
+ static int vmw_move(struct ttm_buffer_object *bo, |
11397 |
+ bool evict, |
11398 |
+ struct ttm_operation_ctx *ctx, |
11399 |
+@@ -684,7 +678,7 @@ static int vmw_move(struct ttm_buffer_object *bo, |
11400 |
+ struct ttm_resource_manager *new_man = ttm_manager_type(bo->bdev, new_mem->mem_type); |
11401 |
+ int ret; |
11402 |
+ |
11403 |
+- if (new_man->use_tt && new_mem->mem_type != TTM_PL_SYSTEM) { |
11404 |
++ if (new_man->use_tt && !vmw_memtype_is_system(new_mem->mem_type)) { |
11405 |
+ ret = vmw_ttm_bind(bo->bdev, bo->ttm, new_mem); |
11406 |
+ if (ret) |
11407 |
+ return ret; |
11408 |
+@@ -693,7 +687,7 @@ static int vmw_move(struct ttm_buffer_object *bo, |
11409 |
+ vmw_move_notify(bo, bo->resource, new_mem); |
11410 |
+ |
11411 |
+ if (old_man->use_tt && new_man->use_tt) { |
11412 |
+- if (bo->resource->mem_type == TTM_PL_SYSTEM) { |
11413 |
++ if (vmw_memtype_is_system(bo->resource->mem_type)) { |
11414 |
+ ttm_bo_move_null(bo, new_mem); |
11415 |
+ return 0; |
11416 |
+ } |
11417 |
+@@ -740,7 +734,7 @@ int vmw_bo_create_and_populate(struct vmw_private *dev_priv, |
11418 |
+ int ret; |
11419 |
+ |
11420 |
+ ret = vmw_bo_create_kernel(dev_priv, bo_size, |
11421 |
+- &vmw_sys_placement, |
11422 |
++ &vmw_pt_sys_placement, |
11423 |
+ &bo); |
11424 |
+ if (unlikely(ret != 0)) |
11425 |
+ return ret; |
11426 |
+diff --git a/drivers/gpu/host1x/Kconfig b/drivers/gpu/host1x/Kconfig |
11427 |
+index 6dab94adf25e5..6815b4db17c1b 100644 |
11428 |
+--- a/drivers/gpu/host1x/Kconfig |
11429 |
++++ b/drivers/gpu/host1x/Kconfig |
11430 |
+@@ -2,6 +2,7 @@ |
11431 |
+ config TEGRA_HOST1X |
11432 |
+ tristate "NVIDIA Tegra host1x driver" |
11433 |
+ depends on ARCH_TEGRA || (ARM && COMPILE_TEST) |
11434 |
++ select DMA_SHARED_BUFFER |
11435 |
+ select IOMMU_IOVA |
11436 |
+ help |
11437 |
+ Driver for the NVIDIA Tegra host1x hardware. |
11438 |
+diff --git a/drivers/gpu/host1x/dev.c b/drivers/gpu/host1x/dev.c |
11439 |
+index fbb6447b8659e..3872e4cd26989 100644 |
11440 |
+--- a/drivers/gpu/host1x/dev.c |
11441 |
++++ b/drivers/gpu/host1x/dev.c |
11442 |
+@@ -18,6 +18,10 @@ |
11443 |
+ #include <trace/events/host1x.h> |
11444 |
+ #undef CREATE_TRACE_POINTS |
11445 |
+ |
11446 |
++#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) |
11447 |
++#include <asm/dma-iommu.h> |
11448 |
++#endif |
11449 |
++ |
11450 |
+ #include "bus.h" |
11451 |
+ #include "channel.h" |
11452 |
+ #include "debug.h" |
11453 |
+@@ -238,6 +242,17 @@ static struct iommu_domain *host1x_iommu_attach(struct host1x *host) |
11454 |
+ struct iommu_domain *domain = iommu_get_domain_for_dev(host->dev); |
11455 |
+ int err; |
11456 |
+ |
11457 |
++#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) |
11458 |
++ if (host->dev->archdata.mapping) { |
11459 |
++ struct dma_iommu_mapping *mapping = |
11460 |
++ to_dma_iommu_mapping(host->dev); |
11461 |
++ arm_iommu_detach_device(host->dev); |
11462 |
++ arm_iommu_release_mapping(mapping); |
11463 |
++ |
11464 |
++ domain = iommu_get_domain_for_dev(host->dev); |
11465 |
++ } |
11466 |
++#endif |
11467 |
++ |
11468 |
+ /* |
11469 |
+ * We may not always want to enable IOMMU support (for example if the |
11470 |
+ * host1x firewall is already enabled and we don't support addressing |
11471 |
+diff --git a/drivers/hid/hid-apple.c b/drivers/hid/hid-apple.c |
11472 |
+index 6ccfa0cb997ab..b683c0e8557d4 100644 |
11473 |
+--- a/drivers/hid/hid-apple.c |
11474 |
++++ b/drivers/hid/hid-apple.c |
11475 |
+@@ -429,7 +429,7 @@ static int apple_input_configured(struct hid_device *hdev, |
11476 |
+ |
11477 |
+ if ((asc->quirks & APPLE_HAS_FN) && !asc->fn_found) { |
11478 |
+ hid_info(hdev, "Fn key not found (Apple Wireless Keyboard clone?), disabling Fn key handling\n"); |
11479 |
+- asc->quirks = 0; |
11480 |
++ asc->quirks &= ~APPLE_HAS_FN; |
11481 |
+ } |
11482 |
+ |
11483 |
+ return 0; |
11484 |
+diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h |
11485 |
+index 70e65eb1b868d..bdedf594e2d1e 100644 |
11486 |
+--- a/drivers/hid/hid-ids.h |
11487 |
++++ b/drivers/hid/hid-ids.h |
11488 |
+@@ -394,6 +394,7 @@ |
11489 |
+ #define USB_DEVICE_ID_HP_X2 0x074d |
11490 |
+ #define USB_DEVICE_ID_HP_X2_10_COVER 0x0755 |
11491 |
+ #define I2C_DEVICE_ID_HP_SPECTRE_X360_15 0x2817 |
11492 |
++#define I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100 0x29CF |
11493 |
+ #define USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN 0x2544 |
11494 |
+ #define USB_DEVICE_ID_ASUS_UX550_TOUCHSCREEN 0x2706 |
11495 |
+ #define I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN 0x261A |
11496 |
+diff --git a/drivers/hid/hid-input.c b/drivers/hid/hid-input.c |
11497 |
+index 55017db98d896..3d33c0c06cbb3 100644 |
11498 |
+--- a/drivers/hid/hid-input.c |
11499 |
++++ b/drivers/hid/hid-input.c |
11500 |
+@@ -327,6 +327,8 @@ static const struct hid_device_id hid_battery_quirks[] = { |
11501 |
+ HID_BATTERY_QUIRK_IGNORE }, |
11502 |
+ { HID_USB_DEVICE(USB_VENDOR_ID_ELAN, USB_DEVICE_ID_ASUS_UX550VE_TOUCHSCREEN), |
11503 |
+ HID_BATTERY_QUIRK_IGNORE }, |
11504 |
++ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_ENVY_X360_15T_DR100), |
11505 |
++ HID_BATTERY_QUIRK_IGNORE }, |
11506 |
+ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_HP_SPECTRE_X360_15), |
11507 |
+ HID_BATTERY_QUIRK_IGNORE }, |
11508 |
+ { HID_I2C_DEVICE(USB_VENDOR_ID_ELAN, I2C_DEVICE_ID_SURFACE_GO_TOUCHSCREEN), |
11509 |
+@@ -1330,6 +1332,12 @@ void hidinput_hid_event(struct hid_device *hid, struct hid_field *field, struct |
11510 |
+ |
11511 |
+ input = field->hidinput->input; |
11512 |
+ |
11513 |
++ if (usage->type == EV_ABS && |
11514 |
++ (((*quirks & HID_QUIRK_X_INVERT) && usage->code == ABS_X) || |
11515 |
++ ((*quirks & HID_QUIRK_Y_INVERT) && usage->code == ABS_Y))) { |
11516 |
++ value = field->logical_maximum - value; |
11517 |
++ } |
11518 |
++ |
11519 |
+ if (usage->hat_min < usage->hat_max || usage->hat_dir) { |
11520 |
+ int hat_dir = usage->hat_dir; |
11521 |
+ if (!hat_dir) |
11522 |
+diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c |
11523 |
+index d7687ce706144..b8b08f0a8c541 100644 |
11524 |
+--- a/drivers/hid/hid-magicmouse.c |
11525 |
++++ b/drivers/hid/hid-magicmouse.c |
11526 |
+@@ -57,6 +57,8 @@ MODULE_PARM_DESC(report_undeciphered, "Report undeciphered multi-touch state fie |
11527 |
+ #define MOUSE_REPORT_ID 0x29 |
11528 |
+ #define MOUSE2_REPORT_ID 0x12 |
11529 |
+ #define DOUBLE_REPORT_ID 0xf7 |
11530 |
++#define USB_BATTERY_TIMEOUT_MS 60000 |
11531 |
++ |
11532 |
+ /* These definitions are not precise, but they're close enough. (Bits |
11533 |
+ * 0x03 seem to indicate the aspect ratio of the touch, bits 0x70 seem |
11534 |
+ * to be some kind of bit mask -- 0x20 may be a near-field reading, |
11535 |
+@@ -140,6 +142,7 @@ struct magicmouse_sc { |
11536 |
+ |
11537 |
+ struct hid_device *hdev; |
11538 |
+ struct delayed_work work; |
11539 |
++ struct timer_list battery_timer; |
11540 |
+ }; |
11541 |
+ |
11542 |
+ static int magicmouse_firm_touch(struct magicmouse_sc *msc) |
11543 |
+@@ -738,6 +741,44 @@ static void magicmouse_enable_mt_work(struct work_struct *work) |
11544 |
+ hid_err(msc->hdev, "unable to request touch data (%d)\n", ret); |
11545 |
+ } |
11546 |
+ |
11547 |
++static int magicmouse_fetch_battery(struct hid_device *hdev) |
11548 |
++{ |
11549 |
++#ifdef CONFIG_HID_BATTERY_STRENGTH |
11550 |
++ struct hid_report_enum *report_enum; |
11551 |
++ struct hid_report *report; |
11552 |
++ |
11553 |
++ if (!hdev->battery || hdev->vendor != USB_VENDOR_ID_APPLE || |
11554 |
++ (hdev->product != USB_DEVICE_ID_APPLE_MAGICMOUSE2 && |
11555 |
++ hdev->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2)) |
11556 |
++ return -1; |
11557 |
++ |
11558 |
++ report_enum = &hdev->report_enum[hdev->battery_report_type]; |
11559 |
++ report = report_enum->report_id_hash[hdev->battery_report_id]; |
11560 |
++ |
11561 |
++ if (!report || report->maxfield < 1) |
11562 |
++ return -1; |
11563 |
++ |
11564 |
++ if (hdev->battery_capacity == hdev->battery_max) |
11565 |
++ return -1; |
11566 |
++ |
11567 |
++ hid_hw_request(hdev, report, HID_REQ_GET_REPORT); |
11568 |
++ return 0; |
11569 |
++#else |
11570 |
++ return -1; |
11571 |
++#endif |
11572 |
++} |
11573 |
++ |
11574 |
++static void magicmouse_battery_timer_tick(struct timer_list *t) |
11575 |
++{ |
11576 |
++ struct magicmouse_sc *msc = from_timer(msc, t, battery_timer); |
11577 |
++ struct hid_device *hdev = msc->hdev; |
11578 |
++ |
11579 |
++ if (magicmouse_fetch_battery(hdev) == 0) { |
11580 |
++ mod_timer(&msc->battery_timer, |
11581 |
++ jiffies + msecs_to_jiffies(USB_BATTERY_TIMEOUT_MS)); |
11582 |
++ } |
11583 |
++} |
11584 |
++ |
11585 |
+ static int magicmouse_probe(struct hid_device *hdev, |
11586 |
+ const struct hid_device_id *id) |
11587 |
+ { |
11588 |
+@@ -745,11 +786,6 @@ static int magicmouse_probe(struct hid_device *hdev, |
11589 |
+ struct hid_report *report; |
11590 |
+ int ret; |
11591 |
+ |
11592 |
+- if (id->vendor == USB_VENDOR_ID_APPLE && |
11593 |
+- id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 && |
11594 |
+- hdev->type != HID_TYPE_USBMOUSE) |
11595 |
+- return -ENODEV; |
11596 |
+- |
11597 |
+ msc = devm_kzalloc(&hdev->dev, sizeof(*msc), GFP_KERNEL); |
11598 |
+ if (msc == NULL) { |
11599 |
+ hid_err(hdev, "can't alloc magicmouse descriptor\n"); |
11600 |
+@@ -775,6 +811,16 @@ static int magicmouse_probe(struct hid_device *hdev, |
11601 |
+ return ret; |
11602 |
+ } |
11603 |
+ |
11604 |
++ timer_setup(&msc->battery_timer, magicmouse_battery_timer_tick, 0); |
11605 |
++ mod_timer(&msc->battery_timer, |
11606 |
++ jiffies + msecs_to_jiffies(USB_BATTERY_TIMEOUT_MS)); |
11607 |
++ magicmouse_fetch_battery(hdev); |
11608 |
++ |
11609 |
++ if (id->vendor == USB_VENDOR_ID_APPLE && |
11610 |
++ (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 || |
11611 |
++ (id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 && hdev->type != HID_TYPE_USBMOUSE))) |
11612 |
++ return 0; |
11613 |
++ |
11614 |
+ if (!msc->input) { |
11615 |
+ hid_err(hdev, "magicmouse input not registered\n"); |
11616 |
+ ret = -ENOMEM; |
11617 |
+@@ -827,6 +873,7 @@ static int magicmouse_probe(struct hid_device *hdev, |
11618 |
+ |
11619 |
+ return 0; |
11620 |
+ err_stop_hw: |
11621 |
++ del_timer_sync(&msc->battery_timer); |
11622 |
+ hid_hw_stop(hdev); |
11623 |
+ return ret; |
11624 |
+ } |
11625 |
+@@ -835,17 +882,52 @@ static void magicmouse_remove(struct hid_device *hdev) |
11626 |
+ { |
11627 |
+ struct magicmouse_sc *msc = hid_get_drvdata(hdev); |
11628 |
+ |
11629 |
+- if (msc) |
11630 |
++ if (msc) { |
11631 |
+ cancel_delayed_work_sync(&msc->work); |
11632 |
++ del_timer_sync(&msc->battery_timer); |
11633 |
++ } |
11634 |
+ |
11635 |
+ hid_hw_stop(hdev); |
11636 |
+ } |
11637 |
+ |
11638 |
++static __u8 *magicmouse_report_fixup(struct hid_device *hdev, __u8 *rdesc, |
11639 |
++ unsigned int *rsize) |
11640 |
++{ |
11641 |
++ /* |
11642 |
++ * Change the usage from: |
11643 |
++ * 0x06, 0x00, 0xff, // Usage Page (Vendor Defined Page 1) 0 |
11644 |
++ * 0x09, 0x0b, // Usage (Vendor Usage 0x0b) 3 |
11645 |
++ * To: |
11646 |
++ * 0x05, 0x01, // Usage Page (Generic Desktop) 0 |
11647 |
++ * 0x09, 0x02, // Usage (Mouse) 2 |
11648 |
++ */ |
11649 |
++ if (hdev->vendor == USB_VENDOR_ID_APPLE && |
11650 |
++ (hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 || |
11651 |
++ hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2) && |
11652 |
++ *rsize == 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) { |
11653 |
++ hid_info(hdev, |
11654 |
++ "fixing up magicmouse battery report descriptor\n"); |
11655 |
++ *rsize = *rsize - 1; |
11656 |
++ rdesc = kmemdup(rdesc + 1, *rsize, GFP_KERNEL); |
11657 |
++ if (!rdesc) |
11658 |
++ return NULL; |
11659 |
++ |
11660 |
++ rdesc[0] = 0x05; |
11661 |
++ rdesc[1] = 0x01; |
11662 |
++ rdesc[2] = 0x09; |
11663 |
++ rdesc[3] = 0x02; |
11664 |
++ } |
11665 |
++ |
11666 |
++ return rdesc; |
11667 |
++} |
11668 |
++ |
11669 |
+ static const struct hid_device_id magic_mice[] = { |
11670 |
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
11671 |
+ USB_DEVICE_ID_APPLE_MAGICMOUSE), .driver_data = 0 }, |
11672 |
+ { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, |
11673 |
+ USB_DEVICE_ID_APPLE_MAGICMOUSE2), .driver_data = 0 }, |
11674 |
++ { HID_USB_DEVICE(USB_VENDOR_ID_APPLE, |
11675 |
++ USB_DEVICE_ID_APPLE_MAGICMOUSE2), .driver_data = 0 }, |
11676 |
+ { HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_APPLE, |
11677 |
+ USB_DEVICE_ID_APPLE_MAGICTRACKPAD), .driver_data = 0 }, |
11678 |
+ { HID_BLUETOOTH_DEVICE(BT_VENDOR_ID_APPLE, |
11679 |
+@@ -861,6 +943,7 @@ static struct hid_driver magicmouse_driver = { |
11680 |
+ .id_table = magic_mice, |
11681 |
+ .probe = magicmouse_probe, |
11682 |
+ .remove = magicmouse_remove, |
11683 |
++ .report_fixup = magicmouse_report_fixup, |
11684 |
+ .raw_event = magicmouse_raw_event, |
11685 |
+ .event = magicmouse_event, |
11686 |
+ .input_mapping = magicmouse_input_mapping, |
11687 |
+diff --git a/drivers/hid/hid-uclogic-params.c b/drivers/hid/hid-uclogic-params.c |
11688 |
+index adff1bd68d9f8..3e70f969fb849 100644 |
11689 |
+--- a/drivers/hid/hid-uclogic-params.c |
11690 |
++++ b/drivers/hid/hid-uclogic-params.c |
11691 |
+@@ -66,7 +66,7 @@ static int uclogic_params_get_str_desc(__u8 **pbuf, struct hid_device *hdev, |
11692 |
+ __u8 idx, size_t len) |
11693 |
+ { |
11694 |
+ int rc; |
11695 |
+- struct usb_device *udev = hid_to_usb_dev(hdev); |
11696 |
++ struct usb_device *udev; |
11697 |
+ __u8 *buf = NULL; |
11698 |
+ |
11699 |
+ /* Check arguments */ |
11700 |
+@@ -75,6 +75,8 @@ static int uclogic_params_get_str_desc(__u8 **pbuf, struct hid_device *hdev, |
11701 |
+ goto cleanup; |
11702 |
+ } |
11703 |
+ |
11704 |
++ udev = hid_to_usb_dev(hdev); |
11705 |
++ |
11706 |
+ buf = kmalloc(len, GFP_KERNEL); |
11707 |
+ if (buf == NULL) { |
11708 |
+ rc = -ENOMEM; |
11709 |
+@@ -450,7 +452,7 @@ static int uclogic_params_frame_init_v1_buttonpad( |
11710 |
+ { |
11711 |
+ int rc; |
11712 |
+ bool found = false; |
11713 |
+- struct usb_device *usb_dev = hid_to_usb_dev(hdev); |
11714 |
++ struct usb_device *usb_dev; |
11715 |
+ char *str_buf = NULL; |
11716 |
+ const size_t str_len = 16; |
11717 |
+ |
11718 |
+@@ -460,6 +462,8 @@ static int uclogic_params_frame_init_v1_buttonpad( |
11719 |
+ goto cleanup; |
11720 |
+ } |
11721 |
+ |
11722 |
++ usb_dev = hid_to_usb_dev(hdev); |
11723 |
++ |
11724 |
+ /* |
11725 |
+ * Enable generic button mode |
11726 |
+ */ |
11727 |
+@@ -707,9 +711,9 @@ static int uclogic_params_huion_init(struct uclogic_params *params, |
11728 |
+ struct hid_device *hdev) |
11729 |
+ { |
11730 |
+ int rc; |
11731 |
+- struct usb_device *udev = hid_to_usb_dev(hdev); |
11732 |
+- struct usb_interface *iface = to_usb_interface(hdev->dev.parent); |
11733 |
+- __u8 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; |
11734 |
++ struct usb_device *udev; |
11735 |
++ struct usb_interface *iface; |
11736 |
++ __u8 bInterfaceNumber; |
11737 |
+ bool found; |
11738 |
+ /* The resulting parameters (noop) */ |
11739 |
+ struct uclogic_params p = {0, }; |
11740 |
+@@ -723,6 +727,10 @@ static int uclogic_params_huion_init(struct uclogic_params *params, |
11741 |
+ goto cleanup; |
11742 |
+ } |
11743 |
+ |
11744 |
++ udev = hid_to_usb_dev(hdev); |
11745 |
++ iface = to_usb_interface(hdev->dev.parent); |
11746 |
++ bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; |
11747 |
++ |
11748 |
+ /* If it's not a pen interface */ |
11749 |
+ if (bInterfaceNumber != 0) { |
11750 |
+ /* TODO: Consider marking the interface invalid */ |
11751 |
+@@ -834,10 +842,10 @@ int uclogic_params_init(struct uclogic_params *params, |
11752 |
+ struct hid_device *hdev) |
11753 |
+ { |
11754 |
+ int rc; |
11755 |
+- struct usb_device *udev = hid_to_usb_dev(hdev); |
11756 |
+- __u8 bNumInterfaces = udev->config->desc.bNumInterfaces; |
11757 |
+- struct usb_interface *iface = to_usb_interface(hdev->dev.parent); |
11758 |
+- __u8 bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; |
11759 |
++ struct usb_device *udev; |
11760 |
++ __u8 bNumInterfaces; |
11761 |
++ struct usb_interface *iface; |
11762 |
++ __u8 bInterfaceNumber; |
11763 |
+ bool found; |
11764 |
+ /* The resulting parameters (noop) */ |
11765 |
+ struct uclogic_params p = {0, }; |
11766 |
+@@ -848,6 +856,11 @@ int uclogic_params_init(struct uclogic_params *params, |
11767 |
+ goto cleanup; |
11768 |
+ } |
11769 |
+ |
11770 |
++ udev = hid_to_usb_dev(hdev); |
11771 |
++ bNumInterfaces = udev->config->desc.bNumInterfaces; |
11772 |
++ iface = to_usb_interface(hdev->dev.parent); |
11773 |
++ bInterfaceNumber = iface->cur_altsetting->desc.bInterfaceNumber; |
11774 |
++ |
11775 |
+ /* |
11776 |
+ * Set replacement report descriptor if the original matches the |
11777 |
+ * specified size. Otherwise keep interface unchanged. |
11778 |
+diff --git a/drivers/hid/hid-vivaldi.c b/drivers/hid/hid-vivaldi.c |
11779 |
+index 72957a9f71170..576518e704ee6 100644 |
11780 |
+--- a/drivers/hid/hid-vivaldi.c |
11781 |
++++ b/drivers/hid/hid-vivaldi.c |
11782 |
+@@ -74,10 +74,11 @@ static void vivaldi_feature_mapping(struct hid_device *hdev, |
11783 |
+ struct hid_usage *usage) |
11784 |
+ { |
11785 |
+ struct vivaldi_data *drvdata = hid_get_drvdata(hdev); |
11786 |
++ struct hid_report *report = field->report; |
11787 |
+ int fn_key; |
11788 |
+ int ret; |
11789 |
+ u32 report_len; |
11790 |
+- u8 *buf; |
11791 |
++ u8 *report_data, *buf; |
11792 |
+ |
11793 |
+ if (field->logical != HID_USAGE_FN_ROW_PHYSMAP || |
11794 |
+ (usage->hid & HID_USAGE_PAGE) != HID_UP_ORDINAL) |
11795 |
+@@ -89,12 +90,24 @@ static void vivaldi_feature_mapping(struct hid_device *hdev, |
11796 |
+ if (fn_key > drvdata->max_function_row_key) |
11797 |
+ drvdata->max_function_row_key = fn_key; |
11798 |
+ |
11799 |
+- buf = hid_alloc_report_buf(field->report, GFP_KERNEL); |
11800 |
+- if (!buf) |
11801 |
++ report_data = buf = hid_alloc_report_buf(report, GFP_KERNEL); |
11802 |
++ if (!report_data) |
11803 |
+ return; |
11804 |
+ |
11805 |
+- report_len = hid_report_len(field->report); |
11806 |
+- ret = hid_hw_raw_request(hdev, field->report->id, buf, |
11807 |
++ report_len = hid_report_len(report); |
11808 |
++ if (!report->id) { |
11809 |
++ /* |
11810 |
++ * hid_hw_raw_request() will stuff report ID (which will be 0) |
11811 |
++ * into the first byte of the buffer even for unnumbered |
11812 |
++ * reports, so we need to account for this to avoid getting |
11813 |
++ * -EOVERFLOW in return. |
11814 |
++ * Note that hid_alloc_report_buf() adds 7 bytes to the size |
11815 |
++ * so we can safely say that we have space for an extra byte. |
11816 |
++ */ |
11817 |
++ report_len++; |
11818 |
++ } |
11819 |
++ |
11820 |
++ ret = hid_hw_raw_request(hdev, report->id, report_data, |
11821 |
+ report_len, HID_FEATURE_REPORT, |
11822 |
+ HID_REQ_GET_REPORT); |
11823 |
+ if (ret < 0) { |
11824 |
+@@ -103,7 +116,16 @@ static void vivaldi_feature_mapping(struct hid_device *hdev, |
11825 |
+ goto out; |
11826 |
+ } |
11827 |
+ |
11828 |
+- ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, buf, |
11829 |
++ if (!report->id) { |
11830 |
++ /* |
11831 |
++ * Undo the damage from hid_hw_raw_request() for unnumbered |
11832 |
++ * reports. |
11833 |
++ */ |
11834 |
++ report_data++; |
11835 |
++ report_len--; |
11836 |
++ } |
11837 |
++ |
11838 |
++ ret = hid_report_raw_event(hdev, HID_FEATURE_REPORT, report_data, |
11839 |
+ report_len, 0); |
11840 |
+ if (ret) { |
11841 |
+ dev_warn(&hdev->dev, "failed to report feature %d\n", |
11842 |
+diff --git a/drivers/hid/i2c-hid/i2c-hid-acpi.c b/drivers/hid/i2c-hid/i2c-hid-acpi.c |
11843 |
+index a6f0257a26de3..b96ae15e0ad91 100644 |
11844 |
+--- a/drivers/hid/i2c-hid/i2c-hid-acpi.c |
11845 |
++++ b/drivers/hid/i2c-hid/i2c-hid-acpi.c |
11846 |
+@@ -111,7 +111,7 @@ static int i2c_hid_acpi_probe(struct i2c_client *client) |
11847 |
+ } |
11848 |
+ |
11849 |
+ return i2c_hid_core_probe(client, &ihid_acpi->ops, |
11850 |
+- hid_descriptor_address); |
11851 |
++ hid_descriptor_address, 0); |
11852 |
+ } |
11853 |
+ |
11854 |
+ static const struct acpi_device_id i2c_hid_acpi_match[] = { |
11855 |
+diff --git a/drivers/hid/i2c-hid/i2c-hid-core.c b/drivers/hid/i2c-hid/i2c-hid-core.c |
11856 |
+index 517141138b007..4804d71e5293a 100644 |
11857 |
+--- a/drivers/hid/i2c-hid/i2c-hid-core.c |
11858 |
++++ b/drivers/hid/i2c-hid/i2c-hid-core.c |
11859 |
+@@ -912,7 +912,7 @@ static void i2c_hid_core_shutdown_tail(struct i2c_hid *ihid) |
11860 |
+ } |
11861 |
+ |
11862 |
+ int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops, |
11863 |
+- u16 hid_descriptor_address) |
11864 |
++ u16 hid_descriptor_address, u32 quirks) |
11865 |
+ { |
11866 |
+ int ret; |
11867 |
+ struct i2c_hid *ihid; |
11868 |
+@@ -1009,6 +1009,8 @@ int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops, |
11869 |
+ goto err_mem_free; |
11870 |
+ } |
11871 |
+ |
11872 |
++ hid->quirks |= quirks; |
11873 |
++ |
11874 |
+ return 0; |
11875 |
+ |
11876 |
+ err_mem_free: |
11877 |
+diff --git a/drivers/hid/i2c-hid/i2c-hid-of-goodix.c b/drivers/hid/i2c-hid/i2c-hid-of-goodix.c |
11878 |
+index 52674149a2750..b4dad66fa954d 100644 |
11879 |
+--- a/drivers/hid/i2c-hid/i2c-hid-of-goodix.c |
11880 |
++++ b/drivers/hid/i2c-hid/i2c-hid-of-goodix.c |
11881 |
+@@ -150,7 +150,7 @@ static int i2c_hid_of_goodix_probe(struct i2c_client *client, |
11882 |
+ goodix_i2c_hid_deassert_reset(ihid_goodix, true); |
11883 |
+ mutex_unlock(&ihid_goodix->regulator_mutex); |
11884 |
+ |
11885 |
+- return i2c_hid_core_probe(client, &ihid_goodix->ops, 0x0001); |
11886 |
++ return i2c_hid_core_probe(client, &ihid_goodix->ops, 0x0001, 0); |
11887 |
+ } |
11888 |
+ |
11889 |
+ static const struct goodix_i2c_hid_timing_data goodix_gt7375p_timing_data = { |
11890 |
+diff --git a/drivers/hid/i2c-hid/i2c-hid-of.c b/drivers/hid/i2c-hid/i2c-hid-of.c |
11891 |
+index 4bf7cea926379..97a27a803f58d 100644 |
11892 |
+--- a/drivers/hid/i2c-hid/i2c-hid-of.c |
11893 |
++++ b/drivers/hid/i2c-hid/i2c-hid-of.c |
11894 |
+@@ -21,6 +21,7 @@ |
11895 |
+ |
11896 |
+ #include <linux/delay.h> |
11897 |
+ #include <linux/device.h> |
11898 |
++#include <linux/hid.h> |
11899 |
+ #include <linux/i2c.h> |
11900 |
+ #include <linux/kernel.h> |
11901 |
+ #include <linux/module.h> |
11902 |
+@@ -71,6 +72,7 @@ static int i2c_hid_of_probe(struct i2c_client *client, |
11903 |
+ struct device *dev = &client->dev; |
11904 |
+ struct i2c_hid_of *ihid_of; |
11905 |
+ u16 hid_descriptor_address; |
11906 |
++ u32 quirks = 0; |
11907 |
+ int ret; |
11908 |
+ u32 val; |
11909 |
+ |
11910 |
+@@ -105,8 +107,14 @@ static int i2c_hid_of_probe(struct i2c_client *client, |
11911 |
+ if (ret) |
11912 |
+ return ret; |
11913 |
+ |
11914 |
++ if (device_property_read_bool(dev, "touchscreen-inverted-x")) |
11915 |
++ quirks |= HID_QUIRK_X_INVERT; |
11916 |
++ |
11917 |
++ if (device_property_read_bool(dev, "touchscreen-inverted-y")) |
11918 |
++ quirks |= HID_QUIRK_Y_INVERT; |
11919 |
++ |
11920 |
+ return i2c_hid_core_probe(client, &ihid_of->ops, |
11921 |
+- hid_descriptor_address); |
11922 |
++ hid_descriptor_address, quirks); |
11923 |
+ } |
11924 |
+ |
11925 |
+ static const struct of_device_id i2c_hid_of_match[] = { |
11926 |
+diff --git a/drivers/hid/i2c-hid/i2c-hid.h b/drivers/hid/i2c-hid/i2c-hid.h |
11927 |
+index 05a7827d211af..236cc062d5ef8 100644 |
11928 |
+--- a/drivers/hid/i2c-hid/i2c-hid.h |
11929 |
++++ b/drivers/hid/i2c-hid/i2c-hid.h |
11930 |
+@@ -32,7 +32,7 @@ struct i2chid_ops { |
11931 |
+ }; |
11932 |
+ |
11933 |
+ int i2c_hid_core_probe(struct i2c_client *client, struct i2chid_ops *ops, |
11934 |
+- u16 hid_descriptor_address); |
11935 |
++ u16 hid_descriptor_address, u32 quirks); |
11936 |
+ int i2c_hid_core_remove(struct i2c_client *client); |
11937 |
+ |
11938 |
+ void i2c_hid_core_shutdown(struct i2c_client *client); |
11939 |
+diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c |
11940 |
+index 8fe3efcb83271..fc06d8bb42e0f 100644 |
11941 |
+--- a/drivers/hid/uhid.c |
11942 |
++++ b/drivers/hid/uhid.c |
11943 |
+@@ -28,11 +28,22 @@ |
11944 |
+ |
11945 |
+ struct uhid_device { |
11946 |
+ struct mutex devlock; |
11947 |
++ |
11948 |
++ /* This flag tracks whether the HID device is usable for commands from |
11949 |
++ * userspace. The flag is already set before hid_add_device(), which |
11950 |
++ * runs in workqueue context, to allow hid_add_device() to communicate |
11951 |
++ * with userspace. |
11952 |
++ * However, if hid_add_device() fails, the flag is cleared without |
11953 |
++ * holding devlock. |
11954 |
++ * We guarantee that if @running changes from true to false while you're |
11955 |
++ * holding @devlock, it's still fine to access @hid. |
11956 |
++ */ |
11957 |
+ bool running; |
11958 |
+ |
11959 |
+ __u8 *rd_data; |
11960 |
+ uint rd_size; |
11961 |
+ |
11962 |
++ /* When this is NULL, userspace may use UHID_CREATE/UHID_CREATE2. */ |
11963 |
+ struct hid_device *hid; |
11964 |
+ struct uhid_event input_buf; |
11965 |
+ |
11966 |
+@@ -63,9 +74,18 @@ static void uhid_device_add_worker(struct work_struct *work) |
11967 |
+ if (ret) { |
11968 |
+ hid_err(uhid->hid, "Cannot register HID device: error %d\n", ret); |
11969 |
+ |
11970 |
+- hid_destroy_device(uhid->hid); |
11971 |
+- uhid->hid = NULL; |
11972 |
++ /* We used to call hid_destroy_device() here, but that's really |
11973 |
++ * messy to get right because we have to coordinate with |
11974 |
++ * concurrent writes from userspace that might be in the middle |
11975 |
++ * of using uhid->hid. |
11976 |
++ * Just leave uhid->hid as-is for now, and clean it up when |
11977 |
++ * userspace tries to close or reinitialize the uhid instance. |
11978 |
++ * |
11979 |
++ * However, we do have to clear the ->running flag and do a |
11980 |
++ * wakeup to make sure userspace knows that the device is gone. |
11981 |
++ */ |
11982 |
+ uhid->running = false; |
11983 |
++ wake_up_interruptible(&uhid->report_wait); |
11984 |
+ } |
11985 |
+ } |
11986 |
+ |
11987 |
+@@ -474,7 +494,7 @@ static int uhid_dev_create2(struct uhid_device *uhid, |
11988 |
+ void *rd_data; |
11989 |
+ int ret; |
11990 |
+ |
11991 |
+- if (uhid->running) |
11992 |
++ if (uhid->hid) |
11993 |
+ return -EALREADY; |
11994 |
+ |
11995 |
+ rd_size = ev->u.create2.rd_size; |
11996 |
+@@ -556,7 +576,7 @@ static int uhid_dev_create(struct uhid_device *uhid, |
11997 |
+ |
11998 |
+ static int uhid_dev_destroy(struct uhid_device *uhid) |
11999 |
+ { |
12000 |
+- if (!uhid->running) |
12001 |
++ if (!uhid->hid) |
12002 |
+ return -EINVAL; |
12003 |
+ |
12004 |
+ uhid->running = false; |
12005 |
+@@ -565,6 +585,7 @@ static int uhid_dev_destroy(struct uhid_device *uhid) |
12006 |
+ cancel_work_sync(&uhid->worker); |
12007 |
+ |
12008 |
+ hid_destroy_device(uhid->hid); |
12009 |
++ uhid->hid = NULL; |
12010 |
+ kfree(uhid->rd_data); |
12011 |
+ |
12012 |
+ return 0; |
12013 |
+diff --git a/drivers/hid/wacom_wac.c b/drivers/hid/wacom_wac.c |
12014 |
+index 2a4cc39962e76..a7176fc0635dd 100644 |
12015 |
+--- a/drivers/hid/wacom_wac.c |
12016 |
++++ b/drivers/hid/wacom_wac.c |
12017 |
+@@ -2588,6 +2588,24 @@ static void wacom_wac_finger_slot(struct wacom_wac *wacom_wac, |
12018 |
+ } |
12019 |
+ } |
12020 |
+ |
12021 |
++static bool wacom_wac_slot_is_active(struct input_dev *dev, int key) |
12022 |
++{ |
12023 |
++ struct input_mt *mt = dev->mt; |
12024 |
++ struct input_mt_slot *s; |
12025 |
++ |
12026 |
++ if (!mt) |
12027 |
++ return false; |
12028 |
++ |
12029 |
++ for (s = mt->slots; s != mt->slots + mt->num_slots; s++) { |
12030 |
++ if (s->key == key && |
12031 |
++ input_mt_get_value(s, ABS_MT_TRACKING_ID) >= 0) { |
12032 |
++ return true; |
12033 |
++ } |
12034 |
++ } |
12035 |
++ |
12036 |
++ return false; |
12037 |
++} |
12038 |
++ |
12039 |
+ static void wacom_wac_finger_event(struct hid_device *hdev, |
12040 |
+ struct hid_field *field, struct hid_usage *usage, __s32 value) |
12041 |
+ { |
12042 |
+@@ -2638,9 +2656,14 @@ static void wacom_wac_finger_event(struct hid_device *hdev, |
12043 |
+ } |
12044 |
+ |
12045 |
+ if (usage->usage_index + 1 == field->report_count) { |
12046 |
+- if (equivalent_usage == wacom_wac->hid_data.last_slot_field && |
12047 |
+- wacom_wac->hid_data.confidence) |
12048 |
+- wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input); |
12049 |
++ if (equivalent_usage == wacom_wac->hid_data.last_slot_field) { |
12050 |
++ bool touch_removed = wacom_wac_slot_is_active(wacom_wac->touch_input, |
12051 |
++ wacom_wac->hid_data.id) && !wacom_wac->hid_data.tipswitch; |
12052 |
++ |
12053 |
++ if (wacom_wac->hid_data.confidence || touch_removed) { |
12054 |
++ wacom_wac_finger_slot(wacom_wac, wacom_wac->touch_input); |
12055 |
++ } |
12056 |
++ } |
12057 |
+ } |
12058 |
+ } |
12059 |
+ |
12060 |
+@@ -2659,6 +2682,10 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev, |
12061 |
+ |
12062 |
+ hid_data->confidence = true; |
12063 |
+ |
12064 |
++ hid_data->cc_report = 0; |
12065 |
++ hid_data->cc_index = -1; |
12066 |
++ hid_data->cc_value_index = -1; |
12067 |
++ |
12068 |
+ for (i = 0; i < report->maxfield; i++) { |
12069 |
+ struct hid_field *field = report->field[i]; |
12070 |
+ int j; |
12071 |
+@@ -2692,11 +2719,14 @@ static void wacom_wac_finger_pre_report(struct hid_device *hdev, |
12072 |
+ hid_data->cc_index >= 0) { |
12073 |
+ struct hid_field *field = report->field[hid_data->cc_index]; |
12074 |
+ int value = field->value[hid_data->cc_value_index]; |
12075 |
+- if (value) |
12076 |
++ if (value) { |
12077 |
+ hid_data->num_expected = value; |
12078 |
++ hid_data->num_received = 0; |
12079 |
++ } |
12080 |
+ } |
12081 |
+ else { |
12082 |
+ hid_data->num_expected = wacom_wac->features.touch_max; |
12083 |
++ hid_data->num_received = 0; |
12084 |
+ } |
12085 |
+ } |
12086 |
+ |
12087 |
+@@ -2724,6 +2754,7 @@ static void wacom_wac_finger_report(struct hid_device *hdev, |
12088 |
+ |
12089 |
+ input_sync(input); |
12090 |
+ wacom_wac->hid_data.num_received = 0; |
12091 |
++ wacom_wac->hid_data.num_expected = 0; |
12092 |
+ |
12093 |
+ /* keep touch state for pen event */ |
12094 |
+ wacom_wac->shared->touch_down = wacom_wac_finger_count_touches(wacom_wac); |
12095 |
+diff --git a/drivers/hsi/hsi_core.c b/drivers/hsi/hsi_core.c |
12096 |
+index ec90713564e32..884066109699c 100644 |
12097 |
+--- a/drivers/hsi/hsi_core.c |
12098 |
++++ b/drivers/hsi/hsi_core.c |
12099 |
+@@ -102,6 +102,7 @@ struct hsi_client *hsi_new_client(struct hsi_port *port, |
12100 |
+ if (device_register(&cl->device) < 0) { |
12101 |
+ pr_err("hsi: failed to register client: %s\n", info->name); |
12102 |
+ put_device(&cl->device); |
12103 |
++ goto err; |
12104 |
+ } |
12105 |
+ |
12106 |
+ return cl; |
12107 |
+diff --git a/drivers/hwmon/mr75203.c b/drivers/hwmon/mr75203.c |
12108 |
+index 868243dba1ee0..1ba1e31459690 100644 |
12109 |
+--- a/drivers/hwmon/mr75203.c |
12110 |
++++ b/drivers/hwmon/mr75203.c |
12111 |
+@@ -93,7 +93,7 @@ |
12112 |
+ #define VM_CH_REQ BIT(21) |
12113 |
+ |
12114 |
+ #define IP_TMR 0x05 |
12115 |
+-#define POWER_DELAY_CYCLE_256 0x80 |
12116 |
++#define POWER_DELAY_CYCLE_256 0x100 |
12117 |
+ #define POWER_DELAY_CYCLE_64 0x40 |
12118 |
+ |
12119 |
+ #define PVT_POLL_DELAY_US 20 |
12120 |
+diff --git a/drivers/i2c/busses/i2c-designware-pcidrv.c b/drivers/i2c/busses/i2c-designware-pcidrv.c |
12121 |
+index 0f409a4c2da0d..5b45941bcbddc 100644 |
12122 |
+--- a/drivers/i2c/busses/i2c-designware-pcidrv.c |
12123 |
++++ b/drivers/i2c/busses/i2c-designware-pcidrv.c |
12124 |
+@@ -39,10 +39,10 @@ enum dw_pci_ctl_id_t { |
12125 |
+ }; |
12126 |
+ |
12127 |
+ struct dw_scl_sda_cfg { |
12128 |
+- u32 ss_hcnt; |
12129 |
+- u32 fs_hcnt; |
12130 |
+- u32 ss_lcnt; |
12131 |
+- u32 fs_lcnt; |
12132 |
++ u16 ss_hcnt; |
12133 |
++ u16 fs_hcnt; |
12134 |
++ u16 ss_lcnt; |
12135 |
++ u16 fs_lcnt; |
12136 |
+ u32 sda_hold; |
12137 |
+ }; |
12138 |
+ |
12139 |
+diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c |
12140 |
+index 1f929e6c30bea..98e39a17fb830 100644 |
12141 |
+--- a/drivers/i2c/busses/i2c-i801.c |
12142 |
++++ b/drivers/i2c/busses/i2c-i801.c |
12143 |
+@@ -763,6 +763,11 @@ static int i801_block_transaction(struct i801_priv *priv, union i2c_smbus_data * |
12144 |
+ int result = 0; |
12145 |
+ unsigned char hostc; |
12146 |
+ |
12147 |
++ if (read_write == I2C_SMBUS_READ && command == I2C_SMBUS_BLOCK_DATA) |
12148 |
++ data->block[0] = I2C_SMBUS_BLOCK_MAX; |
12149 |
++ else if (data->block[0] < 1 || data->block[0] > I2C_SMBUS_BLOCK_MAX) |
12150 |
++ return -EPROTO; |
12151 |
++ |
12152 |
+ if (command == I2C_SMBUS_I2C_BLOCK_DATA) { |
12153 |
+ if (read_write == I2C_SMBUS_WRITE) { |
12154 |
+ /* set I2C_EN bit in configuration register */ |
12155 |
+@@ -776,16 +781,6 @@ static int i801_block_transaction(struct i801_priv *priv, union i2c_smbus_data * |
12156 |
+ } |
12157 |
+ } |
12158 |
+ |
12159 |
+- if (read_write == I2C_SMBUS_WRITE |
12160 |
+- || command == I2C_SMBUS_I2C_BLOCK_DATA) { |
12161 |
+- if (data->block[0] < 1) |
12162 |
+- data->block[0] = 1; |
12163 |
+- if (data->block[0] > I2C_SMBUS_BLOCK_MAX) |
12164 |
+- data->block[0] = I2C_SMBUS_BLOCK_MAX; |
12165 |
+- } else { |
12166 |
+- data->block[0] = 32; /* max for SMBus block reads */ |
12167 |
+- } |
12168 |
+- |
12169 |
+ /* Experience has shown that the block buffer can only be used for |
12170 |
+ SMBus (not I2C) block transactions, even though the datasheet |
12171 |
+ doesn't mention this limitation. */ |
12172 |
+diff --git a/drivers/i2c/busses/i2c-mpc.c b/drivers/i2c/busses/i2c-mpc.c |
12173 |
+index db26cc36e13fe..6c698c10d3cdb 100644 |
12174 |
+--- a/drivers/i2c/busses/i2c-mpc.c |
12175 |
++++ b/drivers/i2c/busses/i2c-mpc.c |
12176 |
+@@ -119,23 +119,30 @@ static inline void writeccr(struct mpc_i2c *i2c, u32 x) |
12177 |
+ /* Sometimes 9th clock pulse isn't generated, and slave doesn't release |
12178 |
+ * the bus, because it wants to send ACK. |
12179 |
+ * Following sequence of enabling/disabling and sending start/stop generates |
12180 |
+- * the 9 pulses, so it's all OK. |
12181 |
++ * the 9 pulses, each with a START then ending with STOP, so it's all OK. |
12182 |
+ */ |
12183 |
+ static void mpc_i2c_fixup(struct mpc_i2c *i2c) |
12184 |
+ { |
12185 |
+ int k; |
12186 |
+- u32 delay_val = 1000000 / i2c->real_clk + 1; |
12187 |
+- |
12188 |
+- if (delay_val < 2) |
12189 |
+- delay_val = 2; |
12190 |
++ unsigned long flags; |
12191 |
+ |
12192 |
+ for (k = 9; k; k--) { |
12193 |
+ writeccr(i2c, 0); |
12194 |
+- writeccr(i2c, CCR_MSTA | CCR_MTX | CCR_MEN); |
12195 |
++ writeb(0, i2c->base + MPC_I2C_SR); /* clear any status bits */ |
12196 |
++ writeccr(i2c, CCR_MEN | CCR_MSTA); /* START */ |
12197 |
++ readb(i2c->base + MPC_I2C_DR); /* init xfer */ |
12198 |
++ udelay(15); /* let it hit the bus */ |
12199 |
++ local_irq_save(flags); /* should not be delayed further */ |
12200 |
++ writeccr(i2c, CCR_MEN | CCR_MSTA | CCR_RSTA); /* delay SDA */ |
12201 |
+ readb(i2c->base + MPC_I2C_DR); |
12202 |
+- writeccr(i2c, CCR_MEN); |
12203 |
+- udelay(delay_val << 1); |
12204 |
++ if (k != 1) |
12205 |
++ udelay(5); |
12206 |
++ local_irq_restore(flags); |
12207 |
+ } |
12208 |
++ writeccr(i2c, CCR_MEN); /* Initiate STOP */ |
12209 |
++ readb(i2c->base + MPC_I2C_DR); |
12210 |
++ udelay(15); /* Let STOP propagate */ |
12211 |
++ writeccr(i2c, 0); |
12212 |
+ } |
12213 |
+ |
12214 |
+ static int i2c_mpc_wait_sr(struct mpc_i2c *i2c, int mask) |
12215 |
+diff --git a/drivers/iio/adc/ti-adc081c.c b/drivers/iio/adc/ti-adc081c.c |
12216 |
+index 16fc608db36a5..bd48b073e7200 100644 |
12217 |
+--- a/drivers/iio/adc/ti-adc081c.c |
12218 |
++++ b/drivers/iio/adc/ti-adc081c.c |
12219 |
+@@ -19,6 +19,7 @@ |
12220 |
+ #include <linux/i2c.h> |
12221 |
+ #include <linux/module.h> |
12222 |
+ #include <linux/mod_devicetable.h> |
12223 |
++#include <linux/property.h> |
12224 |
+ |
12225 |
+ #include <linux/iio/iio.h> |
12226 |
+ #include <linux/iio/buffer.h> |
12227 |
+@@ -156,13 +157,16 @@ static int adc081c_probe(struct i2c_client *client, |
12228 |
+ { |
12229 |
+ struct iio_dev *iio; |
12230 |
+ struct adc081c *adc; |
12231 |
+- struct adcxx1c_model *model; |
12232 |
++ const struct adcxx1c_model *model; |
12233 |
+ int err; |
12234 |
+ |
12235 |
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WORD_DATA)) |
12236 |
+ return -EOPNOTSUPP; |
12237 |
+ |
12238 |
+- model = &adcxx1c_models[id->driver_data]; |
12239 |
++ if (dev_fwnode(&client->dev)) |
12240 |
++ model = device_get_match_data(&client->dev); |
12241 |
++ else |
12242 |
++ model = &adcxx1c_models[id->driver_data]; |
12243 |
+ |
12244 |
+ iio = devm_iio_device_alloc(&client->dev, sizeof(*adc)); |
12245 |
+ if (!iio) |
12246 |
+@@ -210,10 +214,17 @@ static const struct i2c_device_id adc081c_id[] = { |
12247 |
+ }; |
12248 |
+ MODULE_DEVICE_TABLE(i2c, adc081c_id); |
12249 |
+ |
12250 |
++static const struct acpi_device_id adc081c_acpi_match[] = { |
12251 |
++ /* Used on some AAEON boards */ |
12252 |
++ { "ADC081C", (kernel_ulong_t)&adcxx1c_models[ADC081C] }, |
12253 |
++ { } |
12254 |
++}; |
12255 |
++MODULE_DEVICE_TABLE(acpi, adc081c_acpi_match); |
12256 |
++ |
12257 |
+ static const struct of_device_id adc081c_of_match[] = { |
12258 |
+- { .compatible = "ti,adc081c" }, |
12259 |
+- { .compatible = "ti,adc101c" }, |
12260 |
+- { .compatible = "ti,adc121c" }, |
12261 |
++ { .compatible = "ti,adc081c", .data = &adcxx1c_models[ADC081C] }, |
12262 |
++ { .compatible = "ti,adc101c", .data = &adcxx1c_models[ADC101C] }, |
12263 |
++ { .compatible = "ti,adc121c", .data = &adcxx1c_models[ADC121C] }, |
12264 |
+ { } |
12265 |
+ }; |
12266 |
+ MODULE_DEVICE_TABLE(of, adc081c_of_match); |
12267 |
+@@ -222,6 +233,7 @@ static struct i2c_driver adc081c_driver = { |
12268 |
+ .driver = { |
12269 |
+ .name = "adc081c", |
12270 |
+ .of_match_table = adc081c_of_match, |
12271 |
++ .acpi_match_table = adc081c_acpi_match, |
12272 |
+ }, |
12273 |
+ .probe = adc081c_probe, |
12274 |
+ .id_table = adc081c_id, |
12275 |
+diff --git a/drivers/iio/industrialio-trigger.c b/drivers/iio/industrialio-trigger.c |
12276 |
+index 93990ff1dfe39..f504ed351b3e2 100644 |
12277 |
+--- a/drivers/iio/industrialio-trigger.c |
12278 |
++++ b/drivers/iio/industrialio-trigger.c |
12279 |
+@@ -162,6 +162,39 @@ static struct iio_trigger *iio_trigger_acquire_by_name(const char *name) |
12280 |
+ return trig; |
12281 |
+ } |
12282 |
+ |
12283 |
++static void iio_reenable_work_fn(struct work_struct *work) |
12284 |
++{ |
12285 |
++ struct iio_trigger *trig = container_of(work, struct iio_trigger, |
12286 |
++ reenable_work); |
12287 |
++ |
12288 |
++ /* |
12289 |
++ * This 'might' occur after the trigger state is set to disabled - |
12290 |
++ * in that case the driver should skip reenabling. |
12291 |
++ */ |
12292 |
++ trig->ops->reenable(trig); |
12293 |
++} |
12294 |
++ |
12295 |
++/* |
12296 |
++ * In general, reenable callbacks may need to sleep and this path is |
12297 |
++ * not performance sensitive, so just queue up a work item |
12298 |
++ * to reneable the trigger for us. |
12299 |
++ * |
12300 |
++ * Races that can cause this. |
12301 |
++ * 1) A handler occurs entirely in interrupt context so the counter |
12302 |
++ * the final decrement is still in this interrupt. |
12303 |
++ * 2) The trigger has been removed, but one last interrupt gets through. |
12304 |
++ * |
12305 |
++ * For (1) we must call reenable, but not in atomic context. |
12306 |
++ * For (2) it should be safe to call reenanble, if drivers never blindly |
12307 |
++ * reenable after state is off. |
12308 |
++ */ |
12309 |
++static void iio_trigger_notify_done_atomic(struct iio_trigger *trig) |
12310 |
++{ |
12311 |
++ if (atomic_dec_and_test(&trig->use_count) && trig->ops && |
12312 |
++ trig->ops->reenable) |
12313 |
++ schedule_work(&trig->reenable_work); |
12314 |
++} |
12315 |
++ |
12316 |
+ void iio_trigger_poll(struct iio_trigger *trig) |
12317 |
+ { |
12318 |
+ int i; |
12319 |
+@@ -173,7 +206,7 @@ void iio_trigger_poll(struct iio_trigger *trig) |
12320 |
+ if (trig->subirqs[i].enabled) |
12321 |
+ generic_handle_irq(trig->subirq_base + i); |
12322 |
+ else |
12323 |
+- iio_trigger_notify_done(trig); |
12324 |
++ iio_trigger_notify_done_atomic(trig); |
12325 |
+ } |
12326 |
+ } |
12327 |
+ } |
12328 |
+@@ -535,6 +568,7 @@ struct iio_trigger *viio_trigger_alloc(struct device *parent, |
12329 |
+ trig->dev.type = &iio_trig_type; |
12330 |
+ trig->dev.bus = &iio_bus_type; |
12331 |
+ device_initialize(&trig->dev); |
12332 |
++ INIT_WORK(&trig->reenable_work, iio_reenable_work_fn); |
12333 |
+ |
12334 |
+ mutex_init(&trig->pool_lock); |
12335 |
+ trig->subirq_base = irq_alloc_descs(-1, 0, |
12336 |
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c |
12337 |
+index 704ce595542c5..3d419741e8916 100644 |
12338 |
+--- a/drivers/infiniband/core/cma.c |
12339 |
++++ b/drivers/infiniband/core/cma.c |
12340 |
+@@ -766,6 +766,7 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv) |
12341 |
+ unsigned int p; |
12342 |
+ u16 pkey, index; |
12343 |
+ enum ib_port_state port_state; |
12344 |
++ int ret; |
12345 |
+ int i; |
12346 |
+ |
12347 |
+ cma_dev = NULL; |
12348 |
+@@ -784,9 +785,14 @@ static int cma_resolve_ib_dev(struct rdma_id_private *id_priv) |
12349 |
+ |
12350 |
+ if (ib_get_cached_port_state(cur_dev->device, p, &port_state)) |
12351 |
+ continue; |
12352 |
+- for (i = 0; !rdma_query_gid(cur_dev->device, |
12353 |
+- p, i, &gid); |
12354 |
+- i++) { |
12355 |
++ |
12356 |
++ for (i = 0; i < cur_dev->device->port_data[p].immutable.gid_tbl_len; |
12357 |
++ ++i) { |
12358 |
++ ret = rdma_query_gid(cur_dev->device, p, i, |
12359 |
++ &gid); |
12360 |
++ if (ret) |
12361 |
++ continue; |
12362 |
++ |
12363 |
+ if (!memcmp(&gid, dgid, sizeof(gid))) { |
12364 |
+ cma_dev = cur_dev; |
12365 |
+ sgid = gid; |
12366 |
+@@ -4031,8 +4037,7 @@ static int cma_resolve_ib_udp(struct rdma_id_private *id_priv, |
12367 |
+ |
12368 |
+ memset(&req, 0, sizeof req); |
12369 |
+ offset = cma_user_data_offset(id_priv); |
12370 |
+- req.private_data_len = offset + conn_param->private_data_len; |
12371 |
+- if (req.private_data_len < conn_param->private_data_len) |
12372 |
++ if (check_add_overflow(offset, conn_param->private_data_len, &req.private_data_len)) |
12373 |
+ return -EINVAL; |
12374 |
+ |
12375 |
+ if (req.private_data_len) { |
12376 |
+@@ -4091,8 +4096,7 @@ static int cma_connect_ib(struct rdma_id_private *id_priv, |
12377 |
+ |
12378 |
+ memset(&req, 0, sizeof req); |
12379 |
+ offset = cma_user_data_offset(id_priv); |
12380 |
+- req.private_data_len = offset + conn_param->private_data_len; |
12381 |
+- if (req.private_data_len < conn_param->private_data_len) |
12382 |
++ if (check_add_overflow(offset, conn_param->private_data_len, &req.private_data_len)) |
12383 |
+ return -EINVAL; |
12384 |
+ |
12385 |
+ if (req.private_data_len) { |
12386 |
+diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c |
12387 |
+index f4814bb7f082f..6ab46648af909 100644 |
12388 |
+--- a/drivers/infiniband/core/device.c |
12389 |
++++ b/drivers/infiniband/core/device.c |
12390 |
+@@ -2461,7 +2461,8 @@ int ib_find_gid(struct ib_device *device, union ib_gid *gid, |
12391 |
+ ++i) { |
12392 |
+ ret = rdma_query_gid(device, port, i, &tmp_gid); |
12393 |
+ if (ret) |
12394 |
+- return ret; |
12395 |
++ continue; |
12396 |
++ |
12397 |
+ if (!memcmp(&tmp_gid, gid, sizeof *gid)) { |
12398 |
+ *port_num = port; |
12399 |
+ if (index) |
12400 |
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c |
12401 |
+index 5d384def5e5fe..d2d39126f1852 100644 |
12402 |
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c |
12403 |
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.c |
12404 |
+@@ -618,8 +618,6 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res, |
12405 |
+ if (!cmdq->cmdq_bitmap) |
12406 |
+ goto fail; |
12407 |
+ |
12408 |
+- cmdq->bmap_size = bmap_size; |
12409 |
+- |
12410 |
+ /* Allocate one extra to hold the QP1 entries */ |
12411 |
+ rcfw->qp_tbl_size = qp_tbl_sz + 1; |
12412 |
+ rcfw->qp_tbl = kcalloc(rcfw->qp_tbl_size, sizeof(struct bnxt_qplib_qp_node), |
12413 |
+@@ -667,8 +665,8 @@ void bnxt_qplib_disable_rcfw_channel(struct bnxt_qplib_rcfw *rcfw) |
12414 |
+ iounmap(cmdq->cmdq_mbox.reg.bar_reg); |
12415 |
+ iounmap(creq->creq_db.reg.bar_reg); |
12416 |
+ |
12417 |
+- indx = find_first_bit(cmdq->cmdq_bitmap, cmdq->bmap_size); |
12418 |
+- if (indx != cmdq->bmap_size) |
12419 |
++ indx = find_first_bit(cmdq->cmdq_bitmap, rcfw->cmdq_depth); |
12420 |
++ if (indx != rcfw->cmdq_depth) |
12421 |
+ dev_err(&rcfw->pdev->dev, |
12422 |
+ "disabling RCFW with pending cmd-bit %lx\n", indx); |
12423 |
+ |
12424 |
+diff --git a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h |
12425 |
+index 9474c00465821..0c6d0b70ce890 100644 |
12426 |
+--- a/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h |
12427 |
++++ b/drivers/infiniband/hw/bnxt_re/qplib_rcfw.h |
12428 |
+@@ -152,7 +152,6 @@ struct bnxt_qplib_cmdq_ctx { |
12429 |
+ wait_queue_head_t waitq; |
12430 |
+ unsigned long flags; |
12431 |
+ unsigned long *cmdq_bitmap; |
12432 |
+- u32 bmap_size; |
12433 |
+ u32 seq_num; |
12434 |
+ }; |
12435 |
+ |
12436 |
+diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c |
12437 |
+index d20b4ef2c853d..ffbd9a89981e7 100644 |
12438 |
+--- a/drivers/infiniband/hw/cxgb4/qp.c |
12439 |
++++ b/drivers/infiniband/hw/cxgb4/qp.c |
12440 |
+@@ -2460,6 +2460,7 @@ int c4iw_ib_query_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, |
12441 |
+ memset(attr, 0, sizeof(*attr)); |
12442 |
+ memset(init_attr, 0, sizeof(*init_attr)); |
12443 |
+ attr->qp_state = to_ib_qp_state(qhp->attr.state); |
12444 |
++ attr->cur_qp_state = to_ib_qp_state(qhp->attr.state); |
12445 |
+ init_attr->cap.max_send_wr = qhp->attr.sq_num_entries; |
12446 |
+ init_attr->cap.max_recv_wr = qhp->attr.rq_num_entries; |
12447 |
+ init_attr->cap.max_send_sge = qhp->attr.sq_max_sges; |
12448 |
+diff --git a/drivers/infiniband/hw/hns/hns_roce_main.c b/drivers/infiniband/hw/hns/hns_roce_main.c |
12449 |
+index 5d39bd08582af..1f2209de88122 100644 |
12450 |
+--- a/drivers/infiniband/hw/hns/hns_roce_main.c |
12451 |
++++ b/drivers/infiniband/hw/hns/hns_roce_main.c |
12452 |
+@@ -269,6 +269,9 @@ static enum rdma_link_layer hns_roce_get_link_layer(struct ib_device *device, |
12453 |
+ static int hns_roce_query_pkey(struct ib_device *ib_dev, u32 port, u16 index, |
12454 |
+ u16 *pkey) |
12455 |
+ { |
12456 |
++ if (index > 0) |
12457 |
++ return -EINVAL; |
12458 |
++ |
12459 |
+ *pkey = PKEY_ID; |
12460 |
+ |
12461 |
+ return 0; |
12462 |
+@@ -349,7 +352,7 @@ static int hns_roce_mmap(struct ib_ucontext *context, |
12463 |
+ return rdma_user_mmap_io(context, vma, |
12464 |
+ to_hr_ucontext(context)->uar.pfn, |
12465 |
+ PAGE_SIZE, |
12466 |
+- pgprot_noncached(vma->vm_page_prot), |
12467 |
++ pgprot_device(vma->vm_page_prot), |
12468 |
+ NULL); |
12469 |
+ |
12470 |
+ /* vm_pgoff: 1 -- TPTR */ |
12471 |
+diff --git a/drivers/infiniband/hw/qedr/verbs.c b/drivers/infiniband/hw/qedr/verbs.c |
12472 |
+index 3d4e4a766574a..f652d083ff20f 100644 |
12473 |
+--- a/drivers/infiniband/hw/qedr/verbs.c |
12474 |
++++ b/drivers/infiniband/hw/qedr/verbs.c |
12475 |
+@@ -1941,6 +1941,7 @@ static int qedr_create_user_qp(struct qedr_dev *dev, |
12476 |
+ /* db offset was calculated in copy_qp_uresp, now set in the user q */ |
12477 |
+ if (qedr_qp_has_sq(qp)) { |
12478 |
+ qp->usq.db_addr = ctx->dpi_addr + uresp.sq_db_offset; |
12479 |
++ qp->sq.max_wr = attrs->cap.max_send_wr; |
12480 |
+ rc = qedr_db_recovery_add(dev, qp->usq.db_addr, |
12481 |
+ &qp->usq.db_rec_data->db_data, |
12482 |
+ DB_REC_WIDTH_32B, |
12483 |
+@@ -1951,6 +1952,7 @@ static int qedr_create_user_qp(struct qedr_dev *dev, |
12484 |
+ |
12485 |
+ if (qedr_qp_has_rq(qp)) { |
12486 |
+ qp->urq.db_addr = ctx->dpi_addr + uresp.rq_db_offset; |
12487 |
++ qp->rq.max_wr = attrs->cap.max_recv_wr; |
12488 |
+ rc = qedr_db_recovery_add(dev, qp->urq.db_addr, |
12489 |
+ &qp->urq.db_rec_data->db_data, |
12490 |
+ DB_REC_WIDTH_32B, |
12491 |
+diff --git a/drivers/infiniband/sw/rxe/rxe_opcode.c b/drivers/infiniband/sw/rxe/rxe_opcode.c |
12492 |
+index 3ef5a10a6efd8..47ebaac8f4754 100644 |
12493 |
+--- a/drivers/infiniband/sw/rxe/rxe_opcode.c |
12494 |
++++ b/drivers/infiniband/sw/rxe/rxe_opcode.c |
12495 |
+@@ -117,7 +117,7 @@ struct rxe_opcode_info rxe_opcode[RXE_NUM_OPCODE] = { |
12496 |
+ } |
12497 |
+ }, |
12498 |
+ [IB_OPCODE_RC_SEND_MIDDLE] = { |
12499 |
+- .name = "IB_OPCODE_RC_SEND_MIDDLE]", |
12500 |
++ .name = "IB_OPCODE_RC_SEND_MIDDLE", |
12501 |
+ .mask = RXE_PAYLOAD_MASK | RXE_REQ_MASK | RXE_SEND_MASK |
12502 |
+ | RXE_MIDDLE_MASK, |
12503 |
+ .length = RXE_BTH_BYTES, |
12504 |
+diff --git a/drivers/infiniband/ulp/rtrs/rtrs-clt.c b/drivers/infiniband/ulp/rtrs/rtrs-clt.c |
12505 |
+index bc8824b4ee0d4..55ebe01ec9951 100644 |
12506 |
+--- a/drivers/infiniband/ulp/rtrs/rtrs-clt.c |
12507 |
++++ b/drivers/infiniband/ulp/rtrs/rtrs-clt.c |
12508 |
+@@ -867,7 +867,7 @@ static struct rtrs_clt_sess *get_next_path_min_latency(struct path_it *it) |
12509 |
+ struct rtrs_clt_sess *min_path = NULL; |
12510 |
+ struct rtrs_clt *clt = it->clt; |
12511 |
+ struct rtrs_clt_sess *sess; |
12512 |
+- ktime_t min_latency = INT_MAX; |
12513 |
++ ktime_t min_latency = KTIME_MAX; |
12514 |
+ ktime_t latency; |
12515 |
+ |
12516 |
+ list_for_each_entry_rcu(sess, &clt->paths_list, s.entry) { |
12517 |
+diff --git a/drivers/interconnect/qcom/icc-rpm.c b/drivers/interconnect/qcom/icc-rpm.c |
12518 |
+index 54de49ca7808a..ddf1805ded0c0 100644 |
12519 |
+--- a/drivers/interconnect/qcom/icc-rpm.c |
12520 |
++++ b/drivers/interconnect/qcom/icc-rpm.c |
12521 |
+@@ -68,6 +68,7 @@ static int qcom_icc_set(struct icc_node *src, struct icc_node *dst) |
12522 |
+ rate = max(sum_bw, max_peak_bw); |
12523 |
+ |
12524 |
+ do_div(rate, qn->buswidth); |
12525 |
++ rate = min_t(u64, rate, LONG_MAX); |
12526 |
+ |
12527 |
+ if (qn->rate == rate) |
12528 |
+ return 0; |
12529 |
+diff --git a/drivers/iommu/amd/amd_iommu_types.h b/drivers/iommu/amd/amd_iommu_types.h |
12530 |
+index 8dbe61e2b3c15..8394c2787ff89 100644 |
12531 |
+--- a/drivers/iommu/amd/amd_iommu_types.h |
12532 |
++++ b/drivers/iommu/amd/amd_iommu_types.h |
12533 |
+@@ -643,8 +643,6 @@ struct amd_iommu { |
12534 |
+ /* DebugFS Info */ |
12535 |
+ struct dentry *debugfs; |
12536 |
+ #endif |
12537 |
+- /* IRQ notifier for IntCapXT interrupt */ |
12538 |
+- struct irq_affinity_notify intcapxt_notify; |
12539 |
+ }; |
12540 |
+ |
12541 |
+ static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev) |
12542 |
+diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c |
12543 |
+index 2a822b229bd05..50e5a728f12a1 100644 |
12544 |
+--- a/drivers/iommu/amd/init.c |
12545 |
++++ b/drivers/iommu/amd/init.c |
12546 |
+@@ -804,16 +804,27 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu) |
12547 |
+ { |
12548 |
+ #ifdef CONFIG_IRQ_REMAP |
12549 |
+ u32 status, i; |
12550 |
++ u64 entry; |
12551 |
+ |
12552 |
+ if (!iommu->ga_log) |
12553 |
+ return -EINVAL; |
12554 |
+ |
12555 |
+- status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET); |
12556 |
+- |
12557 |
+ /* Check if already running */ |
12558 |
+- if (status & (MMIO_STATUS_GALOG_RUN_MASK)) |
12559 |
++ status = readl(iommu->mmio_base + MMIO_STATUS_OFFSET); |
12560 |
++ if (WARN_ON(status & (MMIO_STATUS_GALOG_RUN_MASK))) |
12561 |
+ return 0; |
12562 |
+ |
12563 |
++ entry = iommu_virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512; |
12564 |
++ memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_BASE_OFFSET, |
12565 |
++ &entry, sizeof(entry)); |
12566 |
++ entry = (iommu_virt_to_phys(iommu->ga_log_tail) & |
12567 |
++ (BIT_ULL(52)-1)) & ~7ULL; |
12568 |
++ memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_TAIL_OFFSET, |
12569 |
++ &entry, sizeof(entry)); |
12570 |
++ writel(0x00, iommu->mmio_base + MMIO_GA_HEAD_OFFSET); |
12571 |
++ writel(0x00, iommu->mmio_base + MMIO_GA_TAIL_OFFSET); |
12572 |
++ |
12573 |
++ |
12574 |
+ iommu_feature_enable(iommu, CONTROL_GAINT_EN); |
12575 |
+ iommu_feature_enable(iommu, CONTROL_GALOG_EN); |
12576 |
+ |
12577 |
+@@ -823,7 +834,7 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu) |
12578 |
+ break; |
12579 |
+ } |
12580 |
+ |
12581 |
+- if (i >= LOOP_TIMEOUT) |
12582 |
++ if (WARN_ON(i >= LOOP_TIMEOUT)) |
12583 |
+ return -EINVAL; |
12584 |
+ #endif /* CONFIG_IRQ_REMAP */ |
12585 |
+ return 0; |
12586 |
+@@ -832,8 +843,6 @@ static int iommu_ga_log_enable(struct amd_iommu *iommu) |
12587 |
+ static int iommu_init_ga_log(struct amd_iommu *iommu) |
12588 |
+ { |
12589 |
+ #ifdef CONFIG_IRQ_REMAP |
12590 |
+- u64 entry; |
12591 |
+- |
12592 |
+ if (!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir)) |
12593 |
+ return 0; |
12594 |
+ |
12595 |
+@@ -847,16 +856,6 @@ static int iommu_init_ga_log(struct amd_iommu *iommu) |
12596 |
+ if (!iommu->ga_log_tail) |
12597 |
+ goto err_out; |
12598 |
+ |
12599 |
+- entry = iommu_virt_to_phys(iommu->ga_log) | GA_LOG_SIZE_512; |
12600 |
+- memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_BASE_OFFSET, |
12601 |
+- &entry, sizeof(entry)); |
12602 |
+- entry = (iommu_virt_to_phys(iommu->ga_log_tail) & |
12603 |
+- (BIT_ULL(52)-1)) & ~7ULL; |
12604 |
+- memcpy_toio(iommu->mmio_base + MMIO_GA_LOG_TAIL_OFFSET, |
12605 |
+- &entry, sizeof(entry)); |
12606 |
+- writel(0x00, iommu->mmio_base + MMIO_GA_HEAD_OFFSET); |
12607 |
+- writel(0x00, iommu->mmio_base + MMIO_GA_TAIL_OFFSET); |
12608 |
+- |
12609 |
+ return 0; |
12610 |
+ err_out: |
12611 |
+ free_ga_log(iommu); |
12612 |
+@@ -2013,48 +2012,18 @@ union intcapxt { |
12613 |
+ }; |
12614 |
+ } __attribute__ ((packed)); |
12615 |
+ |
12616 |
+-/* |
12617 |
+- * There isn't really any need to mask/unmask at the irqchip level because |
12618 |
+- * the 64-bit INTCAPXT registers can be updated atomically without tearing |
12619 |
+- * when the affinity is being updated. |
12620 |
+- */ |
12621 |
+-static void intcapxt_unmask_irq(struct irq_data *data) |
12622 |
+-{ |
12623 |
+-} |
12624 |
+- |
12625 |
+-static void intcapxt_mask_irq(struct irq_data *data) |
12626 |
+-{ |
12627 |
+-} |
12628 |
+ |
12629 |
+ static struct irq_chip intcapxt_controller; |
12630 |
+ |
12631 |
+ static int intcapxt_irqdomain_activate(struct irq_domain *domain, |
12632 |
+ struct irq_data *irqd, bool reserve) |
12633 |
+ { |
12634 |
+- struct amd_iommu *iommu = irqd->chip_data; |
12635 |
+- struct irq_cfg *cfg = irqd_cfg(irqd); |
12636 |
+- union intcapxt xt; |
12637 |
+- |
12638 |
+- xt.capxt = 0ULL; |
12639 |
+- xt.dest_mode_logical = apic->dest_mode_logical; |
12640 |
+- xt.vector = cfg->vector; |
12641 |
+- xt.destid_0_23 = cfg->dest_apicid & GENMASK(23, 0); |
12642 |
+- xt.destid_24_31 = cfg->dest_apicid >> 24; |
12643 |
+- |
12644 |
+- /** |
12645 |
+- * Current IOMMU implemtation uses the same IRQ for all |
12646 |
+- * 3 IOMMU interrupts. |
12647 |
+- */ |
12648 |
+- writeq(xt.capxt, iommu->mmio_base + MMIO_INTCAPXT_EVT_OFFSET); |
12649 |
+- writeq(xt.capxt, iommu->mmio_base + MMIO_INTCAPXT_PPR_OFFSET); |
12650 |
+- writeq(xt.capxt, iommu->mmio_base + MMIO_INTCAPXT_GALOG_OFFSET); |
12651 |
+ return 0; |
12652 |
+ } |
12653 |
+ |
12654 |
+ static void intcapxt_irqdomain_deactivate(struct irq_domain *domain, |
12655 |
+ struct irq_data *irqd) |
12656 |
+ { |
12657 |
+- intcapxt_mask_irq(irqd); |
12658 |
+ } |
12659 |
+ |
12660 |
+ |
12661 |
+@@ -2088,6 +2057,38 @@ static void intcapxt_irqdomain_free(struct irq_domain *domain, unsigned int virq |
12662 |
+ irq_domain_free_irqs_top(domain, virq, nr_irqs); |
12663 |
+ } |
12664 |
+ |
12665 |
++ |
12666 |
++static void intcapxt_unmask_irq(struct irq_data *irqd) |
12667 |
++{ |
12668 |
++ struct amd_iommu *iommu = irqd->chip_data; |
12669 |
++ struct irq_cfg *cfg = irqd_cfg(irqd); |
12670 |
++ union intcapxt xt; |
12671 |
++ |
12672 |
++ xt.capxt = 0ULL; |
12673 |
++ xt.dest_mode_logical = apic->dest_mode_logical; |
12674 |
++ xt.vector = cfg->vector; |
12675 |
++ xt.destid_0_23 = cfg->dest_apicid & GENMASK(23, 0); |
12676 |
++ xt.destid_24_31 = cfg->dest_apicid >> 24; |
12677 |
++ |
12678 |
++ /** |
12679 |
++ * Current IOMMU implementation uses the same IRQ for all |
12680 |
++ * 3 IOMMU interrupts. |
12681 |
++ */ |
12682 |
++ writeq(xt.capxt, iommu->mmio_base + MMIO_INTCAPXT_EVT_OFFSET); |
12683 |
++ writeq(xt.capxt, iommu->mmio_base + MMIO_INTCAPXT_PPR_OFFSET); |
12684 |
++ writeq(xt.capxt, iommu->mmio_base + MMIO_INTCAPXT_GALOG_OFFSET); |
12685 |
++} |
12686 |
++ |
12687 |
++static void intcapxt_mask_irq(struct irq_data *irqd) |
12688 |
++{ |
12689 |
++ struct amd_iommu *iommu = irqd->chip_data; |
12690 |
++ |
12691 |
++ writeq(0, iommu->mmio_base + MMIO_INTCAPXT_EVT_OFFSET); |
12692 |
++ writeq(0, iommu->mmio_base + MMIO_INTCAPXT_PPR_OFFSET); |
12693 |
++ writeq(0, iommu->mmio_base + MMIO_INTCAPXT_GALOG_OFFSET); |
12694 |
++} |
12695 |
++ |
12696 |
++ |
12697 |
+ static int intcapxt_set_affinity(struct irq_data *irqd, |
12698 |
+ const struct cpumask *mask, bool force) |
12699 |
+ { |
12700 |
+@@ -2097,8 +2098,12 @@ static int intcapxt_set_affinity(struct irq_data *irqd, |
12701 |
+ ret = parent->chip->irq_set_affinity(parent, mask, force); |
12702 |
+ if (ret < 0 || ret == IRQ_SET_MASK_OK_DONE) |
12703 |
+ return ret; |
12704 |
++ return 0; |
12705 |
++} |
12706 |
+ |
12707 |
+- return intcapxt_irqdomain_activate(irqd->domain, irqd, false); |
12708 |
++static int intcapxt_set_wake(struct irq_data *irqd, unsigned int on) |
12709 |
++{ |
12710 |
++ return on ? -EOPNOTSUPP : 0; |
12711 |
+ } |
12712 |
+ |
12713 |
+ static struct irq_chip intcapxt_controller = { |
12714 |
+@@ -2108,7 +2113,8 @@ static struct irq_chip intcapxt_controller = { |
12715 |
+ .irq_ack = irq_chip_ack_parent, |
12716 |
+ .irq_retrigger = irq_chip_retrigger_hierarchy, |
12717 |
+ .irq_set_affinity = intcapxt_set_affinity, |
12718 |
+- .flags = IRQCHIP_SKIP_SET_WAKE, |
12719 |
++ .irq_set_wake = intcapxt_set_wake, |
12720 |
++ .flags = IRQCHIP_MASK_ON_SUSPEND, |
12721 |
+ }; |
12722 |
+ |
12723 |
+ static const struct irq_domain_ops intcapxt_domain_ops = { |
12724 |
+@@ -2170,7 +2176,6 @@ static int iommu_setup_intcapxt(struct amd_iommu *iommu) |
12725 |
+ return ret; |
12726 |
+ } |
12727 |
+ |
12728 |
+- iommu_feature_enable(iommu, CONTROL_INTCAPXT_EN); |
12729 |
+ return 0; |
12730 |
+ } |
12731 |
+ |
12732 |
+@@ -2193,6 +2198,10 @@ static int iommu_init_irq(struct amd_iommu *iommu) |
12733 |
+ |
12734 |
+ iommu->int_enabled = true; |
12735 |
+ enable_faults: |
12736 |
++ |
12737 |
++ if (amd_iommu_xt_mode == IRQ_REMAP_X2APIC_MODE) |
12738 |
++ iommu_feature_enable(iommu, CONTROL_INTCAPXT_EN); |
12739 |
++ |
12740 |
+ iommu_feature_enable(iommu, CONTROL_EVT_INT_EN); |
12741 |
+ |
12742 |
+ if (iommu->ppr_log != NULL) |
12743 |
+diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c |
12744 |
+index 55690af1b25d0..c998960495b4e 100644 |
12745 |
+--- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c |
12746 |
++++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c |
12747 |
+@@ -51,7 +51,7 @@ static void qcom_adreno_smmu_get_fault_info(const void *cookie, |
12748 |
+ info->fsynr1 = arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_FSYNR1); |
12749 |
+ info->far = arm_smmu_cb_readq(smmu, cfg->cbndx, ARM_SMMU_CB_FAR); |
12750 |
+ info->cbfrsynra = arm_smmu_gr1_read(smmu, ARM_SMMU_GR1_CBFRSYNRA(cfg->cbndx)); |
12751 |
+- info->ttbr0 = arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_TTBR0); |
12752 |
++ info->ttbr0 = arm_smmu_cb_readq(smmu, cfg->cbndx, ARM_SMMU_CB_TTBR0); |
12753 |
+ info->contextidr = arm_smmu_cb_read(smmu, cfg->cbndx, ARM_SMMU_CB_CONTEXTIDR); |
12754 |
+ } |
12755 |
+ |
12756 |
+diff --git a/drivers/iommu/io-pgtable-arm-v7s.c b/drivers/iommu/io-pgtable-arm-v7s.c |
12757 |
+index bfb6acb651e5f..be066c1503d37 100644 |
12758 |
+--- a/drivers/iommu/io-pgtable-arm-v7s.c |
12759 |
++++ b/drivers/iommu/io-pgtable-arm-v7s.c |
12760 |
+@@ -246,13 +246,17 @@ static void *__arm_v7s_alloc_table(int lvl, gfp_t gfp, |
12761 |
+ __GFP_ZERO | ARM_V7S_TABLE_GFP_DMA, get_order(size)); |
12762 |
+ else if (lvl == 2) |
12763 |
+ table = kmem_cache_zalloc(data->l2_tables, gfp); |
12764 |
++ |
12765 |
++ if (!table) |
12766 |
++ return NULL; |
12767 |
++ |
12768 |
+ phys = virt_to_phys(table); |
12769 |
+ if (phys != (arm_v7s_iopte)phys) { |
12770 |
+ /* Doesn't fit in PTE */ |
12771 |
+ dev_err(dev, "Page table does not fit in PTE: %pa", &phys); |
12772 |
+ goto out_free; |
12773 |
+ } |
12774 |
+- if (table && !cfg->coherent_walk) { |
12775 |
++ if (!cfg->coherent_walk) { |
12776 |
+ dma = dma_map_single(dev, table, size, DMA_TO_DEVICE); |
12777 |
+ if (dma_mapping_error(dev, dma)) |
12778 |
+ goto out_free; |
12779 |
+diff --git a/drivers/iommu/io-pgtable-arm.c b/drivers/iommu/io-pgtable-arm.c |
12780 |
+index dd9e47189d0d9..94ff319ae8acc 100644 |
12781 |
+--- a/drivers/iommu/io-pgtable-arm.c |
12782 |
++++ b/drivers/iommu/io-pgtable-arm.c |
12783 |
+@@ -315,11 +315,12 @@ static int arm_lpae_init_pte(struct arm_lpae_io_pgtable *data, |
12784 |
+ static arm_lpae_iopte arm_lpae_install_table(arm_lpae_iopte *table, |
12785 |
+ arm_lpae_iopte *ptep, |
12786 |
+ arm_lpae_iopte curr, |
12787 |
+- struct io_pgtable_cfg *cfg) |
12788 |
++ struct arm_lpae_io_pgtable *data) |
12789 |
+ { |
12790 |
+ arm_lpae_iopte old, new; |
12791 |
++ struct io_pgtable_cfg *cfg = &data->iop.cfg; |
12792 |
+ |
12793 |
+- new = __pa(table) | ARM_LPAE_PTE_TYPE_TABLE; |
12794 |
++ new = paddr_to_iopte(__pa(table), data) | ARM_LPAE_PTE_TYPE_TABLE; |
12795 |
+ if (cfg->quirks & IO_PGTABLE_QUIRK_ARM_NS) |
12796 |
+ new |= ARM_LPAE_PTE_NSTABLE; |
12797 |
+ |
12798 |
+@@ -380,7 +381,7 @@ static int __arm_lpae_map(struct arm_lpae_io_pgtable *data, unsigned long iova, |
12799 |
+ if (!cptep) |
12800 |
+ return -ENOMEM; |
12801 |
+ |
12802 |
+- pte = arm_lpae_install_table(cptep, ptep, 0, cfg); |
12803 |
++ pte = arm_lpae_install_table(cptep, ptep, 0, data); |
12804 |
+ if (pte) |
12805 |
+ __arm_lpae_free_pages(cptep, tblsz, cfg); |
12806 |
+ } else if (!cfg->coherent_walk && !(pte & ARM_LPAE_PTE_SW_SYNC)) { |
12807 |
+@@ -592,7 +593,7 @@ static size_t arm_lpae_split_blk_unmap(struct arm_lpae_io_pgtable *data, |
12808 |
+ __arm_lpae_init_pte(data, blk_paddr, pte, lvl, 1, &tablep[i]); |
12809 |
+ } |
12810 |
+ |
12811 |
+- pte = arm_lpae_install_table(tablep, ptep, blk_pte, cfg); |
12812 |
++ pte = arm_lpae_install_table(tablep, ptep, blk_pte, data); |
12813 |
+ if (pte != blk_pte) { |
12814 |
+ __arm_lpae_free_pages(tablep, tablesz, cfg); |
12815 |
+ /* |
12816 |
+diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c |
12817 |
+index 3303d707bab4b..f62fb6a58f109 100644 |
12818 |
+--- a/drivers/iommu/iommu.c |
12819 |
++++ b/drivers/iommu/iommu.c |
12820 |
+@@ -287,11 +287,11 @@ int iommu_probe_device(struct device *dev) |
12821 |
+ */ |
12822 |
+ mutex_lock(&group->mutex); |
12823 |
+ iommu_alloc_default_domain(group, dev); |
12824 |
+- mutex_unlock(&group->mutex); |
12825 |
+ |
12826 |
+ if (group->default_domain) { |
12827 |
+ ret = __iommu_attach_device(group->default_domain, dev); |
12828 |
+ if (ret) { |
12829 |
++ mutex_unlock(&group->mutex); |
12830 |
+ iommu_group_put(group); |
12831 |
+ goto err_release; |
12832 |
+ } |
12833 |
+@@ -299,6 +299,7 @@ int iommu_probe_device(struct device *dev) |
12834 |
+ |
12835 |
+ iommu_create_device_direct_mappings(group, dev); |
12836 |
+ |
12837 |
++ mutex_unlock(&group->mutex); |
12838 |
+ iommu_group_put(group); |
12839 |
+ |
12840 |
+ if (ops->probe_finalize) |
12841 |
+diff --git a/drivers/iommu/iova.c b/drivers/iommu/iova.c |
12842 |
+index 9e8bc802ac053..920fcc27c9a1e 100644 |
12843 |
+--- a/drivers/iommu/iova.c |
12844 |
++++ b/drivers/iommu/iova.c |
12845 |
+@@ -83,8 +83,7 @@ static void free_iova_flush_queue(struct iova_domain *iovad) |
12846 |
+ if (!has_iova_flush_queue(iovad)) |
12847 |
+ return; |
12848 |
+ |
12849 |
+- if (timer_pending(&iovad->fq_timer)) |
12850 |
+- del_timer(&iovad->fq_timer); |
12851 |
++ del_timer_sync(&iovad->fq_timer); |
12852 |
+ |
12853 |
+ fq_destroy_all_entries(iovad); |
12854 |
+ |
12855 |
+diff --git a/drivers/irqchip/irq-gic-v3.c b/drivers/irqchip/irq-gic-v3.c |
12856 |
+index fd4e9a37fea67..7bbccb13b896b 100644 |
12857 |
+--- a/drivers/irqchip/irq-gic-v3.c |
12858 |
++++ b/drivers/irqchip/irq-gic-v3.c |
12859 |
+@@ -920,6 +920,22 @@ static int __gic_update_rdist_properties(struct redist_region *region, |
12860 |
+ { |
12861 |
+ u64 typer = gic_read_typer(ptr + GICR_TYPER); |
12862 |
+ |
12863 |
++ /* Boot-time cleanip */ |
12864 |
++ if ((typer & GICR_TYPER_VLPIS) && (typer & GICR_TYPER_RVPEID)) { |
12865 |
++ u64 val; |
12866 |
++ |
12867 |
++ /* Deactivate any present vPE */ |
12868 |
++ val = gicr_read_vpendbaser(ptr + SZ_128K + GICR_VPENDBASER); |
12869 |
++ if (val & GICR_VPENDBASER_Valid) |
12870 |
++ gicr_write_vpendbaser(GICR_VPENDBASER_PendingLast, |
12871 |
++ ptr + SZ_128K + GICR_VPENDBASER); |
12872 |
++ |
12873 |
++ /* Mark the VPE table as invalid */ |
12874 |
++ val = gicr_read_vpropbaser(ptr + SZ_128K + GICR_VPROPBASER); |
12875 |
++ val &= ~GICR_VPROPBASER_4_1_VALID; |
12876 |
++ gicr_write_vpropbaser(val, ptr + SZ_128K + GICR_VPROPBASER); |
12877 |
++ } |
12878 |
++ |
12879 |
+ gic_data.rdists.has_vlpis &= !!(typer & GICR_TYPER_VLPIS); |
12880 |
+ |
12881 |
+ /* RVPEID implies some form of DirectLPI, no matter what the doc says... :-/ */ |
12882 |
+diff --git a/drivers/leds/leds-lp55xx-common.c b/drivers/leds/leds-lp55xx-common.c |
12883 |
+index d1657c46ee2f8..9fdfc1b9a1a0c 100644 |
12884 |
+--- a/drivers/leds/leds-lp55xx-common.c |
12885 |
++++ b/drivers/leds/leds-lp55xx-common.c |
12886 |
+@@ -439,6 +439,8 @@ int lp55xx_init_device(struct lp55xx_chip *chip) |
12887 |
+ return -EINVAL; |
12888 |
+ |
12889 |
+ if (pdata->enable_gpiod) { |
12890 |
++ gpiod_direction_output(pdata->enable_gpiod, 0); |
12891 |
++ |
12892 |
+ gpiod_set_consumer_name(pdata->enable_gpiod, "LP55xx enable"); |
12893 |
+ gpiod_set_value(pdata->enable_gpiod, 0); |
12894 |
+ usleep_range(1000, 2000); /* Keep enable down at least 1ms */ |
12895 |
+@@ -694,7 +696,7 @@ struct lp55xx_platform_data *lp55xx_of_populate_pdata(struct device *dev, |
12896 |
+ of_property_read_u8(np, "clock-mode", &pdata->clock_mode); |
12897 |
+ |
12898 |
+ pdata->enable_gpiod = devm_gpiod_get_optional(dev, "enable", |
12899 |
+- GPIOD_OUT_LOW); |
12900 |
++ GPIOD_ASIS); |
12901 |
+ if (IS_ERR(pdata->enable_gpiod)) |
12902 |
+ return ERR_CAST(pdata->enable_gpiod); |
12903 |
+ |
12904 |
+diff --git a/drivers/mailbox/mailbox-mpfs.c b/drivers/mailbox/mailbox-mpfs.c |
12905 |
+index 0d6e2231a2c75..4e34854d12389 100644 |
12906 |
+--- a/drivers/mailbox/mailbox-mpfs.c |
12907 |
++++ b/drivers/mailbox/mailbox-mpfs.c |
12908 |
+@@ -232,7 +232,7 @@ static int mpfs_mbox_probe(struct platform_device *pdev) |
12909 |
+ } |
12910 |
+ |
12911 |
+ static const struct of_device_id mpfs_mbox_of_match[] = { |
12912 |
+- {.compatible = "microchip,polarfire-soc-mailbox", }, |
12913 |
++ {.compatible = "microchip,mpfs-mailbox", }, |
12914 |
+ {}, |
12915 |
+ }; |
12916 |
+ MODULE_DEVICE_TABLE(of, mpfs_mbox_of_match); |
12917 |
+diff --git a/drivers/mailbox/mtk-cmdq-mailbox.c b/drivers/mailbox/mtk-cmdq-mailbox.c |
12918 |
+index bb4793c7b38fd..3583c2aad0edc 100644 |
12919 |
+--- a/drivers/mailbox/mtk-cmdq-mailbox.c |
12920 |
++++ b/drivers/mailbox/mtk-cmdq-mailbox.c |
12921 |
+@@ -660,7 +660,7 @@ static const struct gce_plat gce_plat_v5 = { |
12922 |
+ .thread_nr = 24, |
12923 |
+ .shift = 3, |
12924 |
+ .control_by_sw = true, |
12925 |
+- .gce_num = 2 |
12926 |
++ .gce_num = 1 |
12927 |
+ }; |
12928 |
+ |
12929 |
+ static const struct gce_plat gce_plat_v6 = { |
12930 |
+diff --git a/drivers/md/dm.c b/drivers/md/dm.c |
12931 |
+index 76d9da49fda75..671bb454f1649 100644 |
12932 |
+--- a/drivers/md/dm.c |
12933 |
++++ b/drivers/md/dm.c |
12934 |
+@@ -1794,8 +1794,10 @@ static struct mapped_device *alloc_dev(int minor) |
12935 |
+ if (IS_ENABLED(CONFIG_DAX_DRIVER)) { |
12936 |
+ md->dax_dev = alloc_dax(md, md->disk->disk_name, |
12937 |
+ &dm_dax_ops, 0); |
12938 |
+- if (IS_ERR(md->dax_dev)) |
12939 |
++ if (IS_ERR(md->dax_dev)) { |
12940 |
++ md->dax_dev = NULL; |
12941 |
+ goto bad; |
12942 |
++ } |
12943 |
+ } |
12944 |
+ |
12945 |
+ format_dev_t(md->name, MKDEV(_major, minor)); |
12946 |
+diff --git a/drivers/md/md.c b/drivers/md/md.c |
12947 |
+index 44006b860d0a5..2d31a079be33f 100644 |
12948 |
+--- a/drivers/md/md.c |
12949 |
++++ b/drivers/md/md.c |
12950 |
+@@ -5872,13 +5872,6 @@ int md_run(struct mddev *mddev) |
12951 |
+ if (err) |
12952 |
+ goto exit_bio_set; |
12953 |
+ } |
12954 |
+- if (mddev->level != 1 && mddev->level != 10 && |
12955 |
+- !bioset_initialized(&mddev->io_acct_set)) { |
12956 |
+- err = bioset_init(&mddev->io_acct_set, BIO_POOL_SIZE, |
12957 |
+- offsetof(struct md_io_acct, bio_clone), 0); |
12958 |
+- if (err) |
12959 |
+- goto exit_sync_set; |
12960 |
+- } |
12961 |
+ |
12962 |
+ spin_lock(&pers_lock); |
12963 |
+ pers = find_pers(mddev->level, mddev->clevel); |
12964 |
+@@ -6055,9 +6048,6 @@ bitmap_abort: |
12965 |
+ module_put(pers->owner); |
12966 |
+ md_bitmap_destroy(mddev); |
12967 |
+ abort: |
12968 |
+- if (mddev->level != 1 && mddev->level != 10) |
12969 |
+- bioset_exit(&mddev->io_acct_set); |
12970 |
+-exit_sync_set: |
12971 |
+ bioset_exit(&mddev->sync_set); |
12972 |
+ exit_bio_set: |
12973 |
+ bioset_exit(&mddev->bio_set); |
12974 |
+@@ -8590,6 +8580,23 @@ void md_submit_discard_bio(struct mddev *mddev, struct md_rdev *rdev, |
12975 |
+ } |
12976 |
+ EXPORT_SYMBOL_GPL(md_submit_discard_bio); |
12977 |
+ |
12978 |
++int acct_bioset_init(struct mddev *mddev) |
12979 |
++{ |
12980 |
++ int err = 0; |
12981 |
++ |
12982 |
++ if (!bioset_initialized(&mddev->io_acct_set)) |
12983 |
++ err = bioset_init(&mddev->io_acct_set, BIO_POOL_SIZE, |
12984 |
++ offsetof(struct md_io_acct, bio_clone), 0); |
12985 |
++ return err; |
12986 |
++} |
12987 |
++EXPORT_SYMBOL_GPL(acct_bioset_init); |
12988 |
++ |
12989 |
++void acct_bioset_exit(struct mddev *mddev) |
12990 |
++{ |
12991 |
++ bioset_exit(&mddev->io_acct_set); |
12992 |
++} |
12993 |
++EXPORT_SYMBOL_GPL(acct_bioset_exit); |
12994 |
++ |
12995 |
+ static void md_end_io_acct(struct bio *bio) |
12996 |
+ { |
12997 |
+ struct md_io_acct *md_io_acct = bio->bi_private; |
12998 |
+diff --git a/drivers/md/md.h b/drivers/md/md.h |
12999 |
+index 4c96c36bd01a1..62852d7011457 100644 |
13000 |
+--- a/drivers/md/md.h |
13001 |
++++ b/drivers/md/md.h |
13002 |
+@@ -721,6 +721,8 @@ extern void md_error(struct mddev *mddev, struct md_rdev *rdev); |
13003 |
+ extern void md_finish_reshape(struct mddev *mddev); |
13004 |
+ void md_submit_discard_bio(struct mddev *mddev, struct md_rdev *rdev, |
13005 |
+ struct bio *bio, sector_t start, sector_t size); |
13006 |
++int acct_bioset_init(struct mddev *mddev); |
13007 |
++void acct_bioset_exit(struct mddev *mddev); |
13008 |
+ void md_account_bio(struct mddev *mddev, struct bio **bio); |
13009 |
+ |
13010 |
+ extern bool __must_check md_flush_request(struct mddev *mddev, struct bio *bio); |
13011 |
+diff --git a/drivers/md/persistent-data/dm-btree.c b/drivers/md/persistent-data/dm-btree.c |
13012 |
+index 0703ca7a7d9a4..5ce64e93aae74 100644 |
13013 |
+--- a/drivers/md/persistent-data/dm-btree.c |
13014 |
++++ b/drivers/md/persistent-data/dm-btree.c |
13015 |
+@@ -81,14 +81,16 @@ void inc_children(struct dm_transaction_manager *tm, struct btree_node *n, |
13016 |
+ } |
13017 |
+ |
13018 |
+ static int insert_at(size_t value_size, struct btree_node *node, unsigned index, |
13019 |
+- uint64_t key, void *value) |
13020 |
+- __dm_written_to_disk(value) |
13021 |
++ uint64_t key, void *value) |
13022 |
++ __dm_written_to_disk(value) |
13023 |
+ { |
13024 |
+ uint32_t nr_entries = le32_to_cpu(node->header.nr_entries); |
13025 |
++ uint32_t max_entries = le32_to_cpu(node->header.max_entries); |
13026 |
+ __le64 key_le = cpu_to_le64(key); |
13027 |
+ |
13028 |
+ if (index > nr_entries || |
13029 |
+- index >= le32_to_cpu(node->header.max_entries)) { |
13030 |
++ index >= max_entries || |
13031 |
++ nr_entries >= max_entries) { |
13032 |
+ DMERR("too many entries in btree node for insert"); |
13033 |
+ __dm_unbless_for_disk(value); |
13034 |
+ return -ENOMEM; |
13035 |
+diff --git a/drivers/md/persistent-data/dm-space-map-common.c b/drivers/md/persistent-data/dm-space-map-common.c |
13036 |
+index 4a6a2a9b4eb49..bfbfa750e0160 100644 |
13037 |
+--- a/drivers/md/persistent-data/dm-space-map-common.c |
13038 |
++++ b/drivers/md/persistent-data/dm-space-map-common.c |
13039 |
+@@ -283,6 +283,11 @@ int sm_ll_lookup_bitmap(struct ll_disk *ll, dm_block_t b, uint32_t *result) |
13040 |
+ struct disk_index_entry ie_disk; |
13041 |
+ struct dm_block *blk; |
13042 |
+ |
13043 |
++ if (b >= ll->nr_blocks) { |
13044 |
++ DMERR_LIMIT("metadata block out of bounds"); |
13045 |
++ return -EINVAL; |
13046 |
++ } |
13047 |
++ |
13048 |
+ b = do_div(index, ll->entries_per_block); |
13049 |
+ r = ll->load_ie(ll, index, &ie_disk); |
13050 |
+ if (r < 0) |
13051 |
+diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c |
13052 |
+index 62c8b6adac70e..b59a77b31b90d 100644 |
13053 |
+--- a/drivers/md/raid0.c |
13054 |
++++ b/drivers/md/raid0.c |
13055 |
+@@ -356,7 +356,21 @@ static sector_t raid0_size(struct mddev *mddev, sector_t sectors, int raid_disks |
13056 |
+ return array_sectors; |
13057 |
+ } |
13058 |
+ |
13059 |
+-static void raid0_free(struct mddev *mddev, void *priv); |
13060 |
++static void free_conf(struct mddev *mddev, struct r0conf *conf) |
13061 |
++{ |
13062 |
++ kfree(conf->strip_zone); |
13063 |
++ kfree(conf->devlist); |
13064 |
++ kfree(conf); |
13065 |
++ mddev->private = NULL; |
13066 |
++} |
13067 |
++ |
13068 |
++static void raid0_free(struct mddev *mddev, void *priv) |
13069 |
++{ |
13070 |
++ struct r0conf *conf = priv; |
13071 |
++ |
13072 |
++ free_conf(mddev, conf); |
13073 |
++ acct_bioset_exit(mddev); |
13074 |
++} |
13075 |
+ |
13076 |
+ static int raid0_run(struct mddev *mddev) |
13077 |
+ { |
13078 |
+@@ -370,11 +384,16 @@ static int raid0_run(struct mddev *mddev) |
13079 |
+ if (md_check_no_bitmap(mddev)) |
13080 |
+ return -EINVAL; |
13081 |
+ |
13082 |
++ if (acct_bioset_init(mddev)) { |
13083 |
++ pr_err("md/raid0:%s: alloc acct bioset failed.\n", mdname(mddev)); |
13084 |
++ return -ENOMEM; |
13085 |
++ } |
13086 |
++ |
13087 |
+ /* if private is not null, we are here after takeover */ |
13088 |
+ if (mddev->private == NULL) { |
13089 |
+ ret = create_strip_zones(mddev, &conf); |
13090 |
+ if (ret < 0) |
13091 |
+- return ret; |
13092 |
++ goto exit_acct_set; |
13093 |
+ mddev->private = conf; |
13094 |
+ } |
13095 |
+ conf = mddev->private; |
13096 |
+@@ -413,17 +432,16 @@ static int raid0_run(struct mddev *mddev) |
13097 |
+ dump_zones(mddev); |
13098 |
+ |
13099 |
+ ret = md_integrity_register(mddev); |
13100 |
++ if (ret) |
13101 |
++ goto free; |
13102 |
+ |
13103 |
+ return ret; |
13104 |
+-} |
13105 |
+ |
13106 |
+-static void raid0_free(struct mddev *mddev, void *priv) |
13107 |
+-{ |
13108 |
+- struct r0conf *conf = priv; |
13109 |
+- |
13110 |
+- kfree(conf->strip_zone); |
13111 |
+- kfree(conf->devlist); |
13112 |
+- kfree(conf); |
13113 |
++free: |
13114 |
++ free_conf(mddev, conf); |
13115 |
++exit_acct_set: |
13116 |
++ acct_bioset_exit(mddev); |
13117 |
++ return ret; |
13118 |
+ } |
13119 |
+ |
13120 |
+ static void raid0_handle_discard(struct mddev *mddev, struct bio *bio) |
13121 |
+diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c |
13122 |
+index 02ed53b20654c..b9d062f0a02b2 100644 |
13123 |
+--- a/drivers/md/raid5.c |
13124 |
++++ b/drivers/md/raid5.c |
13125 |
+@@ -7446,12 +7446,19 @@ static int raid5_run(struct mddev *mddev) |
13126 |
+ struct md_rdev *rdev; |
13127 |
+ struct md_rdev *journal_dev = NULL; |
13128 |
+ sector_t reshape_offset = 0; |
13129 |
+- int i; |
13130 |
++ int i, ret = 0; |
13131 |
+ long long min_offset_diff = 0; |
13132 |
+ int first = 1; |
13133 |
+ |
13134 |
+- if (mddev_init_writes_pending(mddev) < 0) |
13135 |
++ if (acct_bioset_init(mddev)) { |
13136 |
++ pr_err("md/raid456:%s: alloc acct bioset failed.\n", mdname(mddev)); |
13137 |
+ return -ENOMEM; |
13138 |
++ } |
13139 |
++ |
13140 |
++ if (mddev_init_writes_pending(mddev) < 0) { |
13141 |
++ ret = -ENOMEM; |
13142 |
++ goto exit_acct_set; |
13143 |
++ } |
13144 |
+ |
13145 |
+ if (mddev->recovery_cp != MaxSector) |
13146 |
+ pr_notice("md/raid:%s: not clean -- starting background reconstruction\n", |
13147 |
+@@ -7482,7 +7489,8 @@ static int raid5_run(struct mddev *mddev) |
13148 |
+ (mddev->bitmap_info.offset || mddev->bitmap_info.file)) { |
13149 |
+ pr_notice("md/raid:%s: array cannot have both journal and bitmap\n", |
13150 |
+ mdname(mddev)); |
13151 |
+- return -EINVAL; |
13152 |
++ ret = -EINVAL; |
13153 |
++ goto exit_acct_set; |
13154 |
+ } |
13155 |
+ |
13156 |
+ if (mddev->reshape_position != MaxSector) { |
13157 |
+@@ -7507,13 +7515,15 @@ static int raid5_run(struct mddev *mddev) |
13158 |
+ if (journal_dev) { |
13159 |
+ pr_warn("md/raid:%s: don't support reshape with journal - aborting.\n", |
13160 |
+ mdname(mddev)); |
13161 |
+- return -EINVAL; |
13162 |
++ ret = -EINVAL; |
13163 |
++ goto exit_acct_set; |
13164 |
+ } |
13165 |
+ |
13166 |
+ if (mddev->new_level != mddev->level) { |
13167 |
+ pr_warn("md/raid:%s: unsupported reshape required - aborting.\n", |
13168 |
+ mdname(mddev)); |
13169 |
+- return -EINVAL; |
13170 |
++ ret = -EINVAL; |
13171 |
++ goto exit_acct_set; |
13172 |
+ } |
13173 |
+ old_disks = mddev->raid_disks - mddev->delta_disks; |
13174 |
+ /* reshape_position must be on a new-stripe boundary, and one |
13175 |
+@@ -7529,7 +7539,8 @@ static int raid5_run(struct mddev *mddev) |
13176 |
+ if (sector_div(here_new, chunk_sectors * new_data_disks)) { |
13177 |
+ pr_warn("md/raid:%s: reshape_position not on a stripe boundary\n", |
13178 |
+ mdname(mddev)); |
13179 |
+- return -EINVAL; |
13180 |
++ ret = -EINVAL; |
13181 |
++ goto exit_acct_set; |
13182 |
+ } |
13183 |
+ reshape_offset = here_new * chunk_sectors; |
13184 |
+ /* here_new is the stripe we will write to */ |
13185 |
+@@ -7551,7 +7562,8 @@ static int raid5_run(struct mddev *mddev) |
13186 |
+ else if (mddev->ro == 0) { |
13187 |
+ pr_warn("md/raid:%s: in-place reshape must be started in read-only mode - aborting\n", |
13188 |
+ mdname(mddev)); |
13189 |
+- return -EINVAL; |
13190 |
++ ret = -EINVAL; |
13191 |
++ goto exit_acct_set; |
13192 |
+ } |
13193 |
+ } else if (mddev->reshape_backwards |
13194 |
+ ? (here_new * chunk_sectors + min_offset_diff <= |
13195 |
+@@ -7561,7 +7573,8 @@ static int raid5_run(struct mddev *mddev) |
13196 |
+ /* Reading from the same stripe as writing to - bad */ |
13197 |
+ pr_warn("md/raid:%s: reshape_position too early for auto-recovery - aborting.\n", |
13198 |
+ mdname(mddev)); |
13199 |
+- return -EINVAL; |
13200 |
++ ret = -EINVAL; |
13201 |
++ goto exit_acct_set; |
13202 |
+ } |
13203 |
+ pr_debug("md/raid:%s: reshape will continue\n", mdname(mddev)); |
13204 |
+ /* OK, we should be able to continue; */ |
13205 |
+@@ -7585,8 +7598,10 @@ static int raid5_run(struct mddev *mddev) |
13206 |
+ else |
13207 |
+ conf = mddev->private; |
13208 |
+ |
13209 |
+- if (IS_ERR(conf)) |
13210 |
+- return PTR_ERR(conf); |
13211 |
++ if (IS_ERR(conf)) { |
13212 |
++ ret = PTR_ERR(conf); |
13213 |
++ goto exit_acct_set; |
13214 |
++ } |
13215 |
+ |
13216 |
+ if (test_bit(MD_HAS_JOURNAL, &mddev->flags)) { |
13217 |
+ if (!journal_dev) { |
13218 |
+@@ -7786,7 +7801,10 @@ abort: |
13219 |
+ free_conf(conf); |
13220 |
+ mddev->private = NULL; |
13221 |
+ pr_warn("md/raid:%s: failed to run raid set.\n", mdname(mddev)); |
13222 |
+- return -EIO; |
13223 |
++ ret = -EIO; |
13224 |
++exit_acct_set: |
13225 |
++ acct_bioset_exit(mddev); |
13226 |
++ return ret; |
13227 |
+ } |
13228 |
+ |
13229 |
+ static void raid5_free(struct mddev *mddev, void *priv) |
13230 |
+@@ -7794,6 +7812,7 @@ static void raid5_free(struct mddev *mddev, void *priv) |
13231 |
+ struct r5conf *conf = priv; |
13232 |
+ |
13233 |
+ free_conf(conf); |
13234 |
++ acct_bioset_exit(mddev); |
13235 |
+ mddev->to_remove = &raid5_attrs_group; |
13236 |
+ } |
13237 |
+ |
13238 |
+diff --git a/drivers/media/Kconfig b/drivers/media/Kconfig |
13239 |
+index b07812657cee6..f3f24c63536b6 100644 |
13240 |
+--- a/drivers/media/Kconfig |
13241 |
++++ b/drivers/media/Kconfig |
13242 |
+@@ -141,10 +141,10 @@ config MEDIA_TEST_SUPPORT |
13243 |
+ prompt "Test drivers" if MEDIA_SUPPORT_FILTER |
13244 |
+ default y if !MEDIA_SUPPORT_FILTER |
13245 |
+ help |
13246 |
+- Those drivers should not be used on production Kernels, but |
13247 |
+- can be useful on debug ones. It enables several dummy drivers |
13248 |
+- that simulate a real hardware. Very useful to test userspace |
13249 |
+- applications and to validate if the subsystem core is doesn't |
13250 |
++ These drivers should not be used on production kernels, but |
13251 |
++ can be useful on debug ones. This option enables several dummy drivers |
13252 |
++ that simulate real hardware. Very useful to test userspace |
13253 |
++ applications and to validate if the subsystem core doesn't |
13254 |
+ have regressions. |
13255 |
+ |
13256 |
+ Say Y if you want to use some virtual test driver. |
13257 |
+diff --git a/drivers/media/cec/core/cec-adap.c b/drivers/media/cec/core/cec-adap.c |
13258 |
+index cd9cb354dc2c7..1f599e300e42e 100644 |
13259 |
+--- a/drivers/media/cec/core/cec-adap.c |
13260 |
++++ b/drivers/media/cec/core/cec-adap.c |
13261 |
+@@ -161,10 +161,10 @@ static void cec_queue_event(struct cec_adapter *adap, |
13262 |
+ u64 ts = ktime_get_ns(); |
13263 |
+ struct cec_fh *fh; |
13264 |
+ |
13265 |
+- mutex_lock(&adap->devnode.lock); |
13266 |
++ mutex_lock(&adap->devnode.lock_fhs); |
13267 |
+ list_for_each_entry(fh, &adap->devnode.fhs, list) |
13268 |
+ cec_queue_event_fh(fh, ev, ts); |
13269 |
+- mutex_unlock(&adap->devnode.lock); |
13270 |
++ mutex_unlock(&adap->devnode.lock_fhs); |
13271 |
+ } |
13272 |
+ |
13273 |
+ /* Notify userspace that the CEC pin changed state at the given time. */ |
13274 |
+@@ -178,11 +178,12 @@ void cec_queue_pin_cec_event(struct cec_adapter *adap, bool is_high, |
13275 |
+ }; |
13276 |
+ struct cec_fh *fh; |
13277 |
+ |
13278 |
+- mutex_lock(&adap->devnode.lock); |
13279 |
+- list_for_each_entry(fh, &adap->devnode.fhs, list) |
13280 |
++ mutex_lock(&adap->devnode.lock_fhs); |
13281 |
++ list_for_each_entry(fh, &adap->devnode.fhs, list) { |
13282 |
+ if (fh->mode_follower == CEC_MODE_MONITOR_PIN) |
13283 |
+ cec_queue_event_fh(fh, &ev, ktime_to_ns(ts)); |
13284 |
+- mutex_unlock(&adap->devnode.lock); |
13285 |
++ } |
13286 |
++ mutex_unlock(&adap->devnode.lock_fhs); |
13287 |
+ } |
13288 |
+ EXPORT_SYMBOL_GPL(cec_queue_pin_cec_event); |
13289 |
+ |
13290 |
+@@ -195,10 +196,10 @@ void cec_queue_pin_hpd_event(struct cec_adapter *adap, bool is_high, ktime_t ts) |
13291 |
+ }; |
13292 |
+ struct cec_fh *fh; |
13293 |
+ |
13294 |
+- mutex_lock(&adap->devnode.lock); |
13295 |
++ mutex_lock(&adap->devnode.lock_fhs); |
13296 |
+ list_for_each_entry(fh, &adap->devnode.fhs, list) |
13297 |
+ cec_queue_event_fh(fh, &ev, ktime_to_ns(ts)); |
13298 |
+- mutex_unlock(&adap->devnode.lock); |
13299 |
++ mutex_unlock(&adap->devnode.lock_fhs); |
13300 |
+ } |
13301 |
+ EXPORT_SYMBOL_GPL(cec_queue_pin_hpd_event); |
13302 |
+ |
13303 |
+@@ -211,10 +212,10 @@ void cec_queue_pin_5v_event(struct cec_adapter *adap, bool is_high, ktime_t ts) |
13304 |
+ }; |
13305 |
+ struct cec_fh *fh; |
13306 |
+ |
13307 |
+- mutex_lock(&adap->devnode.lock); |
13308 |
++ mutex_lock(&adap->devnode.lock_fhs); |
13309 |
+ list_for_each_entry(fh, &adap->devnode.fhs, list) |
13310 |
+ cec_queue_event_fh(fh, &ev, ktime_to_ns(ts)); |
13311 |
+- mutex_unlock(&adap->devnode.lock); |
13312 |
++ mutex_unlock(&adap->devnode.lock_fhs); |
13313 |
+ } |
13314 |
+ EXPORT_SYMBOL_GPL(cec_queue_pin_5v_event); |
13315 |
+ |
13316 |
+@@ -286,12 +287,12 @@ static void cec_queue_msg_monitor(struct cec_adapter *adap, |
13317 |
+ u32 monitor_mode = valid_la ? CEC_MODE_MONITOR : |
13318 |
+ CEC_MODE_MONITOR_ALL; |
13319 |
+ |
13320 |
+- mutex_lock(&adap->devnode.lock); |
13321 |
++ mutex_lock(&adap->devnode.lock_fhs); |
13322 |
+ list_for_each_entry(fh, &adap->devnode.fhs, list) { |
13323 |
+ if (fh->mode_follower >= monitor_mode) |
13324 |
+ cec_queue_msg_fh(fh, msg); |
13325 |
+ } |
13326 |
+- mutex_unlock(&adap->devnode.lock); |
13327 |
++ mutex_unlock(&adap->devnode.lock_fhs); |
13328 |
+ } |
13329 |
+ |
13330 |
+ /* |
13331 |
+@@ -302,12 +303,12 @@ static void cec_queue_msg_followers(struct cec_adapter *adap, |
13332 |
+ { |
13333 |
+ struct cec_fh *fh; |
13334 |
+ |
13335 |
+- mutex_lock(&adap->devnode.lock); |
13336 |
++ mutex_lock(&adap->devnode.lock_fhs); |
13337 |
+ list_for_each_entry(fh, &adap->devnode.fhs, list) { |
13338 |
+ if (fh->mode_follower == CEC_MODE_FOLLOWER) |
13339 |
+ cec_queue_msg_fh(fh, msg); |
13340 |
+ } |
13341 |
+- mutex_unlock(&adap->devnode.lock); |
13342 |
++ mutex_unlock(&adap->devnode.lock_fhs); |
13343 |
+ } |
13344 |
+ |
13345 |
+ /* Notify userspace of an adapter state change. */ |
13346 |
+@@ -1573,6 +1574,7 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) |
13347 |
+ /* Disabling monitor all mode should always succeed */ |
13348 |
+ if (adap->monitor_all_cnt) |
13349 |
+ WARN_ON(call_op(adap, adap_monitor_all_enable, false)); |
13350 |
++ /* serialize adap_enable */ |
13351 |
+ mutex_lock(&adap->devnode.lock); |
13352 |
+ if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) { |
13353 |
+ WARN_ON(adap->ops->adap_enable(adap, false)); |
13354 |
+@@ -1584,14 +1586,16 @@ void __cec_s_phys_addr(struct cec_adapter *adap, u16 phys_addr, bool block) |
13355 |
+ return; |
13356 |
+ } |
13357 |
+ |
13358 |
++ /* serialize adap_enable */ |
13359 |
+ mutex_lock(&adap->devnode.lock); |
13360 |
+ adap->last_initiator = 0xff; |
13361 |
+ adap->transmit_in_progress = false; |
13362 |
+ |
13363 |
+- if ((adap->needs_hpd || list_empty(&adap->devnode.fhs)) && |
13364 |
+- adap->ops->adap_enable(adap, true)) { |
13365 |
+- mutex_unlock(&adap->devnode.lock); |
13366 |
+- return; |
13367 |
++ if (adap->needs_hpd || list_empty(&adap->devnode.fhs)) { |
13368 |
++ if (adap->ops->adap_enable(adap, true)) { |
13369 |
++ mutex_unlock(&adap->devnode.lock); |
13370 |
++ return; |
13371 |
++ } |
13372 |
+ } |
13373 |
+ |
13374 |
+ if (adap->monitor_all_cnt && |
13375 |
+diff --git a/drivers/media/cec/core/cec-api.c b/drivers/media/cec/core/cec-api.c |
13376 |
+index 769e6b4cddce3..52c30e4e20055 100644 |
13377 |
+--- a/drivers/media/cec/core/cec-api.c |
13378 |
++++ b/drivers/media/cec/core/cec-api.c |
13379 |
+@@ -586,6 +586,7 @@ static int cec_open(struct inode *inode, struct file *filp) |
13380 |
+ return err; |
13381 |
+ } |
13382 |
+ |
13383 |
++ /* serialize adap_enable */ |
13384 |
+ mutex_lock(&devnode->lock); |
13385 |
+ if (list_empty(&devnode->fhs) && |
13386 |
+ !adap->needs_hpd && |
13387 |
+@@ -624,7 +625,9 @@ static int cec_open(struct inode *inode, struct file *filp) |
13388 |
+ } |
13389 |
+ #endif |
13390 |
+ |
13391 |
++ mutex_lock(&devnode->lock_fhs); |
13392 |
+ list_add(&fh->list, &devnode->fhs); |
13393 |
++ mutex_unlock(&devnode->lock_fhs); |
13394 |
+ mutex_unlock(&devnode->lock); |
13395 |
+ |
13396 |
+ return 0; |
13397 |
+@@ -653,8 +656,11 @@ static int cec_release(struct inode *inode, struct file *filp) |
13398 |
+ cec_monitor_all_cnt_dec(adap); |
13399 |
+ mutex_unlock(&adap->lock); |
13400 |
+ |
13401 |
++ /* serialize adap_enable */ |
13402 |
+ mutex_lock(&devnode->lock); |
13403 |
++ mutex_lock(&devnode->lock_fhs); |
13404 |
+ list_del(&fh->list); |
13405 |
++ mutex_unlock(&devnode->lock_fhs); |
13406 |
+ if (cec_is_registered(adap) && list_empty(&devnode->fhs) && |
13407 |
+ !adap->needs_hpd && adap->phys_addr == CEC_PHYS_ADDR_INVALID) { |
13408 |
+ WARN_ON(adap->ops->adap_enable(adap, false)); |
13409 |
+diff --git a/drivers/media/cec/core/cec-core.c b/drivers/media/cec/core/cec-core.c |
13410 |
+index 551689d371a71..ec67065d52021 100644 |
13411 |
+--- a/drivers/media/cec/core/cec-core.c |
13412 |
++++ b/drivers/media/cec/core/cec-core.c |
13413 |
+@@ -169,8 +169,10 @@ static void cec_devnode_unregister(struct cec_adapter *adap) |
13414 |
+ devnode->registered = false; |
13415 |
+ devnode->unregistered = true; |
13416 |
+ |
13417 |
++ mutex_lock(&devnode->lock_fhs); |
13418 |
+ list_for_each_entry(fh, &devnode->fhs, list) |
13419 |
+ wake_up_interruptible(&fh->wait); |
13420 |
++ mutex_unlock(&devnode->lock_fhs); |
13421 |
+ |
13422 |
+ mutex_unlock(&devnode->lock); |
13423 |
+ |
13424 |
+@@ -272,6 +274,7 @@ struct cec_adapter *cec_allocate_adapter(const struct cec_adap_ops *ops, |
13425 |
+ |
13426 |
+ /* adap->devnode initialization */ |
13427 |
+ INIT_LIST_HEAD(&adap->devnode.fhs); |
13428 |
++ mutex_init(&adap->devnode.lock_fhs); |
13429 |
+ mutex_init(&adap->devnode.lock); |
13430 |
+ |
13431 |
+ adap->kthread = kthread_run(cec_thread_func, adap, "cec-%s", name); |
13432 |
+diff --git a/drivers/media/cec/core/cec-pin.c b/drivers/media/cec/core/cec-pin.c |
13433 |
+index 8c613aa649c6f..0eb90cc0ffb0f 100644 |
13434 |
+--- a/drivers/media/cec/core/cec-pin.c |
13435 |
++++ b/drivers/media/cec/core/cec-pin.c |
13436 |
+@@ -1033,6 +1033,7 @@ static int cec_pin_thread_func(void *_adap) |
13437 |
+ { |
13438 |
+ struct cec_adapter *adap = _adap; |
13439 |
+ struct cec_pin *pin = adap->pin; |
13440 |
++ bool irq_enabled = false; |
13441 |
+ |
13442 |
+ for (;;) { |
13443 |
+ wait_event_interruptible(pin->kthread_waitq, |
13444 |
+@@ -1060,6 +1061,7 @@ static int cec_pin_thread_func(void *_adap) |
13445 |
+ ns_to_ktime(pin->work_rx_msg.rx_ts)); |
13446 |
+ msg->len = 0; |
13447 |
+ } |
13448 |
++ |
13449 |
+ if (pin->work_tx_status) { |
13450 |
+ unsigned int tx_status = pin->work_tx_status; |
13451 |
+ |
13452 |
+@@ -1083,27 +1085,39 @@ static int cec_pin_thread_func(void *_adap) |
13453 |
+ switch (atomic_xchg(&pin->work_irq_change, |
13454 |
+ CEC_PIN_IRQ_UNCHANGED)) { |
13455 |
+ case CEC_PIN_IRQ_DISABLE: |
13456 |
+- pin->ops->disable_irq(adap); |
13457 |
++ if (irq_enabled) { |
13458 |
++ pin->ops->disable_irq(adap); |
13459 |
++ irq_enabled = false; |
13460 |
++ } |
13461 |
+ cec_pin_high(pin); |
13462 |
+ cec_pin_to_idle(pin); |
13463 |
+ hrtimer_start(&pin->timer, ns_to_ktime(0), |
13464 |
+ HRTIMER_MODE_REL); |
13465 |
+ break; |
13466 |
+ case CEC_PIN_IRQ_ENABLE: |
13467 |
++ if (irq_enabled) |
13468 |
++ break; |
13469 |
+ pin->enable_irq_failed = !pin->ops->enable_irq(adap); |
13470 |
+ if (pin->enable_irq_failed) { |
13471 |
+ cec_pin_to_idle(pin); |
13472 |
+ hrtimer_start(&pin->timer, ns_to_ktime(0), |
13473 |
+ HRTIMER_MODE_REL); |
13474 |
++ } else { |
13475 |
++ irq_enabled = true; |
13476 |
+ } |
13477 |
+ break; |
13478 |
+ default: |
13479 |
+ break; |
13480 |
+ } |
13481 |
+- |
13482 |
+ if (kthread_should_stop()) |
13483 |
+ break; |
13484 |
+ } |
13485 |
++ if (pin->ops->disable_irq && irq_enabled) |
13486 |
++ pin->ops->disable_irq(adap); |
13487 |
++ hrtimer_cancel(&pin->timer); |
13488 |
++ cec_pin_read(pin); |
13489 |
++ cec_pin_to_idle(pin); |
13490 |
++ pin->state = CEC_ST_OFF; |
13491 |
+ return 0; |
13492 |
+ } |
13493 |
+ |
13494 |
+@@ -1130,13 +1144,7 @@ static int cec_pin_adap_enable(struct cec_adapter *adap, bool enable) |
13495 |
+ hrtimer_start(&pin->timer, ns_to_ktime(0), |
13496 |
+ HRTIMER_MODE_REL); |
13497 |
+ } else { |
13498 |
+- if (pin->ops->disable_irq) |
13499 |
+- pin->ops->disable_irq(adap); |
13500 |
+- hrtimer_cancel(&pin->timer); |
13501 |
+ kthread_stop(pin->kthread); |
13502 |
+- cec_pin_read(pin); |
13503 |
+- cec_pin_to_idle(pin); |
13504 |
+- pin->state = CEC_ST_OFF; |
13505 |
+ } |
13506 |
+ return 0; |
13507 |
+ } |
13508 |
+@@ -1157,11 +1165,8 @@ void cec_pin_start_timer(struct cec_pin *pin) |
13509 |
+ if (pin->state != CEC_ST_RX_IRQ) |
13510 |
+ return; |
13511 |
+ |
13512 |
+- atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_UNCHANGED); |
13513 |
+- pin->ops->disable_irq(pin->adap); |
13514 |
+- cec_pin_high(pin); |
13515 |
+- cec_pin_to_idle(pin); |
13516 |
+- hrtimer_start(&pin->timer, ns_to_ktime(0), HRTIMER_MODE_REL); |
13517 |
++ atomic_set(&pin->work_irq_change, CEC_PIN_IRQ_DISABLE); |
13518 |
++ wake_up_interruptible(&pin->kthread_waitq); |
13519 |
+ } |
13520 |
+ |
13521 |
+ static int cec_pin_adap_transmit(struct cec_adapter *adap, u8 attempts, |
13522 |
+diff --git a/drivers/media/common/saa7146/saa7146_fops.c b/drivers/media/common/saa7146/saa7146_fops.c |
13523 |
+index baf5772c52a96..be32159777142 100644 |
13524 |
+--- a/drivers/media/common/saa7146/saa7146_fops.c |
13525 |
++++ b/drivers/media/common/saa7146/saa7146_fops.c |
13526 |
+@@ -521,7 +521,7 @@ int saa7146_vv_init(struct saa7146_dev* dev, struct saa7146_ext_vv *ext_vv) |
13527 |
+ ERR("out of memory. aborting.\n"); |
13528 |
+ kfree(vv); |
13529 |
+ v4l2_ctrl_handler_free(hdl); |
13530 |
+- return -1; |
13531 |
++ return -ENOMEM; |
13532 |
+ } |
13533 |
+ |
13534 |
+ saa7146_video_uops.init(dev,vv); |
13535 |
+diff --git a/drivers/media/common/videobuf2/videobuf2-dma-contig.c b/drivers/media/common/videobuf2/videobuf2-dma-contig.c |
13536 |
+index be376f3011b68..f8c65b0401054 100644 |
13537 |
+--- a/drivers/media/common/videobuf2/videobuf2-dma-contig.c |
13538 |
++++ b/drivers/media/common/videobuf2/videobuf2-dma-contig.c |
13539 |
+@@ -157,7 +157,7 @@ static void *vb2_dc_alloc(struct vb2_buffer *vb, |
13540 |
+ GFP_KERNEL | vb->vb2_queue->gfp_flags, |
13541 |
+ buf->attrs); |
13542 |
+ if (!buf->cookie) { |
13543 |
+- dev_err(dev, "dma_alloc_coherent of size %ld failed\n", size); |
13544 |
++ dev_err(dev, "dma_alloc_coherent of size %lu failed\n", size); |
13545 |
+ kfree(buf); |
13546 |
+ return ERR_PTR(-ENOMEM); |
13547 |
+ } |
13548 |
+@@ -204,9 +204,9 @@ static int vb2_dc_mmap(void *buf_priv, struct vm_area_struct *vma) |
13549 |
+ |
13550 |
+ vma->vm_ops->open(vma); |
13551 |
+ |
13552 |
+- pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %ld\n", |
13553 |
+- __func__, (unsigned long)buf->dma_addr, vma->vm_start, |
13554 |
+- buf->size); |
13555 |
++ pr_debug("%s: mapped dma addr 0x%08lx at 0x%08lx, size %lu\n", |
13556 |
++ __func__, (unsigned long)buf->dma_addr, vma->vm_start, |
13557 |
++ buf->size); |
13558 |
+ |
13559 |
+ return 0; |
13560 |
+ } |
13561 |
+diff --git a/drivers/media/dvb-core/dmxdev.c b/drivers/media/dvb-core/dmxdev.c |
13562 |
+index 5d5a48475a54f..01f288fa37e0e 100644 |
13563 |
+--- a/drivers/media/dvb-core/dmxdev.c |
13564 |
++++ b/drivers/media/dvb-core/dmxdev.c |
13565 |
+@@ -1413,7 +1413,7 @@ static const struct dvb_device dvbdev_dvr = { |
13566 |
+ }; |
13567 |
+ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) |
13568 |
+ { |
13569 |
+- int i; |
13570 |
++ int i, ret; |
13571 |
+ |
13572 |
+ if (dmxdev->demux->open(dmxdev->demux) < 0) |
13573 |
+ return -EUSERS; |
13574 |
+@@ -1432,14 +1432,26 @@ int dvb_dmxdev_init(struct dmxdev *dmxdev, struct dvb_adapter *dvb_adapter) |
13575 |
+ DMXDEV_STATE_FREE); |
13576 |
+ } |
13577 |
+ |
13578 |
+- dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, |
13579 |
++ ret = dvb_register_device(dvb_adapter, &dmxdev->dvbdev, &dvbdev_demux, dmxdev, |
13580 |
+ DVB_DEVICE_DEMUX, dmxdev->filternum); |
13581 |
+- dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, |
13582 |
++ if (ret < 0) |
13583 |
++ goto err_register_dvbdev; |
13584 |
++ |
13585 |
++ ret = dvb_register_device(dvb_adapter, &dmxdev->dvr_dvbdev, &dvbdev_dvr, |
13586 |
+ dmxdev, DVB_DEVICE_DVR, dmxdev->filternum); |
13587 |
++ if (ret < 0) |
13588 |
++ goto err_register_dvr_dvbdev; |
13589 |
+ |
13590 |
+ dvb_ringbuffer_init(&dmxdev->dvr_buffer, NULL, 8192); |
13591 |
+ |
13592 |
+ return 0; |
13593 |
++ |
13594 |
++err_register_dvr_dvbdev: |
13595 |
++ dvb_unregister_device(dmxdev->dvbdev); |
13596 |
++err_register_dvbdev: |
13597 |
++ vfree(dmxdev->filter); |
13598 |
++ dmxdev->filter = NULL; |
13599 |
++ return ret; |
13600 |
+ } |
13601 |
+ |
13602 |
+ EXPORT_SYMBOL(dvb_dmxdev_init); |
13603 |
+diff --git a/drivers/media/dvb-frontends/dib8000.c b/drivers/media/dvb-frontends/dib8000.c |
13604 |
+index bb02354a48b81..d67f2dd997d06 100644 |
13605 |
+--- a/drivers/media/dvb-frontends/dib8000.c |
13606 |
++++ b/drivers/media/dvb-frontends/dib8000.c |
13607 |
+@@ -4473,8 +4473,10 @@ static struct dvb_frontend *dib8000_init(struct i2c_adapter *i2c_adap, u8 i2c_ad |
13608 |
+ |
13609 |
+ state->timf_default = cfg->pll->timf; |
13610 |
+ |
13611 |
+- if (dib8000_identify(&state->i2c) == 0) |
13612 |
++ if (dib8000_identify(&state->i2c) == 0) { |
13613 |
++ kfree(fe); |
13614 |
+ goto error; |
13615 |
++ } |
13616 |
+ |
13617 |
+ dibx000_init_i2c_master(&state->i2c_master, DIB8000, state->i2c.adap, state->i2c.addr); |
13618 |
+ |
13619 |
+diff --git a/drivers/media/i2c/imx274.c b/drivers/media/i2c/imx274.c |
13620 |
+index 0dce92872176d..4d9b64c61f603 100644 |
13621 |
+--- a/drivers/media/i2c/imx274.c |
13622 |
++++ b/drivers/media/i2c/imx274.c |
13623 |
+@@ -1367,6 +1367,10 @@ static int imx274_s_frame_interval(struct v4l2_subdev *sd, |
13624 |
+ int min, max, def; |
13625 |
+ int ret; |
13626 |
+ |
13627 |
++ ret = pm_runtime_resume_and_get(&imx274->client->dev); |
13628 |
++ if (ret < 0) |
13629 |
++ return ret; |
13630 |
++ |
13631 |
+ mutex_lock(&imx274->lock); |
13632 |
+ ret = imx274_set_frame_interval(imx274, fi->interval); |
13633 |
+ |
13634 |
+@@ -1398,6 +1402,7 @@ static int imx274_s_frame_interval(struct v4l2_subdev *sd, |
13635 |
+ |
13636 |
+ unlock: |
13637 |
+ mutex_unlock(&imx274->lock); |
13638 |
++ pm_runtime_put(&imx274->client->dev); |
13639 |
+ |
13640 |
+ return ret; |
13641 |
+ } |
13642 |
+diff --git a/drivers/media/i2c/ov8865.c b/drivers/media/i2c/ov8865.c |
13643 |
+index ce50f3ea87b8e..92f6c3a940cfb 100644 |
13644 |
+--- a/drivers/media/i2c/ov8865.c |
13645 |
++++ b/drivers/media/i2c/ov8865.c |
13646 |
+@@ -2330,27 +2330,27 @@ static int ov8865_sensor_power(struct ov8865_sensor *sensor, bool on) |
13647 |
+ if (ret) { |
13648 |
+ dev_err(sensor->dev, |
13649 |
+ "failed to enable DOVDD regulator\n"); |
13650 |
+- goto disable; |
13651 |
++ return ret; |
13652 |
+ } |
13653 |
+ |
13654 |
+ ret = regulator_enable(sensor->avdd); |
13655 |
+ if (ret) { |
13656 |
+ dev_err(sensor->dev, |
13657 |
+ "failed to enable AVDD regulator\n"); |
13658 |
+- goto disable; |
13659 |
++ goto disable_dovdd; |
13660 |
+ } |
13661 |
+ |
13662 |
+ ret = regulator_enable(sensor->dvdd); |
13663 |
+ if (ret) { |
13664 |
+ dev_err(sensor->dev, |
13665 |
+ "failed to enable DVDD regulator\n"); |
13666 |
+- goto disable; |
13667 |
++ goto disable_avdd; |
13668 |
+ } |
13669 |
+ |
13670 |
+ ret = clk_prepare_enable(sensor->extclk); |
13671 |
+ if (ret) { |
13672 |
+ dev_err(sensor->dev, "failed to enable EXTCLK clock\n"); |
13673 |
+- goto disable; |
13674 |
++ goto disable_dvdd; |
13675 |
+ } |
13676 |
+ |
13677 |
+ gpiod_set_value_cansleep(sensor->reset, 0); |
13678 |
+@@ -2359,14 +2359,16 @@ static int ov8865_sensor_power(struct ov8865_sensor *sensor, bool on) |
13679 |
+ /* Time to enter streaming mode according to power timings. */ |
13680 |
+ usleep_range(10000, 12000); |
13681 |
+ } else { |
13682 |
+-disable: |
13683 |
+ gpiod_set_value_cansleep(sensor->powerdown, 1); |
13684 |
+ gpiod_set_value_cansleep(sensor->reset, 1); |
13685 |
+ |
13686 |
+ clk_disable_unprepare(sensor->extclk); |
13687 |
+ |
13688 |
++disable_dvdd: |
13689 |
+ regulator_disable(sensor->dvdd); |
13690 |
++disable_avdd: |
13691 |
+ regulator_disable(sensor->avdd); |
13692 |
++disable_dovdd: |
13693 |
+ regulator_disable(sensor->dovdd); |
13694 |
+ } |
13695 |
+ |
13696 |
+@@ -2891,14 +2893,16 @@ static int ov8865_probe(struct i2c_client *client) |
13697 |
+ if (ret) |
13698 |
+ goto error_mutex; |
13699 |
+ |
13700 |
++ mutex_lock(&sensor->mutex); |
13701 |
+ ret = ov8865_state_init(sensor); |
13702 |
++ mutex_unlock(&sensor->mutex); |
13703 |
+ if (ret) |
13704 |
+ goto error_ctrls; |
13705 |
+ |
13706 |
+ /* Runtime PM */ |
13707 |
+ |
13708 |
+- pm_runtime_enable(sensor->dev); |
13709 |
+ pm_runtime_set_suspended(sensor->dev); |
13710 |
++ pm_runtime_enable(sensor->dev); |
13711 |
+ |
13712 |
+ /* V4L2 subdev register */ |
13713 |
+ |
13714 |
+diff --git a/drivers/media/pci/b2c2/flexcop-pci.c b/drivers/media/pci/b2c2/flexcop-pci.c |
13715 |
+index 6a4c7cb0ad0f9..486c8ec0fa60d 100644 |
13716 |
+--- a/drivers/media/pci/b2c2/flexcop-pci.c |
13717 |
++++ b/drivers/media/pci/b2c2/flexcop-pci.c |
13718 |
+@@ -185,6 +185,8 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) |
13719 |
+ dma_addr_t cur_addr = |
13720 |
+ fc->read_ibi_reg(fc,dma1_008).dma_0x8.dma_cur_addr << 2; |
13721 |
+ u32 cur_pos = cur_addr - fc_pci->dma[0].dma_addr0; |
13722 |
++ if (cur_pos > fc_pci->dma[0].size * 2) |
13723 |
++ goto error; |
13724 |
+ |
13725 |
+ deb_irq("%u irq: %08x cur_addr: %llx: cur_pos: %08x, last_cur_pos: %08x ", |
13726 |
+ jiffies_to_usecs(jiffies - fc_pci->last_irq), |
13727 |
+@@ -225,6 +227,7 @@ static irqreturn_t flexcop_pci_isr(int irq, void *dev_id) |
13728 |
+ ret = IRQ_NONE; |
13729 |
+ } |
13730 |
+ |
13731 |
++error: |
13732 |
+ spin_unlock_irqrestore(&fc_pci->irq_lock, flags); |
13733 |
+ return ret; |
13734 |
+ } |
13735 |
+diff --git a/drivers/media/pci/saa7146/hexium_gemini.c b/drivers/media/pci/saa7146/hexium_gemini.c |
13736 |
+index 2214c74bbbf15..3947701cd6c7e 100644 |
13737 |
+--- a/drivers/media/pci/saa7146/hexium_gemini.c |
13738 |
++++ b/drivers/media/pci/saa7146/hexium_gemini.c |
13739 |
+@@ -284,7 +284,12 @@ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_d |
13740 |
+ hexium_set_input(hexium, 0); |
13741 |
+ hexium->cur_input = 0; |
13742 |
+ |
13743 |
+- saa7146_vv_init(dev, &vv_data); |
13744 |
++ ret = saa7146_vv_init(dev, &vv_data); |
13745 |
++ if (ret) { |
13746 |
++ i2c_del_adapter(&hexium->i2c_adapter); |
13747 |
++ kfree(hexium); |
13748 |
++ return ret; |
13749 |
++ } |
13750 |
+ |
13751 |
+ vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input; |
13752 |
+ vv_data.vid_ops.vidioc_g_input = vidioc_g_input; |
13753 |
+diff --git a/drivers/media/pci/saa7146/hexium_orion.c b/drivers/media/pci/saa7146/hexium_orion.c |
13754 |
+index 39d14c179d229..2eb4bee16b71f 100644 |
13755 |
+--- a/drivers/media/pci/saa7146/hexium_orion.c |
13756 |
++++ b/drivers/media/pci/saa7146/hexium_orion.c |
13757 |
+@@ -355,10 +355,16 @@ static struct saa7146_ext_vv vv_data; |
13758 |
+ static int hexium_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) |
13759 |
+ { |
13760 |
+ struct hexium *hexium = (struct hexium *) dev->ext_priv; |
13761 |
++ int ret; |
13762 |
+ |
13763 |
+ DEB_EE("\n"); |
13764 |
+ |
13765 |
+- saa7146_vv_init(dev, &vv_data); |
13766 |
++ ret = saa7146_vv_init(dev, &vv_data); |
13767 |
++ if (ret) { |
13768 |
++ pr_err("Error in saa7146_vv_init()\n"); |
13769 |
++ return ret; |
13770 |
++ } |
13771 |
++ |
13772 |
+ vv_data.vid_ops.vidioc_enum_input = vidioc_enum_input; |
13773 |
+ vv_data.vid_ops.vidioc_g_input = vidioc_g_input; |
13774 |
+ vv_data.vid_ops.vidioc_s_input = vidioc_s_input; |
13775 |
+diff --git a/drivers/media/pci/saa7146/mxb.c b/drivers/media/pci/saa7146/mxb.c |
13776 |
+index 73fc901ecf3db..bf0b9b0914cd5 100644 |
13777 |
+--- a/drivers/media/pci/saa7146/mxb.c |
13778 |
++++ b/drivers/media/pci/saa7146/mxb.c |
13779 |
+@@ -683,10 +683,16 @@ static struct saa7146_ext_vv vv_data; |
13780 |
+ static int mxb_attach(struct saa7146_dev *dev, struct saa7146_pci_extension_data *info) |
13781 |
+ { |
13782 |
+ struct mxb *mxb; |
13783 |
++ int ret; |
13784 |
+ |
13785 |
+ DEB_EE("dev:%p\n", dev); |
13786 |
+ |
13787 |
+- saa7146_vv_init(dev, &vv_data); |
13788 |
++ ret = saa7146_vv_init(dev, &vv_data); |
13789 |
++ if (ret) { |
13790 |
++ ERR("Error in saa7146_vv_init()"); |
13791 |
++ return ret; |
13792 |
++ } |
13793 |
++ |
13794 |
+ if (mxb_probe(dev)) { |
13795 |
+ saa7146_vv_release(dev); |
13796 |
+ return -1; |
13797 |
+diff --git a/drivers/media/platform/aspeed-video.c b/drivers/media/platform/aspeed-video.c |
13798 |
+index 7bb6babdcade0..debc7509c173c 100644 |
13799 |
+--- a/drivers/media/platform/aspeed-video.c |
13800 |
++++ b/drivers/media/platform/aspeed-video.c |
13801 |
+@@ -500,6 +500,10 @@ static void aspeed_video_enable_mode_detect(struct aspeed_video *video) |
13802 |
+ aspeed_video_update(video, VE_INTERRUPT_CTRL, 0, |
13803 |
+ VE_INTERRUPT_MODE_DETECT); |
13804 |
+ |
13805 |
++ /* Disable mode detect in order to re-trigger */ |
13806 |
++ aspeed_video_update(video, VE_SEQ_CTRL, |
13807 |
++ VE_SEQ_CTRL_TRIG_MODE_DET, 0); |
13808 |
++ |
13809 |
+ /* Trigger mode detect */ |
13810 |
+ aspeed_video_update(video, VE_SEQ_CTRL, 0, VE_SEQ_CTRL_TRIG_MODE_DET); |
13811 |
+ } |
13812 |
+@@ -552,6 +556,8 @@ static void aspeed_video_irq_res_change(struct aspeed_video *video, ulong delay) |
13813 |
+ set_bit(VIDEO_RES_CHANGE, &video->flags); |
13814 |
+ clear_bit(VIDEO_FRAME_INPRG, &video->flags); |
13815 |
+ |
13816 |
++ video->v4l2_input_status = V4L2_IN_ST_NO_SIGNAL; |
13817 |
++ |
13818 |
+ aspeed_video_off(video); |
13819 |
+ aspeed_video_bufs_done(video, VB2_BUF_STATE_ERROR); |
13820 |
+ |
13821 |
+@@ -786,10 +792,6 @@ static void aspeed_video_get_resolution(struct aspeed_video *video) |
13822 |
+ return; |
13823 |
+ } |
13824 |
+ |
13825 |
+- /* Disable mode detect in order to re-trigger */ |
13826 |
+- aspeed_video_update(video, VE_SEQ_CTRL, |
13827 |
+- VE_SEQ_CTRL_TRIG_MODE_DET, 0); |
13828 |
+- |
13829 |
+ aspeed_video_check_and_set_polarity(video); |
13830 |
+ |
13831 |
+ aspeed_video_enable_mode_detect(video); |
13832 |
+@@ -1337,7 +1339,6 @@ static void aspeed_video_resolution_work(struct work_struct *work) |
13833 |
+ struct delayed_work *dwork = to_delayed_work(work); |
13834 |
+ struct aspeed_video *video = container_of(dwork, struct aspeed_video, |
13835 |
+ res_work); |
13836 |
+- u32 input_status = video->v4l2_input_status; |
13837 |
+ |
13838 |
+ aspeed_video_on(video); |
13839 |
+ |
13840 |
+@@ -1350,8 +1351,7 @@ static void aspeed_video_resolution_work(struct work_struct *work) |
13841 |
+ aspeed_video_get_resolution(video); |
13842 |
+ |
13843 |
+ if (video->detected_timings.width != video->active_timings.width || |
13844 |
+- video->detected_timings.height != video->active_timings.height || |
13845 |
+- input_status != video->v4l2_input_status) { |
13846 |
++ video->detected_timings.height != video->active_timings.height) { |
13847 |
+ static const struct v4l2_event ev = { |
13848 |
+ .type = V4L2_EVENT_SOURCE_CHANGE, |
13849 |
+ .u.src_change.changes = V4L2_EVENT_SRC_CH_RESOLUTION, |
13850 |
+diff --git a/drivers/media/platform/coda/coda-common.c b/drivers/media/platform/coda/coda-common.c |
13851 |
+index 0e312b0842d7f..9a2640a9c75c6 100644 |
13852 |
+--- a/drivers/media/platform/coda/coda-common.c |
13853 |
++++ b/drivers/media/platform/coda/coda-common.c |
13854 |
+@@ -1537,11 +1537,13 @@ static void coda_pic_run_work(struct work_struct *work) |
13855 |
+ |
13856 |
+ if (!wait_for_completion_timeout(&ctx->completion, |
13857 |
+ msecs_to_jiffies(1000))) { |
13858 |
+- dev_err(dev->dev, "CODA PIC_RUN timeout\n"); |
13859 |
++ if (ctx->use_bit) { |
13860 |
++ dev_err(dev->dev, "CODA PIC_RUN timeout\n"); |
13861 |
+ |
13862 |
+- ctx->hold = true; |
13863 |
++ ctx->hold = true; |
13864 |
+ |
13865 |
+- coda_hw_reset(ctx); |
13866 |
++ coda_hw_reset(ctx); |
13867 |
++ } |
13868 |
+ |
13869 |
+ if (ctx->ops->run_timeout) |
13870 |
+ ctx->ops->run_timeout(ctx); |
13871 |
+diff --git a/drivers/media/platform/coda/coda-jpeg.c b/drivers/media/platform/coda/coda-jpeg.c |
13872 |
+index b11cfbe166dd3..a72f4655e5ad5 100644 |
13873 |
+--- a/drivers/media/platform/coda/coda-jpeg.c |
13874 |
++++ b/drivers/media/platform/coda/coda-jpeg.c |
13875 |
+@@ -1127,7 +1127,8 @@ static int coda9_jpeg_prepare_encode(struct coda_ctx *ctx) |
13876 |
+ coda_write(dev, 0, CODA9_REG_JPEG_GBU_BT_PTR); |
13877 |
+ coda_write(dev, 0, CODA9_REG_JPEG_GBU_WD_PTR); |
13878 |
+ coda_write(dev, 0, CODA9_REG_JPEG_GBU_BBSR); |
13879 |
+- coda_write(dev, 0, CODA9_REG_JPEG_BBC_STRM_CTRL); |
13880 |
++ coda_write(dev, BIT(31) | ((end_addr - start_addr - header_len) / 256), |
13881 |
++ CODA9_REG_JPEG_BBC_STRM_CTRL); |
13882 |
+ coda_write(dev, 0, CODA9_REG_JPEG_GBU_CTRL); |
13883 |
+ coda_write(dev, 0, CODA9_REG_JPEG_GBU_FF_RPTR); |
13884 |
+ coda_write(dev, 127, CODA9_REG_JPEG_GBU_BBER); |
13885 |
+@@ -1257,6 +1258,23 @@ static void coda9_jpeg_finish_encode(struct coda_ctx *ctx) |
13886 |
+ coda_hw_reset(ctx); |
13887 |
+ } |
13888 |
+ |
13889 |
++static void coda9_jpeg_encode_timeout(struct coda_ctx *ctx) |
13890 |
++{ |
13891 |
++ struct coda_dev *dev = ctx->dev; |
13892 |
++ u32 end_addr, wr_ptr; |
13893 |
++ |
13894 |
++ /* Handle missing BBC overflow interrupt via timeout */ |
13895 |
++ end_addr = coda_read(dev, CODA9_REG_JPEG_BBC_END_ADDR); |
13896 |
++ wr_ptr = coda_read(dev, CODA9_REG_JPEG_BBC_WR_PTR); |
13897 |
++ if (wr_ptr >= end_addr - 256) { |
13898 |
++ v4l2_err(&dev->v4l2_dev, "JPEG too large for capture buffer\n"); |
13899 |
++ coda9_jpeg_finish_encode(ctx); |
13900 |
++ return; |
13901 |
++ } |
13902 |
++ |
13903 |
++ coda_hw_reset(ctx); |
13904 |
++} |
13905 |
++ |
13906 |
+ static void coda9_jpeg_release(struct coda_ctx *ctx) |
13907 |
+ { |
13908 |
+ int i; |
13909 |
+@@ -1276,6 +1294,7 @@ const struct coda_context_ops coda9_jpeg_encode_ops = { |
13910 |
+ .start_streaming = coda9_jpeg_start_encoding, |
13911 |
+ .prepare_run = coda9_jpeg_prepare_encode, |
13912 |
+ .finish_run = coda9_jpeg_finish_encode, |
13913 |
++ .run_timeout = coda9_jpeg_encode_timeout, |
13914 |
+ .release = coda9_jpeg_release, |
13915 |
+ }; |
13916 |
+ |
13917 |
+diff --git a/drivers/media/platform/coda/imx-vdoa.c b/drivers/media/platform/coda/imx-vdoa.c |
13918 |
+index 8bc0d83718193..dd6e2e320264e 100644 |
13919 |
+--- a/drivers/media/platform/coda/imx-vdoa.c |
13920 |
++++ b/drivers/media/platform/coda/imx-vdoa.c |
13921 |
+@@ -287,7 +287,11 @@ static int vdoa_probe(struct platform_device *pdev) |
13922 |
+ struct resource *res; |
13923 |
+ int ret; |
13924 |
+ |
13925 |
+- dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); |
13926 |
++ ret = dma_set_coherent_mask(&pdev->dev, DMA_BIT_MASK(32)); |
13927 |
++ if (ret) { |
13928 |
++ dev_err(&pdev->dev, "DMA enable failed\n"); |
13929 |
++ return ret; |
13930 |
++ } |
13931 |
+ |
13932 |
+ vdoa = devm_kzalloc(&pdev->dev, sizeof(*vdoa), GFP_KERNEL); |
13933 |
+ if (!vdoa) |
13934 |
+diff --git a/drivers/media/platform/imx-pxp.c b/drivers/media/platform/imx-pxp.c |
13935 |
+index 4321edc0c23d9..8e9c6fee75a48 100644 |
13936 |
+--- a/drivers/media/platform/imx-pxp.c |
13937 |
++++ b/drivers/media/platform/imx-pxp.c |
13938 |
+@@ -1661,6 +1661,8 @@ static int pxp_probe(struct platform_device *pdev) |
13939 |
+ if (irq < 0) |
13940 |
+ return irq; |
13941 |
+ |
13942 |
++ spin_lock_init(&dev->irqlock); |
13943 |
++ |
13944 |
+ ret = devm_request_threaded_irq(&pdev->dev, irq, NULL, pxp_irq_handler, |
13945 |
+ IRQF_ONESHOT, dev_name(&pdev->dev), dev); |
13946 |
+ if (ret < 0) { |
13947 |
+@@ -1678,8 +1680,6 @@ static int pxp_probe(struct platform_device *pdev) |
13948 |
+ goto err_clk; |
13949 |
+ } |
13950 |
+ |
13951 |
+- spin_lock_init(&dev->irqlock); |
13952 |
+- |
13953 |
+ ret = v4l2_device_register(&pdev->dev, &dev->v4l2_dev); |
13954 |
+ if (ret) |
13955 |
+ goto err_clk; |
13956 |
+diff --git a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c |
13957 |
+index 45d1870c83dd7..4ced20ca647b1 100644 |
13958 |
+--- a/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c |
13959 |
++++ b/drivers/media/platform/mtk-vcodec/mtk_vcodec_enc_drv.c |
13960 |
+@@ -218,11 +218,11 @@ static int fops_vcodec_release(struct file *file) |
13961 |
+ mtk_v4l2_debug(1, "[%d] encoder", ctx->id); |
13962 |
+ mutex_lock(&dev->dev_mutex); |
13963 |
+ |
13964 |
++ v4l2_m2m_ctx_release(ctx->m2m_ctx); |
13965 |
+ mtk_vcodec_enc_release(ctx); |
13966 |
+ v4l2_fh_del(&ctx->fh); |
13967 |
+ v4l2_fh_exit(&ctx->fh); |
13968 |
+ v4l2_ctrl_handler_free(&ctx->ctrl_hdl); |
13969 |
+- v4l2_m2m_ctx_release(ctx->m2m_ctx); |
13970 |
+ |
13971 |
+ list_del_init(&ctx->list); |
13972 |
+ kfree(ctx); |
13973 |
+diff --git a/drivers/media/platform/qcom/venus/core.c b/drivers/media/platform/qcom/venus/core.c |
13974 |
+index 91b15842c5558..1f0181b6353c9 100644 |
13975 |
+--- a/drivers/media/platform/qcom/venus/core.c |
13976 |
++++ b/drivers/media/platform/qcom/venus/core.c |
13977 |
+@@ -349,11 +349,11 @@ static int venus_probe(struct platform_device *pdev) |
13978 |
+ |
13979 |
+ ret = venus_firmware_init(core); |
13980 |
+ if (ret) |
13981 |
+- goto err_runtime_disable; |
13982 |
++ goto err_of_depopulate; |
13983 |
+ |
13984 |
+ ret = venus_boot(core); |
13985 |
+ if (ret) |
13986 |
+- goto err_runtime_disable; |
13987 |
++ goto err_firmware_deinit; |
13988 |
+ |
13989 |
+ ret = hfi_core_resume(core, true); |
13990 |
+ if (ret) |
13991 |
+@@ -385,6 +385,10 @@ err_dev_unregister: |
13992 |
+ v4l2_device_unregister(&core->v4l2_dev); |
13993 |
+ err_venus_shutdown: |
13994 |
+ venus_shutdown(core); |
13995 |
++err_firmware_deinit: |
13996 |
++ venus_firmware_deinit(core); |
13997 |
++err_of_depopulate: |
13998 |
++ of_platform_depopulate(dev); |
13999 |
+ err_runtime_disable: |
14000 |
+ pm_runtime_put_noidle(dev); |
14001 |
+ pm_runtime_set_suspended(dev); |
14002 |
+@@ -472,7 +476,8 @@ static __maybe_unused int venus_runtime_suspend(struct device *dev) |
14003 |
+ err_video_path: |
14004 |
+ icc_set_bw(core->cpucfg_path, kbps_to_icc(1000), 0); |
14005 |
+ err_cpucfg_path: |
14006 |
+- pm_ops->core_power(core, POWER_ON); |
14007 |
++ if (pm_ops->core_power) |
14008 |
++ pm_ops->core_power(core, POWER_ON); |
14009 |
+ |
14010 |
+ return ret; |
14011 |
+ } |
14012 |
+diff --git a/drivers/media/platform/qcom/venus/pm_helpers.c b/drivers/media/platform/qcom/venus/pm_helpers.c |
14013 |
+index e031fd17f4e75..a591dd315ebcc 100644 |
14014 |
+--- a/drivers/media/platform/qcom/venus/pm_helpers.c |
14015 |
++++ b/drivers/media/platform/qcom/venus/pm_helpers.c |
14016 |
+@@ -163,14 +163,12 @@ static u32 load_per_type(struct venus_core *core, u32 session_type) |
14017 |
+ struct venus_inst *inst = NULL; |
14018 |
+ u32 mbs_per_sec = 0; |
14019 |
+ |
14020 |
+- mutex_lock(&core->lock); |
14021 |
+ list_for_each_entry(inst, &core->instances, list) { |
14022 |
+ if (inst->session_type != session_type) |
14023 |
+ continue; |
14024 |
+ |
14025 |
+ mbs_per_sec += load_per_instance(inst); |
14026 |
+ } |
14027 |
+- mutex_unlock(&core->lock); |
14028 |
+ |
14029 |
+ return mbs_per_sec; |
14030 |
+ } |
14031 |
+@@ -219,14 +217,12 @@ static int load_scale_bw(struct venus_core *core) |
14032 |
+ struct venus_inst *inst = NULL; |
14033 |
+ u32 mbs_per_sec, avg, peak, total_avg = 0, total_peak = 0; |
14034 |
+ |
14035 |
+- mutex_lock(&core->lock); |
14036 |
+ list_for_each_entry(inst, &core->instances, list) { |
14037 |
+ mbs_per_sec = load_per_instance(inst); |
14038 |
+ mbs_to_bw(inst, mbs_per_sec, &avg, &peak); |
14039 |
+ total_avg += avg; |
14040 |
+ total_peak += peak; |
14041 |
+ } |
14042 |
+- mutex_unlock(&core->lock); |
14043 |
+ |
14044 |
+ /* |
14045 |
+ * keep minimum bandwidth vote for "video-mem" path, |
14046 |
+@@ -253,8 +249,9 @@ static int load_scale_v1(struct venus_inst *inst) |
14047 |
+ struct device *dev = core->dev; |
14048 |
+ u32 mbs_per_sec; |
14049 |
+ unsigned int i; |
14050 |
+- int ret; |
14051 |
++ int ret = 0; |
14052 |
+ |
14053 |
++ mutex_lock(&core->lock); |
14054 |
+ mbs_per_sec = load_per_type(core, VIDC_SESSION_TYPE_ENC) + |
14055 |
+ load_per_type(core, VIDC_SESSION_TYPE_DEC); |
14056 |
+ |
14057 |
+@@ -279,17 +276,19 @@ set_freq: |
14058 |
+ if (ret) { |
14059 |
+ dev_err(dev, "failed to set clock rate %lu (%d)\n", |
14060 |
+ freq, ret); |
14061 |
+- return ret; |
14062 |
++ goto exit; |
14063 |
+ } |
14064 |
+ |
14065 |
+ ret = load_scale_bw(core); |
14066 |
+ if (ret) { |
14067 |
+ dev_err(dev, "failed to set bandwidth (%d)\n", |
14068 |
+ ret); |
14069 |
+- return ret; |
14070 |
++ goto exit; |
14071 |
+ } |
14072 |
+ |
14073 |
+- return 0; |
14074 |
++exit: |
14075 |
++ mutex_unlock(&core->lock); |
14076 |
++ return ret; |
14077 |
+ } |
14078 |
+ |
14079 |
+ static int core_get_v1(struct venus_core *core) |
14080 |
+@@ -587,8 +586,8 @@ min_loaded_core(struct venus_inst *inst, u32 *min_coreid, u32 *min_load, bool lo |
14081 |
+ if (inst->session_type == VIDC_SESSION_TYPE_DEC) |
14082 |
+ vpp_freq = inst_pos->clk_data.vpp_freq; |
14083 |
+ else if (inst->session_type == VIDC_SESSION_TYPE_ENC) |
14084 |
+- vpp_freq = low_power ? inst_pos->clk_data.vpp_freq : |
14085 |
+- inst_pos->clk_data.low_power_freq; |
14086 |
++ vpp_freq = low_power ? inst_pos->clk_data.low_power_freq : |
14087 |
++ inst_pos->clk_data.vpp_freq; |
14088 |
+ else |
14089 |
+ continue; |
14090 |
+ |
14091 |
+@@ -1116,13 +1115,13 @@ static int load_scale_v4(struct venus_inst *inst) |
14092 |
+ struct device *dev = core->dev; |
14093 |
+ unsigned long freq = 0, freq_core1 = 0, freq_core2 = 0; |
14094 |
+ unsigned long filled_len = 0; |
14095 |
+- int i, ret; |
14096 |
++ int i, ret = 0; |
14097 |
+ |
14098 |
+ for (i = 0; i < inst->num_input_bufs; i++) |
14099 |
+ filled_len = max(filled_len, inst->payloads[i]); |
14100 |
+ |
14101 |
+ if (inst->session_type == VIDC_SESSION_TYPE_DEC && !filled_len) |
14102 |
+- return 0; |
14103 |
++ return ret; |
14104 |
+ |
14105 |
+ freq = calculate_inst_freq(inst, filled_len); |
14106 |
+ inst->clk_data.freq = freq; |
14107 |
+@@ -1138,7 +1137,6 @@ static int load_scale_v4(struct venus_inst *inst) |
14108 |
+ freq_core2 += inst->clk_data.freq; |
14109 |
+ } |
14110 |
+ } |
14111 |
+- mutex_unlock(&core->lock); |
14112 |
+ |
14113 |
+ freq = max(freq_core1, freq_core2); |
14114 |
+ |
14115 |
+@@ -1162,17 +1160,19 @@ set_freq: |
14116 |
+ if (ret) { |
14117 |
+ dev_err(dev, "failed to set clock rate %lu (%d)\n", |
14118 |
+ freq, ret); |
14119 |
+- return ret; |
14120 |
++ goto exit; |
14121 |
+ } |
14122 |
+ |
14123 |
+ ret = load_scale_bw(core); |
14124 |
+ if (ret) { |
14125 |
+ dev_err(dev, "failed to set bandwidth (%d)\n", |
14126 |
+ ret); |
14127 |
+- return ret; |
14128 |
++ goto exit; |
14129 |
+ } |
14130 |
+ |
14131 |
+- return 0; |
14132 |
++exit: |
14133 |
++ mutex_unlock(&core->lock); |
14134 |
++ return ret; |
14135 |
+ } |
14136 |
+ |
14137 |
+ static const struct venus_pm_ops pm_ops_v4 = { |
14138 |
+diff --git a/drivers/media/platform/rcar-vin/rcar-csi2.c b/drivers/media/platform/rcar-vin/rcar-csi2.c |
14139 |
+index ba4a380016cc4..0c5e2f7e04beb 100644 |
14140 |
+--- a/drivers/media/platform/rcar-vin/rcar-csi2.c |
14141 |
++++ b/drivers/media/platform/rcar-vin/rcar-csi2.c |
14142 |
+@@ -445,16 +445,23 @@ static int rcsi2_wait_phy_start(struct rcar_csi2 *priv, |
14143 |
+ static int rcsi2_set_phypll(struct rcar_csi2 *priv, unsigned int mbps) |
14144 |
+ { |
14145 |
+ const struct rcsi2_mbps_reg *hsfreq; |
14146 |
++ const struct rcsi2_mbps_reg *hsfreq_prev = NULL; |
14147 |
+ |
14148 |
+- for (hsfreq = priv->info->hsfreqrange; hsfreq->mbps != 0; hsfreq++) |
14149 |
++ for (hsfreq = priv->info->hsfreqrange; hsfreq->mbps != 0; hsfreq++) { |
14150 |
+ if (hsfreq->mbps >= mbps) |
14151 |
+ break; |
14152 |
++ hsfreq_prev = hsfreq; |
14153 |
++ } |
14154 |
+ |
14155 |
+ if (!hsfreq->mbps) { |
14156 |
+ dev_err(priv->dev, "Unsupported PHY speed (%u Mbps)", mbps); |
14157 |
+ return -ERANGE; |
14158 |
+ } |
14159 |
+ |
14160 |
++ if (hsfreq_prev && |
14161 |
++ ((mbps - hsfreq_prev->mbps) <= (hsfreq->mbps - mbps))) |
14162 |
++ hsfreq = hsfreq_prev; |
14163 |
++ |
14164 |
+ rcsi2_write(priv, PHYPLL_REG, PHYPLL_HSFREQRANGE(hsfreq->reg)); |
14165 |
+ |
14166 |
+ return 0; |
14167 |
+@@ -982,10 +989,17 @@ static int rcsi2_phtw_write_mbps(struct rcar_csi2 *priv, unsigned int mbps, |
14168 |
+ const struct rcsi2_mbps_reg *values, u16 code) |
14169 |
+ { |
14170 |
+ const struct rcsi2_mbps_reg *value; |
14171 |
++ const struct rcsi2_mbps_reg *prev_value = NULL; |
14172 |
+ |
14173 |
+- for (value = values; value->mbps; value++) |
14174 |
++ for (value = values; value->mbps; value++) { |
14175 |
+ if (value->mbps >= mbps) |
14176 |
+ break; |
14177 |
++ prev_value = value; |
14178 |
++ } |
14179 |
++ |
14180 |
++ if (prev_value && |
14181 |
++ ((mbps - prev_value->mbps) <= (value->mbps - mbps))) |
14182 |
++ value = prev_value; |
14183 |
+ |
14184 |
+ if (!value->mbps) { |
14185 |
+ dev_err(priv->dev, "Unsupported PHY speed (%u Mbps)", mbps); |
14186 |
+diff --git a/drivers/media/platform/rcar-vin/rcar-v4l2.c b/drivers/media/platform/rcar-vin/rcar-v4l2.c |
14187 |
+index 0d141155f0e3e..eb8c79bac540f 100644 |
14188 |
+--- a/drivers/media/platform/rcar-vin/rcar-v4l2.c |
14189 |
++++ b/drivers/media/platform/rcar-vin/rcar-v4l2.c |
14190 |
+@@ -175,20 +175,27 @@ static void rvin_format_align(struct rvin_dev *vin, struct v4l2_pix_format *pix) |
14191 |
+ break; |
14192 |
+ } |
14193 |
+ |
14194 |
+- /* HW limit width to a multiple of 32 (2^5) for NV12/16 else 2 (2^1) */ |
14195 |
++ /* Hardware limits width alignment based on format. */ |
14196 |
+ switch (pix->pixelformat) { |
14197 |
++ /* Multiple of 32 (2^5) for NV12/16. */ |
14198 |
+ case V4L2_PIX_FMT_NV12: |
14199 |
+ case V4L2_PIX_FMT_NV16: |
14200 |
+ walign = 5; |
14201 |
+ break; |
14202 |
+- default: |
14203 |
++ /* Multiple of 2 (2^1) for YUV. */ |
14204 |
++ case V4L2_PIX_FMT_YUYV: |
14205 |
++ case V4L2_PIX_FMT_UYVY: |
14206 |
+ walign = 1; |
14207 |
+ break; |
14208 |
++ /* No multiple for RGB. */ |
14209 |
++ default: |
14210 |
++ walign = 0; |
14211 |
++ break; |
14212 |
+ } |
14213 |
+ |
14214 |
+ /* Limit to VIN capabilities */ |
14215 |
+- v4l_bound_align_image(&pix->width, 2, vin->info->max_width, walign, |
14216 |
+- &pix->height, 4, vin->info->max_height, 2, 0); |
14217 |
++ v4l_bound_align_image(&pix->width, 5, vin->info->max_width, walign, |
14218 |
++ &pix->height, 2, vin->info->max_height, 0, 0); |
14219 |
+ |
14220 |
+ pix->bytesperline = rvin_format_bytesperline(vin, pix); |
14221 |
+ pix->sizeimage = rvin_format_sizeimage(pix); |
14222 |
+diff --git a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c |
14223 |
+index 7474150b94ed3..560f928c37520 100644 |
14224 |
+--- a/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c |
14225 |
++++ b/drivers/media/platform/rockchip/rkisp1/rkisp1-dev.c |
14226 |
+@@ -426,7 +426,7 @@ static void rkisp1_debug_init(struct rkisp1_device *rkisp1) |
14227 |
+ { |
14228 |
+ struct rkisp1_debug *debug = &rkisp1->debug; |
14229 |
+ |
14230 |
+- debug->debugfs_dir = debugfs_create_dir(RKISP1_DRIVER_NAME, NULL); |
14231 |
++ debug->debugfs_dir = debugfs_create_dir(dev_name(rkisp1->dev), NULL); |
14232 |
+ debugfs_create_ulong("data_loss", 0444, debug->debugfs_dir, |
14233 |
+ &debug->data_loss); |
14234 |
+ debugfs_create_ulong("outform_size_err", 0444, debug->debugfs_dir, |
14235 |
+diff --git a/drivers/media/radio/si470x/radio-si470x-i2c.c b/drivers/media/radio/si470x/radio-si470x-i2c.c |
14236 |
+index a972c0705ac79..76d39e2e87706 100644 |
14237 |
+--- a/drivers/media/radio/si470x/radio-si470x-i2c.c |
14238 |
++++ b/drivers/media/radio/si470x/radio-si470x-i2c.c |
14239 |
+@@ -368,7 +368,7 @@ static int si470x_i2c_probe(struct i2c_client *client) |
14240 |
+ if (radio->hdl.error) { |
14241 |
+ retval = radio->hdl.error; |
14242 |
+ dev_err(&client->dev, "couldn't register control\n"); |
14243 |
+- goto err_dev; |
14244 |
++ goto err_all; |
14245 |
+ } |
14246 |
+ |
14247 |
+ /* video device initialization */ |
14248 |
+@@ -463,7 +463,6 @@ static int si470x_i2c_probe(struct i2c_client *client) |
14249 |
+ return 0; |
14250 |
+ err_all: |
14251 |
+ v4l2_ctrl_handler_free(&radio->hdl); |
14252 |
+-err_dev: |
14253 |
+ v4l2_device_unregister(&radio->v4l2_dev); |
14254 |
+ err_initial: |
14255 |
+ return retval; |
14256 |
+diff --git a/drivers/media/rc/igorplugusb.c b/drivers/media/rc/igorplugusb.c |
14257 |
+index effaa5751d6c9..3e9988ee785f0 100644 |
14258 |
+--- a/drivers/media/rc/igorplugusb.c |
14259 |
++++ b/drivers/media/rc/igorplugusb.c |
14260 |
+@@ -64,9 +64,11 @@ static void igorplugusb_irdata(struct igorplugusb *ir, unsigned len) |
14261 |
+ if (start >= len) { |
14262 |
+ dev_err(ir->dev, "receive overflow invalid: %u", overflow); |
14263 |
+ } else { |
14264 |
+- if (overflow > 0) |
14265 |
++ if (overflow > 0) { |
14266 |
+ dev_warn(ir->dev, "receive overflow, at least %u lost", |
14267 |
+ overflow); |
14268 |
++ ir_raw_event_reset(ir->rc); |
14269 |
++ } |
14270 |
+ |
14271 |
+ do { |
14272 |
+ rawir.duration = ir->buf_in[i] * 85; |
14273 |
+diff --git a/drivers/media/rc/mceusb.c b/drivers/media/rc/mceusb.c |
14274 |
+index 137a71954aabf..5f296f985b07a 100644 |
14275 |
+--- a/drivers/media/rc/mceusb.c |
14276 |
++++ b/drivers/media/rc/mceusb.c |
14277 |
+@@ -1430,7 +1430,7 @@ static void mceusb_gen1_init(struct mceusb_dev *ir) |
14278 |
+ */ |
14279 |
+ ret = usb_control_msg(ir->usbdev, usb_rcvctrlpipe(ir->usbdev, 0), |
14280 |
+ USB_REQ_SET_ADDRESS, USB_TYPE_VENDOR, 0, 0, |
14281 |
+- data, USB_CTRL_MSG_SZ, HZ * 3); |
14282 |
++ data, USB_CTRL_MSG_SZ, 3000); |
14283 |
+ dev_dbg(dev, "set address - ret = %d", ret); |
14284 |
+ dev_dbg(dev, "set address - data[0] = %d, data[1] = %d", |
14285 |
+ data[0], data[1]); |
14286 |
+@@ -1438,20 +1438,20 @@ static void mceusb_gen1_init(struct mceusb_dev *ir) |
14287 |
+ /* set feature: bit rate 38400 bps */ |
14288 |
+ ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), |
14289 |
+ USB_REQ_SET_FEATURE, USB_TYPE_VENDOR, |
14290 |
+- 0xc04e, 0x0000, NULL, 0, HZ * 3); |
14291 |
++ 0xc04e, 0x0000, NULL, 0, 3000); |
14292 |
+ |
14293 |
+ dev_dbg(dev, "set feature - ret = %d", ret); |
14294 |
+ |
14295 |
+ /* bRequest 4: set char length to 8 bits */ |
14296 |
+ ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), |
14297 |
+ 4, USB_TYPE_VENDOR, |
14298 |
+- 0x0808, 0x0000, NULL, 0, HZ * 3); |
14299 |
++ 0x0808, 0x0000, NULL, 0, 3000); |
14300 |
+ dev_dbg(dev, "set char length - retB = %d", ret); |
14301 |
+ |
14302 |
+ /* bRequest 2: set handshaking to use DTR/DSR */ |
14303 |
+ ret = usb_control_msg(ir->usbdev, usb_sndctrlpipe(ir->usbdev, 0), |
14304 |
+ 2, USB_TYPE_VENDOR, |
14305 |
+- 0x0000, 0x0100, NULL, 0, HZ * 3); |
14306 |
++ 0x0000, 0x0100, NULL, 0, 3000); |
14307 |
+ dev_dbg(dev, "set handshake - retC = %d", ret); |
14308 |
+ |
14309 |
+ /* device resume */ |
14310 |
+diff --git a/drivers/media/rc/redrat3.c b/drivers/media/rc/redrat3.c |
14311 |
+index ac85464864b9d..cb22316b3f002 100644 |
14312 |
+--- a/drivers/media/rc/redrat3.c |
14313 |
++++ b/drivers/media/rc/redrat3.c |
14314 |
+@@ -404,7 +404,7 @@ static int redrat3_send_cmd(int cmd, struct redrat3_dev *rr3) |
14315 |
+ udev = rr3->udev; |
14316 |
+ res = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0), cmd, |
14317 |
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, |
14318 |
+- 0x0000, 0x0000, data, sizeof(u8), HZ * 10); |
14319 |
++ 0x0000, 0x0000, data, sizeof(u8), 10000); |
14320 |
+ |
14321 |
+ if (res < 0) { |
14322 |
+ dev_err(rr3->dev, "%s: Error sending rr3 cmd res %d, data %d", |
14323 |
+@@ -480,7 +480,7 @@ static u32 redrat3_get_timeout(struct redrat3_dev *rr3) |
14324 |
+ pipe = usb_rcvctrlpipe(rr3->udev, 0); |
14325 |
+ ret = usb_control_msg(rr3->udev, pipe, RR3_GET_IR_PARAM, |
14326 |
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, |
14327 |
+- RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, HZ * 5); |
14328 |
++ RR3_IR_IO_SIG_TIMEOUT, 0, tmp, len, 5000); |
14329 |
+ if (ret != len) |
14330 |
+ dev_warn(rr3->dev, "Failed to read timeout from hardware\n"); |
14331 |
+ else { |
14332 |
+@@ -510,7 +510,7 @@ static int redrat3_set_timeout(struct rc_dev *rc_dev, unsigned int timeoutus) |
14333 |
+ ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0), RR3_SET_IR_PARAM, |
14334 |
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, |
14335 |
+ RR3_IR_IO_SIG_TIMEOUT, 0, timeout, sizeof(*timeout), |
14336 |
+- HZ * 25); |
14337 |
++ 25000); |
14338 |
+ dev_dbg(dev, "set ir parm timeout %d ret 0x%02x\n", |
14339 |
+ be32_to_cpu(*timeout), ret); |
14340 |
+ |
14341 |
+@@ -542,32 +542,32 @@ static void redrat3_reset(struct redrat3_dev *rr3) |
14342 |
+ *val = 0x01; |
14343 |
+ rc = usb_control_msg(udev, rxpipe, RR3_RESET, |
14344 |
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, |
14345 |
+- RR3_CPUCS_REG_ADDR, 0, val, len, HZ * 25); |
14346 |
++ RR3_CPUCS_REG_ADDR, 0, val, len, 25000); |
14347 |
+ dev_dbg(dev, "reset returned 0x%02x\n", rc); |
14348 |
+ |
14349 |
+ *val = length_fuzz; |
14350 |
+ rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM, |
14351 |
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, |
14352 |
+- RR3_IR_IO_LENGTH_FUZZ, 0, val, len, HZ * 25); |
14353 |
++ RR3_IR_IO_LENGTH_FUZZ, 0, val, len, 25000); |
14354 |
+ dev_dbg(dev, "set ir parm len fuzz %d rc 0x%02x\n", *val, rc); |
14355 |
+ |
14356 |
+ *val = (65536 - (minimum_pause * 2000)) / 256; |
14357 |
+ rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM, |
14358 |
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, |
14359 |
+- RR3_IR_IO_MIN_PAUSE, 0, val, len, HZ * 25); |
14360 |
++ RR3_IR_IO_MIN_PAUSE, 0, val, len, 25000); |
14361 |
+ dev_dbg(dev, "set ir parm min pause %d rc 0x%02x\n", *val, rc); |
14362 |
+ |
14363 |
+ *val = periods_measure_carrier; |
14364 |
+ rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM, |
14365 |
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, |
14366 |
+- RR3_IR_IO_PERIODS_MF, 0, val, len, HZ * 25); |
14367 |
++ RR3_IR_IO_PERIODS_MF, 0, val, len, 25000); |
14368 |
+ dev_dbg(dev, "set ir parm periods measure carrier %d rc 0x%02x", *val, |
14369 |
+ rc); |
14370 |
+ |
14371 |
+ *val = RR3_DRIVER_MAXLENS; |
14372 |
+ rc = usb_control_msg(udev, txpipe, RR3_SET_IR_PARAM, |
14373 |
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT, |
14374 |
+- RR3_IR_IO_MAX_LENGTHS, 0, val, len, HZ * 25); |
14375 |
++ RR3_IR_IO_MAX_LENGTHS, 0, val, len, 25000); |
14376 |
+ dev_dbg(dev, "set ir parm max lens %d rc 0x%02x\n", *val, rc); |
14377 |
+ |
14378 |
+ kfree(val); |
14379 |
+@@ -585,7 +585,7 @@ static void redrat3_get_firmware_rev(struct redrat3_dev *rr3) |
14380 |
+ rc = usb_control_msg(rr3->udev, usb_rcvctrlpipe(rr3->udev, 0), |
14381 |
+ RR3_FW_VERSION, |
14382 |
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, |
14383 |
+- 0, 0, buffer, RR3_FW_VERSION_LEN, HZ * 5); |
14384 |
++ 0, 0, buffer, RR3_FW_VERSION_LEN, 5000); |
14385 |
+ |
14386 |
+ if (rc >= 0) |
14387 |
+ dev_info(rr3->dev, "Firmware rev: %s", buffer); |
14388 |
+@@ -825,14 +825,14 @@ static int redrat3_transmit_ir(struct rc_dev *rcdev, unsigned *txbuf, |
14389 |
+ |
14390 |
+ pipe = usb_sndbulkpipe(rr3->udev, rr3->ep_out->bEndpointAddress); |
14391 |
+ ret = usb_bulk_msg(rr3->udev, pipe, irdata, |
14392 |
+- sendbuf_len, &ret_len, 10 * HZ); |
14393 |
++ sendbuf_len, &ret_len, 10000); |
14394 |
+ dev_dbg(dev, "sent %d bytes, (ret %d)\n", ret_len, ret); |
14395 |
+ |
14396 |
+ /* now tell the hardware to transmit what we sent it */ |
14397 |
+ pipe = usb_rcvctrlpipe(rr3->udev, 0); |
14398 |
+ ret = usb_control_msg(rr3->udev, pipe, RR3_TX_SEND_SIGNAL, |
14399 |
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_IN, |
14400 |
+- 0, 0, irdata, 2, HZ * 10); |
14401 |
++ 0, 0, irdata, 2, 10000); |
14402 |
+ |
14403 |
+ if (ret < 0) |
14404 |
+ dev_err(dev, "Error: control msg send failed, rc %d\n", ret); |
14405 |
+diff --git a/drivers/media/tuners/msi001.c b/drivers/media/tuners/msi001.c |
14406 |
+index 78e6fd600d8ef..44247049a3190 100644 |
14407 |
+--- a/drivers/media/tuners/msi001.c |
14408 |
++++ b/drivers/media/tuners/msi001.c |
14409 |
+@@ -442,6 +442,13 @@ static int msi001_probe(struct spi_device *spi) |
14410 |
+ V4L2_CID_RF_TUNER_BANDWIDTH_AUTO, 0, 1, 1, 1); |
14411 |
+ dev->bandwidth = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops, |
14412 |
+ V4L2_CID_RF_TUNER_BANDWIDTH, 200000, 8000000, 1, 200000); |
14413 |
++ if (dev->hdl.error) { |
14414 |
++ ret = dev->hdl.error; |
14415 |
++ dev_err(&spi->dev, "Could not initialize controls\n"); |
14416 |
++ /* control init failed, free handler */ |
14417 |
++ goto err_ctrl_handler_free; |
14418 |
++ } |
14419 |
++ |
14420 |
+ v4l2_ctrl_auto_cluster(2, &dev->bandwidth_auto, 0, false); |
14421 |
+ dev->lna_gain = v4l2_ctrl_new_std(&dev->hdl, &msi001_ctrl_ops, |
14422 |
+ V4L2_CID_RF_TUNER_LNA_GAIN, 0, 1, 1, 1); |
14423 |
+diff --git a/drivers/media/tuners/si2157.c b/drivers/media/tuners/si2157.c |
14424 |
+index fefb2625f6558..75ddf7ed1faff 100644 |
14425 |
+--- a/drivers/media/tuners/si2157.c |
14426 |
++++ b/drivers/media/tuners/si2157.c |
14427 |
+@@ -90,7 +90,7 @@ static int si2157_init(struct dvb_frontend *fe) |
14428 |
+ dev_dbg(&client->dev, "\n"); |
14429 |
+ |
14430 |
+ /* Try to get Xtal trim property, to verify tuner still running */ |
14431 |
+- memcpy(cmd.args, "\x15\x00\x04\x02", 4); |
14432 |
++ memcpy(cmd.args, "\x15\x00\x02\x04", 4); |
14433 |
+ cmd.wlen = 4; |
14434 |
+ cmd.rlen = 4; |
14435 |
+ ret = si2157_cmd_execute(client, &cmd); |
14436 |
+diff --git a/drivers/media/usb/b2c2/flexcop-usb.c b/drivers/media/usb/b2c2/flexcop-usb.c |
14437 |
+index 5d38171b7638c..bfeb92d93de39 100644 |
14438 |
+--- a/drivers/media/usb/b2c2/flexcop-usb.c |
14439 |
++++ b/drivers/media/usb/b2c2/flexcop-usb.c |
14440 |
+@@ -87,7 +87,7 @@ static int flexcop_usb_readwrite_dw(struct flexcop_device *fc, u16 wRegOffsPCI, |
14441 |
+ 0, |
14442 |
+ fc_usb->data, |
14443 |
+ sizeof(u32), |
14444 |
+- B2C2_WAIT_FOR_OPERATION_RDW * HZ); |
14445 |
++ B2C2_WAIT_FOR_OPERATION_RDW); |
14446 |
+ |
14447 |
+ if (ret != sizeof(u32)) { |
14448 |
+ err("error while %s dword from %d (%d).", read ? "reading" : |
14449 |
+@@ -155,7 +155,7 @@ static int flexcop_usb_v8_memory_req(struct flexcop_usb *fc_usb, |
14450 |
+ wIndex, |
14451 |
+ fc_usb->data, |
14452 |
+ buflen, |
14453 |
+- nWaitTime * HZ); |
14454 |
++ nWaitTime); |
14455 |
+ if (ret != buflen) |
14456 |
+ ret = -EIO; |
14457 |
+ |
14458 |
+@@ -248,13 +248,13 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c, |
14459 |
+ /* DKT 020208 - add this to support special case of DiSEqC */ |
14460 |
+ case USB_FUNC_I2C_CHECKWRITE: |
14461 |
+ pipe = B2C2_USB_CTRL_PIPE_OUT; |
14462 |
+- nWaitTime = 2; |
14463 |
++ nWaitTime = 2000; |
14464 |
+ request_type |= USB_DIR_OUT; |
14465 |
+ break; |
14466 |
+ case USB_FUNC_I2C_READ: |
14467 |
+ case USB_FUNC_I2C_REPEATREAD: |
14468 |
+ pipe = B2C2_USB_CTRL_PIPE_IN; |
14469 |
+- nWaitTime = 2; |
14470 |
++ nWaitTime = 2000; |
14471 |
+ request_type |= USB_DIR_IN; |
14472 |
+ break; |
14473 |
+ default: |
14474 |
+@@ -281,7 +281,7 @@ static int flexcop_usb_i2c_req(struct flexcop_i2c_adapter *i2c, |
14475 |
+ wIndex, |
14476 |
+ fc_usb->data, |
14477 |
+ buflen, |
14478 |
+- nWaitTime * HZ); |
14479 |
++ nWaitTime); |
14480 |
+ |
14481 |
+ if (ret != buflen) |
14482 |
+ ret = -EIO; |
14483 |
+diff --git a/drivers/media/usb/b2c2/flexcop-usb.h b/drivers/media/usb/b2c2/flexcop-usb.h |
14484 |
+index 2f230bf72252b..c7cca1a5ee59d 100644 |
14485 |
+--- a/drivers/media/usb/b2c2/flexcop-usb.h |
14486 |
++++ b/drivers/media/usb/b2c2/flexcop-usb.h |
14487 |
+@@ -91,13 +91,13 @@ typedef enum { |
14488 |
+ UTILITY_SRAM_TESTVERIFY = 0x16, |
14489 |
+ } flexcop_usb_utility_function_t; |
14490 |
+ |
14491 |
+-#define B2C2_WAIT_FOR_OPERATION_RW (1*HZ) |
14492 |
+-#define B2C2_WAIT_FOR_OPERATION_RDW (3*HZ) |
14493 |
+-#define B2C2_WAIT_FOR_OPERATION_WDW (1*HZ) |
14494 |
++#define B2C2_WAIT_FOR_OPERATION_RW 1000 |
14495 |
++#define B2C2_WAIT_FOR_OPERATION_RDW 3000 |
14496 |
++#define B2C2_WAIT_FOR_OPERATION_WDW 1000 |
14497 |
+ |
14498 |
+-#define B2C2_WAIT_FOR_OPERATION_V8READ (3*HZ) |
14499 |
+-#define B2C2_WAIT_FOR_OPERATION_V8WRITE (3*HZ) |
14500 |
+-#define B2C2_WAIT_FOR_OPERATION_V8FLASH (3*HZ) |
14501 |
++#define B2C2_WAIT_FOR_OPERATION_V8READ 3000 |
14502 |
++#define B2C2_WAIT_FOR_OPERATION_V8WRITE 3000 |
14503 |
++#define B2C2_WAIT_FOR_OPERATION_V8FLASH 3000 |
14504 |
+ |
14505 |
+ typedef enum { |
14506 |
+ V8_MEMORY_PAGE_DVB_CI = 0x20, |
14507 |
+diff --git a/drivers/media/usb/cpia2/cpia2_usb.c b/drivers/media/usb/cpia2/cpia2_usb.c |
14508 |
+index 76aac06f9fb8e..cba03b2864738 100644 |
14509 |
+--- a/drivers/media/usb/cpia2/cpia2_usb.c |
14510 |
++++ b/drivers/media/usb/cpia2/cpia2_usb.c |
14511 |
+@@ -550,7 +550,7 @@ static int write_packet(struct usb_device *udev, |
14512 |
+ 0, /* index */ |
14513 |
+ buf, /* buffer */ |
14514 |
+ size, |
14515 |
+- HZ); |
14516 |
++ 1000); |
14517 |
+ |
14518 |
+ kfree(buf); |
14519 |
+ return ret; |
14520 |
+@@ -582,7 +582,7 @@ static int read_packet(struct usb_device *udev, |
14521 |
+ 0, /* index */ |
14522 |
+ buf, /* buffer */ |
14523 |
+ size, |
14524 |
+- HZ); |
14525 |
++ 1000); |
14526 |
+ |
14527 |
+ if (ret >= 0) |
14528 |
+ memcpy(registers, buf, size); |
14529 |
+diff --git a/drivers/media/usb/dvb-usb/dib0700_core.c b/drivers/media/usb/dvb-usb/dib0700_core.c |
14530 |
+index 70219b3e85666..7ea8f68b0f458 100644 |
14531 |
+--- a/drivers/media/usb/dvb-usb/dib0700_core.c |
14532 |
++++ b/drivers/media/usb/dvb-usb/dib0700_core.c |
14533 |
+@@ -618,8 +618,6 @@ int dib0700_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) |
14534 |
+ deb_info("the endpoint number (%i) is not correct, use the adapter id instead", adap->fe_adap[0].stream.props.endpoint); |
14535 |
+ if (onoff) |
14536 |
+ st->channel_state |= 1 << (adap->id); |
14537 |
+- else |
14538 |
+- st->channel_state |= 1 << ~(adap->id); |
14539 |
+ } else { |
14540 |
+ if (onoff) |
14541 |
+ st->channel_state |= 1 << (adap->fe_adap[0].stream.props.endpoint-2); |
14542 |
+diff --git a/drivers/media/usb/dvb-usb/dw2102.c b/drivers/media/usb/dvb-usb/dw2102.c |
14543 |
+index f0e686b05dc63..ca75ebdc10b37 100644 |
14544 |
+--- a/drivers/media/usb/dvb-usb/dw2102.c |
14545 |
++++ b/drivers/media/usb/dvb-usb/dw2102.c |
14546 |
+@@ -2150,46 +2150,153 @@ static struct dvb_usb_device_properties s6x0_properties = { |
14547 |
+ } |
14548 |
+ }; |
14549 |
+ |
14550 |
+-static const struct dvb_usb_device_description d1100 = { |
14551 |
+- "Prof 1100 USB ", |
14552 |
+- {&dw2102_table[PROF_1100], NULL}, |
14553 |
+- {NULL}, |
14554 |
+-}; |
14555 |
++static struct dvb_usb_device_properties p1100_properties = { |
14556 |
++ .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
14557 |
++ .usb_ctrl = DEVICE_SPECIFIC, |
14558 |
++ .size_of_priv = sizeof(struct dw2102_state), |
14559 |
++ .firmware = P1100_FIRMWARE, |
14560 |
++ .no_reconnect = 1, |
14561 |
+ |
14562 |
+-static const struct dvb_usb_device_description d660 = { |
14563 |
+- "TeVii S660 USB", |
14564 |
+- {&dw2102_table[TEVII_S660], NULL}, |
14565 |
+- {NULL}, |
14566 |
+-}; |
14567 |
++ .i2c_algo = &s6x0_i2c_algo, |
14568 |
++ .rc.core = { |
14569 |
++ .rc_interval = 150, |
14570 |
++ .rc_codes = RC_MAP_TBS_NEC, |
14571 |
++ .module_name = "dw2102", |
14572 |
++ .allowed_protos = RC_PROTO_BIT_NEC, |
14573 |
++ .rc_query = prof_rc_query, |
14574 |
++ }, |
14575 |
+ |
14576 |
+-static const struct dvb_usb_device_description d480_1 = { |
14577 |
+- "TeVii S480.1 USB", |
14578 |
+- {&dw2102_table[TEVII_S480_1], NULL}, |
14579 |
+- {NULL}, |
14580 |
++ .generic_bulk_ctrl_endpoint = 0x81, |
14581 |
++ .num_adapters = 1, |
14582 |
++ .download_firmware = dw2102_load_firmware, |
14583 |
++ .read_mac_address = s6x0_read_mac_address, |
14584 |
++ .adapter = { |
14585 |
++ { |
14586 |
++ .num_frontends = 1, |
14587 |
++ .fe = {{ |
14588 |
++ .frontend_attach = stv0288_frontend_attach, |
14589 |
++ .stream = { |
14590 |
++ .type = USB_BULK, |
14591 |
++ .count = 8, |
14592 |
++ .endpoint = 0x82, |
14593 |
++ .u = { |
14594 |
++ .bulk = { |
14595 |
++ .buffersize = 4096, |
14596 |
++ } |
14597 |
++ } |
14598 |
++ }, |
14599 |
++ } }, |
14600 |
++ } |
14601 |
++ }, |
14602 |
++ .num_device_descs = 1, |
14603 |
++ .devices = { |
14604 |
++ {"Prof 1100 USB ", |
14605 |
++ {&dw2102_table[PROF_1100], NULL}, |
14606 |
++ {NULL}, |
14607 |
++ }, |
14608 |
++ } |
14609 |
+ }; |
14610 |
+ |
14611 |
+-static const struct dvb_usb_device_description d480_2 = { |
14612 |
+- "TeVii S480.2 USB", |
14613 |
+- {&dw2102_table[TEVII_S480_2], NULL}, |
14614 |
+- {NULL}, |
14615 |
+-}; |
14616 |
++static struct dvb_usb_device_properties s660_properties = { |
14617 |
++ .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
14618 |
++ .usb_ctrl = DEVICE_SPECIFIC, |
14619 |
++ .size_of_priv = sizeof(struct dw2102_state), |
14620 |
++ .firmware = S660_FIRMWARE, |
14621 |
++ .no_reconnect = 1, |
14622 |
+ |
14623 |
+-static const struct dvb_usb_device_description d7500 = { |
14624 |
+- "Prof 7500 USB DVB-S2", |
14625 |
+- {&dw2102_table[PROF_7500], NULL}, |
14626 |
+- {NULL}, |
14627 |
+-}; |
14628 |
++ .i2c_algo = &s6x0_i2c_algo, |
14629 |
++ .rc.core = { |
14630 |
++ .rc_interval = 150, |
14631 |
++ .rc_codes = RC_MAP_TEVII_NEC, |
14632 |
++ .module_name = "dw2102", |
14633 |
++ .allowed_protos = RC_PROTO_BIT_NEC, |
14634 |
++ .rc_query = dw2102_rc_query, |
14635 |
++ }, |
14636 |
+ |
14637 |
+-static const struct dvb_usb_device_description d421 = { |
14638 |
+- "TeVii S421 PCI", |
14639 |
+- {&dw2102_table[TEVII_S421], NULL}, |
14640 |
+- {NULL}, |
14641 |
++ .generic_bulk_ctrl_endpoint = 0x81, |
14642 |
++ .num_adapters = 1, |
14643 |
++ .download_firmware = dw2102_load_firmware, |
14644 |
++ .read_mac_address = s6x0_read_mac_address, |
14645 |
++ .adapter = { |
14646 |
++ { |
14647 |
++ .num_frontends = 1, |
14648 |
++ .fe = {{ |
14649 |
++ .frontend_attach = ds3000_frontend_attach, |
14650 |
++ .stream = { |
14651 |
++ .type = USB_BULK, |
14652 |
++ .count = 8, |
14653 |
++ .endpoint = 0x82, |
14654 |
++ .u = { |
14655 |
++ .bulk = { |
14656 |
++ .buffersize = 4096, |
14657 |
++ } |
14658 |
++ } |
14659 |
++ }, |
14660 |
++ } }, |
14661 |
++ } |
14662 |
++ }, |
14663 |
++ .num_device_descs = 3, |
14664 |
++ .devices = { |
14665 |
++ {"TeVii S660 USB", |
14666 |
++ {&dw2102_table[TEVII_S660], NULL}, |
14667 |
++ {NULL}, |
14668 |
++ }, |
14669 |
++ {"TeVii S480.1 USB", |
14670 |
++ {&dw2102_table[TEVII_S480_1], NULL}, |
14671 |
++ {NULL}, |
14672 |
++ }, |
14673 |
++ {"TeVii S480.2 USB", |
14674 |
++ {&dw2102_table[TEVII_S480_2], NULL}, |
14675 |
++ {NULL}, |
14676 |
++ }, |
14677 |
++ } |
14678 |
+ }; |
14679 |
+ |
14680 |
+-static const struct dvb_usb_device_description d632 = { |
14681 |
+- "TeVii S632 USB", |
14682 |
+- {&dw2102_table[TEVII_S632], NULL}, |
14683 |
+- {NULL}, |
14684 |
++static struct dvb_usb_device_properties p7500_properties = { |
14685 |
++ .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
14686 |
++ .usb_ctrl = DEVICE_SPECIFIC, |
14687 |
++ .size_of_priv = sizeof(struct dw2102_state), |
14688 |
++ .firmware = P7500_FIRMWARE, |
14689 |
++ .no_reconnect = 1, |
14690 |
++ |
14691 |
++ .i2c_algo = &s6x0_i2c_algo, |
14692 |
++ .rc.core = { |
14693 |
++ .rc_interval = 150, |
14694 |
++ .rc_codes = RC_MAP_TBS_NEC, |
14695 |
++ .module_name = "dw2102", |
14696 |
++ .allowed_protos = RC_PROTO_BIT_NEC, |
14697 |
++ .rc_query = prof_rc_query, |
14698 |
++ }, |
14699 |
++ |
14700 |
++ .generic_bulk_ctrl_endpoint = 0x81, |
14701 |
++ .num_adapters = 1, |
14702 |
++ .download_firmware = dw2102_load_firmware, |
14703 |
++ .read_mac_address = s6x0_read_mac_address, |
14704 |
++ .adapter = { |
14705 |
++ { |
14706 |
++ .num_frontends = 1, |
14707 |
++ .fe = {{ |
14708 |
++ .frontend_attach = prof_7500_frontend_attach, |
14709 |
++ .stream = { |
14710 |
++ .type = USB_BULK, |
14711 |
++ .count = 8, |
14712 |
++ .endpoint = 0x82, |
14713 |
++ .u = { |
14714 |
++ .bulk = { |
14715 |
++ .buffersize = 4096, |
14716 |
++ } |
14717 |
++ } |
14718 |
++ }, |
14719 |
++ } }, |
14720 |
++ } |
14721 |
++ }, |
14722 |
++ .num_device_descs = 1, |
14723 |
++ .devices = { |
14724 |
++ {"Prof 7500 USB DVB-S2", |
14725 |
++ {&dw2102_table[PROF_7500], NULL}, |
14726 |
++ {NULL}, |
14727 |
++ }, |
14728 |
++ } |
14729 |
+ }; |
14730 |
+ |
14731 |
+ static struct dvb_usb_device_properties su3000_properties = { |
14732 |
+@@ -2273,6 +2380,59 @@ static struct dvb_usb_device_properties su3000_properties = { |
14733 |
+ } |
14734 |
+ }; |
14735 |
+ |
14736 |
++static struct dvb_usb_device_properties s421_properties = { |
14737 |
++ .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
14738 |
++ .usb_ctrl = DEVICE_SPECIFIC, |
14739 |
++ .size_of_priv = sizeof(struct dw2102_state), |
14740 |
++ .power_ctrl = su3000_power_ctrl, |
14741 |
++ .num_adapters = 1, |
14742 |
++ .identify_state = su3000_identify_state, |
14743 |
++ .i2c_algo = &su3000_i2c_algo, |
14744 |
++ |
14745 |
++ .rc.core = { |
14746 |
++ .rc_interval = 150, |
14747 |
++ .rc_codes = RC_MAP_SU3000, |
14748 |
++ .module_name = "dw2102", |
14749 |
++ .allowed_protos = RC_PROTO_BIT_RC5, |
14750 |
++ .rc_query = su3000_rc_query, |
14751 |
++ }, |
14752 |
++ |
14753 |
++ .read_mac_address = su3000_read_mac_address, |
14754 |
++ |
14755 |
++ .generic_bulk_ctrl_endpoint = 0x01, |
14756 |
++ |
14757 |
++ .adapter = { |
14758 |
++ { |
14759 |
++ .num_frontends = 1, |
14760 |
++ .fe = {{ |
14761 |
++ .streaming_ctrl = su3000_streaming_ctrl, |
14762 |
++ .frontend_attach = m88rs2000_frontend_attach, |
14763 |
++ .stream = { |
14764 |
++ .type = USB_BULK, |
14765 |
++ .count = 8, |
14766 |
++ .endpoint = 0x82, |
14767 |
++ .u = { |
14768 |
++ .bulk = { |
14769 |
++ .buffersize = 4096, |
14770 |
++ } |
14771 |
++ } |
14772 |
++ } |
14773 |
++ } }, |
14774 |
++ } |
14775 |
++ }, |
14776 |
++ .num_device_descs = 2, |
14777 |
++ .devices = { |
14778 |
++ { "TeVii S421 PCI", |
14779 |
++ { &dw2102_table[TEVII_S421], NULL }, |
14780 |
++ { NULL }, |
14781 |
++ }, |
14782 |
++ { "TeVii S632 USB", |
14783 |
++ { &dw2102_table[TEVII_S632], NULL }, |
14784 |
++ { NULL }, |
14785 |
++ }, |
14786 |
++ } |
14787 |
++}; |
14788 |
++ |
14789 |
+ static struct dvb_usb_device_properties t220_properties = { |
14790 |
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER, |
14791 |
+ .usb_ctrl = DEVICE_SPECIFIC, |
14792 |
+@@ -2390,101 +2550,33 @@ static struct dvb_usb_device_properties tt_s2_4600_properties = { |
14793 |
+ static int dw2102_probe(struct usb_interface *intf, |
14794 |
+ const struct usb_device_id *id) |
14795 |
+ { |
14796 |
+- int retval = -ENOMEM; |
14797 |
+- struct dvb_usb_device_properties *p1100; |
14798 |
+- struct dvb_usb_device_properties *s660; |
14799 |
+- struct dvb_usb_device_properties *p7500; |
14800 |
+- struct dvb_usb_device_properties *s421; |
14801 |
+- |
14802 |
+- p1100 = kmemdup(&s6x0_properties, |
14803 |
+- sizeof(struct dvb_usb_device_properties), GFP_KERNEL); |
14804 |
+- if (!p1100) |
14805 |
+- goto err0; |
14806 |
+- |
14807 |
+- /* copy default structure */ |
14808 |
+- /* fill only different fields */ |
14809 |
+- p1100->firmware = P1100_FIRMWARE; |
14810 |
+- p1100->devices[0] = d1100; |
14811 |
+- p1100->rc.core.rc_query = prof_rc_query; |
14812 |
+- p1100->rc.core.rc_codes = RC_MAP_TBS_NEC; |
14813 |
+- p1100->adapter->fe[0].frontend_attach = stv0288_frontend_attach; |
14814 |
+- |
14815 |
+- s660 = kmemdup(&s6x0_properties, |
14816 |
+- sizeof(struct dvb_usb_device_properties), GFP_KERNEL); |
14817 |
+- if (!s660) |
14818 |
+- goto err1; |
14819 |
+- |
14820 |
+- s660->firmware = S660_FIRMWARE; |
14821 |
+- s660->num_device_descs = 3; |
14822 |
+- s660->devices[0] = d660; |
14823 |
+- s660->devices[1] = d480_1; |
14824 |
+- s660->devices[2] = d480_2; |
14825 |
+- s660->adapter->fe[0].frontend_attach = ds3000_frontend_attach; |
14826 |
+- |
14827 |
+- p7500 = kmemdup(&s6x0_properties, |
14828 |
+- sizeof(struct dvb_usb_device_properties), GFP_KERNEL); |
14829 |
+- if (!p7500) |
14830 |
+- goto err2; |
14831 |
+- |
14832 |
+- p7500->firmware = P7500_FIRMWARE; |
14833 |
+- p7500->devices[0] = d7500; |
14834 |
+- p7500->rc.core.rc_query = prof_rc_query; |
14835 |
+- p7500->rc.core.rc_codes = RC_MAP_TBS_NEC; |
14836 |
+- p7500->adapter->fe[0].frontend_attach = prof_7500_frontend_attach; |
14837 |
+- |
14838 |
+- |
14839 |
+- s421 = kmemdup(&su3000_properties, |
14840 |
+- sizeof(struct dvb_usb_device_properties), GFP_KERNEL); |
14841 |
+- if (!s421) |
14842 |
+- goto err3; |
14843 |
+- |
14844 |
+- s421->num_device_descs = 2; |
14845 |
+- s421->devices[0] = d421; |
14846 |
+- s421->devices[1] = d632; |
14847 |
+- s421->adapter->fe[0].frontend_attach = m88rs2000_frontend_attach; |
14848 |
+- |
14849 |
+- if (0 == dvb_usb_device_init(intf, &dw2102_properties, |
14850 |
+- THIS_MODULE, NULL, adapter_nr) || |
14851 |
+- 0 == dvb_usb_device_init(intf, &dw2104_properties, |
14852 |
+- THIS_MODULE, NULL, adapter_nr) || |
14853 |
+- 0 == dvb_usb_device_init(intf, &dw3101_properties, |
14854 |
+- THIS_MODULE, NULL, adapter_nr) || |
14855 |
+- 0 == dvb_usb_device_init(intf, &s6x0_properties, |
14856 |
+- THIS_MODULE, NULL, adapter_nr) || |
14857 |
+- 0 == dvb_usb_device_init(intf, p1100, |
14858 |
+- THIS_MODULE, NULL, adapter_nr) || |
14859 |
+- 0 == dvb_usb_device_init(intf, s660, |
14860 |
+- THIS_MODULE, NULL, adapter_nr) || |
14861 |
+- 0 == dvb_usb_device_init(intf, p7500, |
14862 |
+- THIS_MODULE, NULL, adapter_nr) || |
14863 |
+- 0 == dvb_usb_device_init(intf, s421, |
14864 |
+- THIS_MODULE, NULL, adapter_nr) || |
14865 |
+- 0 == dvb_usb_device_init(intf, &su3000_properties, |
14866 |
+- THIS_MODULE, NULL, adapter_nr) || |
14867 |
+- 0 == dvb_usb_device_init(intf, &t220_properties, |
14868 |
+- THIS_MODULE, NULL, adapter_nr) || |
14869 |
+- 0 == dvb_usb_device_init(intf, &tt_s2_4600_properties, |
14870 |
+- THIS_MODULE, NULL, adapter_nr)) { |
14871 |
+- |
14872 |
+- /* clean up copied properties */ |
14873 |
+- kfree(s421); |
14874 |
+- kfree(p7500); |
14875 |
+- kfree(s660); |
14876 |
+- kfree(p1100); |
14877 |
++ if (!(dvb_usb_device_init(intf, &dw2102_properties, |
14878 |
++ THIS_MODULE, NULL, adapter_nr) && |
14879 |
++ dvb_usb_device_init(intf, &dw2104_properties, |
14880 |
++ THIS_MODULE, NULL, adapter_nr) && |
14881 |
++ dvb_usb_device_init(intf, &dw3101_properties, |
14882 |
++ THIS_MODULE, NULL, adapter_nr) && |
14883 |
++ dvb_usb_device_init(intf, &s6x0_properties, |
14884 |
++ THIS_MODULE, NULL, adapter_nr) && |
14885 |
++ dvb_usb_device_init(intf, &p1100_properties, |
14886 |
++ THIS_MODULE, NULL, adapter_nr) && |
14887 |
++ dvb_usb_device_init(intf, &s660_properties, |
14888 |
++ THIS_MODULE, NULL, adapter_nr) && |
14889 |
++ dvb_usb_device_init(intf, &p7500_properties, |
14890 |
++ THIS_MODULE, NULL, adapter_nr) && |
14891 |
++ dvb_usb_device_init(intf, &s421_properties, |
14892 |
++ THIS_MODULE, NULL, adapter_nr) && |
14893 |
++ dvb_usb_device_init(intf, &su3000_properties, |
14894 |
++ THIS_MODULE, NULL, adapter_nr) && |
14895 |
++ dvb_usb_device_init(intf, &t220_properties, |
14896 |
++ THIS_MODULE, NULL, adapter_nr) && |
14897 |
++ dvb_usb_device_init(intf, &tt_s2_4600_properties, |
14898 |
++ THIS_MODULE, NULL, adapter_nr))) { |
14899 |
+ |
14900 |
+ return 0; |
14901 |
+ } |
14902 |
+ |
14903 |
+- retval = -ENODEV; |
14904 |
+- kfree(s421); |
14905 |
+-err3: |
14906 |
+- kfree(p7500); |
14907 |
+-err2: |
14908 |
+- kfree(s660); |
14909 |
+-err1: |
14910 |
+- kfree(p1100); |
14911 |
+-err0: |
14912 |
+- return retval; |
14913 |
++ return -ENODEV; |
14914 |
+ } |
14915 |
+ |
14916 |
+ static void dw2102_disconnect(struct usb_interface *intf) |
14917 |
+diff --git a/drivers/media/usb/dvb-usb/m920x.c b/drivers/media/usb/dvb-usb/m920x.c |
14918 |
+index 4bb5b82599a79..691e05833db19 100644 |
14919 |
+--- a/drivers/media/usb/dvb-usb/m920x.c |
14920 |
++++ b/drivers/media/usb/dvb-usb/m920x.c |
14921 |
+@@ -274,6 +274,13 @@ static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu |
14922 |
+ /* Should check for ack here, if we knew how. */ |
14923 |
+ } |
14924 |
+ if (msg[i].flags & I2C_M_RD) { |
14925 |
++ char *read = kmalloc(1, GFP_KERNEL); |
14926 |
++ if (!read) { |
14927 |
++ ret = -ENOMEM; |
14928 |
++ kfree(read); |
14929 |
++ goto unlock; |
14930 |
++ } |
14931 |
++ |
14932 |
+ for (j = 0; j < msg[i].len; j++) { |
14933 |
+ /* Last byte of transaction? |
14934 |
+ * Send STOP, otherwise send ACK. */ |
14935 |
+@@ -281,9 +288,12 @@ static int m920x_i2c_xfer(struct i2c_adapter *adap, struct i2c_msg msg[], int nu |
14936 |
+ |
14937 |
+ if ((ret = m920x_read(d->udev, M9206_I2C, 0x0, |
14938 |
+ 0x20 | stop, |
14939 |
+- &msg[i].buf[j], 1)) != 0) |
14940 |
++ read, 1)) != 0) |
14941 |
+ goto unlock; |
14942 |
++ msg[i].buf[j] = read[0]; |
14943 |
+ } |
14944 |
++ |
14945 |
++ kfree(read); |
14946 |
+ } else { |
14947 |
+ for (j = 0; j < msg[i].len; j++) { |
14948 |
+ /* Last byte of transaction? Then send STOP. */ |
14949 |
+diff --git a/drivers/media/usb/em28xx/em28xx-cards.c b/drivers/media/usb/em28xx/em28xx-cards.c |
14950 |
+index 948e22e29b42a..ebc430b05f21c 100644 |
14951 |
+--- a/drivers/media/usb/em28xx/em28xx-cards.c |
14952 |
++++ b/drivers/media/usb/em28xx/em28xx-cards.c |
14953 |
+@@ -3625,8 +3625,10 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, |
14954 |
+ |
14955 |
+ if (dev->is_audio_only) { |
14956 |
+ retval = em28xx_audio_setup(dev); |
14957 |
+- if (retval) |
14958 |
+- return -ENODEV; |
14959 |
++ if (retval) { |
14960 |
++ retval = -ENODEV; |
14961 |
++ goto err_deinit_media; |
14962 |
++ } |
14963 |
+ em28xx_init_extension(dev); |
14964 |
+ |
14965 |
+ return 0; |
14966 |
+@@ -3645,7 +3647,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, |
14967 |
+ dev_err(&dev->intf->dev, |
14968 |
+ "%s: em28xx_i2c_register bus 0 - error [%d]!\n", |
14969 |
+ __func__, retval); |
14970 |
+- return retval; |
14971 |
++ goto err_deinit_media; |
14972 |
+ } |
14973 |
+ |
14974 |
+ /* register i2c bus 1 */ |
14975 |
+@@ -3661,9 +3663,7 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, |
14976 |
+ "%s: em28xx_i2c_register bus 1 - error [%d]!\n", |
14977 |
+ __func__, retval); |
14978 |
+ |
14979 |
+- em28xx_i2c_unregister(dev, 0); |
14980 |
+- |
14981 |
+- return retval; |
14982 |
++ goto err_unreg_i2c; |
14983 |
+ } |
14984 |
+ } |
14985 |
+ |
14986 |
+@@ -3671,6 +3671,12 @@ static int em28xx_init_dev(struct em28xx *dev, struct usb_device *udev, |
14987 |
+ em28xx_card_setup(dev); |
14988 |
+ |
14989 |
+ return 0; |
14990 |
++ |
14991 |
++err_unreg_i2c: |
14992 |
++ em28xx_i2c_unregister(dev, 0); |
14993 |
++err_deinit_media: |
14994 |
++ em28xx_unregister_media_device(dev); |
14995 |
++ return retval; |
14996 |
+ } |
14997 |
+ |
14998 |
+ static int em28xx_duplicate_dev(struct em28xx *dev) |
14999 |
+diff --git a/drivers/media/usb/em28xx/em28xx-core.c b/drivers/media/usb/em28xx/em28xx-core.c |
15000 |
+index acc0bf7dbe2b1..c837cc528a335 100644 |
15001 |
+--- a/drivers/media/usb/em28xx/em28xx-core.c |
15002 |
++++ b/drivers/media/usb/em28xx/em28xx-core.c |
15003 |
+@@ -89,7 +89,7 @@ int em28xx_read_reg_req_len(struct em28xx *dev, u8 req, u16 reg, |
15004 |
+ mutex_lock(&dev->ctrl_urb_lock); |
15005 |
+ ret = usb_control_msg(udev, pipe, req, |
15006 |
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
15007 |
+- 0x0000, reg, dev->urb_buf, len, HZ); |
15008 |
++ 0x0000, reg, dev->urb_buf, len, 1000); |
15009 |
+ if (ret < 0) { |
15010 |
+ em28xx_regdbg("(pipe 0x%08x): IN: %02x %02x %02x %02x %02x %02x %02x %02x failed with error %i\n", |
15011 |
+ pipe, |
15012 |
+@@ -158,7 +158,7 @@ int em28xx_write_regs_req(struct em28xx *dev, u8 req, u16 reg, char *buf, |
15013 |
+ memcpy(dev->urb_buf, buf, len); |
15014 |
+ ret = usb_control_msg(udev, pipe, req, |
15015 |
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
15016 |
+- 0x0000, reg, dev->urb_buf, len, HZ); |
15017 |
++ 0x0000, reg, dev->urb_buf, len, 1000); |
15018 |
+ mutex_unlock(&dev->ctrl_urb_lock); |
15019 |
+ |
15020 |
+ if (ret < 0) { |
15021 |
+diff --git a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c |
15022 |
+index d38dee1792e41..3915d551d59e7 100644 |
15023 |
+--- a/drivers/media/usb/pvrusb2/pvrusb2-hdw.c |
15024 |
++++ b/drivers/media/usb/pvrusb2/pvrusb2-hdw.c |
15025 |
+@@ -1467,7 +1467,7 @@ static int pvr2_upload_firmware1(struct pvr2_hdw *hdw) |
15026 |
+ for (address = 0; address < fwsize; address += 0x800) { |
15027 |
+ memcpy(fw_ptr, fw_entry->data + address, 0x800); |
15028 |
+ ret += usb_control_msg(hdw->usb_dev, pipe, 0xa0, 0x40, address, |
15029 |
+- 0, fw_ptr, 0x800, HZ); |
15030 |
++ 0, fw_ptr, 0x800, 1000); |
15031 |
+ } |
15032 |
+ |
15033 |
+ trace_firmware("Upload done, releasing device's CPU"); |
15034 |
+@@ -1605,7 +1605,7 @@ int pvr2_upload_firmware2(struct pvr2_hdw *hdw) |
15035 |
+ ((u32 *)fw_ptr)[icnt] = swab32(((u32 *)fw_ptr)[icnt]); |
15036 |
+ |
15037 |
+ ret |= usb_bulk_msg(hdw->usb_dev, pipe, fw_ptr,bcnt, |
15038 |
+- &actual_length, HZ); |
15039 |
++ &actual_length, 1000); |
15040 |
+ ret |= (actual_length != bcnt); |
15041 |
+ if (ret) break; |
15042 |
+ fw_done += bcnt; |
15043 |
+@@ -3438,7 +3438,7 @@ void pvr2_hdw_cpufw_set_enabled(struct pvr2_hdw *hdw, |
15044 |
+ 0xa0,0xc0, |
15045 |
+ address,0, |
15046 |
+ hdw->fw_buffer+address, |
15047 |
+- 0x800,HZ); |
15048 |
++ 0x800,1000); |
15049 |
+ if (ret < 0) break; |
15050 |
+ } |
15051 |
+ |
15052 |
+@@ -3977,7 +3977,7 @@ void pvr2_hdw_cpureset_assert(struct pvr2_hdw *hdw,int val) |
15053 |
+ /* Write the CPUCS register on the 8051. The lsb of the register |
15054 |
+ is the reset bit; a 1 asserts reset while a 0 clears it. */ |
15055 |
+ pipe = usb_sndctrlpipe(hdw->usb_dev, 0); |
15056 |
+- ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,HZ); |
15057 |
++ ret = usb_control_msg(hdw->usb_dev,pipe,0xa0,0x40,0xe600,0,da,1,1000); |
15058 |
+ if (ret < 0) { |
15059 |
+ pvr2_trace(PVR2_TRACE_ERROR_LEGS, |
15060 |
+ "cpureset_assert(%d) error=%d",val,ret); |
15061 |
+diff --git a/drivers/media/usb/s2255/s2255drv.c b/drivers/media/usb/s2255/s2255drv.c |
15062 |
+index 3b0e4ed75d99c..acf18e2251a52 100644 |
15063 |
+--- a/drivers/media/usb/s2255/s2255drv.c |
15064 |
++++ b/drivers/media/usb/s2255/s2255drv.c |
15065 |
+@@ -1882,7 +1882,7 @@ static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request, |
15066 |
+ USB_TYPE_VENDOR | USB_RECIP_DEVICE | |
15067 |
+ USB_DIR_IN, |
15068 |
+ Value, Index, buf, |
15069 |
+- TransferBufferLength, HZ * 5); |
15070 |
++ TransferBufferLength, USB_CTRL_SET_TIMEOUT); |
15071 |
+ |
15072 |
+ if (r >= 0) |
15073 |
+ memcpy(TransferBuffer, buf, TransferBufferLength); |
15074 |
+@@ -1891,7 +1891,7 @@ static long s2255_vendor_req(struct s2255_dev *dev, unsigned char Request, |
15075 |
+ r = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, 0), |
15076 |
+ Request, USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
15077 |
+ Value, Index, buf, |
15078 |
+- TransferBufferLength, HZ * 5); |
15079 |
++ TransferBufferLength, USB_CTRL_SET_TIMEOUT); |
15080 |
+ } |
15081 |
+ kfree(buf); |
15082 |
+ return r; |
15083 |
+diff --git a/drivers/media/usb/stk1160/stk1160-core.c b/drivers/media/usb/stk1160/stk1160-core.c |
15084 |
+index b4f8bc5db1389..4e1698f788187 100644 |
15085 |
+--- a/drivers/media/usb/stk1160/stk1160-core.c |
15086 |
++++ b/drivers/media/usb/stk1160/stk1160-core.c |
15087 |
+@@ -65,7 +65,7 @@ int stk1160_read_reg(struct stk1160 *dev, u16 reg, u8 *value) |
15088 |
+ return -ENOMEM; |
15089 |
+ ret = usb_control_msg(dev->udev, pipe, 0x00, |
15090 |
+ USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
15091 |
+- 0x00, reg, buf, sizeof(u8), HZ); |
15092 |
++ 0x00, reg, buf, sizeof(u8), 1000); |
15093 |
+ if (ret < 0) { |
15094 |
+ stk1160_err("read failed on reg 0x%x (%d)\n", |
15095 |
+ reg, ret); |
15096 |
+@@ -85,7 +85,7 @@ int stk1160_write_reg(struct stk1160 *dev, u16 reg, u16 value) |
15097 |
+ |
15098 |
+ ret = usb_control_msg(dev->udev, pipe, 0x01, |
15099 |
+ USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, |
15100 |
+- value, reg, NULL, 0, HZ); |
15101 |
++ value, reg, NULL, 0, 1000); |
15102 |
+ if (ret < 0) { |
15103 |
+ stk1160_err("write failed on reg 0x%x (%d)\n", |
15104 |
+ reg, ret); |
15105 |
+diff --git a/drivers/media/usb/uvc/uvcvideo.h b/drivers/media/usb/uvc/uvcvideo.h |
15106 |
+index cce5e38133cd3..c3ea6a53869f5 100644 |
15107 |
+--- a/drivers/media/usb/uvc/uvcvideo.h |
15108 |
++++ b/drivers/media/usb/uvc/uvcvideo.h |
15109 |
+@@ -189,7 +189,7 @@ |
15110 |
+ /* Maximum status buffer size in bytes of interrupt URB. */ |
15111 |
+ #define UVC_MAX_STATUS_SIZE 16 |
15112 |
+ |
15113 |
+-#define UVC_CTRL_CONTROL_TIMEOUT 500 |
15114 |
++#define UVC_CTRL_CONTROL_TIMEOUT 5000 |
15115 |
+ #define UVC_CTRL_STREAMING_TIMEOUT 5000 |
15116 |
+ |
15117 |
+ /* Maximum allowed number of control mappings per device */ |
15118 |
+diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c |
15119 |
+index f4f67b385d00a..c7308a2a80a0f 100644 |
15120 |
+--- a/drivers/media/v4l2-core/v4l2-ioctl.c |
15121 |
++++ b/drivers/media/v4l2-core/v4l2-ioctl.c |
15122 |
+@@ -2088,6 +2088,7 @@ static int v4l_prepare_buf(const struct v4l2_ioctl_ops *ops, |
15123 |
+ static int v4l_g_parm(const struct v4l2_ioctl_ops *ops, |
15124 |
+ struct file *file, void *fh, void *arg) |
15125 |
+ { |
15126 |
++ struct video_device *vfd = video_devdata(file); |
15127 |
+ struct v4l2_streamparm *p = arg; |
15128 |
+ v4l2_std_id std; |
15129 |
+ int ret = check_fmt(file, p->type); |
15130 |
+@@ -2099,7 +2100,8 @@ static int v4l_g_parm(const struct v4l2_ioctl_ops *ops, |
15131 |
+ if (p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE && |
15132 |
+ p->type != V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE) |
15133 |
+ return -EINVAL; |
15134 |
+- p->parm.capture.readbuffers = 2; |
15135 |
++ if (vfd->device_caps & V4L2_CAP_READWRITE) |
15136 |
++ p->parm.capture.readbuffers = 2; |
15137 |
+ ret = ops->vidioc_g_std(file, fh, &std); |
15138 |
+ if (ret == 0) |
15139 |
+ v4l2_video_std_frame_period(std, &p->parm.capture.timeperframe); |
15140 |
+diff --git a/drivers/memory/renesas-rpc-if.c b/drivers/memory/renesas-rpc-if.c |
15141 |
+index 77a011d5ff8c1..8618702233002 100644 |
15142 |
+--- a/drivers/memory/renesas-rpc-if.c |
15143 |
++++ b/drivers/memory/renesas-rpc-if.c |
15144 |
+@@ -244,7 +244,7 @@ int rpcif_sw_init(struct rpcif *rpc, struct device *dev) |
15145 |
+ res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dirmap"); |
15146 |
+ rpc->dirmap = devm_ioremap_resource(&pdev->dev, res); |
15147 |
+ if (IS_ERR(rpc->dirmap)) |
15148 |
+- rpc->dirmap = NULL; |
15149 |
++ return PTR_ERR(rpc->dirmap); |
15150 |
+ rpc->size = resource_size(res); |
15151 |
+ |
15152 |
+ rpc->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL); |
15153 |
+diff --git a/drivers/mfd/atmel-flexcom.c b/drivers/mfd/atmel-flexcom.c |
15154 |
+index d2f5c073fdf31..559eb4d352b68 100644 |
15155 |
+--- a/drivers/mfd/atmel-flexcom.c |
15156 |
++++ b/drivers/mfd/atmel-flexcom.c |
15157 |
+@@ -87,8 +87,7 @@ static const struct of_device_id atmel_flexcom_of_match[] = { |
15158 |
+ }; |
15159 |
+ MODULE_DEVICE_TABLE(of, atmel_flexcom_of_match); |
15160 |
+ |
15161 |
+-#ifdef CONFIG_PM_SLEEP |
15162 |
+-static int atmel_flexcom_resume(struct device *dev) |
15163 |
++static int __maybe_unused atmel_flexcom_resume_noirq(struct device *dev) |
15164 |
+ { |
15165 |
+ struct atmel_flexcom *ddata = dev_get_drvdata(dev); |
15166 |
+ int err; |
15167 |
+@@ -105,16 +104,16 @@ static int atmel_flexcom_resume(struct device *dev) |
15168 |
+ |
15169 |
+ return 0; |
15170 |
+ } |
15171 |
+-#endif |
15172 |
+ |
15173 |
+-static SIMPLE_DEV_PM_OPS(atmel_flexcom_pm_ops, NULL, |
15174 |
+- atmel_flexcom_resume); |
15175 |
++static const struct dev_pm_ops atmel_flexcom_pm_ops = { |
15176 |
++ .resume_noirq = atmel_flexcom_resume_noirq, |
15177 |
++}; |
15178 |
+ |
15179 |
+ static struct platform_driver atmel_flexcom_driver = { |
15180 |
+ .probe = atmel_flexcom_probe, |
15181 |
+ .driver = { |
15182 |
+ .name = "atmel_flexcom", |
15183 |
+- .pm = &atmel_flexcom_pm_ops, |
15184 |
++ .pm = pm_ptr(&atmel_flexcom_pm_ops), |
15185 |
+ .of_match_table = atmel_flexcom_of_match, |
15186 |
+ }, |
15187 |
+ }; |
15188 |
+diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c |
15189 |
+index 6e105cca27d47..67e2707af4bce 100644 |
15190 |
+--- a/drivers/mfd/tps65910.c |
15191 |
++++ b/drivers/mfd/tps65910.c |
15192 |
+@@ -436,15 +436,6 @@ static void tps65910_power_off(void) |
15193 |
+ |
15194 |
+ tps65910 = dev_get_drvdata(&tps65910_i2c_client->dev); |
15195 |
+ |
15196 |
+- /* |
15197 |
+- * The PWR_OFF bit needs to be set separately, before transitioning |
15198 |
+- * to the OFF state. It enables the "sequential" power-off mode on |
15199 |
+- * TPS65911, it's a NO-OP on TPS65910. |
15200 |
+- */ |
15201 |
+- if (regmap_set_bits(tps65910->regmap, TPS65910_DEVCTRL, |
15202 |
+- DEVCTRL_PWR_OFF_MASK) < 0) |
15203 |
+- return; |
15204 |
+- |
15205 |
+ regmap_update_bits(tps65910->regmap, TPS65910_DEVCTRL, |
15206 |
+ DEVCTRL_DEV_OFF_MASK | DEVCTRL_DEV_ON_MASK, |
15207 |
+ DEVCTRL_DEV_OFF_MASK); |
15208 |
+@@ -504,6 +495,19 @@ static int tps65910_i2c_probe(struct i2c_client *i2c, |
15209 |
+ tps65910_sleepinit(tps65910, pmic_plat_data); |
15210 |
+ |
15211 |
+ if (pmic_plat_data->pm_off && !pm_power_off) { |
15212 |
++ /* |
15213 |
++ * The PWR_OFF bit needs to be set separately, before |
15214 |
++ * transitioning to the OFF state. It enables the "sequential" |
15215 |
++ * power-off mode on TPS65911, it's a NO-OP on TPS65910. |
15216 |
++ */ |
15217 |
++ ret = regmap_set_bits(tps65910->regmap, TPS65910_DEVCTRL, |
15218 |
++ DEVCTRL_PWR_OFF_MASK); |
15219 |
++ if (ret) { |
15220 |
++ dev_err(&i2c->dev, "failed to set power-off mode: %d\n", |
15221 |
++ ret); |
15222 |
++ return ret; |
15223 |
++ } |
15224 |
++ |
15225 |
+ tps65910_i2c_client = i2c; |
15226 |
+ pm_power_off = tps65910_power_off; |
15227 |
+ } |
15228 |
+diff --git a/drivers/misc/eeprom/at25.c b/drivers/misc/eeprom/at25.c |
15229 |
+index b38978a3b3ffa..9193b812bc07e 100644 |
15230 |
+--- a/drivers/misc/eeprom/at25.c |
15231 |
++++ b/drivers/misc/eeprom/at25.c |
15232 |
+@@ -17,8 +17,6 @@ |
15233 |
+ #include <linux/spi/spi.h> |
15234 |
+ #include <linux/spi/eeprom.h> |
15235 |
+ #include <linux/property.h> |
15236 |
+-#include <linux/of.h> |
15237 |
+-#include <linux/of_device.h> |
15238 |
+ #include <linux/math.h> |
15239 |
+ |
15240 |
+ /* |
15241 |
+@@ -380,13 +378,14 @@ static int at25_probe(struct spi_device *spi) |
15242 |
+ int sr; |
15243 |
+ u8 id[FM25_ID_LEN]; |
15244 |
+ u8 sernum[FM25_SN_LEN]; |
15245 |
++ bool is_fram; |
15246 |
+ int i; |
15247 |
+- const struct of_device_id *match; |
15248 |
+- bool is_fram = 0; |
15249 |
+ |
15250 |
+- match = of_match_device(of_match_ptr(at25_of_match), &spi->dev); |
15251 |
+- if (match && !strcmp(match->compatible, "cypress,fm25")) |
15252 |
+- is_fram = 1; |
15253 |
++ err = device_property_match_string(&spi->dev, "compatible", "cypress,fm25"); |
15254 |
++ if (err >= 0) |
15255 |
++ is_fram = true; |
15256 |
++ else |
15257 |
++ is_fram = false; |
15258 |
+ |
15259 |
+ at25 = devm_kzalloc(&spi->dev, sizeof(struct at25_data), GFP_KERNEL); |
15260 |
+ if (!at25) |
15261 |
+diff --git a/drivers/misc/habanalabs/common/firmware_if.c b/drivers/misc/habanalabs/common/firmware_if.c |
15262 |
+index 8d2568c63f19e..a8e683964ab03 100644 |
15263 |
+--- a/drivers/misc/habanalabs/common/firmware_if.c |
15264 |
++++ b/drivers/misc/habanalabs/common/firmware_if.c |
15265 |
+@@ -1703,6 +1703,9 @@ static int hl_fw_dynamic_validate_descriptor(struct hl_device *hdev, |
15266 |
+ return rc; |
15267 |
+ } |
15268 |
+ |
15269 |
++ /* here we can mark the descriptor as valid as the content has been validated */ |
15270 |
++ fw_loader->dynamic_loader.fw_desc_valid = true; |
15271 |
++ |
15272 |
+ return 0; |
15273 |
+ } |
15274 |
+ |
15275 |
+@@ -1759,7 +1762,13 @@ static int hl_fw_dynamic_read_and_validate_descriptor(struct hl_device *hdev, |
15276 |
+ return rc; |
15277 |
+ } |
15278 |
+ |
15279 |
+- /* extract address copy the descriptor from */ |
15280 |
++ /* |
15281 |
++ * extract address to copy the descriptor from |
15282 |
++ * in addition, as the descriptor value is going to be over-ridden by new data- we mark it |
15283 |
++ * as invalid. |
15284 |
++ * it will be marked again as valid once validated |
15285 |
++ */ |
15286 |
++ fw_loader->dynamic_loader.fw_desc_valid = false; |
15287 |
+ src = hdev->pcie_bar[region->bar_id] + region->offset_in_bar + |
15288 |
+ response->ram_offset; |
15289 |
+ memcpy_fromio(fw_desc, src, sizeof(struct lkd_fw_comms_desc)); |
15290 |
+@@ -2239,6 +2248,9 @@ static int hl_fw_dynamic_init_cpu(struct hl_device *hdev, |
15291 |
+ dev_info(hdev->dev, |
15292 |
+ "Loading firmware to device, may take some time...\n"); |
15293 |
+ |
15294 |
++ /* initialize FW descriptor as invalid */ |
15295 |
++ fw_loader->dynamic_loader.fw_desc_valid = false; |
15296 |
++ |
15297 |
+ /* |
15298 |
+ * In this stage, "cpu_dyn_regs" contains only LKD's hard coded values! |
15299 |
+ * It will be updated from FW after hl_fw_dynamic_request_descriptor(). |
15300 |
+@@ -2325,7 +2337,8 @@ static int hl_fw_dynamic_init_cpu(struct hl_device *hdev, |
15301 |
+ return 0; |
15302 |
+ |
15303 |
+ protocol_err: |
15304 |
+- fw_read_errors(hdev, le32_to_cpu(dyn_regs->cpu_boot_err0), |
15305 |
++ if (fw_loader->dynamic_loader.fw_desc_valid) |
15306 |
++ fw_read_errors(hdev, le32_to_cpu(dyn_regs->cpu_boot_err0), |
15307 |
+ le32_to_cpu(dyn_regs->cpu_boot_err1), |
15308 |
+ le32_to_cpu(dyn_regs->cpu_boot_dev_sts0), |
15309 |
+ le32_to_cpu(dyn_regs->cpu_boot_dev_sts1)); |
15310 |
+diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h |
15311 |
+index bebebcb163ee8..dfcd87b98ca08 100644 |
15312 |
+--- a/drivers/misc/habanalabs/common/habanalabs.h |
15313 |
++++ b/drivers/misc/habanalabs/common/habanalabs.h |
15314 |
+@@ -992,6 +992,7 @@ struct fw_response { |
15315 |
+ * @image_region: region to copy the FW image to |
15316 |
+ * @fw_image_size: size of FW image to load |
15317 |
+ * @wait_for_bl_timeout: timeout for waiting for boot loader to respond |
15318 |
++ * @fw_desc_valid: true if FW descriptor has been validated and hence the data can be used |
15319 |
+ */ |
15320 |
+ struct dynamic_fw_load_mgr { |
15321 |
+ struct fw_response response; |
15322 |
+@@ -999,6 +1000,7 @@ struct dynamic_fw_load_mgr { |
15323 |
+ struct pci_mem_region *image_region; |
15324 |
+ size_t fw_image_size; |
15325 |
+ u32 wait_for_bl_timeout; |
15326 |
++ bool fw_desc_valid; |
15327 |
+ }; |
15328 |
+ |
15329 |
+ /** |
15330 |
+diff --git a/drivers/misc/lattice-ecp3-config.c b/drivers/misc/lattice-ecp3-config.c |
15331 |
+index 0f54730c7ed56..98828030b5a4d 100644 |
15332 |
+--- a/drivers/misc/lattice-ecp3-config.c |
15333 |
++++ b/drivers/misc/lattice-ecp3-config.c |
15334 |
+@@ -76,12 +76,12 @@ static void firmware_load(const struct firmware *fw, void *context) |
15335 |
+ |
15336 |
+ if (fw == NULL) { |
15337 |
+ dev_err(&spi->dev, "Cannot load firmware, aborting\n"); |
15338 |
+- return; |
15339 |
++ goto out; |
15340 |
+ } |
15341 |
+ |
15342 |
+ if (fw->size == 0) { |
15343 |
+ dev_err(&spi->dev, "Error: Firmware size is 0!\n"); |
15344 |
+- return; |
15345 |
++ goto out; |
15346 |
+ } |
15347 |
+ |
15348 |
+ /* Fill dummy data (24 stuffing bits for commands) */ |
15349 |
+@@ -103,7 +103,7 @@ static void firmware_load(const struct firmware *fw, void *context) |
15350 |
+ dev_err(&spi->dev, |
15351 |
+ "Error: No supported FPGA detected (JEDEC_ID=%08x)!\n", |
15352 |
+ jedec_id); |
15353 |
+- return; |
15354 |
++ goto out; |
15355 |
+ } |
15356 |
+ |
15357 |
+ dev_info(&spi->dev, "FPGA %s detected\n", ecp3_dev[i].name); |
15358 |
+@@ -116,7 +116,7 @@ static void firmware_load(const struct firmware *fw, void *context) |
15359 |
+ buffer = kzalloc(fw->size + 8, GFP_KERNEL); |
15360 |
+ if (!buffer) { |
15361 |
+ dev_err(&spi->dev, "Error: Can't allocate memory!\n"); |
15362 |
+- return; |
15363 |
++ goto out; |
15364 |
+ } |
15365 |
+ |
15366 |
+ /* |
15367 |
+@@ -155,7 +155,7 @@ static void firmware_load(const struct firmware *fw, void *context) |
15368 |
+ "Error: Timeout waiting for FPGA to clear (status=%08x)!\n", |
15369 |
+ status); |
15370 |
+ kfree(buffer); |
15371 |
+- return; |
15372 |
++ goto out; |
15373 |
+ } |
15374 |
+ |
15375 |
+ dev_info(&spi->dev, "Configuring the FPGA...\n"); |
15376 |
+@@ -181,7 +181,7 @@ static void firmware_load(const struct firmware *fw, void *context) |
15377 |
+ release_firmware(fw); |
15378 |
+ |
15379 |
+ kfree(buffer); |
15380 |
+- |
15381 |
++out: |
15382 |
+ complete(&data->fw_loaded); |
15383 |
+ } |
15384 |
+ |
15385 |
+diff --git a/drivers/misc/lkdtm/Makefile b/drivers/misc/lkdtm/Makefile |
15386 |
+index aa12097668d33..e2984ce51fe4d 100644 |
15387 |
+--- a/drivers/misc/lkdtm/Makefile |
15388 |
++++ b/drivers/misc/lkdtm/Makefile |
15389 |
+@@ -20,7 +20,7 @@ CFLAGS_REMOVE_rodata.o += $(CC_FLAGS_LTO) |
15390 |
+ |
15391 |
+ OBJCOPYFLAGS := |
15392 |
+ OBJCOPYFLAGS_rodata_objcopy.o := \ |
15393 |
+- --rename-section .noinstr.text=.rodata,alloc,readonly,load |
15394 |
++ --rename-section .noinstr.text=.rodata,alloc,readonly,load,contents |
15395 |
+ targets += rodata.o rodata_objcopy.o |
15396 |
+ $(obj)/rodata_objcopy.o: $(obj)/rodata.o FORCE |
15397 |
+ $(call if_changed,objcopy) |
15398 |
+diff --git a/drivers/misc/mei/hbm.c b/drivers/misc/mei/hbm.c |
15399 |
+index be41843df75bc..cebcca6d6d3ef 100644 |
15400 |
+--- a/drivers/misc/mei/hbm.c |
15401 |
++++ b/drivers/misc/mei/hbm.c |
15402 |
+@@ -672,10 +672,14 @@ static void mei_hbm_cl_dma_map_res(struct mei_device *dev, |
15403 |
+ if (!cl) |
15404 |
+ return; |
15405 |
+ |
15406 |
+- dev_dbg(dev->dev, "cl dma map result = %d\n", res->status); |
15407 |
+- cl->status = res->status; |
15408 |
+- if (!cl->status) |
15409 |
++ if (res->status) { |
15410 |
++ dev_err(dev->dev, "cl dma map failed %d\n", res->status); |
15411 |
++ cl->status = -EFAULT; |
15412 |
++ } else { |
15413 |
++ dev_dbg(dev->dev, "cl dma map succeeded\n"); |
15414 |
+ cl->dma_mapped = 1; |
15415 |
++ cl->status = 0; |
15416 |
++ } |
15417 |
+ wake_up(&cl->wait); |
15418 |
+ } |
15419 |
+ |
15420 |
+@@ -698,10 +702,14 @@ static void mei_hbm_cl_dma_unmap_res(struct mei_device *dev, |
15421 |
+ if (!cl) |
15422 |
+ return; |
15423 |
+ |
15424 |
+- dev_dbg(dev->dev, "cl dma unmap result = %d\n", res->status); |
15425 |
+- cl->status = res->status; |
15426 |
+- if (!cl->status) |
15427 |
++ if (res->status) { |
15428 |
++ dev_err(dev->dev, "cl dma unmap failed %d\n", res->status); |
15429 |
++ cl->status = -EFAULT; |
15430 |
++ } else { |
15431 |
++ dev_dbg(dev->dev, "cl dma unmap succeeded\n"); |
15432 |
+ cl->dma_mapped = 0; |
15433 |
++ cl->status = 0; |
15434 |
++ } |
15435 |
+ wake_up(&cl->wait); |
15436 |
+ } |
15437 |
+ |
15438 |
+diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c |
15439 |
+index 68edf7a615be5..5447c47157aa5 100644 |
15440 |
+--- a/drivers/mmc/core/sdio.c |
15441 |
++++ b/drivers/mmc/core/sdio.c |
15442 |
+@@ -708,6 +708,8 @@ try_again: |
15443 |
+ if (host->ops->init_card) |
15444 |
+ host->ops->init_card(host, card); |
15445 |
+ |
15446 |
++ card->ocr = ocr_card; |
15447 |
++ |
15448 |
+ /* |
15449 |
+ * If the host and card support UHS-I mode request the card |
15450 |
+ * to switch to 1.8V signaling level. No 1.8v signalling if |
15451 |
+@@ -820,7 +822,7 @@ try_again: |
15452 |
+ goto mismatch; |
15453 |
+ } |
15454 |
+ } |
15455 |
+- card->ocr = ocr_card; |
15456 |
++ |
15457 |
+ mmc_fixup_device(card, sdio_fixup_methods); |
15458 |
+ |
15459 |
+ if (card->type == MMC_TYPE_SD_COMBO) { |
15460 |
+diff --git a/drivers/mmc/host/meson-mx-sdhc-mmc.c b/drivers/mmc/host/meson-mx-sdhc-mmc.c |
15461 |
+index 8fdd0bbbfa21f..28aa78aa08f3f 100644 |
15462 |
+--- a/drivers/mmc/host/meson-mx-sdhc-mmc.c |
15463 |
++++ b/drivers/mmc/host/meson-mx-sdhc-mmc.c |
15464 |
+@@ -854,6 +854,11 @@ static int meson_mx_sdhc_probe(struct platform_device *pdev) |
15465 |
+ goto err_disable_pclk; |
15466 |
+ |
15467 |
+ irq = platform_get_irq(pdev, 0); |
15468 |
++ if (irq < 0) { |
15469 |
++ ret = irq; |
15470 |
++ goto err_disable_pclk; |
15471 |
++ } |
15472 |
++ |
15473 |
+ ret = devm_request_threaded_irq(dev, irq, meson_mx_sdhc_irq, |
15474 |
+ meson_mx_sdhc_irq_thread, IRQF_ONESHOT, |
15475 |
+ NULL, host); |
15476 |
+diff --git a/drivers/mmc/host/meson-mx-sdio.c b/drivers/mmc/host/meson-mx-sdio.c |
15477 |
+index d4a48916bfb67..3a19a05ef55a7 100644 |
15478 |
+--- a/drivers/mmc/host/meson-mx-sdio.c |
15479 |
++++ b/drivers/mmc/host/meson-mx-sdio.c |
15480 |
+@@ -662,6 +662,11 @@ static int meson_mx_mmc_probe(struct platform_device *pdev) |
15481 |
+ } |
15482 |
+ |
15483 |
+ irq = platform_get_irq(pdev, 0); |
15484 |
++ if (irq < 0) { |
15485 |
++ ret = irq; |
15486 |
++ goto error_free_mmc; |
15487 |
++ } |
15488 |
++ |
15489 |
+ ret = devm_request_threaded_irq(host->controller_dev, irq, |
15490 |
+ meson_mx_mmc_irq, |
15491 |
+ meson_mx_mmc_irq_thread, IRQF_ONESHOT, |
15492 |
+diff --git a/drivers/mmc/host/mtk-sd.c b/drivers/mmc/host/mtk-sd.c |
15493 |
+index 9e6dab7e34242..1ac92015992ed 100644 |
15494 |
+--- a/drivers/mmc/host/mtk-sd.c |
15495 |
++++ b/drivers/mmc/host/mtk-sd.c |
15496 |
+@@ -628,12 +628,11 @@ static void msdc_reset_hw(struct msdc_host *host) |
15497 |
+ u32 val; |
15498 |
+ |
15499 |
+ sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_RST); |
15500 |
+- while (readl(host->base + MSDC_CFG) & MSDC_CFG_RST) |
15501 |
+- cpu_relax(); |
15502 |
++ readl_poll_timeout(host->base + MSDC_CFG, val, !(val & MSDC_CFG_RST), 0, 0); |
15503 |
+ |
15504 |
+ sdr_set_bits(host->base + MSDC_FIFOCS, MSDC_FIFOCS_CLR); |
15505 |
+- while (readl(host->base + MSDC_FIFOCS) & MSDC_FIFOCS_CLR) |
15506 |
+- cpu_relax(); |
15507 |
++ readl_poll_timeout(host->base + MSDC_FIFOCS, val, |
15508 |
++ !(val & MSDC_FIFOCS_CLR), 0, 0); |
15509 |
+ |
15510 |
+ val = readl(host->base + MSDC_INT); |
15511 |
+ writel(val, host->base + MSDC_INT); |
15512 |
+@@ -806,8 +805,9 @@ static void msdc_gate_clock(struct msdc_host *host) |
15513 |
+ clk_disable_unprepare(host->h_clk); |
15514 |
+ } |
15515 |
+ |
15516 |
+-static void msdc_ungate_clock(struct msdc_host *host) |
15517 |
++static int msdc_ungate_clock(struct msdc_host *host) |
15518 |
+ { |
15519 |
++ u32 val; |
15520 |
+ int ret; |
15521 |
+ |
15522 |
+ clk_prepare_enable(host->h_clk); |
15523 |
+@@ -817,11 +817,11 @@ static void msdc_ungate_clock(struct msdc_host *host) |
15524 |
+ ret = clk_bulk_prepare_enable(MSDC_NR_CLOCKS, host->bulk_clks); |
15525 |
+ if (ret) { |
15526 |
+ dev_err(host->dev, "Cannot enable pclk/axi/ahb clock gates\n"); |
15527 |
+- return; |
15528 |
++ return ret; |
15529 |
+ } |
15530 |
+ |
15531 |
+- while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB)) |
15532 |
+- cpu_relax(); |
15533 |
++ return readl_poll_timeout(host->base + MSDC_CFG, val, |
15534 |
++ (val & MSDC_CFG_CKSTB), 1, 20000); |
15535 |
+ } |
15536 |
+ |
15537 |
+ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz) |
15538 |
+@@ -832,6 +832,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz) |
15539 |
+ u32 div; |
15540 |
+ u32 sclk; |
15541 |
+ u32 tune_reg = host->dev_comp->pad_tune_reg; |
15542 |
++ u32 val; |
15543 |
+ |
15544 |
+ if (!hz) { |
15545 |
+ dev_dbg(host->dev, "set mclk to 0\n"); |
15546 |
+@@ -912,8 +913,7 @@ static void msdc_set_mclk(struct msdc_host *host, unsigned char timing, u32 hz) |
15547 |
+ else |
15548 |
+ clk_prepare_enable(clk_get_parent(host->src_clk)); |
15549 |
+ |
15550 |
+- while (!(readl(host->base + MSDC_CFG) & MSDC_CFG_CKSTB)) |
15551 |
+- cpu_relax(); |
15552 |
++ readl_poll_timeout(host->base + MSDC_CFG, val, (val & MSDC_CFG_CKSTB), 0, 0); |
15553 |
+ sdr_set_bits(host->base + MSDC_CFG, MSDC_CFG_CKPDN); |
15554 |
+ mmc->actual_clock = sclk; |
15555 |
+ host->mclk = hz; |
15556 |
+@@ -1223,13 +1223,13 @@ static bool msdc_cmd_done(struct msdc_host *host, int events, |
15557 |
+ static inline bool msdc_cmd_is_ready(struct msdc_host *host, |
15558 |
+ struct mmc_request *mrq, struct mmc_command *cmd) |
15559 |
+ { |
15560 |
+- /* The max busy time we can endure is 20ms */ |
15561 |
+- unsigned long tmo = jiffies + msecs_to_jiffies(20); |
15562 |
++ u32 val; |
15563 |
++ int ret; |
15564 |
+ |
15565 |
+- while ((readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) && |
15566 |
+- time_before(jiffies, tmo)) |
15567 |
+- cpu_relax(); |
15568 |
+- if (readl(host->base + SDC_STS) & SDC_STS_CMDBUSY) { |
15569 |
++ /* The max busy time we can endure is 20ms */ |
15570 |
++ ret = readl_poll_timeout_atomic(host->base + SDC_STS, val, |
15571 |
++ !(val & SDC_STS_CMDBUSY), 1, 20000); |
15572 |
++ if (ret) { |
15573 |
+ dev_err(host->dev, "CMD bus busy detected\n"); |
15574 |
+ host->error |= REQ_CMD_BUSY; |
15575 |
+ msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, cmd); |
15576 |
+@@ -1237,12 +1237,10 @@ static inline bool msdc_cmd_is_ready(struct msdc_host *host, |
15577 |
+ } |
15578 |
+ |
15579 |
+ if (mmc_resp_type(cmd) == MMC_RSP_R1B || cmd->data) { |
15580 |
+- tmo = jiffies + msecs_to_jiffies(20); |
15581 |
+ /* R1B or with data, should check SDCBUSY */ |
15582 |
+- while ((readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) && |
15583 |
+- time_before(jiffies, tmo)) |
15584 |
+- cpu_relax(); |
15585 |
+- if (readl(host->base + SDC_STS) & SDC_STS_SDCBUSY) { |
15586 |
++ ret = readl_poll_timeout_atomic(host->base + SDC_STS, val, |
15587 |
++ !(val & SDC_STS_SDCBUSY), 1, 20000); |
15588 |
++ if (ret) { |
15589 |
+ dev_err(host->dev, "Controller busy detected\n"); |
15590 |
+ host->error |= REQ_CMD_BUSY; |
15591 |
+ msdc_cmd_done(host, MSDC_INT_CMDTMO, mrq, cmd); |
15592 |
+@@ -1367,6 +1365,8 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events, |
15593 |
+ (MSDC_INT_XFER_COMPL | MSDC_INT_DATCRCERR | MSDC_INT_DATTMO |
15594 |
+ | MSDC_INT_DMA_BDCSERR | MSDC_INT_DMA_GPDCSERR |
15595 |
+ | MSDC_INT_DMA_PROTECT); |
15596 |
++ u32 val; |
15597 |
++ int ret; |
15598 |
+ |
15599 |
+ spin_lock_irqsave(&host->lock, flags); |
15600 |
+ done = !host->data; |
15601 |
+@@ -1383,8 +1383,14 @@ static bool msdc_data_xfer_done(struct msdc_host *host, u32 events, |
15602 |
+ readl(host->base + MSDC_DMA_CFG)); |
15603 |
+ sdr_set_field(host->base + MSDC_DMA_CTRL, MSDC_DMA_CTRL_STOP, |
15604 |
+ 1); |
15605 |
+- while (readl(host->base + MSDC_DMA_CFG) & MSDC_DMA_CFG_STS) |
15606 |
+- cpu_relax(); |
15607 |
++ |
15608 |
++ ret = readl_poll_timeout_atomic(host->base + MSDC_DMA_CFG, val, |
15609 |
++ !(val & MSDC_DMA_CFG_STS), 1, 20000); |
15610 |
++ if (ret) { |
15611 |
++ dev_dbg(host->dev, "DMA stop timed out\n"); |
15612 |
++ return false; |
15613 |
++ } |
15614 |
++ |
15615 |
+ sdr_clr_bits(host->base + MSDC_INTEN, data_ints_mask); |
15616 |
+ dev_dbg(host->dev, "DMA stop\n"); |
15617 |
+ |
15618 |
+@@ -2598,7 +2604,11 @@ static int msdc_drv_probe(struct platform_device *pdev) |
15619 |
+ spin_lock_init(&host->lock); |
15620 |
+ |
15621 |
+ platform_set_drvdata(pdev, mmc); |
15622 |
+- msdc_ungate_clock(host); |
15623 |
++ ret = msdc_ungate_clock(host); |
15624 |
++ if (ret) { |
15625 |
++ dev_err(&pdev->dev, "Cannot ungate clocks!\n"); |
15626 |
++ goto release_mem; |
15627 |
++ } |
15628 |
+ msdc_init_hw(host); |
15629 |
+ |
15630 |
+ if (mmc->caps2 & MMC_CAP2_CQE) { |
15631 |
+@@ -2757,8 +2767,12 @@ static int __maybe_unused msdc_runtime_resume(struct device *dev) |
15632 |
+ { |
15633 |
+ struct mmc_host *mmc = dev_get_drvdata(dev); |
15634 |
+ struct msdc_host *host = mmc_priv(mmc); |
15635 |
++ int ret; |
15636 |
++ |
15637 |
++ ret = msdc_ungate_clock(host); |
15638 |
++ if (ret) |
15639 |
++ return ret; |
15640 |
+ |
15641 |
+- msdc_ungate_clock(host); |
15642 |
+ msdc_restore_reg(host); |
15643 |
+ return 0; |
15644 |
+ } |
15645 |
+diff --git a/drivers/mmc/host/sdhci-pci-gli.c b/drivers/mmc/host/sdhci-pci-gli.c |
15646 |
+index 4fd99c1e82ba3..ad50f16658fe2 100644 |
15647 |
+--- a/drivers/mmc/host/sdhci-pci-gli.c |
15648 |
++++ b/drivers/mmc/host/sdhci-pci-gli.c |
15649 |
+@@ -12,6 +12,7 @@ |
15650 |
+ #include <linux/pci.h> |
15651 |
+ #include <linux/mmc/mmc.h> |
15652 |
+ #include <linux/delay.h> |
15653 |
++#include <linux/of.h> |
15654 |
+ #include "sdhci.h" |
15655 |
+ #include "sdhci-pci.h" |
15656 |
+ #include "cqhci.h" |
15657 |
+@@ -116,6 +117,8 @@ |
15658 |
+ #define PCI_GLI_9755_PECONF 0x44 |
15659 |
+ #define PCI_GLI_9755_LFCLK GENMASK(14, 12) |
15660 |
+ #define PCI_GLI_9755_DMACLK BIT(29) |
15661 |
++#define PCI_GLI_9755_INVERT_CD BIT(30) |
15662 |
++#define PCI_GLI_9755_INVERT_WP BIT(31) |
15663 |
+ |
15664 |
+ #define PCI_GLI_9755_CFG2 0x48 |
15665 |
+ #define PCI_GLI_9755_CFG2_L1DLY GENMASK(28, 24) |
15666 |
+@@ -570,6 +573,14 @@ static void gl9755_hw_setting(struct sdhci_pci_slot *slot) |
15667 |
+ gl9755_wt_on(pdev); |
15668 |
+ |
15669 |
+ pci_read_config_dword(pdev, PCI_GLI_9755_PECONF, &value); |
15670 |
++ /* |
15671 |
++ * Apple ARM64 platforms using these chips may have |
15672 |
++ * inverted CD/WP detection. |
15673 |
++ */ |
15674 |
++ if (of_property_read_bool(pdev->dev.of_node, "cd-inverted")) |
15675 |
++ value |= PCI_GLI_9755_INVERT_CD; |
15676 |
++ if (of_property_read_bool(pdev->dev.of_node, "wp-inverted")) |
15677 |
++ value |= PCI_GLI_9755_INVERT_WP; |
15678 |
+ value &= ~PCI_GLI_9755_LFCLK; |
15679 |
+ value &= ~PCI_GLI_9755_DMACLK; |
15680 |
+ pci_write_config_dword(pdev, PCI_GLI_9755_PECONF, value); |
15681 |
+diff --git a/drivers/mmc/host/tmio_mmc_core.c b/drivers/mmc/host/tmio_mmc_core.c |
15682 |
+index e2affa52ef469..a5850d83908be 100644 |
15683 |
+--- a/drivers/mmc/host/tmio_mmc_core.c |
15684 |
++++ b/drivers/mmc/host/tmio_mmc_core.c |
15685 |
+@@ -960,14 +960,8 @@ static void tmio_mmc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
15686 |
+ case MMC_POWER_OFF: |
15687 |
+ tmio_mmc_power_off(host); |
15688 |
+ /* For R-Car Gen2+, we need to reset SDHI specific SCC */ |
15689 |
+- if (host->pdata->flags & TMIO_MMC_MIN_RCAR2) { |
15690 |
+- host->reset(host); |
15691 |
+- |
15692 |
+- if (host->native_hotplug) |
15693 |
+- tmio_mmc_enable_mmc_irqs(host, |
15694 |
+- TMIO_STAT_CARD_REMOVE | |
15695 |
+- TMIO_STAT_CARD_INSERT); |
15696 |
+- } |
15697 |
++ if (host->pdata->flags & TMIO_MMC_MIN_RCAR2) |
15698 |
++ tmio_mmc_reset(host); |
15699 |
+ |
15700 |
+ host->set_clock(host, 0); |
15701 |
+ break; |
15702 |
+@@ -1175,6 +1169,7 @@ int tmio_mmc_host_probe(struct tmio_mmc_host *_host) |
15703 |
+ if (mmc_can_gpio_cd(mmc)) |
15704 |
+ _host->ops.get_cd = mmc_gpio_get_cd; |
15705 |
+ |
15706 |
++ /* must be set before tmio_mmc_reset() */ |
15707 |
+ _host->native_hotplug = !(mmc_can_gpio_cd(mmc) || |
15708 |
+ mmc->caps & MMC_CAP_NEEDS_POLL || |
15709 |
+ !mmc_card_is_removable(mmc)); |
15710 |
+@@ -1295,10 +1290,6 @@ int tmio_mmc_host_runtime_resume(struct device *dev) |
15711 |
+ if (host->clk_cache) |
15712 |
+ host->set_clock(host, host->clk_cache); |
15713 |
+ |
15714 |
+- if (host->native_hotplug) |
15715 |
+- tmio_mmc_enable_mmc_irqs(host, |
15716 |
+- TMIO_STAT_CARD_REMOVE | TMIO_STAT_CARD_INSERT); |
15717 |
+- |
15718 |
+ tmio_mmc_enable_dma(host, true); |
15719 |
+ |
15720 |
+ return 0; |
15721 |
+diff --git a/drivers/mtd/hyperbus/rpc-if.c b/drivers/mtd/hyperbus/rpc-if.c |
15722 |
+index ecb050ba95cdf..dc164c18f8429 100644 |
15723 |
+--- a/drivers/mtd/hyperbus/rpc-if.c |
15724 |
++++ b/drivers/mtd/hyperbus/rpc-if.c |
15725 |
+@@ -124,7 +124,9 @@ static int rpcif_hb_probe(struct platform_device *pdev) |
15726 |
+ if (!hyperbus) |
15727 |
+ return -ENOMEM; |
15728 |
+ |
15729 |
+- rpcif_sw_init(&hyperbus->rpc, pdev->dev.parent); |
15730 |
++ error = rpcif_sw_init(&hyperbus->rpc, pdev->dev.parent); |
15731 |
++ if (error) |
15732 |
++ return error; |
15733 |
+ |
15734 |
+ platform_set_drvdata(pdev, hyperbus); |
15735 |
+ |
15736 |
+@@ -150,9 +152,9 @@ static int rpcif_hb_remove(struct platform_device *pdev) |
15737 |
+ { |
15738 |
+ struct rpcif_hyperbus *hyperbus = platform_get_drvdata(pdev); |
15739 |
+ int error = hyperbus_unregister_device(&hyperbus->hbdev); |
15740 |
+- struct rpcif *rpc = dev_get_drvdata(pdev->dev.parent); |
15741 |
+ |
15742 |
+- rpcif_disable_rpm(rpc); |
15743 |
++ rpcif_disable_rpm(&hyperbus->rpc); |
15744 |
++ |
15745 |
+ return error; |
15746 |
+ } |
15747 |
+ |
15748 |
+diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c |
15749 |
+index 1532291989471..54df9cfd588ea 100644 |
15750 |
+--- a/drivers/mtd/mtdcore.c |
15751 |
++++ b/drivers/mtd/mtdcore.c |
15752 |
+@@ -825,8 +825,7 @@ static struct nvmem_device *mtd_otp_nvmem_register(struct mtd_info *mtd, |
15753 |
+ |
15754 |
+ /* OTP nvmem will be registered on the physical device */ |
15755 |
+ config.dev = mtd->dev.parent; |
15756 |
+- /* just reuse the compatible as name */ |
15757 |
+- config.name = compatible; |
15758 |
++ config.name = kasprintf(GFP_KERNEL, "%s-%s", dev_name(&mtd->dev), compatible); |
15759 |
+ config.id = NVMEM_DEVID_NONE; |
15760 |
+ config.owner = THIS_MODULE; |
15761 |
+ config.type = NVMEM_TYPE_OTP; |
15762 |
+@@ -842,6 +841,7 @@ static struct nvmem_device *mtd_otp_nvmem_register(struct mtd_info *mtd, |
15763 |
+ nvmem = NULL; |
15764 |
+ |
15765 |
+ of_node_put(np); |
15766 |
++ kfree(config.name); |
15767 |
+ |
15768 |
+ return nvmem; |
15769 |
+ } |
15770 |
+diff --git a/drivers/mtd/mtdpart.c b/drivers/mtd/mtdpart.c |
15771 |
+index 04af12b66110c..357661b62c94d 100644 |
15772 |
+--- a/drivers/mtd/mtdpart.c |
15773 |
++++ b/drivers/mtd/mtdpart.c |
15774 |
+@@ -312,7 +312,7 @@ static int __mtd_del_partition(struct mtd_info *mtd) |
15775 |
+ if (err) |
15776 |
+ return err; |
15777 |
+ |
15778 |
+- list_del(&child->part.node); |
15779 |
++ list_del(&mtd->part.node); |
15780 |
+ free_partition(mtd); |
15781 |
+ |
15782 |
+ return 0; |
15783 |
+diff --git a/drivers/mtd/nand/raw/davinci_nand.c b/drivers/mtd/nand/raw/davinci_nand.c |
15784 |
+index 118da9944e3bc..45fec8c192aba 100644 |
15785 |
+--- a/drivers/mtd/nand/raw/davinci_nand.c |
15786 |
++++ b/drivers/mtd/nand/raw/davinci_nand.c |
15787 |
+@@ -371,77 +371,6 @@ correct: |
15788 |
+ return corrected; |
15789 |
+ } |
15790 |
+ |
15791 |
+-/** |
15792 |
+- * nand_read_page_hwecc_oob_first - hw ecc, read oob first |
15793 |
+- * @chip: nand chip info structure |
15794 |
+- * @buf: buffer to store read data |
15795 |
+- * @oob_required: caller requires OOB data read to chip->oob_poi |
15796 |
+- * @page: page number to read |
15797 |
+- * |
15798 |
+- * Hardware ECC for large page chips, require OOB to be read first. For this |
15799 |
+- * ECC mode, the write_page method is re-used from ECC_HW. These methods |
15800 |
+- * read/write ECC from the OOB area, unlike the ECC_HW_SYNDROME support with |
15801 |
+- * multiple ECC steps, follows the "infix ECC" scheme and reads/writes ECC from |
15802 |
+- * the data area, by overwriting the NAND manufacturer bad block markings. |
15803 |
+- */ |
15804 |
+-static int nand_davinci_read_page_hwecc_oob_first(struct nand_chip *chip, |
15805 |
+- uint8_t *buf, |
15806 |
+- int oob_required, int page) |
15807 |
+-{ |
15808 |
+- struct mtd_info *mtd = nand_to_mtd(chip); |
15809 |
+- int i, eccsize = chip->ecc.size, ret; |
15810 |
+- int eccbytes = chip->ecc.bytes; |
15811 |
+- int eccsteps = chip->ecc.steps; |
15812 |
+- uint8_t *p = buf; |
15813 |
+- uint8_t *ecc_code = chip->ecc.code_buf; |
15814 |
+- uint8_t *ecc_calc = chip->ecc.calc_buf; |
15815 |
+- unsigned int max_bitflips = 0; |
15816 |
+- |
15817 |
+- /* Read the OOB area first */ |
15818 |
+- ret = nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize); |
15819 |
+- if (ret) |
15820 |
+- return ret; |
15821 |
+- |
15822 |
+- ret = nand_read_page_op(chip, page, 0, NULL, 0); |
15823 |
+- if (ret) |
15824 |
+- return ret; |
15825 |
+- |
15826 |
+- ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0, |
15827 |
+- chip->ecc.total); |
15828 |
+- if (ret) |
15829 |
+- return ret; |
15830 |
+- |
15831 |
+- for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { |
15832 |
+- int stat; |
15833 |
+- |
15834 |
+- chip->ecc.hwctl(chip, NAND_ECC_READ); |
15835 |
+- |
15836 |
+- ret = nand_read_data_op(chip, p, eccsize, false, false); |
15837 |
+- if (ret) |
15838 |
+- return ret; |
15839 |
+- |
15840 |
+- chip->ecc.calculate(chip, p, &ecc_calc[i]); |
15841 |
+- |
15842 |
+- stat = chip->ecc.correct(chip, p, &ecc_code[i], NULL); |
15843 |
+- if (stat == -EBADMSG && |
15844 |
+- (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { |
15845 |
+- /* check for empty pages with bitflips */ |
15846 |
+- stat = nand_check_erased_ecc_chunk(p, eccsize, |
15847 |
+- &ecc_code[i], |
15848 |
+- eccbytes, NULL, 0, |
15849 |
+- chip->ecc.strength); |
15850 |
+- } |
15851 |
+- |
15852 |
+- if (stat < 0) { |
15853 |
+- mtd->ecc_stats.failed++; |
15854 |
+- } else { |
15855 |
+- mtd->ecc_stats.corrected += stat; |
15856 |
+- max_bitflips = max_t(unsigned int, max_bitflips, stat); |
15857 |
+- } |
15858 |
+- } |
15859 |
+- return max_bitflips; |
15860 |
+-} |
15861 |
+- |
15862 |
+ /*----------------------------------------------------------------------*/ |
15863 |
+ |
15864 |
+ /* An ECC layout for using 4-bit ECC with small-page flash, storing |
15865 |
+@@ -651,7 +580,7 @@ static int davinci_nand_attach_chip(struct nand_chip *chip) |
15866 |
+ } else if (chunks == 4 || chunks == 8) { |
15867 |
+ mtd_set_ooblayout(mtd, |
15868 |
+ nand_get_large_page_ooblayout()); |
15869 |
+- chip->ecc.read_page = nand_davinci_read_page_hwecc_oob_first; |
15870 |
++ chip->ecc.read_page = nand_read_page_hwecc_oob_first; |
15871 |
+ } else { |
15872 |
+ return -EIO; |
15873 |
+ } |
15874 |
+diff --git a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c |
15875 |
+index 4d08e4ab5c1b6..6e9f7d80ef8b8 100644 |
15876 |
+--- a/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c |
15877 |
++++ b/drivers/mtd/nand/raw/gpmi-nand/gpmi-nand.c |
15878 |
+@@ -713,14 +713,32 @@ static void gpmi_nfc_compute_timings(struct gpmi_nand_data *this, |
15879 |
+ (use_half_period ? BM_GPMI_CTRL1_HALF_PERIOD : 0); |
15880 |
+ } |
15881 |
+ |
15882 |
+-static void gpmi_nfc_apply_timings(struct gpmi_nand_data *this) |
15883 |
++static int gpmi_nfc_apply_timings(struct gpmi_nand_data *this) |
15884 |
+ { |
15885 |
+ struct gpmi_nfc_hardware_timing *hw = &this->hw; |
15886 |
+ struct resources *r = &this->resources; |
15887 |
+ void __iomem *gpmi_regs = r->gpmi_regs; |
15888 |
+ unsigned int dll_wait_time_us; |
15889 |
++ int ret; |
15890 |
++ |
15891 |
++ /* Clock dividers do NOT guarantee a clean clock signal on its output |
15892 |
++ * during the change of the divide factor on i.MX6Q/UL/SX. On i.MX7/8, |
15893 |
++ * all clock dividers provide these guarantee. |
15894 |
++ */ |
15895 |
++ if (GPMI_IS_MX6Q(this) || GPMI_IS_MX6SX(this)) |
15896 |
++ clk_disable_unprepare(r->clock[0]); |
15897 |
+ |
15898 |
+- clk_set_rate(r->clock[0], hw->clk_rate); |
15899 |
++ ret = clk_set_rate(r->clock[0], hw->clk_rate); |
15900 |
++ if (ret) { |
15901 |
++ dev_err(this->dev, "cannot set clock rate to %lu Hz: %d\n", hw->clk_rate, ret); |
15902 |
++ return ret; |
15903 |
++ } |
15904 |
++ |
15905 |
++ if (GPMI_IS_MX6Q(this) || GPMI_IS_MX6SX(this)) { |
15906 |
++ ret = clk_prepare_enable(r->clock[0]); |
15907 |
++ if (ret) |
15908 |
++ return ret; |
15909 |
++ } |
15910 |
+ |
15911 |
+ writel(hw->timing0, gpmi_regs + HW_GPMI_TIMING0); |
15912 |
+ writel(hw->timing1, gpmi_regs + HW_GPMI_TIMING1); |
15913 |
+@@ -739,6 +757,8 @@ static void gpmi_nfc_apply_timings(struct gpmi_nand_data *this) |
15914 |
+ |
15915 |
+ /* Wait for the DLL to settle. */ |
15916 |
+ udelay(dll_wait_time_us); |
15917 |
++ |
15918 |
++ return 0; |
15919 |
+ } |
15920 |
+ |
15921 |
+ static int gpmi_setup_interface(struct nand_chip *chip, int chipnr, |
15922 |
+@@ -1034,15 +1054,6 @@ static int gpmi_get_clks(struct gpmi_nand_data *this) |
15923 |
+ r->clock[i] = clk; |
15924 |
+ } |
15925 |
+ |
15926 |
+- if (GPMI_IS_MX6(this)) |
15927 |
+- /* |
15928 |
+- * Set the default value for the gpmi clock. |
15929 |
+- * |
15930 |
+- * If you want to use the ONFI nand which is in the |
15931 |
+- * Synchronous Mode, you should change the clock as you need. |
15932 |
+- */ |
15933 |
+- clk_set_rate(r->clock[0], 22000000); |
15934 |
+- |
15935 |
+ return 0; |
15936 |
+ |
15937 |
+ err_clock: |
15938 |
+@@ -2280,7 +2291,9 @@ static int gpmi_nfc_exec_op(struct nand_chip *chip, |
15939 |
+ */ |
15940 |
+ if (this->hw.must_apply_timings) { |
15941 |
+ this->hw.must_apply_timings = false; |
15942 |
+- gpmi_nfc_apply_timings(this); |
15943 |
++ ret = gpmi_nfc_apply_timings(this); |
15944 |
++ if (ret) |
15945 |
++ return ret; |
15946 |
+ } |
15947 |
+ |
15948 |
+ dev_dbg(this->dev, "%s: %d instructions\n", __func__, op->ninstrs); |
15949 |
+diff --git a/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c b/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c |
15950 |
+index 0e9d426fe4f2b..b18861bdcdc88 100644 |
15951 |
+--- a/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c |
15952 |
++++ b/drivers/mtd/nand/raw/ingenic/ingenic_nand_drv.c |
15953 |
+@@ -32,6 +32,7 @@ struct jz_soc_info { |
15954 |
+ unsigned long addr_offset; |
15955 |
+ unsigned long cmd_offset; |
15956 |
+ const struct mtd_ooblayout_ops *oob_layout; |
15957 |
++ bool oob_first; |
15958 |
+ }; |
15959 |
+ |
15960 |
+ struct ingenic_nand_cs { |
15961 |
+@@ -240,6 +241,9 @@ static int ingenic_nand_attach_chip(struct nand_chip *chip) |
15962 |
+ if (chip->bbt_options & NAND_BBT_USE_FLASH) |
15963 |
+ chip->bbt_options |= NAND_BBT_NO_OOB; |
15964 |
+ |
15965 |
++ if (nfc->soc_info->oob_first) |
15966 |
++ chip->ecc.read_page = nand_read_page_hwecc_oob_first; |
15967 |
++ |
15968 |
+ /* For legacy reasons we use a different layout on the qi,lb60 board. */ |
15969 |
+ if (of_machine_is_compatible("qi,lb60")) |
15970 |
+ mtd_set_ooblayout(mtd, &qi_lb60_ooblayout_ops); |
15971 |
+@@ -534,6 +538,7 @@ static const struct jz_soc_info jz4740_soc_info = { |
15972 |
+ .data_offset = 0x00000000, |
15973 |
+ .cmd_offset = 0x00008000, |
15974 |
+ .addr_offset = 0x00010000, |
15975 |
++ .oob_first = true, |
15976 |
+ }; |
15977 |
+ |
15978 |
+ static const struct jz_soc_info jz4725b_soc_info = { |
15979 |
+diff --git a/drivers/mtd/nand/raw/nand_base.c b/drivers/mtd/nand/raw/nand_base.c |
15980 |
+index a130320de4128..d5a2110eb38ed 100644 |
15981 |
+--- a/drivers/mtd/nand/raw/nand_base.c |
15982 |
++++ b/drivers/mtd/nand/raw/nand_base.c |
15983 |
+@@ -3160,6 +3160,73 @@ static int nand_read_page_hwecc(struct nand_chip *chip, uint8_t *buf, |
15984 |
+ return max_bitflips; |
15985 |
+ } |
15986 |
+ |
15987 |
++/** |
15988 |
++ * nand_read_page_hwecc_oob_first - Hardware ECC page read with ECC |
15989 |
++ * data read from OOB area |
15990 |
++ * @chip: nand chip info structure |
15991 |
++ * @buf: buffer to store read data |
15992 |
++ * @oob_required: caller requires OOB data read to chip->oob_poi |
15993 |
++ * @page: page number to read |
15994 |
++ * |
15995 |
++ * Hardware ECC for large page chips, which requires the ECC data to be |
15996 |
++ * extracted from the OOB before the actual data is read. |
15997 |
++ */ |
15998 |
++int nand_read_page_hwecc_oob_first(struct nand_chip *chip, uint8_t *buf, |
15999 |
++ int oob_required, int page) |
16000 |
++{ |
16001 |
++ struct mtd_info *mtd = nand_to_mtd(chip); |
16002 |
++ int i, eccsize = chip->ecc.size, ret; |
16003 |
++ int eccbytes = chip->ecc.bytes; |
16004 |
++ int eccsteps = chip->ecc.steps; |
16005 |
++ uint8_t *p = buf; |
16006 |
++ uint8_t *ecc_code = chip->ecc.code_buf; |
16007 |
++ unsigned int max_bitflips = 0; |
16008 |
++ |
16009 |
++ /* Read the OOB area first */ |
16010 |
++ ret = nand_read_oob_op(chip, page, 0, chip->oob_poi, mtd->oobsize); |
16011 |
++ if (ret) |
16012 |
++ return ret; |
16013 |
++ |
16014 |
++ /* Move read cursor to start of page */ |
16015 |
++ ret = nand_change_read_column_op(chip, 0, NULL, 0, false); |
16016 |
++ if (ret) |
16017 |
++ return ret; |
16018 |
++ |
16019 |
++ ret = mtd_ooblayout_get_eccbytes(mtd, ecc_code, chip->oob_poi, 0, |
16020 |
++ chip->ecc.total); |
16021 |
++ if (ret) |
16022 |
++ return ret; |
16023 |
++ |
16024 |
++ for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) { |
16025 |
++ int stat; |
16026 |
++ |
16027 |
++ chip->ecc.hwctl(chip, NAND_ECC_READ); |
16028 |
++ |
16029 |
++ ret = nand_read_data_op(chip, p, eccsize, false, false); |
16030 |
++ if (ret) |
16031 |
++ return ret; |
16032 |
++ |
16033 |
++ stat = chip->ecc.correct(chip, p, &ecc_code[i], NULL); |
16034 |
++ if (stat == -EBADMSG && |
16035 |
++ (chip->ecc.options & NAND_ECC_GENERIC_ERASED_CHECK)) { |
16036 |
++ /* check for empty pages with bitflips */ |
16037 |
++ stat = nand_check_erased_ecc_chunk(p, eccsize, |
16038 |
++ &ecc_code[i], |
16039 |
++ eccbytes, NULL, 0, |
16040 |
++ chip->ecc.strength); |
16041 |
++ } |
16042 |
++ |
16043 |
++ if (stat < 0) { |
16044 |
++ mtd->ecc_stats.failed++; |
16045 |
++ } else { |
16046 |
++ mtd->ecc_stats.corrected += stat; |
16047 |
++ max_bitflips = max_t(unsigned int, max_bitflips, stat); |
16048 |
++ } |
16049 |
++ } |
16050 |
++ return max_bitflips; |
16051 |
++} |
16052 |
++EXPORT_SYMBOL_GPL(nand_read_page_hwecc_oob_first); |
16053 |
++ |
16054 |
+ /** |
16055 |
+ * nand_read_page_syndrome - [REPLACEABLE] hardware ECC syndrome based page read |
16056 |
+ * @chip: nand chip info structure |
16057 |
+diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c |
16058 |
+index 77dc79a7f5748..83cdaabd7b69d 100644 |
16059 |
+--- a/drivers/net/bonding/bond_main.c |
16060 |
++++ b/drivers/net/bonding/bond_main.c |
16061 |
+@@ -1096,9 +1096,6 @@ static bool bond_should_notify_peers(struct bonding *bond) |
16062 |
+ slave = rcu_dereference(bond->curr_active_slave); |
16063 |
+ rcu_read_unlock(); |
16064 |
+ |
16065 |
+- netdev_dbg(bond->dev, "bond_should_notify_peers: slave %s\n", |
16066 |
+- slave ? slave->dev->name : "NULL"); |
16067 |
+- |
16068 |
+ if (!slave || !bond->send_peer_notif || |
16069 |
+ bond->send_peer_notif % |
16070 |
+ max(1, bond->params.peer_notif_delay) != 0 || |
16071 |
+@@ -1106,6 +1103,9 @@ static bool bond_should_notify_peers(struct bonding *bond) |
16072 |
+ test_bit(__LINK_STATE_LINKWATCH_PENDING, &slave->dev->state)) |
16073 |
+ return false; |
16074 |
+ |
16075 |
++ netdev_dbg(bond->dev, "bond_should_notify_peers: slave %s\n", |
16076 |
++ slave ? slave->dev->name : "NULL"); |
16077 |
++ |
16078 |
+ return true; |
16079 |
+ } |
16080 |
+ |
16081 |
+@@ -3872,8 +3872,8 @@ u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb) |
16082 |
+ skb->l4_hash) |
16083 |
+ return skb->hash; |
16084 |
+ |
16085 |
+- return __bond_xmit_hash(bond, skb, skb->head, skb->protocol, |
16086 |
+- skb->mac_header, skb->network_header, |
16087 |
++ return __bond_xmit_hash(bond, skb, skb->data, skb->protocol, |
16088 |
++ skb_mac_offset(skb), skb_network_offset(skb), |
16089 |
+ skb_headlen(skb)); |
16090 |
+ } |
16091 |
+ |
16092 |
+@@ -4843,25 +4843,39 @@ static netdev_tx_t bond_xmit_broadcast(struct sk_buff *skb, |
16093 |
+ struct bonding *bond = netdev_priv(bond_dev); |
16094 |
+ struct slave *slave = NULL; |
16095 |
+ struct list_head *iter; |
16096 |
++ bool xmit_suc = false; |
16097 |
++ bool skb_used = false; |
16098 |
+ |
16099 |
+ bond_for_each_slave_rcu(bond, slave, iter) { |
16100 |
+- if (bond_is_last_slave(bond, slave)) |
16101 |
+- break; |
16102 |
+- if (bond_slave_is_up(slave) && slave->link == BOND_LINK_UP) { |
16103 |
+- struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC); |
16104 |
++ struct sk_buff *skb2; |
16105 |
++ |
16106 |
++ if (!(bond_slave_is_up(slave) && slave->link == BOND_LINK_UP)) |
16107 |
++ continue; |
16108 |
+ |
16109 |
++ if (bond_is_last_slave(bond, slave)) { |
16110 |
++ skb2 = skb; |
16111 |
++ skb_used = true; |
16112 |
++ } else { |
16113 |
++ skb2 = skb_clone(skb, GFP_ATOMIC); |
16114 |
+ if (!skb2) { |
16115 |
+ net_err_ratelimited("%s: Error: %s: skb_clone() failed\n", |
16116 |
+ bond_dev->name, __func__); |
16117 |
+ continue; |
16118 |
+ } |
16119 |
+- bond_dev_queue_xmit(bond, skb2, slave->dev); |
16120 |
+ } |
16121 |
++ |
16122 |
++ if (bond_dev_queue_xmit(bond, skb2, slave->dev) == NETDEV_TX_OK) |
16123 |
++ xmit_suc = true; |
16124 |
+ } |
16125 |
+- if (slave && bond_slave_is_up(slave) && slave->link == BOND_LINK_UP) |
16126 |
+- return bond_dev_queue_xmit(bond, skb, slave->dev); |
16127 |
+ |
16128 |
+- return bond_tx_drop(bond_dev, skb); |
16129 |
++ if (!skb_used) |
16130 |
++ dev_kfree_skb_any(skb); |
16131 |
++ |
16132 |
++ if (xmit_suc) |
16133 |
++ return NETDEV_TX_OK; |
16134 |
++ |
16135 |
++ atomic_long_inc(&bond_dev->tx_dropped); |
16136 |
++ return NET_XMIT_DROP; |
16137 |
+ } |
16138 |
+ |
16139 |
+ /*------------------------- Device initialization ---------------------------*/ |
16140 |
+diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c |
16141 |
+index 7734229aa0788..18d7bb99ec1bd 100644 |
16142 |
+--- a/drivers/net/can/flexcan.c |
16143 |
++++ b/drivers/net/can/flexcan.c |
16144 |
+@@ -173,9 +173,9 @@ |
16145 |
+ |
16146 |
+ /* FLEXCAN interrupt flag register (IFLAG) bits */ |
16147 |
+ /* Errata ERR005829 step7: Reserve first valid MB */ |
16148 |
+-#define FLEXCAN_TX_MB_RESERVED_OFF_FIFO 8 |
16149 |
+-#define FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP 0 |
16150 |
+-#define FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST (FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP + 1) |
16151 |
++#define FLEXCAN_TX_MB_RESERVED_RX_FIFO 8 |
16152 |
++#define FLEXCAN_TX_MB_RESERVED_RX_MAILBOX 0 |
16153 |
++#define FLEXCAN_RX_MB_RX_MAILBOX_FIRST (FLEXCAN_TX_MB_RESERVED_RX_MAILBOX + 1) |
16154 |
+ #define FLEXCAN_IFLAG_MB(x) BIT_ULL(x) |
16155 |
+ #define FLEXCAN_IFLAG_RX_FIFO_OVERFLOW BIT(7) |
16156 |
+ #define FLEXCAN_IFLAG_RX_FIFO_WARN BIT(6) |
16157 |
+@@ -234,8 +234,8 @@ |
16158 |
+ #define FLEXCAN_QUIRK_ENABLE_EACEN_RRS BIT(3) |
16159 |
+ /* Disable non-correctable errors interrupt and freeze mode */ |
16160 |
+ #define FLEXCAN_QUIRK_DISABLE_MECR BIT(4) |
16161 |
+-/* Use timestamp based offloading */ |
16162 |
+-#define FLEXCAN_QUIRK_USE_OFF_TIMESTAMP BIT(5) |
16163 |
++/* Use mailboxes (not FIFO) for RX path */ |
16164 |
++#define FLEXCAN_QUIRK_USE_RX_MAILBOX BIT(5) |
16165 |
+ /* No interrupt for error passive */ |
16166 |
+ #define FLEXCAN_QUIRK_BROKEN_PERR_STATE BIT(6) |
16167 |
+ /* default to BE register access */ |
16168 |
+@@ -252,6 +252,12 @@ |
16169 |
+ #define FLEXCAN_QUIRK_NR_IRQ_3 BIT(12) |
16170 |
+ /* Setup 16 mailboxes */ |
16171 |
+ #define FLEXCAN_QUIRK_NR_MB_16 BIT(13) |
16172 |
++/* Device supports RX via mailboxes */ |
16173 |
++#define FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX BIT(14) |
16174 |
++/* Device supports RTR reception via mailboxes */ |
16175 |
++#define FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX_RTR BIT(15) |
16176 |
++/* Device supports RX via FIFO */ |
16177 |
++#define FLEXCAN_QUIRK_SUPPPORT_RX_FIFO BIT(16) |
16178 |
+ |
16179 |
+ /* Structure of the message buffer */ |
16180 |
+ struct flexcan_mb { |
16181 |
+@@ -365,7 +371,7 @@ struct flexcan_priv { |
16182 |
+ |
16183 |
+ struct clk *clk_ipg; |
16184 |
+ struct clk *clk_per; |
16185 |
+- const struct flexcan_devtype_data *devtype_data; |
16186 |
++ struct flexcan_devtype_data devtype_data; |
16187 |
+ struct regulator *reg_xceiver; |
16188 |
+ struct flexcan_stop_mode stm; |
16189 |
+ |
16190 |
+@@ -382,59 +388,78 @@ struct flexcan_priv { |
16191 |
+ |
16192 |
+ static const struct flexcan_devtype_data fsl_mcf5441x_devtype_data = { |
16193 |
+ .quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE | |
16194 |
+- FLEXCAN_QUIRK_NR_IRQ_3 | FLEXCAN_QUIRK_NR_MB_16, |
16195 |
++ FLEXCAN_QUIRK_NR_IRQ_3 | FLEXCAN_QUIRK_NR_MB_16 | |
16196 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_FIFO, |
16197 |
+ }; |
16198 |
+ |
16199 |
+ static const struct flexcan_devtype_data fsl_p1010_devtype_data = { |
16200 |
+ .quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE | |
16201 |
+ FLEXCAN_QUIRK_BROKEN_PERR_STATE | |
16202 |
+- FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN, |
16203 |
++ FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN | |
16204 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX | |
16205 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_FIFO, |
16206 |
+ }; |
16207 |
+ |
16208 |
+ static const struct flexcan_devtype_data fsl_imx25_devtype_data = { |
16209 |
+ .quirks = FLEXCAN_QUIRK_BROKEN_WERR_STATE | |
16210 |
+- FLEXCAN_QUIRK_BROKEN_PERR_STATE, |
16211 |
++ FLEXCAN_QUIRK_BROKEN_PERR_STATE | |
16212 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX | |
16213 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_FIFO, |
16214 |
+ }; |
16215 |
+ |
16216 |
+ static const struct flexcan_devtype_data fsl_imx28_devtype_data = { |
16217 |
+- .quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE, |
16218 |
++ .quirks = FLEXCAN_QUIRK_BROKEN_PERR_STATE | |
16219 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX | |
16220 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_FIFO, |
16221 |
+ }; |
16222 |
+ |
16223 |
+ static const struct flexcan_devtype_data fsl_imx6q_devtype_data = { |
16224 |
+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
16225 |
+- FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE | |
16226 |
+- FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR, |
16227 |
++ FLEXCAN_QUIRK_USE_RX_MAILBOX | FLEXCAN_QUIRK_BROKEN_PERR_STATE | |
16228 |
++ FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR | |
16229 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX | |
16230 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX_RTR, |
16231 |
+ }; |
16232 |
+ |
16233 |
+ static const struct flexcan_devtype_data fsl_imx8qm_devtype_data = { |
16234 |
+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
16235 |
+- FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_BROKEN_PERR_STATE | |
16236 |
+- FLEXCAN_QUIRK_SUPPORT_FD | FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW, |
16237 |
++ FLEXCAN_QUIRK_USE_RX_MAILBOX | FLEXCAN_QUIRK_BROKEN_PERR_STATE | |
16238 |
++ FLEXCAN_QUIRK_SUPPORT_FD | FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW | |
16239 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX | |
16240 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX_RTR, |
16241 |
+ }; |
16242 |
+ |
16243 |
+ static struct flexcan_devtype_data fsl_imx8mp_devtype_data = { |
16244 |
+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
16245 |
+- FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | |
16246 |
++ FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_RX_MAILBOX | |
16247 |
+ FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR | |
16248 |
+- FLEXCAN_QUIRK_SUPPORT_FD | FLEXCAN_QUIRK_SUPPORT_ECC, |
16249 |
++ FLEXCAN_QUIRK_SUPPORT_FD | FLEXCAN_QUIRK_SUPPORT_ECC | |
16250 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX | |
16251 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX_RTR, |
16252 |
+ }; |
16253 |
+ |
16254 |
+ static const struct flexcan_devtype_data fsl_vf610_devtype_data = { |
16255 |
+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
16256 |
+- FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | |
16257 |
+- FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SUPPORT_ECC, |
16258 |
++ FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_USE_RX_MAILBOX | |
16259 |
++ FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_SUPPORT_ECC | |
16260 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX | |
16261 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX_RTR, |
16262 |
+ }; |
16263 |
+ |
16264 |
+ static const struct flexcan_devtype_data fsl_ls1021a_r2_devtype_data = { |
16265 |
+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
16266 |
+- FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_USE_OFF_TIMESTAMP, |
16267 |
++ FLEXCAN_QUIRK_BROKEN_PERR_STATE | FLEXCAN_QUIRK_USE_RX_MAILBOX | |
16268 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX | |
16269 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX_RTR, |
16270 |
+ }; |
16271 |
+ |
16272 |
+ static const struct flexcan_devtype_data fsl_lx2160a_r1_devtype_data = { |
16273 |
+ .quirks = FLEXCAN_QUIRK_DISABLE_RXFG | FLEXCAN_QUIRK_ENABLE_EACEN_RRS | |
16274 |
+ FLEXCAN_QUIRK_DISABLE_MECR | FLEXCAN_QUIRK_BROKEN_PERR_STATE | |
16275 |
+- FLEXCAN_QUIRK_USE_OFF_TIMESTAMP | FLEXCAN_QUIRK_SUPPORT_FD | |
16276 |
+- FLEXCAN_QUIRK_SUPPORT_ECC, |
16277 |
++ FLEXCAN_QUIRK_USE_RX_MAILBOX | FLEXCAN_QUIRK_SUPPORT_FD | |
16278 |
++ FLEXCAN_QUIRK_SUPPORT_ECC | |
16279 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX | |
16280 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX_RTR, |
16281 |
+ }; |
16282 |
+ |
16283 |
+ static const struct can_bittiming_const flexcan_bittiming_const = { |
16284 |
+@@ -596,7 +621,7 @@ static inline int flexcan_enter_stop_mode(struct flexcan_priv *priv) |
16285 |
+ priv->write(reg_mcr, ®s->mcr); |
16286 |
+ |
16287 |
+ /* enable stop request */ |
16288 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW) { |
16289 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW) { |
16290 |
+ ret = flexcan_stop_mode_enable_scfw(priv, true); |
16291 |
+ if (ret < 0) |
16292 |
+ return ret; |
16293 |
+@@ -615,7 +640,7 @@ static inline int flexcan_exit_stop_mode(struct flexcan_priv *priv) |
16294 |
+ int ret; |
16295 |
+ |
16296 |
+ /* remove stop request */ |
16297 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW) { |
16298 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW) { |
16299 |
+ ret = flexcan_stop_mode_enable_scfw(priv, false); |
16300 |
+ if (ret < 0) |
16301 |
+ return ret; |
16302 |
+@@ -1018,7 +1043,7 @@ static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload, |
16303 |
+ |
16304 |
+ mb = flexcan_get_mb(priv, n); |
16305 |
+ |
16306 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
16307 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) { |
16308 |
+ u32 code; |
16309 |
+ |
16310 |
+ do { |
16311 |
+@@ -1083,7 +1108,7 @@ static struct sk_buff *flexcan_mailbox_read(struct can_rx_offload *offload, |
16312 |
+ } |
16313 |
+ |
16314 |
+ mark_as_read: |
16315 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) |
16316 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) |
16317 |
+ flexcan_write64(priv, FLEXCAN_IFLAG_MB(n), ®s->iflag1); |
16318 |
+ else |
16319 |
+ priv->write(FLEXCAN_IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1); |
16320 |
+@@ -1109,7 +1134,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) |
16321 |
+ enum can_state last_state = priv->can.state; |
16322 |
+ |
16323 |
+ /* reception interrupt */ |
16324 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
16325 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) { |
16326 |
+ u64 reg_iflag_rx; |
16327 |
+ int ret; |
16328 |
+ |
16329 |
+@@ -1169,7 +1194,7 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) |
16330 |
+ |
16331 |
+ /* state change interrupt or broken error state quirk fix is enabled */ |
16332 |
+ if ((reg_esr & FLEXCAN_ESR_ERR_STATE) || |
16333 |
+- (priv->devtype_data->quirks & (FLEXCAN_QUIRK_BROKEN_WERR_STATE | |
16334 |
++ (priv->devtype_data.quirks & (FLEXCAN_QUIRK_BROKEN_WERR_STATE | |
16335 |
+ FLEXCAN_QUIRK_BROKEN_PERR_STATE))) |
16336 |
+ flexcan_irq_state(dev, reg_esr); |
16337 |
+ |
16338 |
+@@ -1191,11 +1216,11 @@ static irqreturn_t flexcan_irq(int irq, void *dev_id) |
16339 |
+ * (1): enabled if FLEXCAN_QUIRK_BROKEN_WERR_STATE is enabled |
16340 |
+ */ |
16341 |
+ if ((last_state != priv->can.state) && |
16342 |
+- (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_PERR_STATE) && |
16343 |
++ (priv->devtype_data.quirks & FLEXCAN_QUIRK_BROKEN_PERR_STATE) && |
16344 |
+ !(priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING)) { |
16345 |
+ switch (priv->can.state) { |
16346 |
+ case CAN_STATE_ERROR_ACTIVE: |
16347 |
+- if (priv->devtype_data->quirks & |
16348 |
++ if (priv->devtype_data.quirks & |
16349 |
+ FLEXCAN_QUIRK_BROKEN_WERR_STATE) |
16350 |
+ flexcan_error_irq_enable(priv); |
16351 |
+ else |
16352 |
+@@ -1423,26 +1448,26 @@ static int flexcan_rx_offload_setup(struct net_device *dev) |
16353 |
+ else |
16354 |
+ priv->mb_size = sizeof(struct flexcan_mb) + CAN_MAX_DLEN; |
16355 |
+ |
16356 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_NR_MB_16) |
16357 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_MB_16) |
16358 |
+ priv->mb_count = 16; |
16359 |
+ else |
16360 |
+ priv->mb_count = (sizeof(priv->regs->mb[0]) / priv->mb_size) + |
16361 |
+ (sizeof(priv->regs->mb[1]) / priv->mb_size); |
16362 |
+ |
16363 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) |
16364 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) |
16365 |
+ priv->tx_mb_reserved = |
16366 |
+- flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_TIMESTAMP); |
16367 |
++ flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_RX_MAILBOX); |
16368 |
+ else |
16369 |
+ priv->tx_mb_reserved = |
16370 |
+- flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_OFF_FIFO); |
16371 |
++ flexcan_get_mb(priv, FLEXCAN_TX_MB_RESERVED_RX_FIFO); |
16372 |
+ priv->tx_mb_idx = priv->mb_count - 1; |
16373 |
+ priv->tx_mb = flexcan_get_mb(priv, priv->tx_mb_idx); |
16374 |
+ priv->tx_mask = FLEXCAN_IFLAG_MB(priv->tx_mb_idx); |
16375 |
+ |
16376 |
+ priv->offload.mailbox_read = flexcan_mailbox_read; |
16377 |
+ |
16378 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
16379 |
+- priv->offload.mb_first = FLEXCAN_RX_MB_OFF_TIMESTAMP_FIRST; |
16380 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) { |
16381 |
++ priv->offload.mb_first = FLEXCAN_RX_MB_RX_MAILBOX_FIRST; |
16382 |
+ priv->offload.mb_last = priv->mb_count - 2; |
16383 |
+ |
16384 |
+ priv->rx_mask = GENMASK_ULL(priv->offload.mb_last, |
16385 |
+@@ -1506,7 +1531,7 @@ static int flexcan_chip_start(struct net_device *dev) |
16386 |
+ if (err) |
16387 |
+ goto out_chip_disable; |
16388 |
+ |
16389 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SUPPORT_ECC) |
16390 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SUPPORT_ECC) |
16391 |
+ flexcan_ram_init(dev); |
16392 |
+ |
16393 |
+ flexcan_set_bittiming(dev); |
16394 |
+@@ -1532,10 +1557,10 @@ static int flexcan_chip_start(struct net_device *dev) |
16395 |
+ /* MCR |
16396 |
+ * |
16397 |
+ * FIFO: |
16398 |
+- * - disable for timestamp mode |
16399 |
++ * - disable for mailbox mode |
16400 |
+ * - enable for FIFO mode |
16401 |
+ */ |
16402 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) |
16403 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) |
16404 |
+ reg_mcr &= ~FLEXCAN_MCR_FEN; |
16405 |
+ else |
16406 |
+ reg_mcr |= FLEXCAN_MCR_FEN; |
16407 |
+@@ -1586,7 +1611,7 @@ static int flexcan_chip_start(struct net_device *dev) |
16408 |
+ * on most Flexcan cores, too. Otherwise we don't get |
16409 |
+ * any error warning or passive interrupts. |
16410 |
+ */ |
16411 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_BROKEN_WERR_STATE || |
16412 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_BROKEN_WERR_STATE || |
16413 |
+ priv->can.ctrlmode & CAN_CTRLMODE_BERR_REPORTING) |
16414 |
+ reg_ctrl |= FLEXCAN_CTRL_ERR_MSK; |
16415 |
+ else |
16416 |
+@@ -1599,7 +1624,7 @@ static int flexcan_chip_start(struct net_device *dev) |
16417 |
+ netdev_dbg(dev, "%s: writing ctrl=0x%08x", __func__, reg_ctrl); |
16418 |
+ priv->write(reg_ctrl, ®s->ctrl); |
16419 |
+ |
16420 |
+- if ((priv->devtype_data->quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) { |
16421 |
++ if ((priv->devtype_data.quirks & FLEXCAN_QUIRK_ENABLE_EACEN_RRS)) { |
16422 |
+ reg_ctrl2 = priv->read(®s->ctrl2); |
16423 |
+ reg_ctrl2 |= FLEXCAN_CTRL2_EACEN | FLEXCAN_CTRL2_RRS; |
16424 |
+ priv->write(reg_ctrl2, ®s->ctrl2); |
16425 |
+@@ -1631,7 +1656,7 @@ static int flexcan_chip_start(struct net_device *dev) |
16426 |
+ priv->write(reg_fdctrl, ®s->fdctrl); |
16427 |
+ } |
16428 |
+ |
16429 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP) { |
16430 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_USE_RX_MAILBOX) { |
16431 |
+ for (i = priv->offload.mb_first; i <= priv->offload.mb_last; i++) { |
16432 |
+ mb = flexcan_get_mb(priv, i); |
16433 |
+ priv->write(FLEXCAN_MB_CODE_RX_EMPTY, |
16434 |
+@@ -1639,7 +1664,7 @@ static int flexcan_chip_start(struct net_device *dev) |
16435 |
+ } |
16436 |
+ } else { |
16437 |
+ /* clear and invalidate unused mailboxes first */ |
16438 |
+- for (i = FLEXCAN_TX_MB_RESERVED_OFF_FIFO; i < priv->mb_count; i++) { |
16439 |
++ for (i = FLEXCAN_TX_MB_RESERVED_RX_FIFO; i < priv->mb_count; i++) { |
16440 |
+ mb = flexcan_get_mb(priv, i); |
16441 |
+ priv->write(FLEXCAN_MB_CODE_RX_INACTIVE, |
16442 |
+ &mb->can_ctrl); |
16443 |
+@@ -1659,7 +1684,7 @@ static int flexcan_chip_start(struct net_device *dev) |
16444 |
+ priv->write(0x0, ®s->rx14mask); |
16445 |
+ priv->write(0x0, ®s->rx15mask); |
16446 |
+ |
16447 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_RXFG) |
16448 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_DISABLE_RXFG) |
16449 |
+ priv->write(0x0, ®s->rxfgmask); |
16450 |
+ |
16451 |
+ /* clear acceptance filters */ |
16452 |
+@@ -1673,7 +1698,7 @@ static int flexcan_chip_start(struct net_device *dev) |
16453 |
+ * This also works around errata e5295 which generates false |
16454 |
+ * positive memory errors and put the device in freeze mode. |
16455 |
+ */ |
16456 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_DISABLE_MECR) { |
16457 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_DISABLE_MECR) { |
16458 |
+ /* Follow the protocol as described in "Detection |
16459 |
+ * and Correction of Memory Errors" to write to |
16460 |
+ * MECR register (step 1 - 5) |
16461 |
+@@ -1799,7 +1824,7 @@ static int flexcan_open(struct net_device *dev) |
16462 |
+ if (err) |
16463 |
+ goto out_can_rx_offload_disable; |
16464 |
+ |
16465 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_NR_IRQ_3) { |
16466 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_IRQ_3) { |
16467 |
+ err = request_irq(priv->irq_boff, |
16468 |
+ flexcan_irq, IRQF_SHARED, dev->name, dev); |
16469 |
+ if (err) |
16470 |
+@@ -1845,7 +1870,7 @@ static int flexcan_close(struct net_device *dev) |
16471 |
+ netif_stop_queue(dev); |
16472 |
+ flexcan_chip_interrupts_disable(dev); |
16473 |
+ |
16474 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_NR_IRQ_3) { |
16475 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_IRQ_3) { |
16476 |
+ free_irq(priv->irq_err, dev); |
16477 |
+ free_irq(priv->irq_boff, dev); |
16478 |
+ } |
16479 |
+@@ -2051,9 +2076,9 @@ static int flexcan_setup_stop_mode(struct platform_device *pdev) |
16480 |
+ |
16481 |
+ priv = netdev_priv(dev); |
16482 |
+ |
16483 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW) |
16484 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_SCFW) |
16485 |
+ ret = flexcan_setup_stop_mode_scfw(pdev); |
16486 |
+- else if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR) |
16487 |
++ else if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SETUP_STOP_MODE_GPR) |
16488 |
+ ret = flexcan_setup_stop_mode_gpr(pdev); |
16489 |
+ else |
16490 |
+ /* return 0 directly if doesn't support stop mode feature */ |
16491 |
+@@ -2164,8 +2189,25 @@ static int flexcan_probe(struct platform_device *pdev) |
16492 |
+ return -ENODEV; |
16493 |
+ |
16494 |
+ if ((devtype_data->quirks & FLEXCAN_QUIRK_SUPPORT_FD) && |
16495 |
+- !(devtype_data->quirks & FLEXCAN_QUIRK_USE_OFF_TIMESTAMP)) { |
16496 |
+- dev_err(&pdev->dev, "CAN-FD mode doesn't work with FIFO mode!\n"); |
16497 |
++ !((devtype_data->quirks & |
16498 |
++ (FLEXCAN_QUIRK_USE_RX_MAILBOX | |
16499 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX | |
16500 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX_RTR | |
16501 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_FIFO)) == |
16502 |
++ (FLEXCAN_QUIRK_USE_RX_MAILBOX | |
16503 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX | |
16504 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX_RTR))) { |
16505 |
++ dev_err(&pdev->dev, "CAN-FD mode doesn't work in RX-FIFO mode!\n"); |
16506 |
++ return -EINVAL; |
16507 |
++ } |
16508 |
++ |
16509 |
++ if ((devtype_data->quirks & |
16510 |
++ (FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX | |
16511 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX_RTR)) == |
16512 |
++ FLEXCAN_QUIRK_SUPPPORT_RX_MAILBOX_RTR) { |
16513 |
++ dev_err(&pdev->dev, |
16514 |
++ "Quirks (0x%08x) inconsistent: RX_MAILBOX_RX supported but not RX_MAILBOX\n", |
16515 |
++ devtype_data->quirks); |
16516 |
+ return -EINVAL; |
16517 |
+ } |
16518 |
+ |
16519 |
+@@ -2181,9 +2223,10 @@ static int flexcan_probe(struct platform_device *pdev) |
16520 |
+ dev->flags |= IFF_ECHO; |
16521 |
+ |
16522 |
+ priv = netdev_priv(dev); |
16523 |
++ priv->devtype_data = *devtype_data; |
16524 |
+ |
16525 |
+ if (of_property_read_bool(pdev->dev.of_node, "big-endian") || |
16526 |
+- devtype_data->quirks & FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN) { |
16527 |
++ priv->devtype_data.quirks & FLEXCAN_QUIRK_DEFAULT_BIG_ENDIAN) { |
16528 |
+ priv->read = flexcan_read_be; |
16529 |
+ priv->write = flexcan_write_be; |
16530 |
+ } else { |
16531 |
+@@ -2202,10 +2245,9 @@ static int flexcan_probe(struct platform_device *pdev) |
16532 |
+ priv->clk_ipg = clk_ipg; |
16533 |
+ priv->clk_per = clk_per; |
16534 |
+ priv->clk_src = clk_src; |
16535 |
+- priv->devtype_data = devtype_data; |
16536 |
+ priv->reg_xceiver = reg_xceiver; |
16537 |
+ |
16538 |
+- if (devtype_data->quirks & FLEXCAN_QUIRK_NR_IRQ_3) { |
16539 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_NR_IRQ_3) { |
16540 |
+ priv->irq_boff = platform_get_irq(pdev, 1); |
16541 |
+ if (priv->irq_boff <= 0) { |
16542 |
+ err = -ENODEV; |
16543 |
+@@ -2218,7 +2260,7 @@ static int flexcan_probe(struct platform_device *pdev) |
16544 |
+ } |
16545 |
+ } |
16546 |
+ |
16547 |
+- if (priv->devtype_data->quirks & FLEXCAN_QUIRK_SUPPORT_FD) { |
16548 |
++ if (priv->devtype_data.quirks & FLEXCAN_QUIRK_SUPPORT_FD) { |
16549 |
+ priv->can.ctrlmode_supported |= CAN_CTRLMODE_FD | |
16550 |
+ CAN_CTRLMODE_FD_NON_ISO; |
16551 |
+ priv->can.bittiming_const = &flexcan_fd_bittiming_const; |
16552 |
+diff --git a/drivers/net/can/rcar/rcar_canfd.c b/drivers/net/can/rcar/rcar_canfd.c |
16553 |
+index ff9d0f5ae0dd2..388521e70837f 100644 |
16554 |
+--- a/drivers/net/can/rcar/rcar_canfd.c |
16555 |
++++ b/drivers/net/can/rcar/rcar_canfd.c |
16556 |
+@@ -1640,8 +1640,7 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, |
16557 |
+ ndev = alloc_candev(sizeof(*priv), RCANFD_FIFO_DEPTH); |
16558 |
+ if (!ndev) { |
16559 |
+ dev_err(&pdev->dev, "alloc_candev() failed\n"); |
16560 |
+- err = -ENOMEM; |
16561 |
+- goto fail; |
16562 |
++ return -ENOMEM; |
16563 |
+ } |
16564 |
+ priv = netdev_priv(ndev); |
16565 |
+ |
16566 |
+@@ -1735,8 +1734,8 @@ static int rcar_canfd_channel_probe(struct rcar_canfd_global *gpriv, u32 ch, |
16567 |
+ |
16568 |
+ fail_candev: |
16569 |
+ netif_napi_del(&priv->napi); |
16570 |
+- free_candev(ndev); |
16571 |
+ fail: |
16572 |
++ free_candev(ndev); |
16573 |
+ return err; |
16574 |
+ } |
16575 |
+ |
16576 |
+diff --git a/drivers/net/can/softing/softing_cs.c b/drivers/net/can/softing/softing_cs.c |
16577 |
+index 2e93ee7923739..e5c939b63fa65 100644 |
16578 |
+--- a/drivers/net/can/softing/softing_cs.c |
16579 |
++++ b/drivers/net/can/softing/softing_cs.c |
16580 |
+@@ -293,7 +293,7 @@ static int softingcs_probe(struct pcmcia_device *pcmcia) |
16581 |
+ return 0; |
16582 |
+ |
16583 |
+ platform_failed: |
16584 |
+- kfree(dev); |
16585 |
++ platform_device_put(pdev); |
16586 |
+ mem_failed: |
16587 |
+ pcmcia_bad: |
16588 |
+ pcmcia_failed: |
16589 |
+diff --git a/drivers/net/can/softing/softing_fw.c b/drivers/net/can/softing/softing_fw.c |
16590 |
+index 7e15368779931..32286f861a195 100644 |
16591 |
+--- a/drivers/net/can/softing/softing_fw.c |
16592 |
++++ b/drivers/net/can/softing/softing_fw.c |
16593 |
+@@ -565,18 +565,19 @@ int softing_startstop(struct net_device *dev, int up) |
16594 |
+ if (ret < 0) |
16595 |
+ goto failed; |
16596 |
+ } |
16597 |
+- /* enable_error_frame */ |
16598 |
+- /* |
16599 |
++ |
16600 |
++ /* enable_error_frame |
16601 |
++ * |
16602 |
+ * Error reporting is switched off at the moment since |
16603 |
+ * the receiving of them is not yet 100% verified |
16604 |
+ * This should be enabled sooner or later |
16605 |
+- * |
16606 |
+- if (error_reporting) { |
16607 |
++ */ |
16608 |
++ if (0 && error_reporting) { |
16609 |
+ ret = softing_fct_cmd(card, 51, "enable_error_frame"); |
16610 |
+ if (ret < 0) |
16611 |
+ goto failed; |
16612 |
+ } |
16613 |
+- */ |
16614 |
++ |
16615 |
+ /* initialize interface */ |
16616 |
+ iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 2]); |
16617 |
+ iowrite16(1, &card->dpram[DPRAM_FCT_PARAM + 4]); |
16618 |
+diff --git a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c |
16619 |
+index e16dc482f3270..9a4791d88683c 100644 |
16620 |
+--- a/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c |
16621 |
++++ b/drivers/net/can/spi/mcp251xfd/mcp251xfd-core.c |
16622 |
+@@ -1336,7 +1336,7 @@ mcp251xfd_tef_obj_read(const struct mcp251xfd_priv *priv, |
16623 |
+ len > tx_ring->obj_num || |
16624 |
+ offset + len > tx_ring->obj_num)) { |
16625 |
+ netdev_err(priv->ndev, |
16626 |
+- "Trying to read to many TEF objects (max=%d, offset=%d, len=%d).\n", |
16627 |
++ "Trying to read too many TEF objects (max=%d, offset=%d, len=%d).\n", |
16628 |
+ tx_ring->obj_num, offset, len); |
16629 |
+ return -ERANGE; |
16630 |
+ } |
16631 |
+@@ -2625,7 +2625,7 @@ static int mcp251xfd_register_chip_detect(struct mcp251xfd_priv *priv) |
16632 |
+ if (!mcp251xfd_is_251X(priv) && |
16633 |
+ priv->devtype_data.model != devtype_data->model) { |
16634 |
+ netdev_info(ndev, |
16635 |
+- "Detected %s, but firmware specifies a %s. Fixing up.", |
16636 |
++ "Detected %s, but firmware specifies a %s. Fixing up.\n", |
16637 |
+ __mcp251xfd_get_model_str(devtype_data->model), |
16638 |
+ mcp251xfd_get_model_str(priv)); |
16639 |
+ } |
16640 |
+@@ -2662,7 +2662,7 @@ static int mcp251xfd_register_check_rx_int(struct mcp251xfd_priv *priv) |
16641 |
+ return 0; |
16642 |
+ |
16643 |
+ netdev_info(priv->ndev, |
16644 |
+- "RX_INT active after softreset, disabling RX_INT support."); |
16645 |
++ "RX_INT active after softreset, disabling RX_INT support.\n"); |
16646 |
+ devm_gpiod_put(&priv->spi->dev, priv->rx_int); |
16647 |
+ priv->rx_int = NULL; |
16648 |
+ |
16649 |
+diff --git a/drivers/net/can/xilinx_can.c b/drivers/net/can/xilinx_can.c |
16650 |
+index 3b883e607d8ba..a579b9b791ede 100644 |
16651 |
+--- a/drivers/net/can/xilinx_can.c |
16652 |
++++ b/drivers/net/can/xilinx_can.c |
16653 |
+@@ -1762,7 +1762,12 @@ static int xcan_probe(struct platform_device *pdev) |
16654 |
+ spin_lock_init(&priv->tx_lock); |
16655 |
+ |
16656 |
+ /* Get IRQ for the device */ |
16657 |
+- ndev->irq = platform_get_irq(pdev, 0); |
16658 |
++ ret = platform_get_irq(pdev, 0); |
16659 |
++ if (ret < 0) |
16660 |
++ goto err_free; |
16661 |
++ |
16662 |
++ ndev->irq = ret; |
16663 |
++ |
16664 |
+ ndev->flags |= IFF_ECHO; /* We support local echo */ |
16665 |
+ |
16666 |
+ platform_set_drvdata(pdev, ndev); |
16667 |
+diff --git a/drivers/net/dsa/hirschmann/hellcreek.c b/drivers/net/dsa/hirschmann/hellcreek.c |
16668 |
+index 354655f9ed003..950a54ec4b59b 100644 |
16669 |
+--- a/drivers/net/dsa/hirschmann/hellcreek.c |
16670 |
++++ b/drivers/net/dsa/hirschmann/hellcreek.c |
16671 |
+@@ -710,8 +710,9 @@ static int __hellcreek_fdb_add(struct hellcreek *hellcreek, |
16672 |
+ u16 meta = 0; |
16673 |
+ |
16674 |
+ dev_dbg(hellcreek->dev, "Add static FDB entry: MAC=%pM, MASK=0x%02x, " |
16675 |
+- "OBT=%d, REPRIO_EN=%d, PRIO=%d\n", entry->mac, entry->portmask, |
16676 |
+- entry->is_obt, entry->reprio_en, entry->reprio_tc); |
16677 |
++ "OBT=%d, PASS_BLOCKED=%d, REPRIO_EN=%d, PRIO=%d\n", entry->mac, |
16678 |
++ entry->portmask, entry->is_obt, entry->pass_blocked, |
16679 |
++ entry->reprio_en, entry->reprio_tc); |
16680 |
+ |
16681 |
+ /* Add mac address */ |
16682 |
+ hellcreek_write(hellcreek, entry->mac[1] | (entry->mac[0] << 8), HR_FDBWDH); |
16683 |
+@@ -722,6 +723,8 @@ static int __hellcreek_fdb_add(struct hellcreek *hellcreek, |
16684 |
+ meta |= entry->portmask << HR_FDBWRM0_PORTMASK_SHIFT; |
16685 |
+ if (entry->is_obt) |
16686 |
+ meta |= HR_FDBWRM0_OBT; |
16687 |
++ if (entry->pass_blocked) |
16688 |
++ meta |= HR_FDBWRM0_PASS_BLOCKED; |
16689 |
+ if (entry->reprio_en) { |
16690 |
+ meta |= HR_FDBWRM0_REPRIO_EN; |
16691 |
+ meta |= entry->reprio_tc << HR_FDBWRM0_REPRIO_TC_SHIFT; |
16692 |
+@@ -1049,7 +1052,7 @@ static void hellcreek_setup_tc_identity_mapping(struct hellcreek *hellcreek) |
16693 |
+ |
16694 |
+ static int hellcreek_setup_fdb(struct hellcreek *hellcreek) |
16695 |
+ { |
16696 |
+- static struct hellcreek_fdb_entry ptp = { |
16697 |
++ static struct hellcreek_fdb_entry l2_ptp = { |
16698 |
+ /* MAC: 01-1B-19-00-00-00 */ |
16699 |
+ .mac = { 0x01, 0x1b, 0x19, 0x00, 0x00, 0x00 }, |
16700 |
+ .portmask = 0x03, /* Management ports */ |
16701 |
+@@ -1060,24 +1063,94 @@ static int hellcreek_setup_fdb(struct hellcreek *hellcreek) |
16702 |
+ .reprio_tc = 6, /* TC: 6 as per IEEE 802.1AS */ |
16703 |
+ .reprio_en = 1, |
16704 |
+ }; |
16705 |
+- static struct hellcreek_fdb_entry p2p = { |
16706 |
++ static struct hellcreek_fdb_entry udp4_ptp = { |
16707 |
++ /* MAC: 01-00-5E-00-01-81 */ |
16708 |
++ .mac = { 0x01, 0x00, 0x5e, 0x00, 0x01, 0x81 }, |
16709 |
++ .portmask = 0x03, /* Management ports */ |
16710 |
++ .age = 0, |
16711 |
++ .is_obt = 0, |
16712 |
++ .pass_blocked = 0, |
16713 |
++ .is_static = 1, |
16714 |
++ .reprio_tc = 6, |
16715 |
++ .reprio_en = 1, |
16716 |
++ }; |
16717 |
++ static struct hellcreek_fdb_entry udp6_ptp = { |
16718 |
++ /* MAC: 33-33-00-00-01-81 */ |
16719 |
++ .mac = { 0x33, 0x33, 0x00, 0x00, 0x01, 0x81 }, |
16720 |
++ .portmask = 0x03, /* Management ports */ |
16721 |
++ .age = 0, |
16722 |
++ .is_obt = 0, |
16723 |
++ .pass_blocked = 0, |
16724 |
++ .is_static = 1, |
16725 |
++ .reprio_tc = 6, |
16726 |
++ .reprio_en = 1, |
16727 |
++ }; |
16728 |
++ static struct hellcreek_fdb_entry l2_p2p = { |
16729 |
+ /* MAC: 01-80-C2-00-00-0E */ |
16730 |
+ .mac = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x0e }, |
16731 |
+ .portmask = 0x03, /* Management ports */ |
16732 |
+ .age = 0, |
16733 |
+ .is_obt = 0, |
16734 |
+- .pass_blocked = 0, |
16735 |
++ .pass_blocked = 1, |
16736 |
+ .is_static = 1, |
16737 |
+ .reprio_tc = 6, /* TC: 6 as per IEEE 802.1AS */ |
16738 |
+ .reprio_en = 1, |
16739 |
+ }; |
16740 |
++ static struct hellcreek_fdb_entry udp4_p2p = { |
16741 |
++ /* MAC: 01-00-5E-00-00-6B */ |
16742 |
++ .mac = { 0x01, 0x00, 0x5e, 0x00, 0x00, 0x6b }, |
16743 |
++ .portmask = 0x03, /* Management ports */ |
16744 |
++ .age = 0, |
16745 |
++ .is_obt = 0, |
16746 |
++ .pass_blocked = 1, |
16747 |
++ .is_static = 1, |
16748 |
++ .reprio_tc = 6, |
16749 |
++ .reprio_en = 1, |
16750 |
++ }; |
16751 |
++ static struct hellcreek_fdb_entry udp6_p2p = { |
16752 |
++ /* MAC: 33-33-00-00-00-6B */ |
16753 |
++ .mac = { 0x33, 0x33, 0x00, 0x00, 0x00, 0x6b }, |
16754 |
++ .portmask = 0x03, /* Management ports */ |
16755 |
++ .age = 0, |
16756 |
++ .is_obt = 0, |
16757 |
++ .pass_blocked = 1, |
16758 |
++ .is_static = 1, |
16759 |
++ .reprio_tc = 6, |
16760 |
++ .reprio_en = 1, |
16761 |
++ }; |
16762 |
++ static struct hellcreek_fdb_entry stp = { |
16763 |
++ /* MAC: 01-80-C2-00-00-00 */ |
16764 |
++ .mac = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 }, |
16765 |
++ .portmask = 0x03, /* Management ports */ |
16766 |
++ .age = 0, |
16767 |
++ .is_obt = 0, |
16768 |
++ .pass_blocked = 1, |
16769 |
++ .is_static = 1, |
16770 |
++ .reprio_tc = 6, |
16771 |
++ .reprio_en = 1, |
16772 |
++ }; |
16773 |
+ int ret; |
16774 |
+ |
16775 |
+ mutex_lock(&hellcreek->reg_lock); |
16776 |
+- ret = __hellcreek_fdb_add(hellcreek, &ptp); |
16777 |
++ ret = __hellcreek_fdb_add(hellcreek, &l2_ptp); |
16778 |
++ if (ret) |
16779 |
++ goto out; |
16780 |
++ ret = __hellcreek_fdb_add(hellcreek, &udp4_ptp); |
16781 |
++ if (ret) |
16782 |
++ goto out; |
16783 |
++ ret = __hellcreek_fdb_add(hellcreek, &udp6_ptp); |
16784 |
++ if (ret) |
16785 |
++ goto out; |
16786 |
++ ret = __hellcreek_fdb_add(hellcreek, &l2_p2p); |
16787 |
++ if (ret) |
16788 |
++ goto out; |
16789 |
++ ret = __hellcreek_fdb_add(hellcreek, &udp4_p2p); |
16790 |
++ if (ret) |
16791 |
++ goto out; |
16792 |
++ ret = __hellcreek_fdb_add(hellcreek, &udp6_p2p); |
16793 |
+ if (ret) |
16794 |
+ goto out; |
16795 |
+- ret = __hellcreek_fdb_add(hellcreek, &p2p); |
16796 |
++ ret = __hellcreek_fdb_add(hellcreek, &stp); |
16797 |
+ out: |
16798 |
+ mutex_unlock(&hellcreek->reg_lock); |
16799 |
+ |
16800 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/Makefile b/drivers/net/ethernet/broadcom/bnxt/Makefile |
16801 |
+index c6ef7ec2c1151..2bc2b707d6eee 100644 |
16802 |
+--- a/drivers/net/ethernet/broadcom/bnxt/Makefile |
16803 |
++++ b/drivers/net/ethernet/broadcom/bnxt/Makefile |
16804 |
+@@ -1,6 +1,6 @@ |
16805 |
+ # SPDX-License-Identifier: GPL-2.0-only |
16806 |
+ obj-$(CONFIG_BNXT) += bnxt_en.o |
16807 |
+ |
16808 |
+-bnxt_en-y := bnxt.o bnxt_hwrm.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_ptp.o bnxt_vfr.o bnxt_devlink.o bnxt_dim.o |
16809 |
++bnxt_en-y := bnxt.o bnxt_hwrm.o bnxt_sriov.o bnxt_ethtool.o bnxt_dcb.o bnxt_ulp.o bnxt_xdp.o bnxt_ptp.o bnxt_vfr.o bnxt_devlink.o bnxt_dim.o bnxt_coredump.o |
16810 |
+ bnxt_en-$(CONFIG_BNXT_FLOWER_OFFLOAD) += bnxt_tc.o |
16811 |
+ bnxt_en-$(CONFIG_DEBUG_FS) += bnxt_debugfs.o |
16812 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.c b/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
16813 |
+index 0fba01db336cc..a8855a200a3c5 100644 |
16814 |
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
16815 |
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c |
16816 |
+@@ -8004,6 +8004,12 @@ static int bnxt_hwrm_ver_get(struct bnxt *bp) |
16817 |
+ bp->hwrm_cmd_timeout = le16_to_cpu(resp->def_req_timeout); |
16818 |
+ if (!bp->hwrm_cmd_timeout) |
16819 |
+ bp->hwrm_cmd_timeout = DFLT_HWRM_CMD_TIMEOUT; |
16820 |
++ bp->hwrm_cmd_max_timeout = le16_to_cpu(resp->max_req_timeout) * 1000; |
16821 |
++ if (!bp->hwrm_cmd_max_timeout) |
16822 |
++ bp->hwrm_cmd_max_timeout = HWRM_CMD_MAX_TIMEOUT; |
16823 |
++ else if (bp->hwrm_cmd_max_timeout > HWRM_CMD_MAX_TIMEOUT) |
16824 |
++ netdev_warn(bp->dev, "Device requests max timeout of %d seconds, may trigger hung task watchdog\n", |
16825 |
++ bp->hwrm_cmd_max_timeout / 1000); |
16826 |
+ |
16827 |
+ if (resp->hwrm_intf_maj_8b >= 1) { |
16828 |
+ bp->hwrm_max_req_len = le16_to_cpu(resp->max_req_win_len); |
16829 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt.h b/drivers/net/ethernet/broadcom/bnxt/bnxt.h |
16830 |
+index 19fe6478e9b4b..0a5137c1f6d4e 100644 |
16831 |
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h |
16832 |
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h |
16833 |
+@@ -1901,7 +1901,8 @@ struct bnxt { |
16834 |
+ |
16835 |
+ u16 hwrm_max_req_len; |
16836 |
+ u16 hwrm_max_ext_req_len; |
16837 |
+- int hwrm_cmd_timeout; |
16838 |
++ unsigned int hwrm_cmd_timeout; |
16839 |
++ unsigned int hwrm_cmd_max_timeout; |
16840 |
+ struct mutex hwrm_cmd_lock; /* serialize hwrm messages */ |
16841 |
+ struct hwrm_ver_get_output ver_resp; |
16842 |
+ #define FW_VER_STR_LEN 32 |
16843 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c |
16844 |
+new file mode 100644 |
16845 |
+index 0000000000000..156f76bcea7eb |
16846 |
+--- /dev/null |
16847 |
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.c |
16848 |
+@@ -0,0 +1,372 @@ |
16849 |
++/* Broadcom NetXtreme-C/E network driver. |
16850 |
++ * |
16851 |
++ * Copyright (c) 2021 Broadcom Limited |
16852 |
++ * |
16853 |
++ * This program is free software; you can redistribute it and/or modify |
16854 |
++ * it under the terms of the GNU General Public License as published by |
16855 |
++ * the Free Software Foundation. |
16856 |
++ */ |
16857 |
++ |
16858 |
++#include <linux/types.h> |
16859 |
++#include <linux/errno.h> |
16860 |
++#include <linux/pci.h> |
16861 |
++#include "bnxt_hsi.h" |
16862 |
++#include "bnxt.h" |
16863 |
++#include "bnxt_hwrm.h" |
16864 |
++#include "bnxt_coredump.h" |
16865 |
++ |
16866 |
++static int bnxt_hwrm_dbg_dma_data(struct bnxt *bp, void *msg, |
16867 |
++ struct bnxt_hwrm_dbg_dma_info *info) |
16868 |
++{ |
16869 |
++ struct hwrm_dbg_cmn_input *cmn_req = msg; |
16870 |
++ __le16 *seq_ptr = msg + info->seq_off; |
16871 |
++ struct hwrm_dbg_cmn_output *cmn_resp; |
16872 |
++ u16 seq = 0, len, segs_off; |
16873 |
++ dma_addr_t dma_handle; |
16874 |
++ void *dma_buf, *resp; |
16875 |
++ int rc, off = 0; |
16876 |
++ |
16877 |
++ dma_buf = hwrm_req_dma_slice(bp, msg, info->dma_len, &dma_handle); |
16878 |
++ if (!dma_buf) { |
16879 |
++ hwrm_req_drop(bp, msg); |
16880 |
++ return -ENOMEM; |
16881 |
++ } |
16882 |
++ |
16883 |
++ hwrm_req_timeout(bp, msg, bp->hwrm_cmd_max_timeout); |
16884 |
++ cmn_resp = hwrm_req_hold(bp, msg); |
16885 |
++ resp = cmn_resp; |
16886 |
++ |
16887 |
++ segs_off = offsetof(struct hwrm_dbg_coredump_list_output, |
16888 |
++ total_segments); |
16889 |
++ cmn_req->host_dest_addr = cpu_to_le64(dma_handle); |
16890 |
++ cmn_req->host_buf_len = cpu_to_le32(info->dma_len); |
16891 |
++ while (1) { |
16892 |
++ *seq_ptr = cpu_to_le16(seq); |
16893 |
++ rc = hwrm_req_send(bp, msg); |
16894 |
++ if (rc) |
16895 |
++ break; |
16896 |
++ |
16897 |
++ len = le16_to_cpu(*((__le16 *)(resp + info->data_len_off))); |
16898 |
++ if (!seq && |
16899 |
++ cmn_req->req_type == cpu_to_le16(HWRM_DBG_COREDUMP_LIST)) { |
16900 |
++ info->segs = le16_to_cpu(*((__le16 *)(resp + |
16901 |
++ segs_off))); |
16902 |
++ if (!info->segs) { |
16903 |
++ rc = -EIO; |
16904 |
++ break; |
16905 |
++ } |
16906 |
++ |
16907 |
++ info->dest_buf_size = info->segs * |
16908 |
++ sizeof(struct coredump_segment_record); |
16909 |
++ info->dest_buf = kmalloc(info->dest_buf_size, |
16910 |
++ GFP_KERNEL); |
16911 |
++ if (!info->dest_buf) { |
16912 |
++ rc = -ENOMEM; |
16913 |
++ break; |
16914 |
++ } |
16915 |
++ } |
16916 |
++ |
16917 |
++ if (info->dest_buf) { |
16918 |
++ if ((info->seg_start + off + len) <= |
16919 |
++ BNXT_COREDUMP_BUF_LEN(info->buf_len)) { |
16920 |
++ memcpy(info->dest_buf + off, dma_buf, len); |
16921 |
++ } else { |
16922 |
++ rc = -ENOBUFS; |
16923 |
++ break; |
16924 |
++ } |
16925 |
++ } |
16926 |
++ |
16927 |
++ if (cmn_req->req_type == |
16928 |
++ cpu_to_le16(HWRM_DBG_COREDUMP_RETRIEVE)) |
16929 |
++ info->dest_buf_size += len; |
16930 |
++ |
16931 |
++ if (!(cmn_resp->flags & HWRM_DBG_CMN_FLAGS_MORE)) |
16932 |
++ break; |
16933 |
++ |
16934 |
++ seq++; |
16935 |
++ off += len; |
16936 |
++ } |
16937 |
++ hwrm_req_drop(bp, msg); |
16938 |
++ return rc; |
16939 |
++} |
16940 |
++ |
16941 |
++static int bnxt_hwrm_dbg_coredump_list(struct bnxt *bp, |
16942 |
++ struct bnxt_coredump *coredump) |
16943 |
++{ |
16944 |
++ struct bnxt_hwrm_dbg_dma_info info = {NULL}; |
16945 |
++ struct hwrm_dbg_coredump_list_input *req; |
16946 |
++ int rc; |
16947 |
++ |
16948 |
++ rc = hwrm_req_init(bp, req, HWRM_DBG_COREDUMP_LIST); |
16949 |
++ if (rc) |
16950 |
++ return rc; |
16951 |
++ |
16952 |
++ info.dma_len = COREDUMP_LIST_BUF_LEN; |
16953 |
++ info.seq_off = offsetof(struct hwrm_dbg_coredump_list_input, seq_no); |
16954 |
++ info.data_len_off = offsetof(struct hwrm_dbg_coredump_list_output, |
16955 |
++ data_len); |
16956 |
++ |
16957 |
++ rc = bnxt_hwrm_dbg_dma_data(bp, req, &info); |
16958 |
++ if (!rc) { |
16959 |
++ coredump->data = info.dest_buf; |
16960 |
++ coredump->data_size = info.dest_buf_size; |
16961 |
++ coredump->total_segs = info.segs; |
16962 |
++ } |
16963 |
++ return rc; |
16964 |
++} |
16965 |
++ |
16966 |
++static int bnxt_hwrm_dbg_coredump_initiate(struct bnxt *bp, u16 component_id, |
16967 |
++ u16 segment_id) |
16968 |
++{ |
16969 |
++ struct hwrm_dbg_coredump_initiate_input *req; |
16970 |
++ int rc; |
16971 |
++ |
16972 |
++ rc = hwrm_req_init(bp, req, HWRM_DBG_COREDUMP_INITIATE); |
16973 |
++ if (rc) |
16974 |
++ return rc; |
16975 |
++ |
16976 |
++ hwrm_req_timeout(bp, req, bp->hwrm_cmd_max_timeout); |
16977 |
++ req->component_id = cpu_to_le16(component_id); |
16978 |
++ req->segment_id = cpu_to_le16(segment_id); |
16979 |
++ |
16980 |
++ return hwrm_req_send(bp, req); |
16981 |
++} |
16982 |
++ |
16983 |
++static int bnxt_hwrm_dbg_coredump_retrieve(struct bnxt *bp, u16 component_id, |
16984 |
++ u16 segment_id, u32 *seg_len, |
16985 |
++ void *buf, u32 buf_len, u32 offset) |
16986 |
++{ |
16987 |
++ struct hwrm_dbg_coredump_retrieve_input *req; |
16988 |
++ struct bnxt_hwrm_dbg_dma_info info = {NULL}; |
16989 |
++ int rc; |
16990 |
++ |
16991 |
++ rc = hwrm_req_init(bp, req, HWRM_DBG_COREDUMP_RETRIEVE); |
16992 |
++ if (rc) |
16993 |
++ return rc; |
16994 |
++ |
16995 |
++ req->component_id = cpu_to_le16(component_id); |
16996 |
++ req->segment_id = cpu_to_le16(segment_id); |
16997 |
++ |
16998 |
++ info.dma_len = COREDUMP_RETRIEVE_BUF_LEN; |
16999 |
++ info.seq_off = offsetof(struct hwrm_dbg_coredump_retrieve_input, |
17000 |
++ seq_no); |
17001 |
++ info.data_len_off = offsetof(struct hwrm_dbg_coredump_retrieve_output, |
17002 |
++ data_len); |
17003 |
++ if (buf) { |
17004 |
++ info.dest_buf = buf + offset; |
17005 |
++ info.buf_len = buf_len; |
17006 |
++ info.seg_start = offset; |
17007 |
++ } |
17008 |
++ |
17009 |
++ rc = bnxt_hwrm_dbg_dma_data(bp, req, &info); |
17010 |
++ if (!rc) |
17011 |
++ *seg_len = info.dest_buf_size; |
17012 |
++ |
17013 |
++ return rc; |
17014 |
++} |
17015 |
++ |
17016 |
++static void |
17017 |
++bnxt_fill_coredump_seg_hdr(struct bnxt *bp, |
17018 |
++ struct bnxt_coredump_segment_hdr *seg_hdr, |
17019 |
++ struct coredump_segment_record *seg_rec, u32 seg_len, |
17020 |
++ int status, u32 duration, u32 instance) |
17021 |
++{ |
17022 |
++ memset(seg_hdr, 0, sizeof(*seg_hdr)); |
17023 |
++ memcpy(seg_hdr->signature, "sEgM", 4); |
17024 |
++ if (seg_rec) { |
17025 |
++ seg_hdr->component_id = (__force __le32)seg_rec->component_id; |
17026 |
++ seg_hdr->segment_id = (__force __le32)seg_rec->segment_id; |
17027 |
++ seg_hdr->low_version = seg_rec->version_low; |
17028 |
++ seg_hdr->high_version = seg_rec->version_hi; |
17029 |
++ } else { |
17030 |
++ /* For hwrm_ver_get response Component id = 2 |
17031 |
++ * and Segment id = 0 |
17032 |
++ */ |
17033 |
++ seg_hdr->component_id = cpu_to_le32(2); |
17034 |
++ seg_hdr->segment_id = 0; |
17035 |
++ } |
17036 |
++ seg_hdr->function_id = cpu_to_le16(bp->pdev->devfn); |
17037 |
++ seg_hdr->length = cpu_to_le32(seg_len); |
17038 |
++ seg_hdr->status = cpu_to_le32(status); |
17039 |
++ seg_hdr->duration = cpu_to_le32(duration); |
17040 |
++ seg_hdr->data_offset = cpu_to_le32(sizeof(*seg_hdr)); |
17041 |
++ seg_hdr->instance = cpu_to_le32(instance); |
17042 |
++} |
17043 |
++ |
17044 |
++static void |
17045 |
++bnxt_fill_coredump_record(struct bnxt *bp, struct bnxt_coredump_record *record, |
17046 |
++ time64_t start, s16 start_utc, u16 total_segs, |
17047 |
++ int status) |
17048 |
++{ |
17049 |
++ time64_t end = ktime_get_real_seconds(); |
17050 |
++ u32 os_ver_major = 0, os_ver_minor = 0; |
17051 |
++ struct tm tm; |
17052 |
++ |
17053 |
++ time64_to_tm(start, 0, &tm); |
17054 |
++ memset(record, 0, sizeof(*record)); |
17055 |
++ memcpy(record->signature, "cOrE", 4); |
17056 |
++ record->flags = 0; |
17057 |
++ record->low_version = 0; |
17058 |
++ record->high_version = 1; |
17059 |
++ record->asic_state = 0; |
17060 |
++ strscpy(record->system_name, utsname()->nodename, |
17061 |
++ sizeof(record->system_name)); |
17062 |
++ record->year = cpu_to_le16(tm.tm_year + 1900); |
17063 |
++ record->month = cpu_to_le16(tm.tm_mon + 1); |
17064 |
++ record->day = cpu_to_le16(tm.tm_mday); |
17065 |
++ record->hour = cpu_to_le16(tm.tm_hour); |
17066 |
++ record->minute = cpu_to_le16(tm.tm_min); |
17067 |
++ record->second = cpu_to_le16(tm.tm_sec); |
17068 |
++ record->utc_bias = cpu_to_le16(start_utc); |
17069 |
++ strcpy(record->commandline, "ethtool -w"); |
17070 |
++ record->total_segments = cpu_to_le32(total_segs); |
17071 |
++ |
17072 |
++ if (sscanf(utsname()->release, "%u.%u", &os_ver_major, &os_ver_minor) != 2) |
17073 |
++ netdev_warn(bp->dev, "Unknown OS release in coredump\n"); |
17074 |
++ record->os_ver_major = cpu_to_le32(os_ver_major); |
17075 |
++ record->os_ver_minor = cpu_to_le32(os_ver_minor); |
17076 |
++ |
17077 |
++ strscpy(record->os_name, utsname()->sysname, sizeof(record->os_name)); |
17078 |
++ time64_to_tm(end, 0, &tm); |
17079 |
++ record->end_year = cpu_to_le16(tm.tm_year + 1900); |
17080 |
++ record->end_month = cpu_to_le16(tm.tm_mon + 1); |
17081 |
++ record->end_day = cpu_to_le16(tm.tm_mday); |
17082 |
++ record->end_hour = cpu_to_le16(tm.tm_hour); |
17083 |
++ record->end_minute = cpu_to_le16(tm.tm_min); |
17084 |
++ record->end_second = cpu_to_le16(tm.tm_sec); |
17085 |
++ record->end_utc_bias = cpu_to_le16(sys_tz.tz_minuteswest * 60); |
17086 |
++ record->asic_id1 = cpu_to_le32(bp->chip_num << 16 | |
17087 |
++ bp->ver_resp.chip_rev << 8 | |
17088 |
++ bp->ver_resp.chip_metal); |
17089 |
++ record->asic_id2 = 0; |
17090 |
++ record->coredump_status = cpu_to_le32(status); |
17091 |
++ record->ioctl_low_version = 0; |
17092 |
++ record->ioctl_high_version = 0; |
17093 |
++} |
17094 |
++ |
17095 |
++static int __bnxt_get_coredump(struct bnxt *bp, void *buf, u32 *dump_len) |
17096 |
++{ |
17097 |
++ u32 ver_get_resp_len = sizeof(struct hwrm_ver_get_output); |
17098 |
++ u32 offset = 0, seg_hdr_len, seg_record_len, buf_len = 0; |
17099 |
++ struct coredump_segment_record *seg_record = NULL; |
17100 |
++ struct bnxt_coredump_segment_hdr seg_hdr; |
17101 |
++ struct bnxt_coredump coredump = {NULL}; |
17102 |
++ time64_t start_time; |
17103 |
++ u16 start_utc; |
17104 |
++ int rc = 0, i; |
17105 |
++ |
17106 |
++ if (buf) |
17107 |
++ buf_len = *dump_len; |
17108 |
++ |
17109 |
++ start_time = ktime_get_real_seconds(); |
17110 |
++ start_utc = sys_tz.tz_minuteswest * 60; |
17111 |
++ seg_hdr_len = sizeof(seg_hdr); |
17112 |
++ |
17113 |
++ /* First segment should be hwrm_ver_get response */ |
17114 |
++ *dump_len = seg_hdr_len + ver_get_resp_len; |
17115 |
++ if (buf) { |
17116 |
++ bnxt_fill_coredump_seg_hdr(bp, &seg_hdr, NULL, ver_get_resp_len, |
17117 |
++ 0, 0, 0); |
17118 |
++ memcpy(buf + offset, &seg_hdr, seg_hdr_len); |
17119 |
++ offset += seg_hdr_len; |
17120 |
++ memcpy(buf + offset, &bp->ver_resp, ver_get_resp_len); |
17121 |
++ offset += ver_get_resp_len; |
17122 |
++ } |
17123 |
++ |
17124 |
++ rc = bnxt_hwrm_dbg_coredump_list(bp, &coredump); |
17125 |
++ if (rc) { |
17126 |
++ netdev_err(bp->dev, "Failed to get coredump segment list\n"); |
17127 |
++ goto err; |
17128 |
++ } |
17129 |
++ |
17130 |
++ *dump_len += seg_hdr_len * coredump.total_segs; |
17131 |
++ |
17132 |
++ seg_record = (struct coredump_segment_record *)coredump.data; |
17133 |
++ seg_record_len = sizeof(*seg_record); |
17134 |
++ |
17135 |
++ for (i = 0; i < coredump.total_segs; i++) { |
17136 |
++ u16 comp_id = le16_to_cpu(seg_record->component_id); |
17137 |
++ u16 seg_id = le16_to_cpu(seg_record->segment_id); |
17138 |
++ u32 duration = 0, seg_len = 0; |
17139 |
++ unsigned long start, end; |
17140 |
++ |
17141 |
++ if (buf && ((offset + seg_hdr_len) > |
17142 |
++ BNXT_COREDUMP_BUF_LEN(buf_len))) { |
17143 |
++ rc = -ENOBUFS; |
17144 |
++ goto err; |
17145 |
++ } |
17146 |
++ |
17147 |
++ start = jiffies; |
17148 |
++ |
17149 |
++ rc = bnxt_hwrm_dbg_coredump_initiate(bp, comp_id, seg_id); |
17150 |
++ if (rc) { |
17151 |
++ netdev_err(bp->dev, |
17152 |
++ "Failed to initiate coredump for seg = %d\n", |
17153 |
++ seg_record->segment_id); |
17154 |
++ goto next_seg; |
17155 |
++ } |
17156 |
++ |
17157 |
++ /* Write segment data into the buffer */ |
17158 |
++ rc = bnxt_hwrm_dbg_coredump_retrieve(bp, comp_id, seg_id, |
17159 |
++ &seg_len, buf, buf_len, |
17160 |
++ offset + seg_hdr_len); |
17161 |
++ if (rc && rc == -ENOBUFS) |
17162 |
++ goto err; |
17163 |
++ else if (rc) |
17164 |
++ netdev_err(bp->dev, |
17165 |
++ "Failed to retrieve coredump for seg = %d\n", |
17166 |
++ seg_record->segment_id); |
17167 |
++ |
17168 |
++next_seg: |
17169 |
++ end = jiffies; |
17170 |
++ duration = jiffies_to_msecs(end - start); |
17171 |
++ bnxt_fill_coredump_seg_hdr(bp, &seg_hdr, seg_record, seg_len, |
17172 |
++ rc, duration, 0); |
17173 |
++ |
17174 |
++ if (buf) { |
17175 |
++ /* Write segment header into the buffer */ |
17176 |
++ memcpy(buf + offset, &seg_hdr, seg_hdr_len); |
17177 |
++ offset += seg_hdr_len + seg_len; |
17178 |
++ } |
17179 |
++ |
17180 |
++ *dump_len += seg_len; |
17181 |
++ seg_record = |
17182 |
++ (struct coredump_segment_record *)((u8 *)seg_record + |
17183 |
++ seg_record_len); |
17184 |
++ } |
17185 |
++ |
17186 |
++err: |
17187 |
++ if (buf) |
17188 |
++ bnxt_fill_coredump_record(bp, buf + offset, start_time, |
17189 |
++ start_utc, coredump.total_segs + 1, |
17190 |
++ rc); |
17191 |
++ kfree(coredump.data); |
17192 |
++ *dump_len += sizeof(struct bnxt_coredump_record); |
17193 |
++ if (rc == -ENOBUFS) |
17194 |
++ netdev_err(bp->dev, "Firmware returned large coredump buffer\n"); |
17195 |
++ return rc; |
17196 |
++} |
17197 |
++ |
17198 |
++int bnxt_get_coredump(struct bnxt *bp, u16 dump_type, void *buf, u32 *dump_len) |
17199 |
++{ |
17200 |
++ if (dump_type == BNXT_DUMP_CRASH) { |
17201 |
++#ifdef CONFIG_TEE_BNXT_FW |
17202 |
++ return tee_bnxt_copy_coredump(buf, 0, *dump_len); |
17203 |
++#else |
17204 |
++ return -EOPNOTSUPP; |
17205 |
++#endif |
17206 |
++ } else { |
17207 |
++ return __bnxt_get_coredump(bp, buf, dump_len); |
17208 |
++ } |
17209 |
++} |
17210 |
++ |
17211 |
++u32 bnxt_get_coredump_length(struct bnxt *bp, u16 dump_type) |
17212 |
++{ |
17213 |
++ u32 len = 0; |
17214 |
++ |
17215 |
++ if (dump_type == BNXT_DUMP_CRASH) |
17216 |
++ len = BNXT_CRASH_DUMP_LEN; |
17217 |
++ else |
17218 |
++ __bnxt_get_coredump(bp, NULL, &len); |
17219 |
++ return len; |
17220 |
++} |
17221 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.h |
17222 |
+index 09c22f8fe3991..b1a1b2fffb194 100644 |
17223 |
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.h |
17224 |
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_coredump.h |
17225 |
+@@ -10,6 +10,10 @@ |
17226 |
+ #ifndef BNXT_COREDUMP_H |
17227 |
+ #define BNXT_COREDUMP_H |
17228 |
+ |
17229 |
++#include <linux/utsname.h> |
17230 |
++#include <linux/time.h> |
17231 |
++#include <linux/rtc.h> |
17232 |
++ |
17233 |
+ struct bnxt_coredump_segment_hdr { |
17234 |
+ __u8 signature[4]; |
17235 |
+ __le32 component_id; |
17236 |
+@@ -63,4 +67,51 @@ struct bnxt_coredump_record { |
17237 |
+ __u8 ioctl_high_version; |
17238 |
+ __le16 rsvd3[313]; |
17239 |
+ }; |
17240 |
++ |
17241 |
++#define BNXT_CRASH_DUMP_LEN (8 << 20) |
17242 |
++ |
17243 |
++#define COREDUMP_LIST_BUF_LEN 2048 |
17244 |
++#define COREDUMP_RETRIEVE_BUF_LEN 4096 |
17245 |
++ |
17246 |
++struct bnxt_coredump { |
17247 |
++ void *data; |
17248 |
++ int data_size; |
17249 |
++ u16 total_segs; |
17250 |
++}; |
17251 |
++ |
17252 |
++#define BNXT_COREDUMP_BUF_LEN(len) ((len) - sizeof(struct bnxt_coredump_record)) |
17253 |
++ |
17254 |
++struct bnxt_hwrm_dbg_dma_info { |
17255 |
++ void *dest_buf; |
17256 |
++ int dest_buf_size; |
17257 |
++ u16 dma_len; |
17258 |
++ u16 seq_off; |
17259 |
++ u16 data_len_off; |
17260 |
++ u16 segs; |
17261 |
++ u32 seg_start; |
17262 |
++ u32 buf_len; |
17263 |
++}; |
17264 |
++ |
17265 |
++struct hwrm_dbg_cmn_input { |
17266 |
++ __le16 req_type; |
17267 |
++ __le16 cmpl_ring; |
17268 |
++ __le16 seq_id; |
17269 |
++ __le16 target_id; |
17270 |
++ __le64 resp_addr; |
17271 |
++ __le64 host_dest_addr; |
17272 |
++ __le32 host_buf_len; |
17273 |
++}; |
17274 |
++ |
17275 |
++struct hwrm_dbg_cmn_output { |
17276 |
++ __le16 error_code; |
17277 |
++ __le16 req_type; |
17278 |
++ __le16 seq_id; |
17279 |
++ __le16 resp_len; |
17280 |
++ u8 flags; |
17281 |
++ #define HWRM_DBG_CMN_FLAGS_MORE 1 |
17282 |
++}; |
17283 |
++ |
17284 |
++int bnxt_get_coredump(struct bnxt *bp, u16 dump_type, void *buf, u32 *dump_len); |
17285 |
++u32 bnxt_get_coredump_length(struct bnxt *bp, u16 dump_type); |
17286 |
++ |
17287 |
+ #endif |
17288 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c |
17289 |
+index 7260910e75fb2..2497925105215 100644 |
17290 |
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c |
17291 |
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.c |
17292 |
+@@ -31,9 +31,6 @@ |
17293 |
+ #include "bnxt_nvm_defs.h" /* NVRAM content constant and structure defs */ |
17294 |
+ #include "bnxt_fw_hdr.h" /* Firmware hdr constant and structure defs */ |
17295 |
+ #include "bnxt_coredump.h" |
17296 |
+-#define FLASH_NVRAM_TIMEOUT ((HWRM_CMD_TIMEOUT) * 100) |
17297 |
+-#define FLASH_PACKAGE_TIMEOUT ((HWRM_CMD_TIMEOUT) * 200) |
17298 |
+-#define INSTALL_PACKAGE_TIMEOUT ((HWRM_CMD_TIMEOUT) * 200) |
17299 |
+ |
17300 |
+ static u32 bnxt_get_msglevel(struct net_device *dev) |
17301 |
+ { |
17302 |
+@@ -2167,7 +2164,7 @@ static int bnxt_flash_nvram(struct net_device *dev, u16 dir_type, |
17303 |
+ req->host_src_addr = cpu_to_le64(dma_handle); |
17304 |
+ } |
17305 |
+ |
17306 |
+- hwrm_req_timeout(bp, req, FLASH_NVRAM_TIMEOUT); |
17307 |
++ hwrm_req_timeout(bp, req, bp->hwrm_cmd_max_timeout); |
17308 |
+ req->dir_type = cpu_to_le16(dir_type); |
17309 |
+ req->dir_ordinal = cpu_to_le16(dir_ordinal); |
17310 |
+ req->dir_ext = cpu_to_le16(dir_ext); |
17311 |
+@@ -2508,8 +2505,8 @@ int bnxt_flash_package_from_fw_obj(struct net_device *dev, const struct firmware |
17312 |
+ return rc; |
17313 |
+ } |
17314 |
+ |
17315 |
+- hwrm_req_timeout(bp, modify, FLASH_PACKAGE_TIMEOUT); |
17316 |
+- hwrm_req_timeout(bp, install, INSTALL_PACKAGE_TIMEOUT); |
17317 |
++ hwrm_req_timeout(bp, modify, bp->hwrm_cmd_max_timeout); |
17318 |
++ hwrm_req_timeout(bp, install, bp->hwrm_cmd_max_timeout); |
17319 |
+ |
17320 |
+ hwrm_req_hold(bp, modify); |
17321 |
+ modify->host_src_addr = cpu_to_le64(dma_handle); |
17322 |
+@@ -3609,337 +3606,6 @@ static int bnxt_reset(struct net_device *dev, u32 *flags) |
17323 |
+ return 0; |
17324 |
+ } |
17325 |
+ |
17326 |
+-static int bnxt_hwrm_dbg_dma_data(struct bnxt *bp, void *msg, |
17327 |
+- struct bnxt_hwrm_dbg_dma_info *info) |
17328 |
+-{ |
17329 |
+- struct hwrm_dbg_cmn_input *cmn_req = msg; |
17330 |
+- __le16 *seq_ptr = msg + info->seq_off; |
17331 |
+- struct hwrm_dbg_cmn_output *cmn_resp; |
17332 |
+- u16 seq = 0, len, segs_off; |
17333 |
+- dma_addr_t dma_handle; |
17334 |
+- void *dma_buf, *resp; |
17335 |
+- int rc, off = 0; |
17336 |
+- |
17337 |
+- dma_buf = hwrm_req_dma_slice(bp, msg, info->dma_len, &dma_handle); |
17338 |
+- if (!dma_buf) { |
17339 |
+- hwrm_req_drop(bp, msg); |
17340 |
+- return -ENOMEM; |
17341 |
+- } |
17342 |
+- |
17343 |
+- hwrm_req_timeout(bp, msg, HWRM_COREDUMP_TIMEOUT); |
17344 |
+- cmn_resp = hwrm_req_hold(bp, msg); |
17345 |
+- resp = cmn_resp; |
17346 |
+- |
17347 |
+- segs_off = offsetof(struct hwrm_dbg_coredump_list_output, |
17348 |
+- total_segments); |
17349 |
+- cmn_req->host_dest_addr = cpu_to_le64(dma_handle); |
17350 |
+- cmn_req->host_buf_len = cpu_to_le32(info->dma_len); |
17351 |
+- while (1) { |
17352 |
+- *seq_ptr = cpu_to_le16(seq); |
17353 |
+- rc = hwrm_req_send(bp, msg); |
17354 |
+- if (rc) |
17355 |
+- break; |
17356 |
+- |
17357 |
+- len = le16_to_cpu(*((__le16 *)(resp + info->data_len_off))); |
17358 |
+- if (!seq && |
17359 |
+- cmn_req->req_type == cpu_to_le16(HWRM_DBG_COREDUMP_LIST)) { |
17360 |
+- info->segs = le16_to_cpu(*((__le16 *)(resp + |
17361 |
+- segs_off))); |
17362 |
+- if (!info->segs) { |
17363 |
+- rc = -EIO; |
17364 |
+- break; |
17365 |
+- } |
17366 |
+- |
17367 |
+- info->dest_buf_size = info->segs * |
17368 |
+- sizeof(struct coredump_segment_record); |
17369 |
+- info->dest_buf = kmalloc(info->dest_buf_size, |
17370 |
+- GFP_KERNEL); |
17371 |
+- if (!info->dest_buf) { |
17372 |
+- rc = -ENOMEM; |
17373 |
+- break; |
17374 |
+- } |
17375 |
+- } |
17376 |
+- |
17377 |
+- if (info->dest_buf) { |
17378 |
+- if ((info->seg_start + off + len) <= |
17379 |
+- BNXT_COREDUMP_BUF_LEN(info->buf_len)) { |
17380 |
+- memcpy(info->dest_buf + off, dma_buf, len); |
17381 |
+- } else { |
17382 |
+- rc = -ENOBUFS; |
17383 |
+- break; |
17384 |
+- } |
17385 |
+- } |
17386 |
+- |
17387 |
+- if (cmn_req->req_type == |
17388 |
+- cpu_to_le16(HWRM_DBG_COREDUMP_RETRIEVE)) |
17389 |
+- info->dest_buf_size += len; |
17390 |
+- |
17391 |
+- if (!(cmn_resp->flags & HWRM_DBG_CMN_FLAGS_MORE)) |
17392 |
+- break; |
17393 |
+- |
17394 |
+- seq++; |
17395 |
+- off += len; |
17396 |
+- } |
17397 |
+- hwrm_req_drop(bp, msg); |
17398 |
+- return rc; |
17399 |
+-} |
17400 |
+- |
17401 |
+-static int bnxt_hwrm_dbg_coredump_list(struct bnxt *bp, |
17402 |
+- struct bnxt_coredump *coredump) |
17403 |
+-{ |
17404 |
+- struct bnxt_hwrm_dbg_dma_info info = {NULL}; |
17405 |
+- struct hwrm_dbg_coredump_list_input *req; |
17406 |
+- int rc; |
17407 |
+- |
17408 |
+- rc = hwrm_req_init(bp, req, HWRM_DBG_COREDUMP_LIST); |
17409 |
+- if (rc) |
17410 |
+- return rc; |
17411 |
+- |
17412 |
+- info.dma_len = COREDUMP_LIST_BUF_LEN; |
17413 |
+- info.seq_off = offsetof(struct hwrm_dbg_coredump_list_input, seq_no); |
17414 |
+- info.data_len_off = offsetof(struct hwrm_dbg_coredump_list_output, |
17415 |
+- data_len); |
17416 |
+- |
17417 |
+- rc = bnxt_hwrm_dbg_dma_data(bp, req, &info); |
17418 |
+- if (!rc) { |
17419 |
+- coredump->data = info.dest_buf; |
17420 |
+- coredump->data_size = info.dest_buf_size; |
17421 |
+- coredump->total_segs = info.segs; |
17422 |
+- } |
17423 |
+- return rc; |
17424 |
+-} |
17425 |
+- |
17426 |
+-static int bnxt_hwrm_dbg_coredump_initiate(struct bnxt *bp, u16 component_id, |
17427 |
+- u16 segment_id) |
17428 |
+-{ |
17429 |
+- struct hwrm_dbg_coredump_initiate_input *req; |
17430 |
+- int rc; |
17431 |
+- |
17432 |
+- rc = hwrm_req_init(bp, req, HWRM_DBG_COREDUMP_INITIATE); |
17433 |
+- if (rc) |
17434 |
+- return rc; |
17435 |
+- |
17436 |
+- hwrm_req_timeout(bp, req, HWRM_COREDUMP_TIMEOUT); |
17437 |
+- req->component_id = cpu_to_le16(component_id); |
17438 |
+- req->segment_id = cpu_to_le16(segment_id); |
17439 |
+- |
17440 |
+- return hwrm_req_send(bp, req); |
17441 |
+-} |
17442 |
+- |
17443 |
+-static int bnxt_hwrm_dbg_coredump_retrieve(struct bnxt *bp, u16 component_id, |
17444 |
+- u16 segment_id, u32 *seg_len, |
17445 |
+- void *buf, u32 buf_len, u32 offset) |
17446 |
+-{ |
17447 |
+- struct hwrm_dbg_coredump_retrieve_input *req; |
17448 |
+- struct bnxt_hwrm_dbg_dma_info info = {NULL}; |
17449 |
+- int rc; |
17450 |
+- |
17451 |
+- rc = hwrm_req_init(bp, req, HWRM_DBG_COREDUMP_RETRIEVE); |
17452 |
+- if (rc) |
17453 |
+- return rc; |
17454 |
+- |
17455 |
+- req->component_id = cpu_to_le16(component_id); |
17456 |
+- req->segment_id = cpu_to_le16(segment_id); |
17457 |
+- |
17458 |
+- info.dma_len = COREDUMP_RETRIEVE_BUF_LEN; |
17459 |
+- info.seq_off = offsetof(struct hwrm_dbg_coredump_retrieve_input, |
17460 |
+- seq_no); |
17461 |
+- info.data_len_off = offsetof(struct hwrm_dbg_coredump_retrieve_output, |
17462 |
+- data_len); |
17463 |
+- if (buf) { |
17464 |
+- info.dest_buf = buf + offset; |
17465 |
+- info.buf_len = buf_len; |
17466 |
+- info.seg_start = offset; |
17467 |
+- } |
17468 |
+- |
17469 |
+- rc = bnxt_hwrm_dbg_dma_data(bp, req, &info); |
17470 |
+- if (!rc) |
17471 |
+- *seg_len = info.dest_buf_size; |
17472 |
+- |
17473 |
+- return rc; |
17474 |
+-} |
17475 |
+- |
17476 |
+-static void |
17477 |
+-bnxt_fill_coredump_seg_hdr(struct bnxt *bp, |
17478 |
+- struct bnxt_coredump_segment_hdr *seg_hdr, |
17479 |
+- struct coredump_segment_record *seg_rec, u32 seg_len, |
17480 |
+- int status, u32 duration, u32 instance) |
17481 |
+-{ |
17482 |
+- memset(seg_hdr, 0, sizeof(*seg_hdr)); |
17483 |
+- memcpy(seg_hdr->signature, "sEgM", 4); |
17484 |
+- if (seg_rec) { |
17485 |
+- seg_hdr->component_id = (__force __le32)seg_rec->component_id; |
17486 |
+- seg_hdr->segment_id = (__force __le32)seg_rec->segment_id; |
17487 |
+- seg_hdr->low_version = seg_rec->version_low; |
17488 |
+- seg_hdr->high_version = seg_rec->version_hi; |
17489 |
+- } else { |
17490 |
+- /* For hwrm_ver_get response Component id = 2 |
17491 |
+- * and Segment id = 0 |
17492 |
+- */ |
17493 |
+- seg_hdr->component_id = cpu_to_le32(2); |
17494 |
+- seg_hdr->segment_id = 0; |
17495 |
+- } |
17496 |
+- seg_hdr->function_id = cpu_to_le16(bp->pdev->devfn); |
17497 |
+- seg_hdr->length = cpu_to_le32(seg_len); |
17498 |
+- seg_hdr->status = cpu_to_le32(status); |
17499 |
+- seg_hdr->duration = cpu_to_le32(duration); |
17500 |
+- seg_hdr->data_offset = cpu_to_le32(sizeof(*seg_hdr)); |
17501 |
+- seg_hdr->instance = cpu_to_le32(instance); |
17502 |
+-} |
17503 |
+- |
17504 |
+-static void |
17505 |
+-bnxt_fill_coredump_record(struct bnxt *bp, struct bnxt_coredump_record *record, |
17506 |
+- time64_t start, s16 start_utc, u16 total_segs, |
17507 |
+- int status) |
17508 |
+-{ |
17509 |
+- time64_t end = ktime_get_real_seconds(); |
17510 |
+- u32 os_ver_major = 0, os_ver_minor = 0; |
17511 |
+- struct tm tm; |
17512 |
+- |
17513 |
+- time64_to_tm(start, 0, &tm); |
17514 |
+- memset(record, 0, sizeof(*record)); |
17515 |
+- memcpy(record->signature, "cOrE", 4); |
17516 |
+- record->flags = 0; |
17517 |
+- record->low_version = 0; |
17518 |
+- record->high_version = 1; |
17519 |
+- record->asic_state = 0; |
17520 |
+- strlcpy(record->system_name, utsname()->nodename, |
17521 |
+- sizeof(record->system_name)); |
17522 |
+- record->year = cpu_to_le16(tm.tm_year + 1900); |
17523 |
+- record->month = cpu_to_le16(tm.tm_mon + 1); |
17524 |
+- record->day = cpu_to_le16(tm.tm_mday); |
17525 |
+- record->hour = cpu_to_le16(tm.tm_hour); |
17526 |
+- record->minute = cpu_to_le16(tm.tm_min); |
17527 |
+- record->second = cpu_to_le16(tm.tm_sec); |
17528 |
+- record->utc_bias = cpu_to_le16(start_utc); |
17529 |
+- strcpy(record->commandline, "ethtool -w"); |
17530 |
+- record->total_segments = cpu_to_le32(total_segs); |
17531 |
+- |
17532 |
+- sscanf(utsname()->release, "%u.%u", &os_ver_major, &os_ver_minor); |
17533 |
+- record->os_ver_major = cpu_to_le32(os_ver_major); |
17534 |
+- record->os_ver_minor = cpu_to_le32(os_ver_minor); |
17535 |
+- |
17536 |
+- strlcpy(record->os_name, utsname()->sysname, 32); |
17537 |
+- time64_to_tm(end, 0, &tm); |
17538 |
+- record->end_year = cpu_to_le16(tm.tm_year + 1900); |
17539 |
+- record->end_month = cpu_to_le16(tm.tm_mon + 1); |
17540 |
+- record->end_day = cpu_to_le16(tm.tm_mday); |
17541 |
+- record->end_hour = cpu_to_le16(tm.tm_hour); |
17542 |
+- record->end_minute = cpu_to_le16(tm.tm_min); |
17543 |
+- record->end_second = cpu_to_le16(tm.tm_sec); |
17544 |
+- record->end_utc_bias = cpu_to_le16(sys_tz.tz_minuteswest * 60); |
17545 |
+- record->asic_id1 = cpu_to_le32(bp->chip_num << 16 | |
17546 |
+- bp->ver_resp.chip_rev << 8 | |
17547 |
+- bp->ver_resp.chip_metal); |
17548 |
+- record->asic_id2 = 0; |
17549 |
+- record->coredump_status = cpu_to_le32(status); |
17550 |
+- record->ioctl_low_version = 0; |
17551 |
+- record->ioctl_high_version = 0; |
17552 |
+-} |
17553 |
+- |
17554 |
+-static int bnxt_get_coredump(struct bnxt *bp, void *buf, u32 *dump_len) |
17555 |
+-{ |
17556 |
+- u32 ver_get_resp_len = sizeof(struct hwrm_ver_get_output); |
17557 |
+- u32 offset = 0, seg_hdr_len, seg_record_len, buf_len = 0; |
17558 |
+- struct coredump_segment_record *seg_record = NULL; |
17559 |
+- struct bnxt_coredump_segment_hdr seg_hdr; |
17560 |
+- struct bnxt_coredump coredump = {NULL}; |
17561 |
+- time64_t start_time; |
17562 |
+- u16 start_utc; |
17563 |
+- int rc = 0, i; |
17564 |
+- |
17565 |
+- if (buf) |
17566 |
+- buf_len = *dump_len; |
17567 |
+- |
17568 |
+- start_time = ktime_get_real_seconds(); |
17569 |
+- start_utc = sys_tz.tz_minuteswest * 60; |
17570 |
+- seg_hdr_len = sizeof(seg_hdr); |
17571 |
+- |
17572 |
+- /* First segment should be hwrm_ver_get response */ |
17573 |
+- *dump_len = seg_hdr_len + ver_get_resp_len; |
17574 |
+- if (buf) { |
17575 |
+- bnxt_fill_coredump_seg_hdr(bp, &seg_hdr, NULL, ver_get_resp_len, |
17576 |
+- 0, 0, 0); |
17577 |
+- memcpy(buf + offset, &seg_hdr, seg_hdr_len); |
17578 |
+- offset += seg_hdr_len; |
17579 |
+- memcpy(buf + offset, &bp->ver_resp, ver_get_resp_len); |
17580 |
+- offset += ver_get_resp_len; |
17581 |
+- } |
17582 |
+- |
17583 |
+- rc = bnxt_hwrm_dbg_coredump_list(bp, &coredump); |
17584 |
+- if (rc) { |
17585 |
+- netdev_err(bp->dev, "Failed to get coredump segment list\n"); |
17586 |
+- goto err; |
17587 |
+- } |
17588 |
+- |
17589 |
+- *dump_len += seg_hdr_len * coredump.total_segs; |
17590 |
+- |
17591 |
+- seg_record = (struct coredump_segment_record *)coredump.data; |
17592 |
+- seg_record_len = sizeof(*seg_record); |
17593 |
+- |
17594 |
+- for (i = 0; i < coredump.total_segs; i++) { |
17595 |
+- u16 comp_id = le16_to_cpu(seg_record->component_id); |
17596 |
+- u16 seg_id = le16_to_cpu(seg_record->segment_id); |
17597 |
+- u32 duration = 0, seg_len = 0; |
17598 |
+- unsigned long start, end; |
17599 |
+- |
17600 |
+- if (buf && ((offset + seg_hdr_len) > |
17601 |
+- BNXT_COREDUMP_BUF_LEN(buf_len))) { |
17602 |
+- rc = -ENOBUFS; |
17603 |
+- goto err; |
17604 |
+- } |
17605 |
+- |
17606 |
+- start = jiffies; |
17607 |
+- |
17608 |
+- rc = bnxt_hwrm_dbg_coredump_initiate(bp, comp_id, seg_id); |
17609 |
+- if (rc) { |
17610 |
+- netdev_err(bp->dev, |
17611 |
+- "Failed to initiate coredump for seg = %d\n", |
17612 |
+- seg_record->segment_id); |
17613 |
+- goto next_seg; |
17614 |
+- } |
17615 |
+- |
17616 |
+- /* Write segment data into the buffer */ |
17617 |
+- rc = bnxt_hwrm_dbg_coredump_retrieve(bp, comp_id, seg_id, |
17618 |
+- &seg_len, buf, buf_len, |
17619 |
+- offset + seg_hdr_len); |
17620 |
+- if (rc && rc == -ENOBUFS) |
17621 |
+- goto err; |
17622 |
+- else if (rc) |
17623 |
+- netdev_err(bp->dev, |
17624 |
+- "Failed to retrieve coredump for seg = %d\n", |
17625 |
+- seg_record->segment_id); |
17626 |
+- |
17627 |
+-next_seg: |
17628 |
+- end = jiffies; |
17629 |
+- duration = jiffies_to_msecs(end - start); |
17630 |
+- bnxt_fill_coredump_seg_hdr(bp, &seg_hdr, seg_record, seg_len, |
17631 |
+- rc, duration, 0); |
17632 |
+- |
17633 |
+- if (buf) { |
17634 |
+- /* Write segment header into the buffer */ |
17635 |
+- memcpy(buf + offset, &seg_hdr, seg_hdr_len); |
17636 |
+- offset += seg_hdr_len + seg_len; |
17637 |
+- } |
17638 |
+- |
17639 |
+- *dump_len += seg_len; |
17640 |
+- seg_record = |
17641 |
+- (struct coredump_segment_record *)((u8 *)seg_record + |
17642 |
+- seg_record_len); |
17643 |
+- } |
17644 |
+- |
17645 |
+-err: |
17646 |
+- if (buf) |
17647 |
+- bnxt_fill_coredump_record(bp, buf + offset, start_time, |
17648 |
+- start_utc, coredump.total_segs + 1, |
17649 |
+- rc); |
17650 |
+- kfree(coredump.data); |
17651 |
+- *dump_len += sizeof(struct bnxt_coredump_record); |
17652 |
+- if (rc == -ENOBUFS) |
17653 |
+- netdev_err(bp->dev, "Firmware returned large coredump buffer\n"); |
17654 |
+- return rc; |
17655 |
+-} |
17656 |
+- |
17657 |
+ static int bnxt_set_dump(struct net_device *dev, struct ethtool_dump *dump) |
17658 |
+ { |
17659 |
+ struct bnxt *bp = netdev_priv(dev); |
17660 |
+@@ -3971,10 +3637,7 @@ static int bnxt_get_dump_flag(struct net_device *dev, struct ethtool_dump *dump) |
17661 |
+ bp->ver_resp.hwrm_fw_rsvd_8b; |
17662 |
+ |
17663 |
+ dump->flag = bp->dump_flag; |
17664 |
+- if (bp->dump_flag == BNXT_DUMP_CRASH) |
17665 |
+- dump->len = BNXT_CRASH_DUMP_LEN; |
17666 |
+- else |
17667 |
+- bnxt_get_coredump(bp, NULL, &dump->len); |
17668 |
++ dump->len = bnxt_get_coredump_length(bp, bp->dump_flag); |
17669 |
+ return 0; |
17670 |
+ } |
17671 |
+ |
17672 |
+@@ -3989,15 +3652,7 @@ static int bnxt_get_dump_data(struct net_device *dev, struct ethtool_dump *dump, |
17673 |
+ memset(buf, 0, dump->len); |
17674 |
+ |
17675 |
+ dump->flag = bp->dump_flag; |
17676 |
+- if (dump->flag == BNXT_DUMP_CRASH) { |
17677 |
+-#ifdef CONFIG_TEE_BNXT_FW |
17678 |
+- return tee_bnxt_copy_coredump(buf, 0, dump->len); |
17679 |
+-#endif |
17680 |
+- } else { |
17681 |
+- return bnxt_get_coredump(bp, buf, &dump->len); |
17682 |
+- } |
17683 |
+- |
17684 |
+- return 0; |
17685 |
++ return bnxt_get_coredump(bp, dump->flag, buf, &dump->len); |
17686 |
+ } |
17687 |
+ |
17688 |
+ static int bnxt_get_ts_info(struct net_device *dev, |
17689 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h |
17690 |
+index 0a57cb6a4a4bf..11a719f98defd 100644 |
17691 |
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h |
17692 |
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_ethtool.h |
17693 |
+@@ -22,49 +22,6 @@ struct bnxt_led_cfg { |
17694 |
+ u8 rsvd; |
17695 |
+ }; |
17696 |
+ |
17697 |
+-#define COREDUMP_LIST_BUF_LEN 2048 |
17698 |
+-#define COREDUMP_RETRIEVE_BUF_LEN 4096 |
17699 |
+- |
17700 |
+-struct bnxt_coredump { |
17701 |
+- void *data; |
17702 |
+- int data_size; |
17703 |
+- u16 total_segs; |
17704 |
+-}; |
17705 |
+- |
17706 |
+-#define BNXT_COREDUMP_BUF_LEN(len) ((len) - sizeof(struct bnxt_coredump_record)) |
17707 |
+- |
17708 |
+-struct bnxt_hwrm_dbg_dma_info { |
17709 |
+- void *dest_buf; |
17710 |
+- int dest_buf_size; |
17711 |
+- u16 dma_len; |
17712 |
+- u16 seq_off; |
17713 |
+- u16 data_len_off; |
17714 |
+- u16 segs; |
17715 |
+- u32 seg_start; |
17716 |
+- u32 buf_len; |
17717 |
+-}; |
17718 |
+- |
17719 |
+-struct hwrm_dbg_cmn_input { |
17720 |
+- __le16 req_type; |
17721 |
+- __le16 cmpl_ring; |
17722 |
+- __le16 seq_id; |
17723 |
+- __le16 target_id; |
17724 |
+- __le64 resp_addr; |
17725 |
+- __le64 host_dest_addr; |
17726 |
+- __le32 host_buf_len; |
17727 |
+-}; |
17728 |
+- |
17729 |
+-struct hwrm_dbg_cmn_output { |
17730 |
+- __le16 error_code; |
17731 |
+- __le16 req_type; |
17732 |
+- __le16 seq_id; |
17733 |
+- __le16 resp_len; |
17734 |
+- u8 flags; |
17735 |
+- #define HWRM_DBG_CMN_FLAGS_MORE 1 |
17736 |
+-}; |
17737 |
+- |
17738 |
+-#define BNXT_CRASH_DUMP_LEN (8 << 20) |
17739 |
+- |
17740 |
+ #define BNXT_LED_DFLT_ENA \ |
17741 |
+ (PORT_LED_CFG_REQ_ENABLES_LED0_ID | \ |
17742 |
+ PORT_LED_CFG_REQ_ENABLES_LED0_STATE | \ |
17743 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c |
17744 |
+index bb7327b82d0b2..8171f4912fa01 100644 |
17745 |
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c |
17746 |
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.c |
17747 |
+@@ -496,7 +496,7 @@ static int __hwrm_send(struct bnxt *bp, struct bnxt_hwrm_ctx *ctx) |
17748 |
+ } |
17749 |
+ |
17750 |
+ /* Limit timeout to an upper limit */ |
17751 |
+- timeout = min_t(uint, ctx->timeout, HWRM_CMD_MAX_TIMEOUT); |
17752 |
++ timeout = min(ctx->timeout, bp->hwrm_cmd_max_timeout ?: HWRM_CMD_MAX_TIMEOUT); |
17753 |
+ /* convert timeout to usec */ |
17754 |
+ timeout *= 1000; |
17755 |
+ |
17756 |
+diff --git a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h |
17757 |
+index 4d17f0d5363bb..9a9fc4e8041b6 100644 |
17758 |
+--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h |
17759 |
++++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_hwrm.h |
17760 |
+@@ -58,11 +58,10 @@ void hwrm_update_token(struct bnxt *bp, u16 seq, enum bnxt_hwrm_wait_state s); |
17761 |
+ |
17762 |
+ #define BNXT_HWRM_MAX_REQ_LEN (bp->hwrm_max_req_len) |
17763 |
+ #define BNXT_HWRM_SHORT_REQ_LEN sizeof(struct hwrm_short_input) |
17764 |
+-#define HWRM_CMD_MAX_TIMEOUT 40000 |
17765 |
++#define HWRM_CMD_MAX_TIMEOUT 40000U |
17766 |
+ #define SHORT_HWRM_CMD_TIMEOUT 20 |
17767 |
+ #define HWRM_CMD_TIMEOUT (bp->hwrm_cmd_timeout) |
17768 |
+ #define HWRM_RESET_TIMEOUT ((HWRM_CMD_TIMEOUT) * 4) |
17769 |
+-#define HWRM_COREDUMP_TIMEOUT ((HWRM_CMD_TIMEOUT) * 12) |
17770 |
+ #define BNXT_HWRM_TARGET 0xffff |
17771 |
+ #define BNXT_HWRM_NO_CMPL_RING -1 |
17772 |
+ #define BNXT_HWRM_REQ_MAX_SIZE 128 |
17773 |
+diff --git a/drivers/net/ethernet/broadcom/genet/bcmgenet.c b/drivers/net/ethernet/broadcom/genet/bcmgenet.c |
17774 |
+index 23c7595d2a1d3..9a67e24f46b27 100644 |
17775 |
+--- a/drivers/net/ethernet/broadcom/genet/bcmgenet.c |
17776 |
++++ b/drivers/net/ethernet/broadcom/genet/bcmgenet.c |
17777 |
+@@ -3966,10 +3966,12 @@ static int bcmgenet_probe(struct platform_device *pdev) |
17778 |
+ |
17779 |
+ /* Request the WOL interrupt and advertise suspend if available */ |
17780 |
+ priv->wol_irq_disabled = true; |
17781 |
+- err = devm_request_irq(&pdev->dev, priv->wol_irq, bcmgenet_wol_isr, 0, |
17782 |
+- dev->name, priv); |
17783 |
+- if (!err) |
17784 |
+- device_set_wakeup_capable(&pdev->dev, 1); |
17785 |
++ if (priv->wol_irq > 0) { |
17786 |
++ err = devm_request_irq(&pdev->dev, priv->wol_irq, |
17787 |
++ bcmgenet_wol_isr, 0, dev->name, priv); |
17788 |
++ if (!err) |
17789 |
++ device_set_wakeup_capable(&pdev->dev, 1); |
17790 |
++ } |
17791 |
+ |
17792 |
+ /* Set the needed headroom to account for any possible |
17793 |
+ * features enabling/disabling at runtime |
17794 |
+diff --git a/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c b/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c |
17795 |
+index d04a6c1634452..da8d10475a08e 100644 |
17796 |
+--- a/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c |
17797 |
++++ b/drivers/net/ethernet/chelsio/libcxgb/libcxgb_cm.c |
17798 |
+@@ -32,6 +32,7 @@ |
17799 |
+ |
17800 |
+ #include <linux/tcp.h> |
17801 |
+ #include <linux/ipv6.h> |
17802 |
++#include <net/inet_ecn.h> |
17803 |
+ #include <net/route.h> |
17804 |
+ #include <net/ip6_route.h> |
17805 |
+ |
17806 |
+@@ -99,7 +100,7 @@ cxgb_find_route(struct cxgb4_lld_info *lldi, |
17807 |
+ |
17808 |
+ rt = ip_route_output_ports(&init_net, &fl4, NULL, peer_ip, local_ip, |
17809 |
+ peer_port, local_port, IPPROTO_TCP, |
17810 |
+- tos, 0); |
17811 |
++ tos & ~INET_ECN_MASK, 0); |
17812 |
+ if (IS_ERR(rt)) |
17813 |
+ return NULL; |
17814 |
+ n = dst_neigh_lookup(&rt->dst, &peer_ip); |
17815 |
+diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c |
17816 |
+index 6e745ca4c4333..012ca11a38cc1 100644 |
17817 |
+--- a/drivers/net/ethernet/cortina/gemini.c |
17818 |
++++ b/drivers/net/ethernet/cortina/gemini.c |
17819 |
+@@ -305,21 +305,21 @@ static void gmac_speed_set(struct net_device *netdev) |
17820 |
+ switch (phydev->speed) { |
17821 |
+ case 1000: |
17822 |
+ status.bits.speed = GMAC_SPEED_1000; |
17823 |
+- if (phydev->interface == PHY_INTERFACE_MODE_RGMII) |
17824 |
++ if (phy_interface_mode_is_rgmii(phydev->interface)) |
17825 |
+ status.bits.mii_rmii = GMAC_PHY_RGMII_1000; |
17826 |
+ netdev_dbg(netdev, "connect %s to RGMII @ 1Gbit\n", |
17827 |
+ phydev_name(phydev)); |
17828 |
+ break; |
17829 |
+ case 100: |
17830 |
+ status.bits.speed = GMAC_SPEED_100; |
17831 |
+- if (phydev->interface == PHY_INTERFACE_MODE_RGMII) |
17832 |
++ if (phy_interface_mode_is_rgmii(phydev->interface)) |
17833 |
+ status.bits.mii_rmii = GMAC_PHY_RGMII_100_10; |
17834 |
+ netdev_dbg(netdev, "connect %s to RGMII @ 100 Mbit\n", |
17835 |
+ phydev_name(phydev)); |
17836 |
+ break; |
17837 |
+ case 10: |
17838 |
+ status.bits.speed = GMAC_SPEED_10; |
17839 |
+- if (phydev->interface == PHY_INTERFACE_MODE_RGMII) |
17840 |
++ if (phy_interface_mode_is_rgmii(phydev->interface)) |
17841 |
+ status.bits.mii_rmii = GMAC_PHY_RGMII_100_10; |
17842 |
+ netdev_dbg(netdev, "connect %s to RGMII @ 10 Mbit\n", |
17843 |
+ phydev_name(phydev)); |
17844 |
+@@ -389,6 +389,9 @@ static int gmac_setup_phy(struct net_device *netdev) |
17845 |
+ status.bits.mii_rmii = GMAC_PHY_GMII; |
17846 |
+ break; |
17847 |
+ case PHY_INTERFACE_MODE_RGMII: |
17848 |
++ case PHY_INTERFACE_MODE_RGMII_ID: |
17849 |
++ case PHY_INTERFACE_MODE_RGMII_TXID: |
17850 |
++ case PHY_INTERFACE_MODE_RGMII_RXID: |
17851 |
+ netdev_dbg(netdev, |
17852 |
+ "RGMII: set GMAC0 and GMAC1 to MII/RGMII mode\n"); |
17853 |
+ status.bits.mii_rmii = GMAC_PHY_RGMII_100_10; |
17854 |
+diff --git a/drivers/net/ethernet/freescale/fman/mac.c b/drivers/net/ethernet/freescale/fman/mac.c |
17855 |
+index d9fc5c456bf3e..39ae965cd4f64 100644 |
17856 |
+--- a/drivers/net/ethernet/freescale/fman/mac.c |
17857 |
++++ b/drivers/net/ethernet/freescale/fman/mac.c |
17858 |
+@@ -94,14 +94,17 @@ static void mac_exception(void *handle, enum fman_mac_exceptions ex) |
17859 |
+ __func__, ex); |
17860 |
+ } |
17861 |
+ |
17862 |
+-static void set_fman_mac_params(struct mac_device *mac_dev, |
17863 |
+- struct fman_mac_params *params) |
17864 |
++static int set_fman_mac_params(struct mac_device *mac_dev, |
17865 |
++ struct fman_mac_params *params) |
17866 |
+ { |
17867 |
+ struct mac_priv_s *priv = mac_dev->priv; |
17868 |
+ |
17869 |
+ params->base_addr = (typeof(params->base_addr)) |
17870 |
+ devm_ioremap(priv->dev, mac_dev->res->start, |
17871 |
+ resource_size(mac_dev->res)); |
17872 |
++ if (!params->base_addr) |
17873 |
++ return -ENOMEM; |
17874 |
++ |
17875 |
+ memcpy(¶ms->addr, mac_dev->addr, sizeof(mac_dev->addr)); |
17876 |
+ params->max_speed = priv->max_speed; |
17877 |
+ params->phy_if = mac_dev->phy_if; |
17878 |
+@@ -112,6 +115,8 @@ static void set_fman_mac_params(struct mac_device *mac_dev, |
17879 |
+ params->event_cb = mac_exception; |
17880 |
+ params->dev_id = mac_dev; |
17881 |
+ params->internal_phy_node = priv->internal_phy_node; |
17882 |
++ |
17883 |
++ return 0; |
17884 |
+ } |
17885 |
+ |
17886 |
+ static int tgec_initialization(struct mac_device *mac_dev) |
17887 |
+@@ -123,7 +128,9 @@ static int tgec_initialization(struct mac_device *mac_dev) |
17888 |
+ |
17889 |
+ priv = mac_dev->priv; |
17890 |
+ |
17891 |
+- set_fman_mac_params(mac_dev, ¶ms); |
17892 |
++ err = set_fman_mac_params(mac_dev, ¶ms); |
17893 |
++ if (err) |
17894 |
++ goto _return; |
17895 |
+ |
17896 |
+ mac_dev->fman_mac = tgec_config(¶ms); |
17897 |
+ if (!mac_dev->fman_mac) { |
17898 |
+@@ -169,7 +176,9 @@ static int dtsec_initialization(struct mac_device *mac_dev) |
17899 |
+ |
17900 |
+ priv = mac_dev->priv; |
17901 |
+ |
17902 |
+- set_fman_mac_params(mac_dev, ¶ms); |
17903 |
++ err = set_fman_mac_params(mac_dev, ¶ms); |
17904 |
++ if (err) |
17905 |
++ goto _return; |
17906 |
+ |
17907 |
+ mac_dev->fman_mac = dtsec_config(¶ms); |
17908 |
+ if (!mac_dev->fman_mac) { |
17909 |
+@@ -218,7 +227,9 @@ static int memac_initialization(struct mac_device *mac_dev) |
17910 |
+ |
17911 |
+ priv = mac_dev->priv; |
17912 |
+ |
17913 |
+- set_fman_mac_params(mac_dev, ¶ms); |
17914 |
++ err = set_fman_mac_params(mac_dev, ¶ms); |
17915 |
++ if (err) |
17916 |
++ goto _return; |
17917 |
+ |
17918 |
+ if (priv->max_speed == SPEED_10000) |
17919 |
+ params.phy_if = PHY_INTERFACE_MODE_XGMII; |
17920 |
+diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c b/drivers/net/ethernet/freescale/xgmac_mdio.c |
17921 |
+index 0b68852379da5..27d07468765f0 100644 |
17922 |
+--- a/drivers/net/ethernet/freescale/xgmac_mdio.c |
17923 |
++++ b/drivers/net/ethernet/freescale/xgmac_mdio.c |
17924 |
+@@ -52,6 +52,7 @@ struct tgec_mdio_controller { |
17925 |
+ struct mdio_fsl_priv { |
17926 |
+ struct tgec_mdio_controller __iomem *mdio_base; |
17927 |
+ bool is_little_endian; |
17928 |
++ bool has_a009885; |
17929 |
+ bool has_a011043; |
17930 |
+ }; |
17931 |
+ |
17932 |
+@@ -187,10 +188,10 @@ static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum) |
17933 |
+ { |
17934 |
+ struct mdio_fsl_priv *priv = (struct mdio_fsl_priv *)bus->priv; |
17935 |
+ struct tgec_mdio_controller __iomem *regs = priv->mdio_base; |
17936 |
++ unsigned long flags; |
17937 |
+ uint16_t dev_addr; |
17938 |
+ uint32_t mdio_stat; |
17939 |
+ uint32_t mdio_ctl; |
17940 |
+- uint16_t value; |
17941 |
+ int ret; |
17942 |
+ bool endian = priv->is_little_endian; |
17943 |
+ |
17944 |
+@@ -222,12 +223,18 @@ static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum) |
17945 |
+ return ret; |
17946 |
+ } |
17947 |
+ |
17948 |
++ if (priv->has_a009885) |
17949 |
++ /* Once the operation completes, i.e. MDIO_STAT_BSY clears, we |
17950 |
++ * must read back the data register within 16 MDC cycles. |
17951 |
++ */ |
17952 |
++ local_irq_save(flags); |
17953 |
++ |
17954 |
+ /* Initiate the read */ |
17955 |
+ xgmac_write32(mdio_ctl | MDIO_CTL_READ, ®s->mdio_ctl, endian); |
17956 |
+ |
17957 |
+ ret = xgmac_wait_until_done(&bus->dev, regs, endian); |
17958 |
+ if (ret) |
17959 |
+- return ret; |
17960 |
++ goto irq_restore; |
17961 |
+ |
17962 |
+ /* Return all Fs if nothing was there */ |
17963 |
+ if ((xgmac_read32(®s->mdio_stat, endian) & MDIO_STAT_RD_ER) && |
17964 |
+@@ -235,13 +242,17 @@ static int xgmac_mdio_read(struct mii_bus *bus, int phy_id, int regnum) |
17965 |
+ dev_dbg(&bus->dev, |
17966 |
+ "Error while reading PHY%d reg at %d.%hhu\n", |
17967 |
+ phy_id, dev_addr, regnum); |
17968 |
+- return 0xffff; |
17969 |
++ ret = 0xffff; |
17970 |
++ } else { |
17971 |
++ ret = xgmac_read32(®s->mdio_data, endian) & 0xffff; |
17972 |
++ dev_dbg(&bus->dev, "read %04x\n", ret); |
17973 |
+ } |
17974 |
+ |
17975 |
+- value = xgmac_read32(®s->mdio_data, endian) & 0xffff; |
17976 |
+- dev_dbg(&bus->dev, "read %04x\n", value); |
17977 |
++irq_restore: |
17978 |
++ if (priv->has_a009885) |
17979 |
++ local_irq_restore(flags); |
17980 |
+ |
17981 |
+- return value; |
17982 |
++ return ret; |
17983 |
+ } |
17984 |
+ |
17985 |
+ static int xgmac_mdio_probe(struct platform_device *pdev) |
17986 |
+@@ -288,6 +299,8 @@ static int xgmac_mdio_probe(struct platform_device *pdev) |
17987 |
+ priv->is_little_endian = device_property_read_bool(&pdev->dev, |
17988 |
+ "little-endian"); |
17989 |
+ |
17990 |
++ priv->has_a009885 = device_property_read_bool(&pdev->dev, |
17991 |
++ "fsl,erratum-a009885"); |
17992 |
+ priv->has_a011043 = device_property_read_bool(&pdev->dev, |
17993 |
+ "fsl,erratum-a011043"); |
17994 |
+ |
17995 |
+@@ -319,9 +332,10 @@ err_ioremap: |
17996 |
+ static int xgmac_mdio_remove(struct platform_device *pdev) |
17997 |
+ { |
17998 |
+ struct mii_bus *bus = platform_get_drvdata(pdev); |
17999 |
++ struct mdio_fsl_priv *priv = bus->priv; |
18000 |
+ |
18001 |
+ mdiobus_unregister(bus); |
18002 |
+- iounmap(bus->priv); |
18003 |
++ iounmap(priv->mdio_base); |
18004 |
+ mdiobus_free(bus); |
18005 |
+ |
18006 |
+ return 0; |
18007 |
+diff --git a/drivers/net/ethernet/i825xx/sni_82596.c b/drivers/net/ethernet/i825xx/sni_82596.c |
18008 |
+index 27937c5d79567..daec9ce04531b 100644 |
18009 |
+--- a/drivers/net/ethernet/i825xx/sni_82596.c |
18010 |
++++ b/drivers/net/ethernet/i825xx/sni_82596.c |
18011 |
+@@ -117,9 +117,10 @@ static int sni_82596_probe(struct platform_device *dev) |
18012 |
+ netdevice->dev_addr[5] = readb(eth_addr + 0x06); |
18013 |
+ iounmap(eth_addr); |
18014 |
+ |
18015 |
+- if (!netdevice->irq) { |
18016 |
++ if (netdevice->irq < 0) { |
18017 |
+ printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n", |
18018 |
+ __FILE__, netdevice->base_addr); |
18019 |
++ retval = netdevice->irq; |
18020 |
+ goto probe_failed; |
18021 |
+ } |
18022 |
+ |
18023 |
+diff --git a/drivers/net/ethernet/intel/igc/igc_main.c b/drivers/net/ethernet/intel/igc/igc_main.c |
18024 |
+index 0a96627391a8c..c7fa978cdf02e 100644 |
18025 |
+--- a/drivers/net/ethernet/intel/igc/igc_main.c |
18026 |
++++ b/drivers/net/ethernet/intel/igc/igc_main.c |
18027 |
+@@ -2447,8 +2447,10 @@ static struct sk_buff *igc_construct_skb_zc(struct igc_ring *ring, |
18028 |
+ |
18029 |
+ skb_reserve(skb, xdp->data_meta - xdp->data_hard_start); |
18030 |
+ memcpy(__skb_put(skb, totalsize), xdp->data_meta, totalsize); |
18031 |
+- if (metasize) |
18032 |
++ if (metasize) { |
18033 |
+ skb_metadata_set(skb, metasize); |
18034 |
++ __skb_pull(skb, metasize); |
18035 |
++ } |
18036 |
+ |
18037 |
+ return skb; |
18038 |
+ } |
18039 |
+diff --git a/drivers/net/ethernet/marvell/octeontx2/af/ptp.c b/drivers/net/ethernet/marvell/octeontx2/af/ptp.c |
18040 |
+index 9b8e59f4c206d..77cb52b80c60f 100644 |
18041 |
+--- a/drivers/net/ethernet/marvell/octeontx2/af/ptp.c |
18042 |
++++ b/drivers/net/ethernet/marvell/octeontx2/af/ptp.c |
18043 |
+@@ -85,6 +85,8 @@ struct ptp *ptp_get(void) |
18044 |
+ /* Check driver is bound to PTP block */ |
18045 |
+ if (!ptp) |
18046 |
+ ptp = ERR_PTR(-EPROBE_DEFER); |
18047 |
++ else |
18048 |
++ pci_dev_get(ptp->pdev); |
18049 |
+ |
18050 |
+ return ptp; |
18051 |
+ } |
18052 |
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c |
18053 |
+index 398c23cec8151..ee1fd472e9252 100644 |
18054 |
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c |
18055 |
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c |
18056 |
+@@ -91,46 +91,53 @@ static int mtk_mdio_busy_wait(struct mtk_eth *eth) |
18057 |
+ } |
18058 |
+ |
18059 |
+ dev_err(eth->dev, "mdio: MDIO timeout\n"); |
18060 |
+- return -1; |
18061 |
++ return -ETIMEDOUT; |
18062 |
+ } |
18063 |
+ |
18064 |
+-static u32 _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, |
18065 |
+- u32 phy_register, u32 write_data) |
18066 |
++static int _mtk_mdio_write(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg, |
18067 |
++ u32 write_data) |
18068 |
+ { |
18069 |
+- if (mtk_mdio_busy_wait(eth)) |
18070 |
+- return -1; |
18071 |
++ int ret; |
18072 |
+ |
18073 |
+- write_data &= 0xffff; |
18074 |
++ ret = mtk_mdio_busy_wait(eth); |
18075 |
++ if (ret < 0) |
18076 |
++ return ret; |
18077 |
+ |
18078 |
+- mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_WRITE | |
18079 |
+- (phy_register << PHY_IAC_REG_SHIFT) | |
18080 |
+- (phy_addr << PHY_IAC_ADDR_SHIFT) | write_data, |
18081 |
++ mtk_w32(eth, PHY_IAC_ACCESS | |
18082 |
++ PHY_IAC_START_C22 | |
18083 |
++ PHY_IAC_CMD_WRITE | |
18084 |
++ PHY_IAC_REG(phy_reg) | |
18085 |
++ PHY_IAC_ADDR(phy_addr) | |
18086 |
++ PHY_IAC_DATA(write_data), |
18087 |
+ MTK_PHY_IAC); |
18088 |
+ |
18089 |
+- if (mtk_mdio_busy_wait(eth)) |
18090 |
+- return -1; |
18091 |
++ ret = mtk_mdio_busy_wait(eth); |
18092 |
++ if (ret < 0) |
18093 |
++ return ret; |
18094 |
+ |
18095 |
+ return 0; |
18096 |
+ } |
18097 |
+ |
18098 |
+-static u32 _mtk_mdio_read(struct mtk_eth *eth, int phy_addr, int phy_reg) |
18099 |
++static int _mtk_mdio_read(struct mtk_eth *eth, u32 phy_addr, u32 phy_reg) |
18100 |
+ { |
18101 |
+- u32 d; |
18102 |
++ int ret; |
18103 |
+ |
18104 |
+- if (mtk_mdio_busy_wait(eth)) |
18105 |
+- return 0xffff; |
18106 |
++ ret = mtk_mdio_busy_wait(eth); |
18107 |
++ if (ret < 0) |
18108 |
++ return ret; |
18109 |
+ |
18110 |
+- mtk_w32(eth, PHY_IAC_ACCESS | PHY_IAC_START | PHY_IAC_READ | |
18111 |
+- (phy_reg << PHY_IAC_REG_SHIFT) | |
18112 |
+- (phy_addr << PHY_IAC_ADDR_SHIFT), |
18113 |
++ mtk_w32(eth, PHY_IAC_ACCESS | |
18114 |
++ PHY_IAC_START_C22 | |
18115 |
++ PHY_IAC_CMD_C22_READ | |
18116 |
++ PHY_IAC_REG(phy_reg) | |
18117 |
++ PHY_IAC_ADDR(phy_addr), |
18118 |
+ MTK_PHY_IAC); |
18119 |
+ |
18120 |
+- if (mtk_mdio_busy_wait(eth)) |
18121 |
+- return 0xffff; |
18122 |
+- |
18123 |
+- d = mtk_r32(eth, MTK_PHY_IAC) & 0xffff; |
18124 |
++ ret = mtk_mdio_busy_wait(eth); |
18125 |
++ if (ret < 0) |
18126 |
++ return ret; |
18127 |
+ |
18128 |
+- return d; |
18129 |
++ return mtk_r32(eth, MTK_PHY_IAC) & PHY_IAC_DATA_MASK; |
18130 |
+ } |
18131 |
+ |
18132 |
+ static int mtk_mdio_write(struct mii_bus *bus, int phy_addr, |
18133 |
+@@ -217,7 +224,7 @@ static void mtk_mac_config(struct phylink_config *config, unsigned int mode, |
18134 |
+ phylink_config); |
18135 |
+ struct mtk_eth *eth = mac->hw; |
18136 |
+ u32 mcr_cur, mcr_new, sid, i; |
18137 |
+- int val, ge_mode, err; |
18138 |
++ int val, ge_mode, err = 0; |
18139 |
+ |
18140 |
+ /* MT76x8 has no hardware settings between for the MAC */ |
18141 |
+ if (!MTK_HAS_CAPS(eth->soc->caps, MTK_SOC_MT7628) && |
18142 |
+diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h |
18143 |
+index 5ef70dd8b49c6..f2d90639d7ed1 100644 |
18144 |
+--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h |
18145 |
++++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h |
18146 |
+@@ -341,11 +341,17 @@ |
18147 |
+ /* PHY Indirect Access Control registers */ |
18148 |
+ #define MTK_PHY_IAC 0x10004 |
18149 |
+ #define PHY_IAC_ACCESS BIT(31) |
18150 |
+-#define PHY_IAC_READ BIT(19) |
18151 |
+-#define PHY_IAC_WRITE BIT(18) |
18152 |
+-#define PHY_IAC_START BIT(16) |
18153 |
+-#define PHY_IAC_ADDR_SHIFT 20 |
18154 |
+-#define PHY_IAC_REG_SHIFT 25 |
18155 |
++#define PHY_IAC_REG_MASK GENMASK(29, 25) |
18156 |
++#define PHY_IAC_REG(x) FIELD_PREP(PHY_IAC_REG_MASK, (x)) |
18157 |
++#define PHY_IAC_ADDR_MASK GENMASK(24, 20) |
18158 |
++#define PHY_IAC_ADDR(x) FIELD_PREP(PHY_IAC_ADDR_MASK, (x)) |
18159 |
++#define PHY_IAC_CMD_MASK GENMASK(19, 18) |
18160 |
++#define PHY_IAC_CMD_WRITE FIELD_PREP(PHY_IAC_CMD_MASK, 1) |
18161 |
++#define PHY_IAC_CMD_C22_READ FIELD_PREP(PHY_IAC_CMD_MASK, 2) |
18162 |
++#define PHY_IAC_START_MASK GENMASK(17, 16) |
18163 |
++#define PHY_IAC_START_C22 FIELD_PREP(PHY_IAC_START_MASK, 1) |
18164 |
++#define PHY_IAC_DATA_MASK GENMASK(15, 0) |
18165 |
++#define PHY_IAC_DATA(x) FIELD_PREP(PHY_IAC_DATA_MASK, (x)) |
18166 |
+ #define PHY_IAC_TIMEOUT HZ |
18167 |
+ |
18168 |
+ #define MTK_MAC_MISC 0x1000c |
18169 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c |
18170 |
+index bea35530c2d0b..00f63fbfe9b48 100644 |
18171 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/cmd.c |
18172 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/cmd.c |
18173 |
+@@ -147,8 +147,12 @@ static void cmd_ent_put(struct mlx5_cmd_work_ent *ent) |
18174 |
+ if (!refcount_dec_and_test(&ent->refcnt)) |
18175 |
+ return; |
18176 |
+ |
18177 |
+- if (ent->idx >= 0) |
18178 |
+- cmd_free_index(ent->cmd, ent->idx); |
18179 |
++ if (ent->idx >= 0) { |
18180 |
++ struct mlx5_cmd *cmd = ent->cmd; |
18181 |
++ |
18182 |
++ cmd_free_index(cmd, ent->idx); |
18183 |
++ up(ent->page_queue ? &cmd->pages_sem : &cmd->sem); |
18184 |
++ } |
18185 |
+ |
18186 |
+ cmd_free_ent(ent); |
18187 |
+ } |
18188 |
+@@ -895,25 +899,6 @@ static bool opcode_allowed(struct mlx5_cmd *cmd, u16 opcode) |
18189 |
+ return cmd->allowed_opcode == opcode; |
18190 |
+ } |
18191 |
+ |
18192 |
+-static int cmd_alloc_index_retry(struct mlx5_cmd *cmd) |
18193 |
+-{ |
18194 |
+- unsigned long alloc_end = jiffies + msecs_to_jiffies(1000); |
18195 |
+- int idx; |
18196 |
+- |
18197 |
+-retry: |
18198 |
+- idx = cmd_alloc_index(cmd); |
18199 |
+- if (idx < 0 && time_before(jiffies, alloc_end)) { |
18200 |
+- /* Index allocation can fail on heavy load of commands. This is a temporary |
18201 |
+- * situation as the current command already holds the semaphore, meaning that |
18202 |
+- * another command completion is being handled and it is expected to release |
18203 |
+- * the entry index soon. |
18204 |
+- */ |
18205 |
+- cpu_relax(); |
18206 |
+- goto retry; |
18207 |
+- } |
18208 |
+- return idx; |
18209 |
+-} |
18210 |
+- |
18211 |
+ bool mlx5_cmd_is_down(struct mlx5_core_dev *dev) |
18212 |
+ { |
18213 |
+ return pci_channel_offline(dev->pdev) || |
18214 |
+@@ -938,7 +923,7 @@ static void cmd_work_handler(struct work_struct *work) |
18215 |
+ sem = ent->page_queue ? &cmd->pages_sem : &cmd->sem; |
18216 |
+ down(sem); |
18217 |
+ if (!ent->page_queue) { |
18218 |
+- alloc_ret = cmd_alloc_index_retry(cmd); |
18219 |
++ alloc_ret = cmd_alloc_index(cmd); |
18220 |
+ if (alloc_ret < 0) { |
18221 |
+ mlx5_core_err_rl(dev, "failed to allocate command entry\n"); |
18222 |
+ if (ent->callback) { |
18223 |
+@@ -1594,8 +1579,6 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force |
18224 |
+ vector = vec & 0xffffffff; |
18225 |
+ for (i = 0; i < (1 << cmd->log_sz); i++) { |
18226 |
+ if (test_bit(i, &vector)) { |
18227 |
+- struct semaphore *sem; |
18228 |
+- |
18229 |
+ ent = cmd->ent_arr[i]; |
18230 |
+ |
18231 |
+ /* if we already completed the command, ignore it */ |
18232 |
+@@ -1618,10 +1601,6 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force |
18233 |
+ dev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) |
18234 |
+ cmd_ent_put(ent); |
18235 |
+ |
18236 |
+- if (ent->page_queue) |
18237 |
+- sem = &cmd->pages_sem; |
18238 |
+- else |
18239 |
+- sem = &cmd->sem; |
18240 |
+ ent->ts2 = ktime_get_ns(); |
18241 |
+ memcpy(ent->out->first.data, ent->lay->out, sizeof(ent->lay->out)); |
18242 |
+ dump_command(dev, ent, 0); |
18243 |
+@@ -1675,7 +1654,6 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force |
18244 |
+ */ |
18245 |
+ complete(&ent->done); |
18246 |
+ } |
18247 |
+- up(sem); |
18248 |
+ } |
18249 |
+ } |
18250 |
+ } |
18251 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c |
18252 |
+index 4a13ef561587d..cf03297c84710 100644 |
18253 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c |
18254 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun.c |
18255 |
+@@ -1,6 +1,7 @@ |
18256 |
+ /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */ |
18257 |
+ /* Copyright (c) 2018 Mellanox Technologies. */ |
18258 |
+ |
18259 |
++#include <net/inet_ecn.h> |
18260 |
+ #include <net/vxlan.h> |
18261 |
+ #include <net/gre.h> |
18262 |
+ #include <net/geneve.h> |
18263 |
+@@ -229,7 +230,7 @@ int mlx5e_tc_tun_create_header_ipv4(struct mlx5e_priv *priv, |
18264 |
+ int err; |
18265 |
+ |
18266 |
+ /* add the IP fields */ |
18267 |
+- attr.fl.fl4.flowi4_tos = tun_key->tos; |
18268 |
++ attr.fl.fl4.flowi4_tos = tun_key->tos & ~INET_ECN_MASK; |
18269 |
+ attr.fl.fl4.daddr = tun_key->u.ipv4.dst; |
18270 |
+ attr.fl.fl4.saddr = tun_key->u.ipv4.src; |
18271 |
+ attr.ttl = tun_key->ttl; |
18272 |
+@@ -344,7 +345,7 @@ int mlx5e_tc_tun_update_header_ipv4(struct mlx5e_priv *priv, |
18273 |
+ int err; |
18274 |
+ |
18275 |
+ /* add the IP fields */ |
18276 |
+- attr.fl.fl4.flowi4_tos = tun_key->tos; |
18277 |
++ attr.fl.fl4.flowi4_tos = tun_key->tos & ~INET_ECN_MASK; |
18278 |
+ attr.fl.fl4.daddr = tun_key->u.ipv4.dst; |
18279 |
+ attr.fl.fl4.saddr = tun_key->u.ipv4.src; |
18280 |
+ attr.ttl = tun_key->ttl; |
18281 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c |
18282 |
+index ec0163d75dd25..700c463ea3679 100644 |
18283 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c |
18284 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc_tun_encap.c |
18285 |
+@@ -1544,6 +1544,8 @@ mlx5e_init_fib_work_ipv4(struct mlx5e_priv *priv, |
18286 |
+ struct net_device *fib_dev; |
18287 |
+ |
18288 |
+ fen_info = container_of(info, struct fib_entry_notifier_info, info); |
18289 |
++ if (fen_info->fi->nh) |
18290 |
++ return NULL; |
18291 |
+ fib_dev = fib_info_nh(fen_info->fi, 0)->fib_nh_dev; |
18292 |
+ if (!fib_dev || fib_dev->netdev_ops != &mlx5e_netdev_ops || |
18293 |
+ fen_info->dst_len != 32) |
18294 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/pool.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/pool.c |
18295 |
+index 7b562d2c8a196..279cd8f4e79f7 100644 |
18296 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/pool.c |
18297 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/pool.c |
18298 |
+@@ -11,13 +11,13 @@ static int mlx5e_xsk_map_pool(struct mlx5e_priv *priv, |
18299 |
+ { |
18300 |
+ struct device *dev = mlx5_core_dma_dev(priv->mdev); |
18301 |
+ |
18302 |
+- return xsk_pool_dma_map(pool, dev, 0); |
18303 |
++ return xsk_pool_dma_map(pool, dev, DMA_ATTR_SKIP_CPU_SYNC); |
18304 |
+ } |
18305 |
+ |
18306 |
+ static void mlx5e_xsk_unmap_pool(struct mlx5e_priv *priv, |
18307 |
+ struct xsk_buff_pool *pool) |
18308 |
+ { |
18309 |
+- return xsk_pool_dma_unmap(pool, 0); |
18310 |
++ return xsk_pool_dma_unmap(pool, DMA_ATTR_SKIP_CPU_SYNC); |
18311 |
+ } |
18312 |
+ |
18313 |
+ static int mlx5e_xsk_get_pools(struct mlx5e_xsk *xsk) |
18314 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c |
18315 |
+index baa0d7d48fc0c..f075bb8ccd00d 100644 |
18316 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c |
18317 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c |
18318 |
+@@ -4485,15 +4485,22 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev) |
18319 |
+ } |
18320 |
+ |
18321 |
+ if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev)) { |
18322 |
+- netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL; |
18323 |
+- netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL; |
18324 |
+- netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL; |
18325 |
++ netdev->hw_features |= NETIF_F_GSO_UDP_TUNNEL | |
18326 |
++ NETIF_F_GSO_UDP_TUNNEL_CSUM; |
18327 |
++ netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL | |
18328 |
++ NETIF_F_GSO_UDP_TUNNEL_CSUM; |
18329 |
++ netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM; |
18330 |
++ netdev->vlan_features |= NETIF_F_GSO_UDP_TUNNEL | |
18331 |
++ NETIF_F_GSO_UDP_TUNNEL_CSUM; |
18332 |
+ } |
18333 |
+ |
18334 |
+ if (mlx5e_tunnel_proto_supported_tx(mdev, IPPROTO_GRE)) { |
18335 |
+- netdev->hw_features |= NETIF_F_GSO_GRE; |
18336 |
+- netdev->hw_enc_features |= NETIF_F_GSO_GRE; |
18337 |
+- netdev->gso_partial_features |= NETIF_F_GSO_GRE; |
18338 |
++ netdev->hw_features |= NETIF_F_GSO_GRE | |
18339 |
++ NETIF_F_GSO_GRE_CSUM; |
18340 |
++ netdev->hw_enc_features |= NETIF_F_GSO_GRE | |
18341 |
++ NETIF_F_GSO_GRE_CSUM; |
18342 |
++ netdev->gso_partial_features |= NETIF_F_GSO_GRE | |
18343 |
++ NETIF_F_GSO_GRE_CSUM; |
18344 |
+ } |
18345 |
+ |
18346 |
+ if (mlx5e_tunnel_proto_supported_tx(mdev, IPPROTO_IPIP)) { |
18347 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c |
18348 |
+index edecd149dcab3..161b60e1139b3 100644 |
18349 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c |
18350 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c |
18351 |
+@@ -50,6 +50,7 @@ |
18352 |
+ #include "fs_core.h" |
18353 |
+ #include "lib/mlx5.h" |
18354 |
+ #include "lib/devcom.h" |
18355 |
++#include "lib/vxlan.h" |
18356 |
+ #define CREATE_TRACE_POINTS |
18357 |
+ #include "diag/en_rep_tracepoint.h" |
18358 |
+ #include "en_accel/ipsec.h" |
18359 |
+@@ -1016,6 +1017,7 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv) |
18360 |
+ rtnl_lock(); |
18361 |
+ if (netif_running(netdev)) |
18362 |
+ mlx5e_open(netdev); |
18363 |
++ udp_tunnel_nic_reset_ntf(priv->netdev); |
18364 |
+ netif_device_attach(netdev); |
18365 |
+ rtnl_unlock(); |
18366 |
+ } |
18367 |
+@@ -1037,6 +1039,7 @@ static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv) |
18368 |
+ mlx5_notifier_unregister(mdev, &priv->events_nb); |
18369 |
+ mlx5e_rep_tc_disable(priv); |
18370 |
+ mlx5_lag_remove_netdev(mdev, priv->netdev); |
18371 |
++ mlx5_vxlan_reset_to_default(mdev->vxlan); |
18372 |
+ } |
18373 |
+ |
18374 |
+ static MLX5E_DEFINE_STATS_GRP(sw_rep, 0); |
18375 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c |
18376 |
+index 29a6586ef28dc..0015545d5235b 100644 |
18377 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c |
18378 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rx.c |
18379 |
+@@ -271,8 +271,8 @@ static inline int mlx5e_page_alloc_pool(struct mlx5e_rq *rq, |
18380 |
+ if (unlikely(!dma_info->page)) |
18381 |
+ return -ENOMEM; |
18382 |
+ |
18383 |
+- dma_info->addr = dma_map_page(rq->pdev, dma_info->page, 0, |
18384 |
+- PAGE_SIZE, rq->buff.map_dir); |
18385 |
++ dma_info->addr = dma_map_page_attrs(rq->pdev, dma_info->page, 0, PAGE_SIZE, |
18386 |
++ rq->buff.map_dir, DMA_ATTR_SKIP_CPU_SYNC); |
18387 |
+ if (unlikely(dma_mapping_error(rq->pdev, dma_info->addr))) { |
18388 |
+ page_pool_recycle_direct(rq->page_pool, dma_info->page); |
18389 |
+ dma_info->page = NULL; |
18390 |
+@@ -293,7 +293,8 @@ static inline int mlx5e_page_alloc(struct mlx5e_rq *rq, |
18391 |
+ |
18392 |
+ void mlx5e_page_dma_unmap(struct mlx5e_rq *rq, struct mlx5e_dma_info *dma_info) |
18393 |
+ { |
18394 |
+- dma_unmap_page(rq->pdev, dma_info->addr, PAGE_SIZE, rq->buff.map_dir); |
18395 |
++ dma_unmap_page_attrs(rq->pdev, dma_info->addr, PAGE_SIZE, rq->buff.map_dir, |
18396 |
++ DMA_ATTR_SKIP_CPU_SYNC); |
18397 |
+ } |
18398 |
+ |
18399 |
+ void mlx5e_page_release_dynamic(struct mlx5e_rq *rq, |
18400 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c |
18401 |
+index fa461bc57baee..8b041deb25e5f 100644 |
18402 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c |
18403 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/en_tc.c |
18404 |
+@@ -1874,6 +1874,111 @@ u8 mlx5e_tc_get_ip_version(struct mlx5_flow_spec *spec, bool outer) |
18405 |
+ return ip_version; |
18406 |
+ } |
18407 |
+ |
18408 |
++/* Tunnel device follows RFC 6040, see include/net/inet_ecn.h. |
18409 |
++ * And changes inner ip_ecn depending on inner and outer ip_ecn as follows: |
18410 |
++ * +---------+----------------------------------------+ |
18411 |
++ * |Arriving | Arriving Outer Header | |
18412 |
++ * | Inner +---------+---------+---------+----------+ |
18413 |
++ * | Header | Not-ECT | ECT(0) | ECT(1) | CE | |
18414 |
++ * +---------+---------+---------+---------+----------+ |
18415 |
++ * | Not-ECT | Not-ECT | Not-ECT | Not-ECT | <drop> | |
18416 |
++ * | ECT(0) | ECT(0) | ECT(0) | ECT(1) | CE* | |
18417 |
++ * | ECT(1) | ECT(1) | ECT(1) | ECT(1)* | CE* | |
18418 |
++ * | CE | CE | CE | CE | CE | |
18419 |
++ * +---------+---------+---------+---------+----------+ |
18420 |
++ * |
18421 |
++ * Tc matches on inner after decapsulation on tunnel device, but hw offload matches |
18422 |
++ * the inner ip_ecn value before hardware decap action. |
18423 |
++ * |
18424 |
++ * Cells marked are changed from original inner packet ip_ecn value during decap, and |
18425 |
++ * so matching those values on inner ip_ecn before decap will fail. |
18426 |
++ * |
18427 |
++ * The following helper allows offload when inner ip_ecn won't be changed by outer ip_ecn, |
18428 |
++ * except for the outer ip_ecn = CE, where in all cases inner ip_ecn will be changed to CE, |
18429 |
++ * and such we can drop the inner ip_ecn=CE match. |
18430 |
++ */ |
18431 |
++ |
18432 |
++static int mlx5e_tc_verify_tunnel_ecn(struct mlx5e_priv *priv, |
18433 |
++ struct flow_cls_offload *f, |
18434 |
++ bool *match_inner_ecn) |
18435 |
++{ |
18436 |
++ u8 outer_ecn_mask = 0, outer_ecn_key = 0, inner_ecn_mask = 0, inner_ecn_key = 0; |
18437 |
++ struct flow_rule *rule = flow_cls_offload_flow_rule(f); |
18438 |
++ struct netlink_ext_ack *extack = f->common.extack; |
18439 |
++ struct flow_match_ip match; |
18440 |
++ |
18441 |
++ *match_inner_ecn = true; |
18442 |
++ |
18443 |
++ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_ENC_IP)) { |
18444 |
++ flow_rule_match_enc_ip(rule, &match); |
18445 |
++ outer_ecn_key = match.key->tos & INET_ECN_MASK; |
18446 |
++ outer_ecn_mask = match.mask->tos & INET_ECN_MASK; |
18447 |
++ } |
18448 |
++ |
18449 |
++ if (flow_rule_match_key(rule, FLOW_DISSECTOR_KEY_IP)) { |
18450 |
++ flow_rule_match_ip(rule, &match); |
18451 |
++ inner_ecn_key = match.key->tos & INET_ECN_MASK; |
18452 |
++ inner_ecn_mask = match.mask->tos & INET_ECN_MASK; |
18453 |
++ } |
18454 |
++ |
18455 |
++ if (outer_ecn_mask != 0 && outer_ecn_mask != INET_ECN_MASK) { |
18456 |
++ NL_SET_ERR_MSG_MOD(extack, "Partial match on enc_tos ecn bits isn't supported"); |
18457 |
++ netdev_warn(priv->netdev, "Partial match on enc_tos ecn bits isn't supported"); |
18458 |
++ return -EOPNOTSUPP; |
18459 |
++ } |
18460 |
++ |
18461 |
++ if (!outer_ecn_mask) { |
18462 |
++ if (!inner_ecn_mask) |
18463 |
++ return 0; |
18464 |
++ |
18465 |
++ NL_SET_ERR_MSG_MOD(extack, |
18466 |
++ "Matching on tos ecn bits without also matching enc_tos ecn bits isn't supported"); |
18467 |
++ netdev_warn(priv->netdev, |
18468 |
++ "Matching on tos ecn bits without also matching enc_tos ecn bits isn't supported"); |
18469 |
++ return -EOPNOTSUPP; |
18470 |
++ } |
18471 |
++ |
18472 |
++ if (inner_ecn_mask && inner_ecn_mask != INET_ECN_MASK) { |
18473 |
++ NL_SET_ERR_MSG_MOD(extack, |
18474 |
++ "Partial match on tos ecn bits with match on enc_tos ecn bits isn't supported"); |
18475 |
++ netdev_warn(priv->netdev, |
18476 |
++ "Partial match on tos ecn bits with match on enc_tos ecn bits isn't supported"); |
18477 |
++ return -EOPNOTSUPP; |
18478 |
++ } |
18479 |
++ |
18480 |
++ if (!inner_ecn_mask) |
18481 |
++ return 0; |
18482 |
++ |
18483 |
++ /* Both inner and outer have full mask on ecn */ |
18484 |
++ |
18485 |
++ if (outer_ecn_key == INET_ECN_ECT_1) { |
18486 |
++ /* inner ecn might change by DECAP action */ |
18487 |
++ |
18488 |
++ NL_SET_ERR_MSG_MOD(extack, "Match on enc_tos ecn = ECT(1) isn't supported"); |
18489 |
++ netdev_warn(priv->netdev, "Match on enc_tos ecn = ECT(1) isn't supported"); |
18490 |
++ return -EOPNOTSUPP; |
18491 |
++ } |
18492 |
++ |
18493 |
++ if (outer_ecn_key != INET_ECN_CE) |
18494 |
++ return 0; |
18495 |
++ |
18496 |
++ if (inner_ecn_key != INET_ECN_CE) { |
18497 |
++ /* Can't happen in software, as packet ecn will be changed to CE after decap */ |
18498 |
++ NL_SET_ERR_MSG_MOD(extack, |
18499 |
++ "Match on tos enc_tos ecn = CE while match on tos ecn != CE isn't supported"); |
18500 |
++ netdev_warn(priv->netdev, |
18501 |
++ "Match on tos enc_tos ecn = CE while match on tos ecn != CE isn't supported"); |
18502 |
++ return -EOPNOTSUPP; |
18503 |
++ } |
18504 |
++ |
18505 |
++ /* outer ecn = CE, inner ecn = CE, as decap will change inner ecn to CE in anycase, |
18506 |
++ * drop match on inner ecn |
18507 |
++ */ |
18508 |
++ *match_inner_ecn = false; |
18509 |
++ |
18510 |
++ return 0; |
18511 |
++} |
18512 |
++ |
18513 |
+ static int parse_tunnel_attr(struct mlx5e_priv *priv, |
18514 |
+ struct mlx5e_tc_flow *flow, |
18515 |
+ struct mlx5_flow_spec *spec, |
18516 |
+@@ -2067,6 +2172,7 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, |
18517 |
+ struct flow_rule *rule = flow_cls_offload_flow_rule(f); |
18518 |
+ struct flow_dissector *dissector = rule->match.dissector; |
18519 |
+ enum fs_flow_table_type fs_type; |
18520 |
++ bool match_inner_ecn = true; |
18521 |
+ u16 addr_type = 0; |
18522 |
+ u8 ip_proto = 0; |
18523 |
+ u8 *match_level; |
18524 |
+@@ -2120,6 +2226,10 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, |
18525 |
+ headers_c = get_match_inner_headers_criteria(spec); |
18526 |
+ headers_v = get_match_inner_headers_value(spec); |
18527 |
+ } |
18528 |
++ |
18529 |
++ err = mlx5e_tc_verify_tunnel_ecn(priv, f, &match_inner_ecn); |
18530 |
++ if (err) |
18531 |
++ return err; |
18532 |
+ } |
18533 |
+ |
18534 |
+ err = mlx5e_flower_parse_meta(filter_dev, f); |
18535 |
+@@ -2341,10 +2451,12 @@ static int __parse_cls_flower(struct mlx5e_priv *priv, |
18536 |
+ struct flow_match_ip match; |
18537 |
+ |
18538 |
+ flow_rule_match_ip(rule, &match); |
18539 |
+- MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_ecn, |
18540 |
+- match.mask->tos & 0x3); |
18541 |
+- MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_ecn, |
18542 |
+- match.key->tos & 0x3); |
18543 |
++ if (match_inner_ecn) { |
18544 |
++ MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_ecn, |
18545 |
++ match.mask->tos & 0x3); |
18546 |
++ MLX5_SET(fte_match_set_lyr_2_4, headers_v, ip_ecn, |
18547 |
++ match.key->tos & 0x3); |
18548 |
++ } |
18549 |
+ |
18550 |
+ MLX5_SET(fte_match_set_lyr_2_4, headers_c, ip_dscp, |
18551 |
+ match.mask->tos >> 2); |
18552 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c |
18553 |
+index df277a6cddc0b..0c4c743ca31e1 100644 |
18554 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c |
18555 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/legacy.c |
18556 |
+@@ -431,7 +431,7 @@ int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw, |
18557 |
+ int err = 0; |
18558 |
+ |
18559 |
+ if (!mlx5_esw_allowed(esw)) |
18560 |
+- return -EPERM; |
18561 |
++ return vlan ? -EPERM : 0; |
18562 |
+ |
18563 |
+ if (vlan || qos) |
18564 |
+ set_flags = SET_VLAN_STRIP | SET_VLAN_INSERT; |
18565 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c b/drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c |
18566 |
+index 21fdaf708f1fe..30282d86e6b96 100644 |
18567 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c |
18568 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c |
18569 |
+@@ -268,10 +268,8 @@ static int mlx5_lag_fib_event(struct notifier_block *nb, |
18570 |
+ fen_info = container_of(info, struct fib_entry_notifier_info, |
18571 |
+ info); |
18572 |
+ fi = fen_info->fi; |
18573 |
+- if (fi->nh) { |
18574 |
+- NL_SET_ERR_MSG_MOD(info->extack, "IPv4 route with nexthop objects is not supported"); |
18575 |
+- return notifier_from_errno(-EINVAL); |
18576 |
+- } |
18577 |
++ if (fi->nh) |
18578 |
++ return NOTIFY_DONE; |
18579 |
+ fib_dev = fib_info_nh(fen_info->fi, 0)->fib_nh_dev; |
18580 |
+ if (fib_dev != ldev->pf[MLX5_LAG_P1].netdev && |
18581 |
+ fib_dev != ldev->pf[MLX5_LAG_P2].netdev) { |
18582 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c |
18583 |
+index 92b01858d7f3e..29b7297a836a5 100644 |
18584 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/main.c |
18585 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c |
18586 |
+@@ -97,6 +97,8 @@ enum { |
18587 |
+ MLX5_ATOMIC_REQ_MODE_HOST_ENDIANNESS = 0x1, |
18588 |
+ }; |
18589 |
+ |
18590 |
++#define LOG_MAX_SUPPORTED_QPS 0xff |
18591 |
++ |
18592 |
+ static struct mlx5_profile profile[] = { |
18593 |
+ [0] = { |
18594 |
+ .mask = 0, |
18595 |
+@@ -108,7 +110,7 @@ static struct mlx5_profile profile[] = { |
18596 |
+ [2] = { |
18597 |
+ .mask = MLX5_PROF_MASK_QP_SIZE | |
18598 |
+ MLX5_PROF_MASK_MR_CACHE, |
18599 |
+- .log_max_qp = 18, |
18600 |
++ .log_max_qp = LOG_MAX_SUPPORTED_QPS, |
18601 |
+ .mr_cache[0] = { |
18602 |
+ .size = 500, |
18603 |
+ .limit = 250 |
18604 |
+@@ -513,7 +515,9 @@ static int handle_hca_cap(struct mlx5_core_dev *dev, void *set_ctx) |
18605 |
+ to_fw_pkey_sz(dev, 128)); |
18606 |
+ |
18607 |
+ /* Check log_max_qp from HCA caps to set in current profile */ |
18608 |
+- if (MLX5_CAP_GEN_MAX(dev, log_max_qp) < prof->log_max_qp) { |
18609 |
++ if (prof->log_max_qp == LOG_MAX_SUPPORTED_QPS) { |
18610 |
++ prof->log_max_qp = MLX5_CAP_GEN_MAX(dev, log_max_qp); |
18611 |
++ } else if (MLX5_CAP_GEN_MAX(dev, log_max_qp) < prof->log_max_qp) { |
18612 |
+ mlx5_core_warn(dev, "log_max_qp value in current profile is %d, changing it to HCA capability limit (%d)\n", |
18613 |
+ prof->log_max_qp, |
18614 |
+ MLX5_CAP_GEN_MAX(dev, log_max_qp)); |
18615 |
+diff --git a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c |
18616 |
+index 871c2fbe18d39..64bbc18332d56 100644 |
18617 |
+--- a/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c |
18618 |
++++ b/drivers/net/ethernet/mellanox/mlx5/core/sf/dev/dev.c |
18619 |
+@@ -28,10 +28,7 @@ bool mlx5_sf_dev_allocated(const struct mlx5_core_dev *dev) |
18620 |
+ { |
18621 |
+ struct mlx5_sf_dev_table *table = dev->priv.sf_dev_table; |
18622 |
+ |
18623 |
+- if (!mlx5_sf_dev_supported(dev)) |
18624 |
+- return false; |
18625 |
+- |
18626 |
+- return !xa_empty(&table->devices); |
18627 |
++ return table && !xa_empty(&table->devices); |
18628 |
+ } |
18629 |
+ |
18630 |
+ static ssize_t sfnum_show(struct device *dev, struct device_attribute *attr, char *buf) |
18631 |
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/cmd.h b/drivers/net/ethernet/mellanox/mlxsw/cmd.h |
18632 |
+index 392ce3cb27f72..51b260d54237e 100644 |
18633 |
+--- a/drivers/net/ethernet/mellanox/mlxsw/cmd.h |
18634 |
++++ b/drivers/net/ethernet/mellanox/mlxsw/cmd.h |
18635 |
+@@ -935,6 +935,18 @@ static inline int mlxsw_cmd_sw2hw_rdq(struct mlxsw_core *mlxsw_core, |
18636 |
+ */ |
18637 |
+ MLXSW_ITEM32(cmd_mbox, sw2hw_dq, cq, 0x00, 24, 8); |
18638 |
+ |
18639 |
++enum mlxsw_cmd_mbox_sw2hw_dq_sdq_lp { |
18640 |
++ MLXSW_CMD_MBOX_SW2HW_DQ_SDQ_LP_WQE, |
18641 |
++ MLXSW_CMD_MBOX_SW2HW_DQ_SDQ_LP_IGNORE_WQE, |
18642 |
++}; |
18643 |
++ |
18644 |
++/* cmd_mbox_sw2hw_dq_sdq_lp |
18645 |
++ * SDQ local Processing |
18646 |
++ * 0: local processing by wqe.lp |
18647 |
++ * 1: local processing (ignoring wqe.lp) |
18648 |
++ */ |
18649 |
++MLXSW_ITEM32(cmd_mbox, sw2hw_dq, sdq_lp, 0x00, 23, 1); |
18650 |
++ |
18651 |
+ /* cmd_mbox_sw2hw_dq_sdq_tclass |
18652 |
+ * SDQ: CPU Egress TClass |
18653 |
+ * RDQ: Reserved |
18654 |
+diff --git a/drivers/net/ethernet/mellanox/mlxsw/pci.c b/drivers/net/ethernet/mellanox/mlxsw/pci.c |
18655 |
+index fcace73eae40f..d9f9cbba62465 100644 |
18656 |
+--- a/drivers/net/ethernet/mellanox/mlxsw/pci.c |
18657 |
++++ b/drivers/net/ethernet/mellanox/mlxsw/pci.c |
18658 |
+@@ -285,6 +285,7 @@ static int mlxsw_pci_sdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, |
18659 |
+ struct mlxsw_pci_queue *q) |
18660 |
+ { |
18661 |
+ int tclass; |
18662 |
++ int lp; |
18663 |
+ int i; |
18664 |
+ int err; |
18665 |
+ |
18666 |
+@@ -292,9 +293,12 @@ static int mlxsw_pci_sdq_init(struct mlxsw_pci *mlxsw_pci, char *mbox, |
18667 |
+ q->consumer_counter = 0; |
18668 |
+ tclass = q->num == MLXSW_PCI_SDQ_EMAD_INDEX ? MLXSW_PCI_SDQ_EMAD_TC : |
18669 |
+ MLXSW_PCI_SDQ_CTL_TC; |
18670 |
++ lp = q->num == MLXSW_PCI_SDQ_EMAD_INDEX ? MLXSW_CMD_MBOX_SW2HW_DQ_SDQ_LP_IGNORE_WQE : |
18671 |
++ MLXSW_CMD_MBOX_SW2HW_DQ_SDQ_LP_WQE; |
18672 |
+ |
18673 |
+ /* Set CQ of same number of this SDQ. */ |
18674 |
+ mlxsw_cmd_mbox_sw2hw_dq_cq_set(mbox, q->num); |
18675 |
++ mlxsw_cmd_mbox_sw2hw_dq_sdq_lp_set(mbox, lp); |
18676 |
+ mlxsw_cmd_mbox_sw2hw_dq_sdq_tclass_set(mbox, tclass); |
18677 |
+ mlxsw_cmd_mbox_sw2hw_dq_log2_dq_sz_set(mbox, 3); /* 8 pages */ |
18678 |
+ for (i = 0; i < MLXSW_PCI_AQ_PAGES; i++) { |
18679 |
+@@ -1678,7 +1682,7 @@ static int mlxsw_pci_skb_transmit(void *bus_priv, struct sk_buff *skb, |
18680 |
+ |
18681 |
+ wqe = elem_info->elem; |
18682 |
+ mlxsw_pci_wqe_c_set(wqe, 1); /* always report completion */ |
18683 |
+- mlxsw_pci_wqe_lp_set(wqe, !!tx_info->is_emad); |
18684 |
++ mlxsw_pci_wqe_lp_set(wqe, 0); |
18685 |
+ mlxsw_pci_wqe_type_set(wqe, MLXSW_PCI_WQE_TYPE_ETHERNET); |
18686 |
+ |
18687 |
+ err = mlxsw_pci_wqe_frag_map(mlxsw_pci, wqe, 0, skb->data, |
18688 |
+@@ -1973,6 +1977,7 @@ int mlxsw_pci_driver_register(struct pci_driver *pci_driver) |
18689 |
+ { |
18690 |
+ pci_driver->probe = mlxsw_pci_probe; |
18691 |
+ pci_driver->remove = mlxsw_pci_remove; |
18692 |
++ pci_driver->shutdown = mlxsw_pci_remove; |
18693 |
+ return pci_register_driver(pci_driver); |
18694 |
+ } |
18695 |
+ EXPORT_SYMBOL(mlxsw_pci_driver_register); |
18696 |
+diff --git a/drivers/net/ethernet/mscc/ocelot.c b/drivers/net/ethernet/mscc/ocelot.c |
18697 |
+index 00b5e6860bf69..be2dd69bfee8b 100644 |
18698 |
+--- a/drivers/net/ethernet/mscc/ocelot.c |
18699 |
++++ b/drivers/net/ethernet/mscc/ocelot.c |
18700 |
+@@ -555,7 +555,10 @@ void ocelot_phylink_mac_link_up(struct ocelot *ocelot, int port, |
18701 |
+ |
18702 |
+ ocelot_write_rix(ocelot, 0, ANA_POL_FLOWC, port); |
18703 |
+ |
18704 |
+- ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_ENA, tx_pause); |
18705 |
++ /* Don't attempt to send PAUSE frames on the NPI port, it's broken */ |
18706 |
++ if (port != ocelot->npi) |
18707 |
++ ocelot_fields_write(ocelot, port, SYS_PAUSE_CFG_PAUSE_ENA, |
18708 |
++ tx_pause); |
18709 |
+ |
18710 |
+ /* Undo the effects of ocelot_phylink_mac_link_down: |
18711 |
+ * enable MAC module |
18712 |
+@@ -1302,8 +1305,7 @@ int ocelot_get_ts_info(struct ocelot *ocelot, int port, |
18713 |
+ } |
18714 |
+ EXPORT_SYMBOL(ocelot_get_ts_info); |
18715 |
+ |
18716 |
+-static u32 ocelot_get_bond_mask(struct ocelot *ocelot, struct net_device *bond, |
18717 |
+- bool only_active_ports) |
18718 |
++static u32 ocelot_get_bond_mask(struct ocelot *ocelot, struct net_device *bond) |
18719 |
+ { |
18720 |
+ u32 mask = 0; |
18721 |
+ int port; |
18722 |
+@@ -1314,12 +1316,8 @@ static u32 ocelot_get_bond_mask(struct ocelot *ocelot, struct net_device *bond, |
18723 |
+ if (!ocelot_port) |
18724 |
+ continue; |
18725 |
+ |
18726 |
+- if (ocelot_port->bond == bond) { |
18727 |
+- if (only_active_ports && !ocelot_port->lag_tx_active) |
18728 |
+- continue; |
18729 |
+- |
18730 |
++ if (ocelot_port->bond == bond) |
18731 |
+ mask |= BIT(port); |
18732 |
+- } |
18733 |
+ } |
18734 |
+ |
18735 |
+ return mask; |
18736 |
+@@ -1406,10 +1404,8 @@ void ocelot_apply_bridge_fwd_mask(struct ocelot *ocelot) |
18737 |
+ mask = ocelot_get_bridge_fwd_mask(ocelot, port, bridge); |
18738 |
+ mask |= cpu_fwd_mask; |
18739 |
+ mask &= ~BIT(port); |
18740 |
+- if (bond) { |
18741 |
+- mask &= ~ocelot_get_bond_mask(ocelot, bond, |
18742 |
+- false); |
18743 |
+- } |
18744 |
++ if (bond) |
18745 |
++ mask &= ~ocelot_get_bond_mask(ocelot, bond); |
18746 |
+ } else { |
18747 |
+ /* Standalone ports forward only to DSA tag_8021q CPU |
18748 |
+ * ports (if those exist), or to the hardware CPU port |
18749 |
+@@ -1727,13 +1723,17 @@ static void ocelot_set_aggr_pgids(struct ocelot *ocelot) |
18750 |
+ if (!bond || (visited & BIT(lag))) |
18751 |
+ continue; |
18752 |
+ |
18753 |
+- bond_mask = ocelot_get_bond_mask(ocelot, bond, true); |
18754 |
++ bond_mask = ocelot_get_bond_mask(ocelot, bond); |
18755 |
+ |
18756 |
+ for_each_set_bit(port, &bond_mask, ocelot->num_phys_ports) { |
18757 |
++ struct ocelot_port *ocelot_port = ocelot->ports[port]; |
18758 |
++ |
18759 |
+ // Destination mask |
18760 |
+ ocelot_write_rix(ocelot, bond_mask, |
18761 |
+ ANA_PGID_PGID, port); |
18762 |
+- aggr_idx[num_active_ports++] = port; |
18763 |
++ |
18764 |
++ if (ocelot_port->lag_tx_active) |
18765 |
++ aggr_idx[num_active_ports++] = port; |
18766 |
+ } |
18767 |
+ |
18768 |
+ for_each_aggr_pgid(ocelot, i) { |
18769 |
+@@ -1782,8 +1782,7 @@ static void ocelot_setup_logical_port_ids(struct ocelot *ocelot) |
18770 |
+ |
18771 |
+ bond = ocelot_port->bond; |
18772 |
+ if (bond) { |
18773 |
+- int lag = __ffs(ocelot_get_bond_mask(ocelot, bond, |
18774 |
+- false)); |
18775 |
++ int lag = __ffs(ocelot_get_bond_mask(ocelot, bond)); |
18776 |
+ |
18777 |
+ ocelot_rmw_gix(ocelot, |
18778 |
+ ANA_PORT_PORT_CFG_PORTID_VAL(lag), |
18779 |
+diff --git a/drivers/net/ethernet/mscc/ocelot_flower.c b/drivers/net/ethernet/mscc/ocelot_flower.c |
18780 |
+index 8b843d3c9189a..afa062c5f82d3 100644 |
18781 |
+--- a/drivers/net/ethernet/mscc/ocelot_flower.c |
18782 |
++++ b/drivers/net/ethernet/mscc/ocelot_flower.c |
18783 |
+@@ -467,13 +467,6 @@ ocelot_flower_parse_key(struct ocelot *ocelot, int port, bool ingress, |
18784 |
+ return -EOPNOTSUPP; |
18785 |
+ } |
18786 |
+ |
18787 |
+- if (filter->block_id == VCAP_IS1 && |
18788 |
+- !is_zero_ether_addr(match.mask->dst)) { |
18789 |
+- NL_SET_ERR_MSG_MOD(extack, |
18790 |
+- "Key type S1_NORMAL cannot match on destination MAC"); |
18791 |
+- return -EOPNOTSUPP; |
18792 |
+- } |
18793 |
+- |
18794 |
+ /* The hw support mac matches only for MAC_ETYPE key, |
18795 |
+ * therefore if other matches(port, tcp flags, etc) are added |
18796 |
+ * then just bail out |
18797 |
+@@ -488,6 +481,14 @@ ocelot_flower_parse_key(struct ocelot *ocelot, int port, bool ingress, |
18798 |
+ return -EOPNOTSUPP; |
18799 |
+ |
18800 |
+ flow_rule_match_eth_addrs(rule, &match); |
18801 |
++ |
18802 |
++ if (filter->block_id == VCAP_IS1 && |
18803 |
++ !is_zero_ether_addr(match.mask->dst)) { |
18804 |
++ NL_SET_ERR_MSG_MOD(extack, |
18805 |
++ "Key type S1_NORMAL cannot match on destination MAC"); |
18806 |
++ return -EOPNOTSUPP; |
18807 |
++ } |
18808 |
++ |
18809 |
+ filter->key_type = OCELOT_VCAP_KEY_ETYPE; |
18810 |
+ ether_addr_copy(filter->key.etype.dmac.value, |
18811 |
+ match.key->dst); |
18812 |
+diff --git a/drivers/net/ethernet/mscc/ocelot_net.c b/drivers/net/ethernet/mscc/ocelot_net.c |
18813 |
+index 2545727fd5b2f..c08c56e07b1d3 100644 |
18814 |
+--- a/drivers/net/ethernet/mscc/ocelot_net.c |
18815 |
++++ b/drivers/net/ethernet/mscc/ocelot_net.c |
18816 |
+@@ -1168,7 +1168,7 @@ static int ocelot_netdevice_bridge_join(struct net_device *dev, |
18817 |
+ ocelot_port_bridge_join(ocelot, port, bridge); |
18818 |
+ |
18819 |
+ err = switchdev_bridge_port_offload(brport_dev, dev, priv, |
18820 |
+- &ocelot_netdevice_nb, |
18821 |
++ &ocelot_switchdev_nb, |
18822 |
+ &ocelot_switchdev_blocking_nb, |
18823 |
+ false, extack); |
18824 |
+ if (err) |
18825 |
+@@ -1182,7 +1182,7 @@ static int ocelot_netdevice_bridge_join(struct net_device *dev, |
18826 |
+ |
18827 |
+ err_switchdev_sync: |
18828 |
+ switchdev_bridge_port_unoffload(brport_dev, priv, |
18829 |
+- &ocelot_netdevice_nb, |
18830 |
++ &ocelot_switchdev_nb, |
18831 |
+ &ocelot_switchdev_blocking_nb); |
18832 |
+ err_switchdev_offload: |
18833 |
+ ocelot_port_bridge_leave(ocelot, port, bridge); |
18834 |
+@@ -1195,7 +1195,7 @@ static void ocelot_netdevice_pre_bridge_leave(struct net_device *dev, |
18835 |
+ struct ocelot_port_private *priv = netdev_priv(dev); |
18836 |
+ |
18837 |
+ switchdev_bridge_port_unoffload(brport_dev, priv, |
18838 |
+- &ocelot_netdevice_nb, |
18839 |
++ &ocelot_switchdev_nb, |
18840 |
+ &ocelot_switchdev_blocking_nb); |
18841 |
+ } |
18842 |
+ |
18843 |
+diff --git a/drivers/net/ethernet/renesas/ravb_main.c b/drivers/net/ethernet/renesas/ravb_main.c |
18844 |
+index 0f85f2d97b18d..4e08b7219403c 100644 |
18845 |
+--- a/drivers/net/ethernet/renesas/ravb_main.c |
18846 |
++++ b/drivers/net/ethernet/renesas/ravb_main.c |
18847 |
+@@ -30,8 +30,7 @@ |
18848 |
+ #include <linux/spinlock.h> |
18849 |
+ #include <linux/sys_soc.h> |
18850 |
+ #include <linux/reset.h> |
18851 |
+- |
18852 |
+-#include <asm/div64.h> |
18853 |
++#include <linux/math64.h> |
18854 |
+ |
18855 |
+ #include "ravb.h" |
18856 |
+ |
18857 |
+@@ -2061,8 +2060,7 @@ static int ravb_set_gti(struct net_device *ndev) |
18858 |
+ if (!rate) |
18859 |
+ return -EINVAL; |
18860 |
+ |
18861 |
+- inc = 1000000000ULL << 20; |
18862 |
+- do_div(inc, rate); |
18863 |
++ inc = div64_ul(1000000000ULL << 20, rate); |
18864 |
+ |
18865 |
+ if (inc < GTI_TIV_MIN || inc > GTI_TIV_MAX) { |
18866 |
+ dev_err(dev, "gti.tiv increment 0x%llx is outside the range 0x%x - 0x%x\n", |
18867 |
+diff --git a/drivers/net/ethernet/rocker/rocker_ofdpa.c b/drivers/net/ethernet/rocker/rocker_ofdpa.c |
18868 |
+index 3e1ca7a8d0295..bc70c6abd6a5b 100644 |
18869 |
+--- a/drivers/net/ethernet/rocker/rocker_ofdpa.c |
18870 |
++++ b/drivers/net/ethernet/rocker/rocker_ofdpa.c |
18871 |
+@@ -2783,7 +2783,8 @@ static void ofdpa_fib4_abort(struct rocker *rocker) |
18872 |
+ if (!ofdpa_port) |
18873 |
+ continue; |
18874 |
+ nh->fib_nh_flags &= ~RTNH_F_OFFLOAD; |
18875 |
+- ofdpa_flow_tbl_del(ofdpa_port, OFDPA_OP_FLAG_REMOVE, |
18876 |
++ ofdpa_flow_tbl_del(ofdpa_port, |
18877 |
++ OFDPA_OP_FLAG_REMOVE | OFDPA_OP_FLAG_NOWAIT, |
18878 |
+ flow_entry); |
18879 |
+ } |
18880 |
+ spin_unlock_irqrestore(&ofdpa->flow_tbl_lock, flags); |
18881 |
+diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c |
18882 |
+index 5c74b6279d690..6b1d9e8879f46 100644 |
18883 |
+--- a/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c |
18884 |
++++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-qcom-ethqos.c |
18885 |
+@@ -113,8 +113,10 @@ static void rgmii_updatel(struct qcom_ethqos *ethqos, |
18886 |
+ rgmii_writel(ethqos, temp, offset); |
18887 |
+ } |
18888 |
+ |
18889 |
+-static void rgmii_dump(struct qcom_ethqos *ethqos) |
18890 |
++static void rgmii_dump(void *priv) |
18891 |
+ { |
18892 |
++ struct qcom_ethqos *ethqos = priv; |
18893 |
++ |
18894 |
+ dev_dbg(ðqos->pdev->dev, "Rgmii register dump\n"); |
18895 |
+ dev_dbg(ðqos->pdev->dev, "RGMII_IO_MACRO_CONFIG: %x\n", |
18896 |
+ rgmii_readl(ethqos, RGMII_IO_MACRO_CONFIG)); |
18897 |
+@@ -499,6 +501,7 @@ static int qcom_ethqos_probe(struct platform_device *pdev) |
18898 |
+ |
18899 |
+ plat_dat->bsp_priv = ethqos; |
18900 |
+ plat_dat->fix_mac_speed = ethqos_fix_mac_speed; |
18901 |
++ plat_dat->dump_debug_regs = rgmii_dump; |
18902 |
+ plat_dat->has_gmac4 = 1; |
18903 |
+ plat_dat->pmt = 1; |
18904 |
+ plat_dat->tso_en = of_property_read_bool(np, "snps,tso"); |
18905 |
+@@ -507,8 +510,6 @@ static int qcom_ethqos_probe(struct platform_device *pdev) |
18906 |
+ if (ret) |
18907 |
+ goto err_clk; |
18908 |
+ |
18909 |
+- rgmii_dump(ethqos); |
18910 |
+- |
18911 |
+ return ret; |
18912 |
+ |
18913 |
+ err_clk: |
18914 |
+diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
18915 |
+index 3422f0746d825..06e5431cf51df 100644 |
18916 |
+--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
18917 |
++++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c |
18918 |
+@@ -7077,6 +7077,9 @@ int stmmac_dvr_probe(struct device *device, |
18919 |
+ stmmac_init_fs(ndev); |
18920 |
+ #endif |
18921 |
+ |
18922 |
++ if (priv->plat->dump_debug_regs) |
18923 |
++ priv->plat->dump_debug_regs(priv->plat->bsp_priv); |
18924 |
++ |
18925 |
+ /* Let pm_runtime_put() disable the clocks. |
18926 |
+ * If CONFIG_PM is not enabled, the clocks will stay powered. |
18927 |
+ */ |
18928 |
+diff --git a/drivers/net/ethernet/ti/cpsw.c b/drivers/net/ethernet/ti/cpsw.c |
18929 |
+index 66f7ddd9b1f99..e226ecd95a2cc 100644 |
18930 |
+--- a/drivers/net/ethernet/ti/cpsw.c |
18931 |
++++ b/drivers/net/ethernet/ti/cpsw.c |
18932 |
+@@ -349,7 +349,7 @@ static void cpsw_rx_handler(void *token, int len, int status) |
18933 |
+ struct cpsw_common *cpsw = ndev_to_cpsw(xmeta->ndev); |
18934 |
+ int pkt_size = cpsw->rx_packet_max; |
18935 |
+ int ret = 0, port, ch = xmeta->ch; |
18936 |
+- int headroom = CPSW_HEADROOM; |
18937 |
++ int headroom = CPSW_HEADROOM_NA; |
18938 |
+ struct net_device *ndev = xmeta->ndev; |
18939 |
+ struct cpsw_priv *priv; |
18940 |
+ struct page_pool *pool; |
18941 |
+@@ -392,7 +392,7 @@ static void cpsw_rx_handler(void *token, int len, int status) |
18942 |
+ } |
18943 |
+ |
18944 |
+ if (priv->xdp_prog) { |
18945 |
+- int headroom = CPSW_HEADROOM, size = len; |
18946 |
++ int size = len; |
18947 |
+ |
18948 |
+ xdp_init_buff(&xdp, PAGE_SIZE, &priv->xdp_rxq[ch]); |
18949 |
+ if (status & CPDMA_RX_VLAN_ENCAP) { |
18950 |
+@@ -442,7 +442,7 @@ requeue: |
18951 |
+ xmeta->ndev = ndev; |
18952 |
+ xmeta->ch = ch; |
18953 |
+ |
18954 |
+- dma = page_pool_get_dma_addr(new_page) + CPSW_HEADROOM; |
18955 |
++ dma = page_pool_get_dma_addr(new_page) + CPSW_HEADROOM_NA; |
18956 |
+ ret = cpdma_chan_submit_mapped(cpsw->rxv[ch].ch, new_page, dma, |
18957 |
+ pkt_size, 0); |
18958 |
+ if (ret < 0) { |
18959 |
+diff --git a/drivers/net/ethernet/ti/cpsw_new.c b/drivers/net/ethernet/ti/cpsw_new.c |
18960 |
+index 7968f24d99c85..9e16afbdbdc1d 100644 |
18961 |
+--- a/drivers/net/ethernet/ti/cpsw_new.c |
18962 |
++++ b/drivers/net/ethernet/ti/cpsw_new.c |
18963 |
+@@ -283,7 +283,7 @@ static void cpsw_rx_handler(void *token, int len, int status) |
18964 |
+ { |
18965 |
+ struct page *new_page, *page = token; |
18966 |
+ void *pa = page_address(page); |
18967 |
+- int headroom = CPSW_HEADROOM; |
18968 |
++ int headroom = CPSW_HEADROOM_NA; |
18969 |
+ struct cpsw_meta_xdp *xmeta; |
18970 |
+ struct cpsw_common *cpsw; |
18971 |
+ struct net_device *ndev; |
18972 |
+@@ -336,7 +336,7 @@ static void cpsw_rx_handler(void *token, int len, int status) |
18973 |
+ } |
18974 |
+ |
18975 |
+ if (priv->xdp_prog) { |
18976 |
+- int headroom = CPSW_HEADROOM, size = len; |
18977 |
++ int size = len; |
18978 |
+ |
18979 |
+ xdp_init_buff(&xdp, PAGE_SIZE, &priv->xdp_rxq[ch]); |
18980 |
+ if (status & CPDMA_RX_VLAN_ENCAP) { |
18981 |
+@@ -386,7 +386,7 @@ requeue: |
18982 |
+ xmeta->ndev = ndev; |
18983 |
+ xmeta->ch = ch; |
18984 |
+ |
18985 |
+- dma = page_pool_get_dma_addr(new_page) + CPSW_HEADROOM; |
18986 |
++ dma = page_pool_get_dma_addr(new_page) + CPSW_HEADROOM_NA; |
18987 |
+ ret = cpdma_chan_submit_mapped(cpsw->rxv[ch].ch, new_page, dma, |
18988 |
+ pkt_size, 0); |
18989 |
+ if (ret < 0) { |
18990 |
+diff --git a/drivers/net/ethernet/ti/cpsw_priv.c b/drivers/net/ethernet/ti/cpsw_priv.c |
18991 |
+index ecc2a6b7e28f2..6bb5ac51d23c3 100644 |
18992 |
+--- a/drivers/net/ethernet/ti/cpsw_priv.c |
18993 |
++++ b/drivers/net/ethernet/ti/cpsw_priv.c |
18994 |
+@@ -1120,7 +1120,7 @@ int cpsw_fill_rx_channels(struct cpsw_priv *priv) |
18995 |
+ xmeta->ndev = priv->ndev; |
18996 |
+ xmeta->ch = ch; |
18997 |
+ |
18998 |
+- dma = page_pool_get_dma_addr(page) + CPSW_HEADROOM; |
18999 |
++ dma = page_pool_get_dma_addr(page) + CPSW_HEADROOM_NA; |
19000 |
+ ret = cpdma_chan_idle_submit_mapped(cpsw->rxv[ch].ch, |
19001 |
+ page, dma, |
19002 |
+ cpsw->rx_packet_max, |
19003 |
+diff --git a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c |
19004 |
+index 871b5ec3183d6..2169417210c2b 100644 |
19005 |
+--- a/drivers/net/ethernet/xilinx/xilinx_axienet_main.c |
19006 |
++++ b/drivers/net/ethernet/xilinx/xilinx_axienet_main.c |
19007 |
+@@ -41,8 +41,9 @@ |
19008 |
+ #include "xilinx_axienet.h" |
19009 |
+ |
19010 |
+ /* Descriptors defines for Tx and Rx DMA */ |
19011 |
+-#define TX_BD_NUM_DEFAULT 64 |
19012 |
++#define TX_BD_NUM_DEFAULT 128 |
19013 |
+ #define RX_BD_NUM_DEFAULT 1024 |
19014 |
++#define TX_BD_NUM_MIN (MAX_SKB_FRAGS + 1) |
19015 |
+ #define TX_BD_NUM_MAX 4096 |
19016 |
+ #define RX_BD_NUM_MAX 4096 |
19017 |
+ |
19018 |
+@@ -496,7 +497,8 @@ static void axienet_setoptions(struct net_device *ndev, u32 options) |
19019 |
+ |
19020 |
+ static int __axienet_device_reset(struct axienet_local *lp) |
19021 |
+ { |
19022 |
+- u32 timeout; |
19023 |
++ u32 value; |
19024 |
++ int ret; |
19025 |
+ |
19026 |
+ /* Reset Axi DMA. This would reset Axi Ethernet core as well. The reset |
19027 |
+ * process of Axi DMA takes a while to complete as all pending |
19028 |
+@@ -506,15 +508,23 @@ static int __axienet_device_reset(struct axienet_local *lp) |
19029 |
+ * they both reset the entire DMA core, so only one needs to be used. |
19030 |
+ */ |
19031 |
+ axienet_dma_out32(lp, XAXIDMA_TX_CR_OFFSET, XAXIDMA_CR_RESET_MASK); |
19032 |
+- timeout = DELAY_OF_ONE_MILLISEC; |
19033 |
+- while (axienet_dma_in32(lp, XAXIDMA_TX_CR_OFFSET) & |
19034 |
+- XAXIDMA_CR_RESET_MASK) { |
19035 |
+- udelay(1); |
19036 |
+- if (--timeout == 0) { |
19037 |
+- netdev_err(lp->ndev, "%s: DMA reset timeout!\n", |
19038 |
+- __func__); |
19039 |
+- return -ETIMEDOUT; |
19040 |
+- } |
19041 |
++ ret = read_poll_timeout(axienet_dma_in32, value, |
19042 |
++ !(value & XAXIDMA_CR_RESET_MASK), |
19043 |
++ DELAY_OF_ONE_MILLISEC, 50000, false, lp, |
19044 |
++ XAXIDMA_TX_CR_OFFSET); |
19045 |
++ if (ret) { |
19046 |
++ dev_err(lp->dev, "%s: DMA reset timeout!\n", __func__); |
19047 |
++ return ret; |
19048 |
++ } |
19049 |
++ |
19050 |
++ /* Wait for PhyRstCmplt bit to be set, indicating the PHY reset has finished */ |
19051 |
++ ret = read_poll_timeout(axienet_ior, value, |
19052 |
++ value & XAE_INT_PHYRSTCMPLT_MASK, |
19053 |
++ DELAY_OF_ONE_MILLISEC, 50000, false, lp, |
19054 |
++ XAE_IS_OFFSET); |
19055 |
++ if (ret) { |
19056 |
++ dev_err(lp->dev, "%s: timeout waiting for PhyRstCmplt\n", __func__); |
19057 |
++ return ret; |
19058 |
+ } |
19059 |
+ |
19060 |
+ return 0; |
19061 |
+@@ -623,6 +633,8 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd, |
19062 |
+ if (nr_bds == -1 && !(status & XAXIDMA_BD_STS_COMPLETE_MASK)) |
19063 |
+ break; |
19064 |
+ |
19065 |
++ /* Ensure we see complete descriptor update */ |
19066 |
++ dma_rmb(); |
19067 |
+ phys = desc_get_phys_addr(lp, cur_p); |
19068 |
+ dma_unmap_single(ndev->dev.parent, phys, |
19069 |
+ (cur_p->cntrl & XAXIDMA_BD_CTRL_LENGTH_MASK), |
19070 |
+@@ -631,13 +643,15 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd, |
19071 |
+ if (cur_p->skb && (status & XAXIDMA_BD_STS_COMPLETE_MASK)) |
19072 |
+ dev_consume_skb_irq(cur_p->skb); |
19073 |
+ |
19074 |
+- cur_p->cntrl = 0; |
19075 |
+ cur_p->app0 = 0; |
19076 |
+ cur_p->app1 = 0; |
19077 |
+ cur_p->app2 = 0; |
19078 |
+ cur_p->app4 = 0; |
19079 |
+- cur_p->status = 0; |
19080 |
+ cur_p->skb = NULL; |
19081 |
++ /* ensure our transmit path and device don't prematurely see status cleared */ |
19082 |
++ wmb(); |
19083 |
++ cur_p->cntrl = 0; |
19084 |
++ cur_p->status = 0; |
19085 |
+ |
19086 |
+ if (sizep) |
19087 |
+ *sizep += status & XAXIDMA_BD_STS_ACTUAL_LEN_MASK; |
19088 |
+@@ -646,6 +660,32 @@ static int axienet_free_tx_chain(struct net_device *ndev, u32 first_bd, |
19089 |
+ return i; |
19090 |
+ } |
19091 |
+ |
19092 |
++/** |
19093 |
++ * axienet_check_tx_bd_space - Checks if a BD/group of BDs are currently busy |
19094 |
++ * @lp: Pointer to the axienet_local structure |
19095 |
++ * @num_frag: The number of BDs to check for |
19096 |
++ * |
19097 |
++ * Return: 0, on success |
19098 |
++ * NETDEV_TX_BUSY, if any of the descriptors are not free |
19099 |
++ * |
19100 |
++ * This function is invoked before BDs are allocated and transmission starts. |
19101 |
++ * This function returns 0 if a BD or group of BDs can be allocated for |
19102 |
++ * transmission. If the BD or any of the BDs are not free the function |
19103 |
++ * returns a busy status. This is invoked from axienet_start_xmit. |
19104 |
++ */ |
19105 |
++static inline int axienet_check_tx_bd_space(struct axienet_local *lp, |
19106 |
++ int num_frag) |
19107 |
++{ |
19108 |
++ struct axidma_bd *cur_p; |
19109 |
++ |
19110 |
++ /* Ensure we see all descriptor updates from device or TX IRQ path */ |
19111 |
++ rmb(); |
19112 |
++ cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % lp->tx_bd_num]; |
19113 |
++ if (cur_p->cntrl) |
19114 |
++ return NETDEV_TX_BUSY; |
19115 |
++ return 0; |
19116 |
++} |
19117 |
++ |
19118 |
+ /** |
19119 |
+ * axienet_start_xmit_done - Invoked once a transmit is completed by the |
19120 |
+ * Axi DMA Tx channel. |
19121 |
+@@ -675,30 +715,8 @@ static void axienet_start_xmit_done(struct net_device *ndev) |
19122 |
+ /* Matches barrier in axienet_start_xmit */ |
19123 |
+ smp_mb(); |
19124 |
+ |
19125 |
+- netif_wake_queue(ndev); |
19126 |
+-} |
19127 |
+- |
19128 |
+-/** |
19129 |
+- * axienet_check_tx_bd_space - Checks if a BD/group of BDs are currently busy |
19130 |
+- * @lp: Pointer to the axienet_local structure |
19131 |
+- * @num_frag: The number of BDs to check for |
19132 |
+- * |
19133 |
+- * Return: 0, on success |
19134 |
+- * NETDEV_TX_BUSY, if any of the descriptors are not free |
19135 |
+- * |
19136 |
+- * This function is invoked before BDs are allocated and transmission starts. |
19137 |
+- * This function returns 0 if a BD or group of BDs can be allocated for |
19138 |
+- * transmission. If the BD or any of the BDs are not free the function |
19139 |
+- * returns a busy status. This is invoked from axienet_start_xmit. |
19140 |
+- */ |
19141 |
+-static inline int axienet_check_tx_bd_space(struct axienet_local *lp, |
19142 |
+- int num_frag) |
19143 |
+-{ |
19144 |
+- struct axidma_bd *cur_p; |
19145 |
+- cur_p = &lp->tx_bd_v[(lp->tx_bd_tail + num_frag) % lp->tx_bd_num]; |
19146 |
+- if (cur_p->status & XAXIDMA_BD_STS_ALL_MASK) |
19147 |
+- return NETDEV_TX_BUSY; |
19148 |
+- return 0; |
19149 |
++ if (!axienet_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1)) |
19150 |
++ netif_wake_queue(ndev); |
19151 |
+ } |
19152 |
+ |
19153 |
+ /** |
19154 |
+@@ -730,20 +748,15 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
19155 |
+ num_frag = skb_shinfo(skb)->nr_frags; |
19156 |
+ cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; |
19157 |
+ |
19158 |
+- if (axienet_check_tx_bd_space(lp, num_frag)) { |
19159 |
+- if (netif_queue_stopped(ndev)) |
19160 |
+- return NETDEV_TX_BUSY; |
19161 |
+- |
19162 |
++ if (axienet_check_tx_bd_space(lp, num_frag + 1)) { |
19163 |
++ /* Should not happen as last start_xmit call should have |
19164 |
++ * checked for sufficient space and queue should only be |
19165 |
++ * woken when sufficient space is available. |
19166 |
++ */ |
19167 |
+ netif_stop_queue(ndev); |
19168 |
+- |
19169 |
+- /* Matches barrier in axienet_start_xmit_done */ |
19170 |
+- smp_mb(); |
19171 |
+- |
19172 |
+- /* Space might have just been freed - check again */ |
19173 |
+- if (axienet_check_tx_bd_space(lp, num_frag)) |
19174 |
+- return NETDEV_TX_BUSY; |
19175 |
+- |
19176 |
+- netif_wake_queue(ndev); |
19177 |
++ if (net_ratelimit()) |
19178 |
++ netdev_warn(ndev, "TX ring unexpectedly full\n"); |
19179 |
++ return NETDEV_TX_BUSY; |
19180 |
+ } |
19181 |
+ |
19182 |
+ if (skb->ip_summed == CHECKSUM_PARTIAL) { |
19183 |
+@@ -804,6 +817,18 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) |
19184 |
+ if (++lp->tx_bd_tail >= lp->tx_bd_num) |
19185 |
+ lp->tx_bd_tail = 0; |
19186 |
+ |
19187 |
++ /* Stop queue if next transmit may not have space */ |
19188 |
++ if (axienet_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1)) { |
19189 |
++ netif_stop_queue(ndev); |
19190 |
++ |
19191 |
++ /* Matches barrier in axienet_start_xmit_done */ |
19192 |
++ smp_mb(); |
19193 |
++ |
19194 |
++ /* Space might have just been freed - check again */ |
19195 |
++ if (!axienet_check_tx_bd_space(lp, MAX_SKB_FRAGS + 1)) |
19196 |
++ netif_wake_queue(ndev); |
19197 |
++ } |
19198 |
++ |
19199 |
+ return NETDEV_TX_OK; |
19200 |
+ } |
19201 |
+ |
19202 |
+@@ -834,6 +859,8 @@ static void axienet_recv(struct net_device *ndev) |
19203 |
+ |
19204 |
+ tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci; |
19205 |
+ |
19206 |
++ /* Ensure we see complete descriptor update */ |
19207 |
++ dma_rmb(); |
19208 |
+ phys = desc_get_phys_addr(lp, cur_p); |
19209 |
+ dma_unmap_single(ndev->dev.parent, phys, lp->max_frm_size, |
19210 |
+ DMA_FROM_DEVICE); |
19211 |
+@@ -1346,7 +1373,8 @@ static int axienet_ethtools_set_ringparam(struct net_device *ndev, |
19212 |
+ if (ering->rx_pending > RX_BD_NUM_MAX || |
19213 |
+ ering->rx_mini_pending || |
19214 |
+ ering->rx_jumbo_pending || |
19215 |
+- ering->rx_pending > TX_BD_NUM_MAX) |
19216 |
++ ering->tx_pending < TX_BD_NUM_MIN || |
19217 |
++ ering->tx_pending > TX_BD_NUM_MAX) |
19218 |
+ return -EINVAL; |
19219 |
+ |
19220 |
+ if (netif_running(ndev)) |
19221 |
+@@ -2082,6 +2110,11 @@ static int axienet_probe(struct platform_device *pdev) |
19222 |
+ lp->coalesce_count_rx = XAXIDMA_DFT_RX_THRESHOLD; |
19223 |
+ lp->coalesce_count_tx = XAXIDMA_DFT_TX_THRESHOLD; |
19224 |
+ |
19225 |
++ /* Reset core now that clocks are enabled, prior to accessing MDIO */ |
19226 |
++ ret = __axienet_device_reset(lp); |
19227 |
++ if (ret) |
19228 |
++ goto cleanup_clk; |
19229 |
++ |
19230 |
+ lp->phy_node = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0); |
19231 |
+ if (lp->phy_node) { |
19232 |
+ ret = axienet_mdio_setup(lp); |
19233 |
+diff --git a/drivers/net/ipa/ipa_endpoint.c b/drivers/net/ipa/ipa_endpoint.c |
19234 |
+index 03a1709934208..c8f90cb1ee8f3 100644 |
19235 |
+--- a/drivers/net/ipa/ipa_endpoint.c |
19236 |
++++ b/drivers/net/ipa/ipa_endpoint.c |
19237 |
+@@ -1067,6 +1067,7 @@ static void ipa_endpoint_replenish(struct ipa_endpoint *endpoint, bool add_one) |
19238 |
+ { |
19239 |
+ struct gsi *gsi; |
19240 |
+ u32 backlog; |
19241 |
++ int delta; |
19242 |
+ |
19243 |
+ if (!endpoint->replenish_enabled) { |
19244 |
+ if (add_one) |
19245 |
+@@ -1084,10 +1085,8 @@ static void ipa_endpoint_replenish(struct ipa_endpoint *endpoint, bool add_one) |
19246 |
+ |
19247 |
+ try_again_later: |
19248 |
+ /* The last one didn't succeed, so fix the backlog */ |
19249 |
+- backlog = atomic_inc_return(&endpoint->replenish_backlog); |
19250 |
+- |
19251 |
+- if (add_one) |
19252 |
+- atomic_inc(&endpoint->replenish_backlog); |
19253 |
++ delta = add_one ? 2 : 1; |
19254 |
++ backlog = atomic_add_return(delta, &endpoint->replenish_backlog); |
19255 |
+ |
19256 |
+ /* Whenever a receive buffer transaction completes we'll try to |
19257 |
+ * replenish again. It's unlikely, but if we fail to supply even |
19258 |
+diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c |
19259 |
+index 4fcfca4e17021..c10cc2cd53b66 100644 |
19260 |
+--- a/drivers/net/phy/marvell.c |
19261 |
++++ b/drivers/net/phy/marvell.c |
19262 |
+@@ -189,6 +189,8 @@ |
19263 |
+ #define MII_88E1510_GEN_CTRL_REG_1_MODE_RGMII_SGMII 0x4 |
19264 |
+ #define MII_88E1510_GEN_CTRL_REG_1_RESET 0x8000 /* Soft reset */ |
19265 |
+ |
19266 |
++#define MII_88E1510_MSCR_2 0x15 |
19267 |
++ |
19268 |
+ #define MII_VCT5_TX_RX_MDI0_COUPLING 0x10 |
19269 |
+ #define MII_VCT5_TX_RX_MDI1_COUPLING 0x11 |
19270 |
+ #define MII_VCT5_TX_RX_MDI2_COUPLING 0x12 |
19271 |
+@@ -1242,6 +1244,12 @@ static int m88e1118_config_init(struct phy_device *phydev) |
19272 |
+ if (err < 0) |
19273 |
+ return err; |
19274 |
+ |
19275 |
++ if (phy_interface_is_rgmii(phydev)) { |
19276 |
++ err = m88e1121_config_aneg_rgmii_delays(phydev); |
19277 |
++ if (err < 0) |
19278 |
++ return err; |
19279 |
++ } |
19280 |
++ |
19281 |
+ /* Adjust LED Control */ |
19282 |
+ if (phydev->dev_flags & MARVELL_PHY_M1118_DNS323_LEDS) |
19283 |
+ err = phy_write(phydev, 0x10, 0x1100); |
19284 |
+@@ -1932,6 +1940,58 @@ static void marvell_get_stats(struct phy_device *phydev, |
19285 |
+ data[i] = marvell_get_stat(phydev, i); |
19286 |
+ } |
19287 |
+ |
19288 |
++static int m88e1510_loopback(struct phy_device *phydev, bool enable) |
19289 |
++{ |
19290 |
++ int err; |
19291 |
++ |
19292 |
++ if (enable) { |
19293 |
++ u16 bmcr_ctl = 0, mscr2_ctl = 0; |
19294 |
++ |
19295 |
++ if (phydev->speed == SPEED_1000) |
19296 |
++ bmcr_ctl = BMCR_SPEED1000; |
19297 |
++ else if (phydev->speed == SPEED_100) |
19298 |
++ bmcr_ctl = BMCR_SPEED100; |
19299 |
++ |
19300 |
++ if (phydev->duplex == DUPLEX_FULL) |
19301 |
++ bmcr_ctl |= BMCR_FULLDPLX; |
19302 |
++ |
19303 |
++ err = phy_write(phydev, MII_BMCR, bmcr_ctl); |
19304 |
++ if (err < 0) |
19305 |
++ return err; |
19306 |
++ |
19307 |
++ if (phydev->speed == SPEED_1000) |
19308 |
++ mscr2_ctl = BMCR_SPEED1000; |
19309 |
++ else if (phydev->speed == SPEED_100) |
19310 |
++ mscr2_ctl = BMCR_SPEED100; |
19311 |
++ |
19312 |
++ err = phy_modify_paged(phydev, MII_MARVELL_MSCR_PAGE, |
19313 |
++ MII_88E1510_MSCR_2, BMCR_SPEED1000 | |
19314 |
++ BMCR_SPEED100, mscr2_ctl); |
19315 |
++ if (err < 0) |
19316 |
++ return err; |
19317 |
++ |
19318 |
++ /* Need soft reset to have speed configuration takes effect */ |
19319 |
++ err = genphy_soft_reset(phydev); |
19320 |
++ if (err < 0) |
19321 |
++ return err; |
19322 |
++ |
19323 |
++ /* FIXME: Based on trial and error test, it seem 1G need to have |
19324 |
++ * delay between soft reset and loopback enablement. |
19325 |
++ */ |
19326 |
++ if (phydev->speed == SPEED_1000) |
19327 |
++ msleep(1000); |
19328 |
++ |
19329 |
++ return phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK, |
19330 |
++ BMCR_LOOPBACK); |
19331 |
++ } else { |
19332 |
++ err = phy_modify(phydev, MII_BMCR, BMCR_LOOPBACK, 0); |
19333 |
++ if (err < 0) |
19334 |
++ return err; |
19335 |
++ |
19336 |
++ return phy_config_aneg(phydev); |
19337 |
++ } |
19338 |
++} |
19339 |
++ |
19340 |
+ static int marvell_vct5_wait_complete(struct phy_device *phydev) |
19341 |
+ { |
19342 |
+ int i; |
19343 |
+@@ -3078,7 +3138,7 @@ static struct phy_driver marvell_drivers[] = { |
19344 |
+ .get_sset_count = marvell_get_sset_count, |
19345 |
+ .get_strings = marvell_get_strings, |
19346 |
+ .get_stats = marvell_get_stats, |
19347 |
+- .set_loopback = genphy_loopback, |
19348 |
++ .set_loopback = m88e1510_loopback, |
19349 |
+ .get_tunable = m88e1011_get_tunable, |
19350 |
+ .set_tunable = m88e1011_set_tunable, |
19351 |
+ .cable_test_start = marvell_vct7_cable_test_start, |
19352 |
+diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c |
19353 |
+index 6865d9319197f..8dc6e6269c65e 100644 |
19354 |
+--- a/drivers/net/phy/mdio_bus.c |
19355 |
++++ b/drivers/net/phy/mdio_bus.c |
19356 |
+@@ -591,7 +591,7 @@ int __mdiobus_register(struct mii_bus *bus, struct module *owner) |
19357 |
+ mdiobus_setup_mdiodev_from_board_info(bus, mdiobus_create_device); |
19358 |
+ |
19359 |
+ bus->state = MDIOBUS_REGISTERED; |
19360 |
+- pr_info("%s: probed\n", bus->name); |
19361 |
++ dev_dbg(&bus->dev, "probed\n"); |
19362 |
+ return 0; |
19363 |
+ |
19364 |
+ error: |
19365 |
+diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c |
19366 |
+index aec0fcefdccd6..e2ac61f44c945 100644 |
19367 |
+--- a/drivers/net/phy/micrel.c |
19368 |
++++ b/drivers/net/phy/micrel.c |
19369 |
+@@ -1547,8 +1547,8 @@ static struct phy_driver ksphy_driver[] = { |
19370 |
+ .config_init = kszphy_config_init, |
19371 |
+ .config_intr = kszphy_config_intr, |
19372 |
+ .handle_interrupt = kszphy_handle_interrupt, |
19373 |
+- .suspend = genphy_suspend, |
19374 |
+- .resume = genphy_resume, |
19375 |
++ .suspend = kszphy_suspend, |
19376 |
++ .resume = kszphy_resume, |
19377 |
+ }, { |
19378 |
+ .phy_id = PHY_ID_KSZ8021, |
19379 |
+ .phy_id_mask = 0x00ffffff, |
19380 |
+@@ -1562,8 +1562,8 @@ static struct phy_driver ksphy_driver[] = { |
19381 |
+ .get_sset_count = kszphy_get_sset_count, |
19382 |
+ .get_strings = kszphy_get_strings, |
19383 |
+ .get_stats = kszphy_get_stats, |
19384 |
+- .suspend = genphy_suspend, |
19385 |
+- .resume = genphy_resume, |
19386 |
++ .suspend = kszphy_suspend, |
19387 |
++ .resume = kszphy_resume, |
19388 |
+ }, { |
19389 |
+ .phy_id = PHY_ID_KSZ8031, |
19390 |
+ .phy_id_mask = 0x00ffffff, |
19391 |
+@@ -1577,8 +1577,8 @@ static struct phy_driver ksphy_driver[] = { |
19392 |
+ .get_sset_count = kszphy_get_sset_count, |
19393 |
+ .get_strings = kszphy_get_strings, |
19394 |
+ .get_stats = kszphy_get_stats, |
19395 |
+- .suspend = genphy_suspend, |
19396 |
+- .resume = genphy_resume, |
19397 |
++ .suspend = kszphy_suspend, |
19398 |
++ .resume = kszphy_resume, |
19399 |
+ }, { |
19400 |
+ .phy_id = PHY_ID_KSZ8041, |
19401 |
+ .phy_id_mask = MICREL_PHY_ID_MASK, |
19402 |
+@@ -1609,8 +1609,8 @@ static struct phy_driver ksphy_driver[] = { |
19403 |
+ .get_sset_count = kszphy_get_sset_count, |
19404 |
+ .get_strings = kszphy_get_strings, |
19405 |
+ .get_stats = kszphy_get_stats, |
19406 |
+- .suspend = genphy_suspend, |
19407 |
+- .resume = genphy_resume, |
19408 |
++ .suspend = kszphy_suspend, |
19409 |
++ .resume = kszphy_resume, |
19410 |
+ }, { |
19411 |
+ .name = "Micrel KSZ8051", |
19412 |
+ /* PHY_BASIC_FEATURES */ |
19413 |
+@@ -1623,8 +1623,8 @@ static struct phy_driver ksphy_driver[] = { |
19414 |
+ .get_strings = kszphy_get_strings, |
19415 |
+ .get_stats = kszphy_get_stats, |
19416 |
+ .match_phy_device = ksz8051_match_phy_device, |
19417 |
+- .suspend = genphy_suspend, |
19418 |
+- .resume = genphy_resume, |
19419 |
++ .suspend = kszphy_suspend, |
19420 |
++ .resume = kszphy_resume, |
19421 |
+ }, { |
19422 |
+ .phy_id = PHY_ID_KSZ8001, |
19423 |
+ .name = "Micrel KSZ8001 or KS8721", |
19424 |
+@@ -1638,8 +1638,8 @@ static struct phy_driver ksphy_driver[] = { |
19425 |
+ .get_sset_count = kszphy_get_sset_count, |
19426 |
+ .get_strings = kszphy_get_strings, |
19427 |
+ .get_stats = kszphy_get_stats, |
19428 |
+- .suspend = genphy_suspend, |
19429 |
+- .resume = genphy_resume, |
19430 |
++ .suspend = kszphy_suspend, |
19431 |
++ .resume = kszphy_resume, |
19432 |
+ }, { |
19433 |
+ .phy_id = PHY_ID_KSZ8081, |
19434 |
+ .name = "Micrel KSZ8081 or KSZ8091", |
19435 |
+@@ -1669,8 +1669,8 @@ static struct phy_driver ksphy_driver[] = { |
19436 |
+ .config_init = ksz8061_config_init, |
19437 |
+ .config_intr = kszphy_config_intr, |
19438 |
+ .handle_interrupt = kszphy_handle_interrupt, |
19439 |
+- .suspend = genphy_suspend, |
19440 |
+- .resume = genphy_resume, |
19441 |
++ .suspend = kszphy_suspend, |
19442 |
++ .resume = kszphy_resume, |
19443 |
+ }, { |
19444 |
+ .phy_id = PHY_ID_KSZ9021, |
19445 |
+ .phy_id_mask = 0x000ffffe, |
19446 |
+@@ -1685,8 +1685,8 @@ static struct phy_driver ksphy_driver[] = { |
19447 |
+ .get_sset_count = kszphy_get_sset_count, |
19448 |
+ .get_strings = kszphy_get_strings, |
19449 |
+ .get_stats = kszphy_get_stats, |
19450 |
+- .suspend = genphy_suspend, |
19451 |
+- .resume = genphy_resume, |
19452 |
++ .suspend = kszphy_suspend, |
19453 |
++ .resume = kszphy_resume, |
19454 |
+ .read_mmd = genphy_read_mmd_unsupported, |
19455 |
+ .write_mmd = genphy_write_mmd_unsupported, |
19456 |
+ }, { |
19457 |
+@@ -1704,7 +1704,7 @@ static struct phy_driver ksphy_driver[] = { |
19458 |
+ .get_sset_count = kszphy_get_sset_count, |
19459 |
+ .get_strings = kszphy_get_strings, |
19460 |
+ .get_stats = kszphy_get_stats, |
19461 |
+- .suspend = genphy_suspend, |
19462 |
++ .suspend = kszphy_suspend, |
19463 |
+ .resume = kszphy_resume, |
19464 |
+ }, { |
19465 |
+ .phy_id = PHY_ID_LAN8814, |
19466 |
+@@ -1732,7 +1732,7 @@ static struct phy_driver ksphy_driver[] = { |
19467 |
+ .get_sset_count = kszphy_get_sset_count, |
19468 |
+ .get_strings = kszphy_get_strings, |
19469 |
+ .get_stats = kszphy_get_stats, |
19470 |
+- .suspend = genphy_suspend, |
19471 |
++ .suspend = kszphy_suspend, |
19472 |
+ .resume = kszphy_resume, |
19473 |
+ }, { |
19474 |
+ .phy_id = PHY_ID_KSZ8873MLL, |
19475 |
+diff --git a/drivers/net/phy/phy-core.c b/drivers/net/phy/phy-core.c |
19476 |
+index 2870c33b8975d..271fc01f7f7fd 100644 |
19477 |
+--- a/drivers/net/phy/phy-core.c |
19478 |
++++ b/drivers/net/phy/phy-core.c |
19479 |
+@@ -162,11 +162,11 @@ static const struct phy_setting settings[] = { |
19480 |
+ PHY_SETTING( 2500, FULL, 2500baseT_Full ), |
19481 |
+ PHY_SETTING( 2500, FULL, 2500baseX_Full ), |
19482 |
+ /* 1G */ |
19483 |
+- PHY_SETTING( 1000, FULL, 1000baseKX_Full ), |
19484 |
+ PHY_SETTING( 1000, FULL, 1000baseT_Full ), |
19485 |
+ PHY_SETTING( 1000, HALF, 1000baseT_Half ), |
19486 |
+ PHY_SETTING( 1000, FULL, 1000baseT1_Full ), |
19487 |
+ PHY_SETTING( 1000, FULL, 1000baseX_Full ), |
19488 |
++ PHY_SETTING( 1000, FULL, 1000baseKX_Full ), |
19489 |
+ /* 100M */ |
19490 |
+ PHY_SETTING( 100, FULL, 100baseT_Full ), |
19491 |
+ PHY_SETTING( 100, FULL, 100baseT1_Full ), |
19492 |
+diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c |
19493 |
+index ab77a9f439ef9..4720b24ca51b5 100644 |
19494 |
+--- a/drivers/net/phy/sfp.c |
19495 |
++++ b/drivers/net/phy/sfp.c |
19496 |
+@@ -1641,17 +1641,20 @@ static int sfp_sm_probe_for_phy(struct sfp *sfp) |
19497 |
+ static int sfp_module_parse_power(struct sfp *sfp) |
19498 |
+ { |
19499 |
+ u32 power_mW = 1000; |
19500 |
++ bool supports_a2; |
19501 |
+ |
19502 |
+ if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_POWER_DECL)) |
19503 |
+ power_mW = 1500; |
19504 |
+ if (sfp->id.ext.options & cpu_to_be16(SFP_OPTIONS_HIGH_POWER_LEVEL)) |
19505 |
+ power_mW = 2000; |
19506 |
+ |
19507 |
++ supports_a2 = sfp->id.ext.sff8472_compliance != |
19508 |
++ SFP_SFF8472_COMPLIANCE_NONE || |
19509 |
++ sfp->id.ext.diagmon & SFP_DIAGMON_DDM; |
19510 |
++ |
19511 |
+ if (power_mW > sfp->max_power_mW) { |
19512 |
+ /* Module power specification exceeds the allowed maximum. */ |
19513 |
+- if (sfp->id.ext.sff8472_compliance == |
19514 |
+- SFP_SFF8472_COMPLIANCE_NONE && |
19515 |
+- !(sfp->id.ext.diagmon & SFP_DIAGMON_DDM)) { |
19516 |
++ if (!supports_a2) { |
19517 |
+ /* The module appears not to implement bus address |
19518 |
+ * 0xa2, so assume that the module powers up in the |
19519 |
+ * indicated mode. |
19520 |
+@@ -1668,11 +1671,25 @@ static int sfp_module_parse_power(struct sfp *sfp) |
19521 |
+ } |
19522 |
+ } |
19523 |
+ |
19524 |
++ if (power_mW <= 1000) { |
19525 |
++ /* Modules below 1W do not require a power change sequence */ |
19526 |
++ sfp->module_power_mW = power_mW; |
19527 |
++ return 0; |
19528 |
++ } |
19529 |
++ |
19530 |
++ if (!supports_a2) { |
19531 |
++ /* The module power level is below the host maximum and the |
19532 |
++ * module appears not to implement bus address 0xa2, so assume |
19533 |
++ * that the module powers up in the indicated mode. |
19534 |
++ */ |
19535 |
++ return 0; |
19536 |
++ } |
19537 |
++ |
19538 |
+ /* If the module requires a higher power mode, but also requires |
19539 |
+ * an address change sequence, warn the user that the module may |
19540 |
+ * not be functional. |
19541 |
+ */ |
19542 |
+- if (sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE && power_mW > 1000) { |
19543 |
++ if (sfp->id.ext.diagmon & SFP_DIAGMON_ADDRMODE) { |
19544 |
+ dev_warn(sfp->dev, |
19545 |
+ "Address Change Sequence not supported but module requires %u.%uW, module may not be functional\n", |
19546 |
+ power_mW / 1000, (power_mW / 100) % 10); |
19547 |
+diff --git a/drivers/net/ppp/ppp_generic.c b/drivers/net/ppp/ppp_generic.c |
19548 |
+index fb52cd175b45d..829d6ada1704c 100644 |
19549 |
+--- a/drivers/net/ppp/ppp_generic.c |
19550 |
++++ b/drivers/net/ppp/ppp_generic.c |
19551 |
+@@ -69,6 +69,8 @@ |
19552 |
+ #define MPHDRLEN 6 /* multilink protocol header length */ |
19553 |
+ #define MPHDRLEN_SSN 4 /* ditto with short sequence numbers */ |
19554 |
+ |
19555 |
++#define PPP_PROTO_LEN 2 |
19556 |
++ |
19557 |
+ /* |
19558 |
+ * An instance of /dev/ppp can be associated with either a ppp |
19559 |
+ * interface unit or a ppp channel. In both cases, file->private_data |
19560 |
+@@ -497,6 +499,9 @@ static ssize_t ppp_write(struct file *file, const char __user *buf, |
19561 |
+ |
19562 |
+ if (!pf) |
19563 |
+ return -ENXIO; |
19564 |
++ /* All PPP packets should start with the 2-byte protocol */ |
19565 |
++ if (count < PPP_PROTO_LEN) |
19566 |
++ return -EINVAL; |
19567 |
+ ret = -ENOMEM; |
19568 |
+ skb = alloc_skb(count + pf->hdrlen, GFP_KERNEL); |
19569 |
+ if (!skb) |
19570 |
+@@ -1764,7 +1769,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb) |
19571 |
+ } |
19572 |
+ |
19573 |
+ ++ppp->stats64.tx_packets; |
19574 |
+- ppp->stats64.tx_bytes += skb->len - 2; |
19575 |
++ ppp->stats64.tx_bytes += skb->len - PPP_PROTO_LEN; |
19576 |
+ |
19577 |
+ switch (proto) { |
19578 |
+ case PPP_IP: |
19579 |
+diff --git a/drivers/net/usb/mcs7830.c b/drivers/net/usb/mcs7830.c |
19580 |
+index 66866bef25df7..a31a3b9cbd58d 100644 |
19581 |
+--- a/drivers/net/usb/mcs7830.c |
19582 |
++++ b/drivers/net/usb/mcs7830.c |
19583 |
+@@ -108,8 +108,16 @@ static const char driver_name[] = "MOSCHIP usb-ethernet driver"; |
19584 |
+ |
19585 |
+ static int mcs7830_get_reg(struct usbnet *dev, u16 index, u16 size, void *data) |
19586 |
+ { |
19587 |
+- return usbnet_read_cmd(dev, MCS7830_RD_BREQ, MCS7830_RD_BMREQ, |
19588 |
+- 0x0000, index, data, size); |
19589 |
++ int ret; |
19590 |
++ |
19591 |
++ ret = usbnet_read_cmd(dev, MCS7830_RD_BREQ, MCS7830_RD_BMREQ, |
19592 |
++ 0x0000, index, data, size); |
19593 |
++ if (ret < 0) |
19594 |
++ return ret; |
19595 |
++ else if (ret < size) |
19596 |
++ return -ENODATA; |
19597 |
++ |
19598 |
++ return ret; |
19599 |
+ } |
19600 |
+ |
19601 |
+ static int mcs7830_set_reg(struct usbnet *dev, u16 index, u16 size, const void *data) |
19602 |
+diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c |
19603 |
+index f91dabd65ecd8..026e7487c45b5 100644 |
19604 |
+--- a/drivers/net/usb/smsc95xx.c |
19605 |
++++ b/drivers/net/usb/smsc95xx.c |
19606 |
+@@ -1961,7 +1961,8 @@ static const struct driver_info smsc95xx_info = { |
19607 |
+ .bind = smsc95xx_bind, |
19608 |
+ .unbind = smsc95xx_unbind, |
19609 |
+ .link_reset = smsc95xx_link_reset, |
19610 |
+- .reset = smsc95xx_start_phy, |
19611 |
++ .reset = smsc95xx_reset, |
19612 |
++ .check_connect = smsc95xx_start_phy, |
19613 |
+ .stop = smsc95xx_stop, |
19614 |
+ .rx_fixup = smsc95xx_rx_fixup, |
19615 |
+ .tx_fixup = smsc95xx_tx_fixup, |
19616 |
+diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c b/drivers/net/wireless/ath/ar5523/ar5523.c |
19617 |
+index 49cc4b7ed5163..1baec4b412c8d 100644 |
19618 |
+--- a/drivers/net/wireless/ath/ar5523/ar5523.c |
19619 |
++++ b/drivers/net/wireless/ath/ar5523/ar5523.c |
19620 |
+@@ -153,6 +153,10 @@ static void ar5523_cmd_rx_cb(struct urb *urb) |
19621 |
+ ar5523_err(ar, "Invalid reply to WDCMSG_TARGET_START"); |
19622 |
+ return; |
19623 |
+ } |
19624 |
++ if (!cmd->odata) { |
19625 |
++ ar5523_err(ar, "Unexpected WDCMSG_TARGET_START reply"); |
19626 |
++ return; |
19627 |
++ } |
19628 |
+ memcpy(cmd->odata, hdr + 1, sizeof(u32)); |
19629 |
+ cmd->olen = sizeof(u32); |
19630 |
+ cmd->res = 0; |
19631 |
+diff --git a/drivers/net/wireless/ath/ath10k/core.c b/drivers/net/wireless/ath/ath10k/core.c |
19632 |
+index 64c7145b51a2e..58e86e662ab83 100644 |
19633 |
+--- a/drivers/net/wireless/ath/ath10k/core.c |
19634 |
++++ b/drivers/net/wireless/ath/ath10k/core.c |
19635 |
+@@ -89,6 +89,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19636 |
+ .rri_on_ddr = false, |
19637 |
+ .hw_filter_reset_required = true, |
19638 |
+ .fw_diag_ce_download = false, |
19639 |
++ .credit_size_workaround = false, |
19640 |
+ .tx_stats_over_pktlog = true, |
19641 |
+ .dynamic_sar_support = false, |
19642 |
+ }, |
19643 |
+@@ -124,6 +125,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19644 |
+ .rri_on_ddr = false, |
19645 |
+ .hw_filter_reset_required = true, |
19646 |
+ .fw_diag_ce_download = false, |
19647 |
++ .credit_size_workaround = false, |
19648 |
+ .tx_stats_over_pktlog = true, |
19649 |
+ .dynamic_sar_support = false, |
19650 |
+ }, |
19651 |
+@@ -160,6 +162,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19652 |
+ .rri_on_ddr = false, |
19653 |
+ .hw_filter_reset_required = true, |
19654 |
+ .fw_diag_ce_download = false, |
19655 |
++ .credit_size_workaround = false, |
19656 |
+ .tx_stats_over_pktlog = false, |
19657 |
+ .dynamic_sar_support = false, |
19658 |
+ }, |
19659 |
+@@ -190,6 +193,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19660 |
+ .num_wds_entries = 0x20, |
19661 |
+ .uart_pin_workaround = true, |
19662 |
+ .tx_stats_over_pktlog = false, |
19663 |
++ .credit_size_workaround = false, |
19664 |
+ .bmi_large_size_download = true, |
19665 |
+ .supports_peer_stats_info = true, |
19666 |
+ .dynamic_sar_support = true, |
19667 |
+@@ -226,6 +230,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19668 |
+ .rri_on_ddr = false, |
19669 |
+ .hw_filter_reset_required = true, |
19670 |
+ .fw_diag_ce_download = false, |
19671 |
++ .credit_size_workaround = false, |
19672 |
+ .tx_stats_over_pktlog = false, |
19673 |
+ .dynamic_sar_support = false, |
19674 |
+ }, |
19675 |
+@@ -261,6 +266,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19676 |
+ .rri_on_ddr = false, |
19677 |
+ .hw_filter_reset_required = true, |
19678 |
+ .fw_diag_ce_download = false, |
19679 |
++ .credit_size_workaround = false, |
19680 |
+ .tx_stats_over_pktlog = false, |
19681 |
+ .dynamic_sar_support = false, |
19682 |
+ }, |
19683 |
+@@ -296,6 +302,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19684 |
+ .rri_on_ddr = false, |
19685 |
+ .hw_filter_reset_required = true, |
19686 |
+ .fw_diag_ce_download = false, |
19687 |
++ .credit_size_workaround = false, |
19688 |
+ .tx_stats_over_pktlog = false, |
19689 |
+ .dynamic_sar_support = false, |
19690 |
+ }, |
19691 |
+@@ -334,6 +341,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19692 |
+ .rri_on_ddr = false, |
19693 |
+ .hw_filter_reset_required = true, |
19694 |
+ .fw_diag_ce_download = true, |
19695 |
++ .credit_size_workaround = false, |
19696 |
+ .tx_stats_over_pktlog = false, |
19697 |
+ .supports_peer_stats_info = true, |
19698 |
+ .dynamic_sar_support = true, |
19699 |
+@@ -376,6 +384,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19700 |
+ .rri_on_ddr = false, |
19701 |
+ .hw_filter_reset_required = true, |
19702 |
+ .fw_diag_ce_download = false, |
19703 |
++ .credit_size_workaround = false, |
19704 |
+ .tx_stats_over_pktlog = false, |
19705 |
+ .dynamic_sar_support = false, |
19706 |
+ }, |
19707 |
+@@ -424,6 +433,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19708 |
+ .rri_on_ddr = false, |
19709 |
+ .hw_filter_reset_required = true, |
19710 |
+ .fw_diag_ce_download = false, |
19711 |
++ .credit_size_workaround = false, |
19712 |
+ .tx_stats_over_pktlog = false, |
19713 |
+ .dynamic_sar_support = false, |
19714 |
+ }, |
19715 |
+@@ -469,6 +479,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19716 |
+ .rri_on_ddr = false, |
19717 |
+ .hw_filter_reset_required = true, |
19718 |
+ .fw_diag_ce_download = false, |
19719 |
++ .credit_size_workaround = false, |
19720 |
+ .tx_stats_over_pktlog = false, |
19721 |
+ .dynamic_sar_support = false, |
19722 |
+ }, |
19723 |
+@@ -504,6 +515,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19724 |
+ .rri_on_ddr = false, |
19725 |
+ .hw_filter_reset_required = true, |
19726 |
+ .fw_diag_ce_download = false, |
19727 |
++ .credit_size_workaround = false, |
19728 |
+ .tx_stats_over_pktlog = false, |
19729 |
+ .dynamic_sar_support = false, |
19730 |
+ }, |
19731 |
+@@ -541,6 +553,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19732 |
+ .rri_on_ddr = false, |
19733 |
+ .hw_filter_reset_required = true, |
19734 |
+ .fw_diag_ce_download = true, |
19735 |
++ .credit_size_workaround = false, |
19736 |
+ .tx_stats_over_pktlog = false, |
19737 |
+ .dynamic_sar_support = false, |
19738 |
+ }, |
19739 |
+@@ -570,6 +583,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19740 |
+ .ast_skid_limit = 0x10, |
19741 |
+ .num_wds_entries = 0x20, |
19742 |
+ .uart_pin_workaround = true, |
19743 |
++ .credit_size_workaround = true, |
19744 |
+ .dynamic_sar_support = false, |
19745 |
+ }, |
19746 |
+ { |
19747 |
+@@ -611,6 +625,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19748 |
+ .rri_on_ddr = false, |
19749 |
+ .hw_filter_reset_required = true, |
19750 |
+ .fw_diag_ce_download = false, |
19751 |
++ .credit_size_workaround = false, |
19752 |
+ .tx_stats_over_pktlog = false, |
19753 |
+ .dynamic_sar_support = false, |
19754 |
+ }, |
19755 |
+@@ -639,6 +654,7 @@ static const struct ath10k_hw_params ath10k_hw_params_list[] = { |
19756 |
+ .rri_on_ddr = true, |
19757 |
+ .hw_filter_reset_required = false, |
19758 |
+ .fw_diag_ce_download = false, |
19759 |
++ .credit_size_workaround = false, |
19760 |
+ .tx_stats_over_pktlog = false, |
19761 |
+ .dynamic_sar_support = true, |
19762 |
+ }, |
19763 |
+@@ -714,6 +730,7 @@ static void ath10k_send_suspend_complete(struct ath10k *ar) |
19764 |
+ |
19765 |
+ static int ath10k_init_sdio(struct ath10k *ar, enum ath10k_firmware_mode mode) |
19766 |
+ { |
19767 |
++ bool mtu_workaround = ar->hw_params.credit_size_workaround; |
19768 |
+ int ret; |
19769 |
+ u32 param = 0; |
19770 |
+ |
19771 |
+@@ -731,7 +748,7 @@ static int ath10k_init_sdio(struct ath10k *ar, enum ath10k_firmware_mode mode) |
19772 |
+ |
19773 |
+ param |= HI_ACS_FLAGS_SDIO_REDUCE_TX_COMPL_SET; |
19774 |
+ |
19775 |
+- if (mode == ATH10K_FIRMWARE_MODE_NORMAL) |
19776 |
++ if (mode == ATH10K_FIRMWARE_MODE_NORMAL && !mtu_workaround) |
19777 |
+ param |= HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE; |
19778 |
+ else |
19779 |
+ param &= ~HI_ACS_FLAGS_ALT_DATA_CREDIT_SIZE; |
19780 |
+diff --git a/drivers/net/wireless/ath/ath10k/htt_tx.c b/drivers/net/wireless/ath/ath10k/htt_tx.c |
19781 |
+index d6b8bdcef4160..b793eac2cfac8 100644 |
19782 |
+--- a/drivers/net/wireless/ath/ath10k/htt_tx.c |
19783 |
++++ b/drivers/net/wireless/ath/ath10k/htt_tx.c |
19784 |
+@@ -147,6 +147,9 @@ void ath10k_htt_tx_dec_pending(struct ath10k_htt *htt) |
19785 |
+ htt->num_pending_tx--; |
19786 |
+ if (htt->num_pending_tx == htt->max_num_pending_tx - 1) |
19787 |
+ ath10k_mac_tx_unlock(htt->ar, ATH10K_TX_PAUSE_Q_FULL); |
19788 |
++ |
19789 |
++ if (htt->num_pending_tx == 0) |
19790 |
++ wake_up(&htt->empty_tx_wq); |
19791 |
+ } |
19792 |
+ |
19793 |
+ int ath10k_htt_tx_inc_pending(struct ath10k_htt *htt) |
19794 |
+diff --git a/drivers/net/wireless/ath/ath10k/hw.h b/drivers/net/wireless/ath/ath10k/hw.h |
19795 |
+index 6b03c7787e36a..591ef7416b613 100644 |
19796 |
+--- a/drivers/net/wireless/ath/ath10k/hw.h |
19797 |
++++ b/drivers/net/wireless/ath/ath10k/hw.h |
19798 |
+@@ -618,6 +618,9 @@ struct ath10k_hw_params { |
19799 |
+ */ |
19800 |
+ bool uart_pin_workaround; |
19801 |
+ |
19802 |
++ /* Workaround for the credit size calculation */ |
19803 |
++ bool credit_size_workaround; |
19804 |
++ |
19805 |
+ /* tx stats support over pktlog */ |
19806 |
+ bool tx_stats_over_pktlog; |
19807 |
+ |
19808 |
+diff --git a/drivers/net/wireless/ath/ath10k/txrx.c b/drivers/net/wireless/ath/ath10k/txrx.c |
19809 |
+index 7c9ea0c073d8b..6f8b642188941 100644 |
19810 |
+--- a/drivers/net/wireless/ath/ath10k/txrx.c |
19811 |
++++ b/drivers/net/wireless/ath/ath10k/txrx.c |
19812 |
+@@ -82,8 +82,6 @@ int ath10k_txrx_tx_unref(struct ath10k_htt *htt, |
19813 |
+ flags = skb_cb->flags; |
19814 |
+ ath10k_htt_tx_free_msdu_id(htt, tx_done->msdu_id); |
19815 |
+ ath10k_htt_tx_dec_pending(htt); |
19816 |
+- if (htt->num_pending_tx == 0) |
19817 |
+- wake_up(&htt->empty_tx_wq); |
19818 |
+ spin_unlock_bh(&htt->tx_lock); |
19819 |
+ |
19820 |
+ rcu_read_lock(); |
19821 |
+diff --git a/drivers/net/wireless/ath/ath11k/ahb.c b/drivers/net/wireless/ath/ath11k/ahb.c |
19822 |
+index 8c9c781afc3e5..3fb0aa0008259 100644 |
19823 |
+--- a/drivers/net/wireless/ath/ath11k/ahb.c |
19824 |
++++ b/drivers/net/wireless/ath/ath11k/ahb.c |
19825 |
+@@ -175,8 +175,11 @@ static void __ath11k_ahb_ext_irq_disable(struct ath11k_base *ab) |
19826 |
+ |
19827 |
+ ath11k_ahb_ext_grp_disable(irq_grp); |
19828 |
+ |
19829 |
+- napi_synchronize(&irq_grp->napi); |
19830 |
+- napi_disable(&irq_grp->napi); |
19831 |
++ if (irq_grp->napi_enabled) { |
19832 |
++ napi_synchronize(&irq_grp->napi); |
19833 |
++ napi_disable(&irq_grp->napi); |
19834 |
++ irq_grp->napi_enabled = false; |
19835 |
++ } |
19836 |
+ } |
19837 |
+ } |
19838 |
+ |
19839 |
+@@ -206,13 +209,13 @@ static void ath11k_ahb_clearbit32(struct ath11k_base *ab, u8 bit, u32 offset) |
19840 |
+ |
19841 |
+ static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) |
19842 |
+ { |
19843 |
+- const struct ce_pipe_config *ce_config; |
19844 |
++ const struct ce_attr *ce_attr; |
19845 |
+ |
19846 |
+- ce_config = &ab->hw_params.target_ce_config[ce_id]; |
19847 |
+- if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_OUT) |
19848 |
++ ce_attr = &ab->hw_params.host_ce_config[ce_id]; |
19849 |
++ if (ce_attr->src_nentries) |
19850 |
+ ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_ADDRESS); |
19851 |
+ |
19852 |
+- if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_IN) { |
19853 |
++ if (ce_attr->dest_nentries) { |
19854 |
+ ath11k_ahb_setbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS); |
19855 |
+ ath11k_ahb_setbit32(ab, ce_id + CE_HOST_IE_3_SHIFT, |
19856 |
+ CE_HOST_IE_3_ADDRESS); |
19857 |
+@@ -221,13 +224,13 @@ static void ath11k_ahb_ce_irq_enable(struct ath11k_base *ab, u16 ce_id) |
19858 |
+ |
19859 |
+ static void ath11k_ahb_ce_irq_disable(struct ath11k_base *ab, u16 ce_id) |
19860 |
+ { |
19861 |
+- const struct ce_pipe_config *ce_config; |
19862 |
++ const struct ce_attr *ce_attr; |
19863 |
+ |
19864 |
+- ce_config = &ab->hw_params.target_ce_config[ce_id]; |
19865 |
+- if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_OUT) |
19866 |
++ ce_attr = &ab->hw_params.host_ce_config[ce_id]; |
19867 |
++ if (ce_attr->src_nentries) |
19868 |
+ ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_ADDRESS); |
19869 |
+ |
19870 |
+- if (__le32_to_cpu(ce_config->pipedir) & PIPEDIR_IN) { |
19871 |
++ if (ce_attr->dest_nentries) { |
19872 |
+ ath11k_ahb_clearbit32(ab, ce_id, CE_HOST_IE_2_ADDRESS); |
19873 |
+ ath11k_ahb_clearbit32(ab, ce_id + CE_HOST_IE_3_SHIFT, |
19874 |
+ CE_HOST_IE_3_ADDRESS); |
19875 |
+@@ -300,7 +303,10 @@ static void ath11k_ahb_ext_irq_enable(struct ath11k_base *ab) |
19876 |
+ for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { |
19877 |
+ struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; |
19878 |
+ |
19879 |
+- napi_enable(&irq_grp->napi); |
19880 |
++ if (!irq_grp->napi_enabled) { |
19881 |
++ napi_enable(&irq_grp->napi); |
19882 |
++ irq_grp->napi_enabled = true; |
19883 |
++ } |
19884 |
+ ath11k_ahb_ext_grp_enable(irq_grp); |
19885 |
+ } |
19886 |
+ } |
19887 |
+diff --git a/drivers/net/wireless/ath/ath11k/core.c b/drivers/net/wireless/ath/ath11k/core.c |
19888 |
+index 969bf1a590d99..7dcf6b13f7949 100644 |
19889 |
+--- a/drivers/net/wireless/ath/ath11k/core.c |
19890 |
++++ b/drivers/net/wireless/ath/ath11k/core.c |
19891 |
+@@ -347,11 +347,26 @@ static int ath11k_core_create_board_name(struct ath11k_base *ab, char *name, |
19892 |
+ scnprintf(variant, sizeof(variant), ",variant=%s", |
19893 |
+ ab->qmi.target.bdf_ext); |
19894 |
+ |
19895 |
+- scnprintf(name, name_len, |
19896 |
+- "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s", |
19897 |
+- ath11k_bus_str(ab->hif.bus), |
19898 |
+- ab->qmi.target.chip_id, |
19899 |
+- ab->qmi.target.board_id, variant); |
19900 |
++ switch (ab->id.bdf_search) { |
19901 |
++ case ATH11K_BDF_SEARCH_BUS_AND_BOARD: |
19902 |
++ scnprintf(name, name_len, |
19903 |
++ "bus=%s,vendor=%04x,device=%04x,subsystem-vendor=%04x,subsystem-device=%04x,qmi-chip-id=%d,qmi-board-id=%d%s", |
19904 |
++ ath11k_bus_str(ab->hif.bus), |
19905 |
++ ab->id.vendor, ab->id.device, |
19906 |
++ ab->id.subsystem_vendor, |
19907 |
++ ab->id.subsystem_device, |
19908 |
++ ab->qmi.target.chip_id, |
19909 |
++ ab->qmi.target.board_id, |
19910 |
++ variant); |
19911 |
++ break; |
19912 |
++ default: |
19913 |
++ scnprintf(name, name_len, |
19914 |
++ "bus=%s,qmi-chip-id=%d,qmi-board-id=%d%s", |
19915 |
++ ath11k_bus_str(ab->hif.bus), |
19916 |
++ ab->qmi.target.chip_id, |
19917 |
++ ab->qmi.target.board_id, variant); |
19918 |
++ break; |
19919 |
++ } |
19920 |
+ |
19921 |
+ ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot using board name '%s'\n", name); |
19922 |
+ |
19923 |
+@@ -588,7 +603,7 @@ static int ath11k_core_fetch_board_data_api_1(struct ath11k_base *ab, |
19924 |
+ return 0; |
19925 |
+ } |
19926 |
+ |
19927 |
+-#define BOARD_NAME_SIZE 100 |
19928 |
++#define BOARD_NAME_SIZE 200 |
19929 |
+ int ath11k_core_fetch_bdf(struct ath11k_base *ab, struct ath11k_board_data *bd) |
19930 |
+ { |
19931 |
+ char boardname[BOARD_NAME_SIZE]; |
19932 |
+diff --git a/drivers/net/wireless/ath/ath11k/core.h b/drivers/net/wireless/ath/ath11k/core.h |
19933 |
+index 018fb2385f2a3..caa8f6eba0097 100644 |
19934 |
+--- a/drivers/net/wireless/ath/ath11k/core.h |
19935 |
++++ b/drivers/net/wireless/ath/ath11k/core.h |
19936 |
+@@ -47,6 +47,11 @@ enum ath11k_supported_bw { |
19937 |
+ ATH11K_BW_160 = 3, |
19938 |
+ }; |
19939 |
+ |
19940 |
++enum ath11k_bdf_search { |
19941 |
++ ATH11K_BDF_SEARCH_DEFAULT, |
19942 |
++ ATH11K_BDF_SEARCH_BUS_AND_BOARD, |
19943 |
++}; |
19944 |
++ |
19945 |
+ enum wme_ac { |
19946 |
+ WME_AC_BE, |
19947 |
+ WME_AC_BK, |
19948 |
+@@ -132,6 +137,7 @@ struct ath11k_ext_irq_grp { |
19949 |
+ u32 num_irq; |
19950 |
+ u32 grp_id; |
19951 |
+ u64 timestamp; |
19952 |
++ bool napi_enabled; |
19953 |
+ struct napi_struct napi; |
19954 |
+ struct net_device napi_ndev; |
19955 |
+ }; |
19956 |
+@@ -701,7 +707,6 @@ struct ath11k_base { |
19957 |
+ u32 wlan_init_status; |
19958 |
+ int irq_num[ATH11K_IRQ_NUM_MAX]; |
19959 |
+ struct ath11k_ext_irq_grp ext_irq_grp[ATH11K_EXT_IRQ_GRP_NUM_MAX]; |
19960 |
+- struct napi_struct *napi; |
19961 |
+ struct ath11k_targ_cap target_caps; |
19962 |
+ u32 ext_service_bitmap[WMI_SERVICE_EXT_BM_SIZE]; |
19963 |
+ bool pdevs_macaddr_valid; |
19964 |
+@@ -747,6 +752,14 @@ struct ath11k_base { |
19965 |
+ |
19966 |
+ struct completion htc_suspend; |
19967 |
+ |
19968 |
++ struct { |
19969 |
++ enum ath11k_bdf_search bdf_search; |
19970 |
++ u32 vendor; |
19971 |
++ u32 device; |
19972 |
++ u32 subsystem_vendor; |
19973 |
++ u32 subsystem_device; |
19974 |
++ } id; |
19975 |
++ |
19976 |
+ /* must be last */ |
19977 |
+ u8 drv_priv[0] __aligned(sizeof(void *)); |
19978 |
+ }; |
19979 |
+diff --git a/drivers/net/wireless/ath/ath11k/dp.h b/drivers/net/wireless/ath/ath11k/dp.h |
19980 |
+index ee768ccce46e1..d3e50e34f23dd 100644 |
19981 |
+--- a/drivers/net/wireless/ath/ath11k/dp.h |
19982 |
++++ b/drivers/net/wireless/ath/ath11k/dp.h |
19983 |
+@@ -515,7 +515,8 @@ struct htt_ppdu_stats_cfg_cmd { |
19984 |
+ } __packed; |
19985 |
+ |
19986 |
+ #define HTT_PPDU_STATS_CFG_MSG_TYPE GENMASK(7, 0) |
19987 |
+-#define HTT_PPDU_STATS_CFG_PDEV_ID GENMASK(15, 8) |
19988 |
++#define HTT_PPDU_STATS_CFG_SOC_STATS BIT(8) |
19989 |
++#define HTT_PPDU_STATS_CFG_PDEV_ID GENMASK(15, 9) |
19990 |
+ #define HTT_PPDU_STATS_CFG_TLV_TYPE_BITMASK GENMASK(31, 16) |
19991 |
+ |
19992 |
+ enum htt_ppdu_stats_tag_type { |
19993 |
+diff --git a/drivers/net/wireless/ath/ath11k/dp_tx.c b/drivers/net/wireless/ath/ath11k/dp_tx.c |
19994 |
+index 8bba5234f81fc..bb8744ccfa00c 100644 |
19995 |
+--- a/drivers/net/wireless/ath/ath11k/dp_tx.c |
19996 |
++++ b/drivers/net/wireless/ath/ath11k/dp_tx.c |
19997 |
+@@ -895,7 +895,7 @@ int ath11k_dp_tx_htt_h2t_ppdu_stats_req(struct ath11k *ar, u32 mask) |
19998 |
+ cmd->msg = FIELD_PREP(HTT_PPDU_STATS_CFG_MSG_TYPE, |
19999 |
+ HTT_H2T_MSG_TYPE_PPDU_STATS_CFG); |
20000 |
+ |
20001 |
+- pdev_mask = 1 << (i + 1); |
20002 |
++ pdev_mask = 1 << (ar->pdev_idx + i); |
20003 |
+ cmd->msg |= FIELD_PREP(HTT_PPDU_STATS_CFG_PDEV_ID, pdev_mask); |
20004 |
+ cmd->msg |= FIELD_PREP(HTT_PPDU_STATS_CFG_TLV_TYPE_BITMASK, mask); |
20005 |
+ |
20006 |
+diff --git a/drivers/net/wireless/ath/ath11k/hal.c b/drivers/net/wireless/ath/ath11k/hal.c |
20007 |
+index eaa0edca55761..5dbf5596c9e8e 100644 |
20008 |
+--- a/drivers/net/wireless/ath/ath11k/hal.c |
20009 |
++++ b/drivers/net/wireless/ath/ath11k/hal.c |
20010 |
+@@ -947,6 +947,7 @@ int ath11k_hal_srng_setup(struct ath11k_base *ab, enum hal_ring_type type, |
20011 |
+ srng->msi_data = params->msi_data; |
20012 |
+ srng->initialized = 1; |
20013 |
+ spin_lock_init(&srng->lock); |
20014 |
++ lockdep_set_class(&srng->lock, hal->srng_key + ring_id); |
20015 |
+ |
20016 |
+ for (i = 0; i < HAL_SRNG_NUM_REG_GRP; i++) { |
20017 |
+ srng->hwreg_base[i] = srng_config->reg_start[i] + |
20018 |
+@@ -1233,6 +1234,24 @@ static int ath11k_hal_srng_create_config(struct ath11k_base *ab) |
20019 |
+ return 0; |
20020 |
+ } |
20021 |
+ |
20022 |
++static void ath11k_hal_register_srng_key(struct ath11k_base *ab) |
20023 |
++{ |
20024 |
++ struct ath11k_hal *hal = &ab->hal; |
20025 |
++ u32 ring_id; |
20026 |
++ |
20027 |
++ for (ring_id = 0; ring_id < HAL_SRNG_RING_ID_MAX; ring_id++) |
20028 |
++ lockdep_register_key(hal->srng_key + ring_id); |
20029 |
++} |
20030 |
++ |
20031 |
++static void ath11k_hal_unregister_srng_key(struct ath11k_base *ab) |
20032 |
++{ |
20033 |
++ struct ath11k_hal *hal = &ab->hal; |
20034 |
++ u32 ring_id; |
20035 |
++ |
20036 |
++ for (ring_id = 0; ring_id < HAL_SRNG_RING_ID_MAX; ring_id++) |
20037 |
++ lockdep_unregister_key(hal->srng_key + ring_id); |
20038 |
++} |
20039 |
++ |
20040 |
+ int ath11k_hal_srng_init(struct ath11k_base *ab) |
20041 |
+ { |
20042 |
+ struct ath11k_hal *hal = &ab->hal; |
20043 |
+@@ -1252,6 +1271,8 @@ int ath11k_hal_srng_init(struct ath11k_base *ab) |
20044 |
+ if (ret) |
20045 |
+ goto err_free_cont_rdp; |
20046 |
+ |
20047 |
++ ath11k_hal_register_srng_key(ab); |
20048 |
++ |
20049 |
+ return 0; |
20050 |
+ |
20051 |
+ err_free_cont_rdp: |
20052 |
+@@ -1266,6 +1287,7 @@ void ath11k_hal_srng_deinit(struct ath11k_base *ab) |
20053 |
+ { |
20054 |
+ struct ath11k_hal *hal = &ab->hal; |
20055 |
+ |
20056 |
++ ath11k_hal_unregister_srng_key(ab); |
20057 |
+ ath11k_hal_free_cont_rdp(ab); |
20058 |
+ ath11k_hal_free_cont_wrp(ab); |
20059 |
+ kfree(hal->srng_config); |
20060 |
+diff --git a/drivers/net/wireless/ath/ath11k/hal.h b/drivers/net/wireless/ath/ath11k/hal.h |
20061 |
+index 35ed3a14e200a..7fdcd8bbf7e98 100644 |
20062 |
+--- a/drivers/net/wireless/ath/ath11k/hal.h |
20063 |
++++ b/drivers/net/wireless/ath/ath11k/hal.h |
20064 |
+@@ -901,6 +901,8 @@ struct ath11k_hal { |
20065 |
+ /* shadow register configuration */ |
20066 |
+ u32 shadow_reg_addr[HAL_SHADOW_NUM_REGS]; |
20067 |
+ int num_shadow_reg_configured; |
20068 |
++ |
20069 |
++ struct lock_class_key srng_key[HAL_SRNG_RING_ID_MAX]; |
20070 |
+ }; |
20071 |
+ |
20072 |
+ u32 ath11k_hal_reo_qdesc_size(u32 ba_window_size, u8 tid); |
20073 |
+diff --git a/drivers/net/wireless/ath/ath11k/hw.c b/drivers/net/wireless/ath/ath11k/hw.c |
20074 |
+index d9596903b0a58..3e92cc7cfe4c9 100644 |
20075 |
+--- a/drivers/net/wireless/ath/ath11k/hw.c |
20076 |
++++ b/drivers/net/wireless/ath/ath11k/hw.c |
20077 |
+@@ -1015,8 +1015,6 @@ const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_ipq8074 = { |
20078 |
+ const struct ath11k_hw_ring_mask ath11k_hw_ring_mask_qca6390 = { |
20079 |
+ .tx = { |
20080 |
+ ATH11K_TX_RING_MASK_0, |
20081 |
+- ATH11K_TX_RING_MASK_1, |
20082 |
+- ATH11K_TX_RING_MASK_2, |
20083 |
+ }, |
20084 |
+ .rx_mon_status = { |
20085 |
+ 0, 0, 0, 0, |
20086 |
+diff --git a/drivers/net/wireless/ath/ath11k/mac.c b/drivers/net/wireless/ath/ath11k/mac.c |
20087 |
+index 89a64ebd620f3..3834be1587057 100644 |
20088 |
+--- a/drivers/net/wireless/ath/ath11k/mac.c |
20089 |
++++ b/drivers/net/wireless/ath/ath11k/mac.c |
20090 |
+@@ -1,6 +1,7 @@ |
20091 |
+ // SPDX-License-Identifier: BSD-3-Clause-Clear |
20092 |
+ /* |
20093 |
+ * Copyright (c) 2018-2019 The Linux Foundation. All rights reserved. |
20094 |
++ * Copyright (c) 2021 Qualcomm Innovation Center, Inc. All rights reserved. |
20095 |
+ */ |
20096 |
+ |
20097 |
+ #include <net/mac80211.h> |
20098 |
+@@ -767,11 +768,15 @@ static int ath11k_mac_setup_bcn_tmpl(struct ath11k_vif *arvif) |
20099 |
+ |
20100 |
+ if (cfg80211_find_ie(WLAN_EID_RSN, ies, (skb_tail_pointer(bcn) - ies))) |
20101 |
+ arvif->rsnie_present = true; |
20102 |
++ else |
20103 |
++ arvif->rsnie_present = false; |
20104 |
+ |
20105 |
+ if (cfg80211_find_vendor_ie(WLAN_OUI_MICROSOFT, |
20106 |
+ WLAN_OUI_TYPE_MICROSOFT_WPA, |
20107 |
+ ies, (skb_tail_pointer(bcn) - ies))) |
20108 |
+ arvif->wpaie_present = true; |
20109 |
++ else |
20110 |
++ arvif->wpaie_present = false; |
20111 |
+ |
20112 |
+ ret = ath11k_wmi_bcn_tmpl(ar, arvif->vdev_id, &offs, bcn); |
20113 |
+ |
20114 |
+@@ -2576,9 +2581,12 @@ static int ath11k_mac_op_hw_scan(struct ieee80211_hw *hw, |
20115 |
+ arg.scan_id = ATH11K_SCAN_ID; |
20116 |
+ |
20117 |
+ if (req->ie_len) { |
20118 |
++ arg.extraie.ptr = kmemdup(req->ie, req->ie_len, GFP_KERNEL); |
20119 |
++ if (!arg.extraie.ptr) { |
20120 |
++ ret = -ENOMEM; |
20121 |
++ goto exit; |
20122 |
++ } |
20123 |
+ arg.extraie.len = req->ie_len; |
20124 |
+- arg.extraie.ptr = kzalloc(req->ie_len, GFP_KERNEL); |
20125 |
+- memcpy(arg.extraie.ptr, req->ie, req->ie_len); |
20126 |
+ } |
20127 |
+ |
20128 |
+ if (req->n_ssids) { |
20129 |
+@@ -2655,9 +2663,7 @@ static int ath11k_install_key(struct ath11k_vif *arvif, |
20130 |
+ return 0; |
20131 |
+ |
20132 |
+ if (cmd == DISABLE_KEY) { |
20133 |
+- /* TODO: Check if FW expects value other than NONE for del */ |
20134 |
+- /* arg.key_cipher = WMI_CIPHER_NONE; */ |
20135 |
+- arg.key_len = 0; |
20136 |
++ arg.key_cipher = WMI_CIPHER_NONE; |
20137 |
+ arg.key_data = NULL; |
20138 |
+ goto install; |
20139 |
+ } |
20140 |
+@@ -2789,7 +2795,7 @@ static int ath11k_mac_op_set_key(struct ieee80211_hw *hw, enum set_key_cmd cmd, |
20141 |
+ /* flush the fragments cache during key (re)install to |
20142 |
+ * ensure all frags in the new frag list belong to the same key. |
20143 |
+ */ |
20144 |
+- if (peer && cmd == SET_KEY) |
20145 |
++ if (peer && sta && cmd == SET_KEY) |
20146 |
+ ath11k_peer_frags_flush(ar, peer); |
20147 |
+ spin_unlock_bh(&ab->base_lock); |
20148 |
+ |
20149 |
+@@ -4131,23 +4137,32 @@ static int __ath11k_set_antenna(struct ath11k *ar, u32 tx_ant, u32 rx_ant) |
20150 |
+ return 0; |
20151 |
+ } |
20152 |
+ |
20153 |
+-int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx) |
20154 |
++static void ath11k_mac_tx_mgmt_free(struct ath11k *ar, int buf_id) |
20155 |
+ { |
20156 |
+- struct sk_buff *msdu = skb; |
20157 |
++ struct sk_buff *msdu; |
20158 |
+ struct ieee80211_tx_info *info; |
20159 |
+- struct ath11k *ar = ctx; |
20160 |
+- struct ath11k_base *ab = ar->ab; |
20161 |
+ |
20162 |
+ spin_lock_bh(&ar->txmgmt_idr_lock); |
20163 |
+- idr_remove(&ar->txmgmt_idr, buf_id); |
20164 |
++ msdu = idr_remove(&ar->txmgmt_idr, buf_id); |
20165 |
+ spin_unlock_bh(&ar->txmgmt_idr_lock); |
20166 |
+- dma_unmap_single(ab->dev, ATH11K_SKB_CB(msdu)->paddr, msdu->len, |
20167 |
++ |
20168 |
++ if (!msdu) |
20169 |
++ return; |
20170 |
++ |
20171 |
++ dma_unmap_single(ar->ab->dev, ATH11K_SKB_CB(msdu)->paddr, msdu->len, |
20172 |
+ DMA_TO_DEVICE); |
20173 |
+ |
20174 |
+ info = IEEE80211_SKB_CB(msdu); |
20175 |
+ memset(&info->status, 0, sizeof(info->status)); |
20176 |
+ |
20177 |
+ ieee80211_free_txskb(ar->hw, msdu); |
20178 |
++} |
20179 |
++ |
20180 |
++int ath11k_mac_tx_mgmt_pending_free(int buf_id, void *skb, void *ctx) |
20181 |
++{ |
20182 |
++ struct ath11k *ar = ctx; |
20183 |
++ |
20184 |
++ ath11k_mac_tx_mgmt_free(ar, buf_id); |
20185 |
+ |
20186 |
+ return 0; |
20187 |
+ } |
20188 |
+@@ -4156,17 +4171,10 @@ static int ath11k_mac_vif_txmgmt_idr_remove(int buf_id, void *skb, void *ctx) |
20189 |
+ { |
20190 |
+ struct ieee80211_vif *vif = ctx; |
20191 |
+ struct ath11k_skb_cb *skb_cb = ATH11K_SKB_CB((struct sk_buff *)skb); |
20192 |
+- struct sk_buff *msdu = skb; |
20193 |
+ struct ath11k *ar = skb_cb->ar; |
20194 |
+- struct ath11k_base *ab = ar->ab; |
20195 |
+ |
20196 |
+- if (skb_cb->vif == vif) { |
20197 |
+- spin_lock_bh(&ar->txmgmt_idr_lock); |
20198 |
+- idr_remove(&ar->txmgmt_idr, buf_id); |
20199 |
+- spin_unlock_bh(&ar->txmgmt_idr_lock); |
20200 |
+- dma_unmap_single(ab->dev, skb_cb->paddr, msdu->len, |
20201 |
+- DMA_TO_DEVICE); |
20202 |
+- } |
20203 |
++ if (skb_cb->vif == vif) |
20204 |
++ ath11k_mac_tx_mgmt_free(ar, buf_id); |
20205 |
+ |
20206 |
+ return 0; |
20207 |
+ } |
20208 |
+@@ -4181,6 +4189,8 @@ static int ath11k_mac_mgmt_tx_wmi(struct ath11k *ar, struct ath11k_vif *arvif, |
20209 |
+ int buf_id; |
20210 |
+ int ret; |
20211 |
+ |
20212 |
++ ATH11K_SKB_CB(skb)->ar = ar; |
20213 |
++ |
20214 |
+ spin_lock_bh(&ar->txmgmt_idr_lock); |
20215 |
+ buf_id = idr_alloc(&ar->txmgmt_idr, skb, 0, |
20216 |
+ ATH11K_TX_MGMT_NUM_PENDING_MAX, GFP_ATOMIC); |
20217 |
+diff --git a/drivers/net/wireless/ath/ath11k/pci.c b/drivers/net/wireless/ath/ath11k/pci.c |
20218 |
+index 5abb38cc3b55f..54ce08f1c6e0c 100644 |
20219 |
+--- a/drivers/net/wireless/ath/ath11k/pci.c |
20220 |
++++ b/drivers/net/wireless/ath/ath11k/pci.c |
20221 |
+@@ -632,8 +632,11 @@ static void __ath11k_pci_ext_irq_disable(struct ath11k_base *sc) |
20222 |
+ |
20223 |
+ ath11k_pci_ext_grp_disable(irq_grp); |
20224 |
+ |
20225 |
+- napi_synchronize(&irq_grp->napi); |
20226 |
+- napi_disable(&irq_grp->napi); |
20227 |
++ if (irq_grp->napi_enabled) { |
20228 |
++ napi_synchronize(&irq_grp->napi); |
20229 |
++ napi_disable(&irq_grp->napi); |
20230 |
++ irq_grp->napi_enabled = false; |
20231 |
++ } |
20232 |
+ } |
20233 |
+ } |
20234 |
+ |
20235 |
+@@ -652,7 +655,10 @@ static void ath11k_pci_ext_irq_enable(struct ath11k_base *ab) |
20236 |
+ for (i = 0; i < ATH11K_EXT_IRQ_GRP_NUM_MAX; i++) { |
20237 |
+ struct ath11k_ext_irq_grp *irq_grp = &ab->ext_irq_grp[i]; |
20238 |
+ |
20239 |
+- napi_enable(&irq_grp->napi); |
20240 |
++ if (!irq_grp->napi_enabled) { |
20241 |
++ napi_enable(&irq_grp->napi); |
20242 |
++ irq_grp->napi_enabled = true; |
20243 |
++ } |
20244 |
+ ath11k_pci_ext_grp_enable(irq_grp); |
20245 |
+ } |
20246 |
+ } |
20247 |
+@@ -1218,6 +1224,15 @@ static int ath11k_pci_probe(struct pci_dev *pdev, |
20248 |
+ goto err_free_core; |
20249 |
+ } |
20250 |
+ |
20251 |
++ ath11k_dbg(ab, ATH11K_DBG_BOOT, "pci probe %04x:%04x %04x:%04x\n", |
20252 |
++ pdev->vendor, pdev->device, |
20253 |
++ pdev->subsystem_vendor, pdev->subsystem_device); |
20254 |
++ |
20255 |
++ ab->id.vendor = pdev->vendor; |
20256 |
++ ab->id.device = pdev->device; |
20257 |
++ ab->id.subsystem_vendor = pdev->subsystem_vendor; |
20258 |
++ ab->id.subsystem_device = pdev->subsystem_device; |
20259 |
++ |
20260 |
+ switch (pci_dev->device) { |
20261 |
+ case QCA6390_DEVICE_ID: |
20262 |
+ ath11k_pci_read_hw_version(ab, &soc_hw_version_major, |
20263 |
+@@ -1240,6 +1255,7 @@ static int ath11k_pci_probe(struct pci_dev *pdev, |
20264 |
+ ab->hw_rev = ATH11K_HW_QCN9074_HW10; |
20265 |
+ break; |
20266 |
+ case WCN6855_DEVICE_ID: |
20267 |
++ ab->id.bdf_search = ATH11K_BDF_SEARCH_BUS_AND_BOARD; |
20268 |
+ ath11k_pci_read_hw_version(ab, &soc_hw_version_major, |
20269 |
+ &soc_hw_version_minor); |
20270 |
+ switch (soc_hw_version_major) { |
20271 |
+diff --git a/drivers/net/wireless/ath/ath11k/qmi.c b/drivers/net/wireless/ath/ath11k/qmi.c |
20272 |
+index 4c5071b7d11dc..e4a65513a1bfd 100644 |
20273 |
+--- a/drivers/net/wireless/ath/ath11k/qmi.c |
20274 |
++++ b/drivers/net/wireless/ath/ath11k/qmi.c |
20275 |
+@@ -1770,7 +1770,7 @@ static int ath11k_qmi_alloc_target_mem_chunk(struct ath11k_base *ab) |
20276 |
+ chunk->vaddr = dma_alloc_coherent(ab->dev, |
20277 |
+ chunk->size, |
20278 |
+ &chunk->paddr, |
20279 |
+- GFP_KERNEL); |
20280 |
++ GFP_KERNEL | __GFP_NOWARN); |
20281 |
+ if (!chunk->vaddr) { |
20282 |
+ if (ab->qmi.mem_seg_count <= ATH11K_QMI_FW_MEM_REQ_SEGMENT_CNT) { |
20283 |
+ ath11k_dbg(ab, ATH11K_DBG_QMI, |
20284 |
+diff --git a/drivers/net/wireless/ath/ath11k/reg.c b/drivers/net/wireless/ath/ath11k/reg.c |
20285 |
+index 92c59009a8ac2..f793324ad0b73 100644 |
20286 |
+--- a/drivers/net/wireless/ath/ath11k/reg.c |
20287 |
++++ b/drivers/net/wireless/ath/ath11k/reg.c |
20288 |
+@@ -459,6 +459,9 @@ ath11k_reg_adjust_bw(u16 start_freq, u16 end_freq, u16 max_bw) |
20289 |
+ { |
20290 |
+ u16 bw; |
20291 |
+ |
20292 |
++ if (end_freq <= start_freq) |
20293 |
++ return 0; |
20294 |
++ |
20295 |
+ bw = end_freq - start_freq; |
20296 |
+ bw = min_t(u16, bw, max_bw); |
20297 |
+ |
20298 |
+@@ -466,8 +469,10 @@ ath11k_reg_adjust_bw(u16 start_freq, u16 end_freq, u16 max_bw) |
20299 |
+ bw = 80; |
20300 |
+ else if (bw >= 40 && bw < 80) |
20301 |
+ bw = 40; |
20302 |
+- else if (bw < 40) |
20303 |
++ else if (bw >= 20 && bw < 40) |
20304 |
+ bw = 20; |
20305 |
++ else |
20306 |
++ bw = 0; |
20307 |
+ |
20308 |
+ return bw; |
20309 |
+ } |
20310 |
+@@ -491,73 +496,77 @@ ath11k_reg_update_weather_radar_band(struct ath11k_base *ab, |
20311 |
+ struct cur_reg_rule *reg_rule, |
20312 |
+ u8 *rule_idx, u32 flags, u16 max_bw) |
20313 |
+ { |
20314 |
++ u32 start_freq; |
20315 |
+ u32 end_freq; |
20316 |
+ u16 bw; |
20317 |
+ u8 i; |
20318 |
+ |
20319 |
+ i = *rule_idx; |
20320 |
+ |
20321 |
++ /* there might be situations when even the input rule must be dropped */ |
20322 |
++ i--; |
20323 |
++ |
20324 |
++ /* frequencies below weather radar */ |
20325 |
+ bw = ath11k_reg_adjust_bw(reg_rule->start_freq, |
20326 |
+ ETSI_WEATHER_RADAR_BAND_LOW, max_bw); |
20327 |
++ if (bw > 0) { |
20328 |
++ i++; |
20329 |
+ |
20330 |
+- ath11k_reg_update_rule(regd->reg_rules + i, reg_rule->start_freq, |
20331 |
+- ETSI_WEATHER_RADAR_BAND_LOW, bw, |
20332 |
+- reg_rule->ant_gain, reg_rule->reg_power, |
20333 |
+- flags); |
20334 |
++ ath11k_reg_update_rule(regd->reg_rules + i, |
20335 |
++ reg_rule->start_freq, |
20336 |
++ ETSI_WEATHER_RADAR_BAND_LOW, bw, |
20337 |
++ reg_rule->ant_gain, reg_rule->reg_power, |
20338 |
++ flags); |
20339 |
+ |
20340 |
+- ath11k_dbg(ab, ATH11K_DBG_REG, |
20341 |
+- "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", |
20342 |
+- i + 1, reg_rule->start_freq, ETSI_WEATHER_RADAR_BAND_LOW, |
20343 |
+- bw, reg_rule->ant_gain, reg_rule->reg_power, |
20344 |
+- regd->reg_rules[i].dfs_cac_ms, |
20345 |
+- flags); |
20346 |
+- |
20347 |
+- if (reg_rule->end_freq > ETSI_WEATHER_RADAR_BAND_HIGH) |
20348 |
+- end_freq = ETSI_WEATHER_RADAR_BAND_HIGH; |
20349 |
+- else |
20350 |
+- end_freq = reg_rule->end_freq; |
20351 |
++ ath11k_dbg(ab, ATH11K_DBG_REG, |
20352 |
++ "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", |
20353 |
++ i + 1, reg_rule->start_freq, |
20354 |
++ ETSI_WEATHER_RADAR_BAND_LOW, bw, reg_rule->ant_gain, |
20355 |
++ reg_rule->reg_power, regd->reg_rules[i].dfs_cac_ms, |
20356 |
++ flags); |
20357 |
++ } |
20358 |
+ |
20359 |
+- bw = ath11k_reg_adjust_bw(ETSI_WEATHER_RADAR_BAND_LOW, end_freq, |
20360 |
+- max_bw); |
20361 |
++ /* weather radar frequencies */ |
20362 |
++ start_freq = max_t(u32, reg_rule->start_freq, |
20363 |
++ ETSI_WEATHER_RADAR_BAND_LOW); |
20364 |
++ end_freq = min_t(u32, reg_rule->end_freq, ETSI_WEATHER_RADAR_BAND_HIGH); |
20365 |
+ |
20366 |
+- i++; |
20367 |
++ bw = ath11k_reg_adjust_bw(start_freq, end_freq, max_bw); |
20368 |
++ if (bw > 0) { |
20369 |
++ i++; |
20370 |
+ |
20371 |
+- ath11k_reg_update_rule(regd->reg_rules + i, |
20372 |
+- ETSI_WEATHER_RADAR_BAND_LOW, end_freq, bw, |
20373 |
+- reg_rule->ant_gain, reg_rule->reg_power, |
20374 |
+- flags); |
20375 |
++ ath11k_reg_update_rule(regd->reg_rules + i, start_freq, |
20376 |
++ end_freq, bw, reg_rule->ant_gain, |
20377 |
++ reg_rule->reg_power, flags); |
20378 |
+ |
20379 |
+- regd->reg_rules[i].dfs_cac_ms = ETSI_WEATHER_RADAR_BAND_CAC_TIMEOUT; |
20380 |
++ regd->reg_rules[i].dfs_cac_ms = ETSI_WEATHER_RADAR_BAND_CAC_TIMEOUT; |
20381 |
+ |
20382 |
+- ath11k_dbg(ab, ATH11K_DBG_REG, |
20383 |
+- "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", |
20384 |
+- i + 1, ETSI_WEATHER_RADAR_BAND_LOW, end_freq, |
20385 |
+- bw, reg_rule->ant_gain, reg_rule->reg_power, |
20386 |
+- regd->reg_rules[i].dfs_cac_ms, |
20387 |
+- flags); |
20388 |
+- |
20389 |
+- if (end_freq == reg_rule->end_freq) { |
20390 |
+- regd->n_reg_rules--; |
20391 |
+- *rule_idx = i; |
20392 |
+- return; |
20393 |
++ ath11k_dbg(ab, ATH11K_DBG_REG, |
20394 |
++ "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", |
20395 |
++ i + 1, start_freq, end_freq, bw, |
20396 |
++ reg_rule->ant_gain, reg_rule->reg_power, |
20397 |
++ regd->reg_rules[i].dfs_cac_ms, flags); |
20398 |
+ } |
20399 |
+ |
20400 |
++ /* frequencies above weather radar */ |
20401 |
+ bw = ath11k_reg_adjust_bw(ETSI_WEATHER_RADAR_BAND_HIGH, |
20402 |
+ reg_rule->end_freq, max_bw); |
20403 |
++ if (bw > 0) { |
20404 |
++ i++; |
20405 |
+ |
20406 |
+- i++; |
20407 |
+- |
20408 |
+- ath11k_reg_update_rule(regd->reg_rules + i, ETSI_WEATHER_RADAR_BAND_HIGH, |
20409 |
+- reg_rule->end_freq, bw, |
20410 |
+- reg_rule->ant_gain, reg_rule->reg_power, |
20411 |
+- flags); |
20412 |
++ ath11k_reg_update_rule(regd->reg_rules + i, |
20413 |
++ ETSI_WEATHER_RADAR_BAND_HIGH, |
20414 |
++ reg_rule->end_freq, bw, |
20415 |
++ reg_rule->ant_gain, reg_rule->reg_power, |
20416 |
++ flags); |
20417 |
+ |
20418 |
+- ath11k_dbg(ab, ATH11K_DBG_REG, |
20419 |
+- "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", |
20420 |
+- i + 1, ETSI_WEATHER_RADAR_BAND_HIGH, reg_rule->end_freq, |
20421 |
+- bw, reg_rule->ant_gain, reg_rule->reg_power, |
20422 |
+- regd->reg_rules[i].dfs_cac_ms, |
20423 |
+- flags); |
20424 |
++ ath11k_dbg(ab, ATH11K_DBG_REG, |
20425 |
++ "\t%d. (%d - %d @ %d) (%d, %d) (%d ms) (FLAGS %d)\n", |
20426 |
++ i + 1, ETSI_WEATHER_RADAR_BAND_HIGH, |
20427 |
++ reg_rule->end_freq, bw, reg_rule->ant_gain, |
20428 |
++ reg_rule->reg_power, regd->reg_rules[i].dfs_cac_ms, |
20429 |
++ flags); |
20430 |
++ } |
20431 |
+ |
20432 |
+ *rule_idx = i; |
20433 |
+ } |
20434 |
+diff --git a/drivers/net/wireless/ath/ath11k/wmi.c b/drivers/net/wireless/ath/ath11k/wmi.c |
20435 |
+index c22ec921b2e97..b11070cf159cc 100644 |
20436 |
+--- a/drivers/net/wireless/ath/ath11k/wmi.c |
20437 |
++++ b/drivers/net/wireless/ath/ath11k/wmi.c |
20438 |
+@@ -1671,7 +1671,8 @@ int ath11k_wmi_vdev_install_key(struct ath11k *ar, |
20439 |
+ tlv = (struct wmi_tlv *)(skb->data + sizeof(*cmd)); |
20440 |
+ tlv->header = FIELD_PREP(WMI_TLV_TAG, WMI_TAG_ARRAY_BYTE) | |
20441 |
+ FIELD_PREP(WMI_TLV_LEN, key_len_aligned); |
20442 |
+- memcpy(tlv->value, (u8 *)arg->key_data, key_len_aligned); |
20443 |
++ if (arg->key_data) |
20444 |
++ memcpy(tlv->value, (u8 *)arg->key_data, key_len_aligned); |
20445 |
+ |
20446 |
+ ret = ath11k_wmi_cmd_send(wmi, skb, WMI_VDEV_INSTALL_KEY_CMDID); |
20447 |
+ if (ret) { |
20448 |
+@@ -5852,7 +5853,7 @@ static int ath11k_reg_chan_list_event(struct ath11k_base *ab, struct sk_buff *sk |
20449 |
+ ar = ab->pdevs[pdev_idx].ar; |
20450 |
+ kfree(ab->new_regd[pdev_idx]); |
20451 |
+ ab->new_regd[pdev_idx] = regd; |
20452 |
+- ieee80211_queue_work(ar->hw, &ar->regd_update_work); |
20453 |
++ queue_work(ab->workqueue, &ar->regd_update_work); |
20454 |
+ } else { |
20455 |
+ /* This regd would be applied during mac registration and is |
20456 |
+ * held constant throughout for regd intersection purpose |
20457 |
+diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c |
20458 |
+index 860da13bfb6ac..f06eec99de688 100644 |
20459 |
+--- a/drivers/net/wireless/ath/ath9k/hif_usb.c |
20460 |
++++ b/drivers/net/wireless/ath/ath9k/hif_usb.c |
20461 |
+@@ -590,6 +590,13 @@ static void ath9k_hif_usb_rx_stream(struct hif_device_usb *hif_dev, |
20462 |
+ return; |
20463 |
+ } |
20464 |
+ |
20465 |
++ if (pkt_len > 2 * MAX_RX_BUF_SIZE) { |
20466 |
++ dev_err(&hif_dev->udev->dev, |
20467 |
++ "ath9k_htc: invalid pkt_len (%x)\n", pkt_len); |
20468 |
++ RX_STAT_INC(skb_dropped); |
20469 |
++ return; |
20470 |
++ } |
20471 |
++ |
20472 |
+ pad_len = 4 - (pkt_len & 0x3); |
20473 |
+ if (pad_len == 4) |
20474 |
+ pad_len = 0; |
20475 |
+diff --git a/drivers/net/wireless/ath/ath9k/htc.h b/drivers/net/wireless/ath/ath9k/htc.h |
20476 |
+index 0a1634238e673..6b45e63fae4ba 100644 |
20477 |
+--- a/drivers/net/wireless/ath/ath9k/htc.h |
20478 |
++++ b/drivers/net/wireless/ath/ath9k/htc.h |
20479 |
+@@ -281,6 +281,7 @@ struct ath9k_htc_rxbuf { |
20480 |
+ struct ath9k_htc_rx { |
20481 |
+ struct list_head rxbuf; |
20482 |
+ spinlock_t rxbuflock; |
20483 |
++ bool initialized; |
20484 |
+ }; |
20485 |
+ |
20486 |
+ #define ATH9K_HTC_TX_CLEANUP_INTERVAL 50 /* ms */ |
20487 |
+@@ -305,6 +306,7 @@ struct ath9k_htc_tx { |
20488 |
+ DECLARE_BITMAP(tx_slot, MAX_TX_BUF_NUM); |
20489 |
+ struct timer_list cleanup_timer; |
20490 |
+ spinlock_t tx_lock; |
20491 |
++ bool initialized; |
20492 |
+ }; |
20493 |
+ |
20494 |
+ struct ath9k_htc_tx_ctl { |
20495 |
+diff --git a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c |
20496 |
+index 8e69e8989f6d3..6a850a0bfa8ad 100644 |
20497 |
+--- a/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c |
20498 |
++++ b/drivers/net/wireless/ath/ath9k/htc_drv_txrx.c |
20499 |
+@@ -813,6 +813,11 @@ int ath9k_tx_init(struct ath9k_htc_priv *priv) |
20500 |
+ skb_queue_head_init(&priv->tx.data_vi_queue); |
20501 |
+ skb_queue_head_init(&priv->tx.data_vo_queue); |
20502 |
+ skb_queue_head_init(&priv->tx.tx_failed); |
20503 |
++ |
20504 |
++ /* Allow ath9k_wmi_event_tasklet(WMI_TXSTATUS_EVENTID) to operate. */ |
20505 |
++ smp_wmb(); |
20506 |
++ priv->tx.initialized = true; |
20507 |
++ |
20508 |
+ return 0; |
20509 |
+ } |
20510 |
+ |
20511 |
+@@ -1130,6 +1135,10 @@ void ath9k_htc_rxep(void *drv_priv, struct sk_buff *skb, |
20512 |
+ struct ath9k_htc_rxbuf *rxbuf = NULL, *tmp_buf = NULL; |
20513 |
+ unsigned long flags; |
20514 |
+ |
20515 |
++ /* Check if ath9k_rx_init() completed. */ |
20516 |
++ if (!data_race(priv->rx.initialized)) |
20517 |
++ goto err; |
20518 |
++ |
20519 |
+ spin_lock_irqsave(&priv->rx.rxbuflock, flags); |
20520 |
+ list_for_each_entry(tmp_buf, &priv->rx.rxbuf, list) { |
20521 |
+ if (!tmp_buf->in_process) { |
20522 |
+@@ -1185,6 +1194,10 @@ int ath9k_rx_init(struct ath9k_htc_priv *priv) |
20523 |
+ list_add_tail(&rxbuf->list, &priv->rx.rxbuf); |
20524 |
+ } |
20525 |
+ |
20526 |
++ /* Allow ath9k_htc_rxep() to operate. */ |
20527 |
++ smp_wmb(); |
20528 |
++ priv->rx.initialized = true; |
20529 |
++ |
20530 |
+ return 0; |
20531 |
+ |
20532 |
+ err: |
20533 |
+diff --git a/drivers/net/wireless/ath/ath9k/wmi.c b/drivers/net/wireless/ath/ath9k/wmi.c |
20534 |
+index fe29ad4b9023c..f315c54bd3ac0 100644 |
20535 |
+--- a/drivers/net/wireless/ath/ath9k/wmi.c |
20536 |
++++ b/drivers/net/wireless/ath/ath9k/wmi.c |
20537 |
+@@ -169,6 +169,10 @@ void ath9k_wmi_event_tasklet(struct tasklet_struct *t) |
20538 |
+ &wmi->drv_priv->fatal_work); |
20539 |
+ break; |
20540 |
+ case WMI_TXSTATUS_EVENTID: |
20541 |
++ /* Check if ath9k_tx_init() completed. */ |
20542 |
++ if (!data_race(priv->tx.initialized)) |
20543 |
++ break; |
20544 |
++ |
20545 |
+ spin_lock_bh(&priv->tx.tx_lock); |
20546 |
+ if (priv->tx.flags & ATH9K_HTC_OP_TX_DRAIN) { |
20547 |
+ spin_unlock_bh(&priv->tx.tx_lock); |
20548 |
+diff --git a/drivers/net/wireless/ath/wcn36xx/dxe.c b/drivers/net/wireless/ath/wcn36xx/dxe.c |
20549 |
+index aff04ef662663..e1a35c2eadb6c 100644 |
20550 |
+--- a/drivers/net/wireless/ath/wcn36xx/dxe.c |
20551 |
++++ b/drivers/net/wireless/ath/wcn36xx/dxe.c |
20552 |
+@@ -272,6 +272,21 @@ static int wcn36xx_dxe_enable_ch_int(struct wcn36xx *wcn, u16 wcn_ch) |
20553 |
+ return 0; |
20554 |
+ } |
20555 |
+ |
20556 |
++static void wcn36xx_dxe_disable_ch_int(struct wcn36xx *wcn, u16 wcn_ch) |
20557 |
++{ |
20558 |
++ int reg_data = 0; |
20559 |
++ |
20560 |
++ wcn36xx_dxe_read_register(wcn, |
20561 |
++ WCN36XX_DXE_INT_MASK_REG, |
20562 |
++ ®_data); |
20563 |
++ |
20564 |
++ reg_data &= ~wcn_ch; |
20565 |
++ |
20566 |
++ wcn36xx_dxe_write_register(wcn, |
20567 |
++ WCN36XX_DXE_INT_MASK_REG, |
20568 |
++ (int)reg_data); |
20569 |
++} |
20570 |
++ |
20571 |
+ static int wcn36xx_dxe_fill_skb(struct device *dev, |
20572 |
+ struct wcn36xx_dxe_ctl *ctl, |
20573 |
+ gfp_t gfp) |
20574 |
+@@ -869,7 +884,6 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn) |
20575 |
+ WCN36XX_DXE_WQ_TX_L); |
20576 |
+ |
20577 |
+ wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_REG_CH_EN, ®_data); |
20578 |
+- wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_TX_L); |
20579 |
+ |
20580 |
+ /***************************************/ |
20581 |
+ /* Init descriptors for TX HIGH channel */ |
20582 |
+@@ -893,9 +907,6 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn) |
20583 |
+ |
20584 |
+ wcn36xx_dxe_read_register(wcn, WCN36XX_DXE_REG_CH_EN, ®_data); |
20585 |
+ |
20586 |
+- /* Enable channel interrupts */ |
20587 |
+- wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_TX_H); |
20588 |
+- |
20589 |
+ /***************************************/ |
20590 |
+ /* Init descriptors for RX LOW channel */ |
20591 |
+ /***************************************/ |
20592 |
+@@ -905,7 +916,6 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn) |
20593 |
+ goto out_err_rxl_ch; |
20594 |
+ } |
20595 |
+ |
20596 |
+- |
20597 |
+ /* For RX we need to preallocated buffers */ |
20598 |
+ wcn36xx_dxe_ch_alloc_skb(wcn, &wcn->dxe_rx_l_ch); |
20599 |
+ |
20600 |
+@@ -928,9 +938,6 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn) |
20601 |
+ WCN36XX_DXE_REG_CTL_RX_L, |
20602 |
+ WCN36XX_DXE_CH_DEFAULT_CTL_RX_L); |
20603 |
+ |
20604 |
+- /* Enable channel interrupts */ |
20605 |
+- wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_RX_L); |
20606 |
+- |
20607 |
+ /***************************************/ |
20608 |
+ /* Init descriptors for RX HIGH channel */ |
20609 |
+ /***************************************/ |
20610 |
+@@ -962,15 +969,18 @@ int wcn36xx_dxe_init(struct wcn36xx *wcn) |
20611 |
+ WCN36XX_DXE_REG_CTL_RX_H, |
20612 |
+ WCN36XX_DXE_CH_DEFAULT_CTL_RX_H); |
20613 |
+ |
20614 |
+- /* Enable channel interrupts */ |
20615 |
+- wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_RX_H); |
20616 |
+- |
20617 |
+ ret = wcn36xx_dxe_request_irqs(wcn); |
20618 |
+ if (ret < 0) |
20619 |
+ goto out_err_irq; |
20620 |
+ |
20621 |
+ timer_setup(&wcn->tx_ack_timer, wcn36xx_dxe_tx_timer, 0); |
20622 |
+ |
20623 |
++ /* Enable channel interrupts */ |
20624 |
++ wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_TX_L); |
20625 |
++ wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_TX_H); |
20626 |
++ wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_RX_L); |
20627 |
++ wcn36xx_dxe_enable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_RX_H); |
20628 |
++ |
20629 |
+ return 0; |
20630 |
+ |
20631 |
+ out_err_irq: |
20632 |
+@@ -987,6 +997,14 @@ out_err_txh_ch: |
20633 |
+ |
20634 |
+ void wcn36xx_dxe_deinit(struct wcn36xx *wcn) |
20635 |
+ { |
20636 |
++ int reg_data = 0; |
20637 |
++ |
20638 |
++ /* Disable channel interrupts */ |
20639 |
++ wcn36xx_dxe_disable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_RX_H); |
20640 |
++ wcn36xx_dxe_disable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_RX_L); |
20641 |
++ wcn36xx_dxe_disable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_TX_H); |
20642 |
++ wcn36xx_dxe_disable_ch_int(wcn, WCN36XX_INT_MASK_CHAN_TX_L); |
20643 |
++ |
20644 |
+ free_irq(wcn->tx_irq, wcn); |
20645 |
+ free_irq(wcn->rx_irq, wcn); |
20646 |
+ del_timer(&wcn->tx_ack_timer); |
20647 |
+@@ -996,6 +1014,15 @@ void wcn36xx_dxe_deinit(struct wcn36xx *wcn) |
20648 |
+ wcn->tx_ack_skb = NULL; |
20649 |
+ } |
20650 |
+ |
20651 |
++ /* Put the DXE block into reset before freeing memory */ |
20652 |
++ reg_data = WCN36XX_DXE_REG_RESET; |
20653 |
++ wcn36xx_dxe_write_register(wcn, WCN36XX_DXE_REG_CSR_RESET, reg_data); |
20654 |
++ |
20655 |
+ wcn36xx_dxe_ch_free_skbs(wcn, &wcn->dxe_rx_l_ch); |
20656 |
+ wcn36xx_dxe_ch_free_skbs(wcn, &wcn->dxe_rx_h_ch); |
20657 |
++ |
20658 |
++ wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_tx_l_ch); |
20659 |
++ wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_tx_h_ch); |
20660 |
++ wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_rx_l_ch); |
20661 |
++ wcn36xx_dxe_deinit_descs(wcn->dev, &wcn->dxe_rx_h_ch); |
20662 |
+ } |
20663 |
+diff --git a/drivers/net/wireless/ath/wcn36xx/main.c b/drivers/net/wireless/ath/wcn36xx/main.c |
20664 |
+index 5d82aca370a72..cf9e1396bd046 100644 |
20665 |
+--- a/drivers/net/wireless/ath/wcn36xx/main.c |
20666 |
++++ b/drivers/net/wireless/ath/wcn36xx/main.c |
20667 |
+@@ -400,6 +400,7 @@ static void wcn36xx_change_opchannel(struct wcn36xx *wcn, int ch) |
20668 |
+ static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed) |
20669 |
+ { |
20670 |
+ struct wcn36xx *wcn = hw->priv; |
20671 |
++ int ret; |
20672 |
+ |
20673 |
+ wcn36xx_dbg(WCN36XX_DBG_MAC, "mac config changed 0x%08x\n", changed); |
20674 |
+ |
20675 |
+@@ -415,17 +416,31 @@ static int wcn36xx_config(struct ieee80211_hw *hw, u32 changed) |
20676 |
+ * want to receive/transmit regular data packets, then |
20677 |
+ * simply stop the scan session and exit PS mode. |
20678 |
+ */ |
20679 |
+- wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN, |
20680 |
+- wcn->sw_scan_vif); |
20681 |
+- wcn->sw_scan_channel = 0; |
20682 |
++ if (wcn->sw_scan_channel) |
20683 |
++ wcn36xx_smd_end_scan(wcn, wcn->sw_scan_channel); |
20684 |
++ if (wcn->sw_scan_init) { |
20685 |
++ wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN, |
20686 |
++ wcn->sw_scan_vif); |
20687 |
++ } |
20688 |
+ } else if (wcn->sw_scan) { |
20689 |
+ /* A scan is ongoing, do not change the operating |
20690 |
+ * channel, but start a scan session on the channel. |
20691 |
+ */ |
20692 |
+- wcn36xx_smd_init_scan(wcn, HAL_SYS_MODE_SCAN, |
20693 |
+- wcn->sw_scan_vif); |
20694 |
++ if (wcn->sw_scan_channel) |
20695 |
++ wcn36xx_smd_end_scan(wcn, wcn->sw_scan_channel); |
20696 |
++ if (!wcn->sw_scan_init) { |
20697 |
++ /* This can fail if we are unable to notify the |
20698 |
++ * operating channel. |
20699 |
++ */ |
20700 |
++ ret = wcn36xx_smd_init_scan(wcn, |
20701 |
++ HAL_SYS_MODE_SCAN, |
20702 |
++ wcn->sw_scan_vif); |
20703 |
++ if (ret) { |
20704 |
++ mutex_unlock(&wcn->conf_mutex); |
20705 |
++ return -EIO; |
20706 |
++ } |
20707 |
++ } |
20708 |
+ wcn36xx_smd_start_scan(wcn, ch); |
20709 |
+- wcn->sw_scan_channel = ch; |
20710 |
+ } else { |
20711 |
+ wcn36xx_change_opchannel(wcn, ch); |
20712 |
+ } |
20713 |
+@@ -713,7 +728,12 @@ static void wcn36xx_sw_scan_complete(struct ieee80211_hw *hw, |
20714 |
+ struct wcn36xx *wcn = hw->priv; |
20715 |
+ |
20716 |
+ /* ensure that any scan session is finished */ |
20717 |
+- wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN, wcn->sw_scan_vif); |
20718 |
++ if (wcn->sw_scan_channel) |
20719 |
++ wcn36xx_smd_end_scan(wcn, wcn->sw_scan_channel); |
20720 |
++ if (wcn->sw_scan_init) { |
20721 |
++ wcn36xx_smd_finish_scan(wcn, HAL_SYS_MODE_SCAN, |
20722 |
++ wcn->sw_scan_vif); |
20723 |
++ } |
20724 |
+ wcn->sw_scan = false; |
20725 |
+ wcn->sw_scan_opchannel = 0; |
20726 |
+ } |
20727 |
+diff --git a/drivers/net/wireless/ath/wcn36xx/smd.c b/drivers/net/wireless/ath/wcn36xx/smd.c |
20728 |
+index 70bffe3d87a12..c056fae1d6418 100644 |
20729 |
+--- a/drivers/net/wireless/ath/wcn36xx/smd.c |
20730 |
++++ b/drivers/net/wireless/ath/wcn36xx/smd.c |
20731 |
+@@ -721,6 +721,7 @@ int wcn36xx_smd_init_scan(struct wcn36xx *wcn, enum wcn36xx_hal_sys_mode mode, |
20732 |
+ wcn36xx_err("hal_init_scan response failed err=%d\n", ret); |
20733 |
+ goto out; |
20734 |
+ } |
20735 |
++ wcn->sw_scan_init = true; |
20736 |
+ out: |
20737 |
+ mutex_unlock(&wcn->hal_mutex); |
20738 |
+ return ret; |
20739 |
+@@ -751,6 +752,7 @@ int wcn36xx_smd_start_scan(struct wcn36xx *wcn, u8 scan_channel) |
20740 |
+ wcn36xx_err("hal_start_scan response failed err=%d\n", ret); |
20741 |
+ goto out; |
20742 |
+ } |
20743 |
++ wcn->sw_scan_channel = scan_channel; |
20744 |
+ out: |
20745 |
+ mutex_unlock(&wcn->hal_mutex); |
20746 |
+ return ret; |
20747 |
+@@ -781,6 +783,7 @@ int wcn36xx_smd_end_scan(struct wcn36xx *wcn, u8 scan_channel) |
20748 |
+ wcn36xx_err("hal_end_scan response failed err=%d\n", ret); |
20749 |
+ goto out; |
20750 |
+ } |
20751 |
++ wcn->sw_scan_channel = 0; |
20752 |
+ out: |
20753 |
+ mutex_unlock(&wcn->hal_mutex); |
20754 |
+ return ret; |
20755 |
+@@ -822,6 +825,7 @@ int wcn36xx_smd_finish_scan(struct wcn36xx *wcn, |
20756 |
+ wcn36xx_err("hal_finish_scan response failed err=%d\n", ret); |
20757 |
+ goto out; |
20758 |
+ } |
20759 |
++ wcn->sw_scan_init = false; |
20760 |
+ out: |
20761 |
+ mutex_unlock(&wcn->hal_mutex); |
20762 |
+ return ret; |
20763 |
+@@ -939,7 +943,7 @@ int wcn36xx_smd_update_channel_list(struct wcn36xx *wcn, struct cfg80211_scan_re |
20764 |
+ |
20765 |
+ INIT_HAL_MSG((*msg_body), WCN36XX_HAL_UPDATE_CHANNEL_LIST_REQ); |
20766 |
+ |
20767 |
+- msg_body->num_channel = min_t(u8, req->n_channels, sizeof(msg_body->channels)); |
20768 |
++ msg_body->num_channel = min_t(u8, req->n_channels, ARRAY_SIZE(msg_body->channels)); |
20769 |
+ for (i = 0; i < msg_body->num_channel; i++) { |
20770 |
+ struct wcn36xx_hal_channel_param *param = &msg_body->channels[i]; |
20771 |
+ u32 min_power = WCN36XX_HAL_DEFAULT_MIN_POWER; |
20772 |
+@@ -2675,7 +2679,7 @@ static int wcn36xx_smd_missed_beacon_ind(struct wcn36xx *wcn, |
20773 |
+ wcn36xx_dbg(WCN36XX_DBG_HAL, "beacon missed bss_index %d\n", |
20774 |
+ tmp->bss_index); |
20775 |
+ vif = wcn36xx_priv_to_vif(tmp); |
20776 |
+- ieee80211_connection_loss(vif); |
20777 |
++ ieee80211_beacon_loss(vif); |
20778 |
+ } |
20779 |
+ return 0; |
20780 |
+ } |
20781 |
+@@ -2690,7 +2694,7 @@ static int wcn36xx_smd_missed_beacon_ind(struct wcn36xx *wcn, |
20782 |
+ wcn36xx_dbg(WCN36XX_DBG_HAL, "beacon missed bss_index %d\n", |
20783 |
+ rsp->bss_index); |
20784 |
+ vif = wcn36xx_priv_to_vif(tmp); |
20785 |
+- ieee80211_connection_loss(vif); |
20786 |
++ ieee80211_beacon_loss(vif); |
20787 |
+ return 0; |
20788 |
+ } |
20789 |
+ } |
20790 |
+diff --git a/drivers/net/wireless/ath/wcn36xx/txrx.c b/drivers/net/wireless/ath/wcn36xx/txrx.c |
20791 |
+index bbd7194c82e27..f33e7228a1010 100644 |
20792 |
+--- a/drivers/net/wireless/ath/wcn36xx/txrx.c |
20793 |
++++ b/drivers/net/wireless/ath/wcn36xx/txrx.c |
20794 |
+@@ -237,7 +237,6 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) |
20795 |
+ const struct wcn36xx_rate *rate; |
20796 |
+ struct ieee80211_hdr *hdr; |
20797 |
+ struct wcn36xx_rx_bd *bd; |
20798 |
+- struct ieee80211_supported_band *sband; |
20799 |
+ u16 fc, sn; |
20800 |
+ |
20801 |
+ /* |
20802 |
+@@ -259,8 +258,6 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) |
20803 |
+ fc = __le16_to_cpu(hdr->frame_control); |
20804 |
+ sn = IEEE80211_SEQ_TO_SN(__le16_to_cpu(hdr->seq_ctrl)); |
20805 |
+ |
20806 |
+- status.freq = WCN36XX_CENTER_FREQ(wcn); |
20807 |
+- status.band = WCN36XX_BAND(wcn); |
20808 |
+ status.mactime = 10; |
20809 |
+ status.signal = -get_rssi0(bd); |
20810 |
+ status.antenna = 1; |
20811 |
+@@ -272,18 +269,36 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) |
20812 |
+ |
20813 |
+ wcn36xx_dbg(WCN36XX_DBG_RX, "status.flags=%x\n", status.flag); |
20814 |
+ |
20815 |
++ if (bd->scan_learn) { |
20816 |
++ /* If packet originate from hardware scanning, extract the |
20817 |
++ * band/channel from bd descriptor. |
20818 |
++ */ |
20819 |
++ u8 hwch = (bd->reserved0 << 4) + bd->rx_ch; |
20820 |
++ |
20821 |
++ if (bd->rf_band != 1 && hwch <= sizeof(ab_rx_ch_map) && hwch >= 1) { |
20822 |
++ status.band = NL80211_BAND_5GHZ; |
20823 |
++ status.freq = ieee80211_channel_to_frequency(ab_rx_ch_map[hwch - 1], |
20824 |
++ status.band); |
20825 |
++ } else { |
20826 |
++ status.band = NL80211_BAND_2GHZ; |
20827 |
++ status.freq = ieee80211_channel_to_frequency(hwch, status.band); |
20828 |
++ } |
20829 |
++ } else { |
20830 |
++ status.band = WCN36XX_BAND(wcn); |
20831 |
++ status.freq = WCN36XX_CENTER_FREQ(wcn); |
20832 |
++ } |
20833 |
++ |
20834 |
+ if (bd->rate_id < ARRAY_SIZE(wcn36xx_rate_table)) { |
20835 |
+ rate = &wcn36xx_rate_table[bd->rate_id]; |
20836 |
+ status.encoding = rate->encoding; |
20837 |
+ status.enc_flags = rate->encoding_flags; |
20838 |
+ status.bw = rate->bw; |
20839 |
+ status.rate_idx = rate->mcs_or_legacy_index; |
20840 |
+- sband = wcn->hw->wiphy->bands[status.band]; |
20841 |
+ status.nss = 1; |
20842 |
+ |
20843 |
+ if (status.band == NL80211_BAND_5GHZ && |
20844 |
+ status.encoding == RX_ENC_LEGACY && |
20845 |
+- status.rate_idx >= sband->n_bitrates) { |
20846 |
++ status.rate_idx >= 4) { |
20847 |
+ /* no dsss rates in 5Ghz rates table */ |
20848 |
+ status.rate_idx -= 4; |
20849 |
+ } |
20850 |
+@@ -298,22 +313,6 @@ int wcn36xx_rx_skb(struct wcn36xx *wcn, struct sk_buff *skb) |
20851 |
+ ieee80211_is_probe_resp(hdr->frame_control)) |
20852 |
+ status.boottime_ns = ktime_get_boottime_ns(); |
20853 |
+ |
20854 |
+- if (bd->scan_learn) { |
20855 |
+- /* If packet originates from hardware scanning, extract the |
20856 |
+- * band/channel from bd descriptor. |
20857 |
+- */ |
20858 |
+- u8 hwch = (bd->reserved0 << 4) + bd->rx_ch; |
20859 |
+- |
20860 |
+- if (bd->rf_band != 1 && hwch <= sizeof(ab_rx_ch_map) && hwch >= 1) { |
20861 |
+- status.band = NL80211_BAND_5GHZ; |
20862 |
+- status.freq = ieee80211_channel_to_frequency(ab_rx_ch_map[hwch - 1], |
20863 |
+- status.band); |
20864 |
+- } else { |
20865 |
+- status.band = NL80211_BAND_2GHZ; |
20866 |
+- status.freq = ieee80211_channel_to_frequency(hwch, status.band); |
20867 |
+- } |
20868 |
+- } |
20869 |
+- |
20870 |
+ memcpy(IEEE80211_SKB_RXCB(skb), &status, sizeof(status)); |
20871 |
+ |
20872 |
+ if (ieee80211_is_beacon(hdr->frame_control)) { |
20873 |
+diff --git a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h |
20874 |
+index e9560f35e9bcf..428546a6047f0 100644 |
20875 |
+--- a/drivers/net/wireless/ath/wcn36xx/wcn36xx.h |
20876 |
++++ b/drivers/net/wireless/ath/wcn36xx/wcn36xx.h |
20877 |
+@@ -246,6 +246,7 @@ struct wcn36xx { |
20878 |
+ struct cfg80211_scan_request *scan_req; |
20879 |
+ bool sw_scan; |
20880 |
+ u8 sw_scan_opchannel; |
20881 |
++ bool sw_scan_init; |
20882 |
+ u8 sw_scan_channel; |
20883 |
+ struct ieee80211_vif *sw_scan_vif; |
20884 |
+ struct mutex scan_lock; |
20885 |
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h |
20886 |
+index cf796403c45c0..845a09d0dabaf 100644 |
20887 |
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-csr.h |
20888 |
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-csr.h |
20889 |
+@@ -104,9 +104,10 @@ |
20890 |
+ /* GIO Chicken Bits (PCI Express bus link power management) */ |
20891 |
+ #define CSR_GIO_CHICKEN_BITS (CSR_BASE+0x100) |
20892 |
+ |
20893 |
+-/* Doorbell NMI (since Bz) */ |
20894 |
++/* Doorbell - since Bz |
20895 |
++ * connected to UREG_DOORBELL_TO_ISR6 (lower 16 bits only) |
20896 |
++ */ |
20897 |
+ #define CSR_DOORBELL_VECTOR (CSR_BASE + 0x130) |
20898 |
+-#define CSR_DOORBELL_VECTOR_NMI BIT(1) |
20899 |
+ |
20900 |
+ /* host chicken bits */ |
20901 |
+ #define CSR_HOST_CHICKEN (CSR_BASE + 0x204) |
20902 |
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c |
20903 |
+index 94553f272d377..b7f7b9c5b670c 100644 |
20904 |
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c |
20905 |
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c |
20906 |
+@@ -131,6 +131,9 @@ static void iwl_dealloc_ucode(struct iwl_drv *drv) |
20907 |
+ |
20908 |
+ for (i = 0; i < IWL_UCODE_TYPE_MAX; i++) |
20909 |
+ iwl_free_fw_img(drv, drv->fw.img + i); |
20910 |
++ |
20911 |
++ /* clear the data for the aborted load case */ |
20912 |
++ memset(&drv->fw, 0, sizeof(drv->fw)); |
20913 |
+ } |
20914 |
+ |
20915 |
+ static int iwl_alloc_fw_desc(struct iwl_drv *drv, struct fw_desc *desc, |
20916 |
+@@ -1333,6 +1336,7 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) |
20917 |
+ int i; |
20918 |
+ bool load_module = false; |
20919 |
+ bool usniffer_images = false; |
20920 |
++ bool failure = true; |
20921 |
+ |
20922 |
+ fw->ucode_capa.max_probe_length = IWL_DEFAULT_MAX_PROBE_LENGTH; |
20923 |
+ fw->ucode_capa.standard_phy_calibration_size = |
20924 |
+@@ -1593,15 +1597,9 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) |
20925 |
+ * else from proceeding if the module fails to load |
20926 |
+ * or hangs loading. |
20927 |
+ */ |
20928 |
+- if (load_module) { |
20929 |
++ if (load_module) |
20930 |
+ request_module("%s", op->name); |
20931 |
+-#ifdef CONFIG_IWLWIFI_OPMODE_MODULAR |
20932 |
+- if (err) |
20933 |
+- IWL_ERR(drv, |
20934 |
+- "failed to load module %s (error %d), is dynamic loading enabled?\n", |
20935 |
+- op->name, err); |
20936 |
+-#endif |
20937 |
+- } |
20938 |
++ failure = false; |
20939 |
+ goto free; |
20940 |
+ |
20941 |
+ try_again: |
20942 |
+@@ -1617,6 +1615,9 @@ static void iwl_req_fw_callback(const struct firmware *ucode_raw, void *context) |
20943 |
+ complete(&drv->request_firmware_complete); |
20944 |
+ device_release_driver(drv->trans->dev); |
20945 |
+ free: |
20946 |
++ if (failure) |
20947 |
++ iwl_dealloc_ucode(drv); |
20948 |
++ |
20949 |
+ if (pieces) { |
20950 |
+ for (i = 0; i < ARRAY_SIZE(pieces->img); i++) |
20951 |
+ kfree(pieces->img[i].sec); |
20952 |
+diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-io.c b/drivers/net/wireless/intel/iwlwifi/iwl-io.c |
20953 |
+index 2517c4ae07ab3..5e76ab6c8ad0a 100644 |
20954 |
+--- a/drivers/net/wireless/intel/iwlwifi/iwl-io.c |
20955 |
++++ b/drivers/net/wireless/intel/iwlwifi/iwl-io.c |
20956 |
+@@ -218,7 +218,7 @@ void iwl_force_nmi(struct iwl_trans *trans) |
20957 |
+ UREG_DOORBELL_TO_ISR6_NMI_BIT); |
20958 |
+ else |
20959 |
+ iwl_write32(trans, CSR_DOORBELL_VECTOR, |
20960 |
+- CSR_DOORBELL_VECTOR_NMI); |
20961 |
++ UREG_DOORBELL_TO_ISR6_NMI_BIT); |
20962 |
+ } |
20963 |
+ IWL_EXPORT_SYMBOL(iwl_force_nmi); |
20964 |
+ |
20965 |
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c |
20966 |
+index 03e5bf5cb9094..bb5fff8174435 100644 |
20967 |
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c |
20968 |
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/ftm-initiator.c |
20969 |
+@@ -499,7 +499,7 @@ iwl_mvm_ftm_put_target(struct iwl_mvm *mvm, struct ieee80211_vif *vif, |
20970 |
+ rcu_read_lock(); |
20971 |
+ |
20972 |
+ sta = rcu_dereference(mvm->fw_id_to_mac_id[mvmvif->ap_sta_id]); |
20973 |
+- if (sta->mfp) |
20974 |
++ if (sta->mfp && (peer->ftm.trigger_based || peer->ftm.non_trigger_based)) |
20975 |
+ FTM_PUT_FLAG(PMF); |
20976 |
+ |
20977 |
+ rcu_read_unlock(); |
20978 |
+@@ -1054,7 +1054,7 @@ static void iwl_mvm_ftm_rtt_smoothing(struct iwl_mvm *mvm, |
20979 |
+ overshoot = IWL_MVM_FTM_INITIATOR_SMOOTH_OVERSHOOT; |
20980 |
+ alpha = IWL_MVM_FTM_INITIATOR_SMOOTH_ALPHA; |
20981 |
+ |
20982 |
+- rtt_avg = (alpha * rtt + (100 - alpha) * resp->rtt_avg) / 100; |
20983 |
++ rtt_avg = div_s64(alpha * rtt + (100 - alpha) * resp->rtt_avg, 100); |
20984 |
+ |
20985 |
+ IWL_DEBUG_INFO(mvm, |
20986 |
+ "%pM: prev rtt_avg=%lld, new rtt_avg=%lld, rtt=%lld\n", |
20987 |
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c |
20988 |
+index 7e5ad943b20cb..750217393f480 100644 |
20989 |
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c |
20990 |
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c |
20991 |
+@@ -1687,6 +1687,7 @@ static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm) |
20992 |
+ struct iwl_mvm_mc_iter_data iter_data = { |
20993 |
+ .mvm = mvm, |
20994 |
+ }; |
20995 |
++ int ret; |
20996 |
+ |
20997 |
+ lockdep_assert_held(&mvm->mutex); |
20998 |
+ |
20999 |
+@@ -1696,6 +1697,22 @@ static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm) |
21000 |
+ ieee80211_iterate_active_interfaces_atomic( |
21001 |
+ mvm->hw, IEEE80211_IFACE_ITER_NORMAL, |
21002 |
+ iwl_mvm_mc_iface_iterator, &iter_data); |
21003 |
++ |
21004 |
++ /* |
21005 |
++ * Send a (synchronous) ech command so that we wait for the |
21006 |
++ * multiple asynchronous MCAST_FILTER_CMD commands sent by |
21007 |
++ * the interface iterator. Otherwise, we might get here over |
21008 |
++ * and over again (by userspace just sending a lot of these) |
21009 |
++ * and the CPU can send them faster than the firmware can |
21010 |
++ * process them. |
21011 |
++ * Note that the CPU is still faster - but with this we'll |
21012 |
++ * actually send fewer commands overall because the CPU will |
21013 |
++ * not schedule the work in mac80211 as frequently if it's |
21014 |
++ * still running when rescheduled (possibly multiple times). |
21015 |
++ */ |
21016 |
++ ret = iwl_mvm_send_cmd_pdu(mvm, ECHO_CMD, 0, 0, NULL); |
21017 |
++ if (ret) |
21018 |
++ IWL_ERR(mvm, "Failed to synchronize multicast groups update\n"); |
21019 |
+ } |
21020 |
+ |
21021 |
+ static u64 iwl_mvm_prepare_multicast(struct ieee80211_hw *hw, |
21022 |
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c |
21023 |
+index c12f303cf652c..efccdd3f33773 100644 |
21024 |
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c |
21025 |
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c |
21026 |
+@@ -121,12 +121,39 @@ static int iwl_mvm_create_skb(struct iwl_mvm *mvm, struct sk_buff *skb, |
21027 |
+ struct iwl_rx_mpdu_desc *desc = (void *)pkt->data; |
21028 |
+ unsigned int headlen, fraglen, pad_len = 0; |
21029 |
+ unsigned int hdrlen = ieee80211_hdrlen(hdr->frame_control); |
21030 |
++ u8 mic_crc_len = u8_get_bits(desc->mac_flags1, |
21031 |
++ IWL_RX_MPDU_MFLG1_MIC_CRC_LEN_MASK) << 1; |
21032 |
+ |
21033 |
+ if (desc->mac_flags2 & IWL_RX_MPDU_MFLG2_PAD) { |
21034 |
+ len -= 2; |
21035 |
+ pad_len = 2; |
21036 |
+ } |
21037 |
+ |
21038 |
++ /* |
21039 |
++ * For non monitor interface strip the bytes the RADA might not have |
21040 |
++ * removed. As monitor interface cannot exist with other interfaces |
21041 |
++ * this removal is safe. |
21042 |
++ */ |
21043 |
++ if (mic_crc_len && !ieee80211_hw_check(mvm->hw, RX_INCLUDES_FCS)) { |
21044 |
++ u32 pkt_flags = le32_to_cpu(pkt->len_n_flags); |
21045 |
++ |
21046 |
++ /* |
21047 |
++ * If RADA was not enabled then decryption was not performed so |
21048 |
++ * the MIC cannot be removed. |
21049 |
++ */ |
21050 |
++ if (!(pkt_flags & FH_RSCSR_RADA_EN)) { |
21051 |
++ if (WARN_ON(crypt_len > mic_crc_len)) |
21052 |
++ return -EINVAL; |
21053 |
++ |
21054 |
++ mic_crc_len -= crypt_len; |
21055 |
++ } |
21056 |
++ |
21057 |
++ if (WARN_ON(mic_crc_len > len)) |
21058 |
++ return -EINVAL; |
21059 |
++ |
21060 |
++ len -= mic_crc_len; |
21061 |
++ } |
21062 |
++ |
21063 |
+ /* If frame is small enough to fit in skb->head, pull it completely. |
21064 |
+ * If not, only pull ieee80211_hdr (including crypto if present, and |
21065 |
+ * an additional 8 bytes for SNAP/ethertype, see below) so that |
21066 |
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c |
21067 |
+index d78e436fa8b53..5461bf3999593 100644 |
21068 |
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/scan.c |
21069 |
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/scan.c |
21070 |
+@@ -1924,22 +1924,19 @@ static void iwl_mvm_scan_6ghz_passive_scan(struct iwl_mvm *mvm, |
21071 |
+ } |
21072 |
+ |
21073 |
+ /* |
21074 |
+- * 6GHz passive scan is allowed while associated in a defined time |
21075 |
+- * interval following HW reset or resume flow |
21076 |
++ * 6GHz passive scan is allowed in a defined time interval following HW |
21077 |
++ * reset or resume flow, or while not associated and a large interval |
21078 |
++ * has passed since the last 6GHz passive scan. |
21079 |
+ */ |
21080 |
+- if (vif->bss_conf.assoc && |
21081 |
++ if ((vif->bss_conf.assoc || |
21082 |
++ time_after(mvm->last_6ghz_passive_scan_jiffies + |
21083 |
++ (IWL_MVM_6GHZ_PASSIVE_SCAN_TIMEOUT * HZ), jiffies)) && |
21084 |
+ (time_before(mvm->last_reset_or_resume_time_jiffies + |
21085 |
+ (IWL_MVM_6GHZ_PASSIVE_SCAN_ASSOC_TIMEOUT * HZ), |
21086 |
+ jiffies))) { |
21087 |
+- IWL_DEBUG_SCAN(mvm, "6GHz passive scan: associated\n"); |
21088 |
+- return; |
21089 |
+- } |
21090 |
+- |
21091 |
+- /* No need for 6GHz passive scan if not enough time elapsed */ |
21092 |
+- if (time_after(mvm->last_6ghz_passive_scan_jiffies + |
21093 |
+- (IWL_MVM_6GHZ_PASSIVE_SCAN_TIMEOUT * HZ), jiffies)) { |
21094 |
+- IWL_DEBUG_SCAN(mvm, |
21095 |
+- "6GHz passive scan: timeout did not expire\n"); |
21096 |
++ IWL_DEBUG_SCAN(mvm, "6GHz passive scan: %s\n", |
21097 |
++ vif->bss_conf.assoc ? "associated" : |
21098 |
++ "timeout did not expire"); |
21099 |
+ return; |
21100 |
+ } |
21101 |
+ |
21102 |
+@@ -2490,7 +2487,7 @@ static int iwl_mvm_check_running_scans(struct iwl_mvm *mvm, int type) |
21103 |
+ return -EIO; |
21104 |
+ } |
21105 |
+ |
21106 |
+-#define SCAN_TIMEOUT 20000 |
21107 |
++#define SCAN_TIMEOUT 30000 |
21108 |
+ |
21109 |
+ void iwl_mvm_scan_timeout_wk(struct work_struct *work) |
21110 |
+ { |
21111 |
+diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c |
21112 |
+index e91f8e889df70..ab06dcda1462a 100644 |
21113 |
+--- a/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c |
21114 |
++++ b/drivers/net/wireless/intel/iwlwifi/mvm/time-event.c |
21115 |
+@@ -49,14 +49,13 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk) |
21116 |
+ struct iwl_mvm *mvm = container_of(wk, struct iwl_mvm, roc_done_wk); |
21117 |
+ |
21118 |
+ /* |
21119 |
+- * Clear the ROC_RUNNING /ROC_AUX_RUNNING status bit. |
21120 |
++ * Clear the ROC_RUNNING status bit. |
21121 |
+ * This will cause the TX path to drop offchannel transmissions. |
21122 |
+ * That would also be done by mac80211, but it is racy, in particular |
21123 |
+ * in the case that the time event actually completed in the firmware |
21124 |
+ * (which is handled in iwl_mvm_te_handle_notif). |
21125 |
+ */ |
21126 |
+ clear_bit(IWL_MVM_STATUS_ROC_RUNNING, &mvm->status); |
21127 |
+- clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status); |
21128 |
+ |
21129 |
+ synchronize_net(); |
21130 |
+ |
21131 |
+@@ -82,9 +81,19 @@ void iwl_mvm_roc_done_wk(struct work_struct *wk) |
21132 |
+ mvmvif = iwl_mvm_vif_from_mac80211(mvm->p2p_device_vif); |
21133 |
+ iwl_mvm_flush_sta(mvm, &mvmvif->bcast_sta, true); |
21134 |
+ } |
21135 |
+- } else { |
21136 |
++ } |
21137 |
++ |
21138 |
++ /* |
21139 |
++ * Clear the ROC_AUX_RUNNING status bit. |
21140 |
++ * This will cause the TX path to drop offchannel transmissions. |
21141 |
++ * That would also be done by mac80211, but it is racy, in particular |
21142 |
++ * in the case that the time event actually completed in the firmware |
21143 |
++ * (which is handled in iwl_mvm_te_handle_notif). |
21144 |
++ */ |
21145 |
++ if (test_and_clear_bit(IWL_MVM_STATUS_ROC_AUX_RUNNING, &mvm->status)) { |
21146 |
+ /* do the same in case of hot spot 2.0 */ |
21147 |
+ iwl_mvm_flush_sta(mvm, &mvm->aux_sta, true); |
21148 |
++ |
21149 |
+ /* In newer version of this command an aux station is added only |
21150 |
+ * in cases of dedicated tx queue and need to be removed in end |
21151 |
+ * of use */ |
21152 |
+@@ -687,11 +696,14 @@ static bool __iwl_mvm_remove_time_event(struct iwl_mvm *mvm, |
21153 |
+ iwl_mvm_te_clear_data(mvm, te_data); |
21154 |
+ spin_unlock_bh(&mvm->time_event_lock); |
21155 |
+ |
21156 |
+- /* When session protection is supported, the te_data->id field |
21157 |
++ /* When session protection is used, the te_data->id field |
21158 |
+ * is reused to save session protection's configuration. |
21159 |
++ * For AUX ROC, HOT_SPOT_CMD is used and the te_data->id field is set |
21160 |
++ * to HOT_SPOT_CMD. |
21161 |
+ */ |
21162 |
+ if (fw_has_capa(&mvm->fw->ucode_capa, |
21163 |
+- IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD)) { |
21164 |
++ IWL_UCODE_TLV_CAPA_SESSION_PROT_CMD) && |
21165 |
++ id != HOT_SPOT_CMD) { |
21166 |
+ if (mvmvif && id < SESSION_PROTECT_CONF_MAX_ID) { |
21167 |
+ /* Session protection is still ongoing. Cancel it */ |
21168 |
+ iwl_mvm_cancel_session_protection(mvm, mvmvif, id); |
21169 |
+@@ -1027,7 +1039,7 @@ void iwl_mvm_stop_roc(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
21170 |
+ iwl_mvm_p2p_roc_finished(mvm); |
21171 |
+ } else { |
21172 |
+ iwl_mvm_remove_aux_roc_te(mvm, mvmvif, |
21173 |
+- &mvmvif->time_event_data); |
21174 |
++ &mvmvif->hs_time_event_data); |
21175 |
+ iwl_mvm_roc_finished(mvm); |
21176 |
+ } |
21177 |
+ |
21178 |
+@@ -1158,15 +1170,10 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm, |
21179 |
+ cpu_to_le32(FW_CMD_ID_AND_COLOR(mvmvif->id, |
21180 |
+ mvmvif->color)), |
21181 |
+ .action = cpu_to_le32(FW_CTXT_ACTION_ADD), |
21182 |
++ .conf_id = cpu_to_le32(SESSION_PROTECT_CONF_ASSOC), |
21183 |
+ .duration_tu = cpu_to_le32(MSEC_TO_TU(duration)), |
21184 |
+ }; |
21185 |
+ |
21186 |
+- /* The time_event_data.id field is reused to save session |
21187 |
+- * protection's configuration. |
21188 |
+- */ |
21189 |
+- mvmvif->time_event_data.id = SESSION_PROTECT_CONF_ASSOC; |
21190 |
+- cmd.conf_id = cpu_to_le32(mvmvif->time_event_data.id); |
21191 |
+- |
21192 |
+ lockdep_assert_held(&mvm->mutex); |
21193 |
+ |
21194 |
+ spin_lock_bh(&mvm->time_event_lock); |
21195 |
+@@ -1180,6 +1187,11 @@ void iwl_mvm_schedule_session_protection(struct iwl_mvm *mvm, |
21196 |
+ } |
21197 |
+ |
21198 |
+ iwl_mvm_te_clear_data(mvm, te_data); |
21199 |
++ /* |
21200 |
++ * The time_event_data.id field is reused to save session |
21201 |
++ * protection's configuration. |
21202 |
++ */ |
21203 |
++ te_data->id = le32_to_cpu(cmd.conf_id); |
21204 |
+ te_data->duration = le32_to_cpu(cmd.duration_tu); |
21205 |
+ te_data->vif = vif; |
21206 |
+ spin_unlock_bh(&mvm->time_event_lock); |
21207 |
+diff --git a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c |
21208 |
+index 8e45eb38304b2..fea89330f692c 100644 |
21209 |
+--- a/drivers/net/wireless/intel/iwlwifi/pcie/rx.c |
21210 |
++++ b/drivers/net/wireless/intel/iwlwifi/pcie/rx.c |
21211 |
+@@ -2261,7 +2261,12 @@ irqreturn_t iwl_pcie_irq_msix_handler(int irq, void *dev_id) |
21212 |
+ } |
21213 |
+ } |
21214 |
+ |
21215 |
+- if (inta_hw & MSIX_HW_INT_CAUSES_REG_WAKEUP) { |
21216 |
++ /* |
21217 |
++ * In some rare cases when the HW is in a bad state, we may |
21218 |
++ * get this interrupt too early, when prph_info is still NULL. |
21219 |
++ * So make sure that it's not NULL to prevent crashing. |
21220 |
++ */ |
21221 |
++ if (inta_hw & MSIX_HW_INT_CAUSES_REG_WAKEUP && trans_pcie->prph_info) { |
21222 |
+ u32 sleep_notif = |
21223 |
+ le32_to_cpu(trans_pcie->prph_info->sleep_notif); |
21224 |
+ if (sleep_notif == IWL_D3_SLEEP_STATUS_SUSPEND || |
21225 |
+diff --git a/drivers/net/wireless/intel/iwlwifi/queue/tx.c b/drivers/net/wireless/intel/iwlwifi/queue/tx.c |
21226 |
+index 451b060693501..0f3526b0c5b00 100644 |
21227 |
+--- a/drivers/net/wireless/intel/iwlwifi/queue/tx.c |
21228 |
++++ b/drivers/net/wireless/intel/iwlwifi/queue/tx.c |
21229 |
+@@ -1072,6 +1072,7 @@ int iwl_txq_alloc(struct iwl_trans *trans, struct iwl_txq *txq, int slots_num, |
21230 |
+ return 0; |
21231 |
+ err_free_tfds: |
21232 |
+ dma_free_coherent(trans->dev, tfd_sz, txq->tfds, txq->dma_addr); |
21233 |
++ txq->tfds = NULL; |
21234 |
+ error: |
21235 |
+ if (txq->entries && cmd_queue) |
21236 |
+ for (i = 0; i < slots_num; i++) |
21237 |
+diff --git a/drivers/net/wireless/marvell/mwifiex/sta_event.c b/drivers/net/wireless/marvell/mwifiex/sta_event.c |
21238 |
+index 68c63268e2e6b..2b2e6e0166e14 100644 |
21239 |
+--- a/drivers/net/wireless/marvell/mwifiex/sta_event.c |
21240 |
++++ b/drivers/net/wireless/marvell/mwifiex/sta_event.c |
21241 |
+@@ -365,10 +365,12 @@ static void mwifiex_process_uap_tx_pause(struct mwifiex_private *priv, |
21242 |
+ sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac); |
21243 |
+ if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) { |
21244 |
+ sta_ptr->tx_pause = tp->tx_pause; |
21245 |
++ spin_unlock_bh(&priv->sta_list_spinlock); |
21246 |
+ mwifiex_update_ralist_tx_pause(priv, tp->peermac, |
21247 |
+ tp->tx_pause); |
21248 |
++ } else { |
21249 |
++ spin_unlock_bh(&priv->sta_list_spinlock); |
21250 |
+ } |
21251 |
+- spin_unlock_bh(&priv->sta_list_spinlock); |
21252 |
+ } |
21253 |
+ } |
21254 |
+ |
21255 |
+@@ -400,11 +402,13 @@ static void mwifiex_process_sta_tx_pause(struct mwifiex_private *priv, |
21256 |
+ sta_ptr = mwifiex_get_sta_entry(priv, tp->peermac); |
21257 |
+ if (sta_ptr && sta_ptr->tx_pause != tp->tx_pause) { |
21258 |
+ sta_ptr->tx_pause = tp->tx_pause; |
21259 |
++ spin_unlock_bh(&priv->sta_list_spinlock); |
21260 |
+ mwifiex_update_ralist_tx_pause(priv, |
21261 |
+ tp->peermac, |
21262 |
+ tp->tx_pause); |
21263 |
++ } else { |
21264 |
++ spin_unlock_bh(&priv->sta_list_spinlock); |
21265 |
+ } |
21266 |
+- spin_unlock_bh(&priv->sta_list_spinlock); |
21267 |
+ } |
21268 |
+ } |
21269 |
+ } |
21270 |
+diff --git a/drivers/net/wireless/marvell/mwifiex/usb.c b/drivers/net/wireless/marvell/mwifiex/usb.c |
21271 |
+index 9736aa0ab7fd4..8f01fcbe93961 100644 |
21272 |
+--- a/drivers/net/wireless/marvell/mwifiex/usb.c |
21273 |
++++ b/drivers/net/wireless/marvell/mwifiex/usb.c |
21274 |
+@@ -130,7 +130,8 @@ static int mwifiex_usb_recv(struct mwifiex_adapter *adapter, |
21275 |
+ default: |
21276 |
+ mwifiex_dbg(adapter, ERROR, |
21277 |
+ "unknown recv_type %#x\n", recv_type); |
21278 |
+- return -1; |
21279 |
++ ret = -1; |
21280 |
++ goto exit_restore_skb; |
21281 |
+ } |
21282 |
+ break; |
21283 |
+ case MWIFIEX_USB_EP_DATA: |
21284 |
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c |
21285 |
+index 3972c56136a20..65f1f2bb80835 100644 |
21286 |
+--- a/drivers/net/wireless/mediatek/mt76/mt7603/mac.c |
21287 |
++++ b/drivers/net/wireless/mediatek/mt76/mt7603/mac.c |
21288 |
+@@ -525,6 +525,10 @@ mt7603_mac_fill_rx(struct mt7603_dev *dev, struct sk_buff *skb) |
21289 |
+ if (rxd2 & MT_RXD2_NORMAL_TKIP_MIC_ERR) |
21290 |
+ status->flag |= RX_FLAG_MMIC_ERROR; |
21291 |
+ |
21292 |
++ /* ICV error or CCMP/BIP/WPI MIC error */ |
21293 |
++ if (rxd2 & MT_RXD2_NORMAL_ICV_ERR) |
21294 |
++ status->flag |= RX_FLAG_ONLY_MONITOR; |
21295 |
++ |
21296 |
+ if (FIELD_GET(MT_RXD2_NORMAL_SEC_MODE, rxd2) != 0 && |
21297 |
+ !(rxd2 & (MT_RXD2_NORMAL_CLM | MT_RXD2_NORMAL_CM))) { |
21298 |
+ status->flag |= RX_FLAG_DECRYPTED; |
21299 |
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c |
21300 |
+index 5455231f51881..f2704149834a0 100644 |
21301 |
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/mac.c |
21302 |
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/mac.c |
21303 |
+@@ -286,9 +286,16 @@ static int mt7615_mac_fill_rx(struct mt7615_dev *dev, struct sk_buff *skb) |
21304 |
+ if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR) |
21305 |
+ return -EINVAL; |
21306 |
+ |
21307 |
++ hdr_trans = rxd1 & MT_RXD1_NORMAL_HDR_TRANS; |
21308 |
++ if (hdr_trans && (rxd2 & MT_RXD2_NORMAL_CM)) |
21309 |
++ return -EINVAL; |
21310 |
++ |
21311 |
++ /* ICV error or CCMP/BIP/WPI MIC error */ |
21312 |
++ if (rxd2 & MT_RXD2_NORMAL_ICV_ERR) |
21313 |
++ status->flag |= RX_FLAG_ONLY_MONITOR; |
21314 |
++ |
21315 |
+ unicast = (rxd1 & MT_RXD1_NORMAL_ADDR_TYPE) == MT_RXD1_NORMAL_U2M; |
21316 |
+ idx = FIELD_GET(MT_RXD2_NORMAL_WLAN_IDX, rxd2); |
21317 |
+- hdr_trans = rxd1 & MT_RXD1_NORMAL_HDR_TRANS; |
21318 |
+ status->wcid = mt7615_rx_get_wcid(dev, idx, unicast); |
21319 |
+ |
21320 |
+ if (status->wcid) { |
21321 |
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/main.c b/drivers/net/wireless/mediatek/mt76/mt7615/main.c |
21322 |
+index 51260a669d166..fc266da54fe7b 100644 |
21323 |
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/main.c |
21324 |
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/main.c |
21325 |
+@@ -211,11 +211,9 @@ static int mt7615_add_interface(struct ieee80211_hw *hw, |
21326 |
+ mvif->mt76.omac_idx = idx; |
21327 |
+ |
21328 |
+ mvif->mt76.band_idx = ext_phy; |
21329 |
+- if (mt7615_ext_phy(dev)) |
21330 |
+- mvif->mt76.wmm_idx = ext_phy * (MT7615_MAX_WMM_SETS / 2) + |
21331 |
+- mvif->mt76.idx % (MT7615_MAX_WMM_SETS / 2); |
21332 |
+- else |
21333 |
+- mvif->mt76.wmm_idx = mvif->mt76.idx % MT7615_MAX_WMM_SETS; |
21334 |
++ mvif->mt76.wmm_idx = vif->type != NL80211_IFTYPE_AP; |
21335 |
++ if (ext_phy) |
21336 |
++ mvif->mt76.wmm_idx += 2; |
21337 |
+ |
21338 |
+ dev->mt76.vif_mask |= BIT(mvif->mt76.idx); |
21339 |
+ dev->omac_mask |= BIT_ULL(mvif->mt76.omac_idx); |
21340 |
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c |
21341 |
+index a2465b49ecd0c..87b4aa52ee0f9 100644 |
21342 |
+--- a/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c |
21343 |
++++ b/drivers/net/wireless/mediatek/mt76/mt7615/pci_init.c |
21344 |
+@@ -28,8 +28,6 @@ static void mt7615_pci_init_work(struct work_struct *work) |
21345 |
+ return; |
21346 |
+ |
21347 |
+ mt7615_init_work(dev); |
21348 |
+- if (dev->dbdc_support) |
21349 |
+- mt7615_register_ext_phy(dev); |
21350 |
+ } |
21351 |
+ |
21352 |
+ static int mt7615_init_hardware(struct mt7615_dev *dev) |
21353 |
+@@ -160,6 +158,12 @@ int mt7615_register_device(struct mt7615_dev *dev) |
21354 |
+ mt7615_init_txpower(dev, &dev->mphy.sband_2g.sband); |
21355 |
+ mt7615_init_txpower(dev, &dev->mphy.sband_5g.sband); |
21356 |
+ |
21357 |
++ if (dev->dbdc_support) { |
21358 |
++ ret = mt7615_register_ext_phy(dev); |
21359 |
++ if (ret) |
21360 |
++ return ret; |
21361 |
++ } |
21362 |
++ |
21363 |
+ return mt7615_init_debugfs(dev); |
21364 |
+ } |
21365 |
+ |
21366 |
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c |
21367 |
+index bbc996f86b5c3..ff613d7056119 100644 |
21368 |
+--- a/drivers/net/wireless/mediatek/mt76/mt7915/mac.c |
21369 |
++++ b/drivers/net/wireless/mediatek/mt76/mt7915/mac.c |
21370 |
+@@ -349,9 +349,16 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb) |
21371 |
+ if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR) |
21372 |
+ return -EINVAL; |
21373 |
+ |
21374 |
++ hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS; |
21375 |
++ if (hdr_trans && (rxd1 & MT_RXD1_NORMAL_CM)) |
21376 |
++ return -EINVAL; |
21377 |
++ |
21378 |
++ /* ICV error or CCMP/BIP/WPI MIC error */ |
21379 |
++ if (rxd1 & MT_RXD1_NORMAL_ICV_ERR) |
21380 |
++ status->flag |= RX_FLAG_ONLY_MONITOR; |
21381 |
++ |
21382 |
+ unicast = FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) == MT_RXD3_NORMAL_U2M; |
21383 |
+ idx = FIELD_GET(MT_RXD1_NORMAL_WLAN_IDX, rxd1); |
21384 |
+- hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS; |
21385 |
+ status->wcid = mt7915_rx_get_wcid(dev, idx, unicast); |
21386 |
+ |
21387 |
+ if (status->wcid) { |
21388 |
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c |
21389 |
+index 8a16f3f4d5253..04a288029c98e 100644 |
21390 |
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c |
21391 |
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c |
21392 |
+@@ -383,10 +383,17 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb) |
21393 |
+ if (rxd2 & MT_RXD2_NORMAL_AMSDU_ERR) |
21394 |
+ return -EINVAL; |
21395 |
+ |
21396 |
++ hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS; |
21397 |
++ if (hdr_trans && (rxd1 & MT_RXD1_NORMAL_CM)) |
21398 |
++ return -EINVAL; |
21399 |
++ |
21400 |
++ /* ICV error or CCMP/BIP/WPI MIC error */ |
21401 |
++ if (rxd1 & MT_RXD1_NORMAL_ICV_ERR) |
21402 |
++ status->flag |= RX_FLAG_ONLY_MONITOR; |
21403 |
++ |
21404 |
+ chfreq = FIELD_GET(MT_RXD3_NORMAL_CH_FREQ, rxd3); |
21405 |
+ unicast = FIELD_GET(MT_RXD3_NORMAL_ADDR_TYPE, rxd3) == MT_RXD3_NORMAL_U2M; |
21406 |
+ idx = FIELD_GET(MT_RXD1_NORMAL_WLAN_IDX, rxd1); |
21407 |
+- hdr_trans = rxd2 & MT_RXD2_NORMAL_HDR_TRANS; |
21408 |
+ status->wcid = mt7921_rx_get_wcid(dev, idx, unicast); |
21409 |
+ |
21410 |
+ if (status->wcid) { |
21411 |
+diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c |
21412 |
+index 63ec140c9c372..9eb90e6f01031 100644 |
21413 |
+--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c |
21414 |
++++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c |
21415 |
+@@ -285,12 +285,6 @@ static int mt7921_add_interface(struct ieee80211_hw *hw, |
21416 |
+ mtxq->wcid = &mvif->sta.wcid; |
21417 |
+ } |
21418 |
+ |
21419 |
+- if (vif->type != NL80211_IFTYPE_AP && |
21420 |
+- (!mvif->mt76.omac_idx || mvif->mt76.omac_idx > 3)) |
21421 |
+- vif->offload_flags = 0; |
21422 |
+- |
21423 |
+- vif->offload_flags |= IEEE80211_OFFLOAD_ENCAP_4ADDR; |
21424 |
+- |
21425 |
+ out: |
21426 |
+ mt7921_mutex_release(dev); |
21427 |
+ |
21428 |
+diff --git a/drivers/net/wireless/microchip/wilc1000/netdev.c b/drivers/net/wireless/microchip/wilc1000/netdev.c |
21429 |
+index 7e4d9235251cb..9dfb1a285e6a4 100644 |
21430 |
+--- a/drivers/net/wireless/microchip/wilc1000/netdev.c |
21431 |
++++ b/drivers/net/wireless/microchip/wilc1000/netdev.c |
21432 |
+@@ -901,7 +901,6 @@ void wilc_netdev_cleanup(struct wilc *wilc) |
21433 |
+ |
21434 |
+ wilc_wlan_cfg_deinit(wilc); |
21435 |
+ wlan_deinit_locks(wilc); |
21436 |
+- kfree(wilc->bus_data); |
21437 |
+ wiphy_unregister(wilc->wiphy); |
21438 |
+ wiphy_free(wilc->wiphy); |
21439 |
+ } |
21440 |
+diff --git a/drivers/net/wireless/microchip/wilc1000/sdio.c b/drivers/net/wireless/microchip/wilc1000/sdio.c |
21441 |
+index 42e03a701ae16..8b3b735231085 100644 |
21442 |
+--- a/drivers/net/wireless/microchip/wilc1000/sdio.c |
21443 |
++++ b/drivers/net/wireless/microchip/wilc1000/sdio.c |
21444 |
+@@ -167,9 +167,11 @@ free: |
21445 |
+ static void wilc_sdio_remove(struct sdio_func *func) |
21446 |
+ { |
21447 |
+ struct wilc *wilc = sdio_get_drvdata(func); |
21448 |
++ struct wilc_sdio *sdio_priv = wilc->bus_data; |
21449 |
+ |
21450 |
+ clk_disable_unprepare(wilc->rtc_clk); |
21451 |
+ wilc_netdev_cleanup(wilc); |
21452 |
++ kfree(sdio_priv); |
21453 |
+ } |
21454 |
+ |
21455 |
+ static int wilc_sdio_reset(struct wilc *wilc) |
21456 |
+diff --git a/drivers/net/wireless/microchip/wilc1000/spi.c b/drivers/net/wireless/microchip/wilc1000/spi.c |
21457 |
+index dd481dc0b5ce0..c98c0999a6b67 100644 |
21458 |
+--- a/drivers/net/wireless/microchip/wilc1000/spi.c |
21459 |
++++ b/drivers/net/wireless/microchip/wilc1000/spi.c |
21460 |
+@@ -182,9 +182,11 @@ free: |
21461 |
+ static int wilc_bus_remove(struct spi_device *spi) |
21462 |
+ { |
21463 |
+ struct wilc *wilc = spi_get_drvdata(spi); |
21464 |
++ struct wilc_spi *spi_priv = wilc->bus_data; |
21465 |
+ |
21466 |
+ clk_disable_unprepare(wilc->rtc_clk); |
21467 |
+ wilc_netdev_cleanup(wilc); |
21468 |
++ kfree(spi_priv); |
21469 |
+ |
21470 |
+ return 0; |
21471 |
+ } |
21472 |
+diff --git a/drivers/net/wireless/realtek/rtw88/main.c b/drivers/net/wireless/realtek/rtw88/main.c |
21473 |
+index 6bb55e663fc36..69512856bb462 100644 |
21474 |
+--- a/drivers/net/wireless/realtek/rtw88/main.c |
21475 |
++++ b/drivers/net/wireless/realtek/rtw88/main.c |
21476 |
+@@ -1859,7 +1859,7 @@ int rtw_core_init(struct rtw_dev *rtwdev) |
21477 |
+ |
21478 |
+ /* default rx filter setting */ |
21479 |
+ rtwdev->hal.rcr = BIT_APP_FCS | BIT_APP_MIC | BIT_APP_ICV | |
21480 |
+- BIT_HTC_LOC_CTRL | BIT_APP_PHYSTS | |
21481 |
++ BIT_PKTCTL_DLEN | BIT_HTC_LOC_CTRL | BIT_APP_PHYSTS | |
21482 |
+ BIT_AB | BIT_AM | BIT_APM; |
21483 |
+ |
21484 |
+ ret = rtw_load_firmware(rtwdev, RTW_NORMAL_FW); |
21485 |
+diff --git a/drivers/net/wireless/realtek/rtw88/pci.c b/drivers/net/wireless/realtek/rtw88/pci.c |
21486 |
+index a7a6ebfaa203c..08cf66141889b 100644 |
21487 |
+--- a/drivers/net/wireless/realtek/rtw88/pci.c |
21488 |
++++ b/drivers/net/wireless/realtek/rtw88/pci.c |
21489 |
+@@ -2,7 +2,6 @@ |
21490 |
+ /* Copyright(c) 2018-2019 Realtek Corporation |
21491 |
+ */ |
21492 |
+ |
21493 |
+-#include <linux/dmi.h> |
21494 |
+ #include <linux/module.h> |
21495 |
+ #include <linux/pci.h> |
21496 |
+ #include "main.h" |
21497 |
+@@ -1409,7 +1408,11 @@ static void rtw_pci_link_ps(struct rtw_dev *rtwdev, bool enter) |
21498 |
+ * throughput. This is probably because the ASPM behavior slightly |
21499 |
+ * varies from different SOC. |
21500 |
+ */ |
21501 |
+- if (rtwpci->link_ctrl & PCI_EXP_LNKCTL_ASPM_L1) |
21502 |
++ if (!(rtwpci->link_ctrl & PCI_EXP_LNKCTL_ASPM_L1)) |
21503 |
++ return; |
21504 |
++ |
21505 |
++ if ((enter && atomic_dec_if_positive(&rtwpci->link_usage) == 0) || |
21506 |
++ (!enter && atomic_inc_return(&rtwpci->link_usage) == 1)) |
21507 |
+ rtw_pci_aspm_set(rtwdev, enter); |
21508 |
+ } |
21509 |
+ |
21510 |
+@@ -1658,6 +1661,9 @@ static int rtw_pci_napi_poll(struct napi_struct *napi, int budget) |
21511 |
+ priv); |
21512 |
+ int work_done = 0; |
21513 |
+ |
21514 |
++ if (rtwpci->rx_no_aspm) |
21515 |
++ rtw_pci_link_ps(rtwdev, false); |
21516 |
++ |
21517 |
+ while (work_done < budget) { |
21518 |
+ u32 work_done_once; |
21519 |
+ |
21520 |
+@@ -1681,6 +1687,8 @@ static int rtw_pci_napi_poll(struct napi_struct *napi, int budget) |
21521 |
+ if (rtw_pci_get_hw_rx_ring_nr(rtwdev, rtwpci)) |
21522 |
+ napi_schedule(napi); |
21523 |
+ } |
21524 |
++ if (rtwpci->rx_no_aspm) |
21525 |
++ rtw_pci_link_ps(rtwdev, true); |
21526 |
+ |
21527 |
+ return work_done; |
21528 |
+ } |
21529 |
+@@ -1702,50 +1710,13 @@ static void rtw_pci_napi_deinit(struct rtw_dev *rtwdev) |
21530 |
+ netif_napi_del(&rtwpci->napi); |
21531 |
+ } |
21532 |
+ |
21533 |
+-enum rtw88_quirk_dis_pci_caps { |
21534 |
+- QUIRK_DIS_PCI_CAP_MSI, |
21535 |
+- QUIRK_DIS_PCI_CAP_ASPM, |
21536 |
+-}; |
21537 |
+- |
21538 |
+-static int disable_pci_caps(const struct dmi_system_id *dmi) |
21539 |
+-{ |
21540 |
+- uintptr_t dis_caps = (uintptr_t)dmi->driver_data; |
21541 |
+- |
21542 |
+- if (dis_caps & BIT(QUIRK_DIS_PCI_CAP_MSI)) |
21543 |
+- rtw_disable_msi = true; |
21544 |
+- if (dis_caps & BIT(QUIRK_DIS_PCI_CAP_ASPM)) |
21545 |
+- rtw_pci_disable_aspm = true; |
21546 |
+- |
21547 |
+- return 1; |
21548 |
+-} |
21549 |
+- |
21550 |
+-static const struct dmi_system_id rtw88_pci_quirks[] = { |
21551 |
+- { |
21552 |
+- .callback = disable_pci_caps, |
21553 |
+- .ident = "Protempo Ltd L116HTN6SPW", |
21554 |
+- .matches = { |
21555 |
+- DMI_MATCH(DMI_SYS_VENDOR, "Protempo Ltd"), |
21556 |
+- DMI_MATCH(DMI_PRODUCT_NAME, "L116HTN6SPW"), |
21557 |
+- }, |
21558 |
+- .driver_data = (void *)BIT(QUIRK_DIS_PCI_CAP_ASPM), |
21559 |
+- }, |
21560 |
+- { |
21561 |
+- .callback = disable_pci_caps, |
21562 |
+- .ident = "HP HP Pavilion Laptop 14-ce0xxx", |
21563 |
+- .matches = { |
21564 |
+- DMI_MATCH(DMI_SYS_VENDOR, "HP"), |
21565 |
+- DMI_MATCH(DMI_PRODUCT_NAME, "HP Pavilion Laptop 14-ce0xxx"), |
21566 |
+- }, |
21567 |
+- .driver_data = (void *)BIT(QUIRK_DIS_PCI_CAP_ASPM), |
21568 |
+- }, |
21569 |
+- {} |
21570 |
+-}; |
21571 |
+- |
21572 |
+ int rtw_pci_probe(struct pci_dev *pdev, |
21573 |
+ const struct pci_device_id *id) |
21574 |
+ { |
21575 |
++ struct pci_dev *bridge = pci_upstream_bridge(pdev); |
21576 |
+ struct ieee80211_hw *hw; |
21577 |
+ struct rtw_dev *rtwdev; |
21578 |
++ struct rtw_pci *rtwpci; |
21579 |
+ int drv_data_size; |
21580 |
+ int ret; |
21581 |
+ |
21582 |
+@@ -1763,6 +1734,9 @@ int rtw_pci_probe(struct pci_dev *pdev, |
21583 |
+ rtwdev->hci.ops = &rtw_pci_ops; |
21584 |
+ rtwdev->hci.type = RTW_HCI_TYPE_PCIE; |
21585 |
+ |
21586 |
++ rtwpci = (struct rtw_pci *)rtwdev->priv; |
21587 |
++ atomic_set(&rtwpci->link_usage, 1); |
21588 |
++ |
21589 |
+ ret = rtw_core_init(rtwdev); |
21590 |
+ if (ret) |
21591 |
+ goto err_release_hw; |
21592 |
+@@ -1791,7 +1765,10 @@ int rtw_pci_probe(struct pci_dev *pdev, |
21593 |
+ goto err_destroy_pci; |
21594 |
+ } |
21595 |
+ |
21596 |
+- dmi_check_system(rtw88_pci_quirks); |
21597 |
++ /* Disable PCIe ASPM L1 while doing NAPI poll for 8821CE */ |
21598 |
++ if (pdev->device == 0xc821 && bridge->vendor == PCI_VENDOR_ID_INTEL) |
21599 |
++ rtwpci->rx_no_aspm = true; |
21600 |
++ |
21601 |
+ rtw_pci_phy_cfg(rtwdev); |
21602 |
+ |
21603 |
+ ret = rtw_register_hw(rtwdev, hw); |
21604 |
+diff --git a/drivers/net/wireless/realtek/rtw88/pci.h b/drivers/net/wireless/realtek/rtw88/pci.h |
21605 |
+index 66f78eb7757c5..0c37efd8c66fa 100644 |
21606 |
+--- a/drivers/net/wireless/realtek/rtw88/pci.h |
21607 |
++++ b/drivers/net/wireless/realtek/rtw88/pci.h |
21608 |
+@@ -223,6 +223,8 @@ struct rtw_pci { |
21609 |
+ struct rtw_pci_tx_ring tx_rings[RTK_MAX_TX_QUEUE_NUM]; |
21610 |
+ struct rtw_pci_rx_ring rx_rings[RTK_MAX_RX_QUEUE_NUM]; |
21611 |
+ u16 link_ctrl; |
21612 |
++ atomic_t link_usage; |
21613 |
++ bool rx_no_aspm; |
21614 |
+ DECLARE_BITMAP(flags, NUM_OF_RTW_PCI_FLAGS); |
21615 |
+ |
21616 |
+ void __iomem *mmap; |
21617 |
+diff --git a/drivers/net/wireless/realtek/rtw88/rtw8821c.h b/drivers/net/wireless/realtek/rtw88/rtw8821c.h |
21618 |
+index 112faa60f653e..d9fbddd7b0f35 100644 |
21619 |
+--- a/drivers/net/wireless/realtek/rtw88/rtw8821c.h |
21620 |
++++ b/drivers/net/wireless/realtek/rtw88/rtw8821c.h |
21621 |
+@@ -131,7 +131,7 @@ _rtw_write32s_mask(struct rtw_dev *rtwdev, u32 addr, u32 mask, u32 data) |
21622 |
+ #define WLAN_TX_FUNC_CFG2 0x30 |
21623 |
+ #define WLAN_MAC_OPT_NORM_FUNC1 0x98 |
21624 |
+ #define WLAN_MAC_OPT_LB_FUNC1 0x80 |
21625 |
+-#define WLAN_MAC_OPT_FUNC2 0x30810041 |
21626 |
++#define WLAN_MAC_OPT_FUNC2 0xb0810041 |
21627 |
+ |
21628 |
+ #define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \ |
21629 |
+ (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \ |
21630 |
+diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822b.c b/drivers/net/wireless/realtek/rtw88/rtw8822b.c |
21631 |
+index f1789155e9016..247f26e3e8192 100644 |
21632 |
+--- a/drivers/net/wireless/realtek/rtw88/rtw8822b.c |
21633 |
++++ b/drivers/net/wireless/realtek/rtw88/rtw8822b.c |
21634 |
+@@ -204,7 +204,7 @@ static void rtw8822b_phy_set_param(struct rtw_dev *rtwdev) |
21635 |
+ #define WLAN_TX_FUNC_CFG2 0x30 |
21636 |
+ #define WLAN_MAC_OPT_NORM_FUNC1 0x98 |
21637 |
+ #define WLAN_MAC_OPT_LB_FUNC1 0x80 |
21638 |
+-#define WLAN_MAC_OPT_FUNC2 0x30810041 |
21639 |
++#define WLAN_MAC_OPT_FUNC2 0xb0810041 |
21640 |
+ |
21641 |
+ #define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \ |
21642 |
+ (WLAN_SIFS_OFDM_CONT_TX << BIT_SHIFT_SIFS_OFDM_CTX) | \ |
21643 |
+diff --git a/drivers/net/wireless/realtek/rtw88/rtw8822c.c b/drivers/net/wireless/realtek/rtw88/rtw8822c.c |
21644 |
+index f3ad079967a68..bc87e3cb9cdce 100644 |
21645 |
+--- a/drivers/net/wireless/realtek/rtw88/rtw8822c.c |
21646 |
++++ b/drivers/net/wireless/realtek/rtw88/rtw8822c.c |
21647 |
+@@ -1962,7 +1962,7 @@ static void rtw8822c_phy_set_param(struct rtw_dev *rtwdev) |
21648 |
+ #define WLAN_TX_FUNC_CFG2 0x30 |
21649 |
+ #define WLAN_MAC_OPT_NORM_FUNC1 0x98 |
21650 |
+ #define WLAN_MAC_OPT_LB_FUNC1 0x80 |
21651 |
+-#define WLAN_MAC_OPT_FUNC2 0x30810041 |
21652 |
++#define WLAN_MAC_OPT_FUNC2 0xb0810041 |
21653 |
+ #define WLAN_MAC_INT_MIG_CFG 0x33330000 |
21654 |
+ |
21655 |
+ #define WLAN_SIFS_CFG (WLAN_SIFS_CCK_CONT_TX | \ |
21656 |
+diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c b/drivers/net/wireless/rsi/rsi_91x_main.c |
21657 |
+index f1bf71e6c6081..5d1490fc32db4 100644 |
21658 |
+--- a/drivers/net/wireless/rsi/rsi_91x_main.c |
21659 |
++++ b/drivers/net/wireless/rsi/rsi_91x_main.c |
21660 |
+@@ -23,6 +23,7 @@ |
21661 |
+ #include "rsi_common.h" |
21662 |
+ #include "rsi_coex.h" |
21663 |
+ #include "rsi_hal.h" |
21664 |
++#include "rsi_usb.h" |
21665 |
+ |
21666 |
+ u32 rsi_zone_enabled = /* INFO_ZONE | |
21667 |
+ INIT_ZONE | |
21668 |
+@@ -168,6 +169,9 @@ int rsi_read_pkt(struct rsi_common *common, u8 *rx_pkt, s32 rcv_pkt_len) |
21669 |
+ frame_desc = &rx_pkt[index]; |
21670 |
+ actual_length = *(u16 *)&frame_desc[0]; |
21671 |
+ offset = *(u16 *)&frame_desc[2]; |
21672 |
++ if (!rcv_pkt_len && offset > |
21673 |
++ RSI_MAX_RX_USB_PKT_SIZE - FRAME_DESC_SZ) |
21674 |
++ goto fail; |
21675 |
+ |
21676 |
+ queueno = rsi_get_queueno(frame_desc, offset); |
21677 |
+ length = rsi_get_length(frame_desc, offset); |
21678 |
+diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c |
21679 |
+index 6821ea9918956..66fe386ec9cc6 100644 |
21680 |
+--- a/drivers/net/wireless/rsi/rsi_91x_usb.c |
21681 |
++++ b/drivers/net/wireless/rsi/rsi_91x_usb.c |
21682 |
+@@ -269,8 +269,12 @@ static void rsi_rx_done_handler(struct urb *urb) |
21683 |
+ struct rsi_91x_usbdev *dev = (struct rsi_91x_usbdev *)rx_cb->data; |
21684 |
+ int status = -EINVAL; |
21685 |
+ |
21686 |
++ if (!rx_cb->rx_skb) |
21687 |
++ return; |
21688 |
++ |
21689 |
+ if (urb->status) { |
21690 |
+ dev_kfree_skb(rx_cb->rx_skb); |
21691 |
++ rx_cb->rx_skb = NULL; |
21692 |
+ return; |
21693 |
+ } |
21694 |
+ |
21695 |
+@@ -294,8 +298,10 @@ out: |
21696 |
+ if (rsi_rx_urb_submit(dev->priv, rx_cb->ep_num, GFP_ATOMIC)) |
21697 |
+ rsi_dbg(ERR_ZONE, "%s: Failed in urb submission", __func__); |
21698 |
+ |
21699 |
+- if (status) |
21700 |
++ if (status) { |
21701 |
+ dev_kfree_skb(rx_cb->rx_skb); |
21702 |
++ rx_cb->rx_skb = NULL; |
21703 |
++ } |
21704 |
+ } |
21705 |
+ |
21706 |
+ static void rsi_rx_urb_kill(struct rsi_hw *adapter, u8 ep_num) |
21707 |
+@@ -324,7 +330,6 @@ static int rsi_rx_urb_submit(struct rsi_hw *adapter, u8 ep_num, gfp_t mem_flags) |
21708 |
+ struct sk_buff *skb; |
21709 |
+ u8 dword_align_bytes = 0; |
21710 |
+ |
21711 |
+-#define RSI_MAX_RX_USB_PKT_SIZE 3000 |
21712 |
+ skb = dev_alloc_skb(RSI_MAX_RX_USB_PKT_SIZE); |
21713 |
+ if (!skb) |
21714 |
+ return -ENOMEM; |
21715 |
+diff --git a/drivers/net/wireless/rsi/rsi_usb.h b/drivers/net/wireless/rsi/rsi_usb.h |
21716 |
+index 254d19b664123..961851748bc4c 100644 |
21717 |
+--- a/drivers/net/wireless/rsi/rsi_usb.h |
21718 |
++++ b/drivers/net/wireless/rsi/rsi_usb.h |
21719 |
+@@ -44,6 +44,8 @@ |
21720 |
+ #define RSI_USB_BUF_SIZE 4096 |
21721 |
+ #define RSI_USB_CTRL_BUF_SIZE 0x04 |
21722 |
+ |
21723 |
++#define RSI_MAX_RX_USB_PKT_SIZE 3000 |
21724 |
++ |
21725 |
+ struct rx_usb_ctrl_block { |
21726 |
+ u8 *data; |
21727 |
+ struct urb *rx_urb; |
21728 |
+diff --git a/drivers/net/wwan/mhi_wwan_mbim.c b/drivers/net/wwan/mhi_wwan_mbim.c |
21729 |
+index 71bf9b4f769f5..6872782e8dd89 100644 |
21730 |
+--- a/drivers/net/wwan/mhi_wwan_mbim.c |
21731 |
++++ b/drivers/net/wwan/mhi_wwan_mbim.c |
21732 |
+@@ -385,13 +385,13 @@ static void mhi_net_rx_refill_work(struct work_struct *work) |
21733 |
+ int err; |
21734 |
+ |
21735 |
+ while (!mhi_queue_is_full(mdev, DMA_FROM_DEVICE)) { |
21736 |
+- struct sk_buff *skb = alloc_skb(MHI_DEFAULT_MRU, GFP_KERNEL); |
21737 |
++ struct sk_buff *skb = alloc_skb(mbim->mru, GFP_KERNEL); |
21738 |
+ |
21739 |
+ if (unlikely(!skb)) |
21740 |
+ break; |
21741 |
+ |
21742 |
+ err = mhi_queue_skb(mdev, DMA_FROM_DEVICE, skb, |
21743 |
+- MHI_DEFAULT_MRU, MHI_EOT); |
21744 |
++ mbim->mru, MHI_EOT); |
21745 |
+ if (unlikely(err)) { |
21746 |
+ kfree_skb(skb); |
21747 |
+ break; |
21748 |
+diff --git a/drivers/nvmem/core.c b/drivers/nvmem/core.c |
21749 |
+index 8976da38b375a..9aecb83021a2d 100644 |
21750 |
+--- a/drivers/nvmem/core.c |
21751 |
++++ b/drivers/nvmem/core.c |
21752 |
+@@ -307,6 +307,8 @@ static umode_t nvmem_bin_attr_is_visible(struct kobject *kobj, |
21753 |
+ struct device *dev = kobj_to_dev(kobj); |
21754 |
+ struct nvmem_device *nvmem = to_nvmem_device(dev); |
21755 |
+ |
21756 |
++ attr->size = nvmem->size; |
21757 |
++ |
21758 |
+ return nvmem_bin_attr_get_umode(nvmem); |
21759 |
+ } |
21760 |
+ |
21761 |
+diff --git a/drivers/of/base.c b/drivers/of/base.c |
21762 |
+index 0ac17256258d5..54719f8156ed1 100644 |
21763 |
+--- a/drivers/of/base.c |
21764 |
++++ b/drivers/of/base.c |
21765 |
+@@ -1327,9 +1327,14 @@ int of_phandle_iterator_next(struct of_phandle_iterator *it) |
21766 |
+ * property data length |
21767 |
+ */ |
21768 |
+ if (it->cur + count > it->list_end) { |
21769 |
+- pr_err("%pOF: %s = %d found %d\n", |
21770 |
+- it->parent, it->cells_name, |
21771 |
+- count, it->cell_count); |
21772 |
++ if (it->cells_name) |
21773 |
++ pr_err("%pOF: %s = %d found %td\n", |
21774 |
++ it->parent, it->cells_name, |
21775 |
++ count, it->list_end - it->cur); |
21776 |
++ else |
21777 |
++ pr_err("%pOF: phandle %s needs %d, found %td\n", |
21778 |
++ it->parent, of_node_full_name(it->node), |
21779 |
++ count, it->list_end - it->cur); |
21780 |
+ goto err; |
21781 |
+ } |
21782 |
+ } |
21783 |
+diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c |
21784 |
+index 4546572af24bb..59a7a9ee58ef7 100644 |
21785 |
+--- a/drivers/of/fdt.c |
21786 |
++++ b/drivers/of/fdt.c |
21787 |
+@@ -482,9 +482,11 @@ static int __init early_init_dt_reserve_memory_arch(phys_addr_t base, |
21788 |
+ if (nomap) { |
21789 |
+ /* |
21790 |
+ * If the memory is already reserved (by another region), we |
21791 |
+- * should not allow it to be marked nomap. |
21792 |
++ * should not allow it to be marked nomap, but don't worry |
21793 |
++ * if the region isn't memory as it won't be mapped. |
21794 |
+ */ |
21795 |
+- if (memblock_is_region_reserved(base, size)) |
21796 |
++ if (memblock_overlaps_region(&memblock.memory, base, size) && |
21797 |
++ memblock_is_region_reserved(base, size)) |
21798 |
+ return -EBUSY; |
21799 |
+ |
21800 |
+ return memblock_mark_nomap(base, size); |
21801 |
+@@ -969,18 +971,22 @@ static void __init early_init_dt_check_for_elfcorehdr(unsigned long node) |
21802 |
+ elfcorehdr_addr, elfcorehdr_size); |
21803 |
+ } |
21804 |
+ |
21805 |
+-static phys_addr_t cap_mem_addr; |
21806 |
+-static phys_addr_t cap_mem_size; |
21807 |
++static unsigned long chosen_node_offset = -FDT_ERR_NOTFOUND; |
21808 |
+ |
21809 |
+ /** |
21810 |
+ * early_init_dt_check_for_usable_mem_range - Decode usable memory range |
21811 |
+ * location from flat tree |
21812 |
+- * @node: reference to node containing usable memory range location ('chosen') |
21813 |
+ */ |
21814 |
+-static void __init early_init_dt_check_for_usable_mem_range(unsigned long node) |
21815 |
++void __init early_init_dt_check_for_usable_mem_range(void) |
21816 |
+ { |
21817 |
+ const __be32 *prop; |
21818 |
+ int len; |
21819 |
++ phys_addr_t cap_mem_addr; |
21820 |
++ phys_addr_t cap_mem_size; |
21821 |
++ unsigned long node = chosen_node_offset; |
21822 |
++ |
21823 |
++ if ((long)node < 0) |
21824 |
++ return; |
21825 |
+ |
21826 |
+ pr_debug("Looking for usable-memory-range property... "); |
21827 |
+ |
21828 |
+@@ -993,6 +999,8 @@ static void __init early_init_dt_check_for_usable_mem_range(unsigned long node) |
21829 |
+ |
21830 |
+ pr_debug("cap_mem_start=%pa cap_mem_size=%pa\n", &cap_mem_addr, |
21831 |
+ &cap_mem_size); |
21832 |
++ |
21833 |
++ memblock_cap_memory_range(cap_mem_addr, cap_mem_size); |
21834 |
+ } |
21835 |
+ |
21836 |
+ #ifdef CONFIG_SERIAL_EARLYCON |
21837 |
+@@ -1141,9 +1149,10 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, |
21838 |
+ (strcmp(uname, "chosen") != 0 && strcmp(uname, "chosen@0") != 0)) |
21839 |
+ return 0; |
21840 |
+ |
21841 |
++ chosen_node_offset = node; |
21842 |
++ |
21843 |
+ early_init_dt_check_for_initrd(node); |
21844 |
+ early_init_dt_check_for_elfcorehdr(node); |
21845 |
+- early_init_dt_check_for_usable_mem_range(node); |
21846 |
+ |
21847 |
+ /* Retrieve command line */ |
21848 |
+ p = of_get_flat_dt_prop(node, "bootargs", &l); |
21849 |
+@@ -1279,7 +1288,7 @@ void __init early_init_dt_scan_nodes(void) |
21850 |
+ of_scan_flat_dt(early_init_dt_scan_memory, NULL); |
21851 |
+ |
21852 |
+ /* Handle linux,usable-memory-range property */ |
21853 |
+- memblock_cap_memory_range(cap_mem_addr, cap_mem_size); |
21854 |
++ early_init_dt_check_for_usable_mem_range(); |
21855 |
+ } |
21856 |
+ |
21857 |
+ bool __init early_init_dt_scan(void *params) |
21858 |
+diff --git a/drivers/of/unittest.c b/drivers/of/unittest.c |
21859 |
+index 5b85a2a3792ae..2bee1d992408f 100644 |
21860 |
+--- a/drivers/of/unittest.c |
21861 |
++++ b/drivers/of/unittest.c |
21862 |
+@@ -911,11 +911,18 @@ static void __init of_unittest_dma_ranges_one(const char *path, |
21863 |
+ if (!rc) { |
21864 |
+ phys_addr_t paddr; |
21865 |
+ dma_addr_t dma_addr; |
21866 |
+- struct device dev_bogus; |
21867 |
++ struct device *dev_bogus; |
21868 |
+ |
21869 |
+- dev_bogus.dma_range_map = map; |
21870 |
+- paddr = dma_to_phys(&dev_bogus, expect_dma_addr); |
21871 |
+- dma_addr = phys_to_dma(&dev_bogus, expect_paddr); |
21872 |
++ dev_bogus = kzalloc(sizeof(struct device), GFP_KERNEL); |
21873 |
++ if (!dev_bogus) { |
21874 |
++ unittest(0, "kzalloc() failed\n"); |
21875 |
++ kfree(map); |
21876 |
++ return; |
21877 |
++ } |
21878 |
++ |
21879 |
++ dev_bogus->dma_range_map = map; |
21880 |
++ paddr = dma_to_phys(dev_bogus, expect_dma_addr); |
21881 |
++ dma_addr = phys_to_dma(dev_bogus, expect_paddr); |
21882 |
+ |
21883 |
+ unittest(paddr == expect_paddr, |
21884 |
+ "of_dma_get_range: wrong phys addr %pap (expecting %llx) on node %pOF\n", |
21885 |
+@@ -925,6 +932,7 @@ static void __init of_unittest_dma_ranges_one(const char *path, |
21886 |
+ &dma_addr, expect_dma_addr, np); |
21887 |
+ |
21888 |
+ kfree(map); |
21889 |
++ kfree(dev_bogus); |
21890 |
+ } |
21891 |
+ of_node_put(np); |
21892 |
+ #endif |
21893 |
+@@ -934,8 +942,9 @@ static void __init of_unittest_parse_dma_ranges(void) |
21894 |
+ { |
21895 |
+ of_unittest_dma_ranges_one("/testcase-data/address-tests/device@70000000", |
21896 |
+ 0x0, 0x20000000); |
21897 |
+- of_unittest_dma_ranges_one("/testcase-data/address-tests/bus@80000000/device@1000", |
21898 |
+- 0x100000000, 0x20000000); |
21899 |
++ if (IS_ENABLED(CONFIG_ARCH_DMA_ADDR_T_64BIT)) |
21900 |
++ of_unittest_dma_ranges_one("/testcase-data/address-tests/bus@80000000/device@1000", |
21901 |
++ 0x100000000, 0x20000000); |
21902 |
+ of_unittest_dma_ranges_one("/testcase-data/address-tests/pci@90000000", |
21903 |
+ 0x80000000, 0x20000000); |
21904 |
+ } |
21905 |
+diff --git a/drivers/parisc/pdc_stable.c b/drivers/parisc/pdc_stable.c |
21906 |
+index e090978518f1a..4760f82def6ec 100644 |
21907 |
+--- a/drivers/parisc/pdc_stable.c |
21908 |
++++ b/drivers/parisc/pdc_stable.c |
21909 |
+@@ -979,8 +979,10 @@ pdcs_register_pathentries(void) |
21910 |
+ entry->kobj.kset = paths_kset; |
21911 |
+ err = kobject_init_and_add(&entry->kobj, &ktype_pdcspath, NULL, |
21912 |
+ "%s", entry->name); |
21913 |
+- if (err) |
21914 |
++ if (err) { |
21915 |
++ kobject_put(&entry->kobj); |
21916 |
+ return err; |
21917 |
++ } |
21918 |
+ |
21919 |
+ /* kobject is now registered */ |
21920 |
+ write_lock(&entry->rw_lock); |
21921 |
+diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c |
21922 |
+index c3b725afa11fd..85323cbc4888a 100644 |
21923 |
+--- a/drivers/pci/controller/pci-aardvark.c |
21924 |
++++ b/drivers/pci/controller/pci-aardvark.c |
21925 |
+@@ -872,7 +872,6 @@ advk_pci_bridge_emul_pcie_conf_read(struct pci_bridge_emul *bridge, |
21926 |
+ return PCI_BRIDGE_EMUL_HANDLED; |
21927 |
+ } |
21928 |
+ |
21929 |
+- case PCI_CAP_LIST_ID: |
21930 |
+ case PCI_EXP_DEVCAP: |
21931 |
+ case PCI_EXP_DEVCTL: |
21932 |
+ *value = advk_readl(pcie, PCIE_CORE_PCIEXP_CAP + reg); |
21933 |
+@@ -953,6 +952,9 @@ static int advk_sw_pci_bridge_init(struct advk_pcie *pcie) |
21934 |
+ /* Support interrupt A for MSI feature */ |
21935 |
+ bridge->conf.intpin = PCIE_CORE_INT_A_ASSERT_ENABLE; |
21936 |
+ |
21937 |
++ /* Aardvark HW provides PCIe Capability structure in version 2 */ |
21938 |
++ bridge->pcie_conf.cap = cpu_to_le16(2); |
21939 |
++ |
21940 |
+ /* Indicates supports for Completion Retry Status */ |
21941 |
+ bridge->pcie_conf.rootcap = cpu_to_le16(PCI_EXP_RTCAP_CRSVIS); |
21942 |
+ |
21943 |
+diff --git a/drivers/pci/controller/pci-mvebu.c b/drivers/pci/controller/pci-mvebu.c |
21944 |
+index ed13e81cd691d..2dc6890dbcaa2 100644 |
21945 |
+--- a/drivers/pci/controller/pci-mvebu.c |
21946 |
++++ b/drivers/pci/controller/pci-mvebu.c |
21947 |
+@@ -573,6 +573,8 @@ static struct pci_bridge_emul_ops mvebu_pci_bridge_emul_ops = { |
21948 |
+ static void mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port) |
21949 |
+ { |
21950 |
+ struct pci_bridge_emul *bridge = &port->bridge; |
21951 |
++ u32 pcie_cap = mvebu_readl(port, PCIE_CAP_PCIEXP); |
21952 |
++ u8 pcie_cap_ver = ((pcie_cap >> 16) & PCI_EXP_FLAGS_VERS); |
21953 |
+ |
21954 |
+ bridge->conf.vendor = PCI_VENDOR_ID_MARVELL; |
21955 |
+ bridge->conf.device = mvebu_readl(port, PCIE_DEV_ID_OFF) >> 16; |
21956 |
+@@ -585,6 +587,12 @@ static void mvebu_pci_bridge_emul_init(struct mvebu_pcie_port *port) |
21957 |
+ bridge->conf.iolimit = PCI_IO_RANGE_TYPE_32; |
21958 |
+ } |
21959 |
+ |
21960 |
++ /* |
21961 |
++ * Older mvebu hardware provides PCIe Capability structure only in |
21962 |
++ * version 1. New hardware provides it in version 2. |
21963 |
++ */ |
21964 |
++ bridge->pcie_conf.cap = cpu_to_le16(pcie_cap_ver); |
21965 |
++ |
21966 |
+ bridge->has_pcie = true; |
21967 |
+ bridge->data = port; |
21968 |
+ bridge->ops = &mvebu_pci_bridge_emul_ops; |
21969 |
+diff --git a/drivers/pci/controller/pci-xgene.c b/drivers/pci/controller/pci-xgene.c |
21970 |
+index e64536047b651..7d7d8970fdc25 100644 |
21971 |
+--- a/drivers/pci/controller/pci-xgene.c |
21972 |
++++ b/drivers/pci/controller/pci-xgene.c |
21973 |
+@@ -466,7 +466,7 @@ static int xgene_pcie_select_ib_reg(u8 *ib_reg_mask, u64 size) |
21974 |
+ return 1; |
21975 |
+ } |
21976 |
+ |
21977 |
+- if ((size > SZ_1K) && (size < SZ_1T) && !(*ib_reg_mask & (1 << 0))) { |
21978 |
++ if ((size > SZ_1K) && (size < SZ_4G) && !(*ib_reg_mask & (1 << 0))) { |
21979 |
+ *ib_reg_mask |= (1 << 0); |
21980 |
+ return 0; |
21981 |
+ } |
21982 |
+diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h |
21983 |
+index 69fd401691be6..10d7e7e1b5530 100644 |
21984 |
+--- a/drivers/pci/hotplug/pciehp.h |
21985 |
++++ b/drivers/pci/hotplug/pciehp.h |
21986 |
+@@ -75,6 +75,8 @@ extern int pciehp_poll_time; |
21987 |
+ * @reset_lock: prevents access to the Data Link Layer Link Active bit in the |
21988 |
+ * Link Status register and to the Presence Detect State bit in the Slot |
21989 |
+ * Status register during a slot reset which may cause them to flap |
21990 |
++ * @depth: Number of additional hotplug ports in the path to the root bus, |
21991 |
++ * used as lock subclass for @reset_lock |
21992 |
+ * @ist_running: flag to keep user request waiting while IRQ thread is running |
21993 |
+ * @request_result: result of last user request submitted to the IRQ thread |
21994 |
+ * @requester: wait queue to wake up on completion of user request, |
21995 |
+@@ -106,6 +108,7 @@ struct controller { |
21996 |
+ |
21997 |
+ struct hotplug_slot hotplug_slot; /* hotplug core interface */ |
21998 |
+ struct rw_semaphore reset_lock; |
21999 |
++ unsigned int depth; |
22000 |
+ unsigned int ist_running; |
22001 |
+ int request_result; |
22002 |
+ wait_queue_head_t requester; |
22003 |
+diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c |
22004 |
+index ad3393930ecb4..e7fe4b42f0394 100644 |
22005 |
+--- a/drivers/pci/hotplug/pciehp_core.c |
22006 |
++++ b/drivers/pci/hotplug/pciehp_core.c |
22007 |
+@@ -166,7 +166,7 @@ static void pciehp_check_presence(struct controller *ctrl) |
22008 |
+ { |
22009 |
+ int occupied; |
22010 |
+ |
22011 |
+- down_read(&ctrl->reset_lock); |
22012 |
++ down_read_nested(&ctrl->reset_lock, ctrl->depth); |
22013 |
+ mutex_lock(&ctrl->state_lock); |
22014 |
+ |
22015 |
+ occupied = pciehp_card_present_or_link_active(ctrl); |
22016 |
+diff --git a/drivers/pci/hotplug/pciehp_hpc.c b/drivers/pci/hotplug/pciehp_hpc.c |
22017 |
+index 3024d7e85e6a7..3a46227e2c73e 100644 |
22018 |
+--- a/drivers/pci/hotplug/pciehp_hpc.c |
22019 |
++++ b/drivers/pci/hotplug/pciehp_hpc.c |
22020 |
+@@ -583,7 +583,7 @@ static void pciehp_ignore_dpc_link_change(struct controller *ctrl, |
22021 |
+ * the corresponding link change may have been ignored above. |
22022 |
+ * Synthesize it to ensure that it is acted on. |
22023 |
+ */ |
22024 |
+- down_read(&ctrl->reset_lock); |
22025 |
++ down_read_nested(&ctrl->reset_lock, ctrl->depth); |
22026 |
+ if (!pciehp_check_link_active(ctrl)) |
22027 |
+ pciehp_request(ctrl, PCI_EXP_SLTSTA_DLLSC); |
22028 |
+ up_read(&ctrl->reset_lock); |
22029 |
+@@ -746,7 +746,7 @@ static irqreturn_t pciehp_ist(int irq, void *dev_id) |
22030 |
+ * Disable requests have higher priority than Presence Detect Changed |
22031 |
+ * or Data Link Layer State Changed events. |
22032 |
+ */ |
22033 |
+- down_read(&ctrl->reset_lock); |
22034 |
++ down_read_nested(&ctrl->reset_lock, ctrl->depth); |
22035 |
+ if (events & DISABLE_SLOT) |
22036 |
+ pciehp_handle_disable_request(ctrl); |
22037 |
+ else if (events & (PCI_EXP_SLTSTA_PDC | PCI_EXP_SLTSTA_DLLSC)) |
22038 |
+@@ -880,7 +880,7 @@ int pciehp_reset_slot(struct hotplug_slot *hotplug_slot, bool probe) |
22039 |
+ if (probe) |
22040 |
+ return 0; |
22041 |
+ |
22042 |
+- down_write(&ctrl->reset_lock); |
22043 |
++ down_write_nested(&ctrl->reset_lock, ctrl->depth); |
22044 |
+ |
22045 |
+ if (!ATTN_BUTTN(ctrl)) { |
22046 |
+ ctrl_mask |= PCI_EXP_SLTCTL_PDCE; |
22047 |
+@@ -936,6 +936,20 @@ static inline void dbg_ctrl(struct controller *ctrl) |
22048 |
+ |
22049 |
+ #define FLAG(x, y) (((x) & (y)) ? '+' : '-') |
22050 |
+ |
22051 |
++static inline int pcie_hotplug_depth(struct pci_dev *dev) |
22052 |
++{ |
22053 |
++ struct pci_bus *bus = dev->bus; |
22054 |
++ int depth = 0; |
22055 |
++ |
22056 |
++ while (bus->parent) { |
22057 |
++ bus = bus->parent; |
22058 |
++ if (bus->self && bus->self->is_hotplug_bridge) |
22059 |
++ depth++; |
22060 |
++ } |
22061 |
++ |
22062 |
++ return depth; |
22063 |
++} |
22064 |
++ |
22065 |
+ struct controller *pcie_init(struct pcie_device *dev) |
22066 |
+ { |
22067 |
+ struct controller *ctrl; |
22068 |
+@@ -949,6 +963,7 @@ struct controller *pcie_init(struct pcie_device *dev) |
22069 |
+ return NULL; |
22070 |
+ |
22071 |
+ ctrl->pcie = dev; |
22072 |
++ ctrl->depth = pcie_hotplug_depth(dev->port); |
22073 |
+ pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, &slot_cap); |
22074 |
+ |
22075 |
+ if (pdev->hotplug_user_indicators) |
22076 |
+diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c |
22077 |
+index e11530cb05699..cc4c2b8a5efd7 100644 |
22078 |
+--- a/drivers/pci/msi.c |
22079 |
++++ b/drivers/pci/msi.c |
22080 |
+@@ -1193,19 +1193,24 @@ EXPORT_SYMBOL(pci_free_irq_vectors); |
22081 |
+ |
22082 |
+ /** |
22083 |
+ * pci_irq_vector - return Linux IRQ number of a device vector |
22084 |
+- * @dev: PCI device to operate on |
22085 |
+- * @nr: device-relative interrupt vector index (0-based). |
22086 |
++ * @dev: PCI device to operate on |
22087 |
++ * @nr: Interrupt vector index (0-based) |
22088 |
++ * |
22089 |
++ * @nr has the following meanings depending on the interrupt mode: |
22090 |
++ * MSI-X: The index in the MSI-X vector table |
22091 |
++ * MSI: The index of the enabled MSI vectors |
22092 |
++ * INTx: Must be 0 |
22093 |
++ * |
22094 |
++ * Return: The Linux interrupt number or -EINVAl if @nr is out of range. |
22095 |
+ */ |
22096 |
+ int pci_irq_vector(struct pci_dev *dev, unsigned int nr) |
22097 |
+ { |
22098 |
+ if (dev->msix_enabled) { |
22099 |
+ struct msi_desc *entry; |
22100 |
+- int i = 0; |
22101 |
+ |
22102 |
+ for_each_pci_msi_entry(entry, dev) { |
22103 |
+- if (i == nr) |
22104 |
++ if (entry->msi_attrib.entry_nr == nr) |
22105 |
+ return entry->irq; |
22106 |
+- i++; |
22107 |
+ } |
22108 |
+ WARN_ON_ONCE(1); |
22109 |
+ return -EINVAL; |
22110 |
+@@ -1229,17 +1234,22 @@ EXPORT_SYMBOL(pci_irq_vector); |
22111 |
+ * pci_irq_get_affinity - return the affinity of a particular MSI vector |
22112 |
+ * @dev: PCI device to operate on |
22113 |
+ * @nr: device-relative interrupt vector index (0-based). |
22114 |
++ * |
22115 |
++ * @nr has the following meanings depending on the interrupt mode: |
22116 |
++ * MSI-X: The index in the MSI-X vector table |
22117 |
++ * MSI: The index of the enabled MSI vectors |
22118 |
++ * INTx: Must be 0 |
22119 |
++ * |
22120 |
++ * Return: A cpumask pointer or NULL if @nr is out of range |
22121 |
+ */ |
22122 |
+ const struct cpumask *pci_irq_get_affinity(struct pci_dev *dev, int nr) |
22123 |
+ { |
22124 |
+ if (dev->msix_enabled) { |
22125 |
+ struct msi_desc *entry; |
22126 |
+- int i = 0; |
22127 |
+ |
22128 |
+ for_each_pci_msi_entry(entry, dev) { |
22129 |
+- if (i == nr) |
22130 |
++ if (entry->msi_attrib.entry_nr == nr) |
22131 |
+ return &entry->affinity->mask; |
22132 |
+- i++; |
22133 |
+ } |
22134 |
+ WARN_ON_ONCE(1); |
22135 |
+ return NULL; |
22136 |
+diff --git a/drivers/pci/pci-bridge-emul.c b/drivers/pci/pci-bridge-emul.c |
22137 |
+index db97cddfc85e1..37504c2cce9b8 100644 |
22138 |
+--- a/drivers/pci/pci-bridge-emul.c |
22139 |
++++ b/drivers/pci/pci-bridge-emul.c |
22140 |
+@@ -139,8 +139,13 @@ struct pci_bridge_reg_behavior pci_regs_behavior[PCI_STD_HEADER_SIZEOF / 4] = { |
22141 |
+ .ro = GENMASK(7, 0), |
22142 |
+ }, |
22143 |
+ |
22144 |
++ /* |
22145 |
++ * If expansion ROM is unsupported then ROM Base Address register must |
22146 |
++ * be implemented as read-only register that return 0 when read, same |
22147 |
++ * as for unused Base Address registers. |
22148 |
++ */ |
22149 |
+ [PCI_ROM_ADDRESS1 / 4] = { |
22150 |
+- .rw = GENMASK(31, 11) | BIT(0), |
22151 |
++ .ro = ~0, |
22152 |
+ }, |
22153 |
+ |
22154 |
+ /* |
22155 |
+@@ -171,41 +176,55 @@ struct pci_bridge_reg_behavior pcie_cap_regs_behavior[PCI_CAP_PCIE_SIZEOF / 4] = |
22156 |
+ [PCI_CAP_LIST_ID / 4] = { |
22157 |
+ /* |
22158 |
+ * Capability ID, Next Capability Pointer and |
22159 |
+- * Capabilities register are all read-only. |
22160 |
++ * bits [14:0] of Capabilities register are all read-only. |
22161 |
++ * Bit 15 of Capabilities register is reserved. |
22162 |
+ */ |
22163 |
+- .ro = ~0, |
22164 |
++ .ro = GENMASK(30, 0), |
22165 |
+ }, |
22166 |
+ |
22167 |
+ [PCI_EXP_DEVCAP / 4] = { |
22168 |
+- .ro = ~0, |
22169 |
++ /* |
22170 |
++ * Bits [31:29] and [17:16] are reserved. |
22171 |
++ * Bits [27:18] are reserved for non-upstream ports. |
22172 |
++ * Bits 28 and [14:6] are reserved for non-endpoint devices. |
22173 |
++ * Other bits are read-only. |
22174 |
++ */ |
22175 |
++ .ro = BIT(15) | GENMASK(5, 0), |
22176 |
+ }, |
22177 |
+ |
22178 |
+ [PCI_EXP_DEVCTL / 4] = { |
22179 |
+- /* Device control register is RW */ |
22180 |
+- .rw = GENMASK(15, 0), |
22181 |
++ /* |
22182 |
++ * Device control register is RW, except bit 15 which is |
22183 |
++ * reserved for non-endpoints or non-PCIe-to-PCI/X bridges. |
22184 |
++ */ |
22185 |
++ .rw = GENMASK(14, 0), |
22186 |
+ |
22187 |
+ /* |
22188 |
+ * Device status register has bits 6 and [3:0] W1C, [5:4] RO, |
22189 |
+- * the rest is reserved |
22190 |
++ * the rest is reserved. Also bit 6 is reserved for non-upstream |
22191 |
++ * ports. |
22192 |
+ */ |
22193 |
+- .w1c = (BIT(6) | GENMASK(3, 0)) << 16, |
22194 |
++ .w1c = GENMASK(3, 0) << 16, |
22195 |
+ .ro = GENMASK(5, 4) << 16, |
22196 |
+ }, |
22197 |
+ |
22198 |
+ [PCI_EXP_LNKCAP / 4] = { |
22199 |
+- /* All bits are RO, except bit 23 which is reserved */ |
22200 |
+- .ro = lower_32_bits(~BIT(23)), |
22201 |
++ /* |
22202 |
++ * All bits are RO, except bit 23 which is reserved and |
22203 |
++ * bit 18 which is reserved for non-upstream ports. |
22204 |
++ */ |
22205 |
++ .ro = lower_32_bits(~(BIT(23) | PCI_EXP_LNKCAP_CLKPM)), |
22206 |
+ }, |
22207 |
+ |
22208 |
+ [PCI_EXP_LNKCTL / 4] = { |
22209 |
+ /* |
22210 |
+ * Link control has bits [15:14], [11:3] and [1:0] RW, the |
22211 |
+- * rest is reserved. |
22212 |
++ * rest is reserved. Bit 8 is reserved for non-upstream ports. |
22213 |
+ * |
22214 |
+ * Link status has bits [13:0] RO, and bits [15:14] |
22215 |
+ * W1C. |
22216 |
+ */ |
22217 |
+- .rw = GENMASK(15, 14) | GENMASK(11, 3) | GENMASK(1, 0), |
22218 |
++ .rw = GENMASK(15, 14) | GENMASK(11, 9) | GENMASK(7, 3) | GENMASK(1, 0), |
22219 |
+ .ro = GENMASK(13, 0) << 16, |
22220 |
+ .w1c = GENMASK(15, 14) << 16, |
22221 |
+ }, |
22222 |
+@@ -277,11 +296,9 @@ int pci_bridge_emul_init(struct pci_bridge_emul *bridge, |
22223 |
+ |
22224 |
+ if (bridge->has_pcie) { |
22225 |
+ bridge->conf.capabilities_pointer = PCI_CAP_PCIE_START; |
22226 |
++ bridge->conf.status |= cpu_to_le16(PCI_STATUS_CAP_LIST); |
22227 |
+ bridge->pcie_conf.cap_id = PCI_CAP_ID_EXP; |
22228 |
+- /* Set PCIe v2, root port, slot support */ |
22229 |
+- bridge->pcie_conf.cap = |
22230 |
+- cpu_to_le16(PCI_EXP_TYPE_ROOT_PORT << 4 | 2 | |
22231 |
+- PCI_EXP_FLAGS_SLOT); |
22232 |
++ bridge->pcie_conf.cap |= cpu_to_le16(PCI_EXP_TYPE_ROOT_PORT << 4); |
22233 |
+ bridge->pcie_cap_regs_behavior = |
22234 |
+ kmemdup(pcie_cap_regs_behavior, |
22235 |
+ sizeof(pcie_cap_regs_behavior), |
22236 |
+@@ -290,6 +307,27 @@ int pci_bridge_emul_init(struct pci_bridge_emul *bridge, |
22237 |
+ kfree(bridge->pci_regs_behavior); |
22238 |
+ return -ENOMEM; |
22239 |
+ } |
22240 |
++ /* These bits are applicable only for PCI and reserved on PCIe */ |
22241 |
++ bridge->pci_regs_behavior[PCI_CACHE_LINE_SIZE / 4].ro &= |
22242 |
++ ~GENMASK(15, 8); |
22243 |
++ bridge->pci_regs_behavior[PCI_COMMAND / 4].ro &= |
22244 |
++ ~((PCI_COMMAND_SPECIAL | PCI_COMMAND_INVALIDATE | |
22245 |
++ PCI_COMMAND_VGA_PALETTE | PCI_COMMAND_WAIT | |
22246 |
++ PCI_COMMAND_FAST_BACK) | |
22247 |
++ (PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK | |
22248 |
++ PCI_STATUS_DEVSEL_MASK) << 16); |
22249 |
++ bridge->pci_regs_behavior[PCI_PRIMARY_BUS / 4].ro &= |
22250 |
++ ~GENMASK(31, 24); |
22251 |
++ bridge->pci_regs_behavior[PCI_IO_BASE / 4].ro &= |
22252 |
++ ~((PCI_STATUS_66MHZ | PCI_STATUS_FAST_BACK | |
22253 |
++ PCI_STATUS_DEVSEL_MASK) << 16); |
22254 |
++ bridge->pci_regs_behavior[PCI_INTERRUPT_LINE / 4].rw &= |
22255 |
++ ~((PCI_BRIDGE_CTL_MASTER_ABORT | |
22256 |
++ BIT(8) | BIT(9) | BIT(11)) << 16); |
22257 |
++ bridge->pci_regs_behavior[PCI_INTERRUPT_LINE / 4].ro &= |
22258 |
++ ~((PCI_BRIDGE_CTL_FAST_BACK) << 16); |
22259 |
++ bridge->pci_regs_behavior[PCI_INTERRUPT_LINE / 4].w1c &= |
22260 |
++ ~(BIT(10) << 16); |
22261 |
+ } |
22262 |
+ |
22263 |
+ if (flags & PCI_BRIDGE_EMUL_NO_PREFETCHABLE_BAR) { |
22264 |
+diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c |
22265 |
+index 208fa03acdda0..0663762ea69db 100644 |
22266 |
+--- a/drivers/pci/quirks.c |
22267 |
++++ b/drivers/pci/quirks.c |
22268 |
+@@ -4103,6 +4103,9 @@ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9120, |
22269 |
+ quirk_dma_func1_alias); |
22270 |
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9123, |
22271 |
+ quirk_dma_func1_alias); |
22272 |
++/* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c136 */ |
22273 |
++DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9125, |
22274 |
++ quirk_dma_func1_alias); |
22275 |
+ DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_MARVELL_EXT, 0x9128, |
22276 |
+ quirk_dma_func1_alias); |
22277 |
+ /* https://bugzilla.kernel.org/show_bug.cgi?id=42679#c14 */ |
22278 |
+diff --git a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c |
22279 |
+index e211e2619680c..f70197154a362 100644 |
22280 |
+--- a/drivers/pcmcia/cs.c |
22281 |
++++ b/drivers/pcmcia/cs.c |
22282 |
+@@ -666,18 +666,16 @@ static int pccardd(void *__skt) |
22283 |
+ if (events || sysfs_events) |
22284 |
+ continue; |
22285 |
+ |
22286 |
++ set_current_state(TASK_INTERRUPTIBLE); |
22287 |
+ if (kthread_should_stop()) |
22288 |
+ break; |
22289 |
+ |
22290 |
+- set_current_state(TASK_INTERRUPTIBLE); |
22291 |
+- |
22292 |
+ schedule(); |
22293 |
+ |
22294 |
+- /* make sure we are running */ |
22295 |
+- __set_current_state(TASK_RUNNING); |
22296 |
+- |
22297 |
+ try_to_freeze(); |
22298 |
+ } |
22299 |
++ /* make sure we are running before we exit */ |
22300 |
++ __set_current_state(TASK_RUNNING); |
22301 |
+ |
22302 |
+ /* shut down socket, if a device is still present */ |
22303 |
+ if (skt->state & SOCKET_PRESENT) { |
22304 |
+diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c |
22305 |
+index bb15a8bdbaab5..1cac528707111 100644 |
22306 |
+--- a/drivers/pcmcia/rsrc_nonstatic.c |
22307 |
++++ b/drivers/pcmcia/rsrc_nonstatic.c |
22308 |
+@@ -690,6 +690,9 @@ static struct resource *__nonstatic_find_io_region(struct pcmcia_socket *s, |
22309 |
+ unsigned long min = base; |
22310 |
+ int ret; |
22311 |
+ |
22312 |
++ if (!res) |
22313 |
++ return NULL; |
22314 |
++ |
22315 |
+ data.mask = align - 1; |
22316 |
+ data.offset = base & data.mask; |
22317 |
+ data.map = &s_data->io_db; |
22318 |
+@@ -809,6 +812,9 @@ static struct resource *nonstatic_find_mem_region(u_long base, u_long num, |
22319 |
+ unsigned long min, max; |
22320 |
+ int ret, i, j; |
22321 |
+ |
22322 |
++ if (!res) |
22323 |
++ return NULL; |
22324 |
++ |
22325 |
+ low = low || !(s->features & SS_CAP_PAGE_REGS); |
22326 |
+ |
22327 |
+ data.mask = align - 1; |
22328 |
+diff --git a/drivers/perf/arm-cmn.c b/drivers/perf/arm-cmn.c |
22329 |
+index bc3cba5f8c5dc..400eb7f579dce 100644 |
22330 |
+--- a/drivers/perf/arm-cmn.c |
22331 |
++++ b/drivers/perf/arm-cmn.c |
22332 |
+@@ -1561,7 +1561,8 @@ static int arm_cmn_probe(struct platform_device *pdev) |
22333 |
+ |
22334 |
+ err = perf_pmu_register(&cmn->pmu, name, -1); |
22335 |
+ if (err) |
22336 |
+- cpuhp_state_remove_instance(arm_cmn_hp_state, &cmn->cpuhp_node); |
22337 |
++ cpuhp_state_remove_instance_nocalls(arm_cmn_hp_state, &cmn->cpuhp_node); |
22338 |
++ |
22339 |
+ return err; |
22340 |
+ } |
22341 |
+ |
22342 |
+@@ -1572,7 +1573,7 @@ static int arm_cmn_remove(struct platform_device *pdev) |
22343 |
+ writel_relaxed(0, cmn->dtc[0].base + CMN_DT_DTC_CTL); |
22344 |
+ |
22345 |
+ perf_pmu_unregister(&cmn->pmu); |
22346 |
+- cpuhp_state_remove_instance(arm_cmn_hp_state, &cmn->cpuhp_node); |
22347 |
++ cpuhp_state_remove_instance_nocalls(arm_cmn_hp_state, &cmn->cpuhp_node); |
22348 |
+ return 0; |
22349 |
+ } |
22350 |
+ |
22351 |
+diff --git a/drivers/phy/cadence/phy-cadence-sierra.c b/drivers/phy/cadence/phy-cadence-sierra.c |
22352 |
+index e93818e3991fd..3e2d096d54fd7 100644 |
22353 |
+--- a/drivers/phy/cadence/phy-cadence-sierra.c |
22354 |
++++ b/drivers/phy/cadence/phy-cadence-sierra.c |
22355 |
+@@ -215,7 +215,10 @@ static const int pll_mux_parent_index[][SIERRA_NUM_CMN_PLLC_PARENTS] = { |
22356 |
+ [CMN_PLLLC1] = { PLL1_REFCLK, PLL0_REFCLK }, |
22357 |
+ }; |
22358 |
+ |
22359 |
+-static u32 cdns_sierra_pll_mux_table[] = { 0, 1 }; |
22360 |
++static u32 cdns_sierra_pll_mux_table[][SIERRA_NUM_CMN_PLLC_PARENTS] = { |
22361 |
++ [CMN_PLLLC] = { 0, 1 }, |
22362 |
++ [CMN_PLLLC1] = { 1, 0 }, |
22363 |
++}; |
22364 |
+ |
22365 |
+ struct cdns_sierra_inst { |
22366 |
+ struct phy *phy; |
22367 |
+@@ -436,11 +439,25 @@ static const struct phy_ops ops = { |
22368 |
+ static u8 cdns_sierra_pll_mux_get_parent(struct clk_hw *hw) |
22369 |
+ { |
22370 |
+ struct cdns_sierra_pll_mux *mux = to_cdns_sierra_pll_mux(hw); |
22371 |
++ struct regmap_field *plllc1en_field = mux->plllc1en_field; |
22372 |
++ struct regmap_field *termen_field = mux->termen_field; |
22373 |
+ struct regmap_field *field = mux->pfdclk_sel_preg; |
22374 |
+ unsigned int val; |
22375 |
++ int index; |
22376 |
+ |
22377 |
+ regmap_field_read(field, &val); |
22378 |
+- return clk_mux_val_to_index(hw, cdns_sierra_pll_mux_table, 0, val); |
22379 |
++ |
22380 |
++ if (strstr(clk_hw_get_name(hw), clk_names[CDNS_SIERRA_PLL_CMNLC1])) { |
22381 |
++ index = clk_mux_val_to_index(hw, cdns_sierra_pll_mux_table[CMN_PLLLC1], 0, val); |
22382 |
++ if (index == 1) { |
22383 |
++ regmap_field_write(plllc1en_field, 1); |
22384 |
++ regmap_field_write(termen_field, 1); |
22385 |
++ } |
22386 |
++ } else { |
22387 |
++ index = clk_mux_val_to_index(hw, cdns_sierra_pll_mux_table[CMN_PLLLC], 0, val); |
22388 |
++ } |
22389 |
++ |
22390 |
++ return index; |
22391 |
+ } |
22392 |
+ |
22393 |
+ static int cdns_sierra_pll_mux_set_parent(struct clk_hw *hw, u8 index) |
22394 |
+@@ -458,7 +475,11 @@ static int cdns_sierra_pll_mux_set_parent(struct clk_hw *hw, u8 index) |
22395 |
+ ret |= regmap_field_write(termen_field, 1); |
22396 |
+ } |
22397 |
+ |
22398 |
+- val = cdns_sierra_pll_mux_table[index]; |
22399 |
++ if (strstr(clk_hw_get_name(hw), clk_names[CDNS_SIERRA_PLL_CMNLC1])) |
22400 |
++ val = cdns_sierra_pll_mux_table[CMN_PLLLC1][index]; |
22401 |
++ else |
22402 |
++ val = cdns_sierra_pll_mux_table[CMN_PLLLC][index]; |
22403 |
++ |
22404 |
+ ret |= regmap_field_write(field, val); |
22405 |
+ |
22406 |
+ return ret; |
22407 |
+@@ -496,8 +517,8 @@ static int cdns_sierra_pll_mux_register(struct cdns_sierra_phy *sp, |
22408 |
+ for (i = 0; i < num_parents; i++) { |
22409 |
+ clk = sp->input_clks[pll_mux_parent_index[clk_index][i]]; |
22410 |
+ if (IS_ERR_OR_NULL(clk)) { |
22411 |
+- dev_err(dev, "No parent clock for derived_refclk\n"); |
22412 |
+- return PTR_ERR(clk); |
22413 |
++ dev_err(dev, "No parent clock for PLL mux clocks\n"); |
22414 |
++ return IS_ERR(clk) ? PTR_ERR(clk) : -ENOENT; |
22415 |
+ } |
22416 |
+ parent_names[i] = __clk_get_name(clk); |
22417 |
+ } |
22418 |
+diff --git a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c |
22419 |
+index 28ad9403c4414..67b005d5b9e35 100644 |
22420 |
+--- a/drivers/phy/mediatek/phy-mtk-mipi-dsi.c |
22421 |
++++ b/drivers/phy/mediatek/phy-mtk-mipi-dsi.c |
22422 |
+@@ -146,6 +146,8 @@ static int mtk_mipi_tx_probe(struct platform_device *pdev) |
22423 |
+ return -ENOMEM; |
22424 |
+ |
22425 |
+ mipi_tx->driver_data = of_device_get_match_data(dev); |
22426 |
++ if (!mipi_tx->driver_data) |
22427 |
++ return -ENODEV; |
22428 |
+ |
22429 |
+ mipi_tx->regs = devm_platform_ioremap_resource(pdev, 0); |
22430 |
+ if (IS_ERR(mipi_tx->regs)) |
22431 |
+diff --git a/drivers/phy/mediatek/phy-mtk-tphy.c b/drivers/phy/mediatek/phy-mtk-tphy.c |
22432 |
+index cdcef865fe9e5..98a942c607a67 100644 |
22433 |
+--- a/drivers/phy/mediatek/phy-mtk-tphy.c |
22434 |
++++ b/drivers/phy/mediatek/phy-mtk-tphy.c |
22435 |
+@@ -12,6 +12,7 @@ |
22436 |
+ #include <linux/iopoll.h> |
22437 |
+ #include <linux/mfd/syscon.h> |
22438 |
+ #include <linux/module.h> |
22439 |
++#include <linux/nvmem-consumer.h> |
22440 |
+ #include <linux/of_address.h> |
22441 |
+ #include <linux/of_device.h> |
22442 |
+ #include <linux/phy/phy.h> |
22443 |
+@@ -41,6 +42,9 @@ |
22444 |
+ #define SSUSB_SIFSLV_V2_U3PHYD 0x200 |
22445 |
+ #define SSUSB_SIFSLV_V2_U3PHYA 0x400 |
22446 |
+ |
22447 |
++#define U3P_MISC_REG1 0x04 |
22448 |
++#define MR1_EFUSE_AUTO_LOAD_DIS BIT(6) |
22449 |
++ |
22450 |
+ #define U3P_USBPHYACR0 0x000 |
22451 |
+ #define PA0_RG_U2PLL_FORCE_ON BIT(15) |
22452 |
+ #define PA0_USB20_PLL_PREDIV GENMASK(7, 6) |
22453 |
+@@ -133,6 +137,8 @@ |
22454 |
+ #define P3C_RG_SWRST_U3_PHYD_FORCE_EN BIT(24) |
22455 |
+ |
22456 |
+ #define U3P_U3_PHYA_REG0 0x000 |
22457 |
++#define P3A_RG_IEXT_INTR GENMASK(15, 10) |
22458 |
++#define P3A_RG_IEXT_INTR_VAL(x) ((0x3f & (x)) << 10) |
22459 |
+ #define P3A_RG_CLKDRV_OFF GENMASK(3, 2) |
22460 |
+ #define P3A_RG_CLKDRV_OFF_VAL(x) ((0x3 & (x)) << 2) |
22461 |
+ |
22462 |
+@@ -187,6 +193,19 @@ |
22463 |
+ #define P3D_RG_FWAKE_TH GENMASK(21, 16) |
22464 |
+ #define P3D_RG_FWAKE_TH_VAL(x) ((0x3f & (x)) << 16) |
22465 |
+ |
22466 |
++#define U3P_U3_PHYD_IMPCAL0 0x010 |
22467 |
++#define P3D_RG_FORCE_TX_IMPEL BIT(31) |
22468 |
++#define P3D_RG_TX_IMPEL GENMASK(28, 24) |
22469 |
++#define P3D_RG_TX_IMPEL_VAL(x) ((0x1f & (x)) << 24) |
22470 |
++ |
22471 |
++#define U3P_U3_PHYD_IMPCAL1 0x014 |
22472 |
++#define P3D_RG_FORCE_RX_IMPEL BIT(31) |
22473 |
++#define P3D_RG_RX_IMPEL GENMASK(28, 24) |
22474 |
++#define P3D_RG_RX_IMPEL_VAL(x) ((0x1f & (x)) << 24) |
22475 |
++ |
22476 |
++#define U3P_U3_PHYD_RSV 0x054 |
22477 |
++#define P3D_RG_EFUSE_AUTO_LOAD_DIS BIT(12) |
22478 |
++ |
22479 |
+ #define U3P_U3_PHYD_CDR1 0x05c |
22480 |
+ #define P3D_RG_CDR_BIR_LTD1 GENMASK(28, 24) |
22481 |
+ #define P3D_RG_CDR_BIR_LTD1_VAL(x) ((0x1f & (x)) << 24) |
22482 |
+@@ -307,6 +326,11 @@ struct mtk_phy_pdata { |
22483 |
+ * 48M PLL, fix it by switching PLL to 26M from default 48M |
22484 |
+ */ |
22485 |
+ bool sw_pll_48m_to_26m; |
22486 |
++ /* |
22487 |
++ * Some SoCs (e.g. mt8195) drop a bit when use auto load efuse, |
22488 |
++ * support sw way, also support it for v2/v3 optionally. |
22489 |
++ */ |
22490 |
++ bool sw_efuse_supported; |
22491 |
+ enum mtk_phy_version version; |
22492 |
+ }; |
22493 |
+ |
22494 |
+@@ -336,6 +360,10 @@ struct mtk_phy_instance { |
22495 |
+ struct regmap *type_sw; |
22496 |
+ u32 type_sw_reg; |
22497 |
+ u32 type_sw_index; |
22498 |
++ u32 efuse_sw_en; |
22499 |
++ u32 efuse_intr; |
22500 |
++ u32 efuse_tx_imp; |
22501 |
++ u32 efuse_rx_imp; |
22502 |
+ int eye_src; |
22503 |
+ int eye_vrt; |
22504 |
+ int eye_term; |
22505 |
+@@ -1040,6 +1068,130 @@ static int phy_type_set(struct mtk_phy_instance *instance) |
22506 |
+ return 0; |
22507 |
+ } |
22508 |
+ |
22509 |
++static int phy_efuse_get(struct mtk_tphy *tphy, struct mtk_phy_instance *instance) |
22510 |
++{ |
22511 |
++ struct device *dev = &instance->phy->dev; |
22512 |
++ int ret = 0; |
22513 |
++ |
22514 |
++ /* tphy v1 doesn't support sw efuse, skip it */ |
22515 |
++ if (!tphy->pdata->sw_efuse_supported) { |
22516 |
++ instance->efuse_sw_en = 0; |
22517 |
++ return 0; |
22518 |
++ } |
22519 |
++ |
22520 |
++ /* software efuse is optional */ |
22521 |
++ instance->efuse_sw_en = device_property_read_bool(dev, "nvmem-cells"); |
22522 |
++ if (!instance->efuse_sw_en) |
22523 |
++ return 0; |
22524 |
++ |
22525 |
++ switch (instance->type) { |
22526 |
++ case PHY_TYPE_USB2: |
22527 |
++ ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr); |
22528 |
++ if (ret) { |
22529 |
++ dev_err(dev, "fail to get u2 intr efuse, %d\n", ret); |
22530 |
++ break; |
22531 |
++ } |
22532 |
++ |
22533 |
++ /* no efuse, ignore it */ |
22534 |
++ if (!instance->efuse_intr) { |
22535 |
++ dev_warn(dev, "no u2 intr efuse, but dts enable it\n"); |
22536 |
++ instance->efuse_sw_en = 0; |
22537 |
++ break; |
22538 |
++ } |
22539 |
++ |
22540 |
++ dev_dbg(dev, "u2 efuse - intr %x\n", instance->efuse_intr); |
22541 |
++ break; |
22542 |
++ |
22543 |
++ case PHY_TYPE_USB3: |
22544 |
++ case PHY_TYPE_PCIE: |
22545 |
++ ret = nvmem_cell_read_variable_le_u32(dev, "intr", &instance->efuse_intr); |
22546 |
++ if (ret) { |
22547 |
++ dev_err(dev, "fail to get u3 intr efuse, %d\n", ret); |
22548 |
++ break; |
22549 |
++ } |
22550 |
++ |
22551 |
++ ret = nvmem_cell_read_variable_le_u32(dev, "rx_imp", &instance->efuse_rx_imp); |
22552 |
++ if (ret) { |
22553 |
++ dev_err(dev, "fail to get u3 rx_imp efuse, %d\n", ret); |
22554 |
++ break; |
22555 |
++ } |
22556 |
++ |
22557 |
++ ret = nvmem_cell_read_variable_le_u32(dev, "tx_imp", &instance->efuse_tx_imp); |
22558 |
++ if (ret) { |
22559 |
++ dev_err(dev, "fail to get u3 tx_imp efuse, %d\n", ret); |
22560 |
++ break; |
22561 |
++ } |
22562 |
++ |
22563 |
++ /* no efuse, ignore it */ |
22564 |
++ if (!instance->efuse_intr && |
22565 |
++ !instance->efuse_rx_imp && |
22566 |
++ !instance->efuse_rx_imp) { |
22567 |
++ dev_warn(dev, "no u3 intr efuse, but dts enable it\n"); |
22568 |
++ instance->efuse_sw_en = 0; |
22569 |
++ break; |
22570 |
++ } |
22571 |
++ |
22572 |
++ dev_dbg(dev, "u3 efuse - intr %x, rx_imp %x, tx_imp %x\n", |
22573 |
++ instance->efuse_intr, instance->efuse_rx_imp,instance->efuse_tx_imp); |
22574 |
++ break; |
22575 |
++ default: |
22576 |
++ dev_err(dev, "no sw efuse for type %d\n", instance->type); |
22577 |
++ ret = -EINVAL; |
22578 |
++ } |
22579 |
++ |
22580 |
++ return ret; |
22581 |
++} |
22582 |
++ |
22583 |
++static void phy_efuse_set(struct mtk_phy_instance *instance) |
22584 |
++{ |
22585 |
++ struct device *dev = &instance->phy->dev; |
22586 |
++ struct u2phy_banks *u2_banks = &instance->u2_banks; |
22587 |
++ struct u3phy_banks *u3_banks = &instance->u3_banks; |
22588 |
++ u32 tmp; |
22589 |
++ |
22590 |
++ if (!instance->efuse_sw_en) |
22591 |
++ return; |
22592 |
++ |
22593 |
++ switch (instance->type) { |
22594 |
++ case PHY_TYPE_USB2: |
22595 |
++ tmp = readl(u2_banks->misc + U3P_MISC_REG1); |
22596 |
++ tmp |= MR1_EFUSE_AUTO_LOAD_DIS; |
22597 |
++ writel(tmp, u2_banks->misc + U3P_MISC_REG1); |
22598 |
++ |
22599 |
++ tmp = readl(u2_banks->com + U3P_USBPHYACR1); |
22600 |
++ tmp &= ~PA1_RG_INTR_CAL; |
22601 |
++ tmp |= PA1_RG_INTR_CAL_VAL(instance->efuse_intr); |
22602 |
++ writel(tmp, u2_banks->com + U3P_USBPHYACR1); |
22603 |
++ break; |
22604 |
++ case PHY_TYPE_USB3: |
22605 |
++ case PHY_TYPE_PCIE: |
22606 |
++ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_RSV); |
22607 |
++ tmp |= P3D_RG_EFUSE_AUTO_LOAD_DIS; |
22608 |
++ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_RSV); |
22609 |
++ |
22610 |
++ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL0); |
22611 |
++ tmp &= ~P3D_RG_TX_IMPEL; |
22612 |
++ tmp |= P3D_RG_TX_IMPEL_VAL(instance->efuse_tx_imp); |
22613 |
++ tmp |= P3D_RG_FORCE_TX_IMPEL; |
22614 |
++ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_IMPCAL0); |
22615 |
++ |
22616 |
++ tmp = readl(u3_banks->phyd + U3P_U3_PHYD_IMPCAL1); |
22617 |
++ tmp &= ~P3D_RG_RX_IMPEL; |
22618 |
++ tmp |= P3D_RG_RX_IMPEL_VAL(instance->efuse_rx_imp); |
22619 |
++ tmp |= P3D_RG_FORCE_RX_IMPEL; |
22620 |
++ writel(tmp, u3_banks->phyd + U3P_U3_PHYD_IMPCAL1); |
22621 |
++ |
22622 |
++ tmp = readl(u3_banks->phya + U3P_U3_PHYA_REG0); |
22623 |
++ tmp &= ~P3A_RG_IEXT_INTR; |
22624 |
++ tmp |= P3A_RG_IEXT_INTR_VAL(instance->efuse_intr); |
22625 |
++ writel(tmp, u3_banks->phya + U3P_U3_PHYA_REG0); |
22626 |
++ break; |
22627 |
++ default: |
22628 |
++ dev_warn(dev, "no sw efuse for type %d\n", instance->type); |
22629 |
++ break; |
22630 |
++ } |
22631 |
++} |
22632 |
++ |
22633 |
+ static int mtk_phy_init(struct phy *phy) |
22634 |
+ { |
22635 |
+ struct mtk_phy_instance *instance = phy_get_drvdata(phy); |
22636 |
+@@ -1050,6 +1202,8 @@ static int mtk_phy_init(struct phy *phy) |
22637 |
+ if (ret) |
22638 |
+ return ret; |
22639 |
+ |
22640 |
++ phy_efuse_set(instance); |
22641 |
++ |
22642 |
+ switch (instance->type) { |
22643 |
+ case PHY_TYPE_USB2: |
22644 |
+ u2_phy_instance_init(tphy, instance); |
22645 |
+@@ -1134,6 +1288,7 @@ static struct phy *mtk_phy_xlate(struct device *dev, |
22646 |
+ struct mtk_phy_instance *instance = NULL; |
22647 |
+ struct device_node *phy_np = args->np; |
22648 |
+ int index; |
22649 |
++ int ret; |
22650 |
+ |
22651 |
+ if (args->args_count != 1) { |
22652 |
+ dev_err(dev, "invalid number of cells in 'phy' property\n"); |
22653 |
+@@ -1174,6 +1329,10 @@ static struct phy *mtk_phy_xlate(struct device *dev, |
22654 |
+ return ERR_PTR(-EINVAL); |
22655 |
+ } |
22656 |
+ |
22657 |
++ ret = phy_efuse_get(tphy, instance); |
22658 |
++ if (ret) |
22659 |
++ return ERR_PTR(ret); |
22660 |
++ |
22661 |
+ phy_parse_property(tphy, instance); |
22662 |
+ phy_type_set(instance); |
22663 |
+ |
22664 |
+@@ -1196,10 +1355,12 @@ static const struct mtk_phy_pdata tphy_v1_pdata = { |
22665 |
+ |
22666 |
+ static const struct mtk_phy_pdata tphy_v2_pdata = { |
22667 |
+ .avoid_rx_sen_degradation = false, |
22668 |
++ .sw_efuse_supported = true, |
22669 |
+ .version = MTK_PHY_V2, |
22670 |
+ }; |
22671 |
+ |
22672 |
+ static const struct mtk_phy_pdata tphy_v3_pdata = { |
22673 |
++ .sw_efuse_supported = true, |
22674 |
+ .version = MTK_PHY_V3, |
22675 |
+ }; |
22676 |
+ |
22677 |
+@@ -1210,6 +1371,7 @@ static const struct mtk_phy_pdata mt8173_pdata = { |
22678 |
+ |
22679 |
+ static const struct mtk_phy_pdata mt8195_pdata = { |
22680 |
+ .sw_pll_48m_to_26m = true, |
22681 |
++ .sw_efuse_supported = true, |
22682 |
+ .version = MTK_PHY_V3, |
22683 |
+ }; |
22684 |
+ |
22685 |
+diff --git a/drivers/phy/socionext/phy-uniphier-usb3ss.c b/drivers/phy/socionext/phy-uniphier-usb3ss.c |
22686 |
+index 6700645bcbe6b..3b5ffc16a6947 100644 |
22687 |
+--- a/drivers/phy/socionext/phy-uniphier-usb3ss.c |
22688 |
++++ b/drivers/phy/socionext/phy-uniphier-usb3ss.c |
22689 |
+@@ -22,11 +22,13 @@ |
22690 |
+ #include <linux/reset.h> |
22691 |
+ |
22692 |
+ #define SSPHY_TESTI 0x0 |
22693 |
+-#define SSPHY_TESTO 0x4 |
22694 |
+ #define TESTI_DAT_MASK GENMASK(13, 6) |
22695 |
+ #define TESTI_ADR_MASK GENMASK(5, 1) |
22696 |
+ #define TESTI_WR_EN BIT(0) |
22697 |
+ |
22698 |
++#define SSPHY_TESTO 0x4 |
22699 |
++#define TESTO_DAT_MASK GENMASK(7, 0) |
22700 |
++ |
22701 |
+ #define PHY_F(regno, msb, lsb) { (regno), (msb), (lsb) } |
22702 |
+ |
22703 |
+ #define CDR_CPD_TRIM PHY_F(7, 3, 0) /* RxPLL charge pump current */ |
22704 |
+@@ -84,12 +86,12 @@ static void uniphier_u3ssphy_set_param(struct uniphier_u3ssphy_priv *priv, |
22705 |
+ val = FIELD_PREP(TESTI_DAT_MASK, 1); |
22706 |
+ val |= FIELD_PREP(TESTI_ADR_MASK, p->field.reg_no); |
22707 |
+ uniphier_u3ssphy_testio_write(priv, val); |
22708 |
+- val = readl(priv->base + SSPHY_TESTO); |
22709 |
++ val = readl(priv->base + SSPHY_TESTO) & TESTO_DAT_MASK; |
22710 |
+ |
22711 |
+ /* update value */ |
22712 |
+- val &= ~FIELD_PREP(TESTI_DAT_MASK, field_mask); |
22713 |
++ val &= ~field_mask; |
22714 |
+ data = field_mask & (p->value << p->field.lsb); |
22715 |
+- val = FIELD_PREP(TESTI_DAT_MASK, data); |
22716 |
++ val = FIELD_PREP(TESTI_DAT_MASK, data | val); |
22717 |
+ val |= FIELD_PREP(TESTI_ADR_MASK, p->field.reg_no); |
22718 |
+ uniphier_u3ssphy_testio_write(priv, val); |
22719 |
+ uniphier_u3ssphy_testio_write(priv, val | TESTI_WR_EN); |
22720 |
+diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c |
22721 |
+index 5ce260f152ce5..dc52da94af0b9 100644 |
22722 |
+--- a/drivers/pinctrl/pinctrl-rockchip.c |
22723 |
++++ b/drivers/pinctrl/pinctrl-rockchip.c |
22724 |
+@@ -2748,7 +2748,7 @@ static int rockchip_pinctrl_probe(struct platform_device *pdev) |
22725 |
+ |
22726 |
+ platform_set_drvdata(pdev, info); |
22727 |
+ |
22728 |
+- ret = of_platform_populate(np, rockchip_bank_match, NULL, NULL); |
22729 |
++ ret = of_platform_populate(np, NULL, NULL, &pdev->dev); |
22730 |
+ if (ret) { |
22731 |
+ dev_err(&pdev->dev, "failed to register gpio device\n"); |
22732 |
+ return ret; |
22733 |
+diff --git a/drivers/power/reset/mt6323-poweroff.c b/drivers/power/reset/mt6323-poweroff.c |
22734 |
+index 0532803e6cbc4..d90e76fcb9383 100644 |
22735 |
+--- a/drivers/power/reset/mt6323-poweroff.c |
22736 |
++++ b/drivers/power/reset/mt6323-poweroff.c |
22737 |
+@@ -57,6 +57,9 @@ static int mt6323_pwrc_probe(struct platform_device *pdev) |
22738 |
+ return -ENOMEM; |
22739 |
+ |
22740 |
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
22741 |
++ if (!res) |
22742 |
++ return -EINVAL; |
22743 |
++ |
22744 |
+ pwrc->base = res->start; |
22745 |
+ pwrc->regmap = mt6397_chip->regmap; |
22746 |
+ pwrc->dev = &pdev->dev; |
22747 |
+diff --git a/drivers/ptp/ptp_vclock.c b/drivers/ptp/ptp_vclock.c |
22748 |
+index baee0379482bc..ab1d233173e13 100644 |
22749 |
+--- a/drivers/ptp/ptp_vclock.c |
22750 |
++++ b/drivers/ptp/ptp_vclock.c |
22751 |
+@@ -185,8 +185,8 @@ out: |
22752 |
+ } |
22753 |
+ EXPORT_SYMBOL(ptp_get_vclocks_index); |
22754 |
+ |
22755 |
+-void ptp_convert_timestamp(struct skb_shared_hwtstamps *hwtstamps, |
22756 |
+- int vclock_index) |
22757 |
++ktime_t ptp_convert_timestamp(const struct skb_shared_hwtstamps *hwtstamps, |
22758 |
++ int vclock_index) |
22759 |
+ { |
22760 |
+ char name[PTP_CLOCK_NAME_LEN] = ""; |
22761 |
+ struct ptp_vclock *vclock; |
22762 |
+@@ -198,12 +198,12 @@ void ptp_convert_timestamp(struct skb_shared_hwtstamps *hwtstamps, |
22763 |
+ snprintf(name, PTP_CLOCK_NAME_LEN, "ptp%d", vclock_index); |
22764 |
+ dev = class_find_device_by_name(ptp_class, name); |
22765 |
+ if (!dev) |
22766 |
+- return; |
22767 |
++ return 0; |
22768 |
+ |
22769 |
+ ptp = dev_get_drvdata(dev); |
22770 |
+ if (!ptp->is_virtual_clock) { |
22771 |
+ put_device(dev); |
22772 |
+- return; |
22773 |
++ return 0; |
22774 |
+ } |
22775 |
+ |
22776 |
+ vclock = info_to_vclock(ptp->info); |
22777 |
+@@ -215,7 +215,7 @@ void ptp_convert_timestamp(struct skb_shared_hwtstamps *hwtstamps, |
22778 |
+ spin_unlock_irqrestore(&vclock->lock, flags); |
22779 |
+ |
22780 |
+ put_device(dev); |
22781 |
+- hwtstamps->hwtstamp = ns_to_ktime(ns); |
22782 |
++ return ns_to_ktime(ns); |
22783 |
+ } |
22784 |
+ EXPORT_SYMBOL(ptp_convert_timestamp); |
22785 |
+ #endif |
22786 |
+diff --git a/drivers/regulator/da9121-regulator.c b/drivers/regulator/da9121-regulator.c |
22787 |
+index e669250902580..0a4fd449c27d1 100644 |
22788 |
+--- a/drivers/regulator/da9121-regulator.c |
22789 |
++++ b/drivers/regulator/da9121-regulator.c |
22790 |
+@@ -253,6 +253,11 @@ static int da9121_set_current_limit(struct regulator_dev *rdev, |
22791 |
+ goto error; |
22792 |
+ } |
22793 |
+ |
22794 |
++ if (rdev->desc->ops->is_enabled(rdev)) { |
22795 |
++ ret = -EBUSY; |
22796 |
++ goto error; |
22797 |
++ } |
22798 |
++ |
22799 |
+ ret = da9121_ceiling_selector(rdev, min_ua, max_ua, &sel); |
22800 |
+ if (ret < 0) |
22801 |
+ goto error; |
22802 |
+diff --git a/drivers/regulator/qcom-labibb-regulator.c b/drivers/regulator/qcom-labibb-regulator.c |
22803 |
+index b3da0dc58782f..639b71eb41ffe 100644 |
22804 |
+--- a/drivers/regulator/qcom-labibb-regulator.c |
22805 |
++++ b/drivers/regulator/qcom-labibb-regulator.c |
22806 |
+@@ -260,7 +260,7 @@ static irqreturn_t qcom_labibb_ocp_isr(int irq, void *chip) |
22807 |
+ |
22808 |
+ /* If the regulator is not enabled, this is a fake event */ |
22809 |
+ if (!ops->is_enabled(vreg->rdev)) |
22810 |
+- return 0; |
22811 |
++ return IRQ_HANDLED; |
22812 |
+ |
22813 |
+ /* If we tried to recover for too many times it's not getting better */ |
22814 |
+ if (vreg->ocp_irq_count > LABIBB_MAX_OCP_COUNT) |
22815 |
+diff --git a/drivers/regulator/qcom_smd-regulator.c b/drivers/regulator/qcom_smd-regulator.c |
22816 |
+index 198fcc6551f6d..8e077792bddd9 100644 |
22817 |
+--- a/drivers/regulator/qcom_smd-regulator.c |
22818 |
++++ b/drivers/regulator/qcom_smd-regulator.c |
22819 |
+@@ -9,6 +9,7 @@ |
22820 |
+ #include <linux/of_device.h> |
22821 |
+ #include <linux/platform_device.h> |
22822 |
+ #include <linux/regulator/driver.h> |
22823 |
++#include <linux/regulator/of_regulator.h> |
22824 |
+ #include <linux/soc/qcom/smd-rpm.h> |
22825 |
+ |
22826 |
+ struct qcom_rpm_reg { |
22827 |
+@@ -1190,52 +1191,91 @@ static const struct of_device_id rpm_of_match[] = { |
22828 |
+ }; |
22829 |
+ MODULE_DEVICE_TABLE(of, rpm_of_match); |
22830 |
+ |
22831 |
+-static int rpm_reg_probe(struct platform_device *pdev) |
22832 |
++/** |
22833 |
++ * rpm_regulator_init_vreg() - initialize all attributes of a qcom_smd-regulator |
22834 |
++ * @vreg: Pointer to the individual qcom_smd-regulator resource |
22835 |
++ * @dev: Pointer to the top level qcom_smd-regulator PMIC device |
22836 |
++ * @node: Pointer to the individual qcom_smd-regulator resource |
22837 |
++ * device node |
22838 |
++ * @rpm: Pointer to the rpm bus node |
22839 |
++ * @pmic_rpm_data: Pointer to a null-terminated array of qcom_smd-regulator |
22840 |
++ * resources defined for the top level PMIC device |
22841 |
++ * |
22842 |
++ * Return: 0 on success, errno on failure |
22843 |
++ */ |
22844 |
++static int rpm_regulator_init_vreg(struct qcom_rpm_reg *vreg, struct device *dev, |
22845 |
++ struct device_node *node, struct qcom_smd_rpm *rpm, |
22846 |
++ const struct rpm_regulator_data *pmic_rpm_data) |
22847 |
+ { |
22848 |
+- const struct rpm_regulator_data *reg; |
22849 |
+- const struct of_device_id *match; |
22850 |
+- struct regulator_config config = { }; |
22851 |
++ struct regulator_config config = {}; |
22852 |
++ const struct rpm_regulator_data *rpm_data; |
22853 |
+ struct regulator_dev *rdev; |
22854 |
++ int ret; |
22855 |
++ |
22856 |
++ for (rpm_data = pmic_rpm_data; rpm_data->name; rpm_data++) |
22857 |
++ if (of_node_name_eq(node, rpm_data->name)) |
22858 |
++ break; |
22859 |
++ |
22860 |
++ if (!rpm_data->name) { |
22861 |
++ dev_err(dev, "Unknown regulator %pOFn\n", node); |
22862 |
++ return -EINVAL; |
22863 |
++ } |
22864 |
++ |
22865 |
++ vreg->dev = dev; |
22866 |
++ vreg->rpm = rpm; |
22867 |
++ vreg->type = rpm_data->type; |
22868 |
++ vreg->id = rpm_data->id; |
22869 |
++ |
22870 |
++ memcpy(&vreg->desc, rpm_data->desc, sizeof(vreg->desc)); |
22871 |
++ vreg->desc.name = rpm_data->name; |
22872 |
++ vreg->desc.supply_name = rpm_data->supply; |
22873 |
++ vreg->desc.owner = THIS_MODULE; |
22874 |
++ vreg->desc.type = REGULATOR_VOLTAGE; |
22875 |
++ vreg->desc.of_match = rpm_data->name; |
22876 |
++ |
22877 |
++ config.dev = dev; |
22878 |
++ config.of_node = node; |
22879 |
++ config.driver_data = vreg; |
22880 |
++ |
22881 |
++ rdev = devm_regulator_register(dev, &vreg->desc, &config); |
22882 |
++ if (IS_ERR(rdev)) { |
22883 |
++ ret = PTR_ERR(rdev); |
22884 |
++ dev_err(dev, "%pOFn: devm_regulator_register() failed, ret=%d\n", node, ret); |
22885 |
++ return ret; |
22886 |
++ } |
22887 |
++ |
22888 |
++ return 0; |
22889 |
++} |
22890 |
++ |
22891 |
++static int rpm_reg_probe(struct platform_device *pdev) |
22892 |
++{ |
22893 |
++ struct device *dev = &pdev->dev; |
22894 |
++ const struct rpm_regulator_data *vreg_data; |
22895 |
++ struct device_node *node; |
22896 |
+ struct qcom_rpm_reg *vreg; |
22897 |
+ struct qcom_smd_rpm *rpm; |
22898 |
++ int ret; |
22899 |
+ |
22900 |
+ rpm = dev_get_drvdata(pdev->dev.parent); |
22901 |
+ if (!rpm) { |
22902 |
+- dev_err(&pdev->dev, "unable to retrieve handle to rpm\n"); |
22903 |
++ dev_err(&pdev->dev, "Unable to retrieve handle to rpm\n"); |
22904 |
+ return -ENODEV; |
22905 |
+ } |
22906 |
+ |
22907 |
+- match = of_match_device(rpm_of_match, &pdev->dev); |
22908 |
+- if (!match) { |
22909 |
+- dev_err(&pdev->dev, "failed to match device\n"); |
22910 |
++ vreg_data = of_device_get_match_data(dev); |
22911 |
++ if (!vreg_data) |
22912 |
+ return -ENODEV; |
22913 |
+- } |
22914 |
+ |
22915 |
+- for (reg = match->data; reg->name; reg++) { |
22916 |
++ for_each_available_child_of_node(dev->of_node, node) { |
22917 |
+ vreg = devm_kzalloc(&pdev->dev, sizeof(*vreg), GFP_KERNEL); |
22918 |
+ if (!vreg) |
22919 |
+ return -ENOMEM; |
22920 |
+ |
22921 |
+- vreg->dev = &pdev->dev; |
22922 |
+- vreg->type = reg->type; |
22923 |
+- vreg->id = reg->id; |
22924 |
+- vreg->rpm = rpm; |
22925 |
+- |
22926 |
+- memcpy(&vreg->desc, reg->desc, sizeof(vreg->desc)); |
22927 |
+- |
22928 |
+- vreg->desc.id = -1; |
22929 |
+- vreg->desc.owner = THIS_MODULE; |
22930 |
+- vreg->desc.type = REGULATOR_VOLTAGE; |
22931 |
+- vreg->desc.name = reg->name; |
22932 |
+- vreg->desc.supply_name = reg->supply; |
22933 |
+- vreg->desc.of_match = reg->name; |
22934 |
+- |
22935 |
+- config.dev = &pdev->dev; |
22936 |
+- config.driver_data = vreg; |
22937 |
+- rdev = devm_regulator_register(&pdev->dev, &vreg->desc, &config); |
22938 |
+- if (IS_ERR(rdev)) { |
22939 |
+- dev_err(&pdev->dev, "failed to register %s\n", reg->name); |
22940 |
+- return PTR_ERR(rdev); |
22941 |
++ ret = rpm_regulator_init_vreg(vreg, dev, node, rpm, vreg_data); |
22942 |
++ |
22943 |
++ if (ret < 0) { |
22944 |
++ of_node_put(node); |
22945 |
++ return ret; |
22946 |
+ } |
22947 |
+ } |
22948 |
+ |
22949 |
+diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c |
22950 |
+index ff620688fad94..05c39e1c56b49 100644 |
22951 |
+--- a/drivers/remoteproc/imx_rproc.c |
22952 |
++++ b/drivers/remoteproc/imx_rproc.c |
22953 |
+@@ -830,6 +830,7 @@ static int imx_rproc_remove(struct platform_device *pdev) |
22954 |
+ clk_disable_unprepare(priv->clk); |
22955 |
+ rproc_del(rproc); |
22956 |
+ imx_rproc_free_mbox(rproc); |
22957 |
++ destroy_workqueue(priv->workqueue); |
22958 |
+ rproc_free(rproc); |
22959 |
+ |
22960 |
+ return 0; |
22961 |
+diff --git a/drivers/rpmsg/rpmsg_core.c b/drivers/rpmsg/rpmsg_core.c |
22962 |
+index 9151836190ce3..a71de08acc7b9 100644 |
22963 |
+--- a/drivers/rpmsg/rpmsg_core.c |
22964 |
++++ b/drivers/rpmsg/rpmsg_core.c |
22965 |
+@@ -519,13 +519,25 @@ static int rpmsg_dev_probe(struct device *dev) |
22966 |
+ err = rpdrv->probe(rpdev); |
22967 |
+ if (err) { |
22968 |
+ dev_err(dev, "%s: failed: %d\n", __func__, err); |
22969 |
+- if (ept) |
22970 |
+- rpmsg_destroy_ept(ept); |
22971 |
+- goto out; |
22972 |
++ goto destroy_ept; |
22973 |
+ } |
22974 |
+ |
22975 |
+- if (ept && rpdev->ops->announce_create) |
22976 |
++ if (ept && rpdev->ops->announce_create) { |
22977 |
+ err = rpdev->ops->announce_create(rpdev); |
22978 |
++ if (err) { |
22979 |
++ dev_err(dev, "failed to announce creation\n"); |
22980 |
++ goto remove_rpdev; |
22981 |
++ } |
22982 |
++ } |
22983 |
++ |
22984 |
++ return 0; |
22985 |
++ |
22986 |
++remove_rpdev: |
22987 |
++ if (rpdrv->remove) |
22988 |
++ rpdrv->remove(rpdev); |
22989 |
++destroy_ept: |
22990 |
++ if (ept) |
22991 |
++ rpmsg_destroy_ept(ept); |
22992 |
+ out: |
22993 |
+ return err; |
22994 |
+ } |
22995 |
+diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c |
22996 |
+index 4eb53412b8085..dc3f8b0dde989 100644 |
22997 |
+--- a/drivers/rtc/rtc-cmos.c |
22998 |
++++ b/drivers/rtc/rtc-cmos.c |
22999 |
+@@ -457,7 +457,10 @@ static int cmos_set_alarm(struct device *dev, struct rtc_wkalrm *t) |
23000 |
+ min = t->time.tm_min; |
23001 |
+ sec = t->time.tm_sec; |
23002 |
+ |
23003 |
++ spin_lock_irq(&rtc_lock); |
23004 |
+ rtc_control = CMOS_READ(RTC_CONTROL); |
23005 |
++ spin_unlock_irq(&rtc_lock); |
23006 |
++ |
23007 |
+ if (!(rtc_control & RTC_DM_BINARY) || RTC_ALWAYS_BCD) { |
23008 |
+ /* Writing 0xff means "don't care" or "match all". */ |
23009 |
+ mon = (mon <= 12) ? bin2bcd(mon) : 0xff; |
23010 |
+diff --git a/drivers/rtc/rtc-pxa.c b/drivers/rtc/rtc-pxa.c |
23011 |
+index d2f1d8f754bf3..cf8119b6d3204 100644 |
23012 |
+--- a/drivers/rtc/rtc-pxa.c |
23013 |
++++ b/drivers/rtc/rtc-pxa.c |
23014 |
+@@ -330,6 +330,10 @@ static int __init pxa_rtc_probe(struct platform_device *pdev) |
23015 |
+ if (sa1100_rtc->irq_alarm < 0) |
23016 |
+ return -ENXIO; |
23017 |
+ |
23018 |
++ sa1100_rtc->rtc = devm_rtc_allocate_device(&pdev->dev); |
23019 |
++ if (IS_ERR(sa1100_rtc->rtc)) |
23020 |
++ return PTR_ERR(sa1100_rtc->rtc); |
23021 |
++ |
23022 |
+ pxa_rtc->base = devm_ioremap(dev, pxa_rtc->ress->start, |
23023 |
+ resource_size(pxa_rtc->ress)); |
23024 |
+ if (!pxa_rtc->base) { |
23025 |
+diff --git a/drivers/scsi/lpfc/lpfc.h b/drivers/scsi/lpfc/lpfc.h |
23026 |
+index befeb7c342903..19fd9d263f47f 100644 |
23027 |
+--- a/drivers/scsi/lpfc/lpfc.h |
23028 |
++++ b/drivers/scsi/lpfc/lpfc.h |
23029 |
+@@ -1022,7 +1022,6 @@ struct lpfc_hba { |
23030 |
+ #define HBA_DEVLOSS_TMO 0x2000 /* HBA in devloss timeout */ |
23031 |
+ #define HBA_RRQ_ACTIVE 0x4000 /* process the rrq active list */ |
23032 |
+ #define HBA_IOQ_FLUSH 0x8000 /* FCP/NVME I/O queues being flushed */ |
23033 |
+-#define HBA_FW_DUMP_OP 0x10000 /* Skips fn reset before FW dump */ |
23034 |
+ #define HBA_RECOVERABLE_UE 0x20000 /* Firmware supports recoverable UE */ |
23035 |
+ #define HBA_FORCED_LINK_SPEED 0x40000 /* |
23036 |
+ * Firmware supports Forced Link Speed |
23037 |
+@@ -1038,6 +1037,7 @@ struct lpfc_hba { |
23038 |
+ #define HBA_HBEAT_TMO 0x8000000 /* HBEAT initiated after timeout */ |
23039 |
+ #define HBA_FLOGI_OUTSTANDING 0x10000000 /* FLOGI is outstanding */ |
23040 |
+ |
23041 |
++ struct completion *fw_dump_cmpl; /* cmpl event tracker for fw_dump */ |
23042 |
+ uint32_t fcp_ring_in_use; /* When polling test if intr-hndlr active*/ |
23043 |
+ struct lpfc_dmabuf slim2p; |
23044 |
+ |
23045 |
+diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c |
23046 |
+index ebe417921dac0..f20c4fe1fb8b9 100644 |
23047 |
+--- a/drivers/scsi/lpfc/lpfc_attr.c |
23048 |
++++ b/drivers/scsi/lpfc/lpfc_attr.c |
23049 |
+@@ -1709,25 +1709,25 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode) |
23050 |
+ before_fc_flag = phba->pport->fc_flag; |
23051 |
+ sriov_nr_virtfn = phba->cfg_sriov_nr_virtfn; |
23052 |
+ |
23053 |
+- /* Disable SR-IOV virtual functions if enabled */ |
23054 |
+- if (phba->cfg_sriov_nr_virtfn) { |
23055 |
+- pci_disable_sriov(pdev); |
23056 |
+- phba->cfg_sriov_nr_virtfn = 0; |
23057 |
+- } |
23058 |
++ if (opcode == LPFC_FW_DUMP) { |
23059 |
++ init_completion(&online_compl); |
23060 |
++ phba->fw_dump_cmpl = &online_compl; |
23061 |
++ } else { |
23062 |
++ /* Disable SR-IOV virtual functions if enabled */ |
23063 |
++ if (phba->cfg_sriov_nr_virtfn) { |
23064 |
++ pci_disable_sriov(pdev); |
23065 |
++ phba->cfg_sriov_nr_virtfn = 0; |
23066 |
++ } |
23067 |
+ |
23068 |
+- if (opcode == LPFC_FW_DUMP) |
23069 |
+- phba->hba_flag |= HBA_FW_DUMP_OP; |
23070 |
++ status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); |
23071 |
+ |
23072 |
+- status = lpfc_do_offline(phba, LPFC_EVT_OFFLINE); |
23073 |
++ if (status != 0) |
23074 |
++ return status; |
23075 |
+ |
23076 |
+- if (status != 0) { |
23077 |
+- phba->hba_flag &= ~HBA_FW_DUMP_OP; |
23078 |
+- return status; |
23079 |
++ /* wait for the device to be quiesced before firmware reset */ |
23080 |
++ msleep(100); |
23081 |
+ } |
23082 |
+ |
23083 |
+- /* wait for the device to be quiesced before firmware reset */ |
23084 |
+- msleep(100); |
23085 |
+- |
23086 |
+ reg_val = readl(phba->sli4_hba.conf_regs_memmap_p + |
23087 |
+ LPFC_CTL_PDEV_CTL_OFFSET); |
23088 |
+ |
23089 |
+@@ -1756,24 +1756,42 @@ lpfc_sli4_pdev_reg_request(struct lpfc_hba *phba, uint32_t opcode) |
23090 |
+ lpfc_printf_log(phba, KERN_ERR, LOG_SLI, |
23091 |
+ "3153 Fail to perform the requested " |
23092 |
+ "access: x%x\n", reg_val); |
23093 |
++ if (phba->fw_dump_cmpl) |
23094 |
++ phba->fw_dump_cmpl = NULL; |
23095 |
+ return rc; |
23096 |
+ } |
23097 |
+ |
23098 |
+ /* keep the original port state */ |
23099 |
+- if (before_fc_flag & FC_OFFLINE_MODE) |
23100 |
+- goto out; |
23101 |
+- |
23102 |
+- init_completion(&online_compl); |
23103 |
+- job_posted = lpfc_workq_post_event(phba, &status, &online_compl, |
23104 |
+- LPFC_EVT_ONLINE); |
23105 |
+- if (!job_posted) |
23106 |
++ if (before_fc_flag & FC_OFFLINE_MODE) { |
23107 |
++ if (phba->fw_dump_cmpl) |
23108 |
++ phba->fw_dump_cmpl = NULL; |
23109 |
+ goto out; |
23110 |
++ } |
23111 |
+ |
23112 |
+- wait_for_completion(&online_compl); |
23113 |
++ /* Firmware dump will trigger an HA_ERATT event, and |
23114 |
++ * lpfc_handle_eratt_s4 routine already handles bringing the port back |
23115 |
++ * online. |
23116 |
++ */ |
23117 |
++ if (opcode == LPFC_FW_DUMP) { |
23118 |
++ wait_for_completion(phba->fw_dump_cmpl); |
23119 |
++ } else { |
23120 |
++ init_completion(&online_compl); |
23121 |
++ job_posted = lpfc_workq_post_event(phba, &status, &online_compl, |
23122 |
++ LPFC_EVT_ONLINE); |
23123 |
++ if (!job_posted) |
23124 |
++ goto out; |
23125 |
+ |
23126 |
++ wait_for_completion(&online_compl); |
23127 |
++ } |
23128 |
+ out: |
23129 |
+ /* in any case, restore the virtual functions enabled as before */ |
23130 |
+ if (sriov_nr_virtfn) { |
23131 |
++ /* If fw_dump was performed, first disable to clean up */ |
23132 |
++ if (opcode == LPFC_FW_DUMP) { |
23133 |
++ pci_disable_sriov(pdev); |
23134 |
++ phba->cfg_sriov_nr_virtfn = 0; |
23135 |
++ } |
23136 |
++ |
23137 |
+ sriov_err = |
23138 |
+ lpfc_sli_probe_sriov_nr_virtfn(phba, sriov_nr_virtfn); |
23139 |
+ if (!sriov_err) |
23140 |
+diff --git a/drivers/scsi/lpfc/lpfc_els.c b/drivers/scsi/lpfc/lpfc_els.c |
23141 |
+index f7197b7161d52..f08ab8269f441 100644 |
23142 |
+--- a/drivers/scsi/lpfc/lpfc_els.c |
23143 |
++++ b/drivers/scsi/lpfc/lpfc_els.c |
23144 |
+@@ -3531,11 +3531,6 @@ lpfc_issue_els_rscn(struct lpfc_vport *vport, uint8_t retry) |
23145 |
+ return 1; |
23146 |
+ } |
23147 |
+ |
23148 |
+- /* This will cause the callback-function lpfc_cmpl_els_cmd to |
23149 |
+- * trigger the release of node. |
23150 |
+- */ |
23151 |
+- if (!(vport->fc_flag & FC_PT2PT)) |
23152 |
+- lpfc_nlp_put(ndlp); |
23153 |
+ return 0; |
23154 |
+ } |
23155 |
+ |
23156 |
+@@ -6877,6 +6872,7 @@ static int |
23157 |
+ lpfc_get_rdp_info(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context) |
23158 |
+ { |
23159 |
+ LPFC_MBOXQ_t *mbox = NULL; |
23160 |
++ struct lpfc_dmabuf *mp; |
23161 |
+ int rc; |
23162 |
+ |
23163 |
+ mbox = mempool_alloc(phba->mbox_mem_pool, GFP_KERNEL); |
23164 |
+@@ -6892,8 +6888,11 @@ lpfc_get_rdp_info(struct lpfc_hba *phba, struct lpfc_rdp_context *rdp_context) |
23165 |
+ mbox->mbox_cmpl = lpfc_mbx_cmpl_rdp_page_a0; |
23166 |
+ mbox->ctx_ndlp = (struct lpfc_rdp_context *)rdp_context; |
23167 |
+ rc = lpfc_sli_issue_mbox(phba, mbox, MBX_NOWAIT); |
23168 |
+- if (rc == MBX_NOT_FINISHED) |
23169 |
++ if (rc == MBX_NOT_FINISHED) { |
23170 |
++ mp = (struct lpfc_dmabuf *)mbox->ctx_buf; |
23171 |
++ lpfc_mbuf_free(phba, mp->virt, mp->phys); |
23172 |
+ goto issue_mbox_fail; |
23173 |
++ } |
23174 |
+ |
23175 |
+ return 0; |
23176 |
+ |
23177 |
+diff --git a/drivers/scsi/lpfc/lpfc_hbadisc.c b/drivers/scsi/lpfc/lpfc_hbadisc.c |
23178 |
+index 9ccb904e35fcf..3bb7c2aa949f7 100644 |
23179 |
+--- a/drivers/scsi/lpfc/lpfc_hbadisc.c |
23180 |
++++ b/drivers/scsi/lpfc/lpfc_hbadisc.c |
23181 |
+@@ -869,10 +869,16 @@ lpfc_work_done(struct lpfc_hba *phba) |
23182 |
+ if (phba->pci_dev_grp == LPFC_PCI_DEV_OC) |
23183 |
+ lpfc_sli4_post_async_mbox(phba); |
23184 |
+ |
23185 |
+- if (ha_copy & HA_ERATT) |
23186 |
++ if (ha_copy & HA_ERATT) { |
23187 |
+ /* Handle the error attention event */ |
23188 |
+ lpfc_handle_eratt(phba); |
23189 |
+ |
23190 |
++ if (phba->fw_dump_cmpl) { |
23191 |
++ complete(phba->fw_dump_cmpl); |
23192 |
++ phba->fw_dump_cmpl = NULL; |
23193 |
++ } |
23194 |
++ } |
23195 |
++ |
23196 |
+ if (ha_copy & HA_MBATT) |
23197 |
+ lpfc_sli_handle_mb_event(phba); |
23198 |
+ |
23199 |
+diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c |
23200 |
+index 0fee8d590b0c4..2bbd1be6cc5d4 100644 |
23201 |
+--- a/drivers/scsi/lpfc/lpfc_init.c |
23202 |
++++ b/drivers/scsi/lpfc/lpfc_init.c |
23203 |
+@@ -5314,8 +5314,10 @@ lpfc_sli4_async_link_evt(struct lpfc_hba *phba, |
23204 |
+ */ |
23205 |
+ if (!(phba->hba_flag & HBA_FCOE_MODE)) { |
23206 |
+ rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); |
23207 |
+- if (rc == MBX_NOT_FINISHED) |
23208 |
++ if (rc == MBX_NOT_FINISHED) { |
23209 |
++ lpfc_mbuf_free(phba, mp->virt, mp->phys); |
23210 |
+ goto out_free_dmabuf; |
23211 |
++ } |
23212 |
+ return; |
23213 |
+ } |
23214 |
+ /* |
23215 |
+@@ -6266,8 +6268,10 @@ lpfc_sli4_async_fc_evt(struct lpfc_hba *phba, struct lpfc_acqe_fc_la *acqe_fc) |
23216 |
+ } |
23217 |
+ |
23218 |
+ rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT); |
23219 |
+- if (rc == MBX_NOT_FINISHED) |
23220 |
++ if (rc == MBX_NOT_FINISHED) { |
23221 |
++ lpfc_mbuf_free(phba, mp->virt, mp->phys); |
23222 |
+ goto out_free_dmabuf; |
23223 |
++ } |
23224 |
+ return; |
23225 |
+ |
23226 |
+ out_free_dmabuf: |
23227 |
+diff --git a/drivers/scsi/lpfc/lpfc_nportdisc.c b/drivers/scsi/lpfc/lpfc_nportdisc.c |
23228 |
+index 27263f02ab9f6..7d717a4ac14d1 100644 |
23229 |
+--- a/drivers/scsi/lpfc/lpfc_nportdisc.c |
23230 |
++++ b/drivers/scsi/lpfc/lpfc_nportdisc.c |
23231 |
+@@ -322,6 +322,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
23232 |
+ { |
23233 |
+ struct lpfc_hba *phba = vport->phba; |
23234 |
+ struct lpfc_dmabuf *pcmd; |
23235 |
++ struct lpfc_dmabuf *mp; |
23236 |
+ uint64_t nlp_portwwn = 0; |
23237 |
+ uint32_t *lp; |
23238 |
+ IOCB_t *icmd; |
23239 |
+@@ -571,6 +572,11 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp, |
23240 |
+ * a default RPI. |
23241 |
+ */ |
23242 |
+ if (phba->sli_rev == LPFC_SLI_REV4) { |
23243 |
++ mp = (struct lpfc_dmabuf *)login_mbox->ctx_buf; |
23244 |
++ if (mp) { |
23245 |
++ lpfc_mbuf_free(phba, mp->virt, mp->phys); |
23246 |
++ kfree(mp); |
23247 |
++ } |
23248 |
+ mempool_free(login_mbox, phba->mbox_mem_pool); |
23249 |
+ login_mbox = NULL; |
23250 |
+ } else { |
23251 |
+diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c |
23252 |
+index 9c1f485952ef7..e5009f21d97e1 100644 |
23253 |
+--- a/drivers/scsi/lpfc/lpfc_sli.c |
23254 |
++++ b/drivers/scsi/lpfc/lpfc_sli.c |
23255 |
+@@ -5043,12 +5043,6 @@ lpfc_sli4_brdreset(struct lpfc_hba *phba) |
23256 |
+ phba->fcf.fcf_flag = 0; |
23257 |
+ spin_unlock_irq(&phba->hbalock); |
23258 |
+ |
23259 |
+- /* SLI4 INTF 2: if FW dump is being taken skip INIT_PORT */ |
23260 |
+- if (phba->hba_flag & HBA_FW_DUMP_OP) { |
23261 |
+- phba->hba_flag &= ~HBA_FW_DUMP_OP; |
23262 |
+- return rc; |
23263 |
+- } |
23264 |
+- |
23265 |
+ /* Now physically reset the device */ |
23266 |
+ lpfc_printf_log(phba, KERN_INFO, LOG_INIT, |
23267 |
+ "0389 Performing PCI function reset!\n"); |
23268 |
+diff --git a/drivers/scsi/mpi3mr/mpi3mr.h b/drivers/scsi/mpi3mr/mpi3mr.h |
23269 |
+index 9787b53a2b598..2cc42432bd0c0 100644 |
23270 |
+--- a/drivers/scsi/mpi3mr/mpi3mr.h |
23271 |
++++ b/drivers/scsi/mpi3mr/mpi3mr.h |
23272 |
+@@ -79,7 +79,8 @@ extern int prot_mask; |
23273 |
+ |
23274 |
+ /* Operational queue management definitions */ |
23275 |
+ #define MPI3MR_OP_REQ_Q_QD 512 |
23276 |
+-#define MPI3MR_OP_REP_Q_QD 4096 |
23277 |
++#define MPI3MR_OP_REP_Q_QD 1024 |
23278 |
++#define MPI3MR_OP_REP_Q_QD4K 4096 |
23279 |
+ #define MPI3MR_OP_REQ_Q_SEG_SIZE 4096 |
23280 |
+ #define MPI3MR_OP_REP_Q_SEG_SIZE 4096 |
23281 |
+ #define MPI3MR_MAX_SEG_LIST_SIZE 4096 |
23282 |
+diff --git a/drivers/scsi/mpi3mr/mpi3mr_fw.c b/drivers/scsi/mpi3mr/mpi3mr_fw.c |
23283 |
+index 4a8316c6bd41a..5af36c54cb596 100644 |
23284 |
+--- a/drivers/scsi/mpi3mr/mpi3mr_fw.c |
23285 |
++++ b/drivers/scsi/mpi3mr/mpi3mr_fw.c |
23286 |
+@@ -1278,7 +1278,7 @@ static void mpi3mr_free_op_req_q_segments(struct mpi3mr_ioc *mrioc, u16 q_idx) |
23287 |
+ mrioc->op_reply_qinfo[q_idx].q_segment_list = NULL; |
23288 |
+ } |
23289 |
+ } else |
23290 |
+- size = mrioc->req_qinfo[q_idx].num_requests * |
23291 |
++ size = mrioc->req_qinfo[q_idx].segment_qd * |
23292 |
+ mrioc->facts.op_req_sz; |
23293 |
+ |
23294 |
+ for (j = 0; j < mrioc->req_qinfo[q_idx].num_segments; j++) { |
23295 |
+@@ -1565,6 +1565,8 @@ static int mpi3mr_create_op_reply_q(struct mpi3mr_ioc *mrioc, u16 qidx) |
23296 |
+ |
23297 |
+ reply_qid = qidx + 1; |
23298 |
+ op_reply_q->num_replies = MPI3MR_OP_REP_Q_QD; |
23299 |
++ if (!mrioc->pdev->revision) |
23300 |
++ op_reply_q->num_replies = MPI3MR_OP_REP_Q_QD4K; |
23301 |
+ op_reply_q->ci = 0; |
23302 |
+ op_reply_q->ephase = 1; |
23303 |
+ atomic_set(&op_reply_q->pend_ios, 0); |
23304 |
+diff --git a/drivers/scsi/pm8001/pm8001_hwi.c b/drivers/scsi/pm8001/pm8001_hwi.c |
23305 |
+index 639b7e38a1947..880e1f356defc 100644 |
23306 |
+--- a/drivers/scsi/pm8001/pm8001_hwi.c |
23307 |
++++ b/drivers/scsi/pm8001/pm8001_hwi.c |
23308 |
+@@ -1325,7 +1325,9 @@ int pm8001_mpi_build_cmd(struct pm8001_hba_info *pm8001_ha, |
23309 |
+ int q_index = circularQ - pm8001_ha->inbnd_q_tbl; |
23310 |
+ int rv; |
23311 |
+ |
23312 |
+- WARN_ON(q_index >= PM8001_MAX_INB_NUM); |
23313 |
++ if (WARN_ON(q_index >= pm8001_ha->max_q_num)) |
23314 |
++ return -EINVAL; |
23315 |
++ |
23316 |
+ spin_lock_irqsave(&circularQ->iq_lock, flags); |
23317 |
+ rv = pm8001_mpi_msg_free_get(circularQ, pm8001_ha->iomb_size, |
23318 |
+ &pMessage); |
23319 |
+diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c |
23320 |
+index 291ecc33b1fe6..4fc9466d820a7 100644 |
23321 |
+--- a/drivers/scsi/scsi.c |
23322 |
++++ b/drivers/scsi/scsi.c |
23323 |
+@@ -209,11 +209,11 @@ void scsi_finish_command(struct scsi_cmnd *cmd) |
23324 |
+ |
23325 |
+ |
23326 |
+ /* |
23327 |
+- * 1024 is big enough for saturating the fast scsi LUN now |
23328 |
++ * 1024 is big enough for saturating fast SCSI LUNs. |
23329 |
+ */ |
23330 |
+ int scsi_device_max_queue_depth(struct scsi_device *sdev) |
23331 |
+ { |
23332 |
+- return max_t(int, sdev->host->can_queue, 1024); |
23333 |
++ return min_t(int, sdev->host->can_queue, 1024); |
23334 |
+ } |
23335 |
+ |
23336 |
+ /** |
23337 |
+diff --git a/drivers/scsi/scsi_debugfs.c b/drivers/scsi/scsi_debugfs.c |
23338 |
+index d9109771f274d..db8517f1a485a 100644 |
23339 |
+--- a/drivers/scsi/scsi_debugfs.c |
23340 |
++++ b/drivers/scsi/scsi_debugfs.c |
23341 |
+@@ -9,6 +9,7 @@ |
23342 |
+ static const char *const scsi_cmd_flags[] = { |
23343 |
+ SCSI_CMD_FLAG_NAME(TAGGED), |
23344 |
+ SCSI_CMD_FLAG_NAME(INITIALIZED), |
23345 |
++ SCSI_CMD_FLAG_NAME(LAST), |
23346 |
+ }; |
23347 |
+ #undef SCSI_CMD_FLAG_NAME |
23348 |
+ |
23349 |
+diff --git a/drivers/scsi/scsi_pm.c b/drivers/scsi/scsi_pm.c |
23350 |
+index 3717eea37ecb3..e91a0a5bc7a3e 100644 |
23351 |
+--- a/drivers/scsi/scsi_pm.c |
23352 |
++++ b/drivers/scsi/scsi_pm.c |
23353 |
+@@ -262,7 +262,7 @@ static int sdev_runtime_resume(struct device *dev) |
23354 |
+ blk_pre_runtime_resume(sdev->request_queue); |
23355 |
+ if (pm && pm->runtime_resume) |
23356 |
+ err = pm->runtime_resume(dev); |
23357 |
+- blk_post_runtime_resume(sdev->request_queue, err); |
23358 |
++ blk_post_runtime_resume(sdev->request_queue); |
23359 |
+ |
23360 |
+ return err; |
23361 |
+ } |
23362 |
+diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c |
23363 |
+index 8b17b35283aa5..1203374828b97 100644 |
23364 |
+--- a/drivers/scsi/sr.c |
23365 |
++++ b/drivers/scsi/sr.c |
23366 |
+@@ -851,7 +851,7 @@ static void get_capabilities(struct scsi_cd *cd) |
23367 |
+ |
23368 |
+ |
23369 |
+ /* allocate transfer buffer */ |
23370 |
+- buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); |
23371 |
++ buffer = kmalloc(512, GFP_KERNEL); |
23372 |
+ if (!buffer) { |
23373 |
+ sr_printk(KERN_ERR, cd, "out of memory.\n"); |
23374 |
+ return; |
23375 |
+diff --git a/drivers/scsi/sr_vendor.c b/drivers/scsi/sr_vendor.c |
23376 |
+index 1f988a1b9166f..a61635326ae0a 100644 |
23377 |
+--- a/drivers/scsi/sr_vendor.c |
23378 |
++++ b/drivers/scsi/sr_vendor.c |
23379 |
+@@ -131,7 +131,7 @@ int sr_set_blocklength(Scsi_CD *cd, int blocklength) |
23380 |
+ if (cd->vendor == VENDOR_TOSHIBA) |
23381 |
+ density = (blocklength > 2048) ? 0x81 : 0x83; |
23382 |
+ |
23383 |
+- buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); |
23384 |
++ buffer = kmalloc(512, GFP_KERNEL); |
23385 |
+ if (!buffer) |
23386 |
+ return -ENOMEM; |
23387 |
+ |
23388 |
+@@ -179,7 +179,7 @@ int sr_cd_check(struct cdrom_device_info *cdi) |
23389 |
+ if (cd->cdi.mask & CDC_MULTI_SESSION) |
23390 |
+ return 0; |
23391 |
+ |
23392 |
+- buffer = kmalloc(512, GFP_KERNEL | GFP_DMA); |
23393 |
++ buffer = kmalloc(512, GFP_KERNEL); |
23394 |
+ if (!buffer) |
23395 |
+ return -ENOMEM; |
23396 |
+ |
23397 |
+diff --git a/drivers/scsi/ufs/tc-dwc-g210-pci.c b/drivers/scsi/ufs/tc-dwc-g210-pci.c |
23398 |
+index 679289e1a78e6..7b08e2e07cc5f 100644 |
23399 |
+--- a/drivers/scsi/ufs/tc-dwc-g210-pci.c |
23400 |
++++ b/drivers/scsi/ufs/tc-dwc-g210-pci.c |
23401 |
+@@ -110,7 +110,6 @@ tc_dwc_g210_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
23402 |
+ return err; |
23403 |
+ } |
23404 |
+ |
23405 |
+- pci_set_drvdata(pdev, hba); |
23406 |
+ pm_runtime_put_noidle(&pdev->dev); |
23407 |
+ pm_runtime_allow(&pdev->dev); |
23408 |
+ |
23409 |
+diff --git a/drivers/scsi/ufs/ufs-mediatek.c b/drivers/scsi/ufs/ufs-mediatek.c |
23410 |
+index 80b3545dd17d6..4e53857605de8 100644 |
23411 |
+--- a/drivers/scsi/ufs/ufs-mediatek.c |
23412 |
++++ b/drivers/scsi/ufs/ufs-mediatek.c |
23413 |
+@@ -501,7 +501,7 @@ static void ufs_mtk_init_va09_pwr_ctrl(struct ufs_hba *hba) |
23414 |
+ struct ufs_mtk_host *host = ufshcd_get_variant(hba); |
23415 |
+ |
23416 |
+ host->reg_va09 = regulator_get(hba->dev, "va09"); |
23417 |
+- if (!host->reg_va09) |
23418 |
++ if (IS_ERR(host->reg_va09)) |
23419 |
+ dev_info(hba->dev, "failed to get va09"); |
23420 |
+ else |
23421 |
+ host->caps |= UFS_MTK_CAP_VA09_PWR_CTRL; |
23422 |
+diff --git a/drivers/scsi/ufs/ufshcd-pci.c b/drivers/scsi/ufs/ufshcd-pci.c |
23423 |
+index f725248ba57f4..f76692053ca17 100644 |
23424 |
+--- a/drivers/scsi/ufs/ufshcd-pci.c |
23425 |
++++ b/drivers/scsi/ufs/ufshcd-pci.c |
23426 |
+@@ -538,8 +538,6 @@ ufshcd_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id) |
23427 |
+ return err; |
23428 |
+ } |
23429 |
+ |
23430 |
+- pci_set_drvdata(pdev, hba); |
23431 |
+- |
23432 |
+ hba->vops = (struct ufs_hba_variant_ops *)id->driver_data; |
23433 |
+ |
23434 |
+ err = ufshcd_init(hba, mmio_base, pdev->irq); |
23435 |
+diff --git a/drivers/scsi/ufs/ufshcd-pltfrm.c b/drivers/scsi/ufs/ufshcd-pltfrm.c |
23436 |
+index eaeae83b999fd..8b16bbbcb806c 100644 |
23437 |
+--- a/drivers/scsi/ufs/ufshcd-pltfrm.c |
23438 |
++++ b/drivers/scsi/ufs/ufshcd-pltfrm.c |
23439 |
+@@ -361,8 +361,6 @@ int ufshcd_pltfrm_init(struct platform_device *pdev, |
23440 |
+ goto dealloc_host; |
23441 |
+ } |
23442 |
+ |
23443 |
+- platform_set_drvdata(pdev, hba); |
23444 |
+- |
23445 |
+ pm_runtime_set_active(&pdev->dev); |
23446 |
+ pm_runtime_enable(&pdev->dev); |
23447 |
+ |
23448 |
+diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c |
23449 |
+index 31adf25e57b0d..ae7bdd8703198 100644 |
23450 |
+--- a/drivers/scsi/ufs/ufshcd.c |
23451 |
++++ b/drivers/scsi/ufs/ufshcd.c |
23452 |
+@@ -1657,7 +1657,8 @@ int ufshcd_hold(struct ufs_hba *hba, bool async) |
23453 |
+ bool flush_result; |
23454 |
+ unsigned long flags; |
23455 |
+ |
23456 |
+- if (!ufshcd_is_clkgating_allowed(hba)) |
23457 |
++ if (!ufshcd_is_clkgating_allowed(hba) || |
23458 |
++ !hba->clk_gating.is_initialized) |
23459 |
+ goto out; |
23460 |
+ spin_lock_irqsave(hba->host->host_lock, flags); |
23461 |
+ hba->clk_gating.active_reqs++; |
23462 |
+@@ -1817,7 +1818,7 @@ static void __ufshcd_release(struct ufs_hba *hba) |
23463 |
+ |
23464 |
+ if (hba->clk_gating.active_reqs || hba->clk_gating.is_suspended || |
23465 |
+ hba->ufshcd_state != UFSHCD_STATE_OPERATIONAL || |
23466 |
+- hba->outstanding_tasks || |
23467 |
++ hba->outstanding_tasks || !hba->clk_gating.is_initialized || |
23468 |
+ hba->active_uic_cmd || hba->uic_async_done || |
23469 |
+ hba->clk_gating.state == CLKS_OFF) |
23470 |
+ return; |
23471 |
+@@ -1952,11 +1953,15 @@ static void ufshcd_exit_clk_gating(struct ufs_hba *hba) |
23472 |
+ { |
23473 |
+ if (!hba->clk_gating.is_initialized) |
23474 |
+ return; |
23475 |
++ |
23476 |
+ ufshcd_remove_clk_gating_sysfs(hba); |
23477 |
+- cancel_work_sync(&hba->clk_gating.ungate_work); |
23478 |
+- cancel_delayed_work_sync(&hba->clk_gating.gate_work); |
23479 |
+- destroy_workqueue(hba->clk_gating.clk_gating_workq); |
23480 |
++ |
23481 |
++ /* Ungate the clock if necessary. */ |
23482 |
++ ufshcd_hold(hba, false); |
23483 |
+ hba->clk_gating.is_initialized = false; |
23484 |
++ ufshcd_release(hba); |
23485 |
++ |
23486 |
++ destroy_workqueue(hba->clk_gating.clk_gating_workq); |
23487 |
+ } |
23488 |
+ |
23489 |
+ /* Must be called with host lock acquired */ |
23490 |
+@@ -9366,6 +9371,13 @@ int ufshcd_init(struct ufs_hba *hba, void __iomem *mmio_base, unsigned int irq) |
23491 |
+ struct device *dev = hba->dev; |
23492 |
+ char eh_wq_name[sizeof("ufs_eh_wq_00")]; |
23493 |
+ |
23494 |
++ /* |
23495 |
++ * dev_set_drvdata() must be called before any callbacks are registered |
23496 |
++ * that use dev_get_drvdata() (frequency scaling, clock scaling, hwmon, |
23497 |
++ * sysfs). |
23498 |
++ */ |
23499 |
++ dev_set_drvdata(dev, hba); |
23500 |
++ |
23501 |
+ if (!mmio_base) { |
23502 |
+ dev_err(hba->dev, |
23503 |
+ "Invalid memory reference for mmio_base is NULL\n"); |
23504 |
+diff --git a/drivers/soc/imx/gpcv2.c b/drivers/soc/imx/gpcv2.c |
23505 |
+index 8b7a01773aec2..b4aa28420f2a8 100644 |
23506 |
+--- a/drivers/soc/imx/gpcv2.c |
23507 |
++++ b/drivers/soc/imx/gpcv2.c |
23508 |
+@@ -369,7 +369,7 @@ static int imx_pgc_power_down(struct generic_pm_domain *genpd) |
23509 |
+ } |
23510 |
+ } |
23511 |
+ |
23512 |
+- pm_runtime_put(domain->dev); |
23513 |
++ pm_runtime_put_sync_suspend(domain->dev); |
23514 |
+ |
23515 |
+ return 0; |
23516 |
+ |
23517 |
+diff --git a/drivers/soc/mediatek/mtk-scpsys.c b/drivers/soc/mediatek/mtk-scpsys.c |
23518 |
+index ca75b14931ec9..670cc82d17dc2 100644 |
23519 |
+--- a/drivers/soc/mediatek/mtk-scpsys.c |
23520 |
++++ b/drivers/soc/mediatek/mtk-scpsys.c |
23521 |
+@@ -411,12 +411,17 @@ out: |
23522 |
+ return ret; |
23523 |
+ } |
23524 |
+ |
23525 |
+-static void init_clks(struct platform_device *pdev, struct clk **clk) |
23526 |
++static int init_clks(struct platform_device *pdev, struct clk **clk) |
23527 |
+ { |
23528 |
+ int i; |
23529 |
+ |
23530 |
+- for (i = CLK_NONE + 1; i < CLK_MAX; i++) |
23531 |
++ for (i = CLK_NONE + 1; i < CLK_MAX; i++) { |
23532 |
+ clk[i] = devm_clk_get(&pdev->dev, clk_names[i]); |
23533 |
++ if (IS_ERR(clk[i])) |
23534 |
++ return PTR_ERR(clk[i]); |
23535 |
++ } |
23536 |
++ |
23537 |
++ return 0; |
23538 |
+ } |
23539 |
+ |
23540 |
+ static struct scp *init_scp(struct platform_device *pdev, |
23541 |
+@@ -426,7 +431,7 @@ static struct scp *init_scp(struct platform_device *pdev, |
23542 |
+ { |
23543 |
+ struct genpd_onecell_data *pd_data; |
23544 |
+ struct resource *res; |
23545 |
+- int i, j; |
23546 |
++ int i, j, ret; |
23547 |
+ struct scp *scp; |
23548 |
+ struct clk *clk[CLK_MAX]; |
23549 |
+ |
23550 |
+@@ -481,7 +486,9 @@ static struct scp *init_scp(struct platform_device *pdev, |
23551 |
+ |
23552 |
+ pd_data->num_domains = num; |
23553 |
+ |
23554 |
+- init_clks(pdev, clk); |
23555 |
++ ret = init_clks(pdev, clk); |
23556 |
++ if (ret) |
23557 |
++ return ERR_PTR(ret); |
23558 |
+ |
23559 |
+ for (i = 0; i < num; i++) { |
23560 |
+ struct scp_domain *scpd = &scp->domains[i]; |
23561 |
+diff --git a/drivers/soc/qcom/cpr.c b/drivers/soc/qcom/cpr.c |
23562 |
+index 4ce8e816154f9..84dd93472a252 100644 |
23563 |
+--- a/drivers/soc/qcom/cpr.c |
23564 |
++++ b/drivers/soc/qcom/cpr.c |
23565 |
+@@ -1010,7 +1010,7 @@ static int cpr_interpolate(const struct corner *corner, int step_volt, |
23566 |
+ return corner->uV; |
23567 |
+ |
23568 |
+ temp = f_diff * (uV_high - uV_low); |
23569 |
+- do_div(temp, f_high - f_low); |
23570 |
++ temp = div64_ul(temp, f_high - f_low); |
23571 |
+ |
23572 |
+ /* |
23573 |
+ * max_volt_scale has units of uV/MHz while freq values |
23574 |
+diff --git a/drivers/soc/ti/pruss.c b/drivers/soc/ti/pruss.c |
23575 |
+index 49da387d77494..b36779309e49b 100644 |
23576 |
+--- a/drivers/soc/ti/pruss.c |
23577 |
++++ b/drivers/soc/ti/pruss.c |
23578 |
+@@ -129,7 +129,7 @@ static int pruss_clk_init(struct pruss *pruss, struct device_node *cfg_node) |
23579 |
+ |
23580 |
+ clks_np = of_get_child_by_name(cfg_node, "clocks"); |
23581 |
+ if (!clks_np) { |
23582 |
+- dev_err(dev, "%pOF is missing its 'clocks' node\n", clks_np); |
23583 |
++ dev_err(dev, "%pOF is missing its 'clocks' node\n", cfg_node); |
23584 |
+ return -ENODEV; |
23585 |
+ } |
23586 |
+ |
23587 |
+diff --git a/drivers/spi/spi-hisi-kunpeng.c b/drivers/spi/spi-hisi-kunpeng.c |
23588 |
+index 58b823a16fc4d..525cc0143a305 100644 |
23589 |
+--- a/drivers/spi/spi-hisi-kunpeng.c |
23590 |
++++ b/drivers/spi/spi-hisi-kunpeng.c |
23591 |
+@@ -127,7 +127,6 @@ struct hisi_spi { |
23592 |
+ void __iomem *regs; |
23593 |
+ int irq; |
23594 |
+ u32 fifo_len; /* depth of the FIFO buffer */ |
23595 |
+- u16 bus_num; |
23596 |
+ |
23597 |
+ /* Current message transfer state info */ |
23598 |
+ const void *tx; |
23599 |
+@@ -165,7 +164,10 @@ static int hisi_spi_debugfs_init(struct hisi_spi *hs) |
23600 |
+ { |
23601 |
+ char name[32]; |
23602 |
+ |
23603 |
+- snprintf(name, 32, "hisi_spi%d", hs->bus_num); |
23604 |
++ struct spi_controller *master; |
23605 |
++ |
23606 |
++ master = container_of(hs->dev, struct spi_controller, dev); |
23607 |
++ snprintf(name, 32, "hisi_spi%d", master->bus_num); |
23608 |
+ hs->debugfs = debugfs_create_dir(name, NULL); |
23609 |
+ if (!hs->debugfs) |
23610 |
+ return -ENOMEM; |
23611 |
+@@ -467,7 +469,6 @@ static int hisi_spi_probe(struct platform_device *pdev) |
23612 |
+ hs = spi_controller_get_devdata(master); |
23613 |
+ hs->dev = dev; |
23614 |
+ hs->irq = irq; |
23615 |
+- hs->bus_num = pdev->id; |
23616 |
+ |
23617 |
+ hs->regs = devm_platform_ioremap_resource(pdev, 0); |
23618 |
+ if (IS_ERR(hs->regs)) |
23619 |
+@@ -490,7 +491,7 @@ static int hisi_spi_probe(struct platform_device *pdev) |
23620 |
+ master->use_gpio_descriptors = true; |
23621 |
+ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_CS_HIGH | SPI_LOOP; |
23622 |
+ master->bits_per_word_mask = SPI_BPW_RANGE_MASK(4, 32); |
23623 |
+- master->bus_num = hs->bus_num; |
23624 |
++ master->bus_num = pdev->id; |
23625 |
+ master->setup = hisi_spi_setup; |
23626 |
+ master->cleanup = hisi_spi_cleanup; |
23627 |
+ master->transfer_one = hisi_spi_transfer_one; |
23628 |
+@@ -506,15 +507,15 @@ static int hisi_spi_probe(struct platform_device *pdev) |
23629 |
+ return ret; |
23630 |
+ } |
23631 |
+ |
23632 |
+- if (hisi_spi_debugfs_init(hs)) |
23633 |
+- dev_info(dev, "failed to create debugfs dir\n"); |
23634 |
+- |
23635 |
+ ret = spi_register_controller(master); |
23636 |
+ if (ret) { |
23637 |
+ dev_err(dev, "failed to register spi master, ret=%d\n", ret); |
23638 |
+ return ret; |
23639 |
+ } |
23640 |
+ |
23641 |
++ if (hisi_spi_debugfs_init(hs)) |
23642 |
++ dev_info(dev, "failed to create debugfs dir\n"); |
23643 |
++ |
23644 |
+ dev_info(dev, "hw version:0x%x max-freq:%u kHz\n", |
23645 |
+ readl(hs->regs + HISI_SPI_VERSION), |
23646 |
+ master->max_speed_hz / 1000); |
23647 |
+diff --git a/drivers/spi/spi-meson-spifc.c b/drivers/spi/spi-meson-spifc.c |
23648 |
+index 8eca6f24cb799..c8ed7815c4ba6 100644 |
23649 |
+--- a/drivers/spi/spi-meson-spifc.c |
23650 |
++++ b/drivers/spi/spi-meson-spifc.c |
23651 |
+@@ -349,6 +349,7 @@ static int meson_spifc_probe(struct platform_device *pdev) |
23652 |
+ return 0; |
23653 |
+ out_clk: |
23654 |
+ clk_disable_unprepare(spifc->clk); |
23655 |
++ pm_runtime_disable(spifc->dev); |
23656 |
+ out_err: |
23657 |
+ spi_master_put(master); |
23658 |
+ return ret; |
23659 |
+diff --git a/drivers/spi/spi-uniphier.c b/drivers/spi/spi-uniphier.c |
23660 |
+index 8900e51e1a1cc..342ee8d2c4761 100644 |
23661 |
+--- a/drivers/spi/spi-uniphier.c |
23662 |
++++ b/drivers/spi/spi-uniphier.c |
23663 |
+@@ -767,12 +767,13 @@ out_master_put: |
23664 |
+ |
23665 |
+ static int uniphier_spi_remove(struct platform_device *pdev) |
23666 |
+ { |
23667 |
+- struct uniphier_spi_priv *priv = platform_get_drvdata(pdev); |
23668 |
++ struct spi_master *master = platform_get_drvdata(pdev); |
23669 |
++ struct uniphier_spi_priv *priv = spi_master_get_devdata(master); |
23670 |
+ |
23671 |
+- if (priv->master->dma_tx) |
23672 |
+- dma_release_channel(priv->master->dma_tx); |
23673 |
+- if (priv->master->dma_rx) |
23674 |
+- dma_release_channel(priv->master->dma_rx); |
23675 |
++ if (master->dma_tx) |
23676 |
++ dma_release_channel(master->dma_tx); |
23677 |
++ if (master->dma_rx) |
23678 |
++ dma_release_channel(master->dma_rx); |
23679 |
+ |
23680 |
+ clk_disable_unprepare(priv->clk); |
23681 |
+ |
23682 |
+diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c |
23683 |
+index 97b5a811bd7f7..a42b9e8521ce0 100644 |
23684 |
+--- a/drivers/spi/spi.c |
23685 |
++++ b/drivers/spi/spi.c |
23686 |
+@@ -868,12 +868,9 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) |
23687 |
+ spi->controller->last_cs_enable = enable; |
23688 |
+ spi->controller->last_cs_mode_high = spi->mode & SPI_CS_HIGH; |
23689 |
+ |
23690 |
+- if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) || |
23691 |
+- !spi->controller->set_cs_timing) { |
23692 |
+- if (activate) |
23693 |
+- spi_delay_exec(&spi->cs_setup, NULL); |
23694 |
+- else |
23695 |
+- spi_delay_exec(&spi->cs_hold, NULL); |
23696 |
++ if ((spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) || |
23697 |
++ !spi->controller->set_cs_timing) && !activate) { |
23698 |
++ spi_delay_exec(&spi->cs_hold, NULL); |
23699 |
+ } |
23700 |
+ |
23701 |
+ if (spi->mode & SPI_CS_HIGH) |
23702 |
+@@ -915,7 +912,9 @@ static void spi_set_cs(struct spi_device *spi, bool enable, bool force) |
23703 |
+ |
23704 |
+ if (spi->cs_gpiod || gpio_is_valid(spi->cs_gpio) || |
23705 |
+ !spi->controller->set_cs_timing) { |
23706 |
+- if (!activate) |
23707 |
++ if (activate) |
23708 |
++ spi_delay_exec(&spi->cs_setup, NULL); |
23709 |
++ else |
23710 |
+ spi_delay_exec(&spi->cs_inactive, NULL); |
23711 |
+ } |
23712 |
+ } |
23713 |
+diff --git a/drivers/staging/greybus/audio_topology.c b/drivers/staging/greybus/audio_topology.c |
23714 |
+index 7f7d558b76d04..62d7674852bec 100644 |
23715 |
+--- a/drivers/staging/greybus/audio_topology.c |
23716 |
++++ b/drivers/staging/greybus/audio_topology.c |
23717 |
+@@ -147,6 +147,9 @@ static const char **gb_generate_enum_strings(struct gbaudio_module_info *gb, |
23718 |
+ |
23719 |
+ items = le32_to_cpu(gbenum->items); |
23720 |
+ strings = devm_kcalloc(gb->dev, items, sizeof(char *), GFP_KERNEL); |
23721 |
++ if (!strings) |
23722 |
++ return NULL; |
23723 |
++ |
23724 |
+ data = gbenum->names; |
23725 |
+ |
23726 |
+ for (i = 0; i < items; i++) { |
23727 |
+@@ -655,6 +658,8 @@ static int gbaudio_tplg_create_enum_kctl(struct gbaudio_module_info *gb, |
23728 |
+ /* since count=1, and reg is dummy */ |
23729 |
+ gbe->items = le32_to_cpu(gb_enum->items); |
23730 |
+ gbe->texts = gb_generate_enum_strings(gb, gb_enum); |
23731 |
++ if (!gbe->texts) |
23732 |
++ return -ENOMEM; |
23733 |
+ |
23734 |
+ /* debug enum info */ |
23735 |
+ dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->items, |
23736 |
+@@ -862,6 +867,8 @@ static int gbaudio_tplg_create_enum_ctl(struct gbaudio_module_info *gb, |
23737 |
+ /* since count=1, and reg is dummy */ |
23738 |
+ gbe->items = le32_to_cpu(gb_enum->items); |
23739 |
+ gbe->texts = gb_generate_enum_strings(gb, gb_enum); |
23740 |
++ if (!gbe->texts) |
23741 |
++ return -ENOMEM; |
23742 |
+ |
23743 |
+ /* debug enum info */ |
23744 |
+ dev_dbg(gb->dev, "Max:%d, name_length:%d\n", gbe->items, |
23745 |
+@@ -1072,6 +1079,10 @@ static int gbaudio_tplg_create_widget(struct gbaudio_module_info *module, |
23746 |
+ csize += le16_to_cpu(gbenum->names_length); |
23747 |
+ control->texts = (const char * const *) |
23748 |
+ gb_generate_enum_strings(module, gbenum); |
23749 |
++ if (!control->texts) { |
23750 |
++ ret = -ENOMEM; |
23751 |
++ goto error; |
23752 |
++ } |
23753 |
+ control->items = le32_to_cpu(gbenum->items); |
23754 |
+ } else { |
23755 |
+ csize = sizeof(struct gb_audio_control); |
23756 |
+@@ -1181,6 +1192,10 @@ static int gbaudio_tplg_process_kcontrols(struct gbaudio_module_info *module, |
23757 |
+ csize += le16_to_cpu(gbenum->names_length); |
23758 |
+ control->texts = (const char * const *) |
23759 |
+ gb_generate_enum_strings(module, gbenum); |
23760 |
++ if (!control->texts) { |
23761 |
++ ret = -ENOMEM; |
23762 |
++ goto error; |
23763 |
++ } |
23764 |
+ control->items = le32_to_cpu(gbenum->items); |
23765 |
+ } else { |
23766 |
+ csize = sizeof(struct gb_audio_control); |
23767 |
+diff --git a/drivers/staging/media/atomisp/i2c/ov2680.h b/drivers/staging/media/atomisp/i2c/ov2680.h |
23768 |
+index 874115f35fcad..798b28e134b64 100644 |
23769 |
+--- a/drivers/staging/media/atomisp/i2c/ov2680.h |
23770 |
++++ b/drivers/staging/media/atomisp/i2c/ov2680.h |
23771 |
+@@ -289,8 +289,6 @@ static struct ov2680_reg const ov2680_global_setting[] = { |
23772 |
+ */ |
23773 |
+ static struct ov2680_reg const ov2680_QCIF_30fps[] = { |
23774 |
+ {0x3086, 0x01}, |
23775 |
+- {0x3501, 0x24}, |
23776 |
+- {0x3502, 0x40}, |
23777 |
+ {0x370a, 0x23}, |
23778 |
+ {0x3801, 0xa0}, |
23779 |
+ {0x3802, 0x00}, |
23780 |
+@@ -334,8 +332,6 @@ static struct ov2680_reg const ov2680_QCIF_30fps[] = { |
23781 |
+ */ |
23782 |
+ static struct ov2680_reg const ov2680_CIF_30fps[] = { |
23783 |
+ {0x3086, 0x01}, |
23784 |
+- {0x3501, 0x24}, |
23785 |
+- {0x3502, 0x40}, |
23786 |
+ {0x370a, 0x23}, |
23787 |
+ {0x3801, 0xa0}, |
23788 |
+ {0x3802, 0x00}, |
23789 |
+@@ -377,8 +373,6 @@ static struct ov2680_reg const ov2680_CIF_30fps[] = { |
23790 |
+ */ |
23791 |
+ static struct ov2680_reg const ov2680_QVGA_30fps[] = { |
23792 |
+ {0x3086, 0x01}, |
23793 |
+- {0x3501, 0x24}, |
23794 |
+- {0x3502, 0x40}, |
23795 |
+ {0x370a, 0x23}, |
23796 |
+ {0x3801, 0xa0}, |
23797 |
+ {0x3802, 0x00}, |
23798 |
+@@ -420,8 +414,6 @@ static struct ov2680_reg const ov2680_QVGA_30fps[] = { |
23799 |
+ */ |
23800 |
+ static struct ov2680_reg const ov2680_656x496_30fps[] = { |
23801 |
+ {0x3086, 0x01}, |
23802 |
+- {0x3501, 0x24}, |
23803 |
+- {0x3502, 0x40}, |
23804 |
+ {0x370a, 0x23}, |
23805 |
+ {0x3801, 0xa0}, |
23806 |
+ {0x3802, 0x00}, |
23807 |
+@@ -463,8 +455,6 @@ static struct ov2680_reg const ov2680_656x496_30fps[] = { |
23808 |
+ */ |
23809 |
+ static struct ov2680_reg const ov2680_720x592_30fps[] = { |
23810 |
+ {0x3086, 0x01}, |
23811 |
+- {0x3501, 0x26}, |
23812 |
+- {0x3502, 0x40}, |
23813 |
+ {0x370a, 0x23}, |
23814 |
+ {0x3801, 0x00}, // X_ADDR_START; |
23815 |
+ {0x3802, 0x00}, |
23816 |
+@@ -508,8 +498,6 @@ static struct ov2680_reg const ov2680_720x592_30fps[] = { |
23817 |
+ */ |
23818 |
+ static struct ov2680_reg const ov2680_800x600_30fps[] = { |
23819 |
+ {0x3086, 0x01}, |
23820 |
+- {0x3501, 0x26}, |
23821 |
+- {0x3502, 0x40}, |
23822 |
+ {0x370a, 0x23}, |
23823 |
+ {0x3801, 0x00}, |
23824 |
+ {0x3802, 0x00}, |
23825 |
+@@ -551,8 +539,6 @@ static struct ov2680_reg const ov2680_800x600_30fps[] = { |
23826 |
+ */ |
23827 |
+ static struct ov2680_reg const ov2680_720p_30fps[] = { |
23828 |
+ {0x3086, 0x00}, |
23829 |
+- {0x3501, 0x48}, |
23830 |
+- {0x3502, 0xe0}, |
23831 |
+ {0x370a, 0x21}, |
23832 |
+ {0x3801, 0xa0}, |
23833 |
+ {0x3802, 0x00}, |
23834 |
+@@ -594,8 +580,6 @@ static struct ov2680_reg const ov2680_720p_30fps[] = { |
23835 |
+ */ |
23836 |
+ static struct ov2680_reg const ov2680_1296x976_30fps[] = { |
23837 |
+ {0x3086, 0x00}, |
23838 |
+- {0x3501, 0x48}, |
23839 |
+- {0x3502, 0xe0}, |
23840 |
+ {0x370a, 0x21}, |
23841 |
+ {0x3801, 0xa0}, |
23842 |
+ {0x3802, 0x00}, |
23843 |
+@@ -637,8 +621,6 @@ static struct ov2680_reg const ov2680_1296x976_30fps[] = { |
23844 |
+ */ |
23845 |
+ static struct ov2680_reg const ov2680_1456x1096_30fps[] = { |
23846 |
+ {0x3086, 0x00}, |
23847 |
+- {0x3501, 0x48}, |
23848 |
+- {0x3502, 0xe0}, |
23849 |
+ {0x370a, 0x21}, |
23850 |
+ {0x3801, 0x90}, |
23851 |
+ {0x3802, 0x00}, |
23852 |
+@@ -682,8 +664,6 @@ static struct ov2680_reg const ov2680_1456x1096_30fps[] = { |
23853 |
+ |
23854 |
+ static struct ov2680_reg const ov2680_1616x916_30fps[] = { |
23855 |
+ {0x3086, 0x00}, |
23856 |
+- {0x3501, 0x48}, |
23857 |
+- {0x3502, 0xe0}, |
23858 |
+ {0x370a, 0x21}, |
23859 |
+ {0x3801, 0x00}, |
23860 |
+ {0x3802, 0x00}, |
23861 |
+@@ -726,8 +706,6 @@ static struct ov2680_reg const ov2680_1616x916_30fps[] = { |
23862 |
+ #if 0 |
23863 |
+ static struct ov2680_reg const ov2680_1616x1082_30fps[] = { |
23864 |
+ {0x3086, 0x00}, |
23865 |
+- {0x3501, 0x48}, |
23866 |
+- {0x3502, 0xe0}, |
23867 |
+ {0x370a, 0x21}, |
23868 |
+ {0x3801, 0x00}, |
23869 |
+ {0x3802, 0x00}, |
23870 |
+@@ -769,8 +747,6 @@ static struct ov2680_reg const ov2680_1616x1082_30fps[] = { |
23871 |
+ */ |
23872 |
+ static struct ov2680_reg const ov2680_1616x1216_30fps[] = { |
23873 |
+ {0x3086, 0x00}, |
23874 |
+- {0x3501, 0x48}, |
23875 |
+- {0x3502, 0xe0}, |
23876 |
+ {0x370a, 0x21}, |
23877 |
+ {0x3801, 0x00}, |
23878 |
+ {0x3802, 0x00}, |
23879 |
+diff --git a/drivers/staging/media/atomisp/pci/atomisp_cmd.c b/drivers/staging/media/atomisp/pci/atomisp_cmd.c |
23880 |
+index 366161cff5602..ef0b0963cf930 100644 |
23881 |
+--- a/drivers/staging/media/atomisp/pci/atomisp_cmd.c |
23882 |
++++ b/drivers/staging/media/atomisp/pci/atomisp_cmd.c |
23883 |
+@@ -1715,6 +1715,12 @@ void atomisp_wdt_refresh_pipe(struct atomisp_video_pipe *pipe, |
23884 |
+ { |
23885 |
+ unsigned long next; |
23886 |
+ |
23887 |
++ if (!pipe->asd) { |
23888 |
++ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", |
23889 |
++ __func__, pipe->vdev.name); |
23890 |
++ return; |
23891 |
++ } |
23892 |
++ |
23893 |
+ if (delay != ATOMISP_WDT_KEEP_CURRENT_DELAY) |
23894 |
+ pipe->wdt_duration = delay; |
23895 |
+ |
23896 |
+@@ -1777,6 +1783,12 @@ void atomisp_wdt_refresh(struct atomisp_sub_device *asd, unsigned int delay) |
23897 |
+ /* ISP2401 */ |
23898 |
+ void atomisp_wdt_stop_pipe(struct atomisp_video_pipe *pipe, bool sync) |
23899 |
+ { |
23900 |
++ if (!pipe->asd) { |
23901 |
++ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", |
23902 |
++ __func__, pipe->vdev.name); |
23903 |
++ return; |
23904 |
++ } |
23905 |
++ |
23906 |
+ if (!atomisp_is_wdt_running(pipe)) |
23907 |
+ return; |
23908 |
+ |
23909 |
+@@ -4109,6 +4121,12 @@ void atomisp_handle_parameter_and_buffer(struct atomisp_video_pipe *pipe) |
23910 |
+ unsigned long irqflags; |
23911 |
+ bool need_to_enqueue_buffer = false; |
23912 |
+ |
23913 |
++ if (!asd) { |
23914 |
++ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", |
23915 |
++ __func__, pipe->vdev.name); |
23916 |
++ return; |
23917 |
++ } |
23918 |
++ |
23919 |
+ if (atomisp_is_vf_pipe(pipe)) |
23920 |
+ return; |
23921 |
+ |
23922 |
+@@ -4196,6 +4214,12 @@ int atomisp_set_parameters(struct video_device *vdev, |
23923 |
+ struct atomisp_css_params *css_param = &asd->params.css_param; |
23924 |
+ int ret; |
23925 |
+ |
23926 |
++ if (!asd) { |
23927 |
++ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", |
23928 |
++ __func__, vdev->name); |
23929 |
++ return -EINVAL; |
23930 |
++ } |
23931 |
++ |
23932 |
+ if (!asd->stream_env[ATOMISP_INPUT_STREAM_GENERAL].stream) { |
23933 |
+ dev_err(asd->isp->dev, "%s: internal error!\n", __func__); |
23934 |
+ return -EINVAL; |
23935 |
+@@ -4857,6 +4881,12 @@ int atomisp_try_fmt(struct video_device *vdev, struct v4l2_pix_format *f, |
23936 |
+ int source_pad = atomisp_subdev_source_pad(vdev); |
23937 |
+ int ret; |
23938 |
+ |
23939 |
++ if (!asd) { |
23940 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
23941 |
++ __func__, vdev->name); |
23942 |
++ return -EINVAL; |
23943 |
++ } |
23944 |
++ |
23945 |
+ if (!isp->inputs[asd->input_curr].camera) |
23946 |
+ return -EINVAL; |
23947 |
+ |
23948 |
+@@ -5194,10 +5224,17 @@ static int atomisp_set_fmt_to_isp(struct video_device *vdev, |
23949 |
+ int (*configure_pp_input)(struct atomisp_sub_device *asd, |
23950 |
+ unsigned int width, unsigned int height) = |
23951 |
+ configure_pp_input_nop; |
23952 |
+- u16 stream_index = atomisp_source_pad_to_stream_id(asd, source_pad); |
23953 |
++ u16 stream_index; |
23954 |
+ const struct atomisp_in_fmt_conv *fc; |
23955 |
+ int ret, i; |
23956 |
+ |
23957 |
++ if (!asd) { |
23958 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
23959 |
++ __func__, vdev->name); |
23960 |
++ return -EINVAL; |
23961 |
++ } |
23962 |
++ stream_index = atomisp_source_pad_to_stream_id(asd, source_pad); |
23963 |
++ |
23964 |
+ v4l2_fh_init(&fh.vfh, vdev); |
23965 |
+ |
23966 |
+ isp_sink_crop = atomisp_subdev_get_rect( |
23967 |
+@@ -5493,7 +5530,8 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, |
23968 |
+ unsigned int padding_w, unsigned int padding_h, |
23969 |
+ unsigned int dvs_env_w, unsigned int dvs_env_h) |
23970 |
+ { |
23971 |
+- struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; |
23972 |
++ struct atomisp_video_pipe *pipe = atomisp_to_video_pipe(vdev); |
23973 |
++ struct atomisp_sub_device *asd = pipe->asd; |
23974 |
+ const struct atomisp_format_bridge *format; |
23975 |
+ struct v4l2_subdev_pad_config pad_cfg; |
23976 |
+ struct v4l2_subdev_state pad_state = { |
23977 |
+@@ -5504,7 +5542,7 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, |
23978 |
+ }; |
23979 |
+ struct v4l2_mbus_framefmt *ffmt = &vformat.format; |
23980 |
+ struct v4l2_mbus_framefmt *req_ffmt; |
23981 |
+- struct atomisp_device *isp = asd->isp; |
23982 |
++ struct atomisp_device *isp; |
23983 |
+ struct atomisp_input_stream_info *stream_info = |
23984 |
+ (struct atomisp_input_stream_info *)ffmt->reserved; |
23985 |
+ u16 stream_index = ATOMISP_INPUT_STREAM_GENERAL; |
23986 |
+@@ -5512,6 +5550,14 @@ static int atomisp_set_fmt_to_snr(struct video_device *vdev, |
23987 |
+ struct v4l2_subdev_fh fh; |
23988 |
+ int ret; |
23989 |
+ |
23990 |
++ if (!asd) { |
23991 |
++ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", |
23992 |
++ __func__, vdev->name); |
23993 |
++ return -EINVAL; |
23994 |
++ } |
23995 |
++ |
23996 |
++ isp = asd->isp; |
23997 |
++ |
23998 |
+ v4l2_fh_init(&fh.vfh, vdev); |
23999 |
+ |
24000 |
+ stream_index = atomisp_source_pad_to_stream_id(asd, source_pad); |
24001 |
+@@ -5602,6 +5648,12 @@ int atomisp_set_fmt(struct video_device *vdev, struct v4l2_format *f) |
24002 |
+ struct v4l2_subdev_fh fh; |
24003 |
+ int ret; |
24004 |
+ |
24005 |
++ if (!asd) { |
24006 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24007 |
++ __func__, vdev->name); |
24008 |
++ return -EINVAL; |
24009 |
++ } |
24010 |
++ |
24011 |
+ if (source_pad >= ATOMISP_SUBDEV_PADS_NUM) |
24012 |
+ return -EINVAL; |
24013 |
+ |
24014 |
+@@ -6034,6 +6086,12 @@ int atomisp_set_fmt_file(struct video_device *vdev, struct v4l2_format *f) |
24015 |
+ struct v4l2_subdev_fh fh; |
24016 |
+ int ret; |
24017 |
+ |
24018 |
++ if (!asd) { |
24019 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24020 |
++ __func__, vdev->name); |
24021 |
++ return -EINVAL; |
24022 |
++ } |
24023 |
++ |
24024 |
+ v4l2_fh_init(&fh.vfh, vdev); |
24025 |
+ |
24026 |
+ dev_dbg(isp->dev, "setting fmt %ux%u 0x%x for file inject\n", |
24027 |
+@@ -6359,6 +6417,12 @@ bool atomisp_is_vf_pipe(struct atomisp_video_pipe *pipe) |
24028 |
+ { |
24029 |
+ struct atomisp_sub_device *asd = pipe->asd; |
24030 |
+ |
24031 |
++ if (!asd) { |
24032 |
++ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", |
24033 |
++ __func__, pipe->vdev.name); |
24034 |
++ return false; |
24035 |
++ } |
24036 |
++ |
24037 |
+ if (pipe == &asd->video_out_vf) |
24038 |
+ return true; |
24039 |
+ |
24040 |
+@@ -6572,6 +6636,12 @@ static int atomisp_get_pipe_id(struct atomisp_video_pipe *pipe) |
24041 |
+ { |
24042 |
+ struct atomisp_sub_device *asd = pipe->asd; |
24043 |
+ |
24044 |
++ if (!asd) { |
24045 |
++ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", |
24046 |
++ __func__, pipe->vdev.name); |
24047 |
++ return -EINVAL; |
24048 |
++ } |
24049 |
++ |
24050 |
+ if (ATOMISP_USE_YUVPP(asd)) { |
24051 |
+ return IA_CSS_PIPE_ID_YUVPP; |
24052 |
+ } else if (asd->vfpp->val == ATOMISP_VFPP_DISABLE_SCALER) { |
24053 |
+@@ -6609,6 +6679,12 @@ int atomisp_get_invalid_frame_num(struct video_device *vdev, |
24054 |
+ struct ia_css_pipe_info p_info; |
24055 |
+ int ret; |
24056 |
+ |
24057 |
++ if (!asd) { |
24058 |
++ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", |
24059 |
++ __func__, vdev->name); |
24060 |
++ return -EINVAL; |
24061 |
++ } |
24062 |
++ |
24063 |
+ if (asd->isp->inputs[asd->input_curr].camera_caps-> |
24064 |
+ sensor[asd->sensor_curr].stream_num > 1) { |
24065 |
+ /* External ISP */ |
24066 |
+diff --git a/drivers/staging/media/atomisp/pci/atomisp_fops.c b/drivers/staging/media/atomisp/pci/atomisp_fops.c |
24067 |
+index f82bf082aa796..18fff47bd25d2 100644 |
24068 |
+--- a/drivers/staging/media/atomisp/pci/atomisp_fops.c |
24069 |
++++ b/drivers/staging/media/atomisp/pci/atomisp_fops.c |
24070 |
+@@ -877,6 +877,11 @@ done: |
24071 |
+ else |
24072 |
+ pipe->users++; |
24073 |
+ rt_mutex_unlock(&isp->mutex); |
24074 |
++ |
24075 |
++ /* Ensure that a mode is set */ |
24076 |
++ if (asd) |
24077 |
++ v4l2_ctrl_s_ctrl(asd->run_mode, pipe->default_run_mode); |
24078 |
++ |
24079 |
+ return 0; |
24080 |
+ |
24081 |
+ css_error: |
24082 |
+@@ -1171,6 +1176,12 @@ static int atomisp_mmap(struct file *file, struct vm_area_struct *vma) |
24083 |
+ u32 origin_size, new_size; |
24084 |
+ int ret; |
24085 |
+ |
24086 |
++ if (!asd) { |
24087 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24088 |
++ __func__, vdev->name); |
24089 |
++ return -EINVAL; |
24090 |
++ } |
24091 |
++ |
24092 |
+ if (!(vma->vm_flags & (VM_WRITE | VM_READ))) |
24093 |
+ return -EACCES; |
24094 |
+ |
24095 |
+diff --git a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c |
24096 |
+index d8c9e31314b2e..62dc06e224765 100644 |
24097 |
+--- a/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c |
24098 |
++++ b/drivers/staging/media/atomisp/pci/atomisp_gmin_platform.c |
24099 |
+@@ -481,7 +481,7 @@ fail: |
24100 |
+ |
24101 |
+ static u8 gmin_get_pmic_id_and_addr(struct device *dev) |
24102 |
+ { |
24103 |
+- struct i2c_client *power; |
24104 |
++ struct i2c_client *power = NULL; |
24105 |
+ static u8 pmic_i2c_addr; |
24106 |
+ |
24107 |
+ if (pmic_id) |
24108 |
+diff --git a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c |
24109 |
+index c8a625667e81e..b7dda4b96d49c 100644 |
24110 |
+--- a/drivers/staging/media/atomisp/pci/atomisp_ioctl.c |
24111 |
++++ b/drivers/staging/media/atomisp/pci/atomisp_ioctl.c |
24112 |
+@@ -646,6 +646,12 @@ static int atomisp_g_input(struct file *file, void *fh, unsigned int *input) |
24113 |
+ struct atomisp_device *isp = video_get_drvdata(vdev); |
24114 |
+ struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; |
24115 |
+ |
24116 |
++ if (!asd) { |
24117 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24118 |
++ __func__, vdev->name); |
24119 |
++ return -EINVAL; |
24120 |
++ } |
24121 |
++ |
24122 |
+ rt_mutex_lock(&isp->mutex); |
24123 |
+ *input = asd->input_curr; |
24124 |
+ rt_mutex_unlock(&isp->mutex); |
24125 |
+@@ -665,6 +671,12 @@ static int atomisp_s_input(struct file *file, void *fh, unsigned int input) |
24126 |
+ struct v4l2_subdev *motor; |
24127 |
+ int ret; |
24128 |
+ |
24129 |
++ if (!asd) { |
24130 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24131 |
++ __func__, vdev->name); |
24132 |
++ return -EINVAL; |
24133 |
++ } |
24134 |
++ |
24135 |
+ rt_mutex_lock(&isp->mutex); |
24136 |
+ if (input >= ATOM_ISP_MAX_INPUTS || input >= isp->input_cnt) { |
24137 |
+ dev_dbg(isp->dev, "input_cnt: %d\n", isp->input_cnt); |
24138 |
+@@ -761,18 +773,33 @@ static int atomisp_enum_fmt_cap(struct file *file, void *fh, |
24139 |
+ struct video_device *vdev = video_devdata(file); |
24140 |
+ struct atomisp_device *isp = video_get_drvdata(vdev); |
24141 |
+ struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; |
24142 |
+- struct v4l2_subdev_mbus_code_enum code = { 0 }; |
24143 |
++ struct v4l2_subdev_mbus_code_enum code = { |
24144 |
++ .which = V4L2_SUBDEV_FORMAT_ACTIVE, |
24145 |
++ }; |
24146 |
++ struct v4l2_subdev *camera; |
24147 |
+ unsigned int i, fi = 0; |
24148 |
+ int rval; |
24149 |
+ |
24150 |
++ if (!asd) { |
24151 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24152 |
++ __func__, vdev->name); |
24153 |
++ return -EINVAL; |
24154 |
++ } |
24155 |
++ |
24156 |
++ camera = isp->inputs[asd->input_curr].camera; |
24157 |
++ if(!camera) { |
24158 |
++ dev_err(isp->dev, "%s(): camera is NULL, device is %s\n", |
24159 |
++ __func__, vdev->name); |
24160 |
++ return -EINVAL; |
24161 |
++ } |
24162 |
++ |
24163 |
+ rt_mutex_lock(&isp->mutex); |
24164 |
+- rval = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, pad, |
24165 |
+- enum_mbus_code, NULL, &code); |
24166 |
++ |
24167 |
++ rval = v4l2_subdev_call(camera, pad, enum_mbus_code, NULL, &code); |
24168 |
+ if (rval == -ENOIOCTLCMD) { |
24169 |
+ dev_warn(isp->dev, |
24170 |
+- "enum_mbus_code pad op not supported. Please fix your sensor driver!\n"); |
24171 |
+- // rval = v4l2_subdev_call(isp->inputs[asd->input_curr].camera, |
24172 |
+- // video, enum_mbus_fmt, 0, &code.code); |
24173 |
++ "enum_mbus_code pad op not supported by %s. Please fix your sensor driver!\n", |
24174 |
++ camera->name); |
24175 |
+ } |
24176 |
+ rt_mutex_unlock(&isp->mutex); |
24177 |
+ |
24178 |
+@@ -802,6 +829,8 @@ static int atomisp_enum_fmt_cap(struct file *file, void *fh, |
24179 |
+ f->pixelformat = format->pixelformat; |
24180 |
+ return 0; |
24181 |
+ } |
24182 |
++ dev_err(isp->dev, "%s(): format for code %x not found.\n", |
24183 |
++ __func__, code.code); |
24184 |
+ |
24185 |
+ return -EINVAL; |
24186 |
+ } |
24187 |
+@@ -834,6 +863,72 @@ static int atomisp_g_fmt_file(struct file *file, void *fh, |
24188 |
+ return 0; |
24189 |
+ } |
24190 |
+ |
24191 |
++static int atomisp_adjust_fmt(struct v4l2_format *f) |
24192 |
++{ |
24193 |
++ const struct atomisp_format_bridge *format_bridge; |
24194 |
++ u32 padded_width; |
24195 |
++ |
24196 |
++ format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat); |
24197 |
++ |
24198 |
++ padded_width = f->fmt.pix.width + pad_w; |
24199 |
++ |
24200 |
++ if (format_bridge->planar) { |
24201 |
++ f->fmt.pix.bytesperline = padded_width; |
24202 |
++ f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height * |
24203 |
++ DIV_ROUND_UP(format_bridge->depth * |
24204 |
++ padded_width, 8)); |
24205 |
++ } else { |
24206 |
++ f->fmt.pix.bytesperline = DIV_ROUND_UP(format_bridge->depth * |
24207 |
++ padded_width, 8); |
24208 |
++ f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height * f->fmt.pix.bytesperline); |
24209 |
++ } |
24210 |
++ |
24211 |
++ if (f->fmt.pix.field == V4L2_FIELD_ANY) |
24212 |
++ f->fmt.pix.field = V4L2_FIELD_NONE; |
24213 |
++ |
24214 |
++ format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat); |
24215 |
++ if (!format_bridge) |
24216 |
++ return -EINVAL; |
24217 |
++ |
24218 |
++ /* Currently, raw formats are broken!!! */ |
24219 |
++ if (format_bridge->sh_fmt == IA_CSS_FRAME_FORMAT_RAW) { |
24220 |
++ f->fmt.pix.pixelformat = V4L2_PIX_FMT_YUV420; |
24221 |
++ |
24222 |
++ format_bridge = atomisp_get_format_bridge(f->fmt.pix.pixelformat); |
24223 |
++ if (!format_bridge) |
24224 |
++ return -EINVAL; |
24225 |
++ } |
24226 |
++ |
24227 |
++ padded_width = f->fmt.pix.width + pad_w; |
24228 |
++ |
24229 |
++ if (format_bridge->planar) { |
24230 |
++ f->fmt.pix.bytesperline = padded_width; |
24231 |
++ f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height * |
24232 |
++ DIV_ROUND_UP(format_bridge->depth * |
24233 |
++ padded_width, 8)); |
24234 |
++ } else { |
24235 |
++ f->fmt.pix.bytesperline = DIV_ROUND_UP(format_bridge->depth * |
24236 |
++ padded_width, 8); |
24237 |
++ f->fmt.pix.sizeimage = PAGE_ALIGN(f->fmt.pix.height * f->fmt.pix.bytesperline); |
24238 |
++ } |
24239 |
++ |
24240 |
++ if (f->fmt.pix.field == V4L2_FIELD_ANY) |
24241 |
++ f->fmt.pix.field = V4L2_FIELD_NONE; |
24242 |
++ |
24243 |
++ /* |
24244 |
++ * FIXME: do we need to setup this differently, depending on the |
24245 |
++ * sensor or the pipeline? |
24246 |
++ */ |
24247 |
++ f->fmt.pix.colorspace = V4L2_COLORSPACE_REC709; |
24248 |
++ f->fmt.pix.ycbcr_enc = V4L2_YCBCR_ENC_709; |
24249 |
++ f->fmt.pix.xfer_func = V4L2_XFER_FUNC_709; |
24250 |
++ |
24251 |
++ f->fmt.pix.width -= pad_w; |
24252 |
++ f->fmt.pix.height -= pad_h; |
24253 |
++ |
24254 |
++ return 0; |
24255 |
++} |
24256 |
++ |
24257 |
+ /* This function looks up the closest available resolution. */ |
24258 |
+ static int atomisp_try_fmt_cap(struct file *file, void *fh, |
24259 |
+ struct v4l2_format *f) |
24260 |
+@@ -845,7 +940,11 @@ static int atomisp_try_fmt_cap(struct file *file, void *fh, |
24261 |
+ rt_mutex_lock(&isp->mutex); |
24262 |
+ ret = atomisp_try_fmt(vdev, &f->fmt.pix, NULL); |
24263 |
+ rt_mutex_unlock(&isp->mutex); |
24264 |
+- return ret; |
24265 |
++ |
24266 |
++ if (ret) |
24267 |
++ return ret; |
24268 |
++ |
24269 |
++ return atomisp_adjust_fmt(f); |
24270 |
+ } |
24271 |
+ |
24272 |
+ static int atomisp_s_fmt_cap(struct file *file, void *fh, |
24273 |
+@@ -1024,9 +1123,16 @@ int __atomisp_reqbufs(struct file *file, void *fh, |
24274 |
+ struct ia_css_frame *frame; |
24275 |
+ struct videobuf_vmalloc_memory *vm_mem; |
24276 |
+ u16 source_pad = atomisp_subdev_source_pad(vdev); |
24277 |
+- u16 stream_id = atomisp_source_pad_to_stream_id(asd, source_pad); |
24278 |
++ u16 stream_id; |
24279 |
+ int ret = 0, i = 0; |
24280 |
+ |
24281 |
++ if (!asd) { |
24282 |
++ dev_err(pipe->isp->dev, "%s(): asd is NULL, device is %s\n", |
24283 |
++ __func__, vdev->name); |
24284 |
++ return -EINVAL; |
24285 |
++ } |
24286 |
++ stream_id = atomisp_source_pad_to_stream_id(asd, source_pad); |
24287 |
++ |
24288 |
+ if (req->count == 0) { |
24289 |
+ mutex_lock(&pipe->capq.vb_lock); |
24290 |
+ if (!list_empty(&pipe->capq.stream)) |
24291 |
+@@ -1154,6 +1260,12 @@ static int atomisp_qbuf(struct file *file, void *fh, struct v4l2_buffer *buf) |
24292 |
+ u32 pgnr; |
24293 |
+ int ret = 0; |
24294 |
+ |
24295 |
++ if (!asd) { |
24296 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24297 |
++ __func__, vdev->name); |
24298 |
++ return -EINVAL; |
24299 |
++ } |
24300 |
++ |
24301 |
+ rt_mutex_lock(&isp->mutex); |
24302 |
+ if (isp->isp_fatal_error) { |
24303 |
+ ret = -EIO; |
24304 |
+@@ -1389,6 +1501,12 @@ static int atomisp_dqbuf(struct file *file, void *fh, struct v4l2_buffer *buf) |
24305 |
+ struct atomisp_device *isp = video_get_drvdata(vdev); |
24306 |
+ int ret = 0; |
24307 |
+ |
24308 |
++ if (!asd) { |
24309 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24310 |
++ __func__, vdev->name); |
24311 |
++ return -EINVAL; |
24312 |
++ } |
24313 |
++ |
24314 |
+ rt_mutex_lock(&isp->mutex); |
24315 |
+ |
24316 |
+ if (isp->isp_fatal_error) { |
24317 |
+@@ -1640,6 +1758,12 @@ static int atomisp_streamon(struct file *file, void *fh, |
24318 |
+ int ret = 0; |
24319 |
+ unsigned long irqflags; |
24320 |
+ |
24321 |
++ if (!asd) { |
24322 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24323 |
++ __func__, vdev->name); |
24324 |
++ return -EINVAL; |
24325 |
++ } |
24326 |
++ |
24327 |
+ dev_dbg(isp->dev, "Start stream on pad %d for asd%d\n", |
24328 |
+ atomisp_subdev_source_pad(vdev), asd->index); |
24329 |
+ |
24330 |
+@@ -1901,6 +2025,12 @@ int __atomisp_streamoff(struct file *file, void *fh, enum v4l2_buf_type type) |
24331 |
+ unsigned long flags; |
24332 |
+ bool first_streamoff = false; |
24333 |
+ |
24334 |
++ if (!asd) { |
24335 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24336 |
++ __func__, vdev->name); |
24337 |
++ return -EINVAL; |
24338 |
++ } |
24339 |
++ |
24340 |
+ dev_dbg(isp->dev, "Stop stream on pad %d for asd%d\n", |
24341 |
+ atomisp_subdev_source_pad(vdev), asd->index); |
24342 |
+ |
24343 |
+@@ -2150,6 +2280,12 @@ static int atomisp_g_ctrl(struct file *file, void *fh, |
24344 |
+ struct atomisp_device *isp = video_get_drvdata(vdev); |
24345 |
+ int i, ret = -EINVAL; |
24346 |
+ |
24347 |
++ if (!asd) { |
24348 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24349 |
++ __func__, vdev->name); |
24350 |
++ return -EINVAL; |
24351 |
++ } |
24352 |
++ |
24353 |
+ for (i = 0; i < ctrls_num; i++) { |
24354 |
+ if (ci_v4l2_controls[i].id == control->id) { |
24355 |
+ ret = 0; |
24356 |
+@@ -2229,6 +2365,12 @@ static int atomisp_s_ctrl(struct file *file, void *fh, |
24357 |
+ struct atomisp_device *isp = video_get_drvdata(vdev); |
24358 |
+ int i, ret = -EINVAL; |
24359 |
+ |
24360 |
++ if (!asd) { |
24361 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24362 |
++ __func__, vdev->name); |
24363 |
++ return -EINVAL; |
24364 |
++ } |
24365 |
++ |
24366 |
+ for (i = 0; i < ctrls_num; i++) { |
24367 |
+ if (ci_v4l2_controls[i].id == control->id) { |
24368 |
+ ret = 0; |
24369 |
+@@ -2310,6 +2452,12 @@ static int atomisp_queryctl(struct file *file, void *fh, |
24370 |
+ struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; |
24371 |
+ struct atomisp_device *isp = video_get_drvdata(vdev); |
24372 |
+ |
24373 |
++ if (!asd) { |
24374 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24375 |
++ __func__, vdev->name); |
24376 |
++ return -EINVAL; |
24377 |
++ } |
24378 |
++ |
24379 |
+ switch (qc->id) { |
24380 |
+ case V4L2_CID_FOCUS_ABSOLUTE: |
24381 |
+ case V4L2_CID_FOCUS_RELATIVE: |
24382 |
+@@ -2355,6 +2503,12 @@ static int atomisp_camera_g_ext_ctrls(struct file *file, void *fh, |
24383 |
+ int i; |
24384 |
+ int ret = 0; |
24385 |
+ |
24386 |
++ if (!asd) { |
24387 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24388 |
++ __func__, vdev->name); |
24389 |
++ return -EINVAL; |
24390 |
++ } |
24391 |
++ |
24392 |
+ if (!IS_ISP2401) |
24393 |
+ motor = isp->inputs[asd->input_curr].motor; |
24394 |
+ else |
24395 |
+@@ -2466,6 +2620,12 @@ static int atomisp_camera_s_ext_ctrls(struct file *file, void *fh, |
24396 |
+ int i; |
24397 |
+ int ret = 0; |
24398 |
+ |
24399 |
++ if (!asd) { |
24400 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24401 |
++ __func__, vdev->name); |
24402 |
++ return -EINVAL; |
24403 |
++ } |
24404 |
++ |
24405 |
+ if (!IS_ISP2401) |
24406 |
+ motor = isp->inputs[asd->input_curr].motor; |
24407 |
+ else |
24408 |
+@@ -2591,6 +2751,12 @@ static int atomisp_g_parm(struct file *file, void *fh, |
24409 |
+ struct atomisp_sub_device *asd = atomisp_to_video_pipe(vdev)->asd; |
24410 |
+ struct atomisp_device *isp = video_get_drvdata(vdev); |
24411 |
+ |
24412 |
++ if (!asd) { |
24413 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24414 |
++ __func__, vdev->name); |
24415 |
++ return -EINVAL; |
24416 |
++ } |
24417 |
++ |
24418 |
+ if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
24419 |
+ dev_err(isp->dev, "unsupported v4l2 buf type\n"); |
24420 |
+ return -EINVAL; |
24421 |
+@@ -2613,6 +2779,12 @@ static int atomisp_s_parm(struct file *file, void *fh, |
24422 |
+ int rval; |
24423 |
+ int fps; |
24424 |
+ |
24425 |
++ if (!asd) { |
24426 |
++ dev_err(isp->dev, "%s(): asd is NULL, device is %s\n", |
24427 |
++ __func__, vdev->name); |
24428 |
++ return -EINVAL; |
24429 |
++ } |
24430 |
++ |
24431 |
+ if (parm->type != V4L2_BUF_TYPE_VIDEO_CAPTURE) { |
24432 |
+ dev_err(isp->dev, "unsupported v4l2 buf type\n"); |
24433 |
+ return -EINVAL; |
24434 |
+diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.c b/drivers/staging/media/atomisp/pci/atomisp_subdev.c |
24435 |
+index 12f22ad007c73..ffaf11e0b0ad8 100644 |
24436 |
+--- a/drivers/staging/media/atomisp/pci/atomisp_subdev.c |
24437 |
++++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.c |
24438 |
+@@ -1164,23 +1164,28 @@ static int isp_subdev_init_entities(struct atomisp_sub_device *asd) |
24439 |
+ |
24440 |
+ atomisp_init_acc_pipe(asd, &asd->video_acc); |
24441 |
+ |
24442 |
+- ret = atomisp_video_init(&asd->video_in, "MEMORY"); |
24443 |
++ ret = atomisp_video_init(&asd->video_in, "MEMORY", |
24444 |
++ ATOMISP_RUN_MODE_SDV); |
24445 |
+ if (ret < 0) |
24446 |
+ return ret; |
24447 |
+ |
24448 |
+- ret = atomisp_video_init(&asd->video_out_capture, "CAPTURE"); |
24449 |
++ ret = atomisp_video_init(&asd->video_out_capture, "CAPTURE", |
24450 |
++ ATOMISP_RUN_MODE_STILL_CAPTURE); |
24451 |
+ if (ret < 0) |
24452 |
+ return ret; |
24453 |
+ |
24454 |
+- ret = atomisp_video_init(&asd->video_out_vf, "VIEWFINDER"); |
24455 |
++ ret = atomisp_video_init(&asd->video_out_vf, "VIEWFINDER", |
24456 |
++ ATOMISP_RUN_MODE_CONTINUOUS_CAPTURE); |
24457 |
+ if (ret < 0) |
24458 |
+ return ret; |
24459 |
+ |
24460 |
+- ret = atomisp_video_init(&asd->video_out_preview, "PREVIEW"); |
24461 |
++ ret = atomisp_video_init(&asd->video_out_preview, "PREVIEW", |
24462 |
++ ATOMISP_RUN_MODE_PREVIEW); |
24463 |
+ if (ret < 0) |
24464 |
+ return ret; |
24465 |
+ |
24466 |
+- ret = atomisp_video_init(&asd->video_out_video_capture, "VIDEO"); |
24467 |
++ ret = atomisp_video_init(&asd->video_out_video_capture, "VIDEO", |
24468 |
++ ATOMISP_RUN_MODE_VIDEO); |
24469 |
+ if (ret < 0) |
24470 |
+ return ret; |
24471 |
+ |
24472 |
+diff --git a/drivers/staging/media/atomisp/pci/atomisp_subdev.h b/drivers/staging/media/atomisp/pci/atomisp_subdev.h |
24473 |
+index d6fcfab6352d7..a8d210ea5f8be 100644 |
24474 |
+--- a/drivers/staging/media/atomisp/pci/atomisp_subdev.h |
24475 |
++++ b/drivers/staging/media/atomisp/pci/atomisp_subdev.h |
24476 |
+@@ -81,6 +81,9 @@ struct atomisp_video_pipe { |
24477 |
+ /* the link list to store per_frame parameters */ |
24478 |
+ struct list_head per_frame_params; |
24479 |
+ |
24480 |
++ /* Store here the initial run mode */ |
24481 |
++ unsigned int default_run_mode; |
24482 |
++ |
24483 |
+ unsigned int buffers_in_css; |
24484 |
+ |
24485 |
+ /* irq_lock is used to protect video buffer state change operations and |
24486 |
+diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c |
24487 |
+index 1e324f1f656e5..14c39b8987c95 100644 |
24488 |
+--- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.c |
24489 |
++++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.c |
24490 |
+@@ -447,7 +447,8 @@ const struct atomisp_dfs_config dfs_config_cht_soc = { |
24491 |
+ .dfs_table_size = ARRAY_SIZE(dfs_rules_cht_soc), |
24492 |
+ }; |
24493 |
+ |
24494 |
+-int atomisp_video_init(struct atomisp_video_pipe *video, const char *name) |
24495 |
++int atomisp_video_init(struct atomisp_video_pipe *video, const char *name, |
24496 |
++ unsigned int run_mode) |
24497 |
+ { |
24498 |
+ int ret; |
24499 |
+ const char *direction; |
24500 |
+@@ -478,6 +479,7 @@ int atomisp_video_init(struct atomisp_video_pipe *video, const char *name) |
24501 |
+ "ATOMISP ISP %s %s", name, direction); |
24502 |
+ video->vdev.release = video_device_release_empty; |
24503 |
+ video_set_drvdata(&video->vdev, video->isp); |
24504 |
++ video->default_run_mode = run_mode; |
24505 |
+ |
24506 |
+ return 0; |
24507 |
+ } |
24508 |
+@@ -711,15 +713,15 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable) |
24509 |
+ |
24510 |
+ dev_dbg(isp->dev, "IUNIT power-%s.\n", enable ? "on" : "off"); |
24511 |
+ |
24512 |
+- /*WA:Enable DVFS*/ |
24513 |
++ /* WA for P-Unit, if DVFS enabled, ISP timeout observed */ |
24514 |
+ if (IS_CHT && enable) |
24515 |
+- punit_ddr_dvfs_enable(true); |
24516 |
++ punit_ddr_dvfs_enable(false); |
24517 |
+ |
24518 |
+ /* |
24519 |
+ * FIXME:WA for ECS28A, with this sleep, CTS |
24520 |
+ * android.hardware.camera2.cts.CameraDeviceTest#testCameraDeviceAbort |
24521 |
+ * PASS, no impact on other platforms |
24522 |
+- */ |
24523 |
++ */ |
24524 |
+ if (IS_BYT && enable) |
24525 |
+ msleep(10); |
24526 |
+ |
24527 |
+@@ -727,7 +729,7 @@ static int atomisp_mrfld_power(struct atomisp_device *isp, bool enable) |
24528 |
+ iosf_mbi_modify(BT_MBI_UNIT_PMC, MBI_REG_READ, MRFLD_ISPSSPM0, |
24529 |
+ val, MRFLD_ISPSSPM0_ISPSSC_MASK); |
24530 |
+ |
24531 |
+- /*WA:Enable DVFS*/ |
24532 |
++ /* WA:Enable DVFS */ |
24533 |
+ if (IS_CHT && !enable) |
24534 |
+ punit_ddr_dvfs_enable(true); |
24535 |
+ |
24536 |
+@@ -1182,6 +1184,7 @@ static void atomisp_unregister_entities(struct atomisp_device *isp) |
24537 |
+ |
24538 |
+ v4l2_device_unregister(&isp->v4l2_dev); |
24539 |
+ media_device_unregister(&isp->media_dev); |
24540 |
++ media_device_cleanup(&isp->media_dev); |
24541 |
+ } |
24542 |
+ |
24543 |
+ static int atomisp_register_entities(struct atomisp_device *isp) |
24544 |
+diff --git a/drivers/staging/media/atomisp/pci/atomisp_v4l2.h b/drivers/staging/media/atomisp/pci/atomisp_v4l2.h |
24545 |
+index 81bb356b81720..72611b8286a4a 100644 |
24546 |
+--- a/drivers/staging/media/atomisp/pci/atomisp_v4l2.h |
24547 |
++++ b/drivers/staging/media/atomisp/pci/atomisp_v4l2.h |
24548 |
+@@ -27,7 +27,8 @@ struct v4l2_device; |
24549 |
+ struct atomisp_device; |
24550 |
+ struct firmware; |
24551 |
+ |
24552 |
+-int atomisp_video_init(struct atomisp_video_pipe *video, const char *name); |
24553 |
++int atomisp_video_init(struct atomisp_video_pipe *video, const char *name, |
24554 |
++ unsigned int run_mode); |
24555 |
+ void atomisp_acc_init(struct atomisp_acc_pipe *video, const char *name); |
24556 |
+ void atomisp_video_unregister(struct atomisp_video_pipe *video); |
24557 |
+ void atomisp_acc_unregister(struct atomisp_acc_pipe *video); |
24558 |
+diff --git a/drivers/staging/media/atomisp/pci/sh_css.c b/drivers/staging/media/atomisp/pci/sh_css.c |
24559 |
+index c4b35cbab3737..ba25d0da8b811 100644 |
24560 |
+--- a/drivers/staging/media/atomisp/pci/sh_css.c |
24561 |
++++ b/drivers/staging/media/atomisp/pci/sh_css.c |
24562 |
+@@ -522,6 +522,7 @@ ia_css_stream_input_format_bits_per_pixel(struct ia_css_stream *stream) |
24563 |
+ return bpp; |
24564 |
+ } |
24565 |
+ |
24566 |
++/* TODO: move define to proper file in tools */ |
24567 |
+ #define GP_ISEL_TPG_MODE 0x90058 |
24568 |
+ |
24569 |
+ #if !defined(ISP2401) |
24570 |
+@@ -573,12 +574,8 @@ sh_css_config_input_network(struct ia_css_stream *stream) |
24571 |
+ vblank_cycles = vblank_lines * (width + hblank_cycles); |
24572 |
+ sh_css_sp_configure_sync_gen(width, height, hblank_cycles, |
24573 |
+ vblank_cycles); |
24574 |
+- if (!IS_ISP2401) { |
24575 |
+- if (pipe->stream->config.mode == IA_CSS_INPUT_MODE_TPG) { |
24576 |
+- /* TODO: move define to proper file in tools */ |
24577 |
+- ia_css_device_store_uint32(GP_ISEL_TPG_MODE, 0); |
24578 |
+- } |
24579 |
+- } |
24580 |
++ if (pipe->stream->config.mode == IA_CSS_INPUT_MODE_TPG) |
24581 |
++ ia_css_device_store_uint32(GP_ISEL_TPG_MODE, 0); |
24582 |
+ } |
24583 |
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, |
24584 |
+ "sh_css_config_input_network() leave:\n"); |
24585 |
+@@ -1009,16 +1006,14 @@ static bool sh_css_translate_stream_cfg_to_isys_stream_descr( |
24586 |
+ * ia_css_isys_stream_capture_indication() instead of |
24587 |
+ * ia_css_pipeline_sp_wait_for_isys_stream_N() as isp processing of |
24588 |
+ * capture takes longer than getting an ISYS frame |
24589 |
+- * |
24590 |
+- * Only 2401 relevant ?? |
24591 |
+ */ |
24592 |
+-#if 0 // FIXME: NOT USED on Yocto Aero |
24593 |
+- isys_stream_descr->polling_mode |
24594 |
+- = early_polling ? INPUT_SYSTEM_POLL_ON_CAPTURE_REQUEST |
24595 |
+- : INPUT_SYSTEM_POLL_ON_WAIT_FOR_FRAME; |
24596 |
+- ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, |
24597 |
+- "sh_css_translate_stream_cfg_to_isys_stream_descr() leave:\n"); |
24598 |
+-#endif |
24599 |
++ if (IS_ISP2401) { |
24600 |
++ isys_stream_descr->polling_mode |
24601 |
++ = early_polling ? INPUT_SYSTEM_POLL_ON_CAPTURE_REQUEST |
24602 |
++ : INPUT_SYSTEM_POLL_ON_WAIT_FOR_FRAME; |
24603 |
++ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, |
24604 |
++ "sh_css_translate_stream_cfg_to_isys_stream_descr() leave:\n"); |
24605 |
++ } |
24606 |
+ |
24607 |
+ return rc; |
24608 |
+ } |
24609 |
+@@ -1433,7 +1428,7 @@ static void start_pipe( |
24610 |
+ |
24611 |
+ assert(me); /* all callers are in this file and call with non null argument */ |
24612 |
+ |
24613 |
+- if (!IS_ISP2401) { |
24614 |
++ if (IS_ISP2401) { |
24615 |
+ coord = &me->config.internal_frame_origin_bqs_on_sctbl; |
24616 |
+ params = me->stream->isp_params_configs; |
24617 |
+ } |
24618 |
+diff --git a/drivers/staging/media/atomisp/pci/sh_css_mipi.c b/drivers/staging/media/atomisp/pci/sh_css_mipi.c |
24619 |
+index 75489f7d75eec..c1f2f6151c5f8 100644 |
24620 |
+--- a/drivers/staging/media/atomisp/pci/sh_css_mipi.c |
24621 |
++++ b/drivers/staging/media/atomisp/pci/sh_css_mipi.c |
24622 |
+@@ -374,17 +374,17 @@ static bool buffers_needed(struct ia_css_pipe *pipe) |
24623 |
+ { |
24624 |
+ if (!IS_ISP2401) { |
24625 |
+ if (pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR) |
24626 |
+- return false; |
24627 |
+- else |
24628 |
+ return true; |
24629 |
++ else |
24630 |
++ return false; |
24631 |
+ } |
24632 |
+ |
24633 |
+ if (pipe->stream->config.mode == IA_CSS_INPUT_MODE_BUFFERED_SENSOR || |
24634 |
+ pipe->stream->config.mode == IA_CSS_INPUT_MODE_TPG || |
24635 |
+ pipe->stream->config.mode == IA_CSS_INPUT_MODE_PRBS) |
24636 |
+- return false; |
24637 |
++ return true; |
24638 |
+ |
24639 |
+- return true; |
24640 |
++ return false; |
24641 |
+ } |
24642 |
+ |
24643 |
+ int |
24644 |
+@@ -423,14 +423,17 @@ allocate_mipi_frames(struct ia_css_pipe *pipe, |
24645 |
+ return 0; /* AM TODO: Check */ |
24646 |
+ } |
24647 |
+ |
24648 |
+- if (!IS_ISP2401) |
24649 |
++ if (!IS_ISP2401) { |
24650 |
+ port = (unsigned int)pipe->stream->config.source.port.port; |
24651 |
+- else |
24652 |
+- err = ia_css_mipi_is_source_port_valid(pipe, &port); |
24653 |
++ } else { |
24654 |
++ /* Returns true if port is valid. So, invert it */ |
24655 |
++ err = !ia_css_mipi_is_source_port_valid(pipe, &port); |
24656 |
++ } |
24657 |
+ |
24658 |
+ assert(port < N_CSI_PORTS); |
24659 |
+ |
24660 |
+- if (port >= N_CSI_PORTS || err) { |
24661 |
++ if ((!IS_ISP2401 && port >= N_CSI_PORTS) || |
24662 |
++ (IS_ISP2401 && err)) { |
24663 |
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, |
24664 |
+ "allocate_mipi_frames(%p) exit: error: port is not correct (port=%d).\n", |
24665 |
+ pipe, port); |
24666 |
+@@ -552,14 +555,17 @@ free_mipi_frames(struct ia_css_pipe *pipe) |
24667 |
+ return err; |
24668 |
+ } |
24669 |
+ |
24670 |
+- if (!IS_ISP2401) |
24671 |
++ if (!IS_ISP2401) { |
24672 |
+ port = (unsigned int)pipe->stream->config.source.port.port; |
24673 |
+- else |
24674 |
+- err = ia_css_mipi_is_source_port_valid(pipe, &port); |
24675 |
++ } else { |
24676 |
++ /* Returns true if port is valid. So, invert it */ |
24677 |
++ err = !ia_css_mipi_is_source_port_valid(pipe, &port); |
24678 |
++ } |
24679 |
+ |
24680 |
+ assert(port < N_CSI_PORTS); |
24681 |
+ |
24682 |
+- if (port >= N_CSI_PORTS || err) { |
24683 |
++ if ((!IS_ISP2401 && port >= N_CSI_PORTS) || |
24684 |
++ (IS_ISP2401 && err)) { |
24685 |
+ ia_css_debug_dtrace(IA_CSS_DEBUG_TRACE_PRIVATE, |
24686 |
+ "free_mipi_frames(%p, %d) exit: error: pipe port is not correct.\n", |
24687 |
+ pipe, port); |
24688 |
+@@ -663,14 +669,17 @@ send_mipi_frames(struct ia_css_pipe *pipe) |
24689 |
+ /* TODO: AM: maybe this should be returning an error. */ |
24690 |
+ } |
24691 |
+ |
24692 |
+- if (!IS_ISP2401) |
24693 |
++ if (!IS_ISP2401) { |
24694 |
+ port = (unsigned int)pipe->stream->config.source.port.port; |
24695 |
+- else |
24696 |
+- err = ia_css_mipi_is_source_port_valid(pipe, &port); |
24697 |
++ } else { |
24698 |
++ /* Returns true if port is valid. So, invert it */ |
24699 |
++ err = !ia_css_mipi_is_source_port_valid(pipe, &port); |
24700 |
++ } |
24701 |
+ |
24702 |
+ assert(port < N_CSI_PORTS); |
24703 |
+ |
24704 |
+- if (port >= N_CSI_PORTS || err) { |
24705 |
++ if ((!IS_ISP2401 && port >= N_CSI_PORTS) || |
24706 |
++ (IS_ISP2401 && err)) { |
24707 |
+ IA_CSS_ERROR("send_mipi_frames(%p) exit: invalid port specified (port=%d).\n", |
24708 |
+ pipe, port); |
24709 |
+ return err; |
24710 |
+diff --git a/drivers/staging/media/atomisp/pci/sh_css_params.c b/drivers/staging/media/atomisp/pci/sh_css_params.c |
24711 |
+index dbd3bfe3d343c..ccc0078795648 100644 |
24712 |
+--- a/drivers/staging/media/atomisp/pci/sh_css_params.c |
24713 |
++++ b/drivers/staging/media/atomisp/pci/sh_css_params.c |
24714 |
+@@ -2431,7 +2431,7 @@ sh_css_create_isp_params(struct ia_css_stream *stream, |
24715 |
+ unsigned int i; |
24716 |
+ struct sh_css_ddr_address_map *ddr_ptrs; |
24717 |
+ struct sh_css_ddr_address_map_size *ddr_ptrs_size; |
24718 |
+- int err = 0; |
24719 |
++ int err; |
24720 |
+ size_t params_size; |
24721 |
+ struct ia_css_isp_parameters *params = |
24722 |
+ kvmalloc(sizeof(struct ia_css_isp_parameters), GFP_KERNEL); |
24723 |
+@@ -2473,7 +2473,11 @@ sh_css_create_isp_params(struct ia_css_stream *stream, |
24724 |
+ succ &= (ddr_ptrs->macc_tbl != mmgr_NULL); |
24725 |
+ |
24726 |
+ *isp_params_out = params; |
24727 |
+- return err; |
24728 |
++ |
24729 |
++ if (!succ) |
24730 |
++ return -ENOMEM; |
24731 |
++ |
24732 |
++ return 0; |
24733 |
+ } |
24734 |
+ |
24735 |
+ static bool |
24736 |
+diff --git a/drivers/staging/media/hantro/hantro_drv.c b/drivers/staging/media/hantro/hantro_drv.c |
24737 |
+index 20e5081588719..281aa585e3375 100644 |
24738 |
+--- a/drivers/staging/media/hantro/hantro_drv.c |
24739 |
++++ b/drivers/staging/media/hantro/hantro_drv.c |
24740 |
+@@ -958,7 +958,7 @@ static int hantro_probe(struct platform_device *pdev) |
24741 |
+ ret = clk_bulk_prepare(vpu->variant->num_clocks, vpu->clocks); |
24742 |
+ if (ret) { |
24743 |
+ dev_err(&pdev->dev, "Failed to prepare clocks\n"); |
24744 |
+- return ret; |
24745 |
++ goto err_pm_disable; |
24746 |
+ } |
24747 |
+ |
24748 |
+ ret = v4l2_device_register(&pdev->dev, &vpu->v4l2_dev); |
24749 |
+@@ -1014,6 +1014,7 @@ err_v4l2_unreg: |
24750 |
+ v4l2_device_unregister(&vpu->v4l2_dev); |
24751 |
+ err_clk_unprepare: |
24752 |
+ clk_bulk_unprepare(vpu->variant->num_clocks, vpu->clocks); |
24753 |
++err_pm_disable: |
24754 |
+ pm_runtime_dont_use_autosuspend(vpu->dev); |
24755 |
+ pm_runtime_disable(vpu->dev); |
24756 |
+ return ret; |
24757 |
+diff --git a/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c b/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c |
24758 |
+index 56cf261a8e958..9cd713c02a455 100644 |
24759 |
+--- a/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c |
24760 |
++++ b/drivers/staging/media/hantro/hantro_h1_jpeg_enc.c |
24761 |
+@@ -140,7 +140,7 @@ int hantro_h1_jpeg_enc_run(struct hantro_ctx *ctx) |
24762 |
+ return 0; |
24763 |
+ } |
24764 |
+ |
24765 |
+-void hantro_jpeg_enc_done(struct hantro_ctx *ctx) |
24766 |
++void hantro_h1_jpeg_enc_done(struct hantro_ctx *ctx) |
24767 |
+ { |
24768 |
+ struct hantro_dev *vpu = ctx->dev; |
24769 |
+ u32 bytesused = vepu_read(vpu, H1_REG_STR_BUF_LIMIT) / 8; |
24770 |
+diff --git a/drivers/staging/media/hantro/hantro_hw.h b/drivers/staging/media/hantro/hantro_hw.h |
24771 |
+index df7b5e3a57b9b..fd738653a5735 100644 |
24772 |
+--- a/drivers/staging/media/hantro/hantro_hw.h |
24773 |
++++ b/drivers/staging/media/hantro/hantro_hw.h |
24774 |
+@@ -235,7 +235,8 @@ int hantro_h1_jpeg_enc_run(struct hantro_ctx *ctx); |
24775 |
+ int rockchip_vpu2_jpeg_enc_run(struct hantro_ctx *ctx); |
24776 |
+ int hantro_jpeg_enc_init(struct hantro_ctx *ctx); |
24777 |
+ void hantro_jpeg_enc_exit(struct hantro_ctx *ctx); |
24778 |
+-void hantro_jpeg_enc_done(struct hantro_ctx *ctx); |
24779 |
++void hantro_h1_jpeg_enc_done(struct hantro_ctx *ctx); |
24780 |
++void rockchip_vpu2_jpeg_enc_done(struct hantro_ctx *ctx); |
24781 |
+ |
24782 |
+ dma_addr_t hantro_h264_get_ref_buf(struct hantro_ctx *ctx, |
24783 |
+ unsigned int dpb_idx); |
24784 |
+diff --git a/drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c b/drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c |
24785 |
+index 991213ce16108..5d9ff420f0b5f 100644 |
24786 |
+--- a/drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c |
24787 |
++++ b/drivers/staging/media/hantro/rockchip_vpu2_hw_jpeg_enc.c |
24788 |
+@@ -171,3 +171,20 @@ int rockchip_vpu2_jpeg_enc_run(struct hantro_ctx *ctx) |
24789 |
+ |
24790 |
+ return 0; |
24791 |
+ } |
24792 |
++ |
24793 |
++void rockchip_vpu2_jpeg_enc_done(struct hantro_ctx *ctx) |
24794 |
++{ |
24795 |
++ struct hantro_dev *vpu = ctx->dev; |
24796 |
++ u32 bytesused = vepu_read(vpu, VEPU_REG_STR_BUF_LIMIT) / 8; |
24797 |
++ struct vb2_v4l2_buffer *dst_buf = hantro_get_dst_buf(ctx); |
24798 |
++ |
24799 |
++ /* |
24800 |
++ * TODO: Rework the JPEG encoder to eliminate the need |
24801 |
++ * for a bounce buffer. |
24802 |
++ */ |
24803 |
++ memcpy(vb2_plane_vaddr(&dst_buf->vb2_buf, 0) + |
24804 |
++ ctx->vpu_dst_fmt->header_size, |
24805 |
++ ctx->jpeg_enc.bounce_buffer.cpu, bytesused); |
24806 |
++ vb2_set_plane_payload(&dst_buf->vb2_buf, 0, |
24807 |
++ ctx->vpu_dst_fmt->header_size + bytesused); |
24808 |
++} |
24809 |
+diff --git a/drivers/staging/media/hantro/rockchip_vpu_hw.c b/drivers/staging/media/hantro/rockchip_vpu_hw.c |
24810 |
+index d4f52957cc534..0c22039162a00 100644 |
24811 |
+--- a/drivers/staging/media/hantro/rockchip_vpu_hw.c |
24812 |
++++ b/drivers/staging/media/hantro/rockchip_vpu_hw.c |
24813 |
+@@ -343,7 +343,7 @@ static const struct hantro_codec_ops rk3066_vpu_codec_ops[] = { |
24814 |
+ .run = hantro_h1_jpeg_enc_run, |
24815 |
+ .reset = rockchip_vpu1_enc_reset, |
24816 |
+ .init = hantro_jpeg_enc_init, |
24817 |
+- .done = hantro_jpeg_enc_done, |
24818 |
++ .done = hantro_h1_jpeg_enc_done, |
24819 |
+ .exit = hantro_jpeg_enc_exit, |
24820 |
+ }, |
24821 |
+ [HANTRO_MODE_H264_DEC] = { |
24822 |
+@@ -371,7 +371,7 @@ static const struct hantro_codec_ops rk3288_vpu_codec_ops[] = { |
24823 |
+ .run = hantro_h1_jpeg_enc_run, |
24824 |
+ .reset = rockchip_vpu1_enc_reset, |
24825 |
+ .init = hantro_jpeg_enc_init, |
24826 |
+- .done = hantro_jpeg_enc_done, |
24827 |
++ .done = hantro_h1_jpeg_enc_done, |
24828 |
+ .exit = hantro_jpeg_enc_exit, |
24829 |
+ }, |
24830 |
+ [HANTRO_MODE_H264_DEC] = { |
24831 |
+@@ -399,6 +399,7 @@ static const struct hantro_codec_ops rk3399_vpu_codec_ops[] = { |
24832 |
+ .run = rockchip_vpu2_jpeg_enc_run, |
24833 |
+ .reset = rockchip_vpu2_enc_reset, |
24834 |
+ .init = hantro_jpeg_enc_init, |
24835 |
++ .done = rockchip_vpu2_jpeg_enc_done, |
24836 |
+ .exit = hantro_jpeg_enc_exit, |
24837 |
+ }, |
24838 |
+ [HANTRO_MODE_H264_DEC] = { |
24839 |
+diff --git a/drivers/staging/rtl8192e/rtllib.h b/drivers/staging/rtl8192e/rtllib.h |
24840 |
+index c6f8b772335c1..c985e4ebc545a 100644 |
24841 |
+--- a/drivers/staging/rtl8192e/rtllib.h |
24842 |
++++ b/drivers/staging/rtl8192e/rtllib.h |
24843 |
+@@ -1980,7 +1980,7 @@ void SendDisassociation(struct rtllib_device *ieee, bool deauth, u16 asRsn); |
24844 |
+ void rtllib_softmac_xmit(struct rtllib_txb *txb, struct rtllib_device *ieee); |
24845 |
+ |
24846 |
+ void rtllib_start_ibss(struct rtllib_device *ieee); |
24847 |
+-void rtllib_softmac_init(struct rtllib_device *ieee); |
24848 |
++int rtllib_softmac_init(struct rtllib_device *ieee); |
24849 |
+ void rtllib_softmac_free(struct rtllib_device *ieee); |
24850 |
+ void rtllib_disassociate(struct rtllib_device *ieee); |
24851 |
+ void rtllib_stop_scan(struct rtllib_device *ieee); |
24852 |
+diff --git a/drivers/staging/rtl8192e/rtllib_module.c b/drivers/staging/rtl8192e/rtllib_module.c |
24853 |
+index 64d9feee1f392..f00ac94b2639b 100644 |
24854 |
+--- a/drivers/staging/rtl8192e/rtllib_module.c |
24855 |
++++ b/drivers/staging/rtl8192e/rtllib_module.c |
24856 |
+@@ -88,7 +88,7 @@ struct net_device *alloc_rtllib(int sizeof_priv) |
24857 |
+ err = rtllib_networks_allocate(ieee); |
24858 |
+ if (err) { |
24859 |
+ pr_err("Unable to allocate beacon storage: %d\n", err); |
24860 |
+- goto failed; |
24861 |
++ goto free_netdev; |
24862 |
+ } |
24863 |
+ rtllib_networks_initialize(ieee); |
24864 |
+ |
24865 |
+@@ -121,11 +121,13 @@ struct net_device *alloc_rtllib(int sizeof_priv) |
24866 |
+ ieee->hwsec_active = 0; |
24867 |
+ |
24868 |
+ memset(ieee->swcamtable, 0, sizeof(struct sw_cam_table) * 32); |
24869 |
+- rtllib_softmac_init(ieee); |
24870 |
++ err = rtllib_softmac_init(ieee); |
24871 |
++ if (err) |
24872 |
++ goto free_crypt_info; |
24873 |
+ |
24874 |
+ ieee->pHTInfo = kzalloc(sizeof(struct rt_hi_throughput), GFP_KERNEL); |
24875 |
+ if (!ieee->pHTInfo) |
24876 |
+- return NULL; |
24877 |
++ goto free_softmac; |
24878 |
+ |
24879 |
+ HTUpdateDefaultSetting(ieee); |
24880 |
+ HTInitializeHTInfo(ieee); |
24881 |
+@@ -141,8 +143,14 @@ struct net_device *alloc_rtllib(int sizeof_priv) |
24882 |
+ |
24883 |
+ return dev; |
24884 |
+ |
24885 |
+- failed: |
24886 |
++free_softmac: |
24887 |
++ rtllib_softmac_free(ieee); |
24888 |
++free_crypt_info: |
24889 |
++ lib80211_crypt_info_free(&ieee->crypt_info); |
24890 |
++ rtllib_networks_free(ieee); |
24891 |
++free_netdev: |
24892 |
+ free_netdev(dev); |
24893 |
++ |
24894 |
+ return NULL; |
24895 |
+ } |
24896 |
+ EXPORT_SYMBOL(alloc_rtllib); |
24897 |
+diff --git a/drivers/staging/rtl8192e/rtllib_softmac.c b/drivers/staging/rtl8192e/rtllib_softmac.c |
24898 |
+index d2726d01c7573..503d33be71d99 100644 |
24899 |
+--- a/drivers/staging/rtl8192e/rtllib_softmac.c |
24900 |
++++ b/drivers/staging/rtl8192e/rtllib_softmac.c |
24901 |
+@@ -2952,7 +2952,7 @@ void rtllib_start_protocol(struct rtllib_device *ieee) |
24902 |
+ } |
24903 |
+ } |
24904 |
+ |
24905 |
+-void rtllib_softmac_init(struct rtllib_device *ieee) |
24906 |
++int rtllib_softmac_init(struct rtllib_device *ieee) |
24907 |
+ { |
24908 |
+ int i; |
24909 |
+ |
24910 |
+@@ -2963,7 +2963,8 @@ void rtllib_softmac_init(struct rtllib_device *ieee) |
24911 |
+ ieee->seq_ctrl[i] = 0; |
24912 |
+ ieee->dot11d_info = kzalloc(sizeof(struct rt_dot11d_info), GFP_ATOMIC); |
24913 |
+ if (!ieee->dot11d_info) |
24914 |
+- netdev_err(ieee->dev, "Can't alloc memory for DOT11D\n"); |
24915 |
++ return -ENOMEM; |
24916 |
++ |
24917 |
+ ieee->LinkDetectInfo.SlotIndex = 0; |
24918 |
+ ieee->LinkDetectInfo.SlotNum = 2; |
24919 |
+ ieee->LinkDetectInfo.NumRecvBcnInPeriod = 0; |
24920 |
+@@ -3029,6 +3030,7 @@ void rtllib_softmac_init(struct rtllib_device *ieee) |
24921 |
+ |
24922 |
+ tasklet_setup(&ieee->ps_task, rtllib_sta_ps); |
24923 |
+ |
24924 |
++ return 0; |
24925 |
+ } |
24926 |
+ |
24927 |
+ void rtllib_softmac_free(struct rtllib_device *ieee) |
24928 |
+diff --git a/drivers/tee/tee_core.c b/drivers/tee/tee_core.c |
24929 |
+index 2b37bc408fc3d..85102d12d7169 100644 |
24930 |
+--- a/drivers/tee/tee_core.c |
24931 |
++++ b/drivers/tee/tee_core.c |
24932 |
+@@ -98,8 +98,10 @@ void teedev_ctx_put(struct tee_context *ctx) |
24933 |
+ |
24934 |
+ static void teedev_close_context(struct tee_context *ctx) |
24935 |
+ { |
24936 |
+- tee_device_put(ctx->teedev); |
24937 |
++ struct tee_device *teedev = ctx->teedev; |
24938 |
++ |
24939 |
+ teedev_ctx_put(ctx); |
24940 |
++ tee_device_put(teedev); |
24941 |
+ } |
24942 |
+ |
24943 |
+ static int tee_open(struct inode *inode, struct file *filp) |
24944 |
+diff --git a/drivers/thermal/imx8mm_thermal.c b/drivers/thermal/imx8mm_thermal.c |
24945 |
+index 7442e013738f8..af666bd9e8d4d 100644 |
24946 |
+--- a/drivers/thermal/imx8mm_thermal.c |
24947 |
++++ b/drivers/thermal/imx8mm_thermal.c |
24948 |
+@@ -21,6 +21,7 @@ |
24949 |
+ #define TPS 0x4 |
24950 |
+ #define TRITSR 0x20 /* TMU immediate temp */ |
24951 |
+ |
24952 |
++#define TER_ADC_PD BIT(30) |
24953 |
+ #define TER_EN BIT(31) |
24954 |
+ #define TRITSR_TEMP0_VAL_MASK 0xff |
24955 |
+ #define TRITSR_TEMP1_VAL_MASK 0xff0000 |
24956 |
+@@ -113,6 +114,8 @@ static void imx8mm_tmu_enable(struct imx8mm_tmu *tmu, bool enable) |
24957 |
+ |
24958 |
+ val = readl_relaxed(tmu->base + TER); |
24959 |
+ val = enable ? (val | TER_EN) : (val & ~TER_EN); |
24960 |
++ if (tmu->socdata->version == TMU_VER2) |
24961 |
++ val = enable ? (val & ~TER_ADC_PD) : (val | TER_ADC_PD); |
24962 |
+ writel_relaxed(val, tmu->base + TER); |
24963 |
+ } |
24964 |
+ |
24965 |
+diff --git a/drivers/thermal/imx_thermal.c b/drivers/thermal/imx_thermal.c |
24966 |
+index 2c7473d86a59b..16663373b6829 100644 |
24967 |
+--- a/drivers/thermal/imx_thermal.c |
24968 |
++++ b/drivers/thermal/imx_thermal.c |
24969 |
+@@ -15,6 +15,7 @@ |
24970 |
+ #include <linux/regmap.h> |
24971 |
+ #include <linux/thermal.h> |
24972 |
+ #include <linux/nvmem-consumer.h> |
24973 |
++#include <linux/pm_runtime.h> |
24974 |
+ |
24975 |
+ #define REG_SET 0x4 |
24976 |
+ #define REG_CLR 0x8 |
24977 |
+@@ -194,6 +195,7 @@ static struct thermal_soc_data thermal_imx7d_data = { |
24978 |
+ }; |
24979 |
+ |
24980 |
+ struct imx_thermal_data { |
24981 |
++ struct device *dev; |
24982 |
+ struct cpufreq_policy *policy; |
24983 |
+ struct thermal_zone_device *tz; |
24984 |
+ struct thermal_cooling_device *cdev; |
24985 |
+@@ -252,44 +254,15 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp) |
24986 |
+ const struct thermal_soc_data *soc_data = data->socdata; |
24987 |
+ struct regmap *map = data->tempmon; |
24988 |
+ unsigned int n_meas; |
24989 |
+- bool wait, run_measurement; |
24990 |
+ u32 val; |
24991 |
++ int ret; |
24992 |
+ |
24993 |
+- run_measurement = !data->irq_enabled; |
24994 |
+- if (!run_measurement) { |
24995 |
+- /* Check if a measurement is currently in progress */ |
24996 |
+- regmap_read(map, soc_data->temp_data, &val); |
24997 |
+- wait = !(val & soc_data->temp_valid_mask); |
24998 |
+- } else { |
24999 |
+- /* |
25000 |
+- * Every time we measure the temperature, we will power on the |
25001 |
+- * temperature sensor, enable measurements, take a reading, |
25002 |
+- * disable measurements, power off the temperature sensor. |
25003 |
+- */ |
25004 |
+- regmap_write(map, soc_data->sensor_ctrl + REG_CLR, |
25005 |
+- soc_data->power_down_mask); |
25006 |
+- regmap_write(map, soc_data->sensor_ctrl + REG_SET, |
25007 |
+- soc_data->measure_temp_mask); |
25008 |
+- |
25009 |
+- wait = true; |
25010 |
+- } |
25011 |
+- |
25012 |
+- /* |
25013 |
+- * According to the temp sensor designers, it may require up to ~17us |
25014 |
+- * to complete a measurement. |
25015 |
+- */ |
25016 |
+- if (wait) |
25017 |
+- usleep_range(20, 50); |
25018 |
++ ret = pm_runtime_resume_and_get(data->dev); |
25019 |
++ if (ret < 0) |
25020 |
++ return ret; |
25021 |
+ |
25022 |
+ regmap_read(map, soc_data->temp_data, &val); |
25023 |
+ |
25024 |
+- if (run_measurement) { |
25025 |
+- regmap_write(map, soc_data->sensor_ctrl + REG_CLR, |
25026 |
+- soc_data->measure_temp_mask); |
25027 |
+- regmap_write(map, soc_data->sensor_ctrl + REG_SET, |
25028 |
+- soc_data->power_down_mask); |
25029 |
+- } |
25030 |
+- |
25031 |
+ if ((val & soc_data->temp_valid_mask) == 0) { |
25032 |
+ dev_dbg(&tz->device, "temp measurement never finished\n"); |
25033 |
+ return -EAGAIN; |
25034 |
+@@ -328,6 +301,8 @@ static int imx_get_temp(struct thermal_zone_device *tz, int *temp) |
25035 |
+ enable_irq(data->irq); |
25036 |
+ } |
25037 |
+ |
25038 |
++ pm_runtime_put(data->dev); |
25039 |
++ |
25040 |
+ return 0; |
25041 |
+ } |
25042 |
+ |
25043 |
+@@ -335,24 +310,16 @@ static int imx_change_mode(struct thermal_zone_device *tz, |
25044 |
+ enum thermal_device_mode mode) |
25045 |
+ { |
25046 |
+ struct imx_thermal_data *data = tz->devdata; |
25047 |
+- struct regmap *map = data->tempmon; |
25048 |
+- const struct thermal_soc_data *soc_data = data->socdata; |
25049 |
+ |
25050 |
+ if (mode == THERMAL_DEVICE_ENABLED) { |
25051 |
+- regmap_write(map, soc_data->sensor_ctrl + REG_CLR, |
25052 |
+- soc_data->power_down_mask); |
25053 |
+- regmap_write(map, soc_data->sensor_ctrl + REG_SET, |
25054 |
+- soc_data->measure_temp_mask); |
25055 |
++ pm_runtime_get(data->dev); |
25056 |
+ |
25057 |
+ if (!data->irq_enabled) { |
25058 |
+ data->irq_enabled = true; |
25059 |
+ enable_irq(data->irq); |
25060 |
+ } |
25061 |
+ } else { |
25062 |
+- regmap_write(map, soc_data->sensor_ctrl + REG_CLR, |
25063 |
+- soc_data->measure_temp_mask); |
25064 |
+- regmap_write(map, soc_data->sensor_ctrl + REG_SET, |
25065 |
+- soc_data->power_down_mask); |
25066 |
++ pm_runtime_put(data->dev); |
25067 |
+ |
25068 |
+ if (data->irq_enabled) { |
25069 |
+ disable_irq(data->irq); |
25070 |
+@@ -393,6 +360,11 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip, |
25071 |
+ int temp) |
25072 |
+ { |
25073 |
+ struct imx_thermal_data *data = tz->devdata; |
25074 |
++ int ret; |
25075 |
++ |
25076 |
++ ret = pm_runtime_resume_and_get(data->dev); |
25077 |
++ if (ret < 0) |
25078 |
++ return ret; |
25079 |
+ |
25080 |
+ /* do not allow changing critical threshold */ |
25081 |
+ if (trip == IMX_TRIP_CRITICAL) |
25082 |
+@@ -406,6 +378,8 @@ static int imx_set_trip_temp(struct thermal_zone_device *tz, int trip, |
25083 |
+ |
25084 |
+ imx_set_alarm_temp(data, temp); |
25085 |
+ |
25086 |
++ pm_runtime_put(data->dev); |
25087 |
++ |
25088 |
+ return 0; |
25089 |
+ } |
25090 |
+ |
25091 |
+@@ -681,6 +655,8 @@ static int imx_thermal_probe(struct platform_device *pdev) |
25092 |
+ if (!data) |
25093 |
+ return -ENOMEM; |
25094 |
+ |
25095 |
++ data->dev = &pdev->dev; |
25096 |
++ |
25097 |
+ map = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, "fsl,tempmon"); |
25098 |
+ if (IS_ERR(map)) { |
25099 |
+ ret = PTR_ERR(map); |
25100 |
+@@ -800,6 +776,16 @@ static int imx_thermal_probe(struct platform_device *pdev) |
25101 |
+ data->socdata->power_down_mask); |
25102 |
+ regmap_write(map, data->socdata->sensor_ctrl + REG_SET, |
25103 |
+ data->socdata->measure_temp_mask); |
25104 |
++ /* After power up, we need a delay before first access can be done. */ |
25105 |
++ usleep_range(20, 50); |
25106 |
++ |
25107 |
++ /* the core was configured and enabled just before */ |
25108 |
++ pm_runtime_set_active(&pdev->dev); |
25109 |
++ pm_runtime_enable(data->dev); |
25110 |
++ |
25111 |
++ ret = pm_runtime_resume_and_get(data->dev); |
25112 |
++ if (ret < 0) |
25113 |
++ goto disable_runtime_pm; |
25114 |
+ |
25115 |
+ data->irq_enabled = true; |
25116 |
+ ret = thermal_zone_device_enable(data->tz); |
25117 |
+@@ -814,10 +800,15 @@ static int imx_thermal_probe(struct platform_device *pdev) |
25118 |
+ goto thermal_zone_unregister; |
25119 |
+ } |
25120 |
+ |
25121 |
++ pm_runtime_put(data->dev); |
25122 |
++ |
25123 |
+ return 0; |
25124 |
+ |
25125 |
+ thermal_zone_unregister: |
25126 |
+ thermal_zone_device_unregister(data->tz); |
25127 |
++disable_runtime_pm: |
25128 |
++ pm_runtime_put_noidle(data->dev); |
25129 |
++ pm_runtime_disable(data->dev); |
25130 |
+ clk_disable: |
25131 |
+ clk_disable_unprepare(data->thermal_clk); |
25132 |
+ legacy_cleanup: |
25133 |
+@@ -829,13 +820,9 @@ legacy_cleanup: |
25134 |
+ static int imx_thermal_remove(struct platform_device *pdev) |
25135 |
+ { |
25136 |
+ struct imx_thermal_data *data = platform_get_drvdata(pdev); |
25137 |
+- struct regmap *map = data->tempmon; |
25138 |
+ |
25139 |
+- /* Disable measurements */ |
25140 |
+- regmap_write(map, data->socdata->sensor_ctrl + REG_SET, |
25141 |
+- data->socdata->power_down_mask); |
25142 |
+- if (!IS_ERR(data->thermal_clk)) |
25143 |
+- clk_disable_unprepare(data->thermal_clk); |
25144 |
++ pm_runtime_put_noidle(data->dev); |
25145 |
++ pm_runtime_disable(data->dev); |
25146 |
+ |
25147 |
+ thermal_zone_device_unregister(data->tz); |
25148 |
+ imx_thermal_unregister_legacy_cooling(data); |
25149 |
+@@ -858,29 +845,79 @@ static int __maybe_unused imx_thermal_suspend(struct device *dev) |
25150 |
+ ret = thermal_zone_device_disable(data->tz); |
25151 |
+ if (ret) |
25152 |
+ return ret; |
25153 |
++ |
25154 |
++ return pm_runtime_force_suspend(data->dev); |
25155 |
++} |
25156 |
++ |
25157 |
++static int __maybe_unused imx_thermal_resume(struct device *dev) |
25158 |
++{ |
25159 |
++ struct imx_thermal_data *data = dev_get_drvdata(dev); |
25160 |
++ int ret; |
25161 |
++ |
25162 |
++ ret = pm_runtime_force_resume(data->dev); |
25163 |
++ if (ret) |
25164 |
++ return ret; |
25165 |
++ /* Enabled thermal sensor after resume */ |
25166 |
++ return thermal_zone_device_enable(data->tz); |
25167 |
++} |
25168 |
++ |
25169 |
++static int __maybe_unused imx_thermal_runtime_suspend(struct device *dev) |
25170 |
++{ |
25171 |
++ struct imx_thermal_data *data = dev_get_drvdata(dev); |
25172 |
++ const struct thermal_soc_data *socdata = data->socdata; |
25173 |
++ struct regmap *map = data->tempmon; |
25174 |
++ int ret; |
25175 |
++ |
25176 |
++ ret = regmap_write(map, socdata->sensor_ctrl + REG_CLR, |
25177 |
++ socdata->measure_temp_mask); |
25178 |
++ if (ret) |
25179 |
++ return ret; |
25180 |
++ |
25181 |
++ ret = regmap_write(map, socdata->sensor_ctrl + REG_SET, |
25182 |
++ socdata->power_down_mask); |
25183 |
++ if (ret) |
25184 |
++ return ret; |
25185 |
++ |
25186 |
+ clk_disable_unprepare(data->thermal_clk); |
25187 |
+ |
25188 |
+ return 0; |
25189 |
+ } |
25190 |
+ |
25191 |
+-static int __maybe_unused imx_thermal_resume(struct device *dev) |
25192 |
++static int __maybe_unused imx_thermal_runtime_resume(struct device *dev) |
25193 |
+ { |
25194 |
+ struct imx_thermal_data *data = dev_get_drvdata(dev); |
25195 |
++ const struct thermal_soc_data *socdata = data->socdata; |
25196 |
++ struct regmap *map = data->tempmon; |
25197 |
+ int ret; |
25198 |
+ |
25199 |
+ ret = clk_prepare_enable(data->thermal_clk); |
25200 |
+ if (ret) |
25201 |
+ return ret; |
25202 |
+- /* Enabled thermal sensor after resume */ |
25203 |
+- ret = thermal_zone_device_enable(data->tz); |
25204 |
++ |
25205 |
++ ret = regmap_write(map, socdata->sensor_ctrl + REG_CLR, |
25206 |
++ socdata->power_down_mask); |
25207 |
++ if (ret) |
25208 |
++ return ret; |
25209 |
++ |
25210 |
++ ret = regmap_write(map, socdata->sensor_ctrl + REG_SET, |
25211 |
++ socdata->measure_temp_mask); |
25212 |
+ if (ret) |
25213 |
+ return ret; |
25214 |
+ |
25215 |
++ /* |
25216 |
++ * According to the temp sensor designers, it may require up to ~17us |
25217 |
++ * to complete a measurement. |
25218 |
++ */ |
25219 |
++ usleep_range(20, 50); |
25220 |
++ |
25221 |
+ return 0; |
25222 |
+ } |
25223 |
+ |
25224 |
+-static SIMPLE_DEV_PM_OPS(imx_thermal_pm_ops, |
25225 |
+- imx_thermal_suspend, imx_thermal_resume); |
25226 |
++static const struct dev_pm_ops imx_thermal_pm_ops = { |
25227 |
++ SET_SYSTEM_SLEEP_PM_OPS(imx_thermal_suspend, imx_thermal_resume) |
25228 |
++ SET_RUNTIME_PM_OPS(imx_thermal_runtime_suspend, |
25229 |
++ imx_thermal_runtime_resume, NULL) |
25230 |
++}; |
25231 |
+ |
25232 |
+ static struct platform_driver imx_thermal = { |
25233 |
+ .driver = { |
25234 |
+diff --git a/drivers/thunderbolt/acpi.c b/drivers/thunderbolt/acpi.c |
25235 |
+index b67e72d5644b3..7c9597a339295 100644 |
25236 |
+--- a/drivers/thunderbolt/acpi.c |
25237 |
++++ b/drivers/thunderbolt/acpi.c |
25238 |
+@@ -7,6 +7,7 @@ |
25239 |
+ */ |
25240 |
+ |
25241 |
+ #include <linux/acpi.h> |
25242 |
++#include <linux/pm_runtime.h> |
25243 |
+ |
25244 |
+ #include "tb.h" |
25245 |
+ |
25246 |
+@@ -74,8 +75,18 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data, |
25247 |
+ pci_pcie_type(pdev) == PCI_EXP_TYPE_DOWNSTREAM))) { |
25248 |
+ const struct device_link *link; |
25249 |
+ |
25250 |
++ /* |
25251 |
++ * Make them both active first to make sure the NHI does |
25252 |
++ * not runtime suspend before the consumer. The |
25253 |
++ * pm_runtime_put() below then allows the consumer to |
25254 |
++ * runtime suspend again (which then allows NHI runtime |
25255 |
++ * suspend too now that the device link is established). |
25256 |
++ */ |
25257 |
++ pm_runtime_get_sync(&pdev->dev); |
25258 |
++ |
25259 |
+ link = device_link_add(&pdev->dev, &nhi->pdev->dev, |
25260 |
+ DL_FLAG_AUTOREMOVE_SUPPLIER | |
25261 |
++ DL_FLAG_RPM_ACTIVE | |
25262 |
+ DL_FLAG_PM_RUNTIME); |
25263 |
+ if (link) { |
25264 |
+ dev_dbg(&nhi->pdev->dev, "created link from %s\n", |
25265 |
+@@ -84,6 +95,8 @@ static acpi_status tb_acpi_add_link(acpi_handle handle, u32 level, void *data, |
25266 |
+ dev_warn(&nhi->pdev->dev, "device link creation from %s failed\n", |
25267 |
+ dev_name(&pdev->dev)); |
25268 |
+ } |
25269 |
++ |
25270 |
++ pm_runtime_put(&pdev->dev); |
25271 |
+ } |
25272 |
+ |
25273 |
+ out_put: |
25274 |
+diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c |
25275 |
+index 1216f3985e18e..da375851af4e6 100644 |
25276 |
+--- a/drivers/tty/mxser.c |
25277 |
++++ b/drivers/tty/mxser.c |
25278 |
+@@ -261,7 +261,6 @@ struct mxser_port { |
25279 |
+ unsigned int xmit_head; |
25280 |
+ unsigned int xmit_tail; |
25281 |
+ unsigned int xmit_cnt; |
25282 |
+- int closing; |
25283 |
+ |
25284 |
+ spinlock_t slock; |
25285 |
+ }; |
25286 |
+@@ -923,7 +922,6 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) |
25287 |
+ return; |
25288 |
+ if (tty_port_close_start(port, tty, filp) == 0) |
25289 |
+ return; |
25290 |
+- info->closing = 1; |
25291 |
+ mutex_lock(&port->mutex); |
25292 |
+ mxser_close_port(port); |
25293 |
+ mxser_flush_buffer(tty); |
25294 |
+@@ -932,7 +930,6 @@ static void mxser_close(struct tty_struct *tty, struct file *filp) |
25295 |
+ mxser_shutdown_port(port); |
25296 |
+ tty_port_set_initialized(port, 0); |
25297 |
+ mutex_unlock(&port->mutex); |
25298 |
+- info->closing = 0; |
25299 |
+ /* Right now the tty_port set is done outside of the close_end helper |
25300 |
+ as we don't yet have everyone using refcounts */ |
25301 |
+ tty_port_close_end(port, tty); |
25302 |
+@@ -1693,7 +1690,7 @@ static bool mxser_port_isr(struct mxser_port *port) |
25303 |
+ |
25304 |
+ iir &= MOXA_MUST_IIR_MASK; |
25305 |
+ tty = tty_port_tty_get(&port->port); |
25306 |
+- if (!tty || port->closing || !tty_port_initialized(&port->port)) { |
25307 |
++ if (!tty) { |
25308 |
+ status = inb(port->ioaddr + UART_LSR); |
25309 |
+ outb(MOXA_MUST_FCR_GDA_MODE_ENABLE | UART_FCR_ENABLE_FIFO | |
25310 |
+ UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, |
25311 |
+diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c |
25312 |
+index 5163d60756b73..0877cf24f7de0 100644 |
25313 |
+--- a/drivers/tty/serial/8250/8250_bcm7271.c |
25314 |
++++ b/drivers/tty/serial/8250/8250_bcm7271.c |
25315 |
+@@ -1076,14 +1076,18 @@ static int brcmuart_probe(struct platform_device *pdev) |
25316 |
+ priv->rx_bufs = dma_alloc_coherent(dev, |
25317 |
+ priv->rx_size, |
25318 |
+ &priv->rx_addr, GFP_KERNEL); |
25319 |
+- if (!priv->rx_bufs) |
25320 |
++ if (!priv->rx_bufs) { |
25321 |
++ ret = -EINVAL; |
25322 |
+ goto err; |
25323 |
++ } |
25324 |
+ priv->tx_size = UART_XMIT_SIZE; |
25325 |
+ priv->tx_buf = dma_alloc_coherent(dev, |
25326 |
+ priv->tx_size, |
25327 |
+ &priv->tx_addr, GFP_KERNEL); |
25328 |
+- if (!priv->tx_buf) |
25329 |
++ if (!priv->tx_buf) { |
25330 |
++ ret = -EINVAL; |
25331 |
+ goto err; |
25332 |
++ } |
25333 |
+ } |
25334 |
+ |
25335 |
+ ret = serial8250_register_8250_port(&up); |
25336 |
+@@ -1097,6 +1101,7 @@ static int brcmuart_probe(struct platform_device *pdev) |
25337 |
+ if (priv->dma_enabled) { |
25338 |
+ dma_irq = platform_get_irq_byname(pdev, "dma"); |
25339 |
+ if (dma_irq < 0) { |
25340 |
++ ret = dma_irq; |
25341 |
+ dev_err(dev, "no IRQ resource info\n"); |
25342 |
+ goto err1; |
25343 |
+ } |
25344 |
+@@ -1116,7 +1121,7 @@ err1: |
25345 |
+ err: |
25346 |
+ brcmuart_free_bufs(dev, priv); |
25347 |
+ brcmuart_arbitration(priv, 0); |
25348 |
+- return -ENODEV; |
25349 |
++ return ret; |
25350 |
+ } |
25351 |
+ |
25352 |
+ static int brcmuart_remove(struct platform_device *pdev) |
25353 |
+diff --git a/drivers/tty/serial/amba-pl010.c b/drivers/tty/serial/amba-pl010.c |
25354 |
+index e744b953ca346..47654073123d6 100644 |
25355 |
+--- a/drivers/tty/serial/amba-pl010.c |
25356 |
++++ b/drivers/tty/serial/amba-pl010.c |
25357 |
+@@ -446,14 +446,11 @@ pl010_set_termios(struct uart_port *port, struct ktermios *termios, |
25358 |
+ if ((termios->c_cflag & CREAD) == 0) |
25359 |
+ uap->port.ignore_status_mask |= UART_DUMMY_RSR_RX; |
25360 |
+ |
25361 |
+- /* first, disable everything */ |
25362 |
+ old_cr = readb(uap->port.membase + UART010_CR) & ~UART010_CR_MSIE; |
25363 |
+ |
25364 |
+ if (UART_ENABLE_MS(port, termios->c_cflag)) |
25365 |
+ old_cr |= UART010_CR_MSIE; |
25366 |
+ |
25367 |
+- writel(0, uap->port.membase + UART010_CR); |
25368 |
+- |
25369 |
+ /* Set baud rate */ |
25370 |
+ quot -= 1; |
25371 |
+ writel((quot & 0xf00) >> 8, uap->port.membase + UART010_LCRM); |
25372 |
+diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c |
25373 |
+index 52518a606c06a..6ec34260d6b18 100644 |
25374 |
+--- a/drivers/tty/serial/amba-pl011.c |
25375 |
++++ b/drivers/tty/serial/amba-pl011.c |
25376 |
+@@ -2105,9 +2105,7 @@ pl011_set_termios(struct uart_port *port, struct ktermios *termios, |
25377 |
+ if (port->rs485.flags & SER_RS485_ENABLED) |
25378 |
+ termios->c_cflag &= ~CRTSCTS; |
25379 |
+ |
25380 |
+- /* first, disable everything */ |
25381 |
+ old_cr = pl011_read(uap, REG_CR); |
25382 |
+- pl011_write(0, uap, REG_CR); |
25383 |
+ |
25384 |
+ if (termios->c_cflag & CRTSCTS) { |
25385 |
+ if (old_cr & UART011_CR_RTS) |
25386 |
+@@ -2183,32 +2181,13 @@ static const char *pl011_type(struct uart_port *port) |
25387 |
+ return uap->port.type == PORT_AMBA ? uap->type : NULL; |
25388 |
+ } |
25389 |
+ |
25390 |
+-/* |
25391 |
+- * Release the memory region(s) being used by 'port' |
25392 |
+- */ |
25393 |
+-static void pl011_release_port(struct uart_port *port) |
25394 |
+-{ |
25395 |
+- release_mem_region(port->mapbase, SZ_4K); |
25396 |
+-} |
25397 |
+- |
25398 |
+-/* |
25399 |
+- * Request the memory region(s) being used by 'port' |
25400 |
+- */ |
25401 |
+-static int pl011_request_port(struct uart_port *port) |
25402 |
+-{ |
25403 |
+- return request_mem_region(port->mapbase, SZ_4K, "uart-pl011") |
25404 |
+- != NULL ? 0 : -EBUSY; |
25405 |
+-} |
25406 |
+- |
25407 |
+ /* |
25408 |
+ * Configure/autoconfigure the port. |
25409 |
+ */ |
25410 |
+ static void pl011_config_port(struct uart_port *port, int flags) |
25411 |
+ { |
25412 |
+- if (flags & UART_CONFIG_TYPE) { |
25413 |
++ if (flags & UART_CONFIG_TYPE) |
25414 |
+ port->type = PORT_AMBA; |
25415 |
+- pl011_request_port(port); |
25416 |
+- } |
25417 |
+ } |
25418 |
+ |
25419 |
+ /* |
25420 |
+@@ -2223,6 +2202,8 @@ static int pl011_verify_port(struct uart_port *port, struct serial_struct *ser) |
25421 |
+ ret = -EINVAL; |
25422 |
+ if (ser->baud_base < 9600) |
25423 |
+ ret = -EINVAL; |
25424 |
++ if (port->mapbase != (unsigned long) ser->iomem_base) |
25425 |
++ ret = -EINVAL; |
25426 |
+ return ret; |
25427 |
+ } |
25428 |
+ |
25429 |
+@@ -2275,8 +2256,6 @@ static const struct uart_ops amba_pl011_pops = { |
25430 |
+ .flush_buffer = pl011_dma_flush_buffer, |
25431 |
+ .set_termios = pl011_set_termios, |
25432 |
+ .type = pl011_type, |
25433 |
+- .release_port = pl011_release_port, |
25434 |
+- .request_port = pl011_request_port, |
25435 |
+ .config_port = pl011_config_port, |
25436 |
+ .verify_port = pl011_verify_port, |
25437 |
+ #ifdef CONFIG_CONSOLE_POLL |
25438 |
+@@ -2306,8 +2285,6 @@ static const struct uart_ops sbsa_uart_pops = { |
25439 |
+ .shutdown = sbsa_uart_shutdown, |
25440 |
+ .set_termios = sbsa_uart_set_termios, |
25441 |
+ .type = pl011_type, |
25442 |
+- .release_port = pl011_release_port, |
25443 |
+- .request_port = pl011_request_port, |
25444 |
+ .config_port = pl011_config_port, |
25445 |
+ .verify_port = pl011_verify_port, |
25446 |
+ #ifdef CONFIG_CONSOLE_POLL |
25447 |
+diff --git a/drivers/tty/serial/atmel_serial.c b/drivers/tty/serial/atmel_serial.c |
25448 |
+index 249ea35088d27..dd350c5908804 100644 |
25449 |
+--- a/drivers/tty/serial/atmel_serial.c |
25450 |
++++ b/drivers/tty/serial/atmel_serial.c |
25451 |
+@@ -1004,6 +1004,13 @@ static void atmel_tx_dma(struct uart_port *port) |
25452 |
+ desc->callback = atmel_complete_tx_dma; |
25453 |
+ desc->callback_param = atmel_port; |
25454 |
+ atmel_port->cookie_tx = dmaengine_submit(desc); |
25455 |
++ if (dma_submit_error(atmel_port->cookie_tx)) { |
25456 |
++ dev_err(port->dev, "dma_submit_error %d\n", |
25457 |
++ atmel_port->cookie_tx); |
25458 |
++ return; |
25459 |
++ } |
25460 |
++ |
25461 |
++ dma_async_issue_pending(chan); |
25462 |
+ } |
25463 |
+ |
25464 |
+ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) |
25465 |
+@@ -1258,6 +1265,13 @@ static int atmel_prepare_rx_dma(struct uart_port *port) |
25466 |
+ desc->callback_param = port; |
25467 |
+ atmel_port->desc_rx = desc; |
25468 |
+ atmel_port->cookie_rx = dmaengine_submit(desc); |
25469 |
++ if (dma_submit_error(atmel_port->cookie_rx)) { |
25470 |
++ dev_err(port->dev, "dma_submit_error %d\n", |
25471 |
++ atmel_port->cookie_rx); |
25472 |
++ goto chan_err; |
25473 |
++ } |
25474 |
++ |
25475 |
++ dma_async_issue_pending(atmel_port->chan_rx); |
25476 |
+ |
25477 |
+ return 0; |
25478 |
+ |
25479 |
+diff --git a/drivers/tty/serial/imx.c b/drivers/tty/serial/imx.c |
25480 |
+index 51a9f9423b1a6..7820049aba5af 100644 |
25481 |
+--- a/drivers/tty/serial/imx.c |
25482 |
++++ b/drivers/tty/serial/imx.c |
25483 |
+@@ -486,18 +486,21 @@ static void imx_uart_stop_tx(struct uart_port *port) |
25484 |
+ static void imx_uart_stop_rx(struct uart_port *port) |
25485 |
+ { |
25486 |
+ struct imx_port *sport = (struct imx_port *)port; |
25487 |
+- u32 ucr1, ucr2; |
25488 |
++ u32 ucr1, ucr2, ucr4; |
25489 |
+ |
25490 |
+ ucr1 = imx_uart_readl(sport, UCR1); |
25491 |
+ ucr2 = imx_uart_readl(sport, UCR2); |
25492 |
++ ucr4 = imx_uart_readl(sport, UCR4); |
25493 |
+ |
25494 |
+ if (sport->dma_is_enabled) { |
25495 |
+ ucr1 &= ~(UCR1_RXDMAEN | UCR1_ATDMAEN); |
25496 |
+ } else { |
25497 |
+ ucr1 &= ~UCR1_RRDYEN; |
25498 |
+ ucr2 &= ~UCR2_ATEN; |
25499 |
++ ucr4 &= ~UCR4_OREN; |
25500 |
+ } |
25501 |
+ imx_uart_writel(sport, ucr1, UCR1); |
25502 |
++ imx_uart_writel(sport, ucr4, UCR4); |
25503 |
+ |
25504 |
+ ucr2 &= ~UCR2_RXEN; |
25505 |
+ imx_uart_writel(sport, ucr2, UCR2); |
25506 |
+@@ -1544,7 +1547,7 @@ static void imx_uart_shutdown(struct uart_port *port) |
25507 |
+ imx_uart_writel(sport, ucr1, UCR1); |
25508 |
+ |
25509 |
+ ucr4 = imx_uart_readl(sport, UCR4); |
25510 |
+- ucr4 &= ~(UCR4_OREN | UCR4_TCEN); |
25511 |
++ ucr4 &= ~UCR4_TCEN; |
25512 |
+ imx_uart_writel(sport, ucr4, UCR4); |
25513 |
+ |
25514 |
+ spin_unlock_irqrestore(&sport->port.lock, flags); |
25515 |
+diff --git a/drivers/tty/serial/liteuart.c b/drivers/tty/serial/liteuart.c |
25516 |
+index 2941659e52747..7f74bf7bdcff8 100644 |
25517 |
+--- a/drivers/tty/serial/liteuart.c |
25518 |
++++ b/drivers/tty/serial/liteuart.c |
25519 |
+@@ -436,4 +436,4 @@ module_exit(liteuart_exit); |
25520 |
+ MODULE_AUTHOR("Antmicro <www.antmicro.com>"); |
25521 |
+ MODULE_DESCRIPTION("LiteUART serial driver"); |
25522 |
+ MODULE_LICENSE("GPL v2"); |
25523 |
+-MODULE_ALIAS("platform: liteuart"); |
25524 |
++MODULE_ALIAS("platform:liteuart"); |
25525 |
+diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c |
25526 |
+index 61e3dd0222af1..dc6129ddef85d 100644 |
25527 |
+--- a/drivers/tty/serial/serial_core.c |
25528 |
++++ b/drivers/tty/serial/serial_core.c |
25529 |
+@@ -162,7 +162,7 @@ static void uart_port_dtr_rts(struct uart_port *uport, int raise) |
25530 |
+ int RTS_after_send = !!(uport->rs485.flags & SER_RS485_RTS_AFTER_SEND); |
25531 |
+ |
25532 |
+ if (raise) { |
25533 |
+- if (rs485_on && !RTS_after_send) { |
25534 |
++ if (rs485_on && RTS_after_send) { |
25535 |
+ uart_set_mctrl(uport, TIOCM_DTR); |
25536 |
+ uart_clear_mctrl(uport, TIOCM_RTS); |
25537 |
+ } else { |
25538 |
+@@ -171,7 +171,7 @@ static void uart_port_dtr_rts(struct uart_port *uport, int raise) |
25539 |
+ } else { |
25540 |
+ unsigned int clear = TIOCM_DTR; |
25541 |
+ |
25542 |
+- clear |= (!rs485_on || !RTS_after_send) ? TIOCM_RTS : 0; |
25543 |
++ clear |= (!rs485_on || RTS_after_send) ? TIOCM_RTS : 0; |
25544 |
+ uart_clear_mctrl(uport, clear); |
25545 |
+ } |
25546 |
+ } |
25547 |
+@@ -2393,7 +2393,8 @@ uart_configure_port(struct uart_driver *drv, struct uart_state *state, |
25548 |
+ * We probably don't need a spinlock around this, but |
25549 |
+ */ |
25550 |
+ spin_lock_irqsave(&port->lock, flags); |
25551 |
+- port->ops->set_mctrl(port, port->mctrl & TIOCM_DTR); |
25552 |
++ port->mctrl &= TIOCM_DTR; |
25553 |
++ port->ops->set_mctrl(port, port->mctrl); |
25554 |
+ spin_unlock_irqrestore(&port->lock, flags); |
25555 |
+ |
25556 |
+ /* |
25557 |
+diff --git a/drivers/tty/serial/stm32-usart.c b/drivers/tty/serial/stm32-usart.c |
25558 |
+index 8f032e77b954a..3366914dad7a8 100644 |
25559 |
+--- a/drivers/tty/serial/stm32-usart.c |
25560 |
++++ b/drivers/tty/serial/stm32-usart.c |
25561 |
+@@ -691,6 +691,11 @@ static void stm32_usart_shutdown(struct uart_port *port) |
25562 |
+ u32 val, isr; |
25563 |
+ int ret; |
25564 |
+ |
25565 |
++ if (stm32_port->tx_dma_busy) { |
25566 |
++ dmaengine_terminate_async(stm32_port->tx_ch); |
25567 |
++ stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAT); |
25568 |
++ } |
25569 |
++ |
25570 |
+ /* Disable modem control interrupts */ |
25571 |
+ stm32_usart_disable_ms(port); |
25572 |
+ |
25573 |
+@@ -1385,7 +1390,6 @@ static int stm32_usart_serial_remove(struct platform_device *pdev) |
25574 |
+ stm32_usart_clr_bits(port, ofs->cr3, USART_CR3_DMAR); |
25575 |
+ |
25576 |
+ if (stm32_port->tx_ch) { |
25577 |
+- dmaengine_terminate_async(stm32_port->tx_ch); |
25578 |
+ stm32_usart_of_dma_tx_remove(stm32_port, pdev); |
25579 |
+ dma_release_channel(stm32_port->tx_ch); |
25580 |
+ } |
25581 |
+diff --git a/drivers/tty/serial/uartlite.c b/drivers/tty/serial/uartlite.c |
25582 |
+index dfc1ba4e15724..36871cebd6a0f 100644 |
25583 |
+--- a/drivers/tty/serial/uartlite.c |
25584 |
++++ b/drivers/tty/serial/uartlite.c |
25585 |
+@@ -612,7 +612,7 @@ static struct uart_driver ulite_uart_driver = { |
25586 |
+ * |
25587 |
+ * Returns: 0 on success, <0 otherwise |
25588 |
+ */ |
25589 |
+-static int ulite_assign(struct device *dev, int id, u32 base, int irq, |
25590 |
++static int ulite_assign(struct device *dev, int id, phys_addr_t base, int irq, |
25591 |
+ struct uartlite_data *pdata) |
25592 |
+ { |
25593 |
+ struct uart_port *port; |
25594 |
+diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c |
25595 |
+index 3bc4a86c3d0a5..ac6c5ccfe1cb7 100644 |
25596 |
+--- a/drivers/usb/core/hub.c |
25597 |
++++ b/drivers/usb/core/hub.c |
25598 |
+@@ -1110,7 +1110,10 @@ static void hub_activate(struct usb_hub *hub, enum hub_activation_type type) |
25599 |
+ } else { |
25600 |
+ hub_power_on(hub, true); |
25601 |
+ } |
25602 |
+- } |
25603 |
++ /* Give some time on remote wakeup to let links to transit to U0 */ |
25604 |
++ } else if (hub_is_superspeed(hub->hdev)) |
25605 |
++ msleep(20); |
25606 |
++ |
25607 |
+ init2: |
25608 |
+ |
25609 |
+ /* |
25610 |
+diff --git a/drivers/usb/dwc2/gadget.c b/drivers/usb/dwc2/gadget.c |
25611 |
+index 2190225bf3da2..ea0d2d6139a68 100644 |
25612 |
+--- a/drivers/usb/dwc2/gadget.c |
25613 |
++++ b/drivers/usb/dwc2/gadget.c |
25614 |
+@@ -4974,7 +4974,18 @@ int dwc2_gadget_init(struct dwc2_hsotg *hsotg) |
25615 |
+ hsotg->params.g_np_tx_fifo_size); |
25616 |
+ dev_dbg(dev, "RXFIFO size: %d\n", hsotg->params.g_rx_fifo_size); |
25617 |
+ |
25618 |
+- hsotg->gadget.max_speed = USB_SPEED_HIGH; |
25619 |
++ switch (hsotg->params.speed) { |
25620 |
++ case DWC2_SPEED_PARAM_LOW: |
25621 |
++ hsotg->gadget.max_speed = USB_SPEED_LOW; |
25622 |
++ break; |
25623 |
++ case DWC2_SPEED_PARAM_FULL: |
25624 |
++ hsotg->gadget.max_speed = USB_SPEED_FULL; |
25625 |
++ break; |
25626 |
++ default: |
25627 |
++ hsotg->gadget.max_speed = USB_SPEED_HIGH; |
25628 |
++ break; |
25629 |
++ } |
25630 |
++ |
25631 |
+ hsotg->gadget.ops = &dwc2_hsotg_gadget_ops; |
25632 |
+ hsotg->gadget.name = dev_name(dev); |
25633 |
+ hsotg->remote_wakeup_allowed = 0; |
25634 |
+diff --git a/drivers/usb/dwc2/hcd.c b/drivers/usb/dwc2/hcd.c |
25635 |
+index a215ec9e172e6..657dbd50faf11 100644 |
25636 |
+--- a/drivers/usb/dwc2/hcd.c |
25637 |
++++ b/drivers/usb/dwc2/hcd.c |
25638 |
+@@ -4403,11 +4403,12 @@ static int _dwc2_hcd_suspend(struct usb_hcd *hcd) |
25639 |
+ * If not hibernation nor partial power down are supported, |
25640 |
+ * clock gating is used to save power. |
25641 |
+ */ |
25642 |
+- if (!hsotg->params.no_clock_gating) |
25643 |
++ if (!hsotg->params.no_clock_gating) { |
25644 |
+ dwc2_host_enter_clock_gating(hsotg); |
25645 |
+ |
25646 |
+- /* After entering suspend, hardware is not accessible */ |
25647 |
+- clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
25648 |
++ /* After entering suspend, hardware is not accessible */ |
25649 |
++ clear_bit(HCD_FLAG_HW_ACCESSIBLE, &hcd->flags); |
25650 |
++ } |
25651 |
+ break; |
25652 |
+ default: |
25653 |
+ goto skip_power_saving; |
25654 |
+diff --git a/drivers/usb/dwc3/dwc3-meson-g12a.c b/drivers/usb/dwc3/dwc3-meson-g12a.c |
25655 |
+index d0f9b7c296b0d..bd814df3bf8b8 100644 |
25656 |
+--- a/drivers/usb/dwc3/dwc3-meson-g12a.c |
25657 |
++++ b/drivers/usb/dwc3/dwc3-meson-g12a.c |
25658 |
+@@ -755,16 +755,16 @@ static int dwc3_meson_g12a_probe(struct platform_device *pdev) |
25659 |
+ |
25660 |
+ ret = dwc3_meson_g12a_get_phys(priv); |
25661 |
+ if (ret) |
25662 |
+- goto err_disable_clks; |
25663 |
++ goto err_rearm; |
25664 |
+ |
25665 |
+ ret = priv->drvdata->setup_regmaps(priv, base); |
25666 |
+ if (ret) |
25667 |
+- goto err_disable_clks; |
25668 |
++ goto err_rearm; |
25669 |
+ |
25670 |
+ if (priv->vbus) { |
25671 |
+ ret = regulator_enable(priv->vbus); |
25672 |
+ if (ret) |
25673 |
+- goto err_disable_clks; |
25674 |
++ goto err_rearm; |
25675 |
+ } |
25676 |
+ |
25677 |
+ /* Get dr_mode */ |
25678 |
+@@ -825,6 +825,9 @@ err_disable_regulator: |
25679 |
+ if (priv->vbus) |
25680 |
+ regulator_disable(priv->vbus); |
25681 |
+ |
25682 |
++err_rearm: |
25683 |
++ reset_control_rearm(priv->reset); |
25684 |
++ |
25685 |
+ err_disable_clks: |
25686 |
+ clk_bulk_disable_unprepare(priv->drvdata->num_clks, |
25687 |
+ priv->drvdata->clks); |
25688 |
+@@ -852,6 +855,8 @@ static int dwc3_meson_g12a_remove(struct platform_device *pdev) |
25689 |
+ pm_runtime_put_noidle(dev); |
25690 |
+ pm_runtime_set_suspended(dev); |
25691 |
+ |
25692 |
++ reset_control_rearm(priv->reset); |
25693 |
++ |
25694 |
+ clk_bulk_disable_unprepare(priv->drvdata->num_clks, |
25695 |
+ priv->drvdata->clks); |
25696 |
+ |
25697 |
+@@ -892,7 +897,7 @@ static int __maybe_unused dwc3_meson_g12a_suspend(struct device *dev) |
25698 |
+ phy_exit(priv->phys[i]); |
25699 |
+ } |
25700 |
+ |
25701 |
+- reset_control_assert(priv->reset); |
25702 |
++ reset_control_rearm(priv->reset); |
25703 |
+ |
25704 |
+ return 0; |
25705 |
+ } |
25706 |
+@@ -902,7 +907,9 @@ static int __maybe_unused dwc3_meson_g12a_resume(struct device *dev) |
25707 |
+ struct dwc3_meson_g12a *priv = dev_get_drvdata(dev); |
25708 |
+ int i, ret; |
25709 |
+ |
25710 |
+- reset_control_deassert(priv->reset); |
25711 |
++ ret = reset_control_reset(priv->reset); |
25712 |
++ if (ret) |
25713 |
++ return ret; |
25714 |
+ |
25715 |
+ ret = priv->drvdata->usb_init(priv); |
25716 |
+ if (ret) |
25717 |
+diff --git a/drivers/usb/dwc3/dwc3-qcom.c b/drivers/usb/dwc3/dwc3-qcom.c |
25718 |
+index 3cb01cdd02c29..b81a9e1c13153 100644 |
25719 |
+--- a/drivers/usb/dwc3/dwc3-qcom.c |
25720 |
++++ b/drivers/usb/dwc3/dwc3-qcom.c |
25721 |
+@@ -769,9 +769,12 @@ static int dwc3_qcom_probe(struct platform_device *pdev) |
25722 |
+ |
25723 |
+ if (qcom->acpi_pdata->is_urs) { |
25724 |
+ qcom->urs_usb = dwc3_qcom_create_urs_usb_platdev(dev); |
25725 |
+- if (!qcom->urs_usb) { |
25726 |
++ if (IS_ERR_OR_NULL(qcom->urs_usb)) { |
25727 |
+ dev_err(dev, "failed to create URS USB platdev\n"); |
25728 |
+- return -ENODEV; |
25729 |
++ if (!qcom->urs_usb) |
25730 |
++ return -ENODEV; |
25731 |
++ else |
25732 |
++ return PTR_ERR(qcom->urs_usb); |
25733 |
+ } |
25734 |
+ } |
25735 |
+ } |
25736 |
+diff --git a/drivers/usb/gadget/function/f_fs.c b/drivers/usb/gadget/function/f_fs.c |
25737 |
+index aac343f7d7d3d..782d67c2c6e0d 100644 |
25738 |
+--- a/drivers/usb/gadget/function/f_fs.c |
25739 |
++++ b/drivers/usb/gadget/function/f_fs.c |
25740 |
+@@ -614,7 +614,7 @@ static int ffs_ep0_open(struct inode *inode, struct file *file) |
25741 |
+ file->private_data = ffs; |
25742 |
+ ffs_data_opened(ffs); |
25743 |
+ |
25744 |
+- return 0; |
25745 |
++ return stream_open(inode, file); |
25746 |
+ } |
25747 |
+ |
25748 |
+ static int ffs_ep0_release(struct inode *inode, struct file *file) |
25749 |
+@@ -1154,7 +1154,7 @@ ffs_epfile_open(struct inode *inode, struct file *file) |
25750 |
+ file->private_data = epfile; |
25751 |
+ ffs_data_opened(epfile->ffs); |
25752 |
+ |
25753 |
+- return 0; |
25754 |
++ return stream_open(inode, file); |
25755 |
+ } |
25756 |
+ |
25757 |
+ static int ffs_aio_cancel(struct kiocb *kiocb) |
25758 |
+diff --git a/drivers/usb/gadget/function/u_audio.c b/drivers/usb/gadget/function/u_audio.c |
25759 |
+index ad16163b5ff80..d22ac23c94b0f 100644 |
25760 |
+--- a/drivers/usb/gadget/function/u_audio.c |
25761 |
++++ b/drivers/usb/gadget/function/u_audio.c |
25762 |
+@@ -1097,7 +1097,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, |
25763 |
+ } |
25764 |
+ |
25765 |
+ kctl->id.device = pcm->device; |
25766 |
+- kctl->id.subdevice = i; |
25767 |
++ kctl->id.subdevice = 0; |
25768 |
+ |
25769 |
+ err = snd_ctl_add(card, kctl); |
25770 |
+ if (err < 0) |
25771 |
+@@ -1120,7 +1120,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, |
25772 |
+ } |
25773 |
+ |
25774 |
+ kctl->id.device = pcm->device; |
25775 |
+- kctl->id.subdevice = i; |
25776 |
++ kctl->id.subdevice = 0; |
25777 |
+ |
25778 |
+ |
25779 |
+ kctl->tlv.c = u_audio_volume_tlv; |
25780 |
+diff --git a/drivers/usb/host/ehci-brcm.c b/drivers/usb/host/ehci-brcm.c |
25781 |
+index d3626bfa966b4..6a0f64c9e5e88 100644 |
25782 |
+--- a/drivers/usb/host/ehci-brcm.c |
25783 |
++++ b/drivers/usb/host/ehci-brcm.c |
25784 |
+@@ -62,8 +62,12 @@ static int ehci_brcm_hub_control( |
25785 |
+ u32 __iomem *status_reg; |
25786 |
+ unsigned long flags; |
25787 |
+ int retval, irq_disabled = 0; |
25788 |
++ u32 temp; |
25789 |
+ |
25790 |
+- status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1]; |
25791 |
++ temp = (wIndex & 0xff) - 1; |
25792 |
++ if (temp >= HCS_N_PORTS_MAX) /* Avoid index-out-of-bounds warning */ |
25793 |
++ temp = 0; |
25794 |
++ status_reg = &ehci->regs->port_status[temp]; |
25795 |
+ |
25796 |
+ /* |
25797 |
+ * RESUME is cleared when GetPortStatus() is called 20ms after start |
25798 |
+diff --git a/drivers/usb/host/uhci-platform.c b/drivers/usb/host/uhci-platform.c |
25799 |
+index 70dbd95c3f063..be9e9db7cad10 100644 |
25800 |
+--- a/drivers/usb/host/uhci-platform.c |
25801 |
++++ b/drivers/usb/host/uhci-platform.c |
25802 |
+@@ -113,7 +113,8 @@ static int uhci_hcd_platform_probe(struct platform_device *pdev) |
25803 |
+ num_ports); |
25804 |
+ } |
25805 |
+ if (of_device_is_compatible(np, "aspeed,ast2400-uhci") || |
25806 |
+- of_device_is_compatible(np, "aspeed,ast2500-uhci")) { |
25807 |
++ of_device_is_compatible(np, "aspeed,ast2500-uhci") || |
25808 |
++ of_device_is_compatible(np, "aspeed,ast2600-uhci")) { |
25809 |
+ uhci->is_aspeed = 1; |
25810 |
+ dev_info(&pdev->dev, |
25811 |
+ "Enabled Aspeed implementation workarounds\n"); |
25812 |
+diff --git a/drivers/usb/misc/ftdi-elan.c b/drivers/usb/misc/ftdi-elan.c |
25813 |
+index e5a8fcdbb78e7..6c38c62d29b26 100644 |
25814 |
+--- a/drivers/usb/misc/ftdi-elan.c |
25815 |
++++ b/drivers/usb/misc/ftdi-elan.c |
25816 |
+@@ -202,6 +202,7 @@ static void ftdi_elan_delete(struct kref *kref) |
25817 |
+ mutex_unlock(&ftdi_module_lock); |
25818 |
+ kfree(ftdi->bulk_in_buffer); |
25819 |
+ ftdi->bulk_in_buffer = NULL; |
25820 |
++ kfree(ftdi); |
25821 |
+ } |
25822 |
+ |
25823 |
+ static void ftdi_elan_put_kref(struct usb_ftdi *ftdi) |
25824 |
+diff --git a/drivers/vdpa/ifcvf/ifcvf_base.c b/drivers/vdpa/ifcvf/ifcvf_base.c |
25825 |
+index 2808f1ba9f7b8..7d41dfe48adee 100644 |
25826 |
+--- a/drivers/vdpa/ifcvf/ifcvf_base.c |
25827 |
++++ b/drivers/vdpa/ifcvf/ifcvf_base.c |
25828 |
+@@ -143,8 +143,8 @@ int ifcvf_init_hw(struct ifcvf_hw *hw, struct pci_dev *pdev) |
25829 |
+ IFCVF_DBG(pdev, "hw->isr = %p\n", hw->isr); |
25830 |
+ break; |
25831 |
+ case VIRTIO_PCI_CAP_DEVICE_CFG: |
25832 |
+- hw->net_cfg = get_cap_addr(hw, &cap); |
25833 |
+- IFCVF_DBG(pdev, "hw->net_cfg = %p\n", hw->net_cfg); |
25834 |
++ hw->dev_cfg = get_cap_addr(hw, &cap); |
25835 |
++ IFCVF_DBG(pdev, "hw->dev_cfg = %p\n", hw->dev_cfg); |
25836 |
+ break; |
25837 |
+ } |
25838 |
+ |
25839 |
+@@ -153,7 +153,7 @@ next: |
25840 |
+ } |
25841 |
+ |
25842 |
+ if (hw->common_cfg == NULL || hw->notify_base == NULL || |
25843 |
+- hw->isr == NULL || hw->net_cfg == NULL) { |
25844 |
++ hw->isr == NULL || hw->dev_cfg == NULL) { |
25845 |
+ IFCVF_ERR(pdev, "Incomplete PCI capabilities\n"); |
25846 |
+ return -EIO; |
25847 |
+ } |
25848 |
+@@ -174,7 +174,7 @@ next: |
25849 |
+ IFCVF_DBG(pdev, |
25850 |
+ "PCI capability mapping: common cfg: %p, notify base: %p\n, isr cfg: %p, device cfg: %p, multiplier: %u\n", |
25851 |
+ hw->common_cfg, hw->notify_base, hw->isr, |
25852 |
+- hw->net_cfg, hw->notify_off_multiplier); |
25853 |
++ hw->dev_cfg, hw->notify_off_multiplier); |
25854 |
+ |
25855 |
+ return 0; |
25856 |
+ } |
25857 |
+@@ -242,33 +242,54 @@ int ifcvf_verify_min_features(struct ifcvf_hw *hw, u64 features) |
25858 |
+ return 0; |
25859 |
+ } |
25860 |
+ |
25861 |
+-void ifcvf_read_net_config(struct ifcvf_hw *hw, u64 offset, |
25862 |
++u32 ifcvf_get_config_size(struct ifcvf_hw *hw) |
25863 |
++{ |
25864 |
++ struct ifcvf_adapter *adapter; |
25865 |
++ u32 config_size; |
25866 |
++ |
25867 |
++ adapter = vf_to_adapter(hw); |
25868 |
++ switch (hw->dev_type) { |
25869 |
++ case VIRTIO_ID_NET: |
25870 |
++ config_size = sizeof(struct virtio_net_config); |
25871 |
++ break; |
25872 |
++ case VIRTIO_ID_BLOCK: |
25873 |
++ config_size = sizeof(struct virtio_blk_config); |
25874 |
++ break; |
25875 |
++ default: |
25876 |
++ config_size = 0; |
25877 |
++ IFCVF_ERR(adapter->pdev, "VIRTIO ID %u not supported\n", hw->dev_type); |
25878 |
++ } |
25879 |
++ |
25880 |
++ return config_size; |
25881 |
++} |
25882 |
++ |
25883 |
++void ifcvf_read_dev_config(struct ifcvf_hw *hw, u64 offset, |
25884 |
+ void *dst, int length) |
25885 |
+ { |
25886 |
+ u8 old_gen, new_gen, *p; |
25887 |
+ int i; |
25888 |
+ |
25889 |
+- WARN_ON(offset + length > sizeof(struct virtio_net_config)); |
25890 |
++ WARN_ON(offset + length > hw->config_size); |
25891 |
+ do { |
25892 |
+ old_gen = ifc_ioread8(&hw->common_cfg->config_generation); |
25893 |
+ p = dst; |
25894 |
+ for (i = 0; i < length; i++) |
25895 |
+- *p++ = ifc_ioread8(hw->net_cfg + offset + i); |
25896 |
++ *p++ = ifc_ioread8(hw->dev_cfg + offset + i); |
25897 |
+ |
25898 |
+ new_gen = ifc_ioread8(&hw->common_cfg->config_generation); |
25899 |
+ } while (old_gen != new_gen); |
25900 |
+ } |
25901 |
+ |
25902 |
+-void ifcvf_write_net_config(struct ifcvf_hw *hw, u64 offset, |
25903 |
++void ifcvf_write_dev_config(struct ifcvf_hw *hw, u64 offset, |
25904 |
+ const void *src, int length) |
25905 |
+ { |
25906 |
+ const u8 *p; |
25907 |
+ int i; |
25908 |
+ |
25909 |
+ p = src; |
25910 |
+- WARN_ON(offset + length > sizeof(struct virtio_net_config)); |
25911 |
++ WARN_ON(offset + length > hw->config_size); |
25912 |
+ for (i = 0; i < length; i++) |
25913 |
+- ifc_iowrite8(*p++, hw->net_cfg + offset + i); |
25914 |
++ ifc_iowrite8(*p++, hw->dev_cfg + offset + i); |
25915 |
+ } |
25916 |
+ |
25917 |
+ static void ifcvf_set_features(struct ifcvf_hw *hw, u64 features) |
25918 |
+diff --git a/drivers/vdpa/ifcvf/ifcvf_base.h b/drivers/vdpa/ifcvf/ifcvf_base.h |
25919 |
+index 09918af3ecf82..c486873f370a8 100644 |
25920 |
+--- a/drivers/vdpa/ifcvf/ifcvf_base.h |
25921 |
++++ b/drivers/vdpa/ifcvf/ifcvf_base.h |
25922 |
+@@ -71,12 +71,14 @@ struct ifcvf_hw { |
25923 |
+ u64 hw_features; |
25924 |
+ u32 dev_type; |
25925 |
+ struct virtio_pci_common_cfg __iomem *common_cfg; |
25926 |
+- void __iomem *net_cfg; |
25927 |
++ void __iomem *dev_cfg; |
25928 |
+ struct vring_info vring[IFCVF_MAX_QUEUES]; |
25929 |
+ void __iomem * const *base; |
25930 |
+ char config_msix_name[256]; |
25931 |
+ struct vdpa_callback config_cb; |
25932 |
+ unsigned int config_irq; |
25933 |
++ /* virtio-net or virtio-blk device config size */ |
25934 |
++ u32 config_size; |
25935 |
+ }; |
25936 |
+ |
25937 |
+ struct ifcvf_adapter { |
25938 |
+@@ -105,9 +107,9 @@ int ifcvf_init_hw(struct ifcvf_hw *hw, struct pci_dev *dev); |
25939 |
+ int ifcvf_start_hw(struct ifcvf_hw *hw); |
25940 |
+ void ifcvf_stop_hw(struct ifcvf_hw *hw); |
25941 |
+ void ifcvf_notify_queue(struct ifcvf_hw *hw, u16 qid); |
25942 |
+-void ifcvf_read_net_config(struct ifcvf_hw *hw, u64 offset, |
25943 |
++void ifcvf_read_dev_config(struct ifcvf_hw *hw, u64 offset, |
25944 |
+ void *dst, int length); |
25945 |
+-void ifcvf_write_net_config(struct ifcvf_hw *hw, u64 offset, |
25946 |
++void ifcvf_write_dev_config(struct ifcvf_hw *hw, u64 offset, |
25947 |
+ const void *src, int length); |
25948 |
+ u8 ifcvf_get_status(struct ifcvf_hw *hw); |
25949 |
+ void ifcvf_set_status(struct ifcvf_hw *hw, u8 status); |
25950 |
+@@ -120,4 +122,5 @@ u16 ifcvf_get_vq_state(struct ifcvf_hw *hw, u16 qid); |
25951 |
+ int ifcvf_set_vq_state(struct ifcvf_hw *hw, u16 qid, u16 num); |
25952 |
+ struct ifcvf_adapter *vf_to_adapter(struct ifcvf_hw *hw); |
25953 |
+ int ifcvf_probed_virtio_net(struct ifcvf_hw *hw); |
25954 |
++u32 ifcvf_get_config_size(struct ifcvf_hw *hw); |
25955 |
+ #endif /* _IFCVF_H_ */ |
25956 |
+diff --git a/drivers/vdpa/ifcvf/ifcvf_main.c b/drivers/vdpa/ifcvf/ifcvf_main.c |
25957 |
+index dcd648e1f7e7e..003530b19b4ee 100644 |
25958 |
+--- a/drivers/vdpa/ifcvf/ifcvf_main.c |
25959 |
++++ b/drivers/vdpa/ifcvf/ifcvf_main.c |
25960 |
+@@ -366,24 +366,9 @@ static u32 ifcvf_vdpa_get_vq_align(struct vdpa_device *vdpa_dev) |
25961 |
+ |
25962 |
+ static size_t ifcvf_vdpa_get_config_size(struct vdpa_device *vdpa_dev) |
25963 |
+ { |
25964 |
+- struct ifcvf_adapter *adapter = vdpa_to_adapter(vdpa_dev); |
25965 |
+ struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); |
25966 |
+- struct pci_dev *pdev = adapter->pdev; |
25967 |
+- size_t size; |
25968 |
+- |
25969 |
+- switch (vf->dev_type) { |
25970 |
+- case VIRTIO_ID_NET: |
25971 |
+- size = sizeof(struct virtio_net_config); |
25972 |
+- break; |
25973 |
+- case VIRTIO_ID_BLOCK: |
25974 |
+- size = sizeof(struct virtio_blk_config); |
25975 |
+- break; |
25976 |
+- default: |
25977 |
+- size = 0; |
25978 |
+- IFCVF_ERR(pdev, "VIRTIO ID %u not supported\n", vf->dev_type); |
25979 |
+- } |
25980 |
+ |
25981 |
+- return size; |
25982 |
++ return vf->config_size; |
25983 |
+ } |
25984 |
+ |
25985 |
+ static void ifcvf_vdpa_get_config(struct vdpa_device *vdpa_dev, |
25986 |
+@@ -392,8 +377,7 @@ static void ifcvf_vdpa_get_config(struct vdpa_device *vdpa_dev, |
25987 |
+ { |
25988 |
+ struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); |
25989 |
+ |
25990 |
+- WARN_ON(offset + len > sizeof(struct virtio_net_config)); |
25991 |
+- ifcvf_read_net_config(vf, offset, buf, len); |
25992 |
++ ifcvf_read_dev_config(vf, offset, buf, len); |
25993 |
+ } |
25994 |
+ |
25995 |
+ static void ifcvf_vdpa_set_config(struct vdpa_device *vdpa_dev, |
25996 |
+@@ -402,8 +386,7 @@ static void ifcvf_vdpa_set_config(struct vdpa_device *vdpa_dev, |
25997 |
+ { |
25998 |
+ struct ifcvf_hw *vf = vdpa_to_vf(vdpa_dev); |
25999 |
+ |
26000 |
+- WARN_ON(offset + len > sizeof(struct virtio_net_config)); |
26001 |
+- ifcvf_write_net_config(vf, offset, buf, len); |
26002 |
++ ifcvf_write_dev_config(vf, offset, buf, len); |
26003 |
+ } |
26004 |
+ |
26005 |
+ static void ifcvf_vdpa_set_config_cb(struct vdpa_device *vdpa_dev, |
26006 |
+@@ -541,6 +524,7 @@ static int ifcvf_vdpa_dev_add(struct vdpa_mgmt_dev *mdev, const char *name) |
26007 |
+ vf->vring[i].irq = -EINVAL; |
26008 |
+ |
26009 |
+ vf->hw_features = ifcvf_get_hw_features(vf); |
26010 |
++ vf->config_size = ifcvf_get_config_size(vf); |
26011 |
+ |
26012 |
+ adapter->vdpa.mdev = &ifcvf_mgmt_dev->mdev; |
26013 |
+ ret = _vdpa_register_device(&adapter->vdpa, vf->nr_vring); |
26014 |
+diff --git a/drivers/vdpa/mlx5/net/mlx5_vnet.c b/drivers/vdpa/mlx5/net/mlx5_vnet.c |
26015 |
+index ae85d2dd6eb76..1afbda216df52 100644 |
26016 |
+--- a/drivers/vdpa/mlx5/net/mlx5_vnet.c |
26017 |
++++ b/drivers/vdpa/mlx5/net/mlx5_vnet.c |
26018 |
+@@ -873,8 +873,6 @@ static int create_virtqueue(struct mlx5_vdpa_net *ndev, struct mlx5_vdpa_virtque |
26019 |
+ MLX5_SET(virtio_q, vq_ctx, umem_3_id, mvq->umem3.id); |
26020 |
+ MLX5_SET(virtio_q, vq_ctx, umem_3_size, mvq->umem3.size); |
26021 |
+ MLX5_SET(virtio_q, vq_ctx, pd, ndev->mvdev.res.pdn); |
26022 |
+- if (MLX5_CAP_DEV_VDPA_EMULATION(ndev->mvdev.mdev, eth_frame_offload_type)) |
26023 |
+- MLX5_SET(virtio_q, vq_ctx, virtio_version_1_0, 1); |
26024 |
+ |
26025 |
+ err = mlx5_cmd_exec(ndev->mvdev.mdev, in, inlen, out, sizeof(out)); |
26026 |
+ if (err) |
26027 |
+@@ -1512,9 +1510,11 @@ static int change_num_qps(struct mlx5_vdpa_dev *mvdev, int newqps) |
26028 |
+ return 0; |
26029 |
+ |
26030 |
+ clean_added: |
26031 |
+- for (--i; i >= cur_qps; --i) |
26032 |
++ for (--i; i >= 2 * cur_qps; --i) |
26033 |
+ teardown_vq(ndev, &ndev->vqs[i]); |
26034 |
+ |
26035 |
++ ndev->cur_num_vqs = 2 * cur_qps; |
26036 |
++ |
26037 |
+ return err; |
26038 |
+ } |
26039 |
+ |
26040 |
+diff --git a/drivers/video/backlight/qcom-wled.c b/drivers/video/backlight/qcom-wled.c |
26041 |
+index d094299c2a485..f12c76d6e61de 100644 |
26042 |
+--- a/drivers/video/backlight/qcom-wled.c |
26043 |
++++ b/drivers/video/backlight/qcom-wled.c |
26044 |
+@@ -231,14 +231,14 @@ struct wled { |
26045 |
+ static int wled3_set_brightness(struct wled *wled, u16 brightness) |
26046 |
+ { |
26047 |
+ int rc, i; |
26048 |
+- u8 v[2]; |
26049 |
++ __le16 v; |
26050 |
+ |
26051 |
+- v[0] = brightness & 0xff; |
26052 |
+- v[1] = (brightness >> 8) & 0xf; |
26053 |
++ v = cpu_to_le16(brightness & WLED3_SINK_REG_BRIGHT_MAX); |
26054 |
+ |
26055 |
+ for (i = 0; i < wled->cfg.num_strings; ++i) { |
26056 |
+ rc = regmap_bulk_write(wled->regmap, wled->ctrl_addr + |
26057 |
+- WLED3_SINK_REG_BRIGHT(i), v, 2); |
26058 |
++ WLED3_SINK_REG_BRIGHT(wled->cfg.enabled_strings[i]), |
26059 |
++ &v, sizeof(v)); |
26060 |
+ if (rc < 0) |
26061 |
+ return rc; |
26062 |
+ } |
26063 |
+@@ -250,18 +250,18 @@ static int wled4_set_brightness(struct wled *wled, u16 brightness) |
26064 |
+ { |
26065 |
+ int rc, i; |
26066 |
+ u16 low_limit = wled->max_brightness * 4 / 1000; |
26067 |
+- u8 v[2]; |
26068 |
++ __le16 v; |
26069 |
+ |
26070 |
+ /* WLED4's lower limit of operation is 0.4% */ |
26071 |
+ if (brightness > 0 && brightness < low_limit) |
26072 |
+ brightness = low_limit; |
26073 |
+ |
26074 |
+- v[0] = brightness & 0xff; |
26075 |
+- v[1] = (brightness >> 8) & 0xf; |
26076 |
++ v = cpu_to_le16(brightness & WLED3_SINK_REG_BRIGHT_MAX); |
26077 |
+ |
26078 |
+ for (i = 0; i < wled->cfg.num_strings; ++i) { |
26079 |
+ rc = regmap_bulk_write(wled->regmap, wled->sink_addr + |
26080 |
+- WLED4_SINK_REG_BRIGHT(i), v, 2); |
26081 |
++ WLED4_SINK_REG_BRIGHT(wled->cfg.enabled_strings[i]), |
26082 |
++ &v, sizeof(v)); |
26083 |
+ if (rc < 0) |
26084 |
+ return rc; |
26085 |
+ } |
26086 |
+@@ -273,21 +273,20 @@ static int wled5_set_brightness(struct wled *wled, u16 brightness) |
26087 |
+ { |
26088 |
+ int rc, offset; |
26089 |
+ u16 low_limit = wled->max_brightness * 1 / 1000; |
26090 |
+- u8 v[2]; |
26091 |
++ __le16 v; |
26092 |
+ |
26093 |
+ /* WLED5's lower limit is 0.1% */ |
26094 |
+ if (brightness < low_limit) |
26095 |
+ brightness = low_limit; |
26096 |
+ |
26097 |
+- v[0] = brightness & 0xff; |
26098 |
+- v[1] = (brightness >> 8) & 0x7f; |
26099 |
++ v = cpu_to_le16(brightness & WLED5_SINK_REG_BRIGHT_MAX_15B); |
26100 |
+ |
26101 |
+ offset = (wled->cfg.mod_sel == MOD_A) ? |
26102 |
+ WLED5_SINK_REG_MOD_A_BRIGHTNESS_LSB : |
26103 |
+ WLED5_SINK_REG_MOD_B_BRIGHTNESS_LSB; |
26104 |
+ |
26105 |
+ rc = regmap_bulk_write(wled->regmap, wled->sink_addr + offset, |
26106 |
+- v, 2); |
26107 |
++ &v, sizeof(v)); |
26108 |
+ return rc; |
26109 |
+ } |
26110 |
+ |
26111 |
+@@ -572,7 +571,7 @@ unlock_mutex: |
26112 |
+ |
26113 |
+ static void wled_auto_string_detection(struct wled *wled) |
26114 |
+ { |
26115 |
+- int rc = 0, i, delay_time_us; |
26116 |
++ int rc = 0, i, j, delay_time_us; |
26117 |
+ u32 sink_config = 0; |
26118 |
+ u8 sink_test = 0, sink_valid = 0, val; |
26119 |
+ bool fault_set; |
26120 |
+@@ -619,14 +618,15 @@ static void wled_auto_string_detection(struct wled *wled) |
26121 |
+ |
26122 |
+ /* Iterate through the strings one by one */ |
26123 |
+ for (i = 0; i < wled->cfg.num_strings; i++) { |
26124 |
+- sink_test = BIT((WLED4_SINK_REG_CURR_SINK_SHFT + i)); |
26125 |
++ j = wled->cfg.enabled_strings[i]; |
26126 |
++ sink_test = BIT((WLED4_SINK_REG_CURR_SINK_SHFT + j)); |
26127 |
+ |
26128 |
+ /* Enable feedback control */ |
26129 |
+ rc = regmap_write(wled->regmap, wled->ctrl_addr + |
26130 |
+- WLED3_CTRL_REG_FEEDBACK_CONTROL, i + 1); |
26131 |
++ WLED3_CTRL_REG_FEEDBACK_CONTROL, j + 1); |
26132 |
+ if (rc < 0) { |
26133 |
+ dev_err(wled->dev, "Failed to enable feedback for SINK %d rc = %d\n", |
26134 |
+- i + 1, rc); |
26135 |
++ j + 1, rc); |
26136 |
+ goto failed_detect; |
26137 |
+ } |
26138 |
+ |
26139 |
+@@ -635,7 +635,7 @@ static void wled_auto_string_detection(struct wled *wled) |
26140 |
+ WLED4_SINK_REG_CURR_SINK, sink_test); |
26141 |
+ if (rc < 0) { |
26142 |
+ dev_err(wled->dev, "Failed to configure SINK %d rc=%d\n", |
26143 |
+- i + 1, rc); |
26144 |
++ j + 1, rc); |
26145 |
+ goto failed_detect; |
26146 |
+ } |
26147 |
+ |
26148 |
+@@ -662,7 +662,7 @@ static void wled_auto_string_detection(struct wled *wled) |
26149 |
+ |
26150 |
+ if (fault_set) |
26151 |
+ dev_dbg(wled->dev, "WLED OVP fault detected with SINK %d\n", |
26152 |
+- i + 1); |
26153 |
++ j + 1); |
26154 |
+ else |
26155 |
+ sink_valid |= sink_test; |
26156 |
+ |
26157 |
+@@ -702,15 +702,16 @@ static void wled_auto_string_detection(struct wled *wled) |
26158 |
+ /* Enable valid sinks */ |
26159 |
+ if (wled->version == 4) { |
26160 |
+ for (i = 0; i < wled->cfg.num_strings; i++) { |
26161 |
++ j = wled->cfg.enabled_strings[i]; |
26162 |
+ if (sink_config & |
26163 |
+- BIT(WLED4_SINK_REG_CURR_SINK_SHFT + i)) |
26164 |
++ BIT(WLED4_SINK_REG_CURR_SINK_SHFT + j)) |
26165 |
+ val = WLED4_SINK_REG_STR_MOD_MASK; |
26166 |
+ else |
26167 |
+ /* Disable modulator_en for unused sink */ |
26168 |
+ val = 0; |
26169 |
+ |
26170 |
+ rc = regmap_write(wled->regmap, wled->sink_addr + |
26171 |
+- WLED4_SINK_REG_STR_MOD_EN(i), val); |
26172 |
++ WLED4_SINK_REG_STR_MOD_EN(j), val); |
26173 |
+ if (rc < 0) { |
26174 |
+ dev_err(wled->dev, "Failed to configure MODULATOR_EN rc=%d\n", |
26175 |
+ rc); |
26176 |
+@@ -1256,21 +1257,6 @@ static const struct wled_var_cfg wled5_ovp_cfg = { |
26177 |
+ .size = 16, |
26178 |
+ }; |
26179 |
+ |
26180 |
+-static u32 wled3_num_strings_values_fn(u32 idx) |
26181 |
+-{ |
26182 |
+- return idx + 1; |
26183 |
+-} |
26184 |
+- |
26185 |
+-static const struct wled_var_cfg wled3_num_strings_cfg = { |
26186 |
+- .fn = wled3_num_strings_values_fn, |
26187 |
+- .size = 3, |
26188 |
+-}; |
26189 |
+- |
26190 |
+-static const struct wled_var_cfg wled4_num_strings_cfg = { |
26191 |
+- .fn = wled3_num_strings_values_fn, |
26192 |
+- .size = 4, |
26193 |
+-}; |
26194 |
+- |
26195 |
+ static u32 wled3_switch_freq_values_fn(u32 idx) |
26196 |
+ { |
26197 |
+ return 19200 / (2 * (1 + idx)); |
26198 |
+@@ -1344,11 +1330,6 @@ static int wled_configure(struct wled *wled) |
26199 |
+ .val_ptr = &cfg->switch_freq, |
26200 |
+ .cfg = &wled3_switch_freq_cfg, |
26201 |
+ }, |
26202 |
+- { |
26203 |
+- .name = "qcom,num-strings", |
26204 |
+- .val_ptr = &cfg->num_strings, |
26205 |
+- .cfg = &wled3_num_strings_cfg, |
26206 |
+- }, |
26207 |
+ }; |
26208 |
+ |
26209 |
+ const struct wled_u32_opts wled4_opts[] = { |
26210 |
+@@ -1372,11 +1353,6 @@ static int wled_configure(struct wled *wled) |
26211 |
+ .val_ptr = &cfg->switch_freq, |
26212 |
+ .cfg = &wled3_switch_freq_cfg, |
26213 |
+ }, |
26214 |
+- { |
26215 |
+- .name = "qcom,num-strings", |
26216 |
+- .val_ptr = &cfg->num_strings, |
26217 |
+- .cfg = &wled4_num_strings_cfg, |
26218 |
+- }, |
26219 |
+ }; |
26220 |
+ |
26221 |
+ const struct wled_u32_opts wled5_opts[] = { |
26222 |
+@@ -1400,11 +1376,6 @@ static int wled_configure(struct wled *wled) |
26223 |
+ .val_ptr = &cfg->switch_freq, |
26224 |
+ .cfg = &wled3_switch_freq_cfg, |
26225 |
+ }, |
26226 |
+- { |
26227 |
+- .name = "qcom,num-strings", |
26228 |
+- .val_ptr = &cfg->num_strings, |
26229 |
+- .cfg = &wled4_num_strings_cfg, |
26230 |
+- }, |
26231 |
+ { |
26232 |
+ .name = "qcom,modulator-sel", |
26233 |
+ .val_ptr = &cfg->mod_sel, |
26234 |
+@@ -1523,16 +1494,57 @@ static int wled_configure(struct wled *wled) |
26235 |
+ *bool_opts[i].val_ptr = true; |
26236 |
+ } |
26237 |
+ |
26238 |
+- cfg->num_strings = cfg->num_strings + 1; |
26239 |
+- |
26240 |
+ string_len = of_property_count_elems_of_size(dev->of_node, |
26241 |
+ "qcom,enabled-strings", |
26242 |
+ sizeof(u32)); |
26243 |
+- if (string_len > 0) |
26244 |
+- of_property_read_u32_array(dev->of_node, |
26245 |
++ if (string_len > 0) { |
26246 |
++ if (string_len > wled->max_string_count) { |
26247 |
++ dev_err(dev, "Cannot have more than %d strings\n", |
26248 |
++ wled->max_string_count); |
26249 |
++ return -EINVAL; |
26250 |
++ } |
26251 |
++ |
26252 |
++ rc = of_property_read_u32_array(dev->of_node, |
26253 |
+ "qcom,enabled-strings", |
26254 |
+ wled->cfg.enabled_strings, |
26255 |
+- sizeof(u32)); |
26256 |
++ string_len); |
26257 |
++ if (rc) { |
26258 |
++ dev_err(dev, "Failed to read %d elements from qcom,enabled-strings: %d\n", |
26259 |
++ string_len, rc); |
26260 |
++ return rc; |
26261 |
++ } |
26262 |
++ |
26263 |
++ for (i = 0; i < string_len; ++i) { |
26264 |
++ if (wled->cfg.enabled_strings[i] >= wled->max_string_count) { |
26265 |
++ dev_err(dev, |
26266 |
++ "qcom,enabled-strings index %d at %d is out of bounds\n", |
26267 |
++ wled->cfg.enabled_strings[i], i); |
26268 |
++ return -EINVAL; |
26269 |
++ } |
26270 |
++ } |
26271 |
++ |
26272 |
++ cfg->num_strings = string_len; |
26273 |
++ } |
26274 |
++ |
26275 |
++ rc = of_property_read_u32(dev->of_node, "qcom,num-strings", &val); |
26276 |
++ if (!rc) { |
26277 |
++ if (val < 1 || val > wled->max_string_count) { |
26278 |
++ dev_err(dev, "qcom,num-strings must be between 1 and %d\n", |
26279 |
++ wled->max_string_count); |
26280 |
++ return -EINVAL; |
26281 |
++ } |
26282 |
++ |
26283 |
++ if (string_len > 0) { |
26284 |
++ dev_warn(dev, "Only one of qcom,num-strings or qcom,enabled-strings" |
26285 |
++ " should be set\n"); |
26286 |
++ if (val > string_len) { |
26287 |
++ dev_err(dev, "qcom,num-strings exceeds qcom,enabled-strings\n"); |
26288 |
++ return -EINVAL; |
26289 |
++ } |
26290 |
++ } |
26291 |
++ |
26292 |
++ cfg->num_strings = val; |
26293 |
++ } |
26294 |
+ |
26295 |
+ return 0; |
26296 |
+ } |
26297 |
+diff --git a/drivers/virtio/virtio_mem.c b/drivers/virtio/virtio_mem.c |
26298 |
+index bef8ad6bf4661..4624a2c3d0553 100644 |
26299 |
+--- a/drivers/virtio/virtio_mem.c |
26300 |
++++ b/drivers/virtio/virtio_mem.c |
26301 |
+@@ -577,7 +577,7 @@ static int virtio_mem_sbm_sb_states_prepare_next_mb(struct virtio_mem *vm) |
26302 |
+ return -ENOMEM; |
26303 |
+ |
26304 |
+ mutex_lock(&vm->hotplug_mutex); |
26305 |
+- if (new_bitmap) |
26306 |
++ if (vm->sbm.sb_states) |
26307 |
+ memcpy(new_bitmap, vm->sbm.sb_states, old_pages * PAGE_SIZE); |
26308 |
+ |
26309 |
+ old_bitmap = vm->sbm.sb_states; |
26310 |
+diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c |
26311 |
+index 9919407973cd5..603a6f4345efd 100644 |
26312 |
+--- a/drivers/virtio/virtio_ring.c |
26313 |
++++ b/drivers/virtio/virtio_ring.c |
26314 |
+@@ -1197,8 +1197,10 @@ static inline int virtqueue_add_packed(struct virtqueue *_vq, |
26315 |
+ if (virtqueue_use_indirect(_vq, total_sg)) { |
26316 |
+ err = virtqueue_add_indirect_packed(vq, sgs, total_sg, out_sgs, |
26317 |
+ in_sgs, data, gfp); |
26318 |
+- if (err != -ENOMEM) |
26319 |
++ if (err != -ENOMEM) { |
26320 |
++ END_USE(vq); |
26321 |
+ return err; |
26322 |
++ } |
26323 |
+ |
26324 |
+ /* fall back on direct */ |
26325 |
+ } |
26326 |
+diff --git a/drivers/w1/slaves/w1_ds28e04.c b/drivers/w1/slaves/w1_ds28e04.c |
26327 |
+index e4f336111edc6..6cef6e2edb892 100644 |
26328 |
+--- a/drivers/w1/slaves/w1_ds28e04.c |
26329 |
++++ b/drivers/w1/slaves/w1_ds28e04.c |
26330 |
+@@ -32,7 +32,7 @@ static int w1_strong_pullup = 1; |
26331 |
+ module_param_named(strong_pullup, w1_strong_pullup, int, 0); |
26332 |
+ |
26333 |
+ /* enable/disable CRC checking on DS28E04-100 memory accesses */ |
26334 |
+-static char w1_enable_crccheck = 1; |
26335 |
++static bool w1_enable_crccheck = true; |
26336 |
+ |
26337 |
+ #define W1_EEPROM_SIZE 512 |
26338 |
+ #define W1_PAGE_COUNT 16 |
26339 |
+@@ -339,32 +339,18 @@ static BIN_ATTR_RW(pio, 1); |
26340 |
+ static ssize_t crccheck_show(struct device *dev, struct device_attribute *attr, |
26341 |
+ char *buf) |
26342 |
+ { |
26343 |
+- if (put_user(w1_enable_crccheck + 0x30, buf)) |
26344 |
+- return -EFAULT; |
26345 |
+- |
26346 |
+- return sizeof(w1_enable_crccheck); |
26347 |
++ return sysfs_emit(buf, "%d\n", w1_enable_crccheck); |
26348 |
+ } |
26349 |
+ |
26350 |
+ static ssize_t crccheck_store(struct device *dev, struct device_attribute *attr, |
26351 |
+ const char *buf, size_t count) |
26352 |
+ { |
26353 |
+- char val; |
26354 |
+- |
26355 |
+- if (count != 1 || !buf) |
26356 |
+- return -EINVAL; |
26357 |
++ int err = kstrtobool(buf, &w1_enable_crccheck); |
26358 |
+ |
26359 |
+- if (get_user(val, buf)) |
26360 |
+- return -EFAULT; |
26361 |
++ if (err) |
26362 |
++ return err; |
26363 |
+ |
26364 |
+- /* convert to decimal */ |
26365 |
+- val = val - 0x30; |
26366 |
+- if (val != 0 && val != 1) |
26367 |
+- return -EINVAL; |
26368 |
+- |
26369 |
+- /* set the new value */ |
26370 |
+- w1_enable_crccheck = val; |
26371 |
+- |
26372 |
+- return sizeof(w1_enable_crccheck); |
26373 |
++ return count; |
26374 |
+ } |
26375 |
+ |
26376 |
+ static DEVICE_ATTR_RW(crccheck); |
26377 |
+diff --git a/drivers/xen/gntdev.c b/drivers/xen/gntdev.c |
26378 |
+index fec1b65371665..59ffea8000791 100644 |
26379 |
+--- a/drivers/xen/gntdev.c |
26380 |
++++ b/drivers/xen/gntdev.c |
26381 |
+@@ -250,13 +250,13 @@ void gntdev_put_map(struct gntdev_priv *priv, struct gntdev_grant_map *map) |
26382 |
+ if (!refcount_dec_and_test(&map->users)) |
26383 |
+ return; |
26384 |
+ |
26385 |
++ if (map->pages && !use_ptemod) |
26386 |
++ unmap_grant_pages(map, 0, map->count); |
26387 |
++ |
26388 |
+ if (map->notify.flags & UNMAP_NOTIFY_SEND_EVENT) { |
26389 |
+ notify_remote_via_evtchn(map->notify.event); |
26390 |
+ evtchn_put(map->notify.event); |
26391 |
+ } |
26392 |
+- |
26393 |
+- if (map->pages && !use_ptemod) |
26394 |
+- unmap_grant_pages(map, 0, map->count); |
26395 |
+ gntdev_free_map(map); |
26396 |
+ } |
26397 |
+ |
26398 |
+diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c |
26399 |
+index f735b8798ba12..8b090c40daf77 100644 |
26400 |
+--- a/fs/btrfs/backref.c |
26401 |
++++ b/fs/btrfs/backref.c |
26402 |
+@@ -1214,7 +1214,12 @@ again: |
26403 |
+ ret = btrfs_search_slot(NULL, fs_info->extent_root, &key, path, 0, 0); |
26404 |
+ if (ret < 0) |
26405 |
+ goto out; |
26406 |
+- BUG_ON(ret == 0); |
26407 |
++ if (ret == 0) { |
26408 |
++ /* This shouldn't happen, indicates a bug or fs corruption. */ |
26409 |
++ ASSERT(ret != 0); |
26410 |
++ ret = -EUCLEAN; |
26411 |
++ goto out; |
26412 |
++ } |
26413 |
+ |
26414 |
+ #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS |
26415 |
+ if (trans && likely(trans->type != __TRANS_DUMMY) && |
26416 |
+@@ -1360,10 +1365,18 @@ again: |
26417 |
+ goto out; |
26418 |
+ if (!ret && extent_item_pos) { |
26419 |
+ /* |
26420 |
+- * we've recorded that parent, so we must extend |
26421 |
+- * its inode list here |
26422 |
++ * We've recorded that parent, so we must extend |
26423 |
++ * its inode list here. |
26424 |
++ * |
26425 |
++ * However if there was corruption we may not |
26426 |
++ * have found an eie, return an error in this |
26427 |
++ * case. |
26428 |
+ */ |
26429 |
+- BUG_ON(!eie); |
26430 |
++ ASSERT(eie); |
26431 |
++ if (!eie) { |
26432 |
++ ret = -EUCLEAN; |
26433 |
++ goto out; |
26434 |
++ } |
26435 |
+ while (eie->next) |
26436 |
+ eie = eie->next; |
26437 |
+ eie->next = ref->inode_list; |
26438 |
+diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c |
26439 |
+index 84627cbd5b5b5..95a6a63caf047 100644 |
26440 |
+--- a/fs/btrfs/ctree.c |
26441 |
++++ b/fs/btrfs/ctree.c |
26442 |
+@@ -1568,12 +1568,9 @@ static struct extent_buffer *btrfs_search_slot_get_root(struct btrfs_root *root, |
26443 |
+ { |
26444 |
+ struct btrfs_fs_info *fs_info = root->fs_info; |
26445 |
+ struct extent_buffer *b; |
26446 |
+- int root_lock; |
26447 |
++ int root_lock = 0; |
26448 |
+ int level = 0; |
26449 |
+ |
26450 |
+- /* We try very hard to do read locks on the root */ |
26451 |
+- root_lock = BTRFS_READ_LOCK; |
26452 |
+- |
26453 |
+ if (p->search_commit_root) { |
26454 |
+ /* |
26455 |
+ * The commit roots are read only so we always do read locks, |
26456 |
+@@ -1611,6 +1608,9 @@ static struct extent_buffer *btrfs_search_slot_get_root(struct btrfs_root *root, |
26457 |
+ goto out; |
26458 |
+ } |
26459 |
+ |
26460 |
++ /* We try very hard to do read locks on the root */ |
26461 |
++ root_lock = BTRFS_READ_LOCK; |
26462 |
++ |
26463 |
+ /* |
26464 |
+ * If the level is set to maximum, we can skip trying to get the read |
26465 |
+ * lock. |
26466 |
+@@ -1637,6 +1637,17 @@ static struct extent_buffer *btrfs_search_slot_get_root(struct btrfs_root *root, |
26467 |
+ level = btrfs_header_level(b); |
26468 |
+ |
26469 |
+ out: |
26470 |
++ /* |
26471 |
++ * The root may have failed to write out at some point, and thus is no |
26472 |
++ * longer valid, return an error in this case. |
26473 |
++ */ |
26474 |
++ if (!extent_buffer_uptodate(b)) { |
26475 |
++ if (root_lock) |
26476 |
++ btrfs_tree_unlock_rw(b, root_lock); |
26477 |
++ free_extent_buffer(b); |
26478 |
++ return ERR_PTR(-EIO); |
26479 |
++ } |
26480 |
++ |
26481 |
+ p->nodes[level] = b; |
26482 |
+ if (!p->skip_locking) |
26483 |
+ p->locks[level] = root_lock; |
26484 |
+diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c |
26485 |
+index 4af74b62e7d97..e92f0b0afe9ec 100644 |
26486 |
+--- a/fs/btrfs/inode.c |
26487 |
++++ b/fs/btrfs/inode.c |
26488 |
+@@ -10586,9 +10586,19 @@ static int btrfs_add_swap_extent(struct swap_info_struct *sis, |
26489 |
+ struct btrfs_swap_info *bsi) |
26490 |
+ { |
26491 |
+ unsigned long nr_pages; |
26492 |
++ unsigned long max_pages; |
26493 |
+ u64 first_ppage, first_ppage_reported, next_ppage; |
26494 |
+ int ret; |
26495 |
+ |
26496 |
++ /* |
26497 |
++ * Our swapfile may have had its size extended after the swap header was |
26498 |
++ * written. In that case activating the swapfile should not go beyond |
26499 |
++ * the max size set in the swap header. |
26500 |
++ */ |
26501 |
++ if (bsi->nr_pages >= sis->max) |
26502 |
++ return 0; |
26503 |
++ |
26504 |
++ max_pages = sis->max - bsi->nr_pages; |
26505 |
+ first_ppage = ALIGN(bsi->block_start, PAGE_SIZE) >> PAGE_SHIFT; |
26506 |
+ next_ppage = ALIGN_DOWN(bsi->block_start + bsi->block_len, |
26507 |
+ PAGE_SIZE) >> PAGE_SHIFT; |
26508 |
+@@ -10596,6 +10606,7 @@ static int btrfs_add_swap_extent(struct swap_info_struct *sis, |
26509 |
+ if (first_ppage >= next_ppage) |
26510 |
+ return 0; |
26511 |
+ nr_pages = next_ppage - first_ppage; |
26512 |
++ nr_pages = min(nr_pages, max_pages); |
26513 |
+ |
26514 |
+ first_ppage_reported = first_ppage; |
26515 |
+ if (bsi->start == 0) |
26516 |
+diff --git a/fs/btrfs/qgroup.c b/fs/btrfs/qgroup.c |
26517 |
+index db680f5be745a..7f6a05e670f57 100644 |
26518 |
+--- a/fs/btrfs/qgroup.c |
26519 |
++++ b/fs/btrfs/qgroup.c |
26520 |
+@@ -940,6 +940,14 @@ int btrfs_quota_enable(struct btrfs_fs_info *fs_info) |
26521 |
+ int ret = 0; |
26522 |
+ int slot; |
26523 |
+ |
26524 |
++ /* |
26525 |
++ * We need to have subvol_sem write locked, to prevent races between |
26526 |
++ * concurrent tasks trying to enable quotas, because we will unlock |
26527 |
++ * and relock qgroup_ioctl_lock before setting fs_info->quota_root |
26528 |
++ * and before setting BTRFS_FS_QUOTA_ENABLED. |
26529 |
++ */ |
26530 |
++ lockdep_assert_held_write(&fs_info->subvol_sem); |
26531 |
++ |
26532 |
+ mutex_lock(&fs_info->qgroup_ioctl_lock); |
26533 |
+ if (fs_info->quota_root) |
26534 |
+ goto out; |
26535 |
+@@ -1117,8 +1125,19 @@ out_add_root: |
26536 |
+ goto out_free_path; |
26537 |
+ } |
26538 |
+ |
26539 |
++ mutex_unlock(&fs_info->qgroup_ioctl_lock); |
26540 |
++ /* |
26541 |
++ * Commit the transaction while not holding qgroup_ioctl_lock, to avoid |
26542 |
++ * a deadlock with tasks concurrently doing other qgroup operations, such |
26543 |
++ * adding/removing qgroups or adding/deleting qgroup relations for example, |
26544 |
++ * because all qgroup operations first start or join a transaction and then |
26545 |
++ * lock the qgroup_ioctl_lock mutex. |
26546 |
++ * We are safe from a concurrent task trying to enable quotas, by calling |
26547 |
++ * this function, since we are serialized by fs_info->subvol_sem. |
26548 |
++ */ |
26549 |
+ ret = btrfs_commit_transaction(trans); |
26550 |
+ trans = NULL; |
26551 |
++ mutex_lock(&fs_info->qgroup_ioctl_lock); |
26552 |
+ if (ret) |
26553 |
+ goto out_free_path; |
26554 |
+ |
26555 |
+diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c |
26556 |
+index 7d162b0efbf03..950c63fa4d0b2 100644 |
26557 |
+--- a/fs/debugfs/file.c |
26558 |
++++ b/fs/debugfs/file.c |
26559 |
+@@ -147,7 +147,7 @@ static int debugfs_locked_down(struct inode *inode, |
26560 |
+ struct file *filp, |
26561 |
+ const struct file_operations *real_fops) |
26562 |
+ { |
26563 |
+- if ((inode->i_mode & 07777) == 0444 && |
26564 |
++ if ((inode->i_mode & 07777 & ~0444) == 0 && |
26565 |
+ !(filp->f_mode & FMODE_WRITE) && |
26566 |
+ !real_fops->unlocked_ioctl && |
26567 |
+ !real_fops->compat_ioctl && |
26568 |
+diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c |
26569 |
+index c502c065d0075..28d1f35b11a4d 100644 |
26570 |
+--- a/fs/dlm/lock.c |
26571 |
++++ b/fs/dlm/lock.c |
26572 |
+@@ -3973,6 +3973,14 @@ static int validate_message(struct dlm_lkb *lkb, struct dlm_message *ms) |
26573 |
+ int from = ms->m_header.h_nodeid; |
26574 |
+ int error = 0; |
26575 |
+ |
26576 |
++ /* currently mixing of user/kernel locks are not supported */ |
26577 |
++ if (ms->m_flags & DLM_IFL_USER && ~lkb->lkb_flags & DLM_IFL_USER) { |
26578 |
++ log_error(lkb->lkb_resource->res_ls, |
26579 |
++ "got user dlm message for a kernel lock"); |
26580 |
++ error = -EINVAL; |
26581 |
++ goto out; |
26582 |
++ } |
26583 |
++ |
26584 |
+ switch (ms->m_type) { |
26585 |
+ case DLM_MSG_CONVERT: |
26586 |
+ case DLM_MSG_UNLOCK: |
26587 |
+@@ -4001,6 +4009,7 @@ static int validate_message(struct dlm_lkb *lkb, struct dlm_message *ms) |
26588 |
+ error = -EINVAL; |
26589 |
+ } |
26590 |
+ |
26591 |
++out: |
26592 |
+ if (error) |
26593 |
+ log_error(lkb->lkb_resource->res_ls, |
26594 |
+ "ignore invalid message %d from %d %x %x %x %d", |
26595 |
+diff --git a/fs/dlm/lowcomms.c b/fs/dlm/lowcomms.c |
26596 |
+index 8f715c620e1f8..7a8efce1c343e 100644 |
26597 |
+--- a/fs/dlm/lowcomms.c |
26598 |
++++ b/fs/dlm/lowcomms.c |
26599 |
+@@ -592,8 +592,8 @@ int dlm_lowcomms_nodes_set_mark(int nodeid, unsigned int mark) |
26600 |
+ static void lowcomms_error_report(struct sock *sk) |
26601 |
+ { |
26602 |
+ struct connection *con; |
26603 |
+- struct sockaddr_storage saddr; |
26604 |
+ void (*orig_report)(struct sock *) = NULL; |
26605 |
++ struct inet_sock *inet; |
26606 |
+ |
26607 |
+ read_lock_bh(&sk->sk_callback_lock); |
26608 |
+ con = sock2con(sk); |
26609 |
+@@ -601,33 +601,33 @@ static void lowcomms_error_report(struct sock *sk) |
26610 |
+ goto out; |
26611 |
+ |
26612 |
+ orig_report = listen_sock.sk_error_report; |
26613 |
+- if (kernel_getpeername(sk->sk_socket, (struct sockaddr *)&saddr) < 0) { |
26614 |
+- printk_ratelimited(KERN_ERR "dlm: node %d: socket error " |
26615 |
+- "sending to node %d, port %d, " |
26616 |
+- "sk_err=%d/%d\n", dlm_our_nodeid(), |
26617 |
+- con->nodeid, dlm_config.ci_tcp_port, |
26618 |
+- sk->sk_err, sk->sk_err_soft); |
26619 |
+- } else if (saddr.ss_family == AF_INET) { |
26620 |
+- struct sockaddr_in *sin4 = (struct sockaddr_in *)&saddr; |
26621 |
+ |
26622 |
++ inet = inet_sk(sk); |
26623 |
++ switch (sk->sk_family) { |
26624 |
++ case AF_INET: |
26625 |
+ printk_ratelimited(KERN_ERR "dlm: node %d: socket error " |
26626 |
+- "sending to node %d at %pI4, port %d, " |
26627 |
++ "sending to node %d at %pI4, dport %d, " |
26628 |
+ "sk_err=%d/%d\n", dlm_our_nodeid(), |
26629 |
+- con->nodeid, &sin4->sin_addr.s_addr, |
26630 |
+- dlm_config.ci_tcp_port, sk->sk_err, |
26631 |
++ con->nodeid, &inet->inet_daddr, |
26632 |
++ ntohs(inet->inet_dport), sk->sk_err, |
26633 |
+ sk->sk_err_soft); |
26634 |
+- } else { |
26635 |
+- struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&saddr; |
26636 |
+- |
26637 |
++ break; |
26638 |
++#if IS_ENABLED(CONFIG_IPV6) |
26639 |
++ case AF_INET6: |
26640 |
+ printk_ratelimited(KERN_ERR "dlm: node %d: socket error " |
26641 |
+- "sending to node %d at %u.%u.%u.%u, " |
26642 |
+- "port %d, sk_err=%d/%d\n", dlm_our_nodeid(), |
26643 |
+- con->nodeid, sin6->sin6_addr.s6_addr32[0], |
26644 |
+- sin6->sin6_addr.s6_addr32[1], |
26645 |
+- sin6->sin6_addr.s6_addr32[2], |
26646 |
+- sin6->sin6_addr.s6_addr32[3], |
26647 |
+- dlm_config.ci_tcp_port, sk->sk_err, |
26648 |
++ "sending to node %d at %pI6c, " |
26649 |
++ "dport %d, sk_err=%d/%d\n", dlm_our_nodeid(), |
26650 |
++ con->nodeid, &sk->sk_v6_daddr, |
26651 |
++ ntohs(inet->inet_dport), sk->sk_err, |
26652 |
+ sk->sk_err_soft); |
26653 |
++ break; |
26654 |
++#endif |
26655 |
++ default: |
26656 |
++ printk_ratelimited(KERN_ERR "dlm: node %d: socket error " |
26657 |
++ "invalid socket family %d set, " |
26658 |
++ "sk_err=%d/%d\n", dlm_our_nodeid(), |
26659 |
++ sk->sk_family, sk->sk_err, sk->sk_err_soft); |
26660 |
++ goto out; |
26661 |
+ } |
26662 |
+ |
26663 |
+ /* below sendcon only handling */ |
26664 |
+diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h |
26665 |
+index 3825195539d74..c97860ef322db 100644 |
26666 |
+--- a/fs/ext4/ext4.h |
26667 |
++++ b/fs/ext4/ext4.h |
26668 |
+@@ -2934,6 +2934,7 @@ bool ext4_fc_replay_check_excluded(struct super_block *sb, ext4_fsblk_t block); |
26669 |
+ void ext4_fc_replay_cleanup(struct super_block *sb); |
26670 |
+ int ext4_fc_commit(journal_t *journal, tid_t commit_tid); |
26671 |
+ int __init ext4_fc_init_dentry_cache(void); |
26672 |
++void ext4_fc_destroy_dentry_cache(void); |
26673 |
+ |
26674 |
+ /* mballoc.c */ |
26675 |
+ extern const struct seq_operations ext4_mb_seq_groups_ops; |
26676 |
+diff --git a/fs/ext4/ext4_jbd2.c b/fs/ext4/ext4_jbd2.c |
26677 |
+index 6def7339056db..3477a16d08aee 100644 |
26678 |
+--- a/fs/ext4/ext4_jbd2.c |
26679 |
++++ b/fs/ext4/ext4_jbd2.c |
26680 |
+@@ -162,6 +162,8 @@ int __ext4_journal_ensure_credits(handle_t *handle, int check_cred, |
26681 |
+ { |
26682 |
+ if (!ext4_handle_valid(handle)) |
26683 |
+ return 0; |
26684 |
++ if (is_handle_aborted(handle)) |
26685 |
++ return -EROFS; |
26686 |
+ if (jbd2_handle_buffer_credits(handle) >= check_cred && |
26687 |
+ handle->h_revoke_credits >= revoke_cred) |
26688 |
+ return 0; |
26689 |
+diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c |
26690 |
+index daa83525749b3..f9bd3231a1415 100644 |
26691 |
+--- a/fs/ext4/extents.c |
26692 |
++++ b/fs/ext4/extents.c |
26693 |
+@@ -4645,8 +4645,6 @@ static long ext4_zero_range(struct file *file, loff_t offset, |
26694 |
+ ret = ext4_mark_inode_dirty(handle, inode); |
26695 |
+ if (unlikely(ret)) |
26696 |
+ goto out_handle; |
26697 |
+- ext4_fc_track_range(handle, inode, offset >> inode->i_sb->s_blocksize_bits, |
26698 |
+- (offset + len - 1) >> inode->i_sb->s_blocksize_bits); |
26699 |
+ /* Zero out partial block at the edges of the range */ |
26700 |
+ ret = ext4_zero_partial_blocks(handle, inode, offset, len); |
26701 |
+ if (ret >= 0) |
26702 |
+diff --git a/fs/ext4/fast_commit.c b/fs/ext4/fast_commit.c |
26703 |
+index 8ea5a81e65548..e0d393425caca 100644 |
26704 |
+--- a/fs/ext4/fast_commit.c |
26705 |
++++ b/fs/ext4/fast_commit.c |
26706 |
+@@ -1809,11 +1809,14 @@ ext4_fc_replay_del_range(struct super_block *sb, struct ext4_fc_tl *tl, |
26707 |
+ } |
26708 |
+ } |
26709 |
+ |
26710 |
+- ret = ext4_punch_hole(inode, |
26711 |
+- le32_to_cpu(lrange.fc_lblk) << sb->s_blocksize_bits, |
26712 |
+- le32_to_cpu(lrange.fc_len) << sb->s_blocksize_bits); |
26713 |
+- if (ret) |
26714 |
+- jbd_debug(1, "ext4_punch_hole returned %d", ret); |
26715 |
++ down_write(&EXT4_I(inode)->i_data_sem); |
26716 |
++ ret = ext4_ext_remove_space(inode, lrange.fc_lblk, |
26717 |
++ lrange.fc_lblk + lrange.fc_len - 1); |
26718 |
++ up_write(&EXT4_I(inode)->i_data_sem); |
26719 |
++ if (ret) { |
26720 |
++ iput(inode); |
26721 |
++ return 0; |
26722 |
++ } |
26723 |
+ ext4_ext_replay_shrink_inode(inode, |
26724 |
+ i_size_read(inode) >> sb->s_blocksize_bits); |
26725 |
+ ext4_mark_inode_dirty(NULL, inode); |
26726 |
+@@ -2185,3 +2188,8 @@ int __init ext4_fc_init_dentry_cache(void) |
26727 |
+ |
26728 |
+ return 0; |
26729 |
+ } |
26730 |
++ |
26731 |
++void ext4_fc_destroy_dentry_cache(void) |
26732 |
++{ |
26733 |
++ kmem_cache_destroy(ext4_fc_dentry_cachep); |
26734 |
++} |
26735 |
+diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c |
26736 |
+index 9097fccdc6889..b6746cc86cee3 100644 |
26737 |
+--- a/fs/ext4/inode.c |
26738 |
++++ b/fs/ext4/inode.c |
26739 |
+@@ -741,10 +741,11 @@ out_sem: |
26740 |
+ if (ret) |
26741 |
+ return ret; |
26742 |
+ } |
26743 |
+- ext4_fc_track_range(handle, inode, map->m_lblk, |
26744 |
+- map->m_lblk + map->m_len - 1); |
26745 |
+ } |
26746 |
+- |
26747 |
++ if (retval > 0 && (map->m_flags & EXT4_MAP_UNWRITTEN || |
26748 |
++ map->m_flags & EXT4_MAP_MAPPED)) |
26749 |
++ ext4_fc_track_range(handle, inode, map->m_lblk, |
26750 |
++ map->m_lblk + map->m_len - 1); |
26751 |
+ if (retval < 0) |
26752 |
+ ext_debug(inode, "failed with err %d\n", retval); |
26753 |
+ return retval; |
26754 |
+@@ -1844,30 +1845,16 @@ int ext4_da_get_block_prep(struct inode *inode, sector_t iblock, |
26755 |
+ return 0; |
26756 |
+ } |
26757 |
+ |
26758 |
+-static int bget_one(handle_t *handle, struct inode *inode, |
26759 |
+- struct buffer_head *bh) |
26760 |
+-{ |
26761 |
+- get_bh(bh); |
26762 |
+- return 0; |
26763 |
+-} |
26764 |
+- |
26765 |
+-static int bput_one(handle_t *handle, struct inode *inode, |
26766 |
+- struct buffer_head *bh) |
26767 |
+-{ |
26768 |
+- put_bh(bh); |
26769 |
+- return 0; |
26770 |
+-} |
26771 |
+- |
26772 |
+ static int __ext4_journalled_writepage(struct page *page, |
26773 |
+ unsigned int len) |
26774 |
+ { |
26775 |
+ struct address_space *mapping = page->mapping; |
26776 |
+ struct inode *inode = mapping->host; |
26777 |
+- struct buffer_head *page_bufs = NULL; |
26778 |
+ handle_t *handle = NULL; |
26779 |
+ int ret = 0, err = 0; |
26780 |
+ int inline_data = ext4_has_inline_data(inode); |
26781 |
+ struct buffer_head *inode_bh = NULL; |
26782 |
++ loff_t size; |
26783 |
+ |
26784 |
+ ClearPageChecked(page); |
26785 |
+ |
26786 |
+@@ -1877,14 +1864,6 @@ static int __ext4_journalled_writepage(struct page *page, |
26787 |
+ inode_bh = ext4_journalled_write_inline_data(inode, len, page); |
26788 |
+ if (inode_bh == NULL) |
26789 |
+ goto out; |
26790 |
+- } else { |
26791 |
+- page_bufs = page_buffers(page); |
26792 |
+- if (!page_bufs) { |
26793 |
+- BUG(); |
26794 |
+- goto out; |
26795 |
+- } |
26796 |
+- ext4_walk_page_buffers(handle, inode, page_bufs, 0, len, |
26797 |
+- NULL, bget_one); |
26798 |
+ } |
26799 |
+ /* |
26800 |
+ * We need to release the page lock before we start the |
26801 |
+@@ -1905,7 +1884,8 @@ static int __ext4_journalled_writepage(struct page *page, |
26802 |
+ |
26803 |
+ lock_page(page); |
26804 |
+ put_page(page); |
26805 |
+- if (page->mapping != mapping) { |
26806 |
++ size = i_size_read(inode); |
26807 |
++ if (page->mapping != mapping || page_offset(page) > size) { |
26808 |
+ /* The page got truncated from under us */ |
26809 |
+ ext4_journal_stop(handle); |
26810 |
+ ret = 0; |
26811 |
+@@ -1915,6 +1895,13 @@ static int __ext4_journalled_writepage(struct page *page, |
26812 |
+ if (inline_data) { |
26813 |
+ ret = ext4_mark_inode_dirty(handle, inode); |
26814 |
+ } else { |
26815 |
++ struct buffer_head *page_bufs = page_buffers(page); |
26816 |
++ |
26817 |
++ if (page->index == size >> PAGE_SHIFT) |
26818 |
++ len = size & ~PAGE_MASK; |
26819 |
++ else |
26820 |
++ len = PAGE_SIZE; |
26821 |
++ |
26822 |
+ ret = ext4_walk_page_buffers(handle, inode, page_bufs, 0, len, |
26823 |
+ NULL, do_journal_get_write_access); |
26824 |
+ |
26825 |
+@@ -1935,9 +1922,6 @@ static int __ext4_journalled_writepage(struct page *page, |
26826 |
+ out: |
26827 |
+ unlock_page(page); |
26828 |
+ out_no_pagelock: |
26829 |
+- if (!inline_data && page_bufs) |
26830 |
+- ext4_walk_page_buffers(NULL, inode, page_bufs, 0, len, |
26831 |
+- NULL, bput_one); |
26832 |
+ brelse(inode_bh); |
26833 |
+ return ret; |
26834 |
+ } |
26835 |
+@@ -4371,7 +4355,7 @@ has_buffer: |
26836 |
+ static int __ext4_get_inode_loc_noinmem(struct inode *inode, |
26837 |
+ struct ext4_iloc *iloc) |
26838 |
+ { |
26839 |
+- ext4_fsblk_t err_blk; |
26840 |
++ ext4_fsblk_t err_blk = 0; |
26841 |
+ int ret; |
26842 |
+ |
26843 |
+ ret = __ext4_get_inode_loc(inode->i_sb, inode->i_ino, iloc, 0, |
26844 |
+@@ -4386,7 +4370,7 @@ static int __ext4_get_inode_loc_noinmem(struct inode *inode, |
26845 |
+ |
26846 |
+ int ext4_get_inode_loc(struct inode *inode, struct ext4_iloc *iloc) |
26847 |
+ { |
26848 |
+- ext4_fsblk_t err_blk; |
26849 |
++ ext4_fsblk_t err_blk = 0; |
26850 |
+ int ret; |
26851 |
+ |
26852 |
+ /* We have all inode data except xattrs in memory here. */ |
26853 |
+@@ -5413,8 +5397,7 @@ int ext4_setattr(struct user_namespace *mnt_userns, struct dentry *dentry, |
26854 |
+ ext4_fc_track_range(handle, inode, |
26855 |
+ (attr->ia_size > 0 ? attr->ia_size - 1 : 0) >> |
26856 |
+ inode->i_sb->s_blocksize_bits, |
26857 |
+- (oldsize > 0 ? oldsize - 1 : 0) >> |
26858 |
+- inode->i_sb->s_blocksize_bits); |
26859 |
++ EXT_MAX_BLOCKS - 1); |
26860 |
+ else |
26861 |
+ ext4_fc_track_range( |
26862 |
+ handle, inode, |
26863 |
+diff --git a/fs/ext4/ioctl.c b/fs/ext4/ioctl.c |
26864 |
+index 606dee9e08a32..220a4c8178b5e 100644 |
26865 |
+--- a/fs/ext4/ioctl.c |
26866 |
++++ b/fs/ext4/ioctl.c |
26867 |
+@@ -1117,8 +1117,6 @@ resizefs_out: |
26868 |
+ sizeof(range))) |
26869 |
+ return -EFAULT; |
26870 |
+ |
26871 |
+- range.minlen = max((unsigned int)range.minlen, |
26872 |
+- q->limits.discard_granularity); |
26873 |
+ ret = ext4_trim_fs(sb, &range); |
26874 |
+ if (ret < 0) |
26875 |
+ return ret; |
26876 |
+diff --git a/fs/ext4/mballoc.c b/fs/ext4/mballoc.c |
26877 |
+index 72bfac2d6dce9..b05a83be88715 100644 |
26878 |
+--- a/fs/ext4/mballoc.c |
26879 |
++++ b/fs/ext4/mballoc.c |
26880 |
+@@ -4814,7 +4814,7 @@ ext4_mb_release_group_pa(struct ext4_buddy *e4b, |
26881 |
+ */ |
26882 |
+ static noinline_for_stack int |
26883 |
+ ext4_mb_discard_group_preallocations(struct super_block *sb, |
26884 |
+- ext4_group_t group, int needed) |
26885 |
++ ext4_group_t group, int *busy) |
26886 |
+ { |
26887 |
+ struct ext4_group_info *grp = ext4_get_group_info(sb, group); |
26888 |
+ struct buffer_head *bitmap_bh = NULL; |
26889 |
+@@ -4822,8 +4822,7 @@ ext4_mb_discard_group_preallocations(struct super_block *sb, |
26890 |
+ struct list_head list; |
26891 |
+ struct ext4_buddy e4b; |
26892 |
+ int err; |
26893 |
+- int busy = 0; |
26894 |
+- int free, free_total = 0; |
26895 |
++ int free = 0; |
26896 |
+ |
26897 |
+ mb_debug(sb, "discard preallocation for group %u\n", group); |
26898 |
+ if (list_empty(&grp->bb_prealloc_list)) |
26899 |
+@@ -4846,19 +4845,14 @@ ext4_mb_discard_group_preallocations(struct super_block *sb, |
26900 |
+ goto out_dbg; |
26901 |
+ } |
26902 |
+ |
26903 |
+- if (needed == 0) |
26904 |
+- needed = EXT4_CLUSTERS_PER_GROUP(sb) + 1; |
26905 |
+- |
26906 |
+ INIT_LIST_HEAD(&list); |
26907 |
+-repeat: |
26908 |
+- free = 0; |
26909 |
+ ext4_lock_group(sb, group); |
26910 |
+ list_for_each_entry_safe(pa, tmp, |
26911 |
+ &grp->bb_prealloc_list, pa_group_list) { |
26912 |
+ spin_lock(&pa->pa_lock); |
26913 |
+ if (atomic_read(&pa->pa_count)) { |
26914 |
+ spin_unlock(&pa->pa_lock); |
26915 |
+- busy = 1; |
26916 |
++ *busy = 1; |
26917 |
+ continue; |
26918 |
+ } |
26919 |
+ if (pa->pa_deleted) { |
26920 |
+@@ -4898,22 +4892,13 @@ repeat: |
26921 |
+ call_rcu(&(pa)->u.pa_rcu, ext4_mb_pa_callback); |
26922 |
+ } |
26923 |
+ |
26924 |
+- free_total += free; |
26925 |
+- |
26926 |
+- /* if we still need more blocks and some PAs were used, try again */ |
26927 |
+- if (free_total < needed && busy) { |
26928 |
+- ext4_unlock_group(sb, group); |
26929 |
+- cond_resched(); |
26930 |
+- busy = 0; |
26931 |
+- goto repeat; |
26932 |
+- } |
26933 |
+ ext4_unlock_group(sb, group); |
26934 |
+ ext4_mb_unload_buddy(&e4b); |
26935 |
+ put_bh(bitmap_bh); |
26936 |
+ out_dbg: |
26937 |
+ mb_debug(sb, "discarded (%d) blocks preallocated for group %u bb_free (%d)\n", |
26938 |
+- free_total, group, grp->bb_free); |
26939 |
+- return free_total; |
26940 |
++ free, group, grp->bb_free); |
26941 |
++ return free; |
26942 |
+ } |
26943 |
+ |
26944 |
+ /* |
26945 |
+@@ -5455,13 +5440,24 @@ static int ext4_mb_discard_preallocations(struct super_block *sb, int needed) |
26946 |
+ { |
26947 |
+ ext4_group_t i, ngroups = ext4_get_groups_count(sb); |
26948 |
+ int ret; |
26949 |
+- int freed = 0; |
26950 |
++ int freed = 0, busy = 0; |
26951 |
++ int retry = 0; |
26952 |
+ |
26953 |
+ trace_ext4_mb_discard_preallocations(sb, needed); |
26954 |
++ |
26955 |
++ if (needed == 0) |
26956 |
++ needed = EXT4_CLUSTERS_PER_GROUP(sb) + 1; |
26957 |
++ repeat: |
26958 |
+ for (i = 0; i < ngroups && needed > 0; i++) { |
26959 |
+- ret = ext4_mb_discard_group_preallocations(sb, i, needed); |
26960 |
++ ret = ext4_mb_discard_group_preallocations(sb, i, &busy); |
26961 |
+ freed += ret; |
26962 |
+ needed -= ret; |
26963 |
++ cond_resched(); |
26964 |
++ } |
26965 |
++ |
26966 |
++ if (needed > 0 && busy && ++retry < 3) { |
26967 |
++ busy = 0; |
26968 |
++ goto repeat; |
26969 |
+ } |
26970 |
+ |
26971 |
+ return freed; |
26972 |
+@@ -6405,6 +6401,7 @@ ext4_trim_all_free(struct super_block *sb, ext4_group_t group, |
26973 |
+ */ |
26974 |
+ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) |
26975 |
+ { |
26976 |
++ struct request_queue *q = bdev_get_queue(sb->s_bdev); |
26977 |
+ struct ext4_group_info *grp; |
26978 |
+ ext4_group_t group, first_group, last_group; |
26979 |
+ ext4_grpblk_t cnt = 0, first_cluster, last_cluster; |
26980 |
+@@ -6423,6 +6420,13 @@ int ext4_trim_fs(struct super_block *sb, struct fstrim_range *range) |
26981 |
+ start >= max_blks || |
26982 |
+ range->len < sb->s_blocksize) |
26983 |
+ return -EINVAL; |
26984 |
++ /* No point to try to trim less than discard granularity */ |
26985 |
++ if (range->minlen < q->limits.discard_granularity) { |
26986 |
++ minlen = EXT4_NUM_B2C(EXT4_SB(sb), |
26987 |
++ q->limits.discard_granularity >> sb->s_blocksize_bits); |
26988 |
++ if (minlen > EXT4_CLUSTERS_PER_GROUP(sb)) |
26989 |
++ goto out; |
26990 |
++ } |
26991 |
+ if (end >= max_blks) |
26992 |
+ end = max_blks - 1; |
26993 |
+ if (end <= first_data_blk) |
26994 |
+diff --git a/fs/ext4/migrate.c b/fs/ext4/migrate.c |
26995 |
+index 7e0b4f81c6c06..ff8916e1d38e9 100644 |
26996 |
+--- a/fs/ext4/migrate.c |
26997 |
++++ b/fs/ext4/migrate.c |
26998 |
+@@ -437,12 +437,12 @@ int ext4_ext_migrate(struct inode *inode) |
26999 |
+ percpu_down_write(&sbi->s_writepages_rwsem); |
27000 |
+ |
27001 |
+ /* |
27002 |
+- * Worst case we can touch the allocation bitmaps, a bgd |
27003 |
+- * block, and a block to link in the orphan list. We do need |
27004 |
+- * need to worry about credits for modifying the quota inode. |
27005 |
++ * Worst case we can touch the allocation bitmaps and a block |
27006 |
++ * group descriptor block. We do need need to worry about |
27007 |
++ * credits for modifying the quota inode. |
27008 |
+ */ |
27009 |
+ handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, |
27010 |
+- 4 + EXT4_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb)); |
27011 |
++ 3 + EXT4_MAXQUOTAS_TRANS_BLOCKS(inode->i_sb)); |
27012 |
+ |
27013 |
+ if (IS_ERR(handle)) { |
27014 |
+ retval = PTR_ERR(handle); |
27015 |
+@@ -459,6 +459,13 @@ int ext4_ext_migrate(struct inode *inode) |
27016 |
+ ext4_journal_stop(handle); |
27017 |
+ goto out_unlock; |
27018 |
+ } |
27019 |
++ /* |
27020 |
++ * Use the correct seed for checksum (i.e. the seed from 'inode'). This |
27021 |
++ * is so that the metadata blocks will have the correct checksum after |
27022 |
++ * the migration. |
27023 |
++ */ |
27024 |
++ ei = EXT4_I(inode); |
27025 |
++ EXT4_I(tmp_inode)->i_csum_seed = ei->i_csum_seed; |
27026 |
+ i_size_write(tmp_inode, i_size_read(inode)); |
27027 |
+ /* |
27028 |
+ * Set the i_nlink to zero so it will be deleted later |
27029 |
+@@ -467,7 +474,6 @@ int ext4_ext_migrate(struct inode *inode) |
27030 |
+ clear_nlink(tmp_inode); |
27031 |
+ |
27032 |
+ ext4_ext_tree_init(handle, tmp_inode); |
27033 |
+- ext4_orphan_add(handle, tmp_inode); |
27034 |
+ ext4_journal_stop(handle); |
27035 |
+ |
27036 |
+ /* |
27037 |
+@@ -492,17 +498,10 @@ int ext4_ext_migrate(struct inode *inode) |
27038 |
+ |
27039 |
+ handle = ext4_journal_start(inode, EXT4_HT_MIGRATE, 1); |
27040 |
+ if (IS_ERR(handle)) { |
27041 |
+- /* |
27042 |
+- * It is impossible to update on-disk structures without |
27043 |
+- * a handle, so just rollback in-core changes and live other |
27044 |
+- * work to orphan_list_cleanup() |
27045 |
+- */ |
27046 |
+- ext4_orphan_del(NULL, tmp_inode); |
27047 |
+ retval = PTR_ERR(handle); |
27048 |
+ goto out_tmp_inode; |
27049 |
+ } |
27050 |
+ |
27051 |
+- ei = EXT4_I(inode); |
27052 |
+ i_data = ei->i_data; |
27053 |
+ memset(&lb, 0, sizeof(lb)); |
27054 |
+ |
27055 |
+diff --git a/fs/ext4/super.c b/fs/ext4/super.c |
27056 |
+index 8a67e5f3f5763..877c5c17e61f0 100644 |
27057 |
+--- a/fs/ext4/super.c |
27058 |
++++ b/fs/ext4/super.c |
27059 |
+@@ -6266,10 +6266,7 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, |
27060 |
+ |
27061 |
+ lockdep_set_quota_inode(path->dentry->d_inode, I_DATA_SEM_QUOTA); |
27062 |
+ err = dquot_quota_on(sb, type, format_id, path); |
27063 |
+- if (err) { |
27064 |
+- lockdep_set_quota_inode(path->dentry->d_inode, |
27065 |
+- I_DATA_SEM_NORMAL); |
27066 |
+- } else { |
27067 |
++ if (!err) { |
27068 |
+ struct inode *inode = d_inode(path->dentry); |
27069 |
+ handle_t *handle; |
27070 |
+ |
27071 |
+@@ -6289,7 +6286,12 @@ static int ext4_quota_on(struct super_block *sb, int type, int format_id, |
27072 |
+ ext4_journal_stop(handle); |
27073 |
+ unlock_inode: |
27074 |
+ inode_unlock(inode); |
27075 |
++ if (err) |
27076 |
++ dquot_quota_off(sb, type); |
27077 |
+ } |
27078 |
++ if (err) |
27079 |
++ lockdep_set_quota_inode(path->dentry->d_inode, |
27080 |
++ I_DATA_SEM_NORMAL); |
27081 |
+ return err; |
27082 |
+ } |
27083 |
+ |
27084 |
+@@ -6352,8 +6354,19 @@ int ext4_enable_quotas(struct super_block *sb) |
27085 |
+ "Failed to enable quota tracking " |
27086 |
+ "(type=%d, err=%d). Please run " |
27087 |
+ "e2fsck to fix.", type, err); |
27088 |
+- for (type--; type >= 0; type--) |
27089 |
++ for (type--; type >= 0; type--) { |
27090 |
++ struct inode *inode; |
27091 |
++ |
27092 |
++ inode = sb_dqopt(sb)->files[type]; |
27093 |
++ if (inode) |
27094 |
++ inode = igrab(inode); |
27095 |
+ dquot_quota_off(sb, type); |
27096 |
++ if (inode) { |
27097 |
++ lockdep_set_quota_inode(inode, |
27098 |
++ I_DATA_SEM_NORMAL); |
27099 |
++ iput(inode); |
27100 |
++ } |
27101 |
++ } |
27102 |
+ |
27103 |
+ return err; |
27104 |
+ } |
27105 |
+@@ -6457,7 +6470,7 @@ static ssize_t ext4_quota_write(struct super_block *sb, int type, |
27106 |
+ struct buffer_head *bh; |
27107 |
+ handle_t *handle = journal_current_handle(); |
27108 |
+ |
27109 |
+- if (EXT4_SB(sb)->s_journal && !handle) { |
27110 |
++ if (!handle) { |
27111 |
+ ext4_msg(sb, KERN_WARNING, "Quota write (off=%llu, len=%llu)" |
27112 |
+ " cancelled because transaction is not started", |
27113 |
+ (unsigned long long)off, (unsigned long long)len); |
27114 |
+@@ -6640,6 +6653,7 @@ static int __init ext4_init_fs(void) |
27115 |
+ out: |
27116 |
+ unregister_as_ext2(); |
27117 |
+ unregister_as_ext3(); |
27118 |
++ ext4_fc_destroy_dentry_cache(); |
27119 |
+ out05: |
27120 |
+ destroy_inodecache(); |
27121 |
+ out1: |
27122 |
+@@ -6666,6 +6680,7 @@ static void __exit ext4_exit_fs(void) |
27123 |
+ unregister_as_ext2(); |
27124 |
+ unregister_as_ext3(); |
27125 |
+ unregister_filesystem(&ext4_fs_type); |
27126 |
++ ext4_fc_destroy_dentry_cache(); |
27127 |
+ destroy_inodecache(); |
27128 |
+ ext4_exit_mballoc(); |
27129 |
+ ext4_exit_sysfs(); |
27130 |
+diff --git a/fs/f2fs/checkpoint.c b/fs/f2fs/checkpoint.c |
27131 |
+index 7b02827242312..99fced979718e 100644 |
27132 |
+--- a/fs/f2fs/checkpoint.c |
27133 |
++++ b/fs/f2fs/checkpoint.c |
27134 |
+@@ -1305,8 +1305,8 @@ static void update_ckpt_flags(struct f2fs_sb_info *sbi, struct cp_control *cpc) |
27135 |
+ unsigned long flags; |
27136 |
+ |
27137 |
+ if (cpc->reason & CP_UMOUNT) { |
27138 |
+- if (le32_to_cpu(ckpt->cp_pack_total_block_count) > |
27139 |
+- sbi->blocks_per_seg - NM_I(sbi)->nat_bits_blocks) { |
27140 |
++ if (le32_to_cpu(ckpt->cp_pack_total_block_count) + |
27141 |
++ NM_I(sbi)->nat_bits_blocks > sbi->blocks_per_seg) { |
27142 |
+ clear_ckpt_flags(sbi, CP_NAT_BITS_FLAG); |
27143 |
+ f2fs_notice(sbi, "Disable nat_bits due to no space"); |
27144 |
+ } else if (!is_set_ckpt_flags(sbi, CP_NAT_BITS_FLAG) && |
27145 |
+diff --git a/fs/f2fs/compress.c b/fs/f2fs/compress.c |
27146 |
+index 9b663eaf48057..58d255d3a518a 100644 |
27147 |
+--- a/fs/f2fs/compress.c |
27148 |
++++ b/fs/f2fs/compress.c |
27149 |
+@@ -1448,25 +1448,38 @@ static int f2fs_write_raw_pages(struct compress_ctx *cc, |
27150 |
+ enum iostat_type io_type) |
27151 |
+ { |
27152 |
+ struct address_space *mapping = cc->inode->i_mapping; |
27153 |
+- int _submitted, compr_blocks, ret; |
27154 |
+- int i = -1, err = 0; |
27155 |
++ int _submitted, compr_blocks, ret, i; |
27156 |
+ |
27157 |
+ compr_blocks = f2fs_compressed_blocks(cc); |
27158 |
+- if (compr_blocks < 0) { |
27159 |
+- err = compr_blocks; |
27160 |
+- goto out_err; |
27161 |
++ |
27162 |
++ for (i = 0; i < cc->cluster_size; i++) { |
27163 |
++ if (!cc->rpages[i]) |
27164 |
++ continue; |
27165 |
++ |
27166 |
++ redirty_page_for_writepage(wbc, cc->rpages[i]); |
27167 |
++ unlock_page(cc->rpages[i]); |
27168 |
+ } |
27169 |
+ |
27170 |
++ if (compr_blocks < 0) |
27171 |
++ return compr_blocks; |
27172 |
++ |
27173 |
+ for (i = 0; i < cc->cluster_size; i++) { |
27174 |
+ if (!cc->rpages[i]) |
27175 |
+ continue; |
27176 |
+ retry_write: |
27177 |
++ lock_page(cc->rpages[i]); |
27178 |
++ |
27179 |
+ if (cc->rpages[i]->mapping != mapping) { |
27180 |
++continue_unlock: |
27181 |
+ unlock_page(cc->rpages[i]); |
27182 |
+ continue; |
27183 |
+ } |
27184 |
+ |
27185 |
+- BUG_ON(!PageLocked(cc->rpages[i])); |
27186 |
++ if (!PageDirty(cc->rpages[i])) |
27187 |
++ goto continue_unlock; |
27188 |
++ |
27189 |
++ if (!clear_page_dirty_for_io(cc->rpages[i])) |
27190 |
++ goto continue_unlock; |
27191 |
+ |
27192 |
+ ret = f2fs_write_single_data_page(cc->rpages[i], &_submitted, |
27193 |
+ NULL, NULL, wbc, io_type, |
27194 |
+@@ -1481,26 +1494,15 @@ retry_write: |
27195 |
+ * avoid deadlock caused by cluster update race |
27196 |
+ * from foreground operation. |
27197 |
+ */ |
27198 |
+- if (IS_NOQUOTA(cc->inode)) { |
27199 |
+- err = 0; |
27200 |
+- goto out_err; |
27201 |
+- } |
27202 |
++ if (IS_NOQUOTA(cc->inode)) |
27203 |
++ return 0; |
27204 |
+ ret = 0; |
27205 |
+ cond_resched(); |
27206 |
+ congestion_wait(BLK_RW_ASYNC, |
27207 |
+ DEFAULT_IO_TIMEOUT); |
27208 |
+- lock_page(cc->rpages[i]); |
27209 |
+- |
27210 |
+- if (!PageDirty(cc->rpages[i])) { |
27211 |
+- unlock_page(cc->rpages[i]); |
27212 |
+- continue; |
27213 |
+- } |
27214 |
+- |
27215 |
+- clear_page_dirty_for_io(cc->rpages[i]); |
27216 |
+ goto retry_write; |
27217 |
+ } |
27218 |
+- err = ret; |
27219 |
+- goto out_err; |
27220 |
++ return ret; |
27221 |
+ } |
27222 |
+ |
27223 |
+ *submitted += _submitted; |
27224 |
+@@ -1509,14 +1511,6 @@ retry_write: |
27225 |
+ f2fs_balance_fs(F2FS_M_SB(mapping), true); |
27226 |
+ |
27227 |
+ return 0; |
27228 |
+-out_err: |
27229 |
+- for (++i; i < cc->cluster_size; i++) { |
27230 |
+- if (!cc->rpages[i]) |
27231 |
+- continue; |
27232 |
+- redirty_page_for_writepage(wbc, cc->rpages[i]); |
27233 |
+- unlock_page(cc->rpages[i]); |
27234 |
+- } |
27235 |
+- return err; |
27236 |
+ } |
27237 |
+ |
27238 |
+ int f2fs_write_multi_pages(struct compress_ctx *cc, |
27239 |
+diff --git a/fs/f2fs/data.c b/fs/f2fs/data.c |
27240 |
+index f4fd6c246c9a9..e662355cf8c9b 100644 |
27241 |
+--- a/fs/f2fs/data.c |
27242 |
++++ b/fs/f2fs/data.c |
27243 |
+@@ -2564,6 +2564,11 @@ bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio) |
27244 |
+ { |
27245 |
+ struct f2fs_sb_info *sbi = F2FS_I_SB(inode); |
27246 |
+ |
27247 |
++ /* The below cases were checked when setting it. */ |
27248 |
++ if (f2fs_is_pinned_file(inode)) |
27249 |
++ return false; |
27250 |
++ if (fio && is_sbi_flag_set(sbi, SBI_NEED_FSCK)) |
27251 |
++ return true; |
27252 |
+ if (f2fs_lfs_mode(sbi)) |
27253 |
+ return true; |
27254 |
+ if (S_ISDIR(inode->i_mode)) |
27255 |
+@@ -2572,8 +2577,6 @@ bool f2fs_should_update_outplace(struct inode *inode, struct f2fs_io_info *fio) |
27256 |
+ return true; |
27257 |
+ if (f2fs_is_atomic_file(inode)) |
27258 |
+ return true; |
27259 |
+- if (is_sbi_flag_set(sbi, SBI_NEED_FSCK)) |
27260 |
+- return true; |
27261 |
+ |
27262 |
+ /* swap file is migrating in aligned write mode */ |
27263 |
+ if (is_inode_flag_set(inode, FI_ALIGNED_WRITE)) |
27264 |
+diff --git a/fs/f2fs/f2fs.h b/fs/f2fs/f2fs.h |
27265 |
+index c242274e3479b..c68817d83a53b 100644 |
27266 |
+--- a/fs/f2fs/f2fs.h |
27267 |
++++ b/fs/f2fs/f2fs.h |
27268 |
+@@ -1012,6 +1012,7 @@ struct f2fs_sm_info { |
27269 |
+ unsigned int segment_count; /* total # of segments */ |
27270 |
+ unsigned int main_segments; /* # of segments in main area */ |
27271 |
+ unsigned int reserved_segments; /* # of reserved segments */ |
27272 |
++ unsigned int additional_reserved_segments;/* reserved segs for IO align feature */ |
27273 |
+ unsigned int ovp_segments; /* # of overprovision segments */ |
27274 |
+ |
27275 |
+ /* a threshold to reclaim prefree segments */ |
27276 |
+@@ -2184,6 +2185,11 @@ static inline int inc_valid_block_count(struct f2fs_sb_info *sbi, |
27277 |
+ |
27278 |
+ if (!__allow_reserved_blocks(sbi, inode, true)) |
27279 |
+ avail_user_block_count -= F2FS_OPTION(sbi).root_reserved_blocks; |
27280 |
++ |
27281 |
++ if (F2FS_IO_ALIGNED(sbi)) |
27282 |
++ avail_user_block_count -= sbi->blocks_per_seg * |
27283 |
++ SM_I(sbi)->additional_reserved_segments; |
27284 |
++ |
27285 |
+ if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) { |
27286 |
+ if (avail_user_block_count > sbi->unusable_block_count) |
27287 |
+ avail_user_block_count -= sbi->unusable_block_count; |
27288 |
+@@ -2430,6 +2436,11 @@ static inline int inc_valid_node_count(struct f2fs_sb_info *sbi, |
27289 |
+ |
27290 |
+ if (!__allow_reserved_blocks(sbi, inode, false)) |
27291 |
+ valid_block_count += F2FS_OPTION(sbi).root_reserved_blocks; |
27292 |
++ |
27293 |
++ if (F2FS_IO_ALIGNED(sbi)) |
27294 |
++ valid_block_count += sbi->blocks_per_seg * |
27295 |
++ SM_I(sbi)->additional_reserved_segments; |
27296 |
++ |
27297 |
+ user_block_count = sbi->user_block_count; |
27298 |
+ if (unlikely(is_sbi_flag_set(sbi, SBI_CP_DISABLED))) |
27299 |
+ user_block_count -= sbi->unusable_block_count; |
27300 |
+diff --git a/fs/f2fs/file.c b/fs/f2fs/file.c |
27301 |
+index 9c8ef33bd8d32..7ed44752c7580 100644 |
27302 |
+--- a/fs/f2fs/file.c |
27303 |
++++ b/fs/f2fs/file.c |
27304 |
+@@ -3143,17 +3143,17 @@ static int f2fs_ioc_set_pin_file(struct file *filp, unsigned long arg) |
27305 |
+ |
27306 |
+ inode_lock(inode); |
27307 |
+ |
27308 |
+- if (f2fs_should_update_outplace(inode, NULL)) { |
27309 |
+- ret = -EINVAL; |
27310 |
+- goto out; |
27311 |
+- } |
27312 |
+- |
27313 |
+ if (!pin) { |
27314 |
+ clear_inode_flag(inode, FI_PIN_FILE); |
27315 |
+ f2fs_i_gc_failures_write(inode, 0); |
27316 |
+ goto done; |
27317 |
+ } |
27318 |
+ |
27319 |
++ if (f2fs_should_update_outplace(inode, NULL)) { |
27320 |
++ ret = -EINVAL; |
27321 |
++ goto out; |
27322 |
++ } |
27323 |
++ |
27324 |
+ if (f2fs_pin_file_control(inode, false)) { |
27325 |
+ ret = -EAGAIN; |
27326 |
+ goto out; |
27327 |
+diff --git a/fs/f2fs/gc.c b/fs/f2fs/gc.c |
27328 |
+index 77391e3b7d68f..264821df0add1 100644 |
27329 |
+--- a/fs/f2fs/gc.c |
27330 |
++++ b/fs/f2fs/gc.c |
27331 |
+@@ -1023,6 +1023,9 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, |
27332 |
+ set_sbi_flag(sbi, SBI_NEED_FSCK); |
27333 |
+ } |
27334 |
+ |
27335 |
++ if (f2fs_check_nid_range(sbi, dni->ino)) |
27336 |
++ return false; |
27337 |
++ |
27338 |
+ *nofs = ofs_of_node(node_page); |
27339 |
+ source_blkaddr = data_blkaddr(NULL, node_page, ofs_in_node); |
27340 |
+ f2fs_put_page(node_page, 1); |
27341 |
+@@ -1036,7 +1039,7 @@ static bool is_alive(struct f2fs_sb_info *sbi, struct f2fs_summary *sum, |
27342 |
+ if (!test_and_set_bit(segno, SIT_I(sbi)->invalid_segmap)) { |
27343 |
+ f2fs_err(sbi, "mismatched blkaddr %u (source_blkaddr %u) in seg %u", |
27344 |
+ blkaddr, source_blkaddr, segno); |
27345 |
+- f2fs_bug_on(sbi, 1); |
27346 |
++ set_sbi_flag(sbi, SBI_NEED_FSCK); |
27347 |
+ } |
27348 |
+ } |
27349 |
+ #endif |
27350 |
+@@ -1454,7 +1457,8 @@ next_step: |
27351 |
+ |
27352 |
+ if (phase == 3) { |
27353 |
+ inode = f2fs_iget(sb, dni.ino); |
27354 |
+- if (IS_ERR(inode) || is_bad_inode(inode)) |
27355 |
++ if (IS_ERR(inode) || is_bad_inode(inode) || |
27356 |
++ special_file(inode->i_mode)) |
27357 |
+ continue; |
27358 |
+ |
27359 |
+ if (!down_write_trylock( |
27360 |
+diff --git a/fs/f2fs/inode.c b/fs/f2fs/inode.c |
27361 |
+index 1213f15ffd68c..4557de37a9119 100644 |
27362 |
+--- a/fs/f2fs/inode.c |
27363 |
++++ b/fs/f2fs/inode.c |
27364 |
+@@ -516,6 +516,11 @@ make_now: |
27365 |
+ } else if (ino == F2FS_COMPRESS_INO(sbi)) { |
27366 |
+ #ifdef CONFIG_F2FS_FS_COMPRESSION |
27367 |
+ inode->i_mapping->a_ops = &f2fs_compress_aops; |
27368 |
++ /* |
27369 |
++ * generic_error_remove_page only truncates pages of regular |
27370 |
++ * inode |
27371 |
++ */ |
27372 |
++ inode->i_mode |= S_IFREG; |
27373 |
+ #endif |
27374 |
+ mapping_set_gfp_mask(inode->i_mapping, |
27375 |
+ GFP_NOFS | __GFP_HIGHMEM | __GFP_MOVABLE); |
27376 |
+diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h |
27377 |
+index 89fff258727d1..b2d82c9f5a16d 100644 |
27378 |
+--- a/fs/f2fs/segment.h |
27379 |
++++ b/fs/f2fs/segment.h |
27380 |
+@@ -537,7 +537,8 @@ static inline unsigned int free_segments(struct f2fs_sb_info *sbi) |
27381 |
+ |
27382 |
+ static inline unsigned int reserved_segments(struct f2fs_sb_info *sbi) |
27383 |
+ { |
27384 |
+- return SM_I(sbi)->reserved_segments; |
27385 |
++ return SM_I(sbi)->reserved_segments + |
27386 |
++ SM_I(sbi)->additional_reserved_segments; |
27387 |
+ } |
27388 |
+ |
27389 |
+ static inline unsigned int free_sections(struct f2fs_sb_info *sbi) |
27390 |
+diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c |
27391 |
+index 8795a5a8d4e89..6174c4f4cee7f 100644 |
27392 |
+--- a/fs/f2fs/super.c |
27393 |
++++ b/fs/f2fs/super.c |
27394 |
+@@ -327,6 +327,46 @@ static inline void limit_reserve_root(struct f2fs_sb_info *sbi) |
27395 |
+ F2FS_OPTION(sbi).s_resgid)); |
27396 |
+ } |
27397 |
+ |
27398 |
++static inline int adjust_reserved_segment(struct f2fs_sb_info *sbi) |
27399 |
++{ |
27400 |
++ unsigned int sec_blks = sbi->blocks_per_seg * sbi->segs_per_sec; |
27401 |
++ unsigned int avg_vblocks; |
27402 |
++ unsigned int wanted_reserved_segments; |
27403 |
++ block_t avail_user_block_count; |
27404 |
++ |
27405 |
++ if (!F2FS_IO_ALIGNED(sbi)) |
27406 |
++ return 0; |
27407 |
++ |
27408 |
++ /* average valid block count in section in worst case */ |
27409 |
++ avg_vblocks = sec_blks / F2FS_IO_SIZE(sbi); |
27410 |
++ |
27411 |
++ /* |
27412 |
++ * we need enough free space when migrating one section in worst case |
27413 |
++ */ |
27414 |
++ wanted_reserved_segments = (F2FS_IO_SIZE(sbi) / avg_vblocks) * |
27415 |
++ reserved_segments(sbi); |
27416 |
++ wanted_reserved_segments -= reserved_segments(sbi); |
27417 |
++ |
27418 |
++ avail_user_block_count = sbi->user_block_count - |
27419 |
++ sbi->current_reserved_blocks - |
27420 |
++ F2FS_OPTION(sbi).root_reserved_blocks; |
27421 |
++ |
27422 |
++ if (wanted_reserved_segments * sbi->blocks_per_seg > |
27423 |
++ avail_user_block_count) { |
27424 |
++ f2fs_err(sbi, "IO align feature can't grab additional reserved segment: %u, available segments: %u", |
27425 |
++ wanted_reserved_segments, |
27426 |
++ avail_user_block_count >> sbi->log_blocks_per_seg); |
27427 |
++ return -ENOSPC; |
27428 |
++ } |
27429 |
++ |
27430 |
++ SM_I(sbi)->additional_reserved_segments = wanted_reserved_segments; |
27431 |
++ |
27432 |
++ f2fs_info(sbi, "IO align feature needs additional reserved segment: %u", |
27433 |
++ wanted_reserved_segments); |
27434 |
++ |
27435 |
++ return 0; |
27436 |
++} |
27437 |
++ |
27438 |
+ static inline void adjust_unusable_cap_perc(struct f2fs_sb_info *sbi) |
27439 |
+ { |
27440 |
+ if (!F2FS_OPTION(sbi).unusable_cap_perc) |
27441 |
+@@ -4148,6 +4188,10 @@ try_onemore: |
27442 |
+ goto free_nm; |
27443 |
+ } |
27444 |
+ |
27445 |
++ err = adjust_reserved_segment(sbi); |
27446 |
++ if (err) |
27447 |
++ goto free_nm; |
27448 |
++ |
27449 |
+ /* For write statistics */ |
27450 |
+ sbi->sectors_written_start = f2fs_get_sectors_written(sbi); |
27451 |
+ |
27452 |
+diff --git a/fs/f2fs/sysfs.c b/fs/f2fs/sysfs.c |
27453 |
+index a32fe31c33b8e..abc4344fba394 100644 |
27454 |
+--- a/fs/f2fs/sysfs.c |
27455 |
++++ b/fs/f2fs/sysfs.c |
27456 |
+@@ -415,7 +415,9 @@ out: |
27457 |
+ if (a->struct_type == RESERVED_BLOCKS) { |
27458 |
+ spin_lock(&sbi->stat_lock); |
27459 |
+ if (t > (unsigned long)(sbi->user_block_count - |
27460 |
+- F2FS_OPTION(sbi).root_reserved_blocks)) { |
27461 |
++ F2FS_OPTION(sbi).root_reserved_blocks - |
27462 |
++ sbi->blocks_per_seg * |
27463 |
++ SM_I(sbi)->additional_reserved_segments)) { |
27464 |
+ spin_unlock(&sbi->stat_lock); |
27465 |
+ return -EINVAL; |
27466 |
+ } |
27467 |
+diff --git a/fs/fuse/file.c b/fs/fuse/file.c |
27468 |
+index 5c5ed58d91a73..2004d362361e1 100644 |
27469 |
+--- a/fs/fuse/file.c |
27470 |
++++ b/fs/fuse/file.c |
27471 |
+@@ -2913,7 +2913,7 @@ fuse_direct_IO(struct kiocb *iocb, struct iov_iter *iter) |
27472 |
+ |
27473 |
+ static int fuse_writeback_range(struct inode *inode, loff_t start, loff_t end) |
27474 |
+ { |
27475 |
+- int err = filemap_write_and_wait_range(inode->i_mapping, start, -1); |
27476 |
++ int err = filemap_write_and_wait_range(inode->i_mapping, start, LLONG_MAX); |
27477 |
+ |
27478 |
+ if (!err) |
27479 |
+ fuse_sync_writes(inode); |
27480 |
+diff --git a/fs/io_uring.c b/fs/io_uring.c |
27481 |
+index 0006fc7479ca3..ecffeddf90c68 100644 |
27482 |
+--- a/fs/io_uring.c |
27483 |
++++ b/fs/io_uring.c |
27484 |
+@@ -5925,6 +5925,7 @@ static int io_poll_update(struct io_kiocb *req, unsigned int issue_flags) |
27485 |
+ * update those. For multishot, if we're racing with completion, just |
27486 |
+ * let completion re-add it. |
27487 |
+ */ |
27488 |
++ io_poll_remove_double(preq); |
27489 |
+ completing = !__io_poll_remove_one(preq, &preq->poll, false); |
27490 |
+ if (completing && (preq->poll.events & EPOLLONESHOT)) { |
27491 |
+ ret = -EALREADY; |
27492 |
+diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c |
27493 |
+index 4fc8cd698d1a4..bd7d58d27bfc6 100644 |
27494 |
+--- a/fs/jffs2/file.c |
27495 |
++++ b/fs/jffs2/file.c |
27496 |
+@@ -136,20 +136,15 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, |
27497 |
+ struct page *pg; |
27498 |
+ struct inode *inode = mapping->host; |
27499 |
+ struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); |
27500 |
++ struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); |
27501 |
+ pgoff_t index = pos >> PAGE_SHIFT; |
27502 |
+ uint32_t pageofs = index << PAGE_SHIFT; |
27503 |
+ int ret = 0; |
27504 |
+ |
27505 |
+- pg = grab_cache_page_write_begin(mapping, index, flags); |
27506 |
+- if (!pg) |
27507 |
+- return -ENOMEM; |
27508 |
+- *pagep = pg; |
27509 |
+- |
27510 |
+ jffs2_dbg(1, "%s()\n", __func__); |
27511 |
+ |
27512 |
+ if (pageofs > inode->i_size) { |
27513 |
+ /* Make new hole frag from old EOF to new page */ |
27514 |
+- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); |
27515 |
+ struct jffs2_raw_inode ri; |
27516 |
+ struct jffs2_full_dnode *fn; |
27517 |
+ uint32_t alloc_len; |
27518 |
+@@ -160,7 +155,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, |
27519 |
+ ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, |
27520 |
+ ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); |
27521 |
+ if (ret) |
27522 |
+- goto out_page; |
27523 |
++ goto out_err; |
27524 |
+ |
27525 |
+ mutex_lock(&f->sem); |
27526 |
+ memset(&ri, 0, sizeof(ri)); |
27527 |
+@@ -190,7 +185,7 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, |
27528 |
+ ret = PTR_ERR(fn); |
27529 |
+ jffs2_complete_reservation(c); |
27530 |
+ mutex_unlock(&f->sem); |
27531 |
+- goto out_page; |
27532 |
++ goto out_err; |
27533 |
+ } |
27534 |
+ ret = jffs2_add_full_dnode_to_inode(c, f, fn); |
27535 |
+ if (f->metadata) { |
27536 |
+@@ -205,13 +200,26 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, |
27537 |
+ jffs2_free_full_dnode(fn); |
27538 |
+ jffs2_complete_reservation(c); |
27539 |
+ mutex_unlock(&f->sem); |
27540 |
+- goto out_page; |
27541 |
++ goto out_err; |
27542 |
+ } |
27543 |
+ jffs2_complete_reservation(c); |
27544 |
+ inode->i_size = pageofs; |
27545 |
+ mutex_unlock(&f->sem); |
27546 |
+ } |
27547 |
+ |
27548 |
++ /* |
27549 |
++ * While getting a page and reading data in, lock c->alloc_sem until |
27550 |
++ * the page is Uptodate. Otherwise GC task may attempt to read the same |
27551 |
++ * page in read_cache_page(), which causes a deadlock. |
27552 |
++ */ |
27553 |
++ mutex_lock(&c->alloc_sem); |
27554 |
++ pg = grab_cache_page_write_begin(mapping, index, flags); |
27555 |
++ if (!pg) { |
27556 |
++ ret = -ENOMEM; |
27557 |
++ goto release_sem; |
27558 |
++ } |
27559 |
++ *pagep = pg; |
27560 |
++ |
27561 |
+ /* |
27562 |
+ * Read in the page if it wasn't already present. Cannot optimize away |
27563 |
+ * the whole page write case until jffs2_write_end can handle the |
27564 |
+@@ -221,15 +229,17 @@ static int jffs2_write_begin(struct file *filp, struct address_space *mapping, |
27565 |
+ mutex_lock(&f->sem); |
27566 |
+ ret = jffs2_do_readpage_nolock(inode, pg); |
27567 |
+ mutex_unlock(&f->sem); |
27568 |
+- if (ret) |
27569 |
+- goto out_page; |
27570 |
++ if (ret) { |
27571 |
++ unlock_page(pg); |
27572 |
++ put_page(pg); |
27573 |
++ goto release_sem; |
27574 |
++ } |
27575 |
+ } |
27576 |
+ jffs2_dbg(1, "end write_begin(). pg->flags %lx\n", pg->flags); |
27577 |
+- return ret; |
27578 |
+ |
27579 |
+-out_page: |
27580 |
+- unlock_page(pg); |
27581 |
+- put_page(pg); |
27582 |
++release_sem: |
27583 |
++ mutex_unlock(&c->alloc_sem); |
27584 |
++out_err: |
27585 |
+ return ret; |
27586 |
+ } |
27587 |
+ |
27588 |
+diff --git a/fs/ksmbd/connection.c b/fs/ksmbd/connection.c |
27589 |
+index b57a0d8a392ff..f7d5e8b7bef77 100644 |
27590 |
+--- a/fs/ksmbd/connection.c |
27591 |
++++ b/fs/ksmbd/connection.c |
27592 |
+@@ -62,6 +62,7 @@ struct ksmbd_conn *ksmbd_conn_alloc(void) |
27593 |
+ atomic_set(&conn->req_running, 0); |
27594 |
+ atomic_set(&conn->r_count, 0); |
27595 |
+ conn->total_credits = 1; |
27596 |
++ conn->outstanding_credits = 1; |
27597 |
+ |
27598 |
+ init_waitqueue_head(&conn->req_running_q); |
27599 |
+ INIT_LIST_HEAD(&conn->conns_list); |
27600 |
+diff --git a/fs/ksmbd/connection.h b/fs/ksmbd/connection.h |
27601 |
+index e5403c587a58c..8694aef482c1a 100644 |
27602 |
+--- a/fs/ksmbd/connection.h |
27603 |
++++ b/fs/ksmbd/connection.h |
27604 |
+@@ -61,8 +61,8 @@ struct ksmbd_conn { |
27605 |
+ atomic_t req_running; |
27606 |
+ /* References which are made for this Server object*/ |
27607 |
+ atomic_t r_count; |
27608 |
+- unsigned short total_credits; |
27609 |
+- unsigned short max_credits; |
27610 |
++ unsigned int total_credits; |
27611 |
++ unsigned int outstanding_credits; |
27612 |
+ spinlock_t credits_lock; |
27613 |
+ wait_queue_head_t req_running_q; |
27614 |
+ /* Lock to protect requests list*/ |
27615 |
+diff --git a/fs/ksmbd/ksmbd_netlink.h b/fs/ksmbd/ksmbd_netlink.h |
27616 |
+index c6718a05d347f..71bfb7de44725 100644 |
27617 |
+--- a/fs/ksmbd/ksmbd_netlink.h |
27618 |
++++ b/fs/ksmbd/ksmbd_netlink.h |
27619 |
+@@ -103,6 +103,8 @@ struct ksmbd_startup_request { |
27620 |
+ * we set the SPARSE_FILES bit (0x40). |
27621 |
+ */ |
27622 |
+ __u32 sub_auth[3]; /* Subauth value for Security ID */ |
27623 |
++ __u32 smb2_max_credits; /* MAX credits */ |
27624 |
++ __u32 reserved[128]; /* Reserved room */ |
27625 |
+ __u32 ifc_list_sz; /* interfaces list size */ |
27626 |
+ __s8 ____payload[]; |
27627 |
+ }; |
27628 |
+@@ -113,7 +115,7 @@ struct ksmbd_startup_request { |
27629 |
+ * IPC request to shutdown ksmbd server. |
27630 |
+ */ |
27631 |
+ struct ksmbd_shutdown_request { |
27632 |
+- __s32 reserved; |
27633 |
++ __s32 reserved[16]; |
27634 |
+ }; |
27635 |
+ |
27636 |
+ /* |
27637 |
+@@ -122,6 +124,7 @@ struct ksmbd_shutdown_request { |
27638 |
+ struct ksmbd_login_request { |
27639 |
+ __u32 handle; |
27640 |
+ __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; /* user account name */ |
27641 |
++ __u32 reserved[16]; /* Reserved room */ |
27642 |
+ }; |
27643 |
+ |
27644 |
+ /* |
27645 |
+@@ -135,6 +138,7 @@ struct ksmbd_login_response { |
27646 |
+ __u16 status; |
27647 |
+ __u16 hash_sz; /* hash size */ |
27648 |
+ __s8 hash[KSMBD_REQ_MAX_HASH_SZ]; /* password hash */ |
27649 |
++ __u32 reserved[16]; /* Reserved room */ |
27650 |
+ }; |
27651 |
+ |
27652 |
+ /* |
27653 |
+@@ -143,6 +147,7 @@ struct ksmbd_login_response { |
27654 |
+ struct ksmbd_share_config_request { |
27655 |
+ __u32 handle; |
27656 |
+ __s8 share_name[KSMBD_REQ_MAX_SHARE_NAME]; /* share name */ |
27657 |
++ __u32 reserved[16]; /* Reserved room */ |
27658 |
+ }; |
27659 |
+ |
27660 |
+ /* |
27661 |
+@@ -157,6 +162,7 @@ struct ksmbd_share_config_response { |
27662 |
+ __u16 force_directory_mode; |
27663 |
+ __u16 force_uid; |
27664 |
+ __u16 force_gid; |
27665 |
++ __u32 reserved[128]; /* Reserved room */ |
27666 |
+ __u32 veto_list_sz; |
27667 |
+ __s8 ____payload[]; |
27668 |
+ }; |
27669 |
+@@ -187,6 +193,7 @@ struct ksmbd_tree_connect_request { |
27670 |
+ __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; |
27671 |
+ __s8 share[KSMBD_REQ_MAX_SHARE_NAME]; |
27672 |
+ __s8 peer_addr[64]; |
27673 |
++ __u32 reserved[16]; /* Reserved room */ |
27674 |
+ }; |
27675 |
+ |
27676 |
+ /* |
27677 |
+@@ -196,6 +203,7 @@ struct ksmbd_tree_connect_response { |
27678 |
+ __u32 handle; |
27679 |
+ __u16 status; |
27680 |
+ __u16 connection_flags; |
27681 |
++ __u32 reserved[16]; /* Reserved room */ |
27682 |
+ }; |
27683 |
+ |
27684 |
+ /* |
27685 |
+@@ -204,6 +212,7 @@ struct ksmbd_tree_connect_response { |
27686 |
+ struct ksmbd_tree_disconnect_request { |
27687 |
+ __u64 session_id; /* session id */ |
27688 |
+ __u64 connect_id; /* tree connection id */ |
27689 |
++ __u32 reserved[16]; /* Reserved room */ |
27690 |
+ }; |
27691 |
+ |
27692 |
+ /* |
27693 |
+@@ -212,6 +221,7 @@ struct ksmbd_tree_disconnect_request { |
27694 |
+ struct ksmbd_logout_request { |
27695 |
+ __s8 account[KSMBD_REQ_MAX_ACCOUNT_NAME_SZ]; /* user account name */ |
27696 |
+ __u32 account_flags; |
27697 |
++ __u32 reserved[16]; /* Reserved room */ |
27698 |
+ }; |
27699 |
+ |
27700 |
+ /* |
27701 |
+diff --git a/fs/ksmbd/smb2misc.c b/fs/ksmbd/smb2misc.c |
27702 |
+index 9f516f73bd1b6..cc1c38686ecd7 100644 |
27703 |
+--- a/fs/ksmbd/smb2misc.c |
27704 |
++++ b/fs/ksmbd/smb2misc.c |
27705 |
+@@ -290,7 +290,7 @@ static int smb2_validate_credit_charge(struct ksmbd_conn *conn, |
27706 |
+ unsigned int req_len = 0, expect_resp_len = 0, calc_credit_num, max_len; |
27707 |
+ unsigned short credit_charge = le16_to_cpu(hdr->CreditCharge); |
27708 |
+ void *__hdr = hdr; |
27709 |
+- int ret; |
27710 |
++ int ret = 0; |
27711 |
+ |
27712 |
+ switch (hdr->Command) { |
27713 |
+ case SMB2_QUERY_INFO: |
27714 |
+@@ -327,21 +327,27 @@ static int smb2_validate_credit_charge(struct ksmbd_conn *conn, |
27715 |
+ ksmbd_debug(SMB, "Insufficient credit charge, given: %d, needed: %d\n", |
27716 |
+ credit_charge, calc_credit_num); |
27717 |
+ return 1; |
27718 |
+- } else if (credit_charge > conn->max_credits) { |
27719 |
++ } else if (credit_charge > conn->vals->max_credits) { |
27720 |
+ ksmbd_debug(SMB, "Too large credit charge: %d\n", credit_charge); |
27721 |
+ return 1; |
27722 |
+ } |
27723 |
+ |
27724 |
+ spin_lock(&conn->credits_lock); |
27725 |
+- if (credit_charge <= conn->total_credits) { |
27726 |
+- conn->total_credits -= credit_charge; |
27727 |
+- ret = 0; |
27728 |
+- } else { |
27729 |
++ if (credit_charge > conn->total_credits) { |
27730 |
+ ksmbd_debug(SMB, "Insufficient credits granted, given: %u, granted: %u\n", |
27731 |
+ credit_charge, conn->total_credits); |
27732 |
+ ret = 1; |
27733 |
+ } |
27734 |
++ |
27735 |
++ if ((u64)conn->outstanding_credits + credit_charge > conn->vals->max_credits) { |
27736 |
++ ksmbd_debug(SMB, "Limits exceeding the maximum allowable outstanding requests, given : %u, pending : %u\n", |
27737 |
++ credit_charge, conn->outstanding_credits); |
27738 |
++ ret = 1; |
27739 |
++ } else |
27740 |
++ conn->outstanding_credits += credit_charge; |
27741 |
++ |
27742 |
+ spin_unlock(&conn->credits_lock); |
27743 |
++ |
27744 |
+ return ret; |
27745 |
+ } |
27746 |
+ |
27747 |
+diff --git a/fs/ksmbd/smb2ops.c b/fs/ksmbd/smb2ops.c |
27748 |
+index 2a6205103df2c..f0a5b704f301c 100644 |
27749 |
+--- a/fs/ksmbd/smb2ops.c |
27750 |
++++ b/fs/ksmbd/smb2ops.c |
27751 |
+@@ -20,6 +20,7 @@ static struct smb_version_values smb21_server_values = { |
27752 |
+ .max_read_size = SMB21_DEFAULT_IOSIZE, |
27753 |
+ .max_write_size = SMB21_DEFAULT_IOSIZE, |
27754 |
+ .max_trans_size = SMB21_DEFAULT_IOSIZE, |
27755 |
++ .max_credits = SMB2_MAX_CREDITS, |
27756 |
+ .large_lock_type = 0, |
27757 |
+ .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE, |
27758 |
+ .shared_lock_type = SMB2_LOCKFLAG_SHARED, |
27759 |
+@@ -45,6 +46,7 @@ static struct smb_version_values smb30_server_values = { |
27760 |
+ .max_read_size = SMB3_DEFAULT_IOSIZE, |
27761 |
+ .max_write_size = SMB3_DEFAULT_IOSIZE, |
27762 |
+ .max_trans_size = SMB3_DEFAULT_TRANS_SIZE, |
27763 |
++ .max_credits = SMB2_MAX_CREDITS, |
27764 |
+ .large_lock_type = 0, |
27765 |
+ .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE, |
27766 |
+ .shared_lock_type = SMB2_LOCKFLAG_SHARED, |
27767 |
+@@ -71,6 +73,7 @@ static struct smb_version_values smb302_server_values = { |
27768 |
+ .max_read_size = SMB3_DEFAULT_IOSIZE, |
27769 |
+ .max_write_size = SMB3_DEFAULT_IOSIZE, |
27770 |
+ .max_trans_size = SMB3_DEFAULT_TRANS_SIZE, |
27771 |
++ .max_credits = SMB2_MAX_CREDITS, |
27772 |
+ .large_lock_type = 0, |
27773 |
+ .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE, |
27774 |
+ .shared_lock_type = SMB2_LOCKFLAG_SHARED, |
27775 |
+@@ -97,6 +100,7 @@ static struct smb_version_values smb311_server_values = { |
27776 |
+ .max_read_size = SMB3_DEFAULT_IOSIZE, |
27777 |
+ .max_write_size = SMB3_DEFAULT_IOSIZE, |
27778 |
+ .max_trans_size = SMB3_DEFAULT_TRANS_SIZE, |
27779 |
++ .max_credits = SMB2_MAX_CREDITS, |
27780 |
+ .large_lock_type = 0, |
27781 |
+ .exclusive_lock_type = SMB2_LOCKFLAG_EXCLUSIVE, |
27782 |
+ .shared_lock_type = SMB2_LOCKFLAG_SHARED, |
27783 |
+@@ -198,7 +202,6 @@ void init_smb2_1_server(struct ksmbd_conn *conn) |
27784 |
+ conn->ops = &smb2_0_server_ops; |
27785 |
+ conn->cmds = smb2_0_server_cmds; |
27786 |
+ conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds); |
27787 |
+- conn->max_credits = SMB2_MAX_CREDITS; |
27788 |
+ conn->signing_algorithm = SIGNING_ALG_HMAC_SHA256; |
27789 |
+ |
27790 |
+ if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) |
27791 |
+@@ -216,7 +219,6 @@ void init_smb3_0_server(struct ksmbd_conn *conn) |
27792 |
+ conn->ops = &smb3_0_server_ops; |
27793 |
+ conn->cmds = smb2_0_server_cmds; |
27794 |
+ conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds); |
27795 |
+- conn->max_credits = SMB2_MAX_CREDITS; |
27796 |
+ conn->signing_algorithm = SIGNING_ALG_AES_CMAC; |
27797 |
+ |
27798 |
+ if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) |
27799 |
+@@ -241,7 +243,6 @@ void init_smb3_02_server(struct ksmbd_conn *conn) |
27800 |
+ conn->ops = &smb3_0_server_ops; |
27801 |
+ conn->cmds = smb2_0_server_cmds; |
27802 |
+ conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds); |
27803 |
+- conn->max_credits = SMB2_MAX_CREDITS; |
27804 |
+ conn->signing_algorithm = SIGNING_ALG_AES_CMAC; |
27805 |
+ |
27806 |
+ if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) |
27807 |
+@@ -266,7 +267,6 @@ int init_smb3_11_server(struct ksmbd_conn *conn) |
27808 |
+ conn->ops = &smb3_11_server_ops; |
27809 |
+ conn->cmds = smb2_0_server_cmds; |
27810 |
+ conn->max_cmds = ARRAY_SIZE(smb2_0_server_cmds); |
27811 |
+- conn->max_credits = SMB2_MAX_CREDITS; |
27812 |
+ conn->signing_algorithm = SIGNING_ALG_AES_CMAC; |
27813 |
+ |
27814 |
+ if (server_conf.flags & KSMBD_GLOBAL_FLAG_SMB2_LEASES) |
27815 |
+@@ -305,3 +305,11 @@ void init_smb2_max_trans_size(unsigned int sz) |
27816 |
+ smb302_server_values.max_trans_size = sz; |
27817 |
+ smb311_server_values.max_trans_size = sz; |
27818 |
+ } |
27819 |
++ |
27820 |
++void init_smb2_max_credits(unsigned int sz) |
27821 |
++{ |
27822 |
++ smb21_server_values.max_credits = sz; |
27823 |
++ smb30_server_values.max_credits = sz; |
27824 |
++ smb302_server_values.max_credits = sz; |
27825 |
++ smb311_server_values.max_credits = sz; |
27826 |
++} |
27827 |
+diff --git a/fs/ksmbd/smb2pdu.c b/fs/ksmbd/smb2pdu.c |
27828 |
+index cb71cbfc5fc9b..f694ee10a0bc8 100644 |
27829 |
+--- a/fs/ksmbd/smb2pdu.c |
27830 |
++++ b/fs/ksmbd/smb2pdu.c |
27831 |
+@@ -301,16 +301,15 @@ int smb2_set_rsp_credits(struct ksmbd_work *work) |
27832 |
+ struct smb2_hdr *req_hdr = ksmbd_req_buf_next(work); |
27833 |
+ struct smb2_hdr *hdr = ksmbd_resp_buf_next(work); |
27834 |
+ struct ksmbd_conn *conn = work->conn; |
27835 |
+- unsigned short credits_requested; |
27836 |
++ unsigned short credits_requested, aux_max; |
27837 |
+ unsigned short credit_charge, credits_granted = 0; |
27838 |
+- unsigned short aux_max, aux_credits; |
27839 |
+ |
27840 |
+ if (work->send_no_response) |
27841 |
+ return 0; |
27842 |
+ |
27843 |
+ hdr->CreditCharge = req_hdr->CreditCharge; |
27844 |
+ |
27845 |
+- if (conn->total_credits > conn->max_credits) { |
27846 |
++ if (conn->total_credits > conn->vals->max_credits) { |
27847 |
+ hdr->CreditRequest = 0; |
27848 |
+ pr_err("Total credits overflow: %d\n", conn->total_credits); |
27849 |
+ return -EINVAL; |
27850 |
+@@ -318,6 +317,14 @@ int smb2_set_rsp_credits(struct ksmbd_work *work) |
27851 |
+ |
27852 |
+ credit_charge = max_t(unsigned short, |
27853 |
+ le16_to_cpu(req_hdr->CreditCharge), 1); |
27854 |
++ if (credit_charge > conn->total_credits) { |
27855 |
++ ksmbd_debug(SMB, "Insufficient credits granted, given: %u, granted: %u\n", |
27856 |
++ credit_charge, conn->total_credits); |
27857 |
++ return -EINVAL; |
27858 |
++ } |
27859 |
++ |
27860 |
++ conn->total_credits -= credit_charge; |
27861 |
++ conn->outstanding_credits -= credit_charge; |
27862 |
+ credits_requested = max_t(unsigned short, |
27863 |
+ le16_to_cpu(req_hdr->CreditRequest), 1); |
27864 |
+ |
27865 |
+@@ -327,16 +334,14 @@ int smb2_set_rsp_credits(struct ksmbd_work *work) |
27866 |
+ * TODO: Need to adjuct CreditRequest value according to |
27867 |
+ * current cpu load |
27868 |
+ */ |
27869 |
+- aux_credits = credits_requested - 1; |
27870 |
+ if (hdr->Command == SMB2_NEGOTIATE) |
27871 |
+- aux_max = 0; |
27872 |
++ aux_max = 1; |
27873 |
+ else |
27874 |
+- aux_max = conn->max_credits - credit_charge; |
27875 |
+- aux_credits = min_t(unsigned short, aux_credits, aux_max); |
27876 |
+- credits_granted = credit_charge + aux_credits; |
27877 |
++ aux_max = conn->vals->max_credits - credit_charge; |
27878 |
++ credits_granted = min_t(unsigned short, credits_requested, aux_max); |
27879 |
+ |
27880 |
+- if (conn->max_credits - conn->total_credits < credits_granted) |
27881 |
+- credits_granted = conn->max_credits - |
27882 |
++ if (conn->vals->max_credits - conn->total_credits < credits_granted) |
27883 |
++ credits_granted = conn->vals->max_credits - |
27884 |
+ conn->total_credits; |
27885 |
+ |
27886 |
+ conn->total_credits += credits_granted; |
27887 |
+@@ -1457,11 +1462,6 @@ static int ntlm_authenticate(struct ksmbd_work *work) |
27888 |
+ |
27889 |
+ sess->user = user; |
27890 |
+ if (user_guest(sess->user)) { |
27891 |
+- if (conn->sign) { |
27892 |
+- ksmbd_debug(SMB, "Guest login not allowed when signing enabled\n"); |
27893 |
+- return -EPERM; |
27894 |
+- } |
27895 |
+- |
27896 |
+ rsp->SessionFlags = SMB2_SESSION_FLAG_IS_GUEST_LE; |
27897 |
+ } else { |
27898 |
+ struct authenticate_message *authblob; |
27899 |
+@@ -1474,38 +1474,39 @@ static int ntlm_authenticate(struct ksmbd_work *work) |
27900 |
+ ksmbd_debug(SMB, "authentication failed\n"); |
27901 |
+ return -EPERM; |
27902 |
+ } |
27903 |
++ } |
27904 |
+ |
27905 |
+- /* |
27906 |
+- * If session state is SMB2_SESSION_VALID, We can assume |
27907 |
+- * that it is reauthentication. And the user/password |
27908 |
+- * has been verified, so return it here. |
27909 |
+- */ |
27910 |
+- if (sess->state == SMB2_SESSION_VALID) { |
27911 |
+- if (conn->binding) |
27912 |
+- goto binding_session; |
27913 |
+- return 0; |
27914 |
+- } |
27915 |
++ /* |
27916 |
++ * If session state is SMB2_SESSION_VALID, We can assume |
27917 |
++ * that it is reauthentication. And the user/password |
27918 |
++ * has been verified, so return it here. |
27919 |
++ */ |
27920 |
++ if (sess->state == SMB2_SESSION_VALID) { |
27921 |
++ if (conn->binding) |
27922 |
++ goto binding_session; |
27923 |
++ return 0; |
27924 |
++ } |
27925 |
+ |
27926 |
+- if ((conn->sign || server_conf.enforced_signing) || |
27927 |
+- (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED)) |
27928 |
+- sess->sign = true; |
27929 |
++ if ((rsp->SessionFlags != SMB2_SESSION_FLAG_IS_GUEST_LE && |
27930 |
++ (conn->sign || server_conf.enforced_signing)) || |
27931 |
++ (req->SecurityMode & SMB2_NEGOTIATE_SIGNING_REQUIRED)) |
27932 |
++ sess->sign = true; |
27933 |
+ |
27934 |
+- if (smb3_encryption_negotiated(conn) && |
27935 |
+- !(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) { |
27936 |
+- rc = conn->ops->generate_encryptionkey(sess); |
27937 |
+- if (rc) { |
27938 |
+- ksmbd_debug(SMB, |
27939 |
+- "SMB3 encryption key generation failed\n"); |
27940 |
+- return -EINVAL; |
27941 |
+- } |
27942 |
+- sess->enc = true; |
27943 |
+- rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE; |
27944 |
+- /* |
27945 |
+- * signing is disable if encryption is enable |
27946 |
+- * on this session |
27947 |
+- */ |
27948 |
+- sess->sign = false; |
27949 |
++ if (smb3_encryption_negotiated(conn) && |
27950 |
++ !(req->Flags & SMB2_SESSION_REQ_FLAG_BINDING)) { |
27951 |
++ rc = conn->ops->generate_encryptionkey(sess); |
27952 |
++ if (rc) { |
27953 |
++ ksmbd_debug(SMB, |
27954 |
++ "SMB3 encryption key generation failed\n"); |
27955 |
++ return -EINVAL; |
27956 |
+ } |
27957 |
++ sess->enc = true; |
27958 |
++ rsp->SessionFlags = SMB2_SESSION_FLAG_ENCRYPT_DATA_LE; |
27959 |
++ /* |
27960 |
++ * signing is disable if encryption is enable |
27961 |
++ * on this session |
27962 |
++ */ |
27963 |
++ sess->sign = false; |
27964 |
+ } |
27965 |
+ |
27966 |
+ binding_session: |
27967 |
+diff --git a/fs/ksmbd/smb2pdu.h b/fs/ksmbd/smb2pdu.h |
27968 |
+index ff5a2f01d34ae..4f8574944ac19 100644 |
27969 |
+--- a/fs/ksmbd/smb2pdu.h |
27970 |
++++ b/fs/ksmbd/smb2pdu.h |
27971 |
+@@ -1647,6 +1647,7 @@ int init_smb3_11_server(struct ksmbd_conn *conn); |
27972 |
+ void init_smb2_max_read_size(unsigned int sz); |
27973 |
+ void init_smb2_max_write_size(unsigned int sz); |
27974 |
+ void init_smb2_max_trans_size(unsigned int sz); |
27975 |
++void init_smb2_max_credits(unsigned int sz); |
27976 |
+ |
27977 |
+ bool is_smb2_neg_cmd(struct ksmbd_work *work); |
27978 |
+ bool is_smb2_rsp(struct ksmbd_work *work); |
27979 |
+diff --git a/fs/ksmbd/smb_common.h b/fs/ksmbd/smb_common.h |
27980 |
+index 6e79e7577f6b7..1eba8dabaf317 100644 |
27981 |
+--- a/fs/ksmbd/smb_common.h |
27982 |
++++ b/fs/ksmbd/smb_common.h |
27983 |
+@@ -412,6 +412,7 @@ struct smb_version_values { |
27984 |
+ __u32 max_read_size; |
27985 |
+ __u32 max_write_size; |
27986 |
+ __u32 max_trans_size; |
27987 |
++ __u32 max_credits; |
27988 |
+ __u32 large_lock_type; |
27989 |
+ __u32 exclusive_lock_type; |
27990 |
+ __u32 shared_lock_type; |
27991 |
+diff --git a/fs/ksmbd/transport_ipc.c b/fs/ksmbd/transport_ipc.c |
27992 |
+index 1acf1892a466c..3ad6881e0f7ed 100644 |
27993 |
+--- a/fs/ksmbd/transport_ipc.c |
27994 |
++++ b/fs/ksmbd/transport_ipc.c |
27995 |
+@@ -301,6 +301,8 @@ static int ipc_server_config_on_startup(struct ksmbd_startup_request *req) |
27996 |
+ init_smb2_max_write_size(req->smb2_max_write); |
27997 |
+ if (req->smb2_max_trans) |
27998 |
+ init_smb2_max_trans_size(req->smb2_max_trans); |
27999 |
++ if (req->smb2_max_credits) |
28000 |
++ init_smb2_max_credits(req->smb2_max_credits); |
28001 |
+ |
28002 |
+ ret = ksmbd_set_netbios_name(req->netbios_name); |
28003 |
+ ret |= ksmbd_set_server_string(req->server_string); |
28004 |
+diff --git a/fs/ksmbd/transport_tcp.c b/fs/ksmbd/transport_tcp.c |
28005 |
+index c14320e03b698..82a1429bbe127 100644 |
28006 |
+--- a/fs/ksmbd/transport_tcp.c |
28007 |
++++ b/fs/ksmbd/transport_tcp.c |
28008 |
+@@ -404,7 +404,7 @@ static int create_socket(struct interface *iface) |
28009 |
+ &ksmbd_socket); |
28010 |
+ if (ret) { |
28011 |
+ pr_err("Can't create socket for ipv4: %d\n", ret); |
28012 |
+- goto out_error; |
28013 |
++ goto out_clear; |
28014 |
+ } |
28015 |
+ |
28016 |
+ sin.sin_family = PF_INET; |
28017 |
+@@ -462,6 +462,7 @@ static int create_socket(struct interface *iface) |
28018 |
+ |
28019 |
+ out_error: |
28020 |
+ tcp_destroy_socket(ksmbd_socket); |
28021 |
++out_clear: |
28022 |
+ iface->ksmbd_socket = NULL; |
28023 |
+ return ret; |
28024 |
+ } |
28025 |
+diff --git a/fs/ubifs/super.c b/fs/ubifs/super.c |
28026 |
+index f0fb25727d961..eb05038b71911 100644 |
28027 |
+--- a/fs/ubifs/super.c |
28028 |
++++ b/fs/ubifs/super.c |
28029 |
+@@ -1853,7 +1853,6 @@ out: |
28030 |
+ kthread_stop(c->bgt); |
28031 |
+ c->bgt = NULL; |
28032 |
+ } |
28033 |
+- free_wbufs(c); |
28034 |
+ kfree(c->write_reserve_buf); |
28035 |
+ c->write_reserve_buf = NULL; |
28036 |
+ vfree(c->ileb_buf); |
28037 |
+diff --git a/fs/udf/ialloc.c b/fs/udf/ialloc.c |
28038 |
+index 2ecf0e87660e3..b5d611cee749c 100644 |
28039 |
+--- a/fs/udf/ialloc.c |
28040 |
++++ b/fs/udf/ialloc.c |
28041 |
+@@ -77,6 +77,7 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode) |
28042 |
+ GFP_KERNEL); |
28043 |
+ } |
28044 |
+ if (!iinfo->i_data) { |
28045 |
++ make_bad_inode(inode); |
28046 |
+ iput(inode); |
28047 |
+ return ERR_PTR(-ENOMEM); |
28048 |
+ } |
28049 |
+@@ -86,6 +87,7 @@ struct inode *udf_new_inode(struct inode *dir, umode_t mode) |
28050 |
+ dinfo->i_location.partitionReferenceNum, |
28051 |
+ start, &err); |
28052 |
+ if (err) { |
28053 |
++ make_bad_inode(inode); |
28054 |
+ iput(inode); |
28055 |
+ return ERR_PTR(err); |
28056 |
+ } |
28057 |
+diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h |
28058 |
+index 13d93371790ec..e9c7d7b270e73 100644 |
28059 |
+--- a/include/acpi/acpi_bus.h |
28060 |
++++ b/include/acpi/acpi_bus.h |
28061 |
+@@ -613,9 +613,10 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev, int state); |
28062 |
+ int acpi_disable_wakeup_device_power(struct acpi_device *dev); |
28063 |
+ |
28064 |
+ #ifdef CONFIG_X86 |
28065 |
+-bool acpi_device_always_present(struct acpi_device *adev); |
28066 |
++bool acpi_device_override_status(struct acpi_device *adev, unsigned long long *status); |
28067 |
+ #else |
28068 |
+-static inline bool acpi_device_always_present(struct acpi_device *adev) |
28069 |
++static inline bool acpi_device_override_status(struct acpi_device *adev, |
28070 |
++ unsigned long long *status) |
28071 |
+ { |
28072 |
+ return false; |
28073 |
+ } |
28074 |
+diff --git a/include/acpi/actypes.h b/include/acpi/actypes.h |
28075 |
+index 92c71dfce0d5d..cefbb7ad253e0 100644 |
28076 |
+--- a/include/acpi/actypes.h |
28077 |
++++ b/include/acpi/actypes.h |
28078 |
+@@ -536,8 +536,14 @@ typedef u64 acpi_integer; |
28079 |
+ * Can be used with access_width of struct acpi_generic_address and access_size of |
28080 |
+ * struct acpi_resource_generic_register. |
28081 |
+ */ |
28082 |
+-#define ACPI_ACCESS_BIT_WIDTH(size) (1 << ((size) + 2)) |
28083 |
+-#define ACPI_ACCESS_BYTE_WIDTH(size) (1 << ((size) - 1)) |
28084 |
++#define ACPI_ACCESS_BIT_SHIFT 2 |
28085 |
++#define ACPI_ACCESS_BYTE_SHIFT -1 |
28086 |
++#define ACPI_ACCESS_BIT_MAX (31 - ACPI_ACCESS_BIT_SHIFT) |
28087 |
++#define ACPI_ACCESS_BYTE_MAX (31 - ACPI_ACCESS_BYTE_SHIFT) |
28088 |
++#define ACPI_ACCESS_BIT_DEFAULT (8 - ACPI_ACCESS_BIT_SHIFT) |
28089 |
++#define ACPI_ACCESS_BYTE_DEFAULT (8 - ACPI_ACCESS_BYTE_SHIFT) |
28090 |
++#define ACPI_ACCESS_BIT_WIDTH(size) (1 << ((size) + ACPI_ACCESS_BIT_SHIFT)) |
28091 |
++#define ACPI_ACCESS_BYTE_WIDTH(size) (1 << ((size) + ACPI_ACCESS_BYTE_SHIFT)) |
28092 |
+ |
28093 |
+ /******************************************************************************* |
28094 |
+ * |
28095 |
+diff --git a/include/asm-generic/bitops/find.h b/include/asm-generic/bitops/find.h |
28096 |
+index 0d132ee2a2913..835f959a25f25 100644 |
28097 |
+--- a/include/asm-generic/bitops/find.h |
28098 |
++++ b/include/asm-generic/bitops/find.h |
28099 |
+@@ -97,6 +97,7 @@ unsigned long find_next_zero_bit(const unsigned long *addr, unsigned long size, |
28100 |
+ |
28101 |
+ #ifdef CONFIG_GENERIC_FIND_FIRST_BIT |
28102 |
+ |
28103 |
++#ifndef find_first_bit |
28104 |
+ /** |
28105 |
+ * find_first_bit - find the first set bit in a memory region |
28106 |
+ * @addr: The address to start the search at |
28107 |
+@@ -116,7 +117,9 @@ unsigned long find_first_bit(const unsigned long *addr, unsigned long size) |
28108 |
+ |
28109 |
+ return _find_first_bit(addr, size); |
28110 |
+ } |
28111 |
++#endif |
28112 |
+ |
28113 |
++#ifndef find_first_zero_bit |
28114 |
+ /** |
28115 |
+ * find_first_zero_bit - find the first cleared bit in a memory region |
28116 |
+ * @addr: The address to start the search at |
28117 |
+@@ -136,6 +139,8 @@ unsigned long find_first_zero_bit(const unsigned long *addr, unsigned long size) |
28118 |
+ |
28119 |
+ return _find_first_zero_bit(addr, size); |
28120 |
+ } |
28121 |
++#endif |
28122 |
++ |
28123 |
+ #else /* CONFIG_GENERIC_FIND_FIRST_BIT */ |
28124 |
+ |
28125 |
+ #ifndef find_first_bit |
28126 |
+diff --git a/include/linux/blk-pm.h b/include/linux/blk-pm.h |
28127 |
+index b80c65aba2493..2580e05a8ab67 100644 |
28128 |
+--- a/include/linux/blk-pm.h |
28129 |
++++ b/include/linux/blk-pm.h |
28130 |
+@@ -14,7 +14,7 @@ extern void blk_pm_runtime_init(struct request_queue *q, struct device *dev); |
28131 |
+ extern int blk_pre_runtime_suspend(struct request_queue *q); |
28132 |
+ extern void blk_post_runtime_suspend(struct request_queue *q, int err); |
28133 |
+ extern void blk_pre_runtime_resume(struct request_queue *q); |
28134 |
+-extern void blk_post_runtime_resume(struct request_queue *q, int err); |
28135 |
++extern void blk_post_runtime_resume(struct request_queue *q); |
28136 |
+ extern void blk_set_runtime_active(struct request_queue *q); |
28137 |
+ #else |
28138 |
+ static inline void blk_pm_runtime_init(struct request_queue *q, |
28139 |
+diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h |
28140 |
+index 5424124dbe365..364550dd19c4a 100644 |
28141 |
+--- a/include/linux/bpf_verifier.h |
28142 |
++++ b/include/linux/bpf_verifier.h |
28143 |
+@@ -396,6 +396,13 @@ static inline bool bpf_verifier_log_needed(const struct bpf_verifier_log *log) |
28144 |
+ log->level == BPF_LOG_KERNEL); |
28145 |
+ } |
28146 |
+ |
28147 |
++static inline bool |
28148 |
++bpf_verifier_log_attr_valid(const struct bpf_verifier_log *log) |
28149 |
++{ |
28150 |
++ return log->len_total >= 128 && log->len_total <= UINT_MAX >> 2 && |
28151 |
++ log->level && log->ubuf && !(log->level & ~BPF_LOG_MASK); |
28152 |
++} |
28153 |
++ |
28154 |
+ #define BPF_MAX_SUBPROGS 256 |
28155 |
+ |
28156 |
+ struct bpf_subprog_info { |
28157 |
+diff --git a/include/linux/hid.h b/include/linux/hid.h |
28158 |
+index f453be385bd47..26742ca14609a 100644 |
28159 |
+--- a/include/linux/hid.h |
28160 |
++++ b/include/linux/hid.h |
28161 |
+@@ -349,6 +349,8 @@ struct hid_item { |
28162 |
+ /* BIT(9) reserved for backward compatibility, was NO_INIT_INPUT_REPORTS */ |
28163 |
+ #define HID_QUIRK_ALWAYS_POLL BIT(10) |
28164 |
+ #define HID_QUIRK_INPUT_PER_APP BIT(11) |
28165 |
++#define HID_QUIRK_X_INVERT BIT(12) |
28166 |
++#define HID_QUIRK_Y_INVERT BIT(13) |
28167 |
+ #define HID_QUIRK_SKIP_OUTPUT_REPORTS BIT(16) |
28168 |
+ #define HID_QUIRK_SKIP_OUTPUT_REPORT_ID BIT(17) |
28169 |
+ #define HID_QUIRK_NO_OUTPUT_REPORTS_ON_INTR_EP BIT(18) |
28170 |
+diff --git a/include/linux/iio/trigger.h b/include/linux/iio/trigger.h |
28171 |
+index 096f68dd2e0ca..4c69b144677b1 100644 |
28172 |
+--- a/include/linux/iio/trigger.h |
28173 |
++++ b/include/linux/iio/trigger.h |
28174 |
+@@ -55,6 +55,7 @@ struct iio_trigger_ops { |
28175 |
+ * @attached_own_device:[INTERN] if we are using our own device as trigger, |
28176 |
+ * i.e. if we registered a poll function to the same |
28177 |
+ * device as the one providing the trigger. |
28178 |
++ * @reenable_work: [INTERN] work item used to ensure reenable can sleep. |
28179 |
+ **/ |
28180 |
+ struct iio_trigger { |
28181 |
+ const struct iio_trigger_ops *ops; |
28182 |
+@@ -74,6 +75,7 @@ struct iio_trigger { |
28183 |
+ unsigned long pool[BITS_TO_LONGS(CONFIG_IIO_CONSUMERS_PER_TRIGGER)]; |
28184 |
+ struct mutex pool_lock; |
28185 |
+ bool attached_own_device; |
28186 |
++ struct work_struct reenable_work; |
28187 |
+ }; |
28188 |
+ |
28189 |
+ |
28190 |
+diff --git a/include/linux/ipv6.h b/include/linux/ipv6.h |
28191 |
+index c383630d3f065..07cba0b3496d5 100644 |
28192 |
+--- a/include/linux/ipv6.h |
28193 |
++++ b/include/linux/ipv6.h |
28194 |
+@@ -132,6 +132,7 @@ struct inet6_skb_parm { |
28195 |
+ __u16 dsthao; |
28196 |
+ #endif |
28197 |
+ __u16 frag_max_size; |
28198 |
++ __u16 srhoff; |
28199 |
+ |
28200 |
+ #define IP6SKB_XFRM_TRANSFORMED 1 |
28201 |
+ #define IP6SKB_FORWARDED 2 |
28202 |
+@@ -141,6 +142,7 @@ struct inet6_skb_parm { |
28203 |
+ #define IP6SKB_HOPBYHOP 32 |
28204 |
+ #define IP6SKB_L3SLAVE 64 |
28205 |
+ #define IP6SKB_JUMBOGRAM 128 |
28206 |
++#define IP6SKB_SEG6 256 |
28207 |
+ }; |
28208 |
+ |
28209 |
+ #if defined(CONFIG_NET_L3_MASTER_DEV) |
28210 |
+diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h |
28211 |
+index 6a1d79d84675a..fa1ef98614bcb 100644 |
28212 |
+--- a/include/linux/mmzone.h |
28213 |
++++ b/include/linux/mmzone.h |
28214 |
+@@ -1031,6 +1031,15 @@ static inline int is_highmem_idx(enum zone_type idx) |
28215 |
+ #endif |
28216 |
+ } |
28217 |
+ |
28218 |
++#ifdef CONFIG_ZONE_DMA |
28219 |
++bool has_managed_dma(void); |
28220 |
++#else |
28221 |
++static inline bool has_managed_dma(void) |
28222 |
++{ |
28223 |
++ return false; |
28224 |
++} |
28225 |
++#endif |
28226 |
++ |
28227 |
+ /** |
28228 |
+ * is_highmem - helper function to quickly check if a struct zone is a |
28229 |
+ * highmem zone or not. This is an attempt to keep references |
28230 |
+diff --git a/include/linux/mtd/rawnand.h b/include/linux/mtd/rawnand.h |
28231 |
+index b2f9dd3cbd695..5b88cd51fadb5 100644 |
28232 |
+--- a/include/linux/mtd/rawnand.h |
28233 |
++++ b/include/linux/mtd/rawnand.h |
28234 |
+@@ -1539,6 +1539,8 @@ int nand_read_data_op(struct nand_chip *chip, void *buf, unsigned int len, |
28235 |
+ bool force_8bit, bool check_only); |
28236 |
+ int nand_write_data_op(struct nand_chip *chip, const void *buf, |
28237 |
+ unsigned int len, bool force_8bit); |
28238 |
++int nand_read_page_hwecc_oob_first(struct nand_chip *chip, uint8_t *buf, |
28239 |
++ int oob_required, int page); |
28240 |
+ |
28241 |
+ /* Scan and identify a NAND device */ |
28242 |
+ int nand_scan_with_ids(struct nand_chip *chip, unsigned int max_chips, |
28243 |
+diff --git a/include/linux/of_fdt.h b/include/linux/of_fdt.h |
28244 |
+index cf6a65b94d40e..6508b97dbf1d2 100644 |
28245 |
+--- a/include/linux/of_fdt.h |
28246 |
++++ b/include/linux/of_fdt.h |
28247 |
+@@ -62,6 +62,7 @@ extern int early_init_dt_scan_chosen(unsigned long node, const char *uname, |
28248 |
+ int depth, void *data); |
28249 |
+ extern int early_init_dt_scan_memory(unsigned long node, const char *uname, |
28250 |
+ int depth, void *data); |
28251 |
++extern void early_init_dt_check_for_usable_mem_range(void); |
28252 |
+ extern int early_init_dt_scan_chosen_stdout(void); |
28253 |
+ extern void early_init_fdt_scan_reserved_mem(void); |
28254 |
+ extern void early_init_fdt_reserve_self(void); |
28255 |
+@@ -87,6 +88,7 @@ extern void unflatten_and_copy_device_tree(void); |
28256 |
+ extern void early_init_devtree(void *); |
28257 |
+ extern void early_get_first_memblock_info(void *, phys_addr_t *); |
28258 |
+ #else /* CONFIG_OF_EARLY_FLATTREE */ |
28259 |
++static inline void early_init_dt_check_for_usable_mem_range(void) {} |
28260 |
+ static inline int early_init_dt_scan_chosen_stdout(void) { return -ENODEV; } |
28261 |
+ static inline void early_init_fdt_scan_reserved_mem(void) {} |
28262 |
+ static inline void early_init_fdt_reserve_self(void) {} |
28263 |
+diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h |
28264 |
+index eddd66d426caf..016de5776b6db 100644 |
28265 |
+--- a/include/linux/pm_runtime.h |
28266 |
++++ b/include/linux/pm_runtime.h |
28267 |
+@@ -58,6 +58,7 @@ extern void pm_runtime_get_suppliers(struct device *dev); |
28268 |
+ extern void pm_runtime_put_suppliers(struct device *dev); |
28269 |
+ extern void pm_runtime_new_link(struct device *dev); |
28270 |
+ extern void pm_runtime_drop_link(struct device_link *link); |
28271 |
++extern void pm_runtime_release_supplier(struct device_link *link, bool check_idle); |
28272 |
+ |
28273 |
+ extern int devm_pm_runtime_enable(struct device *dev); |
28274 |
+ |
28275 |
+@@ -283,6 +284,8 @@ static inline void pm_runtime_get_suppliers(struct device *dev) {} |
28276 |
+ static inline void pm_runtime_put_suppliers(struct device *dev) {} |
28277 |
+ static inline void pm_runtime_new_link(struct device *dev) {} |
28278 |
+ static inline void pm_runtime_drop_link(struct device_link *link) {} |
28279 |
++static inline void pm_runtime_release_supplier(struct device_link *link, |
28280 |
++ bool check_idle) {} |
28281 |
+ |
28282 |
+ #endif /* !CONFIG_PM */ |
28283 |
+ |
28284 |
+diff --git a/include/linux/psi_types.h b/include/linux/psi_types.h |
28285 |
+index 0a23300d49af7..0819c82dba920 100644 |
28286 |
+--- a/include/linux/psi_types.h |
28287 |
++++ b/include/linux/psi_types.h |
28288 |
+@@ -21,7 +21,17 @@ enum psi_task_count { |
28289 |
+ * don't have to special case any state tracking for it. |
28290 |
+ */ |
28291 |
+ NR_ONCPU, |
28292 |
+- NR_PSI_TASK_COUNTS = 4, |
28293 |
++ /* |
28294 |
++ * For IO and CPU stalls the presence of running/oncpu tasks |
28295 |
++ * in the domain means a partial rather than a full stall. |
28296 |
++ * For memory it's not so simple because of page reclaimers: |
28297 |
++ * they are running/oncpu while representing a stall. To tell |
28298 |
++ * whether a domain has productivity left or not, we need to |
28299 |
++ * distinguish between regular running (i.e. productive) |
28300 |
++ * threads and memstall ones. |
28301 |
++ */ |
28302 |
++ NR_MEMSTALL_RUNNING, |
28303 |
++ NR_PSI_TASK_COUNTS = 5, |
28304 |
+ }; |
28305 |
+ |
28306 |
+ /* Task state bitmasks */ |
28307 |
+@@ -29,6 +39,7 @@ enum psi_task_count { |
28308 |
+ #define TSK_MEMSTALL (1 << NR_MEMSTALL) |
28309 |
+ #define TSK_RUNNING (1 << NR_RUNNING) |
28310 |
+ #define TSK_ONCPU (1 << NR_ONCPU) |
28311 |
++#define TSK_MEMSTALL_RUNNING (1 << NR_MEMSTALL_RUNNING) |
28312 |
+ |
28313 |
+ /* Resources that workloads could be stalled on */ |
28314 |
+ enum psi_res { |
28315 |
+diff --git a/include/linux/ptp_clock_kernel.h b/include/linux/ptp_clock_kernel.h |
28316 |
+index 2e5565067355b..554454cb86931 100644 |
28317 |
+--- a/include/linux/ptp_clock_kernel.h |
28318 |
++++ b/include/linux/ptp_clock_kernel.h |
28319 |
+@@ -351,15 +351,17 @@ int ptp_get_vclocks_index(int pclock_index, int **vclock_index); |
28320 |
+ * |
28321 |
+ * @hwtstamps: skb_shared_hwtstamps structure pointer |
28322 |
+ * @vclock_index: phc index of ptp vclock. |
28323 |
++ * |
28324 |
++ * Returns converted timestamp, or 0 on error. |
28325 |
+ */ |
28326 |
+-void ptp_convert_timestamp(struct skb_shared_hwtstamps *hwtstamps, |
28327 |
+- int vclock_index); |
28328 |
++ktime_t ptp_convert_timestamp(const struct skb_shared_hwtstamps *hwtstamps, |
28329 |
++ int vclock_index); |
28330 |
+ #else |
28331 |
+ static inline int ptp_get_vclocks_index(int pclock_index, int **vclock_index) |
28332 |
+ { return 0; } |
28333 |
+-static inline void ptp_convert_timestamp(struct skb_shared_hwtstamps *hwtstamps, |
28334 |
+- int vclock_index) |
28335 |
+-{ } |
28336 |
++static inline ktime_t ptp_convert_timestamp(const struct skb_shared_hwtstamps *hwtstamps, |
28337 |
++ int vclock_index) |
28338 |
++{ return 0; } |
28339 |
+ |
28340 |
+ #endif |
28341 |
+ |
28342 |
+diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h |
28343 |
+index b8c273af2910c..532f5d402f060 100644 |
28344 |
+--- a/include/linux/skbuff.h |
28345 |
++++ b/include/linux/skbuff.h |
28346 |
+@@ -286,7 +286,10 @@ struct nf_bridge_info { |
28347 |
+ struct tc_skb_ext { |
28348 |
+ __u32 chain; |
28349 |
+ __u16 mru; |
28350 |
+- bool post_ct; |
28351 |
++ __u16 zone; |
28352 |
++ u8 post_ct:1; |
28353 |
++ u8 post_ct_snat:1; |
28354 |
++ u8 post_ct_dnat:1; |
28355 |
+ }; |
28356 |
+ #endif |
28357 |
+ |
28358 |
+@@ -1370,7 +1373,7 @@ skb_flow_dissect_ct(const struct sk_buff *skb, |
28359 |
+ struct flow_dissector *flow_dissector, |
28360 |
+ void *target_container, |
28361 |
+ u16 *ctinfo_map, size_t mapsize, |
28362 |
+- bool post_ct); |
28363 |
++ bool post_ct, u16 zone); |
28364 |
+ void |
28365 |
+ skb_flow_dissect_tunnel_info(const struct sk_buff *skb, |
28366 |
+ struct flow_dissector *flow_dissector, |
28367 |
+diff --git a/include/linux/stmmac.h b/include/linux/stmmac.h |
28368 |
+index a6f03b36fc4f7..1450397fc0bcd 100644 |
28369 |
+--- a/include/linux/stmmac.h |
28370 |
++++ b/include/linux/stmmac.h |
28371 |
+@@ -233,6 +233,7 @@ struct plat_stmmacenet_data { |
28372 |
+ int (*clks_config)(void *priv, bool enabled); |
28373 |
+ int (*crosststamp)(ktime_t *device, struct system_counterval_t *system, |
28374 |
+ void *ctx); |
28375 |
++ void (*dump_debug_regs)(void *priv); |
28376 |
+ void *bsp_priv; |
28377 |
+ struct clk *stmmac_clk; |
28378 |
+ struct clk *pclk; |
28379 |
+diff --git a/include/media/cec.h b/include/media/cec.h |
28380 |
+index 208c9613c07eb..77346f757036d 100644 |
28381 |
+--- a/include/media/cec.h |
28382 |
++++ b/include/media/cec.h |
28383 |
+@@ -26,13 +26,17 @@ |
28384 |
+ * @dev: cec device |
28385 |
+ * @cdev: cec character device |
28386 |
+ * @minor: device node minor number |
28387 |
++ * @lock: lock to serialize open/release and registration |
28388 |
+ * @registered: the device was correctly registered |
28389 |
+ * @unregistered: the device was unregistered |
28390 |
++ * @lock_fhs: lock to control access to @fhs |
28391 |
+ * @fhs: the list of open filehandles (cec_fh) |
28392 |
+- * @lock: lock to control access to this structure |
28393 |
+ * |
28394 |
+ * This structure represents a cec-related device node. |
28395 |
+ * |
28396 |
++ * To add or remove filehandles from @fhs the @lock must be taken first, |
28397 |
++ * followed by @lock_fhs. It is safe to access @fhs if either lock is held. |
28398 |
++ * |
28399 |
+ * The @parent is a physical device. It must be set by core or device drivers |
28400 |
+ * before registering the node. |
28401 |
+ */ |
28402 |
+@@ -43,10 +47,13 @@ struct cec_devnode { |
28403 |
+ |
28404 |
+ /* device info */ |
28405 |
+ int minor; |
28406 |
++ /* serialize open/release and registration */ |
28407 |
++ struct mutex lock; |
28408 |
+ bool registered; |
28409 |
+ bool unregistered; |
28410 |
++ /* protect access to fhs */ |
28411 |
++ struct mutex lock_fhs; |
28412 |
+ struct list_head fhs; |
28413 |
+- struct mutex lock; |
28414 |
+ }; |
28415 |
+ |
28416 |
+ struct cec_adapter; |
28417 |
+diff --git a/include/net/inet_frag.h b/include/net/inet_frag.h |
28418 |
+index 48cc5795ceda6..63540be0fc34a 100644 |
28419 |
+--- a/include/net/inet_frag.h |
28420 |
++++ b/include/net/inet_frag.h |
28421 |
+@@ -117,8 +117,15 @@ int fqdir_init(struct fqdir **fqdirp, struct inet_frags *f, struct net *net); |
28422 |
+ |
28423 |
+ static inline void fqdir_pre_exit(struct fqdir *fqdir) |
28424 |
+ { |
28425 |
+- fqdir->high_thresh = 0; /* prevent creation of new frags */ |
28426 |
+- fqdir->dead = true; |
28427 |
++ /* Prevent creation of new frags. |
28428 |
++ * Pairs with READ_ONCE() in inet_frag_find(). |
28429 |
++ */ |
28430 |
++ WRITE_ONCE(fqdir->high_thresh, 0); |
28431 |
++ |
28432 |
++ /* Pairs with READ_ONCE() in inet_frag_kill(), ip_expire() |
28433 |
++ * and ip6frag_expire_frag_queue(). |
28434 |
++ */ |
28435 |
++ WRITE_ONCE(fqdir->dead, true); |
28436 |
+ } |
28437 |
+ void fqdir_exit(struct fqdir *fqdir); |
28438 |
+ |
28439 |
+diff --git a/include/net/ipv6_frag.h b/include/net/ipv6_frag.h |
28440 |
+index 851029ecff13c..0a4779175a523 100644 |
28441 |
+--- a/include/net/ipv6_frag.h |
28442 |
++++ b/include/net/ipv6_frag.h |
28443 |
+@@ -67,7 +67,8 @@ ip6frag_expire_frag_queue(struct net *net, struct frag_queue *fq) |
28444 |
+ struct sk_buff *head; |
28445 |
+ |
28446 |
+ rcu_read_lock(); |
28447 |
+- if (fq->q.fqdir->dead) |
28448 |
++ /* Paired with the WRITE_ONCE() in fqdir_pre_exit(). */ |
28449 |
++ if (READ_ONCE(fq->q.fqdir->dead)) |
28450 |
+ goto out_rcu_unlock; |
28451 |
+ spin_lock(&fq->q.lock); |
28452 |
+ |
28453 |
+diff --git a/include/net/pkt_sched.h b/include/net/pkt_sched.h |
28454 |
+index 05f18e81f3e87..9e7b21c0b3a6d 100644 |
28455 |
+--- a/include/net/pkt_sched.h |
28456 |
++++ b/include/net/pkt_sched.h |
28457 |
+@@ -197,7 +197,10 @@ struct tc_skb_cb { |
28458 |
+ struct qdisc_skb_cb qdisc_cb; |
28459 |
+ |
28460 |
+ u16 mru; |
28461 |
+- bool post_ct; |
28462 |
++ u8 post_ct:1; |
28463 |
++ u8 post_ct_snat:1; |
28464 |
++ u8 post_ct_dnat:1; |
28465 |
++ u16 zone; /* Only valid if post_ct = true */ |
28466 |
+ }; |
28467 |
+ |
28468 |
+ static inline struct tc_skb_cb *tc_skb_cb(const struct sk_buff *skb) |
28469 |
+diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h |
28470 |
+index 6e7cd00333577..4121ffd0faf8f 100644 |
28471 |
+--- a/include/net/sch_generic.h |
28472 |
++++ b/include/net/sch_generic.h |
28473 |
+@@ -1260,6 +1260,7 @@ struct psched_ratecfg { |
28474 |
+ u64 rate_bytes_ps; /* bytes per second */ |
28475 |
+ u32 mult; |
28476 |
+ u16 overhead; |
28477 |
++ u16 mpu; |
28478 |
+ u8 linklayer; |
28479 |
+ u8 shift; |
28480 |
+ }; |
28481 |
+@@ -1269,6 +1270,9 @@ static inline u64 psched_l2t_ns(const struct psched_ratecfg *r, |
28482 |
+ { |
28483 |
+ len += r->overhead; |
28484 |
+ |
28485 |
++ if (len < r->mpu) |
28486 |
++ len = r->mpu; |
28487 |
++ |
28488 |
+ if (unlikely(r->linklayer == TC_LINKLAYER_ATM)) |
28489 |
+ return ((u64)(DIV_ROUND_UP(len,48)*53) * r->mult) >> r->shift; |
28490 |
+ |
28491 |
+@@ -1291,6 +1295,7 @@ static inline void psched_ratecfg_getrate(struct tc_ratespec *res, |
28492 |
+ res->rate = min_t(u64, r->rate_bytes_ps, ~0U); |
28493 |
+ |
28494 |
+ res->overhead = r->overhead; |
28495 |
++ res->mpu = r->mpu; |
28496 |
+ res->linklayer = (r->linklayer & TC_LINKLAYER_MASK); |
28497 |
+ } |
28498 |
+ |
28499 |
+diff --git a/include/net/seg6.h b/include/net/seg6.h |
28500 |
+index 9d19c15e8545c..af668f17b3988 100644 |
28501 |
+--- a/include/net/seg6.h |
28502 |
++++ b/include/net/seg6.h |
28503 |
+@@ -58,9 +58,30 @@ extern int seg6_local_init(void); |
28504 |
+ extern void seg6_local_exit(void); |
28505 |
+ |
28506 |
+ extern bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len, bool reduced); |
28507 |
++extern struct ipv6_sr_hdr *seg6_get_srh(struct sk_buff *skb, int flags); |
28508 |
++extern void seg6_icmp_srh(struct sk_buff *skb, struct inet6_skb_parm *opt); |
28509 |
+ extern int seg6_do_srh_encap(struct sk_buff *skb, struct ipv6_sr_hdr *osrh, |
28510 |
+ int proto); |
28511 |
+ extern int seg6_do_srh_inline(struct sk_buff *skb, struct ipv6_sr_hdr *osrh); |
28512 |
+ extern int seg6_lookup_nexthop(struct sk_buff *skb, struct in6_addr *nhaddr, |
28513 |
+ u32 tbl_id); |
28514 |
++ |
28515 |
++/* If the packet which invoked an ICMP error contains an SRH return |
28516 |
++ * the true destination address from within the SRH, otherwise use the |
28517 |
++ * destination address in the IP header. |
28518 |
++ */ |
28519 |
++static inline const struct in6_addr *seg6_get_daddr(struct sk_buff *skb, |
28520 |
++ struct inet6_skb_parm *opt) |
28521 |
++{ |
28522 |
++ struct ipv6_sr_hdr *srh; |
28523 |
++ |
28524 |
++ if (opt->flags & IP6SKB_SEG6) { |
28525 |
++ srh = (struct ipv6_sr_hdr *)(skb->data + opt->srhoff); |
28526 |
++ return &srh->segments[0]; |
28527 |
++ } |
28528 |
++ |
28529 |
++ return NULL; |
28530 |
++} |
28531 |
++ |
28532 |
++ |
28533 |
+ #endif |
28534 |
+diff --git a/include/net/xfrm.h b/include/net/xfrm.h |
28535 |
+index 2308210793a01..2b1ce8534993c 100644 |
28536 |
+--- a/include/net/xfrm.h |
28537 |
++++ b/include/net/xfrm.h |
28538 |
+@@ -200,6 +200,11 @@ struct xfrm_state { |
28539 |
+ struct xfrm_algo_aead *aead; |
28540 |
+ const char *geniv; |
28541 |
+ |
28542 |
++ /* mapping change rate limiting */ |
28543 |
++ __be16 new_mapping_sport; |
28544 |
++ u32 new_mapping; /* seconds */ |
28545 |
++ u32 mapping_maxage; /* seconds for input SA */ |
28546 |
++ |
28547 |
+ /* Data for encapsulator */ |
28548 |
+ struct xfrm_encap_tmpl *encap; |
28549 |
+ struct sock __rcu *encap_sk; |
28550 |
+@@ -1162,7 +1167,7 @@ static inline int xfrm_route_forward(struct sk_buff *skb, unsigned short family) |
28551 |
+ { |
28552 |
+ struct net *net = dev_net(skb->dev); |
28553 |
+ |
28554 |
+- if (xfrm_default_allow(net, XFRM_POLICY_FWD)) |
28555 |
++ if (xfrm_default_allow(net, XFRM_POLICY_OUT)) |
28556 |
+ return !net->xfrm.policy_count[XFRM_POLICY_OUT] || |
28557 |
+ (skb_dst(skb)->flags & DST_NOXFRM) || |
28558 |
+ __xfrm_route_forward(skb, family); |
28559 |
+diff --git a/include/sound/hda_codec.h b/include/sound/hda_codec.h |
28560 |
+index 0e45963bb767f..82d9daa178517 100644 |
28561 |
+--- a/include/sound/hda_codec.h |
28562 |
++++ b/include/sound/hda_codec.h |
28563 |
+@@ -8,7 +8,7 @@ |
28564 |
+ #ifndef __SOUND_HDA_CODEC_H |
28565 |
+ #define __SOUND_HDA_CODEC_H |
28566 |
+ |
28567 |
+-#include <linux/kref.h> |
28568 |
++#include <linux/refcount.h> |
28569 |
+ #include <linux/mod_devicetable.h> |
28570 |
+ #include <sound/info.h> |
28571 |
+ #include <sound/control.h> |
28572 |
+@@ -166,8 +166,8 @@ struct hda_pcm { |
28573 |
+ bool own_chmap; /* codec driver provides own channel maps */ |
28574 |
+ /* private: */ |
28575 |
+ struct hda_codec *codec; |
28576 |
+- struct kref kref; |
28577 |
+ struct list_head list; |
28578 |
++ unsigned int disconnected:1; |
28579 |
+ }; |
28580 |
+ |
28581 |
+ /* codec information */ |
28582 |
+@@ -187,6 +187,8 @@ struct hda_codec { |
28583 |
+ |
28584 |
+ /* PCM to create, set by patch_ops.build_pcms callback */ |
28585 |
+ struct list_head pcm_list_head; |
28586 |
++ refcount_t pcm_ref; |
28587 |
++ wait_queue_head_t remove_sleep; |
28588 |
+ |
28589 |
+ /* codec specific info */ |
28590 |
+ void *spec; |
28591 |
+@@ -420,7 +422,7 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec); |
28592 |
+ |
28593 |
+ static inline void snd_hda_codec_pcm_get(struct hda_pcm *pcm) |
28594 |
+ { |
28595 |
+- kref_get(&pcm->kref); |
28596 |
++ refcount_inc(&pcm->codec->pcm_ref); |
28597 |
+ } |
28598 |
+ void snd_hda_codec_pcm_put(struct hda_pcm *pcm); |
28599 |
+ |
28600 |
+diff --git a/include/trace/events/cgroup.h b/include/trace/events/cgroup.h |
28601 |
+index 7f42a3de59e6b..dd7d7c9efecdf 100644 |
28602 |
+--- a/include/trace/events/cgroup.h |
28603 |
++++ b/include/trace/events/cgroup.h |
28604 |
+@@ -59,8 +59,8 @@ DECLARE_EVENT_CLASS(cgroup, |
28605 |
+ |
28606 |
+ TP_STRUCT__entry( |
28607 |
+ __field( int, root ) |
28608 |
+- __field( int, id ) |
28609 |
+ __field( int, level ) |
28610 |
++ __field( u64, id ) |
28611 |
+ __string( path, path ) |
28612 |
+ ), |
28613 |
+ |
28614 |
+@@ -71,7 +71,7 @@ DECLARE_EVENT_CLASS(cgroup, |
28615 |
+ __assign_str(path, path); |
28616 |
+ ), |
28617 |
+ |
28618 |
+- TP_printk("root=%d id=%d level=%d path=%s", |
28619 |
++ TP_printk("root=%d id=%llu level=%d path=%s", |
28620 |
+ __entry->root, __entry->id, __entry->level, __get_str(path)) |
28621 |
+ ); |
28622 |
+ |
28623 |
+@@ -126,8 +126,8 @@ DECLARE_EVENT_CLASS(cgroup_migrate, |
28624 |
+ |
28625 |
+ TP_STRUCT__entry( |
28626 |
+ __field( int, dst_root ) |
28627 |
+- __field( int, dst_id ) |
28628 |
+ __field( int, dst_level ) |
28629 |
++ __field( u64, dst_id ) |
28630 |
+ __field( int, pid ) |
28631 |
+ __string( dst_path, path ) |
28632 |
+ __string( comm, task->comm ) |
28633 |
+@@ -142,7 +142,7 @@ DECLARE_EVENT_CLASS(cgroup_migrate, |
28634 |
+ __assign_str(comm, task->comm); |
28635 |
+ ), |
28636 |
+ |
28637 |
+- TP_printk("dst_root=%d dst_id=%d dst_level=%d dst_path=%s pid=%d comm=%s", |
28638 |
++ TP_printk("dst_root=%d dst_id=%llu dst_level=%d dst_path=%s pid=%d comm=%s", |
28639 |
+ __entry->dst_root, __entry->dst_id, __entry->dst_level, |
28640 |
+ __get_str(dst_path), __entry->pid, __get_str(comm)) |
28641 |
+ ); |
28642 |
+@@ -171,8 +171,8 @@ DECLARE_EVENT_CLASS(cgroup_event, |
28643 |
+ |
28644 |
+ TP_STRUCT__entry( |
28645 |
+ __field( int, root ) |
28646 |
+- __field( int, id ) |
28647 |
+ __field( int, level ) |
28648 |
++ __field( u64, id ) |
28649 |
+ __string( path, path ) |
28650 |
+ __field( int, val ) |
28651 |
+ ), |
28652 |
+@@ -185,7 +185,7 @@ DECLARE_EVENT_CLASS(cgroup_event, |
28653 |
+ __entry->val = val; |
28654 |
+ ), |
28655 |
+ |
28656 |
+- TP_printk("root=%d id=%d level=%d path=%s val=%d", |
28657 |
++ TP_printk("root=%d id=%llu level=%d path=%s val=%d", |
28658 |
+ __entry->root, __entry->id, __entry->level, __get_str(path), |
28659 |
+ __entry->val) |
28660 |
+ ); |
28661 |
+diff --git a/include/uapi/linux/xfrm.h b/include/uapi/linux/xfrm.h |
28662 |
+index eda0426ec4c2b..4e29d78518902 100644 |
28663 |
+--- a/include/uapi/linux/xfrm.h |
28664 |
++++ b/include/uapi/linux/xfrm.h |
28665 |
+@@ -313,6 +313,7 @@ enum xfrm_attr_type_t { |
28666 |
+ XFRMA_SET_MARK, /* __u32 */ |
28667 |
+ XFRMA_SET_MARK_MASK, /* __u32 */ |
28668 |
+ XFRMA_IF_ID, /* __u32 */ |
28669 |
++ XFRMA_MTIMER_THRESH, /* __u32 in seconds for input SA */ |
28670 |
+ __XFRMA_MAX |
28671 |
+ |
28672 |
+ #define XFRMA_OUTPUT_MARK XFRMA_SET_MARK /* Compatibility */ |
28673 |
+diff --git a/kernel/audit.c b/kernel/audit.c |
28674 |
+index 4cebadb5f30db..eab7282668ab9 100644 |
28675 |
+--- a/kernel/audit.c |
28676 |
++++ b/kernel/audit.c |
28677 |
+@@ -1540,6 +1540,20 @@ static void audit_receive(struct sk_buff *skb) |
28678 |
+ nlh = nlmsg_next(nlh, &len); |
28679 |
+ } |
28680 |
+ audit_ctl_unlock(); |
28681 |
++ |
28682 |
++ /* can't block with the ctrl lock, so penalize the sender now */ |
28683 |
++ if (audit_backlog_limit && |
28684 |
++ (skb_queue_len(&audit_queue) > audit_backlog_limit)) { |
28685 |
++ DECLARE_WAITQUEUE(wait, current); |
28686 |
++ |
28687 |
++ /* wake kauditd to try and flush the queue */ |
28688 |
++ wake_up_interruptible(&kauditd_wait); |
28689 |
++ |
28690 |
++ add_wait_queue_exclusive(&audit_backlog_wait, &wait); |
28691 |
++ set_current_state(TASK_UNINTERRUPTIBLE); |
28692 |
++ schedule_timeout(audit_backlog_wait_time); |
28693 |
++ remove_wait_queue(&audit_backlog_wait, &wait); |
28694 |
++ } |
28695 |
+ } |
28696 |
+ |
28697 |
+ /* Log information about who is connecting to the audit multicast socket */ |
28698 |
+@@ -1824,7 +1838,9 @@ struct audit_buffer *audit_log_start(struct audit_context *ctx, gfp_t gfp_mask, |
28699 |
+ * task_tgid_vnr() since auditd_pid is set in audit_receive_msg() |
28700 |
+ * using a PID anchored in the caller's namespace |
28701 |
+ * 2. generator holding the audit_cmd_mutex - we don't want to block |
28702 |
+- * while holding the mutex */ |
28703 |
++ * while holding the mutex, although we do penalize the sender |
28704 |
++ * later in audit_receive() when it is safe to block |
28705 |
++ */ |
28706 |
+ if (!(auditd_test_task(current) || audit_ctl_owner_current())) { |
28707 |
+ long stime = audit_backlog_wait_time; |
28708 |
+ |
28709 |
+diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c |
28710 |
+index dfe61df4f974d..b8ed4da63bc8c 100644 |
28711 |
+--- a/kernel/bpf/btf.c |
28712 |
++++ b/kernel/bpf/btf.c |
28713 |
+@@ -4332,8 +4332,7 @@ static struct btf *btf_parse(bpfptr_t btf_data, u32 btf_data_size, |
28714 |
+ log->len_total = log_size; |
28715 |
+ |
28716 |
+ /* log attributes have to be sane */ |
28717 |
+- if (log->len_total < 128 || log->len_total > UINT_MAX >> 8 || |
28718 |
+- !log->level || !log->ubuf) { |
28719 |
++ if (!bpf_verifier_log_attr_valid(log)) { |
28720 |
+ err = -EINVAL; |
28721 |
+ goto errout; |
28722 |
+ } |
28723 |
+diff --git a/kernel/bpf/inode.c b/kernel/bpf/inode.c |
28724 |
+index 80da1db47c686..5a8d9f7467bf4 100644 |
28725 |
+--- a/kernel/bpf/inode.c |
28726 |
++++ b/kernel/bpf/inode.c |
28727 |
+@@ -648,12 +648,22 @@ static int bpf_parse_param(struct fs_context *fc, struct fs_parameter *param) |
28728 |
+ int opt; |
28729 |
+ |
28730 |
+ opt = fs_parse(fc, bpf_fs_parameters, param, &result); |
28731 |
+- if (opt < 0) |
28732 |
++ if (opt < 0) { |
28733 |
+ /* We might like to report bad mount options here, but |
28734 |
+ * traditionally we've ignored all mount options, so we'd |
28735 |
+ * better continue to ignore non-existing options for bpf. |
28736 |
+ */ |
28737 |
+- return opt == -ENOPARAM ? 0 : opt; |
28738 |
++ if (opt == -ENOPARAM) { |
28739 |
++ opt = vfs_parse_fs_param_source(fc, param); |
28740 |
++ if (opt != -ENOPARAM) |
28741 |
++ return opt; |
28742 |
++ |
28743 |
++ return 0; |
28744 |
++ } |
28745 |
++ |
28746 |
++ if (opt < 0) |
28747 |
++ return opt; |
28748 |
++ } |
28749 |
+ |
28750 |
+ switch (opt) { |
28751 |
+ case OPT_MODE: |
28752 |
+diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c |
28753 |
+index b84e63d62b8af..670721e39c0e8 100644 |
28754 |
+--- a/kernel/bpf/verifier.c |
28755 |
++++ b/kernel/bpf/verifier.c |
28756 |
+@@ -5785,6 +5785,7 @@ static int __check_func_call(struct bpf_verifier_env *env, struct bpf_insn *insn |
28757 |
+ } |
28758 |
+ |
28759 |
+ if (insn->code == (BPF_JMP | BPF_CALL) && |
28760 |
++ insn->src_reg == 0 && |
28761 |
+ insn->imm == BPF_FUNC_timer_set_callback) { |
28762 |
+ struct bpf_verifier_state *async_cb; |
28763 |
+ |
28764 |
+@@ -8771,15 +8772,15 @@ static void mark_ptr_or_null_reg(struct bpf_func_state *state, |
28765 |
+ { |
28766 |
+ if (reg_type_may_be_null(reg->type) && reg->id == id && |
28767 |
+ !WARN_ON_ONCE(!reg->id)) { |
28768 |
+- /* Old offset (both fixed and variable parts) should |
28769 |
+- * have been known-zero, because we don't allow pointer |
28770 |
+- * arithmetic on pointers that might be NULL. |
28771 |
+- */ |
28772 |
+ if (WARN_ON_ONCE(reg->smin_value || reg->smax_value || |
28773 |
+ !tnum_equals_const(reg->var_off, 0) || |
28774 |
+ reg->off)) { |
28775 |
+- __mark_reg_known_zero(reg); |
28776 |
+- reg->off = 0; |
28777 |
++ /* Old offset (both fixed and variable parts) should |
28778 |
++ * have been known-zero, because we don't allow pointer |
28779 |
++ * arithmetic on pointers that might be NULL. If we |
28780 |
++ * see this happening, don't convert the register. |
28781 |
++ */ |
28782 |
++ return; |
28783 |
+ } |
28784 |
+ if (is_null) { |
28785 |
+ reg->type = SCALAR_VALUE; |
28786 |
+@@ -9198,9 +9199,13 @@ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn) |
28787 |
+ return 0; |
28788 |
+ } |
28789 |
+ |
28790 |
+- if (insn->src_reg == BPF_PSEUDO_BTF_ID) { |
28791 |
+- mark_reg_known_zero(env, regs, insn->dst_reg); |
28792 |
++ /* All special src_reg cases are listed below. From this point onwards |
28793 |
++ * we either succeed and assign a corresponding dst_reg->type after |
28794 |
++ * zeroing the offset, or fail and reject the program. |
28795 |
++ */ |
28796 |
++ mark_reg_known_zero(env, regs, insn->dst_reg); |
28797 |
+ |
28798 |
++ if (insn->src_reg == BPF_PSEUDO_BTF_ID) { |
28799 |
+ dst_reg->type = aux->btf_var.reg_type; |
28800 |
+ switch (dst_reg->type) { |
28801 |
+ case PTR_TO_MEM: |
28802 |
+@@ -9237,7 +9242,6 @@ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn) |
28803 |
+ } |
28804 |
+ |
28805 |
+ map = env->used_maps[aux->map_index]; |
28806 |
+- mark_reg_known_zero(env, regs, insn->dst_reg); |
28807 |
+ dst_reg->map_ptr = map; |
28808 |
+ |
28809 |
+ if (insn->src_reg == BPF_PSEUDO_MAP_VALUE || |
28810 |
+@@ -13759,11 +13763,11 @@ int bpf_check(struct bpf_prog **prog, union bpf_attr *attr, bpfptr_t uattr) |
28811 |
+ log->ubuf = (char __user *) (unsigned long) attr->log_buf; |
28812 |
+ log->len_total = attr->log_size; |
28813 |
+ |
28814 |
+- ret = -EINVAL; |
28815 |
+ /* log attributes have to be sane */ |
28816 |
+- if (log->len_total < 128 || log->len_total > UINT_MAX >> 2 || |
28817 |
+- !log->level || !log->ubuf || log->level & ~BPF_LOG_MASK) |
28818 |
++ if (!bpf_verifier_log_attr_valid(log)) { |
28819 |
++ ret = -EINVAL; |
28820 |
+ goto err_unlock; |
28821 |
++ } |
28822 |
+ } |
28823 |
+ |
28824 |
+ if (IS_ERR(btf_vmlinux)) { |
28825 |
+diff --git a/kernel/dma/pool.c b/kernel/dma/pool.c |
28826 |
+index 5f84e6cdb78ea..4d40dcce7604b 100644 |
28827 |
+--- a/kernel/dma/pool.c |
28828 |
++++ b/kernel/dma/pool.c |
28829 |
+@@ -203,7 +203,7 @@ static int __init dma_atomic_pool_init(void) |
28830 |
+ GFP_KERNEL); |
28831 |
+ if (!atomic_pool_kernel) |
28832 |
+ ret = -ENOMEM; |
28833 |
+- if (IS_ENABLED(CONFIG_ZONE_DMA)) { |
28834 |
++ if (has_managed_dma()) { |
28835 |
+ atomic_pool_dma = __dma_atomic_pool_init(atomic_pool_size, |
28836 |
+ GFP_KERNEL | GFP_DMA); |
28837 |
+ if (!atomic_pool_dma) |
28838 |
+@@ -226,7 +226,7 @@ static inline struct gen_pool *dma_guess_pool(struct gen_pool *prev, gfp_t gfp) |
28839 |
+ if (prev == NULL) { |
28840 |
+ if (IS_ENABLED(CONFIG_ZONE_DMA32) && (gfp & GFP_DMA32)) |
28841 |
+ return atomic_pool_dma32; |
28842 |
+- if (IS_ENABLED(CONFIG_ZONE_DMA) && (gfp & GFP_DMA)) |
28843 |
++ if (atomic_pool_dma && (gfp & GFP_DMA)) |
28844 |
+ return atomic_pool_dma; |
28845 |
+ return atomic_pool_kernel; |
28846 |
+ } |
28847 |
+diff --git a/kernel/rcu/rcutorture.c b/kernel/rcu/rcutorture.c |
28848 |
+index 968696ace8f3f..f922937eb39ad 100644 |
28849 |
+--- a/kernel/rcu/rcutorture.c |
28850 |
++++ b/kernel/rcu/rcutorture.c |
28851 |
+@@ -46,6 +46,7 @@ |
28852 |
+ #include <linux/oom.h> |
28853 |
+ #include <linux/tick.h> |
28854 |
+ #include <linux/rcupdate_trace.h> |
28855 |
++#include <linux/nmi.h> |
28856 |
+ |
28857 |
+ #include "rcu.h" |
28858 |
+ |
28859 |
+@@ -109,6 +110,8 @@ torture_param(int, shutdown_secs, 0, "Shutdown time (s), <= zero to disable."); |
28860 |
+ torture_param(int, stall_cpu, 0, "Stall duration (s), zero to disable."); |
28861 |
+ torture_param(int, stall_cpu_holdoff, 10, |
28862 |
+ "Time to wait before starting stall (s)."); |
28863 |
++torture_param(bool, stall_no_softlockup, false, |
28864 |
++ "Avoid softlockup warning during cpu stall."); |
28865 |
+ torture_param(int, stall_cpu_irqsoff, 0, "Disable interrupts while stalling."); |
28866 |
+ torture_param(int, stall_cpu_block, 0, "Sleep while stalling."); |
28867 |
+ torture_param(int, stall_gp_kthread, 0, |
28868 |
+@@ -2052,6 +2055,8 @@ static int rcu_torture_stall(void *args) |
28869 |
+ #else |
28870 |
+ schedule_timeout_uninterruptible(HZ); |
28871 |
+ #endif |
28872 |
++ } else if (stall_no_softlockup) { |
28873 |
++ touch_softlockup_watchdog(); |
28874 |
+ } |
28875 |
+ if (stall_cpu_irqsoff) |
28876 |
+ local_irq_enable(); |
28877 |
+diff --git a/kernel/rcu/tree_exp.h b/kernel/rcu/tree_exp.h |
28878 |
+index 454b516ea566e..16f94118ca34b 100644 |
28879 |
+--- a/kernel/rcu/tree_exp.h |
28880 |
++++ b/kernel/rcu/tree_exp.h |
28881 |
+@@ -387,6 +387,7 @@ retry_ipi: |
28882 |
+ continue; |
28883 |
+ } |
28884 |
+ if (get_cpu() == cpu) { |
28885 |
++ mask_ofl_test |= mask; |
28886 |
+ put_cpu(); |
28887 |
+ continue; |
28888 |
+ } |
28889 |
+diff --git a/kernel/sched/cpuacct.c b/kernel/sched/cpuacct.c |
28890 |
+index 893eece65bfda..ab67d97a84428 100644 |
28891 |
+--- a/kernel/sched/cpuacct.c |
28892 |
++++ b/kernel/sched/cpuacct.c |
28893 |
+@@ -21,15 +21,11 @@ static const char * const cpuacct_stat_desc[] = { |
28894 |
+ [CPUACCT_STAT_SYSTEM] = "system", |
28895 |
+ }; |
28896 |
+ |
28897 |
+-struct cpuacct_usage { |
28898 |
+- u64 usages[CPUACCT_STAT_NSTATS]; |
28899 |
+-}; |
28900 |
+- |
28901 |
+ /* track CPU usage of a group of tasks and its child groups */ |
28902 |
+ struct cpuacct { |
28903 |
+ struct cgroup_subsys_state css; |
28904 |
+ /* cpuusage holds pointer to a u64-type object on every CPU */ |
28905 |
+- struct cpuacct_usage __percpu *cpuusage; |
28906 |
++ u64 __percpu *cpuusage; |
28907 |
+ struct kernel_cpustat __percpu *cpustat; |
28908 |
+ }; |
28909 |
+ |
28910 |
+@@ -49,7 +45,7 @@ static inline struct cpuacct *parent_ca(struct cpuacct *ca) |
28911 |
+ return css_ca(ca->css.parent); |
28912 |
+ } |
28913 |
+ |
28914 |
+-static DEFINE_PER_CPU(struct cpuacct_usage, root_cpuacct_cpuusage); |
28915 |
++static DEFINE_PER_CPU(u64, root_cpuacct_cpuusage); |
28916 |
+ static struct cpuacct root_cpuacct = { |
28917 |
+ .cpustat = &kernel_cpustat, |
28918 |
+ .cpuusage = &root_cpuacct_cpuusage, |
28919 |
+@@ -68,7 +64,7 @@ cpuacct_css_alloc(struct cgroup_subsys_state *parent_css) |
28920 |
+ if (!ca) |
28921 |
+ goto out; |
28922 |
+ |
28923 |
+- ca->cpuusage = alloc_percpu(struct cpuacct_usage); |
28924 |
++ ca->cpuusage = alloc_percpu(u64); |
28925 |
+ if (!ca->cpuusage) |
28926 |
+ goto out_free_ca; |
28927 |
+ |
28928 |
+@@ -99,7 +95,8 @@ static void cpuacct_css_free(struct cgroup_subsys_state *css) |
28929 |
+ static u64 cpuacct_cpuusage_read(struct cpuacct *ca, int cpu, |
28930 |
+ enum cpuacct_stat_index index) |
28931 |
+ { |
28932 |
+- struct cpuacct_usage *cpuusage = per_cpu_ptr(ca->cpuusage, cpu); |
28933 |
++ u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu); |
28934 |
++ u64 *cpustat = per_cpu_ptr(ca->cpustat, cpu)->cpustat; |
28935 |
+ u64 data; |
28936 |
+ |
28937 |
+ /* |
28938 |
+@@ -115,14 +112,17 @@ static u64 cpuacct_cpuusage_read(struct cpuacct *ca, int cpu, |
28939 |
+ raw_spin_rq_lock_irq(cpu_rq(cpu)); |
28940 |
+ #endif |
28941 |
+ |
28942 |
+- if (index == CPUACCT_STAT_NSTATS) { |
28943 |
+- int i = 0; |
28944 |
+- |
28945 |
+- data = 0; |
28946 |
+- for (i = 0; i < CPUACCT_STAT_NSTATS; i++) |
28947 |
+- data += cpuusage->usages[i]; |
28948 |
+- } else { |
28949 |
+- data = cpuusage->usages[index]; |
28950 |
++ switch (index) { |
28951 |
++ case CPUACCT_STAT_USER: |
28952 |
++ data = cpustat[CPUTIME_USER] + cpustat[CPUTIME_NICE]; |
28953 |
++ break; |
28954 |
++ case CPUACCT_STAT_SYSTEM: |
28955 |
++ data = cpustat[CPUTIME_SYSTEM] + cpustat[CPUTIME_IRQ] + |
28956 |
++ cpustat[CPUTIME_SOFTIRQ]; |
28957 |
++ break; |
28958 |
++ case CPUACCT_STAT_NSTATS: |
28959 |
++ data = *cpuusage; |
28960 |
++ break; |
28961 |
+ } |
28962 |
+ |
28963 |
+ #ifndef CONFIG_64BIT |
28964 |
+@@ -132,10 +132,14 @@ static u64 cpuacct_cpuusage_read(struct cpuacct *ca, int cpu, |
28965 |
+ return data; |
28966 |
+ } |
28967 |
+ |
28968 |
+-static void cpuacct_cpuusage_write(struct cpuacct *ca, int cpu, u64 val) |
28969 |
++static void cpuacct_cpuusage_write(struct cpuacct *ca, int cpu) |
28970 |
+ { |
28971 |
+- struct cpuacct_usage *cpuusage = per_cpu_ptr(ca->cpuusage, cpu); |
28972 |
+- int i; |
28973 |
++ u64 *cpuusage = per_cpu_ptr(ca->cpuusage, cpu); |
28974 |
++ u64 *cpustat = per_cpu_ptr(ca->cpustat, cpu)->cpustat; |
28975 |
++ |
28976 |
++ /* Don't allow to reset global kernel_cpustat */ |
28977 |
++ if (ca == &root_cpuacct) |
28978 |
++ return; |
28979 |
+ |
28980 |
+ #ifndef CONFIG_64BIT |
28981 |
+ /* |
28982 |
+@@ -143,9 +147,10 @@ static void cpuacct_cpuusage_write(struct cpuacct *ca, int cpu, u64 val) |
28983 |
+ */ |
28984 |
+ raw_spin_rq_lock_irq(cpu_rq(cpu)); |
28985 |
+ #endif |
28986 |
+- |
28987 |
+- for (i = 0; i < CPUACCT_STAT_NSTATS; i++) |
28988 |
+- cpuusage->usages[i] = val; |
28989 |
++ *cpuusage = 0; |
28990 |
++ cpustat[CPUTIME_USER] = cpustat[CPUTIME_NICE] = 0; |
28991 |
++ cpustat[CPUTIME_SYSTEM] = cpustat[CPUTIME_IRQ] = 0; |
28992 |
++ cpustat[CPUTIME_SOFTIRQ] = 0; |
28993 |
+ |
28994 |
+ #ifndef CONFIG_64BIT |
28995 |
+ raw_spin_rq_unlock_irq(cpu_rq(cpu)); |
28996 |
+@@ -196,7 +201,7 @@ static int cpuusage_write(struct cgroup_subsys_state *css, struct cftype *cft, |
28997 |
+ return -EINVAL; |
28998 |
+ |
28999 |
+ for_each_possible_cpu(cpu) |
29000 |
+- cpuacct_cpuusage_write(ca, cpu, 0); |
29001 |
++ cpuacct_cpuusage_write(ca, cpu); |
29002 |
+ |
29003 |
+ return 0; |
29004 |
+ } |
29005 |
+@@ -243,25 +248,10 @@ static int cpuacct_all_seq_show(struct seq_file *m, void *V) |
29006 |
+ seq_puts(m, "\n"); |
29007 |
+ |
29008 |
+ for_each_possible_cpu(cpu) { |
29009 |
+- struct cpuacct_usage *cpuusage = per_cpu_ptr(ca->cpuusage, cpu); |
29010 |
+- |
29011 |
+ seq_printf(m, "%d", cpu); |
29012 |
+- |
29013 |
+- for (index = 0; index < CPUACCT_STAT_NSTATS; index++) { |
29014 |
+-#ifndef CONFIG_64BIT |
29015 |
+- /* |
29016 |
+- * Take rq->lock to make 64-bit read safe on 32-bit |
29017 |
+- * platforms. |
29018 |
+- */ |
29019 |
+- raw_spin_rq_lock_irq(cpu_rq(cpu)); |
29020 |
+-#endif |
29021 |
+- |
29022 |
+- seq_printf(m, " %llu", cpuusage->usages[index]); |
29023 |
+- |
29024 |
+-#ifndef CONFIG_64BIT |
29025 |
+- raw_spin_rq_unlock_irq(cpu_rq(cpu)); |
29026 |
+-#endif |
29027 |
+- } |
29028 |
++ for (index = 0; index < CPUACCT_STAT_NSTATS; index++) |
29029 |
++ seq_printf(m, " %llu", |
29030 |
++ cpuacct_cpuusage_read(ca, cpu, index)); |
29031 |
+ seq_puts(m, "\n"); |
29032 |
+ } |
29033 |
+ return 0; |
29034 |
+@@ -339,16 +329,11 @@ static struct cftype files[] = { |
29035 |
+ void cpuacct_charge(struct task_struct *tsk, u64 cputime) |
29036 |
+ { |
29037 |
+ struct cpuacct *ca; |
29038 |
+- int index = CPUACCT_STAT_SYSTEM; |
29039 |
+- struct pt_regs *regs = get_irq_regs() ? : task_pt_regs(tsk); |
29040 |
+- |
29041 |
+- if (regs && user_mode(regs)) |
29042 |
+- index = CPUACCT_STAT_USER; |
29043 |
+ |
29044 |
+ rcu_read_lock(); |
29045 |
+ |
29046 |
+ for (ca = task_ca(tsk); ca; ca = parent_ca(ca)) |
29047 |
+- __this_cpu_add(ca->cpuusage->usages[index], cputime); |
29048 |
++ __this_cpu_add(*ca->cpuusage, cputime); |
29049 |
+ |
29050 |
+ rcu_read_unlock(); |
29051 |
+ } |
29052 |
+diff --git a/kernel/sched/cputime.c b/kernel/sched/cputime.c |
29053 |
+index 872e481d5098c..042a6dbce8f32 100644 |
29054 |
+--- a/kernel/sched/cputime.c |
29055 |
++++ b/kernel/sched/cputime.c |
29056 |
+@@ -148,10 +148,10 @@ void account_guest_time(struct task_struct *p, u64 cputime) |
29057 |
+ |
29058 |
+ /* Add guest time to cpustat. */ |
29059 |
+ if (task_nice(p) > 0) { |
29060 |
+- cpustat[CPUTIME_NICE] += cputime; |
29061 |
++ task_group_account_field(p, CPUTIME_NICE, cputime); |
29062 |
+ cpustat[CPUTIME_GUEST_NICE] += cputime; |
29063 |
+ } else { |
29064 |
+- cpustat[CPUTIME_USER] += cputime; |
29065 |
++ task_group_account_field(p, CPUTIME_USER, cputime); |
29066 |
+ cpustat[CPUTIME_GUEST] += cputime; |
29067 |
+ } |
29068 |
+ } |
29069 |
+diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c |
29070 |
+index 6f16dfb742462..d41f966f5866a 100644 |
29071 |
+--- a/kernel/sched/fair.c |
29072 |
++++ b/kernel/sched/fair.c |
29073 |
+@@ -6429,8 +6429,10 @@ static int select_idle_sibling(struct task_struct *p, int prev, int target) |
29074 |
+ * pattern is IO completions. |
29075 |
+ */ |
29076 |
+ if (is_per_cpu_kthread(current) && |
29077 |
++ in_task() && |
29078 |
+ prev == smp_processor_id() && |
29079 |
+- this_rq()->nr_running <= 1) { |
29080 |
++ this_rq()->nr_running <= 1 && |
29081 |
++ asym_fits_capacity(task_util, prev)) { |
29082 |
+ return prev; |
29083 |
+ } |
29084 |
+ |
29085 |
+diff --git a/kernel/sched/psi.c b/kernel/sched/psi.c |
29086 |
+index 1652f2bb54b79..69b19d3af690f 100644 |
29087 |
+--- a/kernel/sched/psi.c |
29088 |
++++ b/kernel/sched/psi.c |
29089 |
+@@ -34,13 +34,19 @@ |
29090 |
+ * delayed on that resource such that nobody is advancing and the CPU |
29091 |
+ * goes idle. This leaves both workload and CPU unproductive. |
29092 |
+ * |
29093 |
+- * Naturally, the FULL state doesn't exist for the CPU resource at the |
29094 |
+- * system level, but exist at the cgroup level, means all non-idle tasks |
29095 |
+- * in a cgroup are delayed on the CPU resource which used by others outside |
29096 |
+- * of the cgroup or throttled by the cgroup cpu.max configuration. |
29097 |
+- * |
29098 |
+ * SOME = nr_delayed_tasks != 0 |
29099 |
+- * FULL = nr_delayed_tasks != 0 && nr_running_tasks == 0 |
29100 |
++ * FULL = nr_delayed_tasks != 0 && nr_productive_tasks == 0 |
29101 |
++ * |
29102 |
++ * What it means for a task to be productive is defined differently |
29103 |
++ * for each resource. For IO, productive means a running task. For |
29104 |
++ * memory, productive means a running task that isn't a reclaimer. For |
29105 |
++ * CPU, productive means an oncpu task. |
29106 |
++ * |
29107 |
++ * Naturally, the FULL state doesn't exist for the CPU resource at the |
29108 |
++ * system level, but exist at the cgroup level. At the cgroup level, |
29109 |
++ * FULL means all non-idle tasks in the cgroup are delayed on the CPU |
29110 |
++ * resource which is being used by others outside of the cgroup or |
29111 |
++ * throttled by the cgroup cpu.max configuration. |
29112 |
+ * |
29113 |
+ * The percentage of wallclock time spent in those compound stall |
29114 |
+ * states gives pressure numbers between 0 and 100 for each resource, |
29115 |
+@@ -81,13 +87,13 @@ |
29116 |
+ * |
29117 |
+ * threads = min(nr_nonidle_tasks, nr_cpus) |
29118 |
+ * SOME = min(nr_delayed_tasks / threads, 1) |
29119 |
+- * FULL = (threads - min(nr_running_tasks, threads)) / threads |
29120 |
++ * FULL = (threads - min(nr_productive_tasks, threads)) / threads |
29121 |
+ * |
29122 |
+ * For the 257 number crunchers on 256 CPUs, this yields: |
29123 |
+ * |
29124 |
+ * threads = min(257, 256) |
29125 |
+ * SOME = min(1 / 256, 1) = 0.4% |
29126 |
+- * FULL = (256 - min(257, 256)) / 256 = 0% |
29127 |
++ * FULL = (256 - min(256, 256)) / 256 = 0% |
29128 |
+ * |
29129 |
+ * For the 1 out of 4 memory-delayed tasks, this yields: |
29130 |
+ * |
29131 |
+@@ -112,7 +118,7 @@ |
29132 |
+ * For each runqueue, we track: |
29133 |
+ * |
29134 |
+ * tSOME[cpu] = time(nr_delayed_tasks[cpu] != 0) |
29135 |
+- * tFULL[cpu] = time(nr_delayed_tasks[cpu] && !nr_running_tasks[cpu]) |
29136 |
++ * tFULL[cpu] = time(nr_delayed_tasks[cpu] && !nr_productive_tasks[cpu]) |
29137 |
+ * tNONIDLE[cpu] = time(nr_nonidle_tasks[cpu] != 0) |
29138 |
+ * |
29139 |
+ * and then periodically aggregate: |
29140 |
+@@ -233,7 +239,8 @@ static bool test_state(unsigned int *tasks, enum psi_states state) |
29141 |
+ case PSI_MEM_SOME: |
29142 |
+ return unlikely(tasks[NR_MEMSTALL]); |
29143 |
+ case PSI_MEM_FULL: |
29144 |
+- return unlikely(tasks[NR_MEMSTALL] && !tasks[NR_RUNNING]); |
29145 |
++ return unlikely(tasks[NR_MEMSTALL] && |
29146 |
++ tasks[NR_RUNNING] == tasks[NR_MEMSTALL_RUNNING]); |
29147 |
+ case PSI_CPU_SOME: |
29148 |
+ return unlikely(tasks[NR_RUNNING] > tasks[NR_ONCPU]); |
29149 |
+ case PSI_CPU_FULL: |
29150 |
+@@ -710,10 +717,11 @@ static void psi_group_change(struct psi_group *group, int cpu, |
29151 |
+ if (groupc->tasks[t]) { |
29152 |
+ groupc->tasks[t]--; |
29153 |
+ } else if (!psi_bug) { |
29154 |
+- printk_deferred(KERN_ERR "psi: task underflow! cpu=%d t=%d tasks=[%u %u %u %u] clear=%x set=%x\n", |
29155 |
++ printk_deferred(KERN_ERR "psi: task underflow! cpu=%d t=%d tasks=[%u %u %u %u %u] clear=%x set=%x\n", |
29156 |
+ cpu, t, groupc->tasks[0], |
29157 |
+ groupc->tasks[1], groupc->tasks[2], |
29158 |
+- groupc->tasks[3], clear, set); |
29159 |
++ groupc->tasks[3], groupc->tasks[4], |
29160 |
++ clear, set); |
29161 |
+ psi_bug = 1; |
29162 |
+ } |
29163 |
+ } |
29164 |
+@@ -854,12 +862,15 @@ void psi_task_switch(struct task_struct *prev, struct task_struct *next, |
29165 |
+ int clear = TSK_ONCPU, set = 0; |
29166 |
+ |
29167 |
+ /* |
29168 |
+- * When we're going to sleep, psi_dequeue() lets us handle |
29169 |
+- * TSK_RUNNING and TSK_IOWAIT here, where we can combine it |
29170 |
+- * with TSK_ONCPU and save walking common ancestors twice. |
29171 |
++ * When we're going to sleep, psi_dequeue() lets us |
29172 |
++ * handle TSK_RUNNING, TSK_MEMSTALL_RUNNING and |
29173 |
++ * TSK_IOWAIT here, where we can combine it with |
29174 |
++ * TSK_ONCPU and save walking common ancestors twice. |
29175 |
+ */ |
29176 |
+ if (sleep) { |
29177 |
+ clear |= TSK_RUNNING; |
29178 |
++ if (prev->in_memstall) |
29179 |
++ clear |= TSK_MEMSTALL_RUNNING; |
29180 |
+ if (prev->in_iowait) |
29181 |
+ set |= TSK_IOWAIT; |
29182 |
+ } |
29183 |
+@@ -908,7 +919,7 @@ void psi_memstall_enter(unsigned long *flags) |
29184 |
+ rq = this_rq_lock_irq(&rf); |
29185 |
+ |
29186 |
+ current->in_memstall = 1; |
29187 |
+- psi_task_change(current, 0, TSK_MEMSTALL); |
29188 |
++ psi_task_change(current, 0, TSK_MEMSTALL | TSK_MEMSTALL_RUNNING); |
29189 |
+ |
29190 |
+ rq_unlock_irq(rq, &rf); |
29191 |
+ } |
29192 |
+@@ -937,7 +948,7 @@ void psi_memstall_leave(unsigned long *flags) |
29193 |
+ rq = this_rq_lock_irq(&rf); |
29194 |
+ |
29195 |
+ current->in_memstall = 0; |
29196 |
+- psi_task_change(current, TSK_MEMSTALL, 0); |
29197 |
++ psi_task_change(current, TSK_MEMSTALL | TSK_MEMSTALL_RUNNING, 0); |
29198 |
+ |
29199 |
+ rq_unlock_irq(rq, &rf); |
29200 |
+ } |
29201 |
+diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c |
29202 |
+index bfef3f39b5552..54f9bb3f15605 100644 |
29203 |
+--- a/kernel/sched/rt.c |
29204 |
++++ b/kernel/sched/rt.c |
29205 |
+@@ -52,11 +52,8 @@ void init_rt_bandwidth(struct rt_bandwidth *rt_b, u64 period, u64 runtime) |
29206 |
+ rt_b->rt_period_timer.function = sched_rt_period_timer; |
29207 |
+ } |
29208 |
+ |
29209 |
+-static void start_rt_bandwidth(struct rt_bandwidth *rt_b) |
29210 |
++static inline void do_start_rt_bandwidth(struct rt_bandwidth *rt_b) |
29211 |
+ { |
29212 |
+- if (!rt_bandwidth_enabled() || rt_b->rt_runtime == RUNTIME_INF) |
29213 |
+- return; |
29214 |
+- |
29215 |
+ raw_spin_lock(&rt_b->rt_runtime_lock); |
29216 |
+ if (!rt_b->rt_period_active) { |
29217 |
+ rt_b->rt_period_active = 1; |
29218 |
+@@ -75,6 +72,14 @@ static void start_rt_bandwidth(struct rt_bandwidth *rt_b) |
29219 |
+ raw_spin_unlock(&rt_b->rt_runtime_lock); |
29220 |
+ } |
29221 |
+ |
29222 |
++static void start_rt_bandwidth(struct rt_bandwidth *rt_b) |
29223 |
++{ |
29224 |
++ if (!rt_bandwidth_enabled() || rt_b->rt_runtime == RUNTIME_INF) |
29225 |
++ return; |
29226 |
++ |
29227 |
++ do_start_rt_bandwidth(rt_b); |
29228 |
++} |
29229 |
++ |
29230 |
+ void init_rt_rq(struct rt_rq *rt_rq) |
29231 |
+ { |
29232 |
+ struct rt_prio_array *array; |
29233 |
+@@ -1029,13 +1034,17 @@ static void update_curr_rt(struct rq *rq) |
29234 |
+ |
29235 |
+ for_each_sched_rt_entity(rt_se) { |
29236 |
+ struct rt_rq *rt_rq = rt_rq_of_se(rt_se); |
29237 |
++ int exceeded; |
29238 |
+ |
29239 |
+ if (sched_rt_runtime(rt_rq) != RUNTIME_INF) { |
29240 |
+ raw_spin_lock(&rt_rq->rt_runtime_lock); |
29241 |
+ rt_rq->rt_time += delta_exec; |
29242 |
+- if (sched_rt_runtime_exceeded(rt_rq)) |
29243 |
++ exceeded = sched_rt_runtime_exceeded(rt_rq); |
29244 |
++ if (exceeded) |
29245 |
+ resched_curr(rq); |
29246 |
+ raw_spin_unlock(&rt_rq->rt_runtime_lock); |
29247 |
++ if (exceeded) |
29248 |
++ do_start_rt_bandwidth(sched_rt_bandwidth(rt_rq)); |
29249 |
+ } |
29250 |
+ } |
29251 |
+ } |
29252 |
+@@ -2785,8 +2794,12 @@ static int sched_rt_global_validate(void) |
29253 |
+ |
29254 |
+ static void sched_rt_do_global(void) |
29255 |
+ { |
29256 |
++ unsigned long flags; |
29257 |
++ |
29258 |
++ raw_spin_lock_irqsave(&def_rt_bandwidth.rt_runtime_lock, flags); |
29259 |
+ def_rt_bandwidth.rt_runtime = global_rt_runtime(); |
29260 |
+ def_rt_bandwidth.rt_period = ns_to_ktime(global_rt_period()); |
29261 |
++ raw_spin_unlock_irqrestore(&def_rt_bandwidth.rt_runtime_lock, flags); |
29262 |
+ } |
29263 |
+ |
29264 |
+ int sched_rt_handler(struct ctl_table *table, int write, void *buffer, |
29265 |
+diff --git a/kernel/sched/stats.h b/kernel/sched/stats.h |
29266 |
+index d8f8eb0c655ba..606a3982d13a5 100644 |
29267 |
+--- a/kernel/sched/stats.h |
29268 |
++++ b/kernel/sched/stats.h |
29269 |
+@@ -69,6 +69,9 @@ static inline void psi_enqueue(struct task_struct *p, bool wakeup) |
29270 |
+ if (static_branch_likely(&psi_disabled)) |
29271 |
+ return; |
29272 |
+ |
29273 |
++ if (p->in_memstall) |
29274 |
++ set |= TSK_MEMSTALL_RUNNING; |
29275 |
++ |
29276 |
+ if (!wakeup || p->sched_psi_wake_requeue) { |
29277 |
+ if (p->in_memstall) |
29278 |
+ set |= TSK_MEMSTALL; |
29279 |
+@@ -99,7 +102,7 @@ static inline void psi_dequeue(struct task_struct *p, bool sleep) |
29280 |
+ return; |
29281 |
+ |
29282 |
+ if (p->in_memstall) |
29283 |
+- clear |= TSK_MEMSTALL; |
29284 |
++ clear |= (TSK_MEMSTALL | TSK_MEMSTALL_RUNNING); |
29285 |
+ |
29286 |
+ psi_task_change(p, clear, 0); |
29287 |
+ } |
29288 |
+diff --git a/kernel/time/clocksource.c b/kernel/time/clocksource.c |
29289 |
+index b8a14d2fb5ba6..bcad1a1e5dcf1 100644 |
29290 |
+--- a/kernel/time/clocksource.c |
29291 |
++++ b/kernel/time/clocksource.c |
29292 |
+@@ -107,7 +107,7 @@ static u64 suspend_start; |
29293 |
+ * This delay could be due to SMIs, NMIs, or to VCPU preemptions. Used as |
29294 |
+ * a lower bound for cs->uncertainty_margin values when registering clocks. |
29295 |
+ */ |
29296 |
+-#define WATCHDOG_MAX_SKEW (50 * NSEC_PER_USEC) |
29297 |
++#define WATCHDOG_MAX_SKEW (100 * NSEC_PER_USEC) |
29298 |
+ |
29299 |
+ #ifdef CONFIG_CLOCKSOURCE_WATCHDOG |
29300 |
+ static void clocksource_watchdog_work(struct work_struct *work); |
29301 |
+@@ -205,17 +205,24 @@ EXPORT_SYMBOL_GPL(max_cswd_read_retries); |
29302 |
+ static int verify_n_cpus = 8; |
29303 |
+ module_param(verify_n_cpus, int, 0644); |
29304 |
+ |
29305 |
+-static bool cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow) |
29306 |
++enum wd_read_status { |
29307 |
++ WD_READ_SUCCESS, |
29308 |
++ WD_READ_UNSTABLE, |
29309 |
++ WD_READ_SKIP |
29310 |
++}; |
29311 |
++ |
29312 |
++static enum wd_read_status cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow) |
29313 |
+ { |
29314 |
+ unsigned int nretries; |
29315 |
+- u64 wd_end, wd_delta; |
29316 |
+- int64_t wd_delay; |
29317 |
++ u64 wd_end, wd_end2, wd_delta; |
29318 |
++ int64_t wd_delay, wd_seq_delay; |
29319 |
+ |
29320 |
+ for (nretries = 0; nretries <= max_cswd_read_retries; nretries++) { |
29321 |
+ local_irq_disable(); |
29322 |
+ *wdnow = watchdog->read(watchdog); |
29323 |
+ *csnow = cs->read(cs); |
29324 |
+ wd_end = watchdog->read(watchdog); |
29325 |
++ wd_end2 = watchdog->read(watchdog); |
29326 |
+ local_irq_enable(); |
29327 |
+ |
29328 |
+ wd_delta = clocksource_delta(wd_end, *wdnow, watchdog->mask); |
29329 |
+@@ -226,13 +233,34 @@ static bool cs_watchdog_read(struct clocksource *cs, u64 *csnow, u64 *wdnow) |
29330 |
+ pr_warn("timekeeping watchdog on CPU%d: %s retried %d times before success\n", |
29331 |
+ smp_processor_id(), watchdog->name, nretries); |
29332 |
+ } |
29333 |
+- return true; |
29334 |
++ return WD_READ_SUCCESS; |
29335 |
+ } |
29336 |
++ |
29337 |
++ /* |
29338 |
++ * Now compute delay in consecutive watchdog read to see if |
29339 |
++ * there is too much external interferences that cause |
29340 |
++ * significant delay in reading both clocksource and watchdog. |
29341 |
++ * |
29342 |
++ * If consecutive WD read-back delay > WATCHDOG_MAX_SKEW/2, |
29343 |
++ * report system busy, reinit the watchdog and skip the current |
29344 |
++ * watchdog test. |
29345 |
++ */ |
29346 |
++ wd_delta = clocksource_delta(wd_end2, wd_end, watchdog->mask); |
29347 |
++ wd_seq_delay = clocksource_cyc2ns(wd_delta, watchdog->mult, watchdog->shift); |
29348 |
++ if (wd_seq_delay > WATCHDOG_MAX_SKEW/2) |
29349 |
++ goto skip_test; |
29350 |
+ } |
29351 |
+ |
29352 |
+ pr_warn("timekeeping watchdog on CPU%d: %s read-back delay of %lldns, attempt %d, marking unstable\n", |
29353 |
+ smp_processor_id(), watchdog->name, wd_delay, nretries); |
29354 |
+- return false; |
29355 |
++ return WD_READ_UNSTABLE; |
29356 |
++ |
29357 |
++skip_test: |
29358 |
++ pr_info("timekeeping watchdog on CPU%d: %s wd-wd read-back delay of %lldns\n", |
29359 |
++ smp_processor_id(), watchdog->name, wd_seq_delay); |
29360 |
++ pr_info("wd-%s-wd read-back delay of %lldns, clock-skew test skipped!\n", |
29361 |
++ cs->name, wd_delay); |
29362 |
++ return WD_READ_SKIP; |
29363 |
+ } |
29364 |
+ |
29365 |
+ static u64 csnow_mid; |
29366 |
+@@ -356,6 +384,7 @@ static void clocksource_watchdog(struct timer_list *unused) |
29367 |
+ int next_cpu, reset_pending; |
29368 |
+ int64_t wd_nsec, cs_nsec; |
29369 |
+ struct clocksource *cs; |
29370 |
++ enum wd_read_status read_ret; |
29371 |
+ u32 md; |
29372 |
+ |
29373 |
+ spin_lock(&watchdog_lock); |
29374 |
+@@ -373,9 +402,12 @@ static void clocksource_watchdog(struct timer_list *unused) |
29375 |
+ continue; |
29376 |
+ } |
29377 |
+ |
29378 |
+- if (!cs_watchdog_read(cs, &csnow, &wdnow)) { |
29379 |
+- /* Clock readout unreliable, so give it up. */ |
29380 |
+- __clocksource_unstable(cs); |
29381 |
++ read_ret = cs_watchdog_read(cs, &csnow, &wdnow); |
29382 |
++ |
29383 |
++ if (read_ret != WD_READ_SUCCESS) { |
29384 |
++ if (read_ret == WD_READ_UNSTABLE) |
29385 |
++ /* Clock readout unreliable, so give it up. */ |
29386 |
++ __clocksource_unstable(cs); |
29387 |
+ continue; |
29388 |
+ } |
29389 |
+ |
29390 |
+diff --git a/kernel/trace/bpf_trace.c b/kernel/trace/bpf_trace.c |
29391 |
+index 6c1038526d1fc..5a18b861fcf75 100644 |
29392 |
+--- a/kernel/trace/bpf_trace.c |
29393 |
++++ b/kernel/trace/bpf_trace.c |
29394 |
+@@ -1322,9 +1322,6 @@ static const struct bpf_func_proto bpf_perf_prog_read_value_proto = { |
29395 |
+ BPF_CALL_4(bpf_read_branch_records, struct bpf_perf_event_data_kern *, ctx, |
29396 |
+ void *, buf, u32, size, u64, flags) |
29397 |
+ { |
29398 |
+-#ifndef CONFIG_X86 |
29399 |
+- return -ENOENT; |
29400 |
+-#else |
29401 |
+ static const u32 br_entry_size = sizeof(struct perf_branch_entry); |
29402 |
+ struct perf_branch_stack *br_stack = ctx->data->br_stack; |
29403 |
+ u32 to_copy; |
29404 |
+@@ -1333,7 +1330,7 @@ BPF_CALL_4(bpf_read_branch_records, struct bpf_perf_event_data_kern *, ctx, |
29405 |
+ return -EINVAL; |
29406 |
+ |
29407 |
+ if (unlikely(!br_stack)) |
29408 |
+- return -EINVAL; |
29409 |
++ return -ENOENT; |
29410 |
+ |
29411 |
+ if (flags & BPF_F_GET_BRANCH_RECORDS_SIZE) |
29412 |
+ return br_stack->nr * br_entry_size; |
29413 |
+@@ -1345,7 +1342,6 @@ BPF_CALL_4(bpf_read_branch_records, struct bpf_perf_event_data_kern *, ctx, |
29414 |
+ memcpy(buf, br_stack->entries, to_copy); |
29415 |
+ |
29416 |
+ return to_copy; |
29417 |
+-#endif |
29418 |
+ } |
29419 |
+ |
29420 |
+ static const struct bpf_func_proto bpf_read_branch_records_proto = { |
29421 |
+diff --git a/kernel/trace/trace_kprobe.c b/kernel/trace/trace_kprobe.c |
29422 |
+index 92caef33b68c2..385981c293baf 100644 |
29423 |
+--- a/kernel/trace/trace_kprobe.c |
29424 |
++++ b/kernel/trace/trace_kprobe.c |
29425 |
+@@ -1175,15 +1175,18 @@ static int probes_profile_seq_show(struct seq_file *m, void *v) |
29426 |
+ { |
29427 |
+ struct dyn_event *ev = v; |
29428 |
+ struct trace_kprobe *tk; |
29429 |
++ unsigned long nmissed; |
29430 |
+ |
29431 |
+ if (!is_trace_kprobe(ev)) |
29432 |
+ return 0; |
29433 |
+ |
29434 |
+ tk = to_trace_kprobe(ev); |
29435 |
++ nmissed = trace_kprobe_is_return(tk) ? |
29436 |
++ tk->rp.kp.nmissed + tk->rp.nmissed : tk->rp.kp.nmissed; |
29437 |
+ seq_printf(m, " %-44s %15lu %15lu\n", |
29438 |
+ trace_probe_name(&tk->tp), |
29439 |
+ trace_kprobe_nhit(tk), |
29440 |
+- tk->rp.kp.nmissed); |
29441 |
++ nmissed); |
29442 |
+ |
29443 |
+ return 0; |
29444 |
+ } |
29445 |
+diff --git a/kernel/trace/trace_osnoise.c b/kernel/trace/trace_osnoise.c |
29446 |
+index c4f14fb98aaac..65a518649997b 100644 |
29447 |
+--- a/kernel/trace/trace_osnoise.c |
29448 |
++++ b/kernel/trace/trace_osnoise.c |
29449 |
+@@ -1932,6 +1932,13 @@ out_unhook_irq: |
29450 |
+ return -EINVAL; |
29451 |
+ } |
29452 |
+ |
29453 |
++static void osnoise_unhook_events(void) |
29454 |
++{ |
29455 |
++ unhook_thread_events(); |
29456 |
++ unhook_softirq_events(); |
29457 |
++ unhook_irq_events(); |
29458 |
++} |
29459 |
++ |
29460 |
+ static int __osnoise_tracer_start(struct trace_array *tr) |
29461 |
+ { |
29462 |
+ int retval; |
29463 |
+@@ -1949,7 +1956,14 @@ static int __osnoise_tracer_start(struct trace_array *tr) |
29464 |
+ |
29465 |
+ retval = start_per_cpu_kthreads(tr); |
29466 |
+ if (retval) { |
29467 |
+- unhook_irq_events(); |
29468 |
++ trace_osnoise_callback_enabled = false; |
29469 |
++ /* |
29470 |
++ * Make sure that ftrace_nmi_enter/exit() see |
29471 |
++ * trace_osnoise_callback_enabled as false before continuing. |
29472 |
++ */ |
29473 |
++ barrier(); |
29474 |
++ |
29475 |
++ osnoise_unhook_events(); |
29476 |
+ return retval; |
29477 |
+ } |
29478 |
+ |
29479 |
+@@ -1981,9 +1995,7 @@ static void osnoise_tracer_stop(struct trace_array *tr) |
29480 |
+ |
29481 |
+ stop_per_cpu_kthreads(); |
29482 |
+ |
29483 |
+- unhook_irq_events(); |
29484 |
+- unhook_softirq_events(); |
29485 |
+- unhook_thread_events(); |
29486 |
++ osnoise_unhook_events(); |
29487 |
+ |
29488 |
+ osnoise_busy = false; |
29489 |
+ } |
29490 |
+diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c |
29491 |
+index 8bfcd3b094226..f755bde42fd07 100644 |
29492 |
+--- a/kernel/trace/trace_syscalls.c |
29493 |
++++ b/kernel/trace/trace_syscalls.c |
29494 |
+@@ -323,8 +323,7 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id) |
29495 |
+ |
29496 |
+ trace_ctx = tracing_gen_ctx(); |
29497 |
+ |
29498 |
+- buffer = tr->array_buffer.buffer; |
29499 |
+- event = trace_buffer_lock_reserve(buffer, |
29500 |
++ event = trace_event_buffer_lock_reserve(&buffer, trace_file, |
29501 |
+ sys_data->enter_event->event.type, size, trace_ctx); |
29502 |
+ if (!event) |
29503 |
+ return; |
29504 |
+@@ -367,8 +366,7 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret) |
29505 |
+ |
29506 |
+ trace_ctx = tracing_gen_ctx(); |
29507 |
+ |
29508 |
+- buffer = tr->array_buffer.buffer; |
29509 |
+- event = trace_buffer_lock_reserve(buffer, |
29510 |
++ event = trace_event_buffer_lock_reserve(&buffer, trace_file, |
29511 |
+ sys_data->exit_event->event.type, sizeof(*entry), |
29512 |
+ trace_ctx); |
29513 |
+ if (!event) |
29514 |
+diff --git a/kernel/tsacct.c b/kernel/tsacct.c |
29515 |
+index 257ffb993ea23..fd2f7a052fdd9 100644 |
29516 |
+--- a/kernel/tsacct.c |
29517 |
++++ b/kernel/tsacct.c |
29518 |
+@@ -38,11 +38,10 @@ void bacct_add_tsk(struct user_namespace *user_ns, |
29519 |
+ stats->ac_btime = clamp_t(time64_t, btime, 0, U32_MAX); |
29520 |
+ stats->ac_btime64 = btime; |
29521 |
+ |
29522 |
+- if (thread_group_leader(tsk)) { |
29523 |
++ if (tsk->flags & PF_EXITING) |
29524 |
+ stats->ac_exitcode = tsk->exit_code; |
29525 |
+- if (tsk->flags & PF_FORKNOEXEC) |
29526 |
+- stats->ac_flag |= AFORK; |
29527 |
+- } |
29528 |
++ if (thread_group_leader(tsk) && (tsk->flags & PF_FORKNOEXEC)) |
29529 |
++ stats->ac_flag |= AFORK; |
29530 |
+ if (tsk->flags & PF_SUPERPRIV) |
29531 |
+ stats->ac_flag |= ASU; |
29532 |
+ if (tsk->flags & PF_DUMPCORE) |
29533 |
+diff --git a/lib/kunit/test.c b/lib/kunit/test.c |
29534 |
+index f246b847024e3..9aef816e573c1 100644 |
29535 |
+--- a/lib/kunit/test.c |
29536 |
++++ b/lib/kunit/test.c |
29537 |
+@@ -504,16 +504,18 @@ int kunit_run_tests(struct kunit_suite *suite) |
29538 |
+ struct kunit_result_stats param_stats = { 0 }; |
29539 |
+ test_case->status = KUNIT_SKIPPED; |
29540 |
+ |
29541 |
+- if (test_case->generate_params) { |
29542 |
++ if (!test_case->generate_params) { |
29543 |
++ /* Non-parameterised test. */ |
29544 |
++ kunit_run_case_catch_errors(suite, test_case, &test); |
29545 |
++ kunit_update_stats(¶m_stats, test.status); |
29546 |
++ } else { |
29547 |
+ /* Get initial param. */ |
29548 |
+ param_desc[0] = '\0'; |
29549 |
+ test.param_value = test_case->generate_params(NULL, param_desc); |
29550 |
+- } |
29551 |
+ |
29552 |
+- do { |
29553 |
+- kunit_run_case_catch_errors(suite, test_case, &test); |
29554 |
++ while (test.param_value) { |
29555 |
++ kunit_run_case_catch_errors(suite, test_case, &test); |
29556 |
+ |
29557 |
+- if (test_case->generate_params) { |
29558 |
+ if (param_desc[0] == '\0') { |
29559 |
+ snprintf(param_desc, sizeof(param_desc), |
29560 |
+ "param-%d", test.param_index); |
29561 |
+@@ -530,11 +532,11 @@ int kunit_run_tests(struct kunit_suite *suite) |
29562 |
+ param_desc[0] = '\0'; |
29563 |
+ test.param_value = test_case->generate_params(test.param_value, param_desc); |
29564 |
+ test.param_index++; |
29565 |
+- } |
29566 |
+ |
29567 |
+- kunit_update_stats(¶m_stats, test.status); |
29568 |
++ kunit_update_stats(¶m_stats, test.status); |
29569 |
++ } |
29570 |
++ } |
29571 |
+ |
29572 |
+- } while (test.param_value); |
29573 |
+ |
29574 |
+ kunit_print_test_stats(&test, param_stats); |
29575 |
+ |
29576 |
+diff --git a/lib/logic_iomem.c b/lib/logic_iomem.c |
29577 |
+index 9bdfde0c0f86d..549b22d4bcde1 100644 |
29578 |
+--- a/lib/logic_iomem.c |
29579 |
++++ b/lib/logic_iomem.c |
29580 |
+@@ -21,15 +21,15 @@ struct logic_iomem_area { |
29581 |
+ |
29582 |
+ #define AREA_SHIFT 24 |
29583 |
+ #define MAX_AREA_SIZE (1 << AREA_SHIFT) |
29584 |
+-#define MAX_AREAS ((1ULL<<32) / MAX_AREA_SIZE) |
29585 |
++#define MAX_AREAS ((1U << 31) / MAX_AREA_SIZE) |
29586 |
+ #define AREA_BITS ((MAX_AREAS - 1) << AREA_SHIFT) |
29587 |
+ #define AREA_MASK (MAX_AREA_SIZE - 1) |
29588 |
+ #ifdef CONFIG_64BIT |
29589 |
+ #define IOREMAP_BIAS 0xDEAD000000000000UL |
29590 |
+ #define IOREMAP_MASK 0xFFFFFFFF00000000UL |
29591 |
+ #else |
29592 |
+-#define IOREMAP_BIAS 0 |
29593 |
+-#define IOREMAP_MASK 0 |
29594 |
++#define IOREMAP_BIAS 0x80000000UL |
29595 |
++#define IOREMAP_MASK 0x80000000UL |
29596 |
+ #endif |
29597 |
+ |
29598 |
+ static DEFINE_MUTEX(regions_mtx); |
29599 |
+@@ -79,7 +79,7 @@ static void __iomem *real_ioremap(phys_addr_t offset, size_t size) |
29600 |
+ static void real_iounmap(void __iomem *addr) |
29601 |
+ { |
29602 |
+ WARN(1, "invalid iounmap for addr 0x%llx\n", |
29603 |
+- (unsigned long long __force)addr); |
29604 |
++ (unsigned long long)(uintptr_t __force)addr); |
29605 |
+ } |
29606 |
+ #endif /* CONFIG_LOGIC_IOMEM_FALLBACK */ |
29607 |
+ |
29608 |
+@@ -173,7 +173,7 @@ EXPORT_SYMBOL(iounmap); |
29609 |
+ static u##sz real_raw_read ## op(const volatile void __iomem *addr) \ |
29610 |
+ { \ |
29611 |
+ WARN(1, "Invalid read" #op " at address %llx\n", \ |
29612 |
+- (unsigned long long __force)addr); \ |
29613 |
++ (unsigned long long)(uintptr_t __force)addr); \ |
29614 |
+ return (u ## sz)~0ULL; \ |
29615 |
+ } \ |
29616 |
+ \ |
29617 |
+@@ -181,7 +181,8 @@ static void real_raw_write ## op(u ## sz val, \ |
29618 |
+ volatile void __iomem *addr) \ |
29619 |
+ { \ |
29620 |
+ WARN(1, "Invalid writeq" #op " of 0x%llx at address %llx\n", \ |
29621 |
+- (unsigned long long)val, (unsigned long long __force)addr);\ |
29622 |
++ (unsigned long long)val, \ |
29623 |
++ (unsigned long long)(uintptr_t __force)addr);\ |
29624 |
+ } \ |
29625 |
+ |
29626 |
+ MAKE_FALLBACK(b, 8); |
29627 |
+@@ -194,14 +195,14 @@ MAKE_FALLBACK(q, 64); |
29628 |
+ static void real_memset_io(volatile void __iomem *addr, int value, size_t size) |
29629 |
+ { |
29630 |
+ WARN(1, "Invalid memset_io at address 0x%llx\n", |
29631 |
+- (unsigned long long __force)addr); |
29632 |
++ (unsigned long long)(uintptr_t __force)addr); |
29633 |
+ } |
29634 |
+ |
29635 |
+ static void real_memcpy_fromio(void *buffer, const volatile void __iomem *addr, |
29636 |
+ size_t size) |
29637 |
+ { |
29638 |
+ WARN(1, "Invalid memcpy_fromio at address 0x%llx\n", |
29639 |
+- (unsigned long long __force)addr); |
29640 |
++ (unsigned long long)(uintptr_t __force)addr); |
29641 |
+ |
29642 |
+ memset(buffer, 0xff, size); |
29643 |
+ } |
29644 |
+@@ -210,7 +211,7 @@ static void real_memcpy_toio(volatile void __iomem *addr, const void *buffer, |
29645 |
+ size_t size) |
29646 |
+ { |
29647 |
+ WARN(1, "Invalid memcpy_toio at address 0x%llx\n", |
29648 |
+- (unsigned long long __force)addr); |
29649 |
++ (unsigned long long)(uintptr_t __force)addr); |
29650 |
+ } |
29651 |
+ #endif /* CONFIG_LOGIC_IOMEM_FALLBACK */ |
29652 |
+ |
29653 |
+diff --git a/lib/mpi/mpi-mod.c b/lib/mpi/mpi-mod.c |
29654 |
+index 47bc59edd4ff9..54fcc01564d9d 100644 |
29655 |
+--- a/lib/mpi/mpi-mod.c |
29656 |
++++ b/lib/mpi/mpi-mod.c |
29657 |
+@@ -40,6 +40,8 @@ mpi_barrett_t mpi_barrett_init(MPI m, int copy) |
29658 |
+ |
29659 |
+ mpi_normalize(m); |
29660 |
+ ctx = kcalloc(1, sizeof(*ctx), GFP_KERNEL); |
29661 |
++ if (!ctx) |
29662 |
++ return NULL; |
29663 |
+ |
29664 |
+ if (copy) { |
29665 |
+ ctx->m = mpi_copy(m); |
29666 |
+diff --git a/lib/test_hmm.c b/lib/test_hmm.c |
29667 |
+index c259842f6d443..ac794e3540693 100644 |
29668 |
+--- a/lib/test_hmm.c |
29669 |
++++ b/lib/test_hmm.c |
29670 |
+@@ -1087,9 +1087,33 @@ static long dmirror_fops_unlocked_ioctl(struct file *filp, |
29671 |
+ return 0; |
29672 |
+ } |
29673 |
+ |
29674 |
++static int dmirror_fops_mmap(struct file *file, struct vm_area_struct *vma) |
29675 |
++{ |
29676 |
++ unsigned long addr; |
29677 |
++ |
29678 |
++ for (addr = vma->vm_start; addr < vma->vm_end; addr += PAGE_SIZE) { |
29679 |
++ struct page *page; |
29680 |
++ int ret; |
29681 |
++ |
29682 |
++ page = alloc_page(GFP_KERNEL | __GFP_ZERO); |
29683 |
++ if (!page) |
29684 |
++ return -ENOMEM; |
29685 |
++ |
29686 |
++ ret = vm_insert_page(vma, addr, page); |
29687 |
++ if (ret) { |
29688 |
++ __free_page(page); |
29689 |
++ return ret; |
29690 |
++ } |
29691 |
++ put_page(page); |
29692 |
++ } |
29693 |
++ |
29694 |
++ return 0; |
29695 |
++} |
29696 |
++ |
29697 |
+ static const struct file_operations dmirror_fops = { |
29698 |
+ .open = dmirror_fops_open, |
29699 |
+ .release = dmirror_fops_release, |
29700 |
++ .mmap = dmirror_fops_mmap, |
29701 |
+ .unlocked_ioctl = dmirror_fops_unlocked_ioctl, |
29702 |
+ .llseek = default_llseek, |
29703 |
+ .owner = THIS_MODULE, |
29704 |
+diff --git a/lib/test_meminit.c b/lib/test_meminit.c |
29705 |
+index e4f706a404b3a..3ca717f113977 100644 |
29706 |
+--- a/lib/test_meminit.c |
29707 |
++++ b/lib/test_meminit.c |
29708 |
+@@ -337,6 +337,7 @@ static int __init do_kmem_cache_size_bulk(int size, int *total_failures) |
29709 |
+ if (num) |
29710 |
+ kmem_cache_free_bulk(c, num, objects); |
29711 |
+ } |
29712 |
++ kmem_cache_destroy(c); |
29713 |
+ *total_failures += fail; |
29714 |
+ return 1; |
29715 |
+ } |
29716 |
+diff --git a/mm/hmm.c b/mm/hmm.c |
29717 |
+index 842e265992380..bd56641c79d4e 100644 |
29718 |
+--- a/mm/hmm.c |
29719 |
++++ b/mm/hmm.c |
29720 |
+@@ -300,7 +300,8 @@ static int hmm_vma_handle_pte(struct mm_walk *walk, unsigned long addr, |
29721 |
+ * Since each architecture defines a struct page for the zero page, just |
29722 |
+ * fall through and treat it like a normal page. |
29723 |
+ */ |
29724 |
+- if (pte_special(pte) && !pte_devmap(pte) && |
29725 |
++ if (!vm_normal_page(walk->vma, addr, pte) && |
29726 |
++ !pte_devmap(pte) && |
29727 |
+ !is_zero_pfn(pte_pfn(pte))) { |
29728 |
+ if (hmm_pte_need_fault(hmm_vma_walk, pfn_req_flags, 0)) { |
29729 |
+ pte_unmap(ptep); |
29730 |
+@@ -518,7 +519,7 @@ static int hmm_vma_walk_test(unsigned long start, unsigned long end, |
29731 |
+ struct hmm_range *range = hmm_vma_walk->range; |
29732 |
+ struct vm_area_struct *vma = walk->vma; |
29733 |
+ |
29734 |
+- if (!(vma->vm_flags & (VM_IO | VM_PFNMAP | VM_MIXEDMAP)) && |
29735 |
++ if (!(vma->vm_flags & (VM_IO | VM_PFNMAP)) && |
29736 |
+ vma->vm_flags & VM_READ) |
29737 |
+ return 0; |
29738 |
+ |
29739 |
+diff --git a/mm/page_alloc.c b/mm/page_alloc.c |
29740 |
+index 23d3339ac4e8e..7773bae3b6edb 100644 |
29741 |
+--- a/mm/page_alloc.c |
29742 |
++++ b/mm/page_alloc.c |
29743 |
+@@ -4210,7 +4210,9 @@ void warn_alloc(gfp_t gfp_mask, nodemask_t *nodemask, const char *fmt, ...) |
29744 |
+ va_list args; |
29745 |
+ static DEFINE_RATELIMIT_STATE(nopage_rs, 10*HZ, 1); |
29746 |
+ |
29747 |
+- if ((gfp_mask & __GFP_NOWARN) || !__ratelimit(&nopage_rs)) |
29748 |
++ if ((gfp_mask & __GFP_NOWARN) || |
29749 |
++ !__ratelimit(&nopage_rs) || |
29750 |
++ ((gfp_mask & __GFP_DMA) && !has_managed_dma())) |
29751 |
+ return; |
29752 |
+ |
29753 |
+ va_start(args, fmt); |
29754 |
+@@ -9449,3 +9451,18 @@ bool take_page_off_buddy(struct page *page) |
29755 |
+ return ret; |
29756 |
+ } |
29757 |
+ #endif |
29758 |
++ |
29759 |
++#ifdef CONFIG_ZONE_DMA |
29760 |
++bool has_managed_dma(void) |
29761 |
++{ |
29762 |
++ struct pglist_data *pgdat; |
29763 |
++ |
29764 |
++ for_each_online_pgdat(pgdat) { |
29765 |
++ struct zone *zone = &pgdat->node_zones[ZONE_DMA]; |
29766 |
++ |
29767 |
++ if (managed_zone(zone)) |
29768 |
++ return true; |
29769 |
++ } |
29770 |
++ return false; |
29771 |
++} |
29772 |
++#endif /* CONFIG_ZONE_DMA */ |
29773 |
+diff --git a/mm/shmem.c b/mm/shmem.c |
29774 |
+index b5860f4a2738e..1609a8daba26e 100644 |
29775 |
+--- a/mm/shmem.c |
29776 |
++++ b/mm/shmem.c |
29777 |
+@@ -555,7 +555,7 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, |
29778 |
+ struct shmem_inode_info *info; |
29779 |
+ struct page *page; |
29780 |
+ unsigned long batch = sc ? sc->nr_to_scan : 128; |
29781 |
+- int removed = 0, split = 0; |
29782 |
++ int split = 0; |
29783 |
+ |
29784 |
+ if (list_empty(&sbinfo->shrinklist)) |
29785 |
+ return SHRINK_STOP; |
29786 |
+@@ -570,7 +570,6 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, |
29787 |
+ /* inode is about to be evicted */ |
29788 |
+ if (!inode) { |
29789 |
+ list_del_init(&info->shrinklist); |
29790 |
+- removed++; |
29791 |
+ goto next; |
29792 |
+ } |
29793 |
+ |
29794 |
+@@ -578,12 +577,12 @@ static unsigned long shmem_unused_huge_shrink(struct shmem_sb_info *sbinfo, |
29795 |
+ if (round_up(inode->i_size, PAGE_SIZE) == |
29796 |
+ round_up(inode->i_size, HPAGE_PMD_SIZE)) { |
29797 |
+ list_move(&info->shrinklist, &to_remove); |
29798 |
+- removed++; |
29799 |
+ goto next; |
29800 |
+ } |
29801 |
+ |
29802 |
+ list_move(&info->shrinklist, &list); |
29803 |
+ next: |
29804 |
++ sbinfo->shrinklist_len--; |
29805 |
+ if (!--batch) |
29806 |
+ break; |
29807 |
+ } |
29808 |
+@@ -603,7 +602,7 @@ next: |
29809 |
+ inode = &info->vfs_inode; |
29810 |
+ |
29811 |
+ if (nr_to_split && split >= nr_to_split) |
29812 |
+- goto leave; |
29813 |
++ goto move_back; |
29814 |
+ |
29815 |
+ page = find_get_page(inode->i_mapping, |
29816 |
+ (inode->i_size & HPAGE_PMD_MASK) >> PAGE_SHIFT); |
29817 |
+@@ -617,38 +616,44 @@ next: |
29818 |
+ } |
29819 |
+ |
29820 |
+ /* |
29821 |
+- * Leave the inode on the list if we failed to lock |
29822 |
+- * the page at this time. |
29823 |
++ * Move the inode on the list back to shrinklist if we failed |
29824 |
++ * to lock the page at this time. |
29825 |
+ * |
29826 |
+ * Waiting for the lock may lead to deadlock in the |
29827 |
+ * reclaim path. |
29828 |
+ */ |
29829 |
+ if (!trylock_page(page)) { |
29830 |
+ put_page(page); |
29831 |
+- goto leave; |
29832 |
++ goto move_back; |
29833 |
+ } |
29834 |
+ |
29835 |
+ ret = split_huge_page(page); |
29836 |
+ unlock_page(page); |
29837 |
+ put_page(page); |
29838 |
+ |
29839 |
+- /* If split failed leave the inode on the list */ |
29840 |
++ /* If split failed move the inode on the list back to shrinklist */ |
29841 |
+ if (ret) |
29842 |
+- goto leave; |
29843 |
++ goto move_back; |
29844 |
+ |
29845 |
+ split++; |
29846 |
+ drop: |
29847 |
+ list_del_init(&info->shrinklist); |
29848 |
+- removed++; |
29849 |
+-leave: |
29850 |
++ goto put; |
29851 |
++move_back: |
29852 |
++ /* |
29853 |
++ * Make sure the inode is either on the global list or deleted |
29854 |
++ * from any local list before iput() since it could be deleted |
29855 |
++ * in another thread once we put the inode (then the local list |
29856 |
++ * is corrupted). |
29857 |
++ */ |
29858 |
++ spin_lock(&sbinfo->shrinklist_lock); |
29859 |
++ list_move(&info->shrinklist, &sbinfo->shrinklist); |
29860 |
++ sbinfo->shrinklist_len++; |
29861 |
++ spin_unlock(&sbinfo->shrinklist_lock); |
29862 |
++put: |
29863 |
+ iput(inode); |
29864 |
+ } |
29865 |
+ |
29866 |
+- spin_lock(&sbinfo->shrinklist_lock); |
29867 |
+- list_splice_tail(&list, &sbinfo->shrinklist); |
29868 |
+- sbinfo->shrinklist_len -= removed; |
29869 |
+- spin_unlock(&sbinfo->shrinklist_lock); |
29870 |
+- |
29871 |
+ return split; |
29872 |
+ } |
29873 |
+ |
29874 |
+diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c |
29875 |
+index aa7785687e757..7473e0cc6d469 100644 |
29876 |
+--- a/net/ax25/af_ax25.c |
29877 |
++++ b/net/ax25/af_ax25.c |
29878 |
+@@ -536,7 +536,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, |
29879 |
+ ax25_cb *ax25; |
29880 |
+ struct net_device *dev; |
29881 |
+ char devname[IFNAMSIZ]; |
29882 |
+- unsigned long opt; |
29883 |
++ unsigned int opt; |
29884 |
+ int res = 0; |
29885 |
+ |
29886 |
+ if (level != SOL_AX25) |
29887 |
+@@ -568,7 +568,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, |
29888 |
+ break; |
29889 |
+ |
29890 |
+ case AX25_T1: |
29891 |
+- if (opt < 1 || opt > ULONG_MAX / HZ) { |
29892 |
++ if (opt < 1 || opt > UINT_MAX / HZ) { |
29893 |
+ res = -EINVAL; |
29894 |
+ break; |
29895 |
+ } |
29896 |
+@@ -577,7 +577,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, |
29897 |
+ break; |
29898 |
+ |
29899 |
+ case AX25_T2: |
29900 |
+- if (opt < 1 || opt > ULONG_MAX / HZ) { |
29901 |
++ if (opt < 1 || opt > UINT_MAX / HZ) { |
29902 |
+ res = -EINVAL; |
29903 |
+ break; |
29904 |
+ } |
29905 |
+@@ -593,7 +593,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, |
29906 |
+ break; |
29907 |
+ |
29908 |
+ case AX25_T3: |
29909 |
+- if (opt < 1 || opt > ULONG_MAX / HZ) { |
29910 |
++ if (opt < 1 || opt > UINT_MAX / HZ) { |
29911 |
+ res = -EINVAL; |
29912 |
+ break; |
29913 |
+ } |
29914 |
+@@ -601,7 +601,7 @@ static int ax25_setsockopt(struct socket *sock, int level, int optname, |
29915 |
+ break; |
29916 |
+ |
29917 |
+ case AX25_IDLE: |
29918 |
+- if (opt > ULONG_MAX / (60 * HZ)) { |
29919 |
++ if (opt > UINT_MAX / (60 * HZ)) { |
29920 |
+ res = -EINVAL; |
29921 |
+ break; |
29922 |
+ } |
29923 |
+diff --git a/net/batman-adv/netlink.c b/net/batman-adv/netlink.c |
29924 |
+index 29276284d281c..00875e1d8c44c 100644 |
29925 |
+--- a/net/batman-adv/netlink.c |
29926 |
++++ b/net/batman-adv/netlink.c |
29927 |
+@@ -1368,21 +1368,21 @@ static const struct genl_small_ops batadv_netlink_ops[] = { |
29928 |
+ { |
29929 |
+ .cmd = BATADV_CMD_TP_METER, |
29930 |
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
29931 |
+- .flags = GENL_ADMIN_PERM, |
29932 |
++ .flags = GENL_UNS_ADMIN_PERM, |
29933 |
+ .doit = batadv_netlink_tp_meter_start, |
29934 |
+ .internal_flags = BATADV_FLAG_NEED_MESH, |
29935 |
+ }, |
29936 |
+ { |
29937 |
+ .cmd = BATADV_CMD_TP_METER_CANCEL, |
29938 |
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
29939 |
+- .flags = GENL_ADMIN_PERM, |
29940 |
++ .flags = GENL_UNS_ADMIN_PERM, |
29941 |
+ .doit = batadv_netlink_tp_meter_cancel, |
29942 |
+ .internal_flags = BATADV_FLAG_NEED_MESH, |
29943 |
+ }, |
29944 |
+ { |
29945 |
+ .cmd = BATADV_CMD_GET_ROUTING_ALGOS, |
29946 |
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
29947 |
+- .flags = GENL_ADMIN_PERM, |
29948 |
++ .flags = GENL_UNS_ADMIN_PERM, |
29949 |
+ .dumpit = batadv_algo_dump, |
29950 |
+ }, |
29951 |
+ { |
29952 |
+@@ -1397,68 +1397,68 @@ static const struct genl_small_ops batadv_netlink_ops[] = { |
29953 |
+ { |
29954 |
+ .cmd = BATADV_CMD_GET_TRANSTABLE_LOCAL, |
29955 |
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
29956 |
+- .flags = GENL_ADMIN_PERM, |
29957 |
++ .flags = GENL_UNS_ADMIN_PERM, |
29958 |
+ .dumpit = batadv_tt_local_dump, |
29959 |
+ }, |
29960 |
+ { |
29961 |
+ .cmd = BATADV_CMD_GET_TRANSTABLE_GLOBAL, |
29962 |
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
29963 |
+- .flags = GENL_ADMIN_PERM, |
29964 |
++ .flags = GENL_UNS_ADMIN_PERM, |
29965 |
+ .dumpit = batadv_tt_global_dump, |
29966 |
+ }, |
29967 |
+ { |
29968 |
+ .cmd = BATADV_CMD_GET_ORIGINATORS, |
29969 |
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
29970 |
+- .flags = GENL_ADMIN_PERM, |
29971 |
++ .flags = GENL_UNS_ADMIN_PERM, |
29972 |
+ .dumpit = batadv_orig_dump, |
29973 |
+ }, |
29974 |
+ { |
29975 |
+ .cmd = BATADV_CMD_GET_NEIGHBORS, |
29976 |
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
29977 |
+- .flags = GENL_ADMIN_PERM, |
29978 |
++ .flags = GENL_UNS_ADMIN_PERM, |
29979 |
+ .dumpit = batadv_hardif_neigh_dump, |
29980 |
+ }, |
29981 |
+ { |
29982 |
+ .cmd = BATADV_CMD_GET_GATEWAYS, |
29983 |
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
29984 |
+- .flags = GENL_ADMIN_PERM, |
29985 |
++ .flags = GENL_UNS_ADMIN_PERM, |
29986 |
+ .dumpit = batadv_gw_dump, |
29987 |
+ }, |
29988 |
+ { |
29989 |
+ .cmd = BATADV_CMD_GET_BLA_CLAIM, |
29990 |
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
29991 |
+- .flags = GENL_ADMIN_PERM, |
29992 |
++ .flags = GENL_UNS_ADMIN_PERM, |
29993 |
+ .dumpit = batadv_bla_claim_dump, |
29994 |
+ }, |
29995 |
+ { |
29996 |
+ .cmd = BATADV_CMD_GET_BLA_BACKBONE, |
29997 |
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
29998 |
+- .flags = GENL_ADMIN_PERM, |
29999 |
++ .flags = GENL_UNS_ADMIN_PERM, |
30000 |
+ .dumpit = batadv_bla_backbone_dump, |
30001 |
+ }, |
30002 |
+ { |
30003 |
+ .cmd = BATADV_CMD_GET_DAT_CACHE, |
30004 |
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
30005 |
+- .flags = GENL_ADMIN_PERM, |
30006 |
++ .flags = GENL_UNS_ADMIN_PERM, |
30007 |
+ .dumpit = batadv_dat_cache_dump, |
30008 |
+ }, |
30009 |
+ { |
30010 |
+ .cmd = BATADV_CMD_GET_MCAST_FLAGS, |
30011 |
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
30012 |
+- .flags = GENL_ADMIN_PERM, |
30013 |
++ .flags = GENL_UNS_ADMIN_PERM, |
30014 |
+ .dumpit = batadv_mcast_flags_dump, |
30015 |
+ }, |
30016 |
+ { |
30017 |
+ .cmd = BATADV_CMD_SET_MESH, |
30018 |
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
30019 |
+- .flags = GENL_ADMIN_PERM, |
30020 |
++ .flags = GENL_UNS_ADMIN_PERM, |
30021 |
+ .doit = batadv_netlink_set_mesh, |
30022 |
+ .internal_flags = BATADV_FLAG_NEED_MESH, |
30023 |
+ }, |
30024 |
+ { |
30025 |
+ .cmd = BATADV_CMD_SET_HARDIF, |
30026 |
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
30027 |
+- .flags = GENL_ADMIN_PERM, |
30028 |
++ .flags = GENL_UNS_ADMIN_PERM, |
30029 |
+ .doit = batadv_netlink_set_hardif, |
30030 |
+ .internal_flags = BATADV_FLAG_NEED_MESH | |
30031 |
+ BATADV_FLAG_NEED_HARDIF, |
30032 |
+@@ -1474,7 +1474,7 @@ static const struct genl_small_ops batadv_netlink_ops[] = { |
30033 |
+ { |
30034 |
+ .cmd = BATADV_CMD_SET_VLAN, |
30035 |
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP, |
30036 |
+- .flags = GENL_ADMIN_PERM, |
30037 |
++ .flags = GENL_UNS_ADMIN_PERM, |
30038 |
+ .doit = batadv_netlink_set_vlan, |
30039 |
+ .internal_flags = BATADV_FLAG_NEED_MESH | |
30040 |
+ BATADV_FLAG_NEED_VLAN, |
30041 |
+diff --git a/net/bluetooth/cmtp/core.c b/net/bluetooth/cmtp/core.c |
30042 |
+index 0a2d78e811cf5..83eb84e8e688f 100644 |
30043 |
+--- a/net/bluetooth/cmtp/core.c |
30044 |
++++ b/net/bluetooth/cmtp/core.c |
30045 |
+@@ -501,9 +501,7 @@ static int __init cmtp_init(void) |
30046 |
+ { |
30047 |
+ BT_INFO("CMTP (CAPI Emulation) ver %s", VERSION); |
30048 |
+ |
30049 |
+- cmtp_init_sockets(); |
30050 |
+- |
30051 |
+- return 0; |
30052 |
++ return cmtp_init_sockets(); |
30053 |
+ } |
30054 |
+ |
30055 |
+ static void __exit cmtp_exit(void) |
30056 |
+diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c |
30057 |
+index 325db9c4c6109..53f1b08017aab 100644 |
30058 |
+--- a/net/bluetooth/hci_core.c |
30059 |
++++ b/net/bluetooth/hci_core.c |
30060 |
+@@ -3999,6 +3999,7 @@ int hci_register_dev(struct hci_dev *hdev) |
30061 |
+ return id; |
30062 |
+ |
30063 |
+ err_wqueue: |
30064 |
++ debugfs_remove_recursive(hdev->debugfs); |
30065 |
+ destroy_workqueue(hdev->workqueue); |
30066 |
+ destroy_workqueue(hdev->req_workqueue); |
30067 |
+ err: |
30068 |
+diff --git a/net/bluetooth/hci_event.c b/net/bluetooth/hci_event.c |
30069 |
+index 0bca035bf2dcc..20e36126bbdae 100644 |
30070 |
+--- a/net/bluetooth/hci_event.c |
30071 |
++++ b/net/bluetooth/hci_event.c |
30072 |
+@@ -1325,8 +1325,10 @@ static void hci_cc_le_set_ext_adv_enable(struct hci_dev *hdev, |
30073 |
+ &conn->le_conn_timeout, |
30074 |
+ conn->conn_timeout); |
30075 |
+ } else { |
30076 |
+- if (adv) { |
30077 |
+- adv->enabled = false; |
30078 |
++ if (cp->num_of_sets) { |
30079 |
++ if (adv) |
30080 |
++ adv->enabled = false; |
30081 |
++ |
30082 |
+ /* If just one instance was disabled check if there are |
30083 |
+ * any other instance enabled before clearing HCI_LE_ADV |
30084 |
+ */ |
30085 |
+@@ -5780,7 +5782,8 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) |
30086 |
+ struct hci_ev_le_advertising_info *ev = ptr; |
30087 |
+ s8 rssi; |
30088 |
+ |
30089 |
+- if (ev->length <= HCI_MAX_AD_LENGTH) { |
30090 |
++ if (ev->length <= HCI_MAX_AD_LENGTH && |
30091 |
++ ev->data + ev->length <= skb_tail_pointer(skb)) { |
30092 |
+ rssi = ev->data[ev->length]; |
30093 |
+ process_adv_report(hdev, ev->evt_type, &ev->bdaddr, |
30094 |
+ ev->bdaddr_type, NULL, 0, rssi, |
30095 |
+@@ -5790,6 +5793,11 @@ static void hci_le_adv_report_evt(struct hci_dev *hdev, struct sk_buff *skb) |
30096 |
+ } |
30097 |
+ |
30098 |
+ ptr += sizeof(*ev) + ev->length + 1; |
30099 |
++ |
30100 |
++ if (ptr > (void *) skb_tail_pointer(skb) - sizeof(*ev)) { |
30101 |
++ bt_dev_err(hdev, "Malicious advertising data. Stopping processing"); |
30102 |
++ break; |
30103 |
++ } |
30104 |
+ } |
30105 |
+ |
30106 |
+ hci_dev_unlock(hdev); |
30107 |
+diff --git a/net/bluetooth/hci_request.c b/net/bluetooth/hci_request.c |
30108 |
+index f15626607b2d6..1d34d330afd34 100644 |
30109 |
+--- a/net/bluetooth/hci_request.c |
30110 |
++++ b/net/bluetooth/hci_request.c |
30111 |
+@@ -2318,7 +2318,7 @@ int __hci_req_enable_ext_advertising(struct hci_request *req, u8 instance) |
30112 |
+ /* Set duration per instance since controller is responsible for |
30113 |
+ * scheduling it. |
30114 |
+ */ |
30115 |
+- if (adv_instance && adv_instance->duration) { |
30116 |
++ if (adv_instance && adv_instance->timeout) { |
30117 |
+ u16 duration = adv_instance->timeout * MSEC_PER_SEC; |
30118 |
+ |
30119 |
+ /* Time = N * 10 ms */ |
30120 |
+diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c |
30121 |
+index 7827639ecf5c3..4e3e0451b08c1 100644 |
30122 |
+--- a/net/bluetooth/hci_sysfs.c |
30123 |
++++ b/net/bluetooth/hci_sysfs.c |
30124 |
+@@ -86,6 +86,8 @@ static void bt_host_release(struct device *dev) |
30125 |
+ |
30126 |
+ if (hci_dev_test_flag(hdev, HCI_UNREGISTER)) |
30127 |
+ hci_release_dev(hdev); |
30128 |
++ else |
30129 |
++ kfree(hdev); |
30130 |
+ module_put(THIS_MODULE); |
30131 |
+ } |
30132 |
+ |
30133 |
+diff --git a/net/bluetooth/l2cap_sock.c b/net/bluetooth/l2cap_sock.c |
30134 |
+index 160c016a5dfb9..d2c6785205992 100644 |
30135 |
+--- a/net/bluetooth/l2cap_sock.c |
30136 |
++++ b/net/bluetooth/l2cap_sock.c |
30137 |
+@@ -161,7 +161,11 @@ static int l2cap_sock_bind(struct socket *sock, struct sockaddr *addr, int alen) |
30138 |
+ break; |
30139 |
+ } |
30140 |
+ |
30141 |
+- if (chan->psm && bdaddr_type_is_le(chan->src_type)) |
30142 |
++ /* Use L2CAP_MODE_LE_FLOWCTL (CoC) in case of LE address and |
30143 |
++ * L2CAP_MODE_EXT_FLOWCTL (ECRED) has not been set. |
30144 |
++ */ |
30145 |
++ if (chan->psm && bdaddr_type_is_le(chan->src_type) && |
30146 |
++ chan->mode != L2CAP_MODE_EXT_FLOWCTL) |
30147 |
+ chan->mode = L2CAP_MODE_LE_FLOWCTL; |
30148 |
+ |
30149 |
+ chan->state = BT_BOUND; |
30150 |
+@@ -172,6 +176,21 @@ done: |
30151 |
+ return err; |
30152 |
+ } |
30153 |
+ |
30154 |
++static void l2cap_sock_init_pid(struct sock *sk) |
30155 |
++{ |
30156 |
++ struct l2cap_chan *chan = l2cap_pi(sk)->chan; |
30157 |
++ |
30158 |
++ /* Only L2CAP_MODE_EXT_FLOWCTL ever need to access the PID in order to |
30159 |
++ * group the channels being requested. |
30160 |
++ */ |
30161 |
++ if (chan->mode != L2CAP_MODE_EXT_FLOWCTL) |
30162 |
++ return; |
30163 |
++ |
30164 |
++ spin_lock(&sk->sk_peer_lock); |
30165 |
++ sk->sk_peer_pid = get_pid(task_tgid(current)); |
30166 |
++ spin_unlock(&sk->sk_peer_lock); |
30167 |
++} |
30168 |
++ |
30169 |
+ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, |
30170 |
+ int alen, int flags) |
30171 |
+ { |
30172 |
+@@ -240,9 +259,15 @@ static int l2cap_sock_connect(struct socket *sock, struct sockaddr *addr, |
30173 |
+ return -EINVAL; |
30174 |
+ } |
30175 |
+ |
30176 |
+- if (chan->psm && bdaddr_type_is_le(chan->src_type) && !chan->mode) |
30177 |
++ /* Use L2CAP_MODE_LE_FLOWCTL (CoC) in case of LE address and |
30178 |
++ * L2CAP_MODE_EXT_FLOWCTL (ECRED) has not been set. |
30179 |
++ */ |
30180 |
++ if (chan->psm && bdaddr_type_is_le(chan->src_type) && |
30181 |
++ chan->mode != L2CAP_MODE_EXT_FLOWCTL) |
30182 |
+ chan->mode = L2CAP_MODE_LE_FLOWCTL; |
30183 |
+ |
30184 |
++ l2cap_sock_init_pid(sk); |
30185 |
++ |
30186 |
+ err = l2cap_chan_connect(chan, la.l2_psm, __le16_to_cpu(la.l2_cid), |
30187 |
+ &la.l2_bdaddr, la.l2_bdaddr_type); |
30188 |
+ if (err) |
30189 |
+@@ -298,6 +323,8 @@ static int l2cap_sock_listen(struct socket *sock, int backlog) |
30190 |
+ goto done; |
30191 |
+ } |
30192 |
+ |
30193 |
++ l2cap_sock_init_pid(sk); |
30194 |
++ |
30195 |
+ sk->sk_max_ack_backlog = backlog; |
30196 |
+ sk->sk_ack_backlog = 0; |
30197 |
+ |
30198 |
+@@ -876,6 +903,8 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, |
30199 |
+ struct l2cap_conn *conn; |
30200 |
+ int len, err = 0; |
30201 |
+ u32 opt; |
30202 |
++ u16 mtu; |
30203 |
++ u8 mode; |
30204 |
+ |
30205 |
+ BT_DBG("sk %p", sk); |
30206 |
+ |
30207 |
+@@ -1058,16 +1087,16 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, |
30208 |
+ break; |
30209 |
+ } |
30210 |
+ |
30211 |
+- if (copy_from_sockptr(&opt, optval, sizeof(u16))) { |
30212 |
++ if (copy_from_sockptr(&mtu, optval, sizeof(u16))) { |
30213 |
+ err = -EFAULT; |
30214 |
+ break; |
30215 |
+ } |
30216 |
+ |
30217 |
+ if (chan->mode == L2CAP_MODE_EXT_FLOWCTL && |
30218 |
+ sk->sk_state == BT_CONNECTED) |
30219 |
+- err = l2cap_chan_reconfigure(chan, opt); |
30220 |
++ err = l2cap_chan_reconfigure(chan, mtu); |
30221 |
+ else |
30222 |
+- chan->imtu = opt; |
30223 |
++ chan->imtu = mtu; |
30224 |
+ |
30225 |
+ break; |
30226 |
+ |
30227 |
+@@ -1089,14 +1118,14 @@ static int l2cap_sock_setsockopt(struct socket *sock, int level, int optname, |
30228 |
+ break; |
30229 |
+ } |
30230 |
+ |
30231 |
+- if (copy_from_sockptr(&opt, optval, sizeof(u8))) { |
30232 |
++ if (copy_from_sockptr(&mode, optval, sizeof(u8))) { |
30233 |
+ err = -EFAULT; |
30234 |
+ break; |
30235 |
+ } |
30236 |
+ |
30237 |
+- BT_DBG("opt %u", opt); |
30238 |
++ BT_DBG("mode %u", mode); |
30239 |
+ |
30240 |
+- err = l2cap_set_mode(chan, opt); |
30241 |
++ err = l2cap_set_mode(chan, mode); |
30242 |
+ if (err) |
30243 |
+ break; |
30244 |
+ |
30245 |
+diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c |
30246 |
+index cea01e275f1ea..f09f0a78eb7be 100644 |
30247 |
+--- a/net/bluetooth/mgmt.c |
30248 |
++++ b/net/bluetooth/mgmt.c |
30249 |
+@@ -3806,7 +3806,7 @@ static const u8 rpa_resolution_uuid[16] = { |
30250 |
+ static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev, |
30251 |
+ void *data, u16 data_len) |
30252 |
+ { |
30253 |
+- char buf[62]; /* Enough space for 3 features */ |
30254 |
++ char buf[62]; /* Enough space for 3 features */ |
30255 |
+ struct mgmt_rp_read_exp_features_info *rp = (void *)buf; |
30256 |
+ u16 idx = 0; |
30257 |
+ u32 flags; |
30258 |
+@@ -3892,150 +3892,186 @@ static int exp_debug_feature_changed(bool enabled, struct sock *skip) |
30259 |
+ } |
30260 |
+ #endif |
30261 |
+ |
30262 |
+-static int set_exp_feature(struct sock *sk, struct hci_dev *hdev, |
30263 |
+- void *data, u16 data_len) |
30264 |
++#define EXP_FEAT(_uuid, _set_func) \ |
30265 |
++{ \ |
30266 |
++ .uuid = _uuid, \ |
30267 |
++ .set_func = _set_func, \ |
30268 |
++} |
30269 |
++ |
30270 |
++/* The zero key uuid is special. Multiple exp features are set through it. */ |
30271 |
++static int set_zero_key_func(struct sock *sk, struct hci_dev *hdev, |
30272 |
++ struct mgmt_cp_set_exp_feature *cp, u16 data_len) |
30273 |
+ { |
30274 |
+- struct mgmt_cp_set_exp_feature *cp = data; |
30275 |
+ struct mgmt_rp_set_exp_feature rp; |
30276 |
+ |
30277 |
+- bt_dev_dbg(hdev, "sock %p", sk); |
30278 |
+- |
30279 |
+- if (!memcmp(cp->uuid, ZERO_KEY, 16)) { |
30280 |
+- memset(rp.uuid, 0, 16); |
30281 |
+- rp.flags = cpu_to_le32(0); |
30282 |
++ memset(rp.uuid, 0, 16); |
30283 |
++ rp.flags = cpu_to_le32(0); |
30284 |
+ |
30285 |
+ #ifdef CONFIG_BT_FEATURE_DEBUG |
30286 |
+- if (!hdev) { |
30287 |
+- bool changed = bt_dbg_get(); |
30288 |
++ if (!hdev) { |
30289 |
++ bool changed = bt_dbg_get(); |
30290 |
+ |
30291 |
+- bt_dbg_set(false); |
30292 |
++ bt_dbg_set(false); |
30293 |
+ |
30294 |
+- if (changed) |
30295 |
+- exp_debug_feature_changed(false, sk); |
30296 |
+- } |
30297 |
++ if (changed) |
30298 |
++ exp_debug_feature_changed(false, sk); |
30299 |
++ } |
30300 |
+ #endif |
30301 |
+ |
30302 |
+- if (hdev && use_ll_privacy(hdev) && !hdev_is_powered(hdev)) { |
30303 |
+- bool changed = hci_dev_test_flag(hdev, |
30304 |
+- HCI_ENABLE_LL_PRIVACY); |
30305 |
+- |
30306 |
+- hci_dev_clear_flag(hdev, HCI_ENABLE_LL_PRIVACY); |
30307 |
++ if (hdev && use_ll_privacy(hdev) && !hdev_is_powered(hdev)) { |
30308 |
++ bool changed; |
30309 |
+ |
30310 |
+- if (changed) |
30311 |
+- exp_ll_privacy_feature_changed(false, hdev, sk); |
30312 |
+- } |
30313 |
++ changed = hci_dev_test_and_clear_flag(hdev, |
30314 |
++ HCI_ENABLE_LL_PRIVACY); |
30315 |
++ if (changed) |
30316 |
++ exp_ll_privacy_feature_changed(false, hdev, sk); |
30317 |
++ } |
30318 |
+ |
30319 |
+- hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS); |
30320 |
++ hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS); |
30321 |
+ |
30322 |
+- return mgmt_cmd_complete(sk, hdev ? hdev->id : MGMT_INDEX_NONE, |
30323 |
+- MGMT_OP_SET_EXP_FEATURE, 0, |
30324 |
+- &rp, sizeof(rp)); |
30325 |
+- } |
30326 |
++ return mgmt_cmd_complete(sk, hdev ? hdev->id : MGMT_INDEX_NONE, |
30327 |
++ MGMT_OP_SET_EXP_FEATURE, 0, |
30328 |
++ &rp, sizeof(rp)); |
30329 |
++} |
30330 |
+ |
30331 |
+ #ifdef CONFIG_BT_FEATURE_DEBUG |
30332 |
+- if (!memcmp(cp->uuid, debug_uuid, 16)) { |
30333 |
+- bool val, changed; |
30334 |
+- int err; |
30335 |
++static int set_debug_func(struct sock *sk, struct hci_dev *hdev, |
30336 |
++ struct mgmt_cp_set_exp_feature *cp, u16 data_len) |
30337 |
++{ |
30338 |
++ struct mgmt_rp_set_exp_feature rp; |
30339 |
+ |
30340 |
+- /* Command requires to use the non-controller index */ |
30341 |
+- if (hdev) |
30342 |
+- return mgmt_cmd_status(sk, hdev->id, |
30343 |
+- MGMT_OP_SET_EXP_FEATURE, |
30344 |
+- MGMT_STATUS_INVALID_INDEX); |
30345 |
++ bool val, changed; |
30346 |
++ int err; |
30347 |
+ |
30348 |
+- /* Parameters are limited to a single octet */ |
30349 |
+- if (data_len != MGMT_SET_EXP_FEATURE_SIZE + 1) |
30350 |
+- return mgmt_cmd_status(sk, MGMT_INDEX_NONE, |
30351 |
+- MGMT_OP_SET_EXP_FEATURE, |
30352 |
+- MGMT_STATUS_INVALID_PARAMS); |
30353 |
++ /* Command requires to use the non-controller index */ |
30354 |
++ if (hdev) |
30355 |
++ return mgmt_cmd_status(sk, hdev->id, |
30356 |
++ MGMT_OP_SET_EXP_FEATURE, |
30357 |
++ MGMT_STATUS_INVALID_INDEX); |
30358 |
+ |
30359 |
+- /* Only boolean on/off is supported */ |
30360 |
+- if (cp->param[0] != 0x00 && cp->param[0] != 0x01) |
30361 |
+- return mgmt_cmd_status(sk, MGMT_INDEX_NONE, |
30362 |
+- MGMT_OP_SET_EXP_FEATURE, |
30363 |
+- MGMT_STATUS_INVALID_PARAMS); |
30364 |
++ /* Parameters are limited to a single octet */ |
30365 |
++ if (data_len != MGMT_SET_EXP_FEATURE_SIZE + 1) |
30366 |
++ return mgmt_cmd_status(sk, MGMT_INDEX_NONE, |
30367 |
++ MGMT_OP_SET_EXP_FEATURE, |
30368 |
++ MGMT_STATUS_INVALID_PARAMS); |
30369 |
+ |
30370 |
+- val = !!cp->param[0]; |
30371 |
+- changed = val ? !bt_dbg_get() : bt_dbg_get(); |
30372 |
+- bt_dbg_set(val); |
30373 |
++ /* Only boolean on/off is supported */ |
30374 |
++ if (cp->param[0] != 0x00 && cp->param[0] != 0x01) |
30375 |
++ return mgmt_cmd_status(sk, MGMT_INDEX_NONE, |
30376 |
++ MGMT_OP_SET_EXP_FEATURE, |
30377 |
++ MGMT_STATUS_INVALID_PARAMS); |
30378 |
+ |
30379 |
+- memcpy(rp.uuid, debug_uuid, 16); |
30380 |
+- rp.flags = cpu_to_le32(val ? BIT(0) : 0); |
30381 |
++ val = !!cp->param[0]; |
30382 |
++ changed = val ? !bt_dbg_get() : bt_dbg_get(); |
30383 |
++ bt_dbg_set(val); |
30384 |
+ |
30385 |
+- hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS); |
30386 |
++ memcpy(rp.uuid, debug_uuid, 16); |
30387 |
++ rp.flags = cpu_to_le32(val ? BIT(0) : 0); |
30388 |
+ |
30389 |
+- err = mgmt_cmd_complete(sk, MGMT_INDEX_NONE, |
30390 |
+- MGMT_OP_SET_EXP_FEATURE, 0, |
30391 |
+- &rp, sizeof(rp)); |
30392 |
++ hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS); |
30393 |
+ |
30394 |
+- if (changed) |
30395 |
+- exp_debug_feature_changed(val, sk); |
30396 |
++ err = mgmt_cmd_complete(sk, MGMT_INDEX_NONE, |
30397 |
++ MGMT_OP_SET_EXP_FEATURE, 0, |
30398 |
++ &rp, sizeof(rp)); |
30399 |
+ |
30400 |
+- return err; |
30401 |
+- } |
30402 |
++ if (changed) |
30403 |
++ exp_debug_feature_changed(val, sk); |
30404 |
++ |
30405 |
++ return err; |
30406 |
++} |
30407 |
+ #endif |
30408 |
+ |
30409 |
+- if (!memcmp(cp->uuid, rpa_resolution_uuid, 16)) { |
30410 |
+- bool val, changed; |
30411 |
+- int err; |
30412 |
+- u32 flags; |
30413 |
++static int set_rpa_resolution_func(struct sock *sk, struct hci_dev *hdev, |
30414 |
++ struct mgmt_cp_set_exp_feature *cp, |
30415 |
++ u16 data_len) |
30416 |
++{ |
30417 |
++ struct mgmt_rp_set_exp_feature rp; |
30418 |
++ bool val, changed; |
30419 |
++ int err; |
30420 |
++ u32 flags; |
30421 |
+ |
30422 |
+- /* Command requires to use the controller index */ |
30423 |
+- if (!hdev) |
30424 |
+- return mgmt_cmd_status(sk, MGMT_INDEX_NONE, |
30425 |
+- MGMT_OP_SET_EXP_FEATURE, |
30426 |
+- MGMT_STATUS_INVALID_INDEX); |
30427 |
++ /* Command requires to use the controller index */ |
30428 |
++ if (!hdev) |
30429 |
++ return mgmt_cmd_status(sk, MGMT_INDEX_NONE, |
30430 |
++ MGMT_OP_SET_EXP_FEATURE, |
30431 |
++ MGMT_STATUS_INVALID_INDEX); |
30432 |
+ |
30433 |
+- /* Changes can only be made when controller is powered down */ |
30434 |
+- if (hdev_is_powered(hdev)) |
30435 |
+- return mgmt_cmd_status(sk, hdev->id, |
30436 |
+- MGMT_OP_SET_EXP_FEATURE, |
30437 |
+- MGMT_STATUS_REJECTED); |
30438 |
++ /* Changes can only be made when controller is powered down */ |
30439 |
++ if (hdev_is_powered(hdev)) |
30440 |
++ return mgmt_cmd_status(sk, hdev->id, |
30441 |
++ MGMT_OP_SET_EXP_FEATURE, |
30442 |
++ MGMT_STATUS_REJECTED); |
30443 |
+ |
30444 |
+- /* Parameters are limited to a single octet */ |
30445 |
+- if (data_len != MGMT_SET_EXP_FEATURE_SIZE + 1) |
30446 |
+- return mgmt_cmd_status(sk, hdev->id, |
30447 |
+- MGMT_OP_SET_EXP_FEATURE, |
30448 |
+- MGMT_STATUS_INVALID_PARAMS); |
30449 |
++ /* Parameters are limited to a single octet */ |
30450 |
++ if (data_len != MGMT_SET_EXP_FEATURE_SIZE + 1) |
30451 |
++ return mgmt_cmd_status(sk, hdev->id, |
30452 |
++ MGMT_OP_SET_EXP_FEATURE, |
30453 |
++ MGMT_STATUS_INVALID_PARAMS); |
30454 |
+ |
30455 |
+- /* Only boolean on/off is supported */ |
30456 |
+- if (cp->param[0] != 0x00 && cp->param[0] != 0x01) |
30457 |
+- return mgmt_cmd_status(sk, hdev->id, |
30458 |
+- MGMT_OP_SET_EXP_FEATURE, |
30459 |
+- MGMT_STATUS_INVALID_PARAMS); |
30460 |
++ /* Only boolean on/off is supported */ |
30461 |
++ if (cp->param[0] != 0x00 && cp->param[0] != 0x01) |
30462 |
++ return mgmt_cmd_status(sk, hdev->id, |
30463 |
++ MGMT_OP_SET_EXP_FEATURE, |
30464 |
++ MGMT_STATUS_INVALID_PARAMS); |
30465 |
+ |
30466 |
+- val = !!cp->param[0]; |
30467 |
++ val = !!cp->param[0]; |
30468 |
+ |
30469 |
+- if (val) { |
30470 |
+- changed = !hci_dev_test_flag(hdev, |
30471 |
++ if (val) { |
30472 |
++ changed = !hci_dev_test_and_set_flag(hdev, |
30473 |
+ HCI_ENABLE_LL_PRIVACY); |
30474 |
+- hci_dev_set_flag(hdev, HCI_ENABLE_LL_PRIVACY); |
30475 |
+- hci_dev_clear_flag(hdev, HCI_ADVERTISING); |
30476 |
++ hci_dev_clear_flag(hdev, HCI_ADVERTISING); |
30477 |
+ |
30478 |
+- /* Enable LL privacy + supported settings changed */ |
30479 |
+- flags = BIT(0) | BIT(1); |
30480 |
+- } else { |
30481 |
+- changed = hci_dev_test_flag(hdev, |
30482 |
+- HCI_ENABLE_LL_PRIVACY); |
30483 |
+- hci_dev_clear_flag(hdev, HCI_ENABLE_LL_PRIVACY); |
30484 |
++ /* Enable LL privacy + supported settings changed */ |
30485 |
++ flags = BIT(0) | BIT(1); |
30486 |
++ } else { |
30487 |
++ changed = hci_dev_test_and_clear_flag(hdev, |
30488 |
++ HCI_ENABLE_LL_PRIVACY); |
30489 |
+ |
30490 |
+- /* Disable LL privacy + supported settings changed */ |
30491 |
+- flags = BIT(1); |
30492 |
+- } |
30493 |
++ /* Disable LL privacy + supported settings changed */ |
30494 |
++ flags = BIT(1); |
30495 |
++ } |
30496 |
+ |
30497 |
+- memcpy(rp.uuid, rpa_resolution_uuid, 16); |
30498 |
+- rp.flags = cpu_to_le32(flags); |
30499 |
++ memcpy(rp.uuid, rpa_resolution_uuid, 16); |
30500 |
++ rp.flags = cpu_to_le32(flags); |
30501 |
+ |
30502 |
+- hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS); |
30503 |
++ hci_sock_set_flag(sk, HCI_MGMT_EXP_FEATURE_EVENTS); |
30504 |
+ |
30505 |
+- err = mgmt_cmd_complete(sk, hdev->id, |
30506 |
+- MGMT_OP_SET_EXP_FEATURE, 0, |
30507 |
+- &rp, sizeof(rp)); |
30508 |
++ err = mgmt_cmd_complete(sk, hdev->id, |
30509 |
++ MGMT_OP_SET_EXP_FEATURE, 0, |
30510 |
++ &rp, sizeof(rp)); |
30511 |
+ |
30512 |
+- if (changed) |
30513 |
+- exp_ll_privacy_feature_changed(val, hdev, sk); |
30514 |
++ if (changed) |
30515 |
++ exp_ll_privacy_feature_changed(val, hdev, sk); |
30516 |
+ |
30517 |
+- return err; |
30518 |
++ return err; |
30519 |
++} |
30520 |
++ |
30521 |
++static const struct mgmt_exp_feature { |
30522 |
++ const u8 *uuid; |
30523 |
++ int (*set_func)(struct sock *sk, struct hci_dev *hdev, |
30524 |
++ struct mgmt_cp_set_exp_feature *cp, u16 data_len); |
30525 |
++} exp_features[] = { |
30526 |
++ EXP_FEAT(ZERO_KEY, set_zero_key_func), |
30527 |
++#ifdef CONFIG_BT_FEATURE_DEBUG |
30528 |
++ EXP_FEAT(debug_uuid, set_debug_func), |
30529 |
++#endif |
30530 |
++ EXP_FEAT(rpa_resolution_uuid, set_rpa_resolution_func), |
30531 |
++ |
30532 |
++ /* end with a null feature */ |
30533 |
++ EXP_FEAT(NULL, NULL) |
30534 |
++}; |
30535 |
++ |
30536 |
++static int set_exp_feature(struct sock *sk, struct hci_dev *hdev, |
30537 |
++ void *data, u16 data_len) |
30538 |
++{ |
30539 |
++ struct mgmt_cp_set_exp_feature *cp = data; |
30540 |
++ size_t i = 0; |
30541 |
++ |
30542 |
++ bt_dev_dbg(hdev, "sock %p", sk); |
30543 |
++ |
30544 |
++ for (i = 0; exp_features[i].uuid; i++) { |
30545 |
++ if (!memcmp(cp->uuid, exp_features[i].uuid, 16)) |
30546 |
++ return exp_features[i].set_func(sk, hdev, cp, data_len); |
30547 |
+ } |
30548 |
+ |
30549 |
+ return mgmt_cmd_status(sk, hdev ? hdev->id : MGMT_INDEX_NONE, |
30550 |
+diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c |
30551 |
+index 8edfb98ae1d58..68c0d0f928908 100644 |
30552 |
+--- a/net/bridge/br_netfilter_hooks.c |
30553 |
++++ b/net/bridge/br_netfilter_hooks.c |
30554 |
+@@ -743,6 +743,9 @@ static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff |
30555 |
+ if (nf_bridge->frag_max_size && nf_bridge->frag_max_size < mtu) |
30556 |
+ mtu = nf_bridge->frag_max_size; |
30557 |
+ |
30558 |
++ nf_bridge_update_protocol(skb); |
30559 |
++ nf_bridge_push_encap_header(skb); |
30560 |
++ |
30561 |
+ if (skb_is_gso(skb) || skb->len + mtu_reserved <= mtu) { |
30562 |
+ nf_bridge_info_free(skb); |
30563 |
+ return br_dev_queue_push_xmit(net, sk, skb); |
30564 |
+@@ -760,8 +763,6 @@ static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff |
30565 |
+ |
30566 |
+ IPCB(skb)->frag_max_size = nf_bridge->frag_max_size; |
30567 |
+ |
30568 |
+- nf_bridge_update_protocol(skb); |
30569 |
+- |
30570 |
+ data = this_cpu_ptr(&brnf_frag_data_storage); |
30571 |
+ |
30572 |
+ if (skb_vlan_tag_present(skb)) { |
30573 |
+@@ -789,8 +790,6 @@ static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff |
30574 |
+ |
30575 |
+ IP6CB(skb)->frag_max_size = nf_bridge->frag_max_size; |
30576 |
+ |
30577 |
+- nf_bridge_update_protocol(skb); |
30578 |
+- |
30579 |
+ data = this_cpu_ptr(&brnf_frag_data_storage); |
30580 |
+ data->encap_size = nf_bridge_encap_header_len(skb); |
30581 |
+ data->size = ETH_HLEN + data->encap_size; |
30582 |
+diff --git a/net/core/dev.c b/net/core/dev.c |
30583 |
+index e0878a500aa92..33dc2a3ff7d78 100644 |
30584 |
+--- a/net/core/dev.c |
30585 |
++++ b/net/core/dev.c |
30586 |
+@@ -9636,6 +9636,12 @@ static int bpf_xdp_link_update(struct bpf_link *link, struct bpf_prog *new_prog, |
30587 |
+ goto out_unlock; |
30588 |
+ } |
30589 |
+ old_prog = link->prog; |
30590 |
++ if (old_prog->type != new_prog->type || |
30591 |
++ old_prog->expected_attach_type != new_prog->expected_attach_type) { |
30592 |
++ err = -EINVAL; |
30593 |
++ goto out_unlock; |
30594 |
++ } |
30595 |
++ |
30596 |
+ if (old_prog == new_prog) { |
30597 |
+ /* no-op, don't disturb drivers */ |
30598 |
+ bpf_prog_put(new_prog); |
30599 |
+diff --git a/net/core/devlink.c b/net/core/devlink.c |
30600 |
+index 6931713e363fd..db76c55e1a6d7 100644 |
30601 |
+--- a/net/core/devlink.c |
30602 |
++++ b/net/core/devlink.c |
30603 |
+@@ -8795,8 +8795,6 @@ static const struct genl_small_ops devlink_nl_ops[] = { |
30604 |
+ GENL_DONT_VALIDATE_DUMP_STRICT, |
30605 |
+ .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit, |
30606 |
+ .flags = GENL_ADMIN_PERM, |
30607 |
+- .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT | |
30608 |
+- DEVLINK_NL_FLAG_NO_LOCK, |
30609 |
+ }, |
30610 |
+ { |
30611 |
+ .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR, |
30612 |
+diff --git a/net/core/filter.c b/net/core/filter.c |
30613 |
+index 1e6831880d1fd..f207e4782bd0e 100644 |
30614 |
+--- a/net/core/filter.c |
30615 |
++++ b/net/core/filter.c |
30616 |
+@@ -4742,12 +4742,14 @@ static int _bpf_setsockopt(struct sock *sk, int level, int optname, |
30617 |
+ switch (optname) { |
30618 |
+ case SO_RCVBUF: |
30619 |
+ val = min_t(u32, val, sysctl_rmem_max); |
30620 |
++ val = min_t(int, val, INT_MAX / 2); |
30621 |
+ sk->sk_userlocks |= SOCK_RCVBUF_LOCK; |
30622 |
+ WRITE_ONCE(sk->sk_rcvbuf, |
30623 |
+ max_t(int, val * 2, SOCK_MIN_RCVBUF)); |
30624 |
+ break; |
30625 |
+ case SO_SNDBUF: |
30626 |
+ val = min_t(u32, val, sysctl_wmem_max); |
30627 |
++ val = min_t(int, val, INT_MAX / 2); |
30628 |
+ sk->sk_userlocks |= SOCK_SNDBUF_LOCK; |
30629 |
+ WRITE_ONCE(sk->sk_sndbuf, |
30630 |
+ max_t(int, val * 2, SOCK_MIN_SNDBUF)); |
30631 |
+@@ -8176,9 +8178,9 @@ void bpf_warn_invalid_xdp_action(u32 act) |
30632 |
+ { |
30633 |
+ const u32 act_max = XDP_REDIRECT; |
30634 |
+ |
30635 |
+- WARN_ONCE(1, "%s XDP return value %u, expect packet loss!\n", |
30636 |
+- act > act_max ? "Illegal" : "Driver unsupported", |
30637 |
+- act); |
30638 |
++ pr_warn_once("%s XDP return value %u, expect packet loss!\n", |
30639 |
++ act > act_max ? "Illegal" : "Driver unsupported", |
30640 |
++ act); |
30641 |
+ } |
30642 |
+ EXPORT_SYMBOL_GPL(bpf_warn_invalid_xdp_action); |
30643 |
+ |
30644 |
+diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c |
30645 |
+index bac0184cf3de7..edffdaa875f1f 100644 |
30646 |
+--- a/net/core/flow_dissector.c |
30647 |
++++ b/net/core/flow_dissector.c |
30648 |
+@@ -238,7 +238,7 @@ void |
30649 |
+ skb_flow_dissect_ct(const struct sk_buff *skb, |
30650 |
+ struct flow_dissector *flow_dissector, |
30651 |
+ void *target_container, u16 *ctinfo_map, |
30652 |
+- size_t mapsize, bool post_ct) |
30653 |
++ size_t mapsize, bool post_ct, u16 zone) |
30654 |
+ { |
30655 |
+ #if IS_ENABLED(CONFIG_NF_CONNTRACK) |
30656 |
+ struct flow_dissector_key_ct *key; |
30657 |
+@@ -260,6 +260,7 @@ skb_flow_dissect_ct(const struct sk_buff *skb, |
30658 |
+ if (!ct) { |
30659 |
+ key->ct_state = TCA_FLOWER_KEY_CT_FLAGS_TRACKED | |
30660 |
+ TCA_FLOWER_KEY_CT_FLAGS_INVALID; |
30661 |
++ key->ct_zone = zone; |
30662 |
+ return; |
30663 |
+ } |
30664 |
+ |
30665 |
+diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c |
30666 |
+index dfa5ecff7f738..a4ae652633844 100644 |
30667 |
+--- a/net/core/net-sysfs.c |
30668 |
++++ b/net/core/net-sysfs.c |
30669 |
+@@ -1820,6 +1820,9 @@ static void remove_queue_kobjects(struct net_device *dev) |
30670 |
+ |
30671 |
+ net_rx_queue_update_kobjects(dev, real_rx, 0); |
30672 |
+ netdev_queue_update_kobjects(dev, real_tx, 0); |
30673 |
++ |
30674 |
++ dev->real_num_rx_queues = 0; |
30675 |
++ dev->real_num_tx_queues = 0; |
30676 |
+ #ifdef CONFIG_SYSFS |
30677 |
+ kset_unregister(dev->queues_kset); |
30678 |
+ #endif |
30679 |
+diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c |
30680 |
+index 202fa5eacd0f9..9702d2b0d9207 100644 |
30681 |
+--- a/net/core/net_namespace.c |
30682 |
++++ b/net/core/net_namespace.c |
30683 |
+@@ -164,8 +164,10 @@ static void ops_exit_list(const struct pernet_operations *ops, |
30684 |
+ { |
30685 |
+ struct net *net; |
30686 |
+ if (ops->exit) { |
30687 |
+- list_for_each_entry(net, net_exit_list, exit_list) |
30688 |
++ list_for_each_entry(net, net_exit_list, exit_list) { |
30689 |
+ ops->exit(net); |
30690 |
++ cond_resched(); |
30691 |
++ } |
30692 |
+ } |
30693 |
+ if (ops->exit_batch) |
30694 |
+ ops->exit_batch(net_exit_list); |
30695 |
+diff --git a/net/core/sock.c b/net/core/sock.c |
30696 |
+index 1b31e10181629..6ea317f84edd2 100644 |
30697 |
+--- a/net/core/sock.c |
30698 |
++++ b/net/core/sock.c |
30699 |
+@@ -830,6 +830,8 @@ static int sock_timestamping_bind_phc(struct sock *sk, int phc_index) |
30700 |
+ } |
30701 |
+ |
30702 |
+ num = ethtool_get_phc_vclocks(dev, &vclock_index); |
30703 |
++ dev_put(dev); |
30704 |
++ |
30705 |
+ for (i = 0; i < num; i++) { |
30706 |
+ if (*(vclock_index + i) == phc_index) { |
30707 |
+ match = true; |
30708 |
+diff --git a/net/core/sock_map.c b/net/core/sock_map.c |
30709 |
+index c89f527411e84..8288b5382f08d 100644 |
30710 |
+--- a/net/core/sock_map.c |
30711 |
++++ b/net/core/sock_map.c |
30712 |
+@@ -292,15 +292,23 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk) |
30713 |
+ if (skb_verdict) |
30714 |
+ psock_set_prog(&psock->progs.skb_verdict, skb_verdict); |
30715 |
+ |
30716 |
++ /* msg_* and stream_* programs references tracked in psock after this |
30717 |
++ * point. Reference dec and cleanup will occur through psock destructor |
30718 |
++ */ |
30719 |
+ ret = sock_map_init_proto(sk, psock); |
30720 |
+- if (ret < 0) |
30721 |
+- goto out_drop; |
30722 |
++ if (ret < 0) { |
30723 |
++ sk_psock_put(sk, psock); |
30724 |
++ goto out; |
30725 |
++ } |
30726 |
+ |
30727 |
+ write_lock_bh(&sk->sk_callback_lock); |
30728 |
+ if (stream_parser && stream_verdict && !psock->saved_data_ready) { |
30729 |
+ ret = sk_psock_init_strp(sk, psock); |
30730 |
+- if (ret) |
30731 |
+- goto out_unlock_drop; |
30732 |
++ if (ret) { |
30733 |
++ write_unlock_bh(&sk->sk_callback_lock); |
30734 |
++ sk_psock_put(sk, psock); |
30735 |
++ goto out; |
30736 |
++ } |
30737 |
+ sk_psock_start_strp(sk, psock); |
30738 |
+ } else if (!stream_parser && stream_verdict && !psock->saved_data_ready) { |
30739 |
+ sk_psock_start_verdict(sk,psock); |
30740 |
+@@ -309,10 +317,6 @@ static int sock_map_link(struct bpf_map *map, struct sock *sk) |
30741 |
+ } |
30742 |
+ write_unlock_bh(&sk->sk_callback_lock); |
30743 |
+ return 0; |
30744 |
+-out_unlock_drop: |
30745 |
+- write_unlock_bh(&sk->sk_callback_lock); |
30746 |
+-out_drop: |
30747 |
+- sk_psock_put(sk, psock); |
30748 |
+ out_progs: |
30749 |
+ if (skb_verdict) |
30750 |
+ bpf_prog_put(skb_verdict); |
30751 |
+@@ -325,6 +329,7 @@ out_put_stream_parser: |
30752 |
+ out_put_stream_verdict: |
30753 |
+ if (stream_verdict) |
30754 |
+ bpf_prog_put(stream_verdict); |
30755 |
++out: |
30756 |
+ return ret; |
30757 |
+ } |
30758 |
+ |
30759 |
+diff --git a/net/dsa/switch.c b/net/dsa/switch.c |
30760 |
+index 44558fbdc65b3..fb69f2f14234e 100644 |
30761 |
+--- a/net/dsa/switch.c |
30762 |
++++ b/net/dsa/switch.c |
30763 |
+@@ -644,7 +644,7 @@ static int |
30764 |
+ dsa_switch_mrp_add_ring_role(struct dsa_switch *ds, |
30765 |
+ struct dsa_notifier_mrp_ring_role_info *info) |
30766 |
+ { |
30767 |
+- if (!ds->ops->port_mrp_add) |
30768 |
++ if (!ds->ops->port_mrp_add_ring_role) |
30769 |
+ return -EOPNOTSUPP; |
30770 |
+ |
30771 |
+ if (ds->index == info->sw_index) |
30772 |
+@@ -658,7 +658,7 @@ static int |
30773 |
+ dsa_switch_mrp_del_ring_role(struct dsa_switch *ds, |
30774 |
+ struct dsa_notifier_mrp_ring_role_info *info) |
30775 |
+ { |
30776 |
+- if (!ds->ops->port_mrp_del) |
30777 |
++ if (!ds->ops->port_mrp_del_ring_role) |
30778 |
+ return -EOPNOTSUPP; |
30779 |
+ |
30780 |
+ if (ds->index == info->sw_index) |
30781 |
+diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c |
30782 |
+index 92c29ab3d0428..5dfb94abe7b10 100644 |
30783 |
+--- a/net/ipv4/fib_semantics.c |
30784 |
++++ b/net/ipv4/fib_semantics.c |
30785 |
+@@ -29,6 +29,7 @@ |
30786 |
+ #include <linux/init.h> |
30787 |
+ #include <linux/slab.h> |
30788 |
+ #include <linux/netlink.h> |
30789 |
++#include <linux/hash.h> |
30790 |
+ |
30791 |
+ #include <net/arp.h> |
30792 |
+ #include <net/ip.h> |
30793 |
+@@ -249,7 +250,6 @@ void free_fib_info(struct fib_info *fi) |
30794 |
+ pr_warn("Freeing alive fib_info %p\n", fi); |
30795 |
+ return; |
30796 |
+ } |
30797 |
+- fib_info_cnt--; |
30798 |
+ |
30799 |
+ call_rcu(&fi->rcu, free_fib_info_rcu); |
30800 |
+ } |
30801 |
+@@ -260,6 +260,10 @@ void fib_release_info(struct fib_info *fi) |
30802 |
+ spin_lock_bh(&fib_info_lock); |
30803 |
+ if (fi && refcount_dec_and_test(&fi->fib_treeref)) { |
30804 |
+ hlist_del(&fi->fib_hash); |
30805 |
++ |
30806 |
++ /* Paired with READ_ONCE() in fib_create_info(). */ |
30807 |
++ WRITE_ONCE(fib_info_cnt, fib_info_cnt - 1); |
30808 |
++ |
30809 |
+ if (fi->fib_prefsrc) |
30810 |
+ hlist_del(&fi->fib_lhash); |
30811 |
+ if (fi->nh) { |
30812 |
+@@ -316,11 +320,15 @@ static inline int nh_comp(struct fib_info *fi, struct fib_info *ofi) |
30813 |
+ |
30814 |
+ static inline unsigned int fib_devindex_hashfn(unsigned int val) |
30815 |
+ { |
30816 |
+- unsigned int mask = DEVINDEX_HASHSIZE - 1; |
30817 |
++ return hash_32(val, DEVINDEX_HASHBITS); |
30818 |
++} |
30819 |
++ |
30820 |
++static struct hlist_head * |
30821 |
++fib_info_devhash_bucket(const struct net_device *dev) |
30822 |
++{ |
30823 |
++ u32 val = net_hash_mix(dev_net(dev)) ^ dev->ifindex; |
30824 |
+ |
30825 |
+- return (val ^ |
30826 |
+- (val >> DEVINDEX_HASHBITS) ^ |
30827 |
+- (val >> (DEVINDEX_HASHBITS * 2))) & mask; |
30828 |
++ return &fib_info_devhash[fib_devindex_hashfn(val)]; |
30829 |
+ } |
30830 |
+ |
30831 |
+ static unsigned int fib_info_hashfn_1(int init_val, u8 protocol, u8 scope, |
30832 |
+@@ -430,12 +438,11 @@ int ip_fib_check_default(__be32 gw, struct net_device *dev) |
30833 |
+ { |
30834 |
+ struct hlist_head *head; |
30835 |
+ struct fib_nh *nh; |
30836 |
+- unsigned int hash; |
30837 |
+ |
30838 |
+ spin_lock(&fib_info_lock); |
30839 |
+ |
30840 |
+- hash = fib_devindex_hashfn(dev->ifindex); |
30841 |
+- head = &fib_info_devhash[hash]; |
30842 |
++ head = fib_info_devhash_bucket(dev); |
30843 |
++ |
30844 |
+ hlist_for_each_entry(nh, head, nh_hash) { |
30845 |
+ if (nh->fib_nh_dev == dev && |
30846 |
+ nh->fib_nh_gw4 == gw && |
30847 |
+@@ -1430,7 +1437,9 @@ struct fib_info *fib_create_info(struct fib_config *cfg, |
30848 |
+ #endif |
30849 |
+ |
30850 |
+ err = -ENOBUFS; |
30851 |
+- if (fib_info_cnt >= fib_info_hash_size) { |
30852 |
++ |
30853 |
++ /* Paired with WRITE_ONCE() in fib_release_info() */ |
30854 |
++ if (READ_ONCE(fib_info_cnt) >= fib_info_hash_size) { |
30855 |
+ unsigned int new_size = fib_info_hash_size << 1; |
30856 |
+ struct hlist_head *new_info_hash; |
30857 |
+ struct hlist_head *new_laddrhash; |
30858 |
+@@ -1462,7 +1471,6 @@ struct fib_info *fib_create_info(struct fib_config *cfg, |
30859 |
+ return ERR_PTR(err); |
30860 |
+ } |
30861 |
+ |
30862 |
+- fib_info_cnt++; |
30863 |
+ fi->fib_net = net; |
30864 |
+ fi->fib_protocol = cfg->fc_protocol; |
30865 |
+ fi->fib_scope = cfg->fc_scope; |
30866 |
+@@ -1589,6 +1597,7 @@ link_it: |
30867 |
+ refcount_set(&fi->fib_treeref, 1); |
30868 |
+ refcount_set(&fi->fib_clntref, 1); |
30869 |
+ spin_lock_bh(&fib_info_lock); |
30870 |
++ fib_info_cnt++; |
30871 |
+ hlist_add_head(&fi->fib_hash, |
30872 |
+ &fib_info_hash[fib_info_hashfn(fi)]); |
30873 |
+ if (fi->fib_prefsrc) { |
30874 |
+@@ -1602,12 +1611,10 @@ link_it: |
30875 |
+ } else { |
30876 |
+ change_nexthops(fi) { |
30877 |
+ struct hlist_head *head; |
30878 |
+- unsigned int hash; |
30879 |
+ |
30880 |
+ if (!nexthop_nh->fib_nh_dev) |
30881 |
+ continue; |
30882 |
+- hash = fib_devindex_hashfn(nexthop_nh->fib_nh_dev->ifindex); |
30883 |
+- head = &fib_info_devhash[hash]; |
30884 |
++ head = fib_info_devhash_bucket(nexthop_nh->fib_nh_dev); |
30885 |
+ hlist_add_head(&nexthop_nh->nh_hash, head); |
30886 |
+ } endfor_nexthops(fi) |
30887 |
+ } |
30888 |
+@@ -1959,8 +1966,7 @@ void fib_nhc_update_mtu(struct fib_nh_common *nhc, u32 new, u32 orig) |
30889 |
+ |
30890 |
+ void fib_sync_mtu(struct net_device *dev, u32 orig_mtu) |
30891 |
+ { |
30892 |
+- unsigned int hash = fib_devindex_hashfn(dev->ifindex); |
30893 |
+- struct hlist_head *head = &fib_info_devhash[hash]; |
30894 |
++ struct hlist_head *head = fib_info_devhash_bucket(dev); |
30895 |
+ struct fib_nh *nh; |
30896 |
+ |
30897 |
+ hlist_for_each_entry(nh, head, nh_hash) { |
30898 |
+@@ -1979,12 +1985,11 @@ void fib_sync_mtu(struct net_device *dev, u32 orig_mtu) |
30899 |
+ */ |
30900 |
+ int fib_sync_down_dev(struct net_device *dev, unsigned long event, bool force) |
30901 |
+ { |
30902 |
+- int ret = 0; |
30903 |
+- int scope = RT_SCOPE_NOWHERE; |
30904 |
++ struct hlist_head *head = fib_info_devhash_bucket(dev); |
30905 |
+ struct fib_info *prev_fi = NULL; |
30906 |
+- unsigned int hash = fib_devindex_hashfn(dev->ifindex); |
30907 |
+- struct hlist_head *head = &fib_info_devhash[hash]; |
30908 |
++ int scope = RT_SCOPE_NOWHERE; |
30909 |
+ struct fib_nh *nh; |
30910 |
++ int ret = 0; |
30911 |
+ |
30912 |
+ if (force) |
30913 |
+ scope = -1; |
30914 |
+@@ -2129,7 +2134,6 @@ out: |
30915 |
+ int fib_sync_up(struct net_device *dev, unsigned char nh_flags) |
30916 |
+ { |
30917 |
+ struct fib_info *prev_fi; |
30918 |
+- unsigned int hash; |
30919 |
+ struct hlist_head *head; |
30920 |
+ struct fib_nh *nh; |
30921 |
+ int ret; |
30922 |
+@@ -2145,8 +2149,7 @@ int fib_sync_up(struct net_device *dev, unsigned char nh_flags) |
30923 |
+ } |
30924 |
+ |
30925 |
+ prev_fi = NULL; |
30926 |
+- hash = fib_devindex_hashfn(dev->ifindex); |
30927 |
+- head = &fib_info_devhash[hash]; |
30928 |
++ head = fib_info_devhash_bucket(dev); |
30929 |
+ ret = 0; |
30930 |
+ |
30931 |
+ hlist_for_each_entry(nh, head, nh_hash) { |
30932 |
+diff --git a/net/ipv4/inet_fragment.c b/net/ipv4/inet_fragment.c |
30933 |
+index 05cd198d7a6ba..341096807100c 100644 |
30934 |
+--- a/net/ipv4/inet_fragment.c |
30935 |
++++ b/net/ipv4/inet_fragment.c |
30936 |
+@@ -235,9 +235,9 @@ void inet_frag_kill(struct inet_frag_queue *fq) |
30937 |
+ /* The RCU read lock provides a memory barrier |
30938 |
+ * guaranteeing that if fqdir->dead is false then |
30939 |
+ * the hash table destruction will not start until |
30940 |
+- * after we unlock. Paired with inet_frags_exit_net(). |
30941 |
++ * after we unlock. Paired with fqdir_pre_exit(). |
30942 |
+ */ |
30943 |
+- if (!fqdir->dead) { |
30944 |
++ if (!READ_ONCE(fqdir->dead)) { |
30945 |
+ rhashtable_remove_fast(&fqdir->rhashtable, &fq->node, |
30946 |
+ fqdir->f->rhash_params); |
30947 |
+ refcount_dec(&fq->refcnt); |
30948 |
+@@ -352,9 +352,11 @@ static struct inet_frag_queue *inet_frag_create(struct fqdir *fqdir, |
30949 |
+ /* TODO : call from rcu_read_lock() and no longer use refcount_inc_not_zero() */ |
30950 |
+ struct inet_frag_queue *inet_frag_find(struct fqdir *fqdir, void *key) |
30951 |
+ { |
30952 |
++ /* This pairs with WRITE_ONCE() in fqdir_pre_exit(). */ |
30953 |
++ long high_thresh = READ_ONCE(fqdir->high_thresh); |
30954 |
+ struct inet_frag_queue *fq = NULL, *prev; |
30955 |
+ |
30956 |
+- if (!fqdir->high_thresh || frag_mem_limit(fqdir) > fqdir->high_thresh) |
30957 |
++ if (!high_thresh || frag_mem_limit(fqdir) > high_thresh) |
30958 |
+ return NULL; |
30959 |
+ |
30960 |
+ rcu_read_lock(); |
30961 |
+diff --git a/net/ipv4/ip_fragment.c b/net/ipv4/ip_fragment.c |
30962 |
+index cfeb8890f94ee..fad803d2d711e 100644 |
30963 |
+--- a/net/ipv4/ip_fragment.c |
30964 |
++++ b/net/ipv4/ip_fragment.c |
30965 |
+@@ -144,7 +144,8 @@ static void ip_expire(struct timer_list *t) |
30966 |
+ |
30967 |
+ rcu_read_lock(); |
30968 |
+ |
30969 |
+- if (qp->q.fqdir->dead) |
30970 |
++ /* Paired with WRITE_ONCE() in fqdir_pre_exit(). */ |
30971 |
++ if (READ_ONCE(qp->q.fqdir->dead)) |
30972 |
+ goto out_rcu_unlock; |
30973 |
+ |
30974 |
+ spin_lock(&qp->q.lock); |
30975 |
+diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c |
30976 |
+index 0fe6c936dc54a..e7f3e37e4aa83 100644 |
30977 |
+--- a/net/ipv4/ip_gre.c |
30978 |
++++ b/net/ipv4/ip_gre.c |
30979 |
+@@ -604,8 +604,9 @@ static int gre_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb) |
30980 |
+ |
30981 |
+ key = &info->key; |
30982 |
+ ip_tunnel_init_flow(&fl4, IPPROTO_GRE, key->u.ipv4.dst, key->u.ipv4.src, |
30983 |
+- tunnel_id_to_key32(key->tun_id), key->tos, 0, |
30984 |
+- skb->mark, skb_get_hash(skb)); |
30985 |
++ tunnel_id_to_key32(key->tun_id), |
30986 |
++ key->tos & ~INET_ECN_MASK, 0, skb->mark, |
30987 |
++ skb_get_hash(skb)); |
30988 |
+ rt = ip_route_output_key(dev_net(dev), &fl4); |
30989 |
+ if (IS_ERR(rt)) |
30990 |
+ return PTR_ERR(rt); |
30991 |
+diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c |
30992 |
+index 8fd1aba8af31c..b518f20c9a244 100644 |
30993 |
+--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c |
30994 |
++++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c |
30995 |
+@@ -520,8 +520,11 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par) |
30996 |
+ if (IS_ERR(config)) |
30997 |
+ return PTR_ERR(config); |
30998 |
+ } |
30999 |
+- } else if (memcmp(&config->clustermac, &cipinfo->clustermac, ETH_ALEN)) |
31000 |
++ } else if (memcmp(&config->clustermac, &cipinfo->clustermac, ETH_ALEN)) { |
31001 |
++ clusterip_config_entry_put(config); |
31002 |
++ clusterip_config_put(config); |
31003 |
+ return -EINVAL; |
31004 |
++ } |
31005 |
+ |
31006 |
+ ret = nf_ct_netns_get(par->net, par->family); |
31007 |
+ if (ret < 0) { |
31008 |
+diff --git a/net/ipv4/tcp_bpf.c b/net/ipv4/tcp_bpf.c |
31009 |
+index f70aa0932bd6c..9b9b02052fd36 100644 |
31010 |
+--- a/net/ipv4/tcp_bpf.c |
31011 |
++++ b/net/ipv4/tcp_bpf.c |
31012 |
+@@ -196,12 +196,39 @@ msg_bytes_ready: |
31013 |
+ long timeo; |
31014 |
+ int data; |
31015 |
+ |
31016 |
++ if (sock_flag(sk, SOCK_DONE)) |
31017 |
++ goto out; |
31018 |
++ |
31019 |
++ if (sk->sk_err) { |
31020 |
++ copied = sock_error(sk); |
31021 |
++ goto out; |
31022 |
++ } |
31023 |
++ |
31024 |
++ if (sk->sk_shutdown & RCV_SHUTDOWN) |
31025 |
++ goto out; |
31026 |
++ |
31027 |
++ if (sk->sk_state == TCP_CLOSE) { |
31028 |
++ copied = -ENOTCONN; |
31029 |
++ goto out; |
31030 |
++ } |
31031 |
++ |
31032 |
+ timeo = sock_rcvtimeo(sk, nonblock); |
31033 |
++ if (!timeo) { |
31034 |
++ copied = -EAGAIN; |
31035 |
++ goto out; |
31036 |
++ } |
31037 |
++ |
31038 |
++ if (signal_pending(current)) { |
31039 |
++ copied = sock_intr_errno(timeo); |
31040 |
++ goto out; |
31041 |
++ } |
31042 |
++ |
31043 |
+ data = tcp_msg_wait_data(sk, psock, timeo); |
31044 |
+ if (data && !sk_psock_queue_empty(psock)) |
31045 |
+ goto msg_bytes_ready; |
31046 |
+ copied = -EAGAIN; |
31047 |
+ } |
31048 |
++out: |
31049 |
+ release_sock(sk); |
31050 |
+ sk_psock_put(sk, psock); |
31051 |
+ return copied; |
31052 |
+diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c |
31053 |
+index a7c31ab67c5d6..96c5cc0f30ceb 100644 |
31054 |
+--- a/net/ipv6/icmp.c |
31055 |
++++ b/net/ipv6/icmp.c |
31056 |
+@@ -57,6 +57,7 @@ |
31057 |
+ #include <net/protocol.h> |
31058 |
+ #include <net/raw.h> |
31059 |
+ #include <net/rawv6.h> |
31060 |
++#include <net/seg6.h> |
31061 |
+ #include <net/transp_v6.h> |
31062 |
+ #include <net/ip6_route.h> |
31063 |
+ #include <net/addrconf.h> |
31064 |
+@@ -820,6 +821,7 @@ out_bh_enable: |
31065 |
+ |
31066 |
+ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info) |
31067 |
+ { |
31068 |
++ struct inet6_skb_parm *opt = IP6CB(skb); |
31069 |
+ const struct inet6_protocol *ipprot; |
31070 |
+ int inner_offset; |
31071 |
+ __be16 frag_off; |
31072 |
+@@ -829,6 +831,8 @@ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info) |
31073 |
+ if (!pskb_may_pull(skb, sizeof(struct ipv6hdr))) |
31074 |
+ goto out; |
31075 |
+ |
31076 |
++ seg6_icmp_srh(skb, opt); |
31077 |
++ |
31078 |
+ nexthdr = ((struct ipv6hdr *)skb->data)->nexthdr; |
31079 |
+ if (ipv6_ext_hdr(nexthdr)) { |
31080 |
+ /* now skip over extension headers */ |
31081 |
+@@ -853,7 +857,7 @@ void icmpv6_notify(struct sk_buff *skb, u8 type, u8 code, __be32 info) |
31082 |
+ |
31083 |
+ ipprot = rcu_dereference(inet6_protos[nexthdr]); |
31084 |
+ if (ipprot && ipprot->err_handler) |
31085 |
+- ipprot->err_handler(skb, NULL, type, code, inner_offset, info); |
31086 |
++ ipprot->err_handler(skb, opt, type, code, inner_offset, info); |
31087 |
+ |
31088 |
+ raw6_icmp_error(skb, nexthdr, type, code, inner_offset, info); |
31089 |
+ return; |
31090 |
+diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c |
31091 |
+index 3ad201d372d88..466a5610e3ca9 100644 |
31092 |
+--- a/net/ipv6/ip6_gre.c |
31093 |
++++ b/net/ipv6/ip6_gre.c |
31094 |
+@@ -755,6 +755,7 @@ static netdev_tx_t __gre6_xmit(struct sk_buff *skb, |
31095 |
+ fl6->daddr = key->u.ipv6.dst; |
31096 |
+ fl6->flowlabel = key->label; |
31097 |
+ fl6->flowi6_uid = sock_net_uid(dev_net(dev), NULL); |
31098 |
++ fl6->fl6_gre_key = tunnel_id_to_key32(key->tun_id); |
31099 |
+ |
31100 |
+ dsfield = key->tos; |
31101 |
+ flags = key->tun_flags & |
31102 |
+@@ -990,6 +991,7 @@ static netdev_tx_t ip6erspan_tunnel_xmit(struct sk_buff *skb, |
31103 |
+ fl6.daddr = key->u.ipv6.dst; |
31104 |
+ fl6.flowlabel = key->label; |
31105 |
+ fl6.flowi6_uid = sock_net_uid(dev_net(dev), NULL); |
31106 |
++ fl6.fl6_gre_key = tunnel_id_to_key32(key->tun_id); |
31107 |
+ |
31108 |
+ dsfield = key->tos; |
31109 |
+ if (!(tun_info->key.tun_flags & TUNNEL_ERSPAN_OPT)) |
31110 |
+@@ -1098,6 +1100,7 @@ static void ip6gre_tnl_link_config_common(struct ip6_tnl *t) |
31111 |
+ fl6->flowi6_oif = p->link; |
31112 |
+ fl6->flowlabel = 0; |
31113 |
+ fl6->flowi6_proto = IPPROTO_GRE; |
31114 |
++ fl6->fl6_gre_key = t->parms.o_key; |
31115 |
+ |
31116 |
+ if (!(p->flags&IP6_TNL_F_USE_ORIG_TCLASS)) |
31117 |
+ fl6->flowlabel |= IPV6_TCLASS_MASK & p->flowinfo; |
31118 |
+@@ -1544,7 +1547,7 @@ static void ip6gre_fb_tunnel_init(struct net_device *dev) |
31119 |
+ static struct inet6_protocol ip6gre_protocol __read_mostly = { |
31120 |
+ .handler = gre_rcv, |
31121 |
+ .err_handler = ip6gre_err, |
31122 |
+- .flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL, |
31123 |
++ .flags = INET6_PROTO_FINAL, |
31124 |
+ }; |
31125 |
+ |
31126 |
+ static void ip6gre_destroy_tunnels(struct net *net, struct list_head *head) |
31127 |
+diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c |
31128 |
+index e412817fba2f3..fa6b64c95d3ae 100644 |
31129 |
+--- a/net/ipv6/seg6.c |
31130 |
++++ b/net/ipv6/seg6.c |
31131 |
+@@ -75,6 +75,65 @@ bool seg6_validate_srh(struct ipv6_sr_hdr *srh, int len, bool reduced) |
31132 |
+ return true; |
31133 |
+ } |
31134 |
+ |
31135 |
++struct ipv6_sr_hdr *seg6_get_srh(struct sk_buff *skb, int flags) |
31136 |
++{ |
31137 |
++ struct ipv6_sr_hdr *srh; |
31138 |
++ int len, srhoff = 0; |
31139 |
++ |
31140 |
++ if (ipv6_find_hdr(skb, &srhoff, IPPROTO_ROUTING, NULL, &flags) < 0) |
31141 |
++ return NULL; |
31142 |
++ |
31143 |
++ if (!pskb_may_pull(skb, srhoff + sizeof(*srh))) |
31144 |
++ return NULL; |
31145 |
++ |
31146 |
++ srh = (struct ipv6_sr_hdr *)(skb->data + srhoff); |
31147 |
++ |
31148 |
++ len = (srh->hdrlen + 1) << 3; |
31149 |
++ |
31150 |
++ if (!pskb_may_pull(skb, srhoff + len)) |
31151 |
++ return NULL; |
31152 |
++ |
31153 |
++ /* note that pskb_may_pull may change pointers in header; |
31154 |
++ * for this reason it is necessary to reload them when needed. |
31155 |
++ */ |
31156 |
++ srh = (struct ipv6_sr_hdr *)(skb->data + srhoff); |
31157 |
++ |
31158 |
++ if (!seg6_validate_srh(srh, len, true)) |
31159 |
++ return NULL; |
31160 |
++ |
31161 |
++ return srh; |
31162 |
++} |
31163 |
++ |
31164 |
++/* Determine if an ICMP invoking packet contains a segment routing |
31165 |
++ * header. If it does, extract the offset to the true destination |
31166 |
++ * address, which is in the first segment address. |
31167 |
++ */ |
31168 |
++void seg6_icmp_srh(struct sk_buff *skb, struct inet6_skb_parm *opt) |
31169 |
++{ |
31170 |
++ __u16 network_header = skb->network_header; |
31171 |
++ struct ipv6_sr_hdr *srh; |
31172 |
++ |
31173 |
++ /* Update network header to point to the invoking packet |
31174 |
++ * inside the ICMP packet, so we can use the seg6_get_srh() |
31175 |
++ * helper. |
31176 |
++ */ |
31177 |
++ skb_reset_network_header(skb); |
31178 |
++ |
31179 |
++ srh = seg6_get_srh(skb, 0); |
31180 |
++ if (!srh) |
31181 |
++ goto out; |
31182 |
++ |
31183 |
++ if (srh->type != IPV6_SRCRT_TYPE_4) |
31184 |
++ goto out; |
31185 |
++ |
31186 |
++ opt->flags |= IP6SKB_SEG6; |
31187 |
++ opt->srhoff = (unsigned char *)srh - skb->data; |
31188 |
++ |
31189 |
++out: |
31190 |
++ /* Restore the network header back to the ICMP packet */ |
31191 |
++ skb->network_header = network_header; |
31192 |
++} |
31193 |
++ |
31194 |
+ static struct genl_family seg6_genl_family; |
31195 |
+ |
31196 |
+ static const struct nla_policy seg6_genl_policy[SEG6_ATTR_MAX + 1] = { |
31197 |
+diff --git a/net/ipv6/seg6_local.c b/net/ipv6/seg6_local.c |
31198 |
+index 2dc40b3f373ef..ef88489c71f52 100644 |
31199 |
+--- a/net/ipv6/seg6_local.c |
31200 |
++++ b/net/ipv6/seg6_local.c |
31201 |
+@@ -150,40 +150,11 @@ static struct seg6_local_lwt *seg6_local_lwtunnel(struct lwtunnel_state *lwt) |
31202 |
+ return (struct seg6_local_lwt *)lwt->data; |
31203 |
+ } |
31204 |
+ |
31205 |
+-static struct ipv6_sr_hdr *get_srh(struct sk_buff *skb, int flags) |
31206 |
+-{ |
31207 |
+- struct ipv6_sr_hdr *srh; |
31208 |
+- int len, srhoff = 0; |
31209 |
+- |
31210 |
+- if (ipv6_find_hdr(skb, &srhoff, IPPROTO_ROUTING, NULL, &flags) < 0) |
31211 |
+- return NULL; |
31212 |
+- |
31213 |
+- if (!pskb_may_pull(skb, srhoff + sizeof(*srh))) |
31214 |
+- return NULL; |
31215 |
+- |
31216 |
+- srh = (struct ipv6_sr_hdr *)(skb->data + srhoff); |
31217 |
+- |
31218 |
+- len = (srh->hdrlen + 1) << 3; |
31219 |
+- |
31220 |
+- if (!pskb_may_pull(skb, srhoff + len)) |
31221 |
+- return NULL; |
31222 |
+- |
31223 |
+- /* note that pskb_may_pull may change pointers in header; |
31224 |
+- * for this reason it is necessary to reload them when needed. |
31225 |
+- */ |
31226 |
+- srh = (struct ipv6_sr_hdr *)(skb->data + srhoff); |
31227 |
+- |
31228 |
+- if (!seg6_validate_srh(srh, len, true)) |
31229 |
+- return NULL; |
31230 |
+- |
31231 |
+- return srh; |
31232 |
+-} |
31233 |
+- |
31234 |
+ static struct ipv6_sr_hdr *get_and_validate_srh(struct sk_buff *skb) |
31235 |
+ { |
31236 |
+ struct ipv6_sr_hdr *srh; |
31237 |
+ |
31238 |
+- srh = get_srh(skb, IP6_FH_F_SKIP_RH); |
31239 |
++ srh = seg6_get_srh(skb, IP6_FH_F_SKIP_RH); |
31240 |
+ if (!srh) |
31241 |
+ return NULL; |
31242 |
+ |
31243 |
+@@ -200,7 +171,7 @@ static bool decap_and_validate(struct sk_buff *skb, int proto) |
31244 |
+ struct ipv6_sr_hdr *srh; |
31245 |
+ unsigned int off = 0; |
31246 |
+ |
31247 |
+- srh = get_srh(skb, 0); |
31248 |
++ srh = seg6_get_srh(skb, 0); |
31249 |
+ if (srh && srh->segments_left > 0) |
31250 |
+ return false; |
31251 |
+ |
31252 |
+diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c |
31253 |
+index 8cd8c0bce0986..932c6f2a54946 100644 |
31254 |
+--- a/net/ipv6/udp.c |
31255 |
++++ b/net/ipv6/udp.c |
31256 |
+@@ -40,6 +40,7 @@ |
31257 |
+ #include <net/transp_v6.h> |
31258 |
+ #include <net/ip6_route.h> |
31259 |
+ #include <net/raw.h> |
31260 |
++#include <net/seg6.h> |
31261 |
+ #include <net/tcp_states.h> |
31262 |
+ #include <net/ip6_checksum.h> |
31263 |
+ #include <net/ip6_tunnel.h> |
31264 |
+@@ -561,7 +562,7 @@ int __udp6_lib_err(struct sk_buff *skb, struct inet6_skb_parm *opt, |
31265 |
+ struct ipv6_pinfo *np; |
31266 |
+ const struct ipv6hdr *hdr = (const struct ipv6hdr *)skb->data; |
31267 |
+ const struct in6_addr *saddr = &hdr->saddr; |
31268 |
+- const struct in6_addr *daddr = &hdr->daddr; |
31269 |
++ const struct in6_addr *daddr = seg6_get_daddr(skb, opt) ? : &hdr->daddr; |
31270 |
+ struct udphdr *uh = (struct udphdr *)(skb->data+offset); |
31271 |
+ bool tunnel = false; |
31272 |
+ struct sock *sk; |
31273 |
+diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c |
31274 |
+index 1958e4d59b524..92ce173dd0c13 100644 |
31275 |
+--- a/net/mac80211/rx.c |
31276 |
++++ b/net/mac80211/rx.c |
31277 |
+@@ -4933,7 +4933,7 @@ void ieee80211_rx_list(struct ieee80211_hw *hw, struct ieee80211_sta *pubsta, |
31278 |
+ goto drop; |
31279 |
+ break; |
31280 |
+ case RX_ENC_VHT: |
31281 |
+- if (WARN_ONCE(status->rate_idx > 9 || |
31282 |
++ if (WARN_ONCE(status->rate_idx > 11 || |
31283 |
+ !status->nss || |
31284 |
+ status->nss > 8, |
31285 |
+ "Rate marked as a VHT rate but data is invalid: MCS: %d, NSS: %d\n", |
31286 |
+diff --git a/net/mptcp/options.c b/net/mptcp/options.c |
31287 |
+index 0966855a7c251..e515ba9ccb5d8 100644 |
31288 |
+--- a/net/mptcp/options.c |
31289 |
++++ b/net/mptcp/options.c |
31290 |
+@@ -823,10 +823,13 @@ bool mptcp_established_options(struct sock *sk, struct sk_buff *skb, |
31291 |
+ if (mptcp_established_options_mp(sk, skb, snd_data_fin, &opt_size, remaining, opts)) |
31292 |
+ ret = true; |
31293 |
+ else if (mptcp_established_options_dss(sk, skb, snd_data_fin, &opt_size, remaining, opts)) { |
31294 |
++ unsigned int mp_fail_size; |
31295 |
++ |
31296 |
+ ret = true; |
31297 |
+- if (mptcp_established_options_mp_fail(sk, &opt_size, remaining, opts)) { |
31298 |
+- *size += opt_size; |
31299 |
+- remaining -= opt_size; |
31300 |
++ if (mptcp_established_options_mp_fail(sk, &mp_fail_size, |
31301 |
++ remaining - opt_size, opts)) { |
31302 |
++ *size += opt_size + mp_fail_size; |
31303 |
++ remaining -= opt_size - mp_fail_size; |
31304 |
+ return true; |
31305 |
+ } |
31306 |
+ } |
31307 |
+@@ -1318,6 +1321,7 @@ void mptcp_write_options(__be32 *ptr, const struct tcp_sock *tp, |
31308 |
+ put_unaligned_be32(mpext->data_len << 16 | |
31309 |
+ TCPOPT_NOP << 8 | TCPOPT_NOP, ptr); |
31310 |
+ } |
31311 |
++ ptr += 1; |
31312 |
+ } |
31313 |
+ } else if ((OPTION_MPTCP_MPC_SYN | OPTION_MPTCP_MPC_SYNACK | |
31314 |
+ OPTION_MPTCP_MPC_ACK) & opts->suboptions) { |
31315 |
+diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c |
31316 |
+index b79251a36dcbc..d96860053816a 100644 |
31317 |
+--- a/net/mptcp/pm_netlink.c |
31318 |
++++ b/net/mptcp/pm_netlink.c |
31319 |
+@@ -710,6 +710,8 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk, |
31320 |
+ return; |
31321 |
+ |
31322 |
+ for (i = 0; i < rm_list->nr; i++) { |
31323 |
++ bool removed = false; |
31324 |
++ |
31325 |
+ list_for_each_entry_safe(subflow, tmp, &msk->conn_list, node) { |
31326 |
+ struct sock *ssk = mptcp_subflow_tcp_sock(subflow); |
31327 |
+ int how = RCV_SHUTDOWN | SEND_SHUTDOWN; |
31328 |
+@@ -729,15 +731,19 @@ static void mptcp_pm_nl_rm_addr_or_subflow(struct mptcp_sock *msk, |
31329 |
+ mptcp_close_ssk(sk, ssk, subflow); |
31330 |
+ spin_lock_bh(&msk->pm.lock); |
31331 |
+ |
31332 |
+- if (rm_type == MPTCP_MIB_RMADDR) { |
31333 |
+- msk->pm.add_addr_accepted--; |
31334 |
+- WRITE_ONCE(msk->pm.accept_addr, true); |
31335 |
+- } else if (rm_type == MPTCP_MIB_RMSUBFLOW) { |
31336 |
+- msk->pm.local_addr_used--; |
31337 |
+- } |
31338 |
++ removed = true; |
31339 |
+ msk->pm.subflows--; |
31340 |
+ __MPTCP_INC_STATS(sock_net(sk), rm_type); |
31341 |
+ } |
31342 |
++ if (!removed) |
31343 |
++ continue; |
31344 |
++ |
31345 |
++ if (rm_type == MPTCP_MIB_RMADDR) { |
31346 |
++ msk->pm.add_addr_accepted--; |
31347 |
++ WRITE_ONCE(msk->pm.accept_addr, true); |
31348 |
++ } else if (rm_type == MPTCP_MIB_RMSUBFLOW) { |
31349 |
++ msk->pm.local_addr_used--; |
31350 |
++ } |
31351 |
+ } |
31352 |
+ } |
31353 |
+ |
31354 |
+diff --git a/net/netfilter/nft_payload.c b/net/netfilter/nft_payload.c |
31355 |
+index a44b14f6c0dc0..132875cd7fff2 100644 |
31356 |
+--- a/net/netfilter/nft_payload.c |
31357 |
++++ b/net/netfilter/nft_payload.c |
31358 |
+@@ -502,6 +502,9 @@ static int nft_payload_l4csum_offset(const struct nft_pktinfo *pkt, |
31359 |
+ struct sk_buff *skb, |
31360 |
+ unsigned int *l4csum_offset) |
31361 |
+ { |
31362 |
++ if (pkt->fragoff) |
31363 |
++ return -1; |
31364 |
++ |
31365 |
+ switch (pkt->tprot) { |
31366 |
+ case IPPROTO_TCP: |
31367 |
+ *l4csum_offset = offsetof(struct tcphdr, check); |
31368 |
+diff --git a/net/netfilter/nft_set_pipapo.c b/net/netfilter/nft_set_pipapo.c |
31369 |
+index dce866d93feed..2c8051d8cca69 100644 |
31370 |
+--- a/net/netfilter/nft_set_pipapo.c |
31371 |
++++ b/net/netfilter/nft_set_pipapo.c |
31372 |
+@@ -1290,6 +1290,11 @@ static struct nft_pipapo_match *pipapo_clone(struct nft_pipapo_match *old) |
31373 |
+ if (!new->scratch_aligned) |
31374 |
+ goto out_scratch; |
31375 |
+ #endif |
31376 |
++ for_each_possible_cpu(i) |
31377 |
++ *per_cpu_ptr(new->scratch, i) = NULL; |
31378 |
++ |
31379 |
++ if (pipapo_realloc_scratch(new, old->bsize_max)) |
31380 |
++ goto out_scratch_realloc; |
31381 |
+ |
31382 |
+ rcu_head_init(&new->rcu); |
31383 |
+ |
31384 |
+@@ -1334,6 +1339,9 @@ out_lt: |
31385 |
+ kvfree(dst->lt); |
31386 |
+ dst--; |
31387 |
+ } |
31388 |
++out_scratch_realloc: |
31389 |
++ for_each_possible_cpu(i) |
31390 |
++ kfree(*per_cpu_ptr(new->scratch, i)); |
31391 |
+ #ifdef NFT_PIPAPO_ALIGN |
31392 |
+ free_percpu(new->scratch_aligned); |
31393 |
+ #endif |
31394 |
+diff --git a/net/netrom/af_netrom.c b/net/netrom/af_netrom.c |
31395 |
+index eef0e3f2f25b0..e5c8a295e6406 100644 |
31396 |
+--- a/net/netrom/af_netrom.c |
31397 |
++++ b/net/netrom/af_netrom.c |
31398 |
+@@ -298,7 +298,7 @@ static int nr_setsockopt(struct socket *sock, int level, int optname, |
31399 |
+ { |
31400 |
+ struct sock *sk = sock->sk; |
31401 |
+ struct nr_sock *nr = nr_sk(sk); |
31402 |
+- unsigned long opt; |
31403 |
++ unsigned int opt; |
31404 |
+ |
31405 |
+ if (level != SOL_NETROM) |
31406 |
+ return -ENOPROTOOPT; |
31407 |
+@@ -306,18 +306,18 @@ static int nr_setsockopt(struct socket *sock, int level, int optname, |
31408 |
+ if (optlen < sizeof(unsigned int)) |
31409 |
+ return -EINVAL; |
31410 |
+ |
31411 |
+- if (copy_from_sockptr(&opt, optval, sizeof(unsigned long))) |
31412 |
++ if (copy_from_sockptr(&opt, optval, sizeof(opt))) |
31413 |
+ return -EFAULT; |
31414 |
+ |
31415 |
+ switch (optname) { |
31416 |
+ case NETROM_T1: |
31417 |
+- if (opt < 1 || opt > ULONG_MAX / HZ) |
31418 |
++ if (opt < 1 || opt > UINT_MAX / HZ) |
31419 |
+ return -EINVAL; |
31420 |
+ nr->t1 = opt * HZ; |
31421 |
+ return 0; |
31422 |
+ |
31423 |
+ case NETROM_T2: |
31424 |
+- if (opt < 1 || opt > ULONG_MAX / HZ) |
31425 |
++ if (opt < 1 || opt > UINT_MAX / HZ) |
31426 |
+ return -EINVAL; |
31427 |
+ nr->t2 = opt * HZ; |
31428 |
+ return 0; |
31429 |
+@@ -329,13 +329,13 @@ static int nr_setsockopt(struct socket *sock, int level, int optname, |
31430 |
+ return 0; |
31431 |
+ |
31432 |
+ case NETROM_T4: |
31433 |
+- if (opt < 1 || opt > ULONG_MAX / HZ) |
31434 |
++ if (opt < 1 || opt > UINT_MAX / HZ) |
31435 |
+ return -EINVAL; |
31436 |
+ nr->t4 = opt * HZ; |
31437 |
+ return 0; |
31438 |
+ |
31439 |
+ case NETROM_IDLE: |
31440 |
+- if (opt > ULONG_MAX / (60 * HZ)) |
31441 |
++ if (opt > UINT_MAX / (60 * HZ)) |
31442 |
+ return -EINVAL; |
31443 |
+ nr->idle = opt * 60 * HZ; |
31444 |
+ return 0; |
31445 |
+diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c |
31446 |
+index 6cfd30fc07985..0b93a17b9f11f 100644 |
31447 |
+--- a/net/nfc/llcp_sock.c |
31448 |
++++ b/net/nfc/llcp_sock.c |
31449 |
+@@ -789,6 +789,11 @@ static int llcp_sock_sendmsg(struct socket *sock, struct msghdr *msg, |
31450 |
+ |
31451 |
+ lock_sock(sk); |
31452 |
+ |
31453 |
++ if (!llcp_sock->local) { |
31454 |
++ release_sock(sk); |
31455 |
++ return -ENODEV; |
31456 |
++ } |
31457 |
++ |
31458 |
+ if (sk->sk_type == SOCK_DGRAM) { |
31459 |
+ DECLARE_SOCKADDR(struct sockaddr_nfc_llcp *, addr, |
31460 |
+ msg->msg_name); |
31461 |
+diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c |
31462 |
+index 9713035b89e3a..02096f2ec6784 100644 |
31463 |
+--- a/net/openvswitch/flow.c |
31464 |
++++ b/net/openvswitch/flow.c |
31465 |
+@@ -34,6 +34,7 @@ |
31466 |
+ #include <net/mpls.h> |
31467 |
+ #include <net/ndisc.h> |
31468 |
+ #include <net/nsh.h> |
31469 |
++#include <net/netfilter/nf_conntrack_zones.h> |
31470 |
+ |
31471 |
+ #include "conntrack.h" |
31472 |
+ #include "datapath.h" |
31473 |
+@@ -858,8 +859,9 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info, |
31474 |
+ #if IS_ENABLED(CONFIG_NET_TC_SKB_EXT) |
31475 |
+ struct tc_skb_ext *tc_ext; |
31476 |
+ #endif |
31477 |
+- bool post_ct = false; |
31478 |
++ bool post_ct = false, post_ct_snat = false, post_ct_dnat = false; |
31479 |
+ int res, err; |
31480 |
++ u16 zone = 0; |
31481 |
+ |
31482 |
+ /* Extract metadata from packet. */ |
31483 |
+ if (tun_info) { |
31484 |
+@@ -898,6 +900,9 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info, |
31485 |
+ key->recirc_id = tc_ext ? tc_ext->chain : 0; |
31486 |
+ OVS_CB(skb)->mru = tc_ext ? tc_ext->mru : 0; |
31487 |
+ post_ct = tc_ext ? tc_ext->post_ct : false; |
31488 |
++ post_ct_snat = post_ct ? tc_ext->post_ct_snat : false; |
31489 |
++ post_ct_dnat = post_ct ? tc_ext->post_ct_dnat : false; |
31490 |
++ zone = post_ct ? tc_ext->zone : 0; |
31491 |
+ } else { |
31492 |
+ key->recirc_id = 0; |
31493 |
+ } |
31494 |
+@@ -906,8 +911,19 @@ int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info, |
31495 |
+ #endif |
31496 |
+ |
31497 |
+ err = key_extract(skb, key); |
31498 |
+- if (!err) |
31499 |
++ if (!err) { |
31500 |
+ ovs_ct_fill_key(skb, key, post_ct); /* Must be after key_extract(). */ |
31501 |
++ if (post_ct) { |
31502 |
++ if (!skb_get_nfct(skb)) { |
31503 |
++ key->ct_zone = zone; |
31504 |
++ } else { |
31505 |
++ if (!post_ct_dnat) |
31506 |
++ key->ct_state &= ~OVS_CS_F_DST_NAT; |
31507 |
++ if (!post_ct_snat) |
31508 |
++ key->ct_state &= ~OVS_CS_F_SRC_NAT; |
31509 |
++ } |
31510 |
++ } |
31511 |
++ } |
31512 |
+ return err; |
31513 |
+ } |
31514 |
+ |
31515 |
+diff --git a/net/sched/act_ct.c b/net/sched/act_ct.c |
31516 |
+index 98e248b9c0b17..2a17eb77c9049 100644 |
31517 |
+--- a/net/sched/act_ct.c |
31518 |
++++ b/net/sched/act_ct.c |
31519 |
+@@ -839,6 +839,12 @@ static int ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct, |
31520 |
+ } |
31521 |
+ |
31522 |
+ err = nf_nat_packet(ct, ctinfo, hooknum, skb); |
31523 |
++ if (err == NF_ACCEPT) { |
31524 |
++ if (maniptype == NF_NAT_MANIP_SRC) |
31525 |
++ tc_skb_cb(skb)->post_ct_snat = 1; |
31526 |
++ if (maniptype == NF_NAT_MANIP_DST) |
31527 |
++ tc_skb_cb(skb)->post_ct_dnat = 1; |
31528 |
++ } |
31529 |
+ out: |
31530 |
+ return err; |
31531 |
+ } |
31532 |
+@@ -1049,6 +1055,7 @@ out_push: |
31533 |
+ skb_push_rcsum(skb, nh_ofs); |
31534 |
+ |
31535 |
+ tc_skb_cb(skb)->post_ct = true; |
31536 |
++ tc_skb_cb(skb)->zone = p->zone; |
31537 |
+ out_clear: |
31538 |
+ if (defrag) |
31539 |
+ qdisc_skb_cb(skb)->pkt_len = skb->len; |
31540 |
+diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c |
31541 |
+index ff8a9383bf1c4..cc9409aa755eb 100644 |
31542 |
+--- a/net/sched/cls_api.c |
31543 |
++++ b/net/sched/cls_api.c |
31544 |
+@@ -1625,6 +1625,9 @@ int tcf_classify(struct sk_buff *skb, |
31545 |
+ ext->chain = last_executed_chain; |
31546 |
+ ext->mru = cb->mru; |
31547 |
+ ext->post_ct = cb->post_ct; |
31548 |
++ ext->post_ct_snat = cb->post_ct_snat; |
31549 |
++ ext->post_ct_dnat = cb->post_ct_dnat; |
31550 |
++ ext->zone = cb->zone; |
31551 |
+ } |
31552 |
+ |
31553 |
+ return ret; |
31554 |
+diff --git a/net/sched/cls_flower.c b/net/sched/cls_flower.c |
31555 |
+index 161bd91c8c6b0..709348262410c 100644 |
31556 |
+--- a/net/sched/cls_flower.c |
31557 |
++++ b/net/sched/cls_flower.c |
31558 |
+@@ -311,6 +311,7 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp, |
31559 |
+ { |
31560 |
+ struct cls_fl_head *head = rcu_dereference_bh(tp->root); |
31561 |
+ bool post_ct = tc_skb_cb(skb)->post_ct; |
31562 |
++ u16 zone = tc_skb_cb(skb)->zone; |
31563 |
+ struct fl_flow_key skb_key; |
31564 |
+ struct fl_flow_mask *mask; |
31565 |
+ struct cls_fl_filter *f; |
31566 |
+@@ -328,7 +329,7 @@ static int fl_classify(struct sk_buff *skb, const struct tcf_proto *tp, |
31567 |
+ skb_flow_dissect_ct(skb, &mask->dissector, &skb_key, |
31568 |
+ fl_ct_info_to_flower_map, |
31569 |
+ ARRAY_SIZE(fl_ct_info_to_flower_map), |
31570 |
+- post_ct); |
31571 |
++ post_ct, zone); |
31572 |
+ skb_flow_dissect_hash(skb, &mask->dissector, &skb_key); |
31573 |
+ skb_flow_dissect(skb, &mask->dissector, &skb_key, 0); |
31574 |
+ |
31575 |
+diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c |
31576 |
+index 12f39a2dffd47..4bbfd26223274 100644 |
31577 |
+--- a/net/sched/sch_api.c |
31578 |
++++ b/net/sched/sch_api.c |
31579 |
+@@ -1062,7 +1062,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent, |
31580 |
+ |
31581 |
+ qdisc_offload_graft_root(dev, new, old, extack); |
31582 |
+ |
31583 |
+- if (new && new->ops->attach) |
31584 |
++ if (new && new->ops->attach && !ingress) |
31585 |
+ goto skip; |
31586 |
+ |
31587 |
+ for (i = 0; i < num_q; i++) { |
31588 |
+diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c |
31589 |
+index 66d2fbe9ef501..47ca76ba7ffa8 100644 |
31590 |
+--- a/net/sched/sch_generic.c |
31591 |
++++ b/net/sched/sch_generic.c |
31592 |
+@@ -1455,6 +1455,7 @@ void psched_ratecfg_precompute(struct psched_ratecfg *r, |
31593 |
+ { |
31594 |
+ memset(r, 0, sizeof(*r)); |
31595 |
+ r->overhead = conf->overhead; |
31596 |
++ r->mpu = conf->mpu; |
31597 |
+ r->rate_bytes_ps = max_t(u64, conf->rate, rate64); |
31598 |
+ r->linklayer = (conf->linklayer & TC_LINKLAYER_MASK); |
31599 |
+ psched_ratecfg_precompute__(r->rate_bytes_ps, &r->mult, &r->shift); |
31600 |
+diff --git a/net/smc/af_smc.c b/net/smc/af_smc.c |
31601 |
+index eea6d4a854e90..07ff719f39077 100644 |
31602 |
+--- a/net/smc/af_smc.c |
31603 |
++++ b/net/smc/af_smc.c |
31604 |
+@@ -613,10 +613,12 @@ static int smc_connect_decline_fallback(struct smc_sock *smc, int reason_code, |
31605 |
+ |
31606 |
+ static void smc_conn_abort(struct smc_sock *smc, int local_first) |
31607 |
+ { |
31608 |
++ struct smc_connection *conn = &smc->conn; |
31609 |
++ struct smc_link_group *lgr = conn->lgr; |
31610 |
++ |
31611 |
++ smc_conn_free(conn); |
31612 |
+ if (local_first) |
31613 |
+- smc_lgr_cleanup_early(&smc->conn); |
31614 |
+- else |
31615 |
+- smc_conn_free(&smc->conn); |
31616 |
++ smc_lgr_cleanup_early(lgr); |
31617 |
+ } |
31618 |
+ |
31619 |
+ /* check if there is a rdma device available for this connection. */ |
31620 |
+diff --git a/net/smc/smc_core.c b/net/smc/smc_core.c |
31621 |
+index 506b8498623b0..36e93a3f284d0 100644 |
31622 |
+--- a/net/smc/smc_core.c |
31623 |
++++ b/net/smc/smc_core.c |
31624 |
+@@ -170,8 +170,10 @@ static int smc_lgr_register_conn(struct smc_connection *conn, bool first) |
31625 |
+ |
31626 |
+ if (!conn->lgr->is_smcd) { |
31627 |
+ rc = smcr_lgr_conn_assign_link(conn, first); |
31628 |
+- if (rc) |
31629 |
++ if (rc) { |
31630 |
++ conn->lgr = NULL; |
31631 |
+ return rc; |
31632 |
++ } |
31633 |
+ } |
31634 |
+ /* find a new alert_token_local value not yet used by some connection |
31635 |
+ * in this link group |
31636 |
+@@ -579,15 +581,13 @@ int smcd_nl_get_lgr(struct sk_buff *skb, struct netlink_callback *cb) |
31637 |
+ return skb->len; |
31638 |
+ } |
31639 |
+ |
31640 |
+-void smc_lgr_cleanup_early(struct smc_connection *conn) |
31641 |
++void smc_lgr_cleanup_early(struct smc_link_group *lgr) |
31642 |
+ { |
31643 |
+- struct smc_link_group *lgr = conn->lgr; |
31644 |
+ spinlock_t *lgr_lock; |
31645 |
+ |
31646 |
+ if (!lgr) |
31647 |
+ return; |
31648 |
+ |
31649 |
+- smc_conn_free(conn); |
31650 |
+ smc_lgr_list_head(lgr, &lgr_lock); |
31651 |
+ spin_lock_bh(lgr_lock); |
31652 |
+ /* do not use this link group for new connections */ |
31653 |
+@@ -1387,16 +1387,11 @@ void smc_smcd_terminate_all(struct smcd_dev *smcd) |
31654 |
+ /* Called when an SMCR device is removed or the smc module is unloaded. |
31655 |
+ * If smcibdev is given, all SMCR link groups using this device are terminated. |
31656 |
+ * If smcibdev is NULL, all SMCR link groups are terminated. |
31657 |
+- * |
31658 |
+- * We must wait here for QPs been destroyed before we destroy the CQs, |
31659 |
+- * or we won't received any CQEs and cdc_pend_tx_wr cannot reach 0 thus |
31660 |
+- * smc_sock cannot be released. |
31661 |
+ */ |
31662 |
+ void smc_smcr_terminate_all(struct smc_ib_device *smcibdev) |
31663 |
+ { |
31664 |
+ struct smc_link_group *lgr, *lg; |
31665 |
+ LIST_HEAD(lgr_free_list); |
31666 |
+- LIST_HEAD(lgr_linkdown_list); |
31667 |
+ int i; |
31668 |
+ |
31669 |
+ spin_lock_bh(&smc_lgr_list.lock); |
31670 |
+@@ -1408,7 +1403,7 @@ void smc_smcr_terminate_all(struct smc_ib_device *smcibdev) |
31671 |
+ list_for_each_entry_safe(lgr, lg, &smc_lgr_list.list, list) { |
31672 |
+ for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { |
31673 |
+ if (lgr->lnk[i].smcibdev == smcibdev) |
31674 |
+- list_move_tail(&lgr->list, &lgr_linkdown_list); |
31675 |
++ smcr_link_down_cond_sched(&lgr->lnk[i]); |
31676 |
+ } |
31677 |
+ } |
31678 |
+ } |
31679 |
+@@ -1420,16 +1415,6 @@ void smc_smcr_terminate_all(struct smc_ib_device *smcibdev) |
31680 |
+ __smc_lgr_terminate(lgr, false); |
31681 |
+ } |
31682 |
+ |
31683 |
+- list_for_each_entry_safe(lgr, lg, &lgr_linkdown_list, list) { |
31684 |
+- for (i = 0; i < SMC_LINKS_PER_LGR_MAX; i++) { |
31685 |
+- if (lgr->lnk[i].smcibdev == smcibdev) { |
31686 |
+- mutex_lock(&lgr->llc_conf_mutex); |
31687 |
+- smcr_link_down_cond(&lgr->lnk[i]); |
31688 |
+- mutex_unlock(&lgr->llc_conf_mutex); |
31689 |
+- } |
31690 |
+- } |
31691 |
+- } |
31692 |
+- |
31693 |
+ if (smcibdev) { |
31694 |
+ if (atomic_read(&smcibdev->lnk_cnt)) |
31695 |
+ wait_event(smcibdev->lnks_deleted, |
31696 |
+@@ -1750,8 +1735,10 @@ create: |
31697 |
+ write_lock_bh(&lgr->conns_lock); |
31698 |
+ rc = smc_lgr_register_conn(conn, true); |
31699 |
+ write_unlock_bh(&lgr->conns_lock); |
31700 |
+- if (rc) |
31701 |
++ if (rc) { |
31702 |
++ smc_lgr_cleanup_early(lgr); |
31703 |
+ goto out; |
31704 |
++ } |
31705 |
+ } |
31706 |
+ conn->local_tx_ctrl.common.type = SMC_CDC_MSG_TYPE; |
31707 |
+ conn->local_tx_ctrl.len = SMC_WR_TX_SIZE; |
31708 |
+diff --git a/net/smc/smc_core.h b/net/smc/smc_core.h |
31709 |
+index 51a3e8248ade2..9a0523f4c7ba6 100644 |
31710 |
+--- a/net/smc/smc_core.h |
31711 |
++++ b/net/smc/smc_core.h |
31712 |
+@@ -419,7 +419,7 @@ static inline void smc_set_pci_values(struct pci_dev *pci_dev, |
31713 |
+ struct smc_sock; |
31714 |
+ struct smc_clc_msg_accept_confirm; |
31715 |
+ |
31716 |
+-void smc_lgr_cleanup_early(struct smc_connection *conn); |
31717 |
++void smc_lgr_cleanup_early(struct smc_link_group *lgr); |
31718 |
+ void smc_lgr_terminate_sched(struct smc_link_group *lgr); |
31719 |
+ void smcr_port_add(struct smc_ib_device *smcibdev, u8 ibport); |
31720 |
+ void smcr_port_err(struct smc_ib_device *smcibdev, u8 ibport); |
31721 |
+diff --git a/net/socket.c b/net/socket.c |
31722 |
+index 7f64a6eccf63f..5053eb0100e48 100644 |
31723 |
+--- a/net/socket.c |
31724 |
++++ b/net/socket.c |
31725 |
+@@ -829,6 +829,7 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, |
31726 |
+ int empty = 1, false_tstamp = 0; |
31727 |
+ struct skb_shared_hwtstamps *shhwtstamps = |
31728 |
+ skb_hwtstamps(skb); |
31729 |
++ ktime_t hwtstamp; |
31730 |
+ |
31731 |
+ /* Race occurred between timestamp enabling and packet |
31732 |
+ receiving. Fill in the current time for now. */ |
31733 |
+@@ -877,10 +878,12 @@ void __sock_recv_timestamp(struct msghdr *msg, struct sock *sk, |
31734 |
+ (sk->sk_tsflags & SOF_TIMESTAMPING_RAW_HARDWARE) && |
31735 |
+ !skb_is_swtx_tstamp(skb, false_tstamp)) { |
31736 |
+ if (sk->sk_tsflags & SOF_TIMESTAMPING_BIND_PHC) |
31737 |
+- ptp_convert_timestamp(shhwtstamps, sk->sk_bind_phc); |
31738 |
++ hwtstamp = ptp_convert_timestamp(shhwtstamps, |
31739 |
++ sk->sk_bind_phc); |
31740 |
++ else |
31741 |
++ hwtstamp = shhwtstamps->hwtstamp; |
31742 |
+ |
31743 |
+- if (ktime_to_timespec64_cond(shhwtstamps->hwtstamp, |
31744 |
+- tss.ts + 2)) { |
31745 |
++ if (ktime_to_timespec64_cond(hwtstamp, tss.ts + 2)) { |
31746 |
+ empty = 0; |
31747 |
+ |
31748 |
+ if ((sk->sk_tsflags & SOF_TIMESTAMPING_OPT_PKTINFO) && |
31749 |
+diff --git a/net/unix/garbage.c b/net/unix/garbage.c |
31750 |
+index 12e2ddaf887f2..d45d5366115a7 100644 |
31751 |
+--- a/net/unix/garbage.c |
31752 |
++++ b/net/unix/garbage.c |
31753 |
+@@ -192,8 +192,11 @@ void wait_for_unix_gc(void) |
31754 |
+ { |
31755 |
+ /* If number of inflight sockets is insane, |
31756 |
+ * force a garbage collect right now. |
31757 |
++ * Paired with the WRITE_ONCE() in unix_inflight(), |
31758 |
++ * unix_notinflight() and gc_in_progress(). |
31759 |
+ */ |
31760 |
+- if (unix_tot_inflight > UNIX_INFLIGHT_TRIGGER_GC && !gc_in_progress) |
31761 |
++ if (READ_ONCE(unix_tot_inflight) > UNIX_INFLIGHT_TRIGGER_GC && |
31762 |
++ !READ_ONCE(gc_in_progress)) |
31763 |
+ unix_gc(); |
31764 |
+ wait_event(unix_gc_wait, gc_in_progress == false); |
31765 |
+ } |
31766 |
+@@ -213,7 +216,9 @@ void unix_gc(void) |
31767 |
+ if (gc_in_progress) |
31768 |
+ goto out; |
31769 |
+ |
31770 |
+- gc_in_progress = true; |
31771 |
++ /* Paired with READ_ONCE() in wait_for_unix_gc(). */ |
31772 |
++ WRITE_ONCE(gc_in_progress, true); |
31773 |
++ |
31774 |
+ /* First, select candidates for garbage collection. Only |
31775 |
+ * in-flight sockets are considered, and from those only ones |
31776 |
+ * which don't have any external reference. |
31777 |
+@@ -299,7 +304,10 @@ void unix_gc(void) |
31778 |
+ |
31779 |
+ /* All candidates should have been detached by now. */ |
31780 |
+ BUG_ON(!list_empty(&gc_candidates)); |
31781 |
+- gc_in_progress = false; |
31782 |
++ |
31783 |
++ /* Paired with READ_ONCE() in wait_for_unix_gc(). */ |
31784 |
++ WRITE_ONCE(gc_in_progress, false); |
31785 |
++ |
31786 |
+ wake_up(&unix_gc_wait); |
31787 |
+ |
31788 |
+ out: |
31789 |
+diff --git a/net/unix/scm.c b/net/unix/scm.c |
31790 |
+index 052ae709ce289..aa27a02478dc1 100644 |
31791 |
+--- a/net/unix/scm.c |
31792 |
++++ b/net/unix/scm.c |
31793 |
+@@ -60,7 +60,8 @@ void unix_inflight(struct user_struct *user, struct file *fp) |
31794 |
+ } else { |
31795 |
+ BUG_ON(list_empty(&u->link)); |
31796 |
+ } |
31797 |
+- unix_tot_inflight++; |
31798 |
++ /* Paired with READ_ONCE() in wait_for_unix_gc() */ |
31799 |
++ WRITE_ONCE(unix_tot_inflight, unix_tot_inflight + 1); |
31800 |
+ } |
31801 |
+ user->unix_inflight++; |
31802 |
+ spin_unlock(&unix_gc_lock); |
31803 |
+@@ -80,7 +81,8 @@ void unix_notinflight(struct user_struct *user, struct file *fp) |
31804 |
+ |
31805 |
+ if (atomic_long_dec_and_test(&u->inflight)) |
31806 |
+ list_del_init(&u->link); |
31807 |
+- unix_tot_inflight--; |
31808 |
++ /* Paired with READ_ONCE() in wait_for_unix_gc() */ |
31809 |
++ WRITE_ONCE(unix_tot_inflight, unix_tot_inflight - 1); |
31810 |
+ } |
31811 |
+ user->unix_inflight--; |
31812 |
+ spin_unlock(&unix_gc_lock); |
31813 |
+diff --git a/net/xfrm/xfrm_compat.c b/net/xfrm/xfrm_compat.c |
31814 |
+index 2bf2693901631..a0f62fa02e06e 100644 |
31815 |
+--- a/net/xfrm/xfrm_compat.c |
31816 |
++++ b/net/xfrm/xfrm_compat.c |
31817 |
+@@ -127,6 +127,7 @@ static const struct nla_policy compat_policy[XFRMA_MAX+1] = { |
31818 |
+ [XFRMA_SET_MARK] = { .type = NLA_U32 }, |
31819 |
+ [XFRMA_SET_MARK_MASK] = { .type = NLA_U32 }, |
31820 |
+ [XFRMA_IF_ID] = { .type = NLA_U32 }, |
31821 |
++ [XFRMA_MTIMER_THRESH] = { .type = NLA_U32 }, |
31822 |
+ }; |
31823 |
+ |
31824 |
+ static struct nlmsghdr *xfrm_nlmsg_put_compat(struct sk_buff *skb, |
31825 |
+@@ -274,9 +275,10 @@ static int xfrm_xlate64_attr(struct sk_buff *dst, const struct nlattr *src) |
31826 |
+ case XFRMA_SET_MARK: |
31827 |
+ case XFRMA_SET_MARK_MASK: |
31828 |
+ case XFRMA_IF_ID: |
31829 |
++ case XFRMA_MTIMER_THRESH: |
31830 |
+ return xfrm_nla_cpy(dst, src, nla_len(src)); |
31831 |
+ default: |
31832 |
+- BUILD_BUG_ON(XFRMA_MAX != XFRMA_IF_ID); |
31833 |
++ BUILD_BUG_ON(XFRMA_MAX != XFRMA_MTIMER_THRESH); |
31834 |
+ pr_warn_once("unsupported nla_type %d\n", src->nla_type); |
31835 |
+ return -EOPNOTSUPP; |
31836 |
+ } |
31837 |
+@@ -431,7 +433,7 @@ static int xfrm_xlate32_attr(void *dst, const struct nlattr *nla, |
31838 |
+ int err; |
31839 |
+ |
31840 |
+ if (type > XFRMA_MAX) { |
31841 |
+- BUILD_BUG_ON(XFRMA_MAX != XFRMA_IF_ID); |
31842 |
++ BUILD_BUG_ON(XFRMA_MAX != XFRMA_MTIMER_THRESH); |
31843 |
+ NL_SET_ERR_MSG(extack, "Bad attribute"); |
31844 |
+ return -EOPNOTSUPP; |
31845 |
+ } |
31846 |
+diff --git a/net/xfrm/xfrm_interface.c b/net/xfrm/xfrm_interface.c |
31847 |
+index 41de46b5ffa94..57448fc519fcd 100644 |
31848 |
+--- a/net/xfrm/xfrm_interface.c |
31849 |
++++ b/net/xfrm/xfrm_interface.c |
31850 |
+@@ -637,11 +637,16 @@ static int xfrmi_newlink(struct net *src_net, struct net_device *dev, |
31851 |
+ struct netlink_ext_ack *extack) |
31852 |
+ { |
31853 |
+ struct net *net = dev_net(dev); |
31854 |
+- struct xfrm_if_parms p; |
31855 |
++ struct xfrm_if_parms p = {}; |
31856 |
+ struct xfrm_if *xi; |
31857 |
+ int err; |
31858 |
+ |
31859 |
+ xfrmi_netlink_parms(data, &p); |
31860 |
++ if (!p.if_id) { |
31861 |
++ NL_SET_ERR_MSG(extack, "if_id must be non zero"); |
31862 |
++ return -EINVAL; |
31863 |
++ } |
31864 |
++ |
31865 |
+ xi = xfrmi_locate(net, &p); |
31866 |
+ if (xi) |
31867 |
+ return -EEXIST; |
31868 |
+@@ -666,7 +671,12 @@ static int xfrmi_changelink(struct net_device *dev, struct nlattr *tb[], |
31869 |
+ { |
31870 |
+ struct xfrm_if *xi = netdev_priv(dev); |
31871 |
+ struct net *net = xi->net; |
31872 |
+- struct xfrm_if_parms p; |
31873 |
++ struct xfrm_if_parms p = {}; |
31874 |
++ |
31875 |
++ if (!p.if_id) { |
31876 |
++ NL_SET_ERR_MSG(extack, "if_id must be non zero"); |
31877 |
++ return -EINVAL; |
31878 |
++ } |
31879 |
+ |
31880 |
+ xfrmi_netlink_parms(data, &p); |
31881 |
+ xi = xfrmi_locate(net, &p); |
31882 |
+diff --git a/net/xfrm/xfrm_output.c b/net/xfrm/xfrm_output.c |
31883 |
+index 229544bc70c21..4dc4a7bbe51cf 100644 |
31884 |
+--- a/net/xfrm/xfrm_output.c |
31885 |
++++ b/net/xfrm/xfrm_output.c |
31886 |
+@@ -647,10 +647,12 @@ static int xfrm_output_gso(struct net *net, struct sock *sk, struct sk_buff *skb |
31887 |
+ * This requires hardware to know the inner packet type to calculate |
31888 |
+ * the inner header checksum. Save inner ip protocol here to avoid |
31889 |
+ * traversing the packet in the vendor's xmit code. |
31890 |
+- * If the encap type is IPIP, just save skb->inner_ipproto. Otherwise, |
31891 |
+- * get the ip protocol from the IP header. |
31892 |
++ * For IPsec tunnel mode save the ip protocol from the IP header of the |
31893 |
++ * plain text packet. Otherwise If the encap type is IPIP, just save |
31894 |
++ * skb->inner_ipproto in any other case get the ip protocol from the IP |
31895 |
++ * header. |
31896 |
+ */ |
31897 |
+-static void xfrm_get_inner_ipproto(struct sk_buff *skb) |
31898 |
++static void xfrm_get_inner_ipproto(struct sk_buff *skb, struct xfrm_state *x) |
31899 |
+ { |
31900 |
+ struct xfrm_offload *xo = xfrm_offload(skb); |
31901 |
+ const struct ethhdr *eth; |
31902 |
+@@ -658,6 +660,25 @@ static void xfrm_get_inner_ipproto(struct sk_buff *skb) |
31903 |
+ if (!xo) |
31904 |
+ return; |
31905 |
+ |
31906 |
++ if (x->outer_mode.encap == XFRM_MODE_TUNNEL) { |
31907 |
++ switch (x->outer_mode.family) { |
31908 |
++ case AF_INET: |
31909 |
++ xo->inner_ipproto = ip_hdr(skb)->protocol; |
31910 |
++ break; |
31911 |
++ case AF_INET6: |
31912 |
++ xo->inner_ipproto = ipv6_hdr(skb)->nexthdr; |
31913 |
++ break; |
31914 |
++ default: |
31915 |
++ break; |
31916 |
++ } |
31917 |
++ |
31918 |
++ return; |
31919 |
++ } |
31920 |
++ |
31921 |
++ /* non-Tunnel Mode */ |
31922 |
++ if (!skb->encapsulation) |
31923 |
++ return; |
31924 |
++ |
31925 |
+ if (skb->inner_protocol_type == ENCAP_TYPE_IPPROTO) { |
31926 |
+ xo->inner_ipproto = skb->inner_ipproto; |
31927 |
+ return; |
31928 |
+@@ -712,8 +733,7 @@ int xfrm_output(struct sock *sk, struct sk_buff *skb) |
31929 |
+ sp->xvec[sp->len++] = x; |
31930 |
+ xfrm_state_hold(x); |
31931 |
+ |
31932 |
+- if (skb->encapsulation) |
31933 |
+- xfrm_get_inner_ipproto(skb); |
31934 |
++ xfrm_get_inner_ipproto(skb, x); |
31935 |
+ skb->encapsulation = 1; |
31936 |
+ |
31937 |
+ if (skb_is_gso(skb)) { |
31938 |
+diff --git a/net/xfrm/xfrm_policy.c b/net/xfrm/xfrm_policy.c |
31939 |
+index 37d17a79617c9..37b149f632624 100644 |
31940 |
+--- a/net/xfrm/xfrm_policy.c |
31941 |
++++ b/net/xfrm/xfrm_policy.c |
31942 |
+@@ -31,8 +31,10 @@ |
31943 |
+ #include <linux/if_tunnel.h> |
31944 |
+ #include <net/dst.h> |
31945 |
+ #include <net/flow.h> |
31946 |
++#include <net/inet_ecn.h> |
31947 |
+ #include <net/xfrm.h> |
31948 |
+ #include <net/ip.h> |
31949 |
++#include <net/gre.h> |
31950 |
+ #if IS_ENABLED(CONFIG_IPV6_MIP6) |
31951 |
+ #include <net/mip6.h> |
31952 |
+ #endif |
31953 |
+@@ -3296,7 +3298,7 @@ decode_session4(struct sk_buff *skb, struct flowi *fl, bool reverse) |
31954 |
+ fl4->flowi4_proto = iph->protocol; |
31955 |
+ fl4->daddr = reverse ? iph->saddr : iph->daddr; |
31956 |
+ fl4->saddr = reverse ? iph->daddr : iph->saddr; |
31957 |
+- fl4->flowi4_tos = iph->tos; |
31958 |
++ fl4->flowi4_tos = iph->tos & ~INET_ECN_MASK; |
31959 |
+ |
31960 |
+ if (!ip_is_fragment(iph)) { |
31961 |
+ switch (iph->protocol) { |
31962 |
+@@ -3424,6 +3426,26 @@ decode_session6(struct sk_buff *skb, struct flowi *fl, bool reverse) |
31963 |
+ } |
31964 |
+ fl6->flowi6_proto = nexthdr; |
31965 |
+ return; |
31966 |
++ case IPPROTO_GRE: |
31967 |
++ if (!onlyproto && |
31968 |
++ (nh + offset + 12 < skb->data || |
31969 |
++ pskb_may_pull(skb, nh + offset + 12 - skb->data))) { |
31970 |
++ struct gre_base_hdr *gre_hdr; |
31971 |
++ __be32 *gre_key; |
31972 |
++ |
31973 |
++ nh = skb_network_header(skb); |
31974 |
++ gre_hdr = (struct gre_base_hdr *)(nh + offset); |
31975 |
++ gre_key = (__be32 *)(gre_hdr + 1); |
31976 |
++ |
31977 |
++ if (gre_hdr->flags & GRE_KEY) { |
31978 |
++ if (gre_hdr->flags & GRE_CSUM) |
31979 |
++ gre_key++; |
31980 |
++ fl6->fl6_gre_key = *gre_key; |
31981 |
++ } |
31982 |
++ } |
31983 |
++ fl6->flowi6_proto = nexthdr; |
31984 |
++ return; |
31985 |
++ |
31986 |
+ #if IS_ENABLED(CONFIG_IPV6_MIP6) |
31987 |
+ case IPPROTO_MH: |
31988 |
+ offset += ipv6_optlen(exthdr); |
31989 |
+diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c |
31990 |
+index a2f4001221d16..78d51399a0f4b 100644 |
31991 |
+--- a/net/xfrm/xfrm_state.c |
31992 |
++++ b/net/xfrm/xfrm_state.c |
31993 |
+@@ -1593,6 +1593,9 @@ static struct xfrm_state *xfrm_state_clone(struct xfrm_state *orig, |
31994 |
+ x->km.seq = orig->km.seq; |
31995 |
+ x->replay = orig->replay; |
31996 |
+ x->preplay = orig->preplay; |
31997 |
++ x->mapping_maxage = orig->mapping_maxage; |
31998 |
++ x->new_mapping = 0; |
31999 |
++ x->new_mapping_sport = 0; |
32000 |
+ |
32001 |
+ return x; |
32002 |
+ |
32003 |
+@@ -2242,7 +2245,7 @@ int km_query(struct xfrm_state *x, struct xfrm_tmpl *t, struct xfrm_policy *pol) |
32004 |
+ } |
32005 |
+ EXPORT_SYMBOL(km_query); |
32006 |
+ |
32007 |
+-int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport) |
32008 |
++static int __km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport) |
32009 |
+ { |
32010 |
+ int err = -EINVAL; |
32011 |
+ struct xfrm_mgr *km; |
32012 |
+@@ -2257,6 +2260,24 @@ int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport) |
32013 |
+ rcu_read_unlock(); |
32014 |
+ return err; |
32015 |
+ } |
32016 |
++ |
32017 |
++int km_new_mapping(struct xfrm_state *x, xfrm_address_t *ipaddr, __be16 sport) |
32018 |
++{ |
32019 |
++ int ret = 0; |
32020 |
++ |
32021 |
++ if (x->mapping_maxage) { |
32022 |
++ if ((jiffies / HZ - x->new_mapping) > x->mapping_maxage || |
32023 |
++ x->new_mapping_sport != sport) { |
32024 |
++ x->new_mapping_sport = sport; |
32025 |
++ x->new_mapping = jiffies / HZ; |
32026 |
++ ret = __km_new_mapping(x, ipaddr, sport); |
32027 |
++ } |
32028 |
++ } else { |
32029 |
++ ret = __km_new_mapping(x, ipaddr, sport); |
32030 |
++ } |
32031 |
++ |
32032 |
++ return ret; |
32033 |
++} |
32034 |
+ EXPORT_SYMBOL(km_new_mapping); |
32035 |
+ |
32036 |
+ void km_policy_expired(struct xfrm_policy *pol, int dir, int hard, u32 portid) |
32037 |
+diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c |
32038 |
+index 3a3cb09eec122..b10f88822c0df 100644 |
32039 |
+--- a/net/xfrm/xfrm_user.c |
32040 |
++++ b/net/xfrm/xfrm_user.c |
32041 |
+@@ -282,6 +282,10 @@ static int verify_newsa_info(struct xfrm_usersa_info *p, |
32042 |
+ |
32043 |
+ err = 0; |
32044 |
+ |
32045 |
++ if (attrs[XFRMA_MTIMER_THRESH]) |
32046 |
++ if (!attrs[XFRMA_ENCAP]) |
32047 |
++ err = -EINVAL; |
32048 |
++ |
32049 |
+ out: |
32050 |
+ return err; |
32051 |
+ } |
32052 |
+@@ -521,6 +525,7 @@ static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs, |
32053 |
+ struct nlattr *lt = attrs[XFRMA_LTIME_VAL]; |
32054 |
+ struct nlattr *et = attrs[XFRMA_ETIMER_THRESH]; |
32055 |
+ struct nlattr *rt = attrs[XFRMA_REPLAY_THRESH]; |
32056 |
++ struct nlattr *mt = attrs[XFRMA_MTIMER_THRESH]; |
32057 |
+ |
32058 |
+ if (re) { |
32059 |
+ struct xfrm_replay_state_esn *replay_esn; |
32060 |
+@@ -552,6 +557,9 @@ static void xfrm_update_ae_params(struct xfrm_state *x, struct nlattr **attrs, |
32061 |
+ |
32062 |
+ if (rt) |
32063 |
+ x->replay_maxdiff = nla_get_u32(rt); |
32064 |
++ |
32065 |
++ if (mt) |
32066 |
++ x->mapping_maxage = nla_get_u32(mt); |
32067 |
+ } |
32068 |
+ |
32069 |
+ static void xfrm_smark_init(struct nlattr **attrs, struct xfrm_mark *m) |
32070 |
+@@ -621,8 +629,13 @@ static struct xfrm_state *xfrm_state_construct(struct net *net, |
32071 |
+ |
32072 |
+ xfrm_smark_init(attrs, &x->props.smark); |
32073 |
+ |
32074 |
+- if (attrs[XFRMA_IF_ID]) |
32075 |
++ if (attrs[XFRMA_IF_ID]) { |
32076 |
+ x->if_id = nla_get_u32(attrs[XFRMA_IF_ID]); |
32077 |
++ if (!x->if_id) { |
32078 |
++ err = -EINVAL; |
32079 |
++ goto error; |
32080 |
++ } |
32081 |
++ } |
32082 |
+ |
32083 |
+ err = __xfrm_init_state(x, false, attrs[XFRMA_OFFLOAD_DEV]); |
32084 |
+ if (err) |
32085 |
+@@ -1024,8 +1037,13 @@ static int copy_to_user_state_extra(struct xfrm_state *x, |
32086 |
+ if (ret) |
32087 |
+ goto out; |
32088 |
+ } |
32089 |
+- if (x->security) |
32090 |
++ if (x->security) { |
32091 |
+ ret = copy_sec_ctx(x->security, skb); |
32092 |
++ if (ret) |
32093 |
++ goto out; |
32094 |
++ } |
32095 |
++ if (x->mapping_maxage) |
32096 |
++ ret = nla_put_u32(skb, XFRMA_MTIMER_THRESH, x->mapping_maxage); |
32097 |
+ out: |
32098 |
+ return ret; |
32099 |
+ } |
32100 |
+@@ -1413,8 +1431,13 @@ static int xfrm_alloc_userspi(struct sk_buff *skb, struct nlmsghdr *nlh, |
32101 |
+ |
32102 |
+ mark = xfrm_mark_get(attrs, &m); |
32103 |
+ |
32104 |
+- if (attrs[XFRMA_IF_ID]) |
32105 |
++ if (attrs[XFRMA_IF_ID]) { |
32106 |
+ if_id = nla_get_u32(attrs[XFRMA_IF_ID]); |
32107 |
++ if (!if_id) { |
32108 |
++ err = -EINVAL; |
32109 |
++ goto out_noput; |
32110 |
++ } |
32111 |
++ } |
32112 |
+ |
32113 |
+ if (p->info.seq) { |
32114 |
+ x = xfrm_find_acq_byseq(net, mark, p->info.seq); |
32115 |
+@@ -1727,8 +1750,13 @@ static struct xfrm_policy *xfrm_policy_construct(struct net *net, struct xfrm_us |
32116 |
+ |
32117 |
+ xfrm_mark_get(attrs, &xp->mark); |
32118 |
+ |
32119 |
+- if (attrs[XFRMA_IF_ID]) |
32120 |
++ if (attrs[XFRMA_IF_ID]) { |
32121 |
+ xp->if_id = nla_get_u32(attrs[XFRMA_IF_ID]); |
32122 |
++ if (!xp->if_id) { |
32123 |
++ err = -EINVAL; |
32124 |
++ goto error; |
32125 |
++ } |
32126 |
++ } |
32127 |
+ |
32128 |
+ return xp; |
32129 |
+ error: |
32130 |
+@@ -3058,7 +3086,7 @@ static inline unsigned int xfrm_sa_len(struct xfrm_state *x) |
32131 |
+ if (x->props.extra_flags) |
32132 |
+ l += nla_total_size(sizeof(x->props.extra_flags)); |
32133 |
+ if (x->xso.dev) |
32134 |
+- l += nla_total_size(sizeof(x->xso)); |
32135 |
++ l += nla_total_size(sizeof(struct xfrm_user_offload)); |
32136 |
+ if (x->props.smark.v | x->props.smark.m) { |
32137 |
+ l += nla_total_size(sizeof(x->props.smark.v)); |
32138 |
+ l += nla_total_size(sizeof(x->props.smark.m)); |
32139 |
+@@ -3069,6 +3097,9 @@ static inline unsigned int xfrm_sa_len(struct xfrm_state *x) |
32140 |
+ /* Must count x->lastused as it may become non-zero behind our back. */ |
32141 |
+ l += nla_total_size_64bit(sizeof(u64)); |
32142 |
+ |
32143 |
++ if (x->mapping_maxage) |
32144 |
++ l += nla_total_size(sizeof(x->mapping_maxage)); |
32145 |
++ |
32146 |
+ return l; |
32147 |
+ } |
32148 |
+ |
32149 |
+diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile |
32150 |
+index 5fd48a8d4f10a..c6e38e43c3fd0 100644 |
32151 |
+--- a/samples/bpf/Makefile |
32152 |
++++ b/samples/bpf/Makefile |
32153 |
+@@ -59,7 +59,11 @@ tprogs-y += xdp_redirect |
32154 |
+ tprogs-y += xdp_monitor |
32155 |
+ |
32156 |
+ # Libbpf dependencies |
32157 |
+-LIBBPF = $(TOOLS_PATH)/lib/bpf/libbpf.a |
32158 |
++LIBBPF_SRC = $(TOOLS_PATH)/lib/bpf |
32159 |
++LIBBPF_OUTPUT = $(abspath $(BPF_SAMPLES_PATH))/libbpf |
32160 |
++LIBBPF_DESTDIR = $(LIBBPF_OUTPUT) |
32161 |
++LIBBPF_INCLUDE = $(LIBBPF_DESTDIR)/include |
32162 |
++LIBBPF = $(LIBBPF_OUTPUT)/libbpf.a |
32163 |
+ |
32164 |
+ CGROUP_HELPERS := ../../tools/testing/selftests/bpf/cgroup_helpers.o |
32165 |
+ TRACE_HELPERS := ../../tools/testing/selftests/bpf/trace_helpers.o |
32166 |
+@@ -198,7 +202,7 @@ TPROGS_CFLAGS += -Wstrict-prototypes |
32167 |
+ |
32168 |
+ TPROGS_CFLAGS += -I$(objtree)/usr/include |
32169 |
+ TPROGS_CFLAGS += -I$(srctree)/tools/testing/selftests/bpf/ |
32170 |
+-TPROGS_CFLAGS += -I$(srctree)/tools/lib/ |
32171 |
++TPROGS_CFLAGS += -I$(LIBBPF_INCLUDE) |
32172 |
+ TPROGS_CFLAGS += -I$(srctree)/tools/include |
32173 |
+ TPROGS_CFLAGS += -I$(srctree)/tools/perf |
32174 |
+ TPROGS_CFLAGS += -DHAVE_ATTR_TEST=0 |
32175 |
+@@ -209,6 +213,11 @@ TPROGS_LDFLAGS := -L$(SYSROOT)/usr/lib |
32176 |
+ endif |
32177 |
+ |
32178 |
+ TPROGS_LDLIBS += $(LIBBPF) -lelf -lz |
32179 |
++TPROGLDLIBS_xdp_monitor += -lm |
32180 |
++TPROGLDLIBS_xdp_redirect += -lm |
32181 |
++TPROGLDLIBS_xdp_redirect_cpu += -lm |
32182 |
++TPROGLDLIBS_xdp_redirect_map += -lm |
32183 |
++TPROGLDLIBS_xdp_redirect_map_multi += -lm |
32184 |
+ TPROGLDLIBS_tracex4 += -lrt |
32185 |
+ TPROGLDLIBS_trace_output += -lrt |
32186 |
+ TPROGLDLIBS_map_perf_test += -lrt |
32187 |
+@@ -268,16 +277,27 @@ all: |
32188 |
+ clean: |
32189 |
+ $(MAKE) -C ../../ M=$(CURDIR) clean |
32190 |
+ @find $(CURDIR) -type f -name '*~' -delete |
32191 |
++ @$(RM) -r $(CURDIR)/libbpf $(CURDIR)/bpftool |
32192 |
+ |
32193 |
+-$(LIBBPF): FORCE |
32194 |
++$(LIBBPF): FORCE | $(LIBBPF_OUTPUT) |
32195 |
+ # Fix up variables inherited from Kbuild that tools/ build system won't like |
32196 |
+- $(MAKE) -C $(dir $@) RM='rm -rf' EXTRA_CFLAGS="$(TPROGS_CFLAGS)" \ |
32197 |
+- LDFLAGS=$(TPROGS_LDFLAGS) srctree=$(BPF_SAMPLES_PATH)/../../ O= |
32198 |
++ $(MAKE) -C $(LIBBPF_SRC) RM='rm -rf' EXTRA_CFLAGS="$(TPROGS_CFLAGS)" \ |
32199 |
++ LDFLAGS=$(TPROGS_LDFLAGS) srctree=$(BPF_SAMPLES_PATH)/../../ \ |
32200 |
++ O= OUTPUT=$(LIBBPF_OUTPUT)/ DESTDIR=$(LIBBPF_DESTDIR) prefix= \ |
32201 |
++ $@ install_headers |
32202 |
+ |
32203 |
+ BPFTOOLDIR := $(TOOLS_PATH)/bpf/bpftool |
32204 |
+-BPFTOOL := $(BPFTOOLDIR)/bpftool |
32205 |
+-$(BPFTOOL): $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) |
32206 |
+- $(MAKE) -C $(BPFTOOLDIR) srctree=$(BPF_SAMPLES_PATH)/../../ |
32207 |
++BPFTOOL_OUTPUT := $(abspath $(BPF_SAMPLES_PATH))/bpftool |
32208 |
++BPFTOOL := $(BPFTOOL_OUTPUT)/bpftool |
32209 |
++$(BPFTOOL): $(LIBBPF) $(wildcard $(BPFTOOLDIR)/*.[ch] $(BPFTOOLDIR)/Makefile) | $(BPFTOOL_OUTPUT) |
32210 |
++ $(MAKE) -C $(BPFTOOLDIR) srctree=$(BPF_SAMPLES_PATH)/../../ \ |
32211 |
++ OUTPUT=$(BPFTOOL_OUTPUT)/ \ |
32212 |
++ LIBBPF_OUTPUT=$(LIBBPF_OUTPUT)/ \ |
32213 |
++ LIBBPF_DESTDIR=$(LIBBPF_DESTDIR)/ |
32214 |
++ |
32215 |
++$(LIBBPF_OUTPUT) $(BPFTOOL_OUTPUT): |
32216 |
++ $(call msg,MKDIR,$@) |
32217 |
++ $(Q)mkdir -p $@ |
32218 |
+ |
32219 |
+ $(obj)/syscall_nrs.h: $(obj)/syscall_nrs.s FORCE |
32220 |
+ $(call filechk,offsets,__SYSCALL_NRS_H__) |
32221 |
+@@ -309,6 +329,11 @@ verify_target_bpf: verify_cmds |
32222 |
+ $(BPF_SAMPLES_PATH)/*.c: verify_target_bpf $(LIBBPF) |
32223 |
+ $(src)/*.c: verify_target_bpf $(LIBBPF) |
32224 |
+ |
32225 |
++libbpf_hdrs: $(LIBBPF) |
32226 |
++$(obj)/$(TRACE_HELPERS) $(obj)/$(CGROUP_HELPERS) $(obj)/$(XDP_SAMPLE): | libbpf_hdrs |
32227 |
++ |
32228 |
++.PHONY: libbpf_hdrs |
32229 |
++ |
32230 |
+ $(obj)/xdp_redirect_cpu_user.o: $(obj)/xdp_redirect_cpu.skel.h |
32231 |
+ $(obj)/xdp_redirect_map_multi_user.o: $(obj)/xdp_redirect_map_multi.skel.h |
32232 |
+ $(obj)/xdp_redirect_map_user.o: $(obj)/xdp_redirect_map.skel.h |
32233 |
+@@ -320,6 +345,17 @@ $(obj)/hbm_out_kern.o: $(src)/hbm.h $(src)/hbm_kern.h |
32234 |
+ $(obj)/hbm.o: $(src)/hbm.h |
32235 |
+ $(obj)/hbm_edt_kern.o: $(src)/hbm.h $(src)/hbm_kern.h |
32236 |
+ |
32237 |
++# Override includes for xdp_sample_user.o because $(srctree)/usr/include in |
32238 |
++# TPROGS_CFLAGS causes conflicts |
32239 |
++XDP_SAMPLE_CFLAGS += -Wall -O2 \ |
32240 |
++ -I$(src)/../../tools/include \ |
32241 |
++ -I$(src)/../../tools/include/uapi \ |
32242 |
++ -I$(LIBBPF_INCLUDE) \ |
32243 |
++ -I$(src)/../../tools/testing/selftests/bpf |
32244 |
++ |
32245 |
++$(obj)/$(XDP_SAMPLE): TPROGS_CFLAGS = $(XDP_SAMPLE_CFLAGS) |
32246 |
++$(obj)/$(XDP_SAMPLE): $(src)/xdp_sample_user.h $(src)/xdp_sample_shared.h |
32247 |
++ |
32248 |
+ -include $(BPF_SAMPLES_PATH)/Makefile.target |
32249 |
+ |
32250 |
+ VMLINUX_BTF_PATHS ?= $(abspath $(if $(O),$(O)/vmlinux)) \ |
32251 |
+@@ -366,7 +402,7 @@ $(obj)/%.bpf.o: $(src)/%.bpf.c $(obj)/vmlinux.h $(src)/xdp_sample.bpf.h $(src)/x |
32252 |
+ $(Q)$(CLANG) -g -O2 -target bpf -D__TARGET_ARCH_$(SRCARCH) \ |
32253 |
+ -Wno-compare-distinct-pointer-types -I$(srctree)/include \ |
32254 |
+ -I$(srctree)/samples/bpf -I$(srctree)/tools/include \ |
32255 |
+- -I$(srctree)/tools/lib $(CLANG_SYS_INCLUDES) \ |
32256 |
++ -I$(LIBBPF_INCLUDE) $(CLANG_SYS_INCLUDES) \ |
32257 |
+ -c $(filter %.bpf.c,$^) -o $@ |
32258 |
+ |
32259 |
+ LINKED_SKELS := xdp_redirect_cpu.skel.h xdp_redirect_map_multi.skel.h \ |
32260 |
+@@ -403,7 +439,7 @@ $(obj)/%.o: $(src)/%.c |
32261 |
+ @echo " CLANG-bpf " $@ |
32262 |
+ $(Q)$(CLANG) $(NOSTDINC_FLAGS) $(LINUXINCLUDE) $(BPF_EXTRA_CFLAGS) \ |
32263 |
+ -I$(obj) -I$(srctree)/tools/testing/selftests/bpf/ \ |
32264 |
+- -I$(srctree)/tools/lib/ \ |
32265 |
++ -I$(LIBBPF_INCLUDE) \ |
32266 |
+ -D__KERNEL__ -D__BPF_TRACING__ -Wno-unused-value -Wno-pointer-sign \ |
32267 |
+ -D__TARGET_ARCH_$(SRCARCH) -Wno-compare-distinct-pointer-types \ |
32268 |
+ -Wno-gnu-variable-sized-type-not-at-end \ |
32269 |
+diff --git a/samples/bpf/Makefile.target b/samples/bpf/Makefile.target |
32270 |
+index 5a368affa0386..7621f55e2947d 100644 |
32271 |
+--- a/samples/bpf/Makefile.target |
32272 |
++++ b/samples/bpf/Makefile.target |
32273 |
+@@ -73,14 +73,3 @@ quiet_cmd_tprog-cobjs = CC $@ |
32274 |
+ cmd_tprog-cobjs = $(CC) $(tprogc_flags) -c -o $@ $< |
32275 |
+ $(tprog-cobjs): $(obj)/%.o: $(src)/%.c FORCE |
32276 |
+ $(call if_changed_dep,tprog-cobjs) |
32277 |
+- |
32278 |
+-# Override includes for xdp_sample_user.o because $(srctree)/usr/include in |
32279 |
+-# TPROGS_CFLAGS causes conflicts |
32280 |
+-XDP_SAMPLE_CFLAGS += -Wall -O2 -lm \ |
32281 |
+- -I./tools/include \ |
32282 |
+- -I./tools/include/uapi \ |
32283 |
+- -I./tools/lib \ |
32284 |
+- -I./tools/testing/selftests/bpf |
32285 |
+-$(obj)/xdp_sample_user.o: $(src)/xdp_sample_user.c \ |
32286 |
+- $(src)/xdp_sample_user.h $(src)/xdp_sample_shared.h |
32287 |
+- $(CC) $(XDP_SAMPLE_CFLAGS) -c -o $@ $< |
32288 |
+diff --git a/samples/bpf/hbm_kern.h b/samples/bpf/hbm_kern.h |
32289 |
+index 722b3fadb4675..1752a46a2b056 100644 |
32290 |
+--- a/samples/bpf/hbm_kern.h |
32291 |
++++ b/samples/bpf/hbm_kern.h |
32292 |
+@@ -9,8 +9,6 @@ |
32293 |
+ * Include file for sample Host Bandwidth Manager (HBM) BPF programs |
32294 |
+ */ |
32295 |
+ #define KBUILD_MODNAME "foo" |
32296 |
+-#include <stddef.h> |
32297 |
+-#include <stdbool.h> |
32298 |
+ #include <uapi/linux/bpf.h> |
32299 |
+ #include <uapi/linux/if_ether.h> |
32300 |
+ #include <uapi/linux/if_packet.h> |
32301 |
+diff --git a/samples/bpf/lwt_len_hist_kern.c b/samples/bpf/lwt_len_hist_kern.c |
32302 |
+index 9ed63e10e1709..1fa14c54963a1 100644 |
32303 |
+--- a/samples/bpf/lwt_len_hist_kern.c |
32304 |
++++ b/samples/bpf/lwt_len_hist_kern.c |
32305 |
+@@ -16,13 +16,6 @@ |
32306 |
+ #include <uapi/linux/in.h> |
32307 |
+ #include <bpf/bpf_helpers.h> |
32308 |
+ |
32309 |
+-# define printk(fmt, ...) \ |
32310 |
+- ({ \ |
32311 |
+- char ____fmt[] = fmt; \ |
32312 |
+- bpf_trace_printk(____fmt, sizeof(____fmt), \ |
32313 |
+- ##__VA_ARGS__); \ |
32314 |
+- }) |
32315 |
+- |
32316 |
+ struct bpf_elf_map { |
32317 |
+ __u32 type; |
32318 |
+ __u32 size_key; |
32319 |
+diff --git a/samples/bpf/xdp_sample_user.h b/samples/bpf/xdp_sample_user.h |
32320 |
+index d97465ff8c62c..5f44b877ecf5f 100644 |
32321 |
+--- a/samples/bpf/xdp_sample_user.h |
32322 |
++++ b/samples/bpf/xdp_sample_user.h |
32323 |
+@@ -45,7 +45,9 @@ const char *get_driver_name(int ifindex); |
32324 |
+ int get_mac_addr(int ifindex, void *mac_addr); |
32325 |
+ |
32326 |
+ #pragma GCC diagnostic push |
32327 |
++#ifndef __clang__ |
32328 |
+ #pragma GCC diagnostic ignored "-Wstringop-truncation" |
32329 |
++#endif |
32330 |
+ __attribute__((unused)) |
32331 |
+ static inline char *safe_strncpy(char *dst, const char *src, size_t size) |
32332 |
+ { |
32333 |
+diff --git a/scripts/dtc/dtx_diff b/scripts/dtc/dtx_diff |
32334 |
+index d3422ee15e300..f2bbde4bba86b 100755 |
32335 |
+--- a/scripts/dtc/dtx_diff |
32336 |
++++ b/scripts/dtc/dtx_diff |
32337 |
+@@ -59,12 +59,8 @@ Otherwise DTx is treated as a dts source file (aka .dts). |
32338 |
+ or '/include/' to be processed. |
32339 |
+ |
32340 |
+ If DTx_1 and DTx_2 are in different architectures, then this script |
32341 |
+- may not work since \${ARCH} is part of the include path. Two possible |
32342 |
+- workarounds: |
32343 |
+- |
32344 |
+- `basename $0` \\ |
32345 |
+- <(ARCH=arch_of_dtx_1 `basename $0` DTx_1) \\ |
32346 |
+- <(ARCH=arch_of_dtx_2 `basename $0` DTx_2) |
32347 |
++ may not work since \${ARCH} is part of the include path. The following |
32348 |
++ workaround can be used: |
32349 |
+ |
32350 |
+ `basename $0` ARCH=arch_of_dtx_1 DTx_1 >tmp_dtx_1.dts |
32351 |
+ `basename $0` ARCH=arch_of_dtx_2 DTx_2 >tmp_dtx_2.dts |
32352 |
+diff --git a/scripts/sphinx-pre-install b/scripts/sphinx-pre-install |
32353 |
+index 288e86a9d1e58..f126ecbb0494d 100755 |
32354 |
+--- a/scripts/sphinx-pre-install |
32355 |
++++ b/scripts/sphinx-pre-install |
32356 |
+@@ -78,6 +78,7 @@ my %texlive = ( |
32357 |
+ 'ucs.sty' => 'texlive-ucs', |
32358 |
+ 'upquote.sty' => 'texlive-upquote', |
32359 |
+ 'wrapfig.sty' => 'texlive-wrapfig', |
32360 |
++ 'ctexhook.sty' => 'texlive-ctex', |
32361 |
+ ); |
32362 |
+ |
32363 |
+ # |
32364 |
+@@ -369,6 +370,9 @@ sub give_debian_hints() |
32365 |
+ ); |
32366 |
+ |
32367 |
+ if ($pdf) { |
32368 |
++ check_missing_file(["/usr/share/texlive/texmf-dist/tex/latex/ctex/ctexhook.sty"], |
32369 |
++ "texlive-lang-chinese", 2); |
32370 |
++ |
32371 |
+ check_missing_file(["/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"], |
32372 |
+ "fonts-dejavu", 2); |
32373 |
+ |
32374 |
+diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c |
32375 |
+index 9309e62d46eda..baa12d1007c7c 100644 |
32376 |
+--- a/security/selinux/hooks.c |
32377 |
++++ b/security/selinux/hooks.c |
32378 |
+@@ -987,18 +987,22 @@ out: |
32379 |
+ static int selinux_add_opt(int token, const char *s, void **mnt_opts) |
32380 |
+ { |
32381 |
+ struct selinux_mnt_opts *opts = *mnt_opts; |
32382 |
++ bool is_alloc_opts = false; |
32383 |
+ |
32384 |
+ if (token == Opt_seclabel) /* eaten and completely ignored */ |
32385 |
+ return 0; |
32386 |
+ |
32387 |
++ if (!s) |
32388 |
++ return -ENOMEM; |
32389 |
++ |
32390 |
+ if (!opts) { |
32391 |
+ opts = kzalloc(sizeof(struct selinux_mnt_opts), GFP_KERNEL); |
32392 |
+ if (!opts) |
32393 |
+ return -ENOMEM; |
32394 |
+ *mnt_opts = opts; |
32395 |
++ is_alloc_opts = true; |
32396 |
+ } |
32397 |
+- if (!s) |
32398 |
+- return -ENOMEM; |
32399 |
++ |
32400 |
+ switch (token) { |
32401 |
+ case Opt_context: |
32402 |
+ if (opts->context || opts->defcontext) |
32403 |
+@@ -1023,6 +1027,10 @@ static int selinux_add_opt(int token, const char *s, void **mnt_opts) |
32404 |
+ } |
32405 |
+ return 0; |
32406 |
+ Einval: |
32407 |
++ if (is_alloc_opts) { |
32408 |
++ kfree(opts); |
32409 |
++ *mnt_opts = NULL; |
32410 |
++ } |
32411 |
+ pr_warn(SEL_MOUNT_FAIL_MSG); |
32412 |
+ return -EINVAL; |
32413 |
+ } |
32414 |
+diff --git a/sound/core/jack.c b/sound/core/jack.c |
32415 |
+index 537df1e98f8ac..d1e3055f2b6a5 100644 |
32416 |
+--- a/sound/core/jack.c |
32417 |
++++ b/sound/core/jack.c |
32418 |
+@@ -62,10 +62,13 @@ static int snd_jack_dev_free(struct snd_device *device) |
32419 |
+ struct snd_card *card = device->card; |
32420 |
+ struct snd_jack_kctl *jack_kctl, *tmp_jack_kctl; |
32421 |
+ |
32422 |
++ down_write(&card->controls_rwsem); |
32423 |
+ list_for_each_entry_safe(jack_kctl, tmp_jack_kctl, &jack->kctl_list, list) { |
32424 |
+ list_del_init(&jack_kctl->list); |
32425 |
+ snd_ctl_remove(card, jack_kctl->kctl); |
32426 |
+ } |
32427 |
++ up_write(&card->controls_rwsem); |
32428 |
++ |
32429 |
+ if (jack->private_free) |
32430 |
+ jack->private_free(jack); |
32431 |
+ |
32432 |
+diff --git a/sound/core/misc.c b/sound/core/misc.c |
32433 |
+index 3579dd7a161f7..50e4aaa6270d1 100644 |
32434 |
+--- a/sound/core/misc.c |
32435 |
++++ b/sound/core/misc.c |
32436 |
+@@ -112,7 +112,7 @@ snd_pci_quirk_lookup_id(u16 vendor, u16 device, |
32437 |
+ { |
32438 |
+ const struct snd_pci_quirk *q; |
32439 |
+ |
32440 |
+- for (q = list; q->subvendor; q++) { |
32441 |
++ for (q = list; q->subvendor || q->subdevice; q++) { |
32442 |
+ if (q->subvendor != vendor) |
32443 |
+ continue; |
32444 |
+ if (!q->subdevice || |
32445 |
+diff --git a/sound/core/oss/pcm_oss.c b/sound/core/oss/pcm_oss.c |
32446 |
+index 20a0a4771b9a8..3ee9edf858156 100644 |
32447 |
+--- a/sound/core/oss/pcm_oss.c |
32448 |
++++ b/sound/core/oss/pcm_oss.c |
32449 |
+@@ -2065,7 +2065,7 @@ static int snd_pcm_oss_set_trigger(struct snd_pcm_oss_file *pcm_oss_file, int tr |
32450 |
+ int err, cmd; |
32451 |
+ |
32452 |
+ #ifdef OSS_DEBUG |
32453 |
+- pcm_dbg(substream->pcm, "pcm_oss: trigger = 0x%x\n", trigger); |
32454 |
++ pr_debug("pcm_oss: trigger = 0x%x\n", trigger); |
32455 |
+ #endif |
32456 |
+ |
32457 |
+ psubstream = pcm_oss_file->streams[SNDRV_PCM_STREAM_PLAYBACK]; |
32458 |
+diff --git a/sound/core/pcm.c b/sound/core/pcm.c |
32459 |
+index 6fd3677685d70..ba4a987ed1c62 100644 |
32460 |
+--- a/sound/core/pcm.c |
32461 |
++++ b/sound/core/pcm.c |
32462 |
+@@ -810,7 +810,11 @@ EXPORT_SYMBOL(snd_pcm_new_internal); |
32463 |
+ static void free_chmap(struct snd_pcm_str *pstr) |
32464 |
+ { |
32465 |
+ if (pstr->chmap_kctl) { |
32466 |
+- snd_ctl_remove(pstr->pcm->card, pstr->chmap_kctl); |
32467 |
++ struct snd_card *card = pstr->pcm->card; |
32468 |
++ |
32469 |
++ down_write(&card->controls_rwsem); |
32470 |
++ snd_ctl_remove(card, pstr->chmap_kctl); |
32471 |
++ up_write(&card->controls_rwsem); |
32472 |
+ pstr->chmap_kctl = NULL; |
32473 |
+ } |
32474 |
+ } |
32475 |
+diff --git a/sound/core/seq/seq_queue.c b/sound/core/seq/seq_queue.c |
32476 |
+index d6c02dea976c8..bc933104c3eea 100644 |
32477 |
+--- a/sound/core/seq/seq_queue.c |
32478 |
++++ b/sound/core/seq/seq_queue.c |
32479 |
+@@ -235,12 +235,15 @@ struct snd_seq_queue *snd_seq_queue_find_name(char *name) |
32480 |
+ |
32481 |
+ /* -------------------------------------------------------- */ |
32482 |
+ |
32483 |
++#define MAX_CELL_PROCESSES_IN_QUEUE 1000 |
32484 |
++ |
32485 |
+ void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop) |
32486 |
+ { |
32487 |
+ unsigned long flags; |
32488 |
+ struct snd_seq_event_cell *cell; |
32489 |
+ snd_seq_tick_time_t cur_tick; |
32490 |
+ snd_seq_real_time_t cur_time; |
32491 |
++ int processed = 0; |
32492 |
+ |
32493 |
+ if (q == NULL) |
32494 |
+ return; |
32495 |
+@@ -263,6 +266,8 @@ void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop) |
32496 |
+ if (!cell) |
32497 |
+ break; |
32498 |
+ snd_seq_dispatch_event(cell, atomic, hop); |
32499 |
++ if (++processed >= MAX_CELL_PROCESSES_IN_QUEUE) |
32500 |
++ goto out; /* the rest processed at the next batch */ |
32501 |
+ } |
32502 |
+ |
32503 |
+ /* Process time queue... */ |
32504 |
+@@ -272,14 +277,19 @@ void snd_seq_check_queue(struct snd_seq_queue *q, int atomic, int hop) |
32505 |
+ if (!cell) |
32506 |
+ break; |
32507 |
+ snd_seq_dispatch_event(cell, atomic, hop); |
32508 |
++ if (++processed >= MAX_CELL_PROCESSES_IN_QUEUE) |
32509 |
++ goto out; /* the rest processed at the next batch */ |
32510 |
+ } |
32511 |
+ |
32512 |
++ out: |
32513 |
+ /* free lock */ |
32514 |
+ spin_lock_irqsave(&q->check_lock, flags); |
32515 |
+ if (q->check_again) { |
32516 |
+ q->check_again = 0; |
32517 |
+- spin_unlock_irqrestore(&q->check_lock, flags); |
32518 |
+- goto __again; |
32519 |
++ if (processed < MAX_CELL_PROCESSES_IN_QUEUE) { |
32520 |
++ spin_unlock_irqrestore(&q->check_lock, flags); |
32521 |
++ goto __again; |
32522 |
++ } |
32523 |
+ } |
32524 |
+ q->check_blocked = 0; |
32525 |
+ spin_unlock_irqrestore(&q->check_lock, flags); |
32526 |
+diff --git a/sound/hda/hdac_stream.c b/sound/hda/hdac_stream.c |
32527 |
+index 9867555883c34..aa7955fdf68a0 100644 |
32528 |
+--- a/sound/hda/hdac_stream.c |
32529 |
++++ b/sound/hda/hdac_stream.c |
32530 |
+@@ -534,17 +534,11 @@ static void azx_timecounter_init(struct hdac_stream *azx_dev, |
32531 |
+ cc->mask = CLOCKSOURCE_MASK(32); |
32532 |
+ |
32533 |
+ /* |
32534 |
+- * Converting from 24 MHz to ns means applying a 125/3 factor. |
32535 |
+- * To avoid any saturation issues in intermediate operations, |
32536 |
+- * the 125 factor is applied first. The division is applied |
32537 |
+- * last after reading the timecounter value. |
32538 |
+- * Applying the 1/3 factor as part of the multiplication |
32539 |
+- * requires at least 20 bits for a decent precision, however |
32540 |
+- * overflows occur after about 4 hours or less, not a option. |
32541 |
++ * Calculate the optimal mult/shift values. The counter wraps |
32542 |
++ * around after ~178.9 seconds. |
32543 |
+ */ |
32544 |
+- |
32545 |
+- cc->mult = 125; /* saturation after 195 years */ |
32546 |
+- cc->shift = 0; |
32547 |
++ clocks_calc_mult_shift(&cc->mult, &cc->shift, 24000000, |
32548 |
++ NSEC_PER_SEC, 178); |
32549 |
+ |
32550 |
+ nsec = 0; /* audio time is elapsed time since trigger */ |
32551 |
+ timecounter_init(tc, cc, nsec); |
32552 |
+diff --git a/sound/pci/hda/hda_bind.c b/sound/pci/hda/hda_bind.c |
32553 |
+index 1c8bffc3eec6e..7153bd53e1893 100644 |
32554 |
+--- a/sound/pci/hda/hda_bind.c |
32555 |
++++ b/sound/pci/hda/hda_bind.c |
32556 |
+@@ -156,6 +156,11 @@ static int hda_codec_driver_remove(struct device *dev) |
32557 |
+ return codec->bus->core.ext_ops->hdev_detach(&codec->core); |
32558 |
+ } |
32559 |
+ |
32560 |
++ refcount_dec(&codec->pcm_ref); |
32561 |
++ snd_hda_codec_disconnect_pcms(codec); |
32562 |
++ wait_event(codec->remove_sleep, !refcount_read(&codec->pcm_ref)); |
32563 |
++ snd_power_sync_ref(codec->bus->card); |
32564 |
++ |
32565 |
+ if (codec->patch_ops.free) |
32566 |
+ codec->patch_ops.free(codec); |
32567 |
+ snd_hda_codec_cleanup_for_unbind(codec); |
32568 |
+diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c |
32569 |
+index 0c4a337c9fc0d..7016b48227bf2 100644 |
32570 |
+--- a/sound/pci/hda/hda_codec.c |
32571 |
++++ b/sound/pci/hda/hda_codec.c |
32572 |
+@@ -703,20 +703,10 @@ get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid) |
32573 |
+ /* |
32574 |
+ * PCM device |
32575 |
+ */ |
32576 |
+-static void release_pcm(struct kref *kref) |
32577 |
+-{ |
32578 |
+- struct hda_pcm *pcm = container_of(kref, struct hda_pcm, kref); |
32579 |
+- |
32580 |
+- if (pcm->pcm) |
32581 |
+- snd_device_free(pcm->codec->card, pcm->pcm); |
32582 |
+- clear_bit(pcm->device, pcm->codec->bus->pcm_dev_bits); |
32583 |
+- kfree(pcm->name); |
32584 |
+- kfree(pcm); |
32585 |
+-} |
32586 |
+- |
32587 |
+ void snd_hda_codec_pcm_put(struct hda_pcm *pcm) |
32588 |
+ { |
32589 |
+- kref_put(&pcm->kref, release_pcm); |
32590 |
++ if (refcount_dec_and_test(&pcm->codec->pcm_ref)) |
32591 |
++ wake_up(&pcm->codec->remove_sleep); |
32592 |
+ } |
32593 |
+ EXPORT_SYMBOL_GPL(snd_hda_codec_pcm_put); |
32594 |
+ |
32595 |
+@@ -731,7 +721,6 @@ struct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec, |
32596 |
+ return NULL; |
32597 |
+ |
32598 |
+ pcm->codec = codec; |
32599 |
+- kref_init(&pcm->kref); |
32600 |
+ va_start(args, fmt); |
32601 |
+ pcm->name = kvasprintf(GFP_KERNEL, fmt, args); |
32602 |
+ va_end(args); |
32603 |
+@@ -741,6 +730,7 @@ struct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec, |
32604 |
+ } |
32605 |
+ |
32606 |
+ list_add_tail(&pcm->list, &codec->pcm_list_head); |
32607 |
++ refcount_inc(&codec->pcm_ref); |
32608 |
+ return pcm; |
32609 |
+ } |
32610 |
+ EXPORT_SYMBOL_GPL(snd_hda_codec_pcm_new); |
32611 |
+@@ -748,15 +738,31 @@ EXPORT_SYMBOL_GPL(snd_hda_codec_pcm_new); |
32612 |
+ /* |
32613 |
+ * codec destructor |
32614 |
+ */ |
32615 |
++void snd_hda_codec_disconnect_pcms(struct hda_codec *codec) |
32616 |
++{ |
32617 |
++ struct hda_pcm *pcm; |
32618 |
++ |
32619 |
++ list_for_each_entry(pcm, &codec->pcm_list_head, list) { |
32620 |
++ if (pcm->disconnected) |
32621 |
++ continue; |
32622 |
++ if (pcm->pcm) |
32623 |
++ snd_device_disconnect(codec->card, pcm->pcm); |
32624 |
++ snd_hda_codec_pcm_put(pcm); |
32625 |
++ pcm->disconnected = 1; |
32626 |
++ } |
32627 |
++} |
32628 |
++ |
32629 |
+ static void codec_release_pcms(struct hda_codec *codec) |
32630 |
+ { |
32631 |
+ struct hda_pcm *pcm, *n; |
32632 |
+ |
32633 |
+ list_for_each_entry_safe(pcm, n, &codec->pcm_list_head, list) { |
32634 |
+- list_del_init(&pcm->list); |
32635 |
++ list_del(&pcm->list); |
32636 |
+ if (pcm->pcm) |
32637 |
+- snd_device_disconnect(codec->card, pcm->pcm); |
32638 |
+- snd_hda_codec_pcm_put(pcm); |
32639 |
++ snd_device_free(pcm->codec->card, pcm->pcm); |
32640 |
++ clear_bit(pcm->device, pcm->codec->bus->pcm_dev_bits); |
32641 |
++ kfree(pcm->name); |
32642 |
++ kfree(pcm); |
32643 |
+ } |
32644 |
+ } |
32645 |
+ |
32646 |
+@@ -769,6 +775,7 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec) |
32647 |
+ codec->registered = 0; |
32648 |
+ } |
32649 |
+ |
32650 |
++ snd_hda_codec_disconnect_pcms(codec); |
32651 |
+ cancel_delayed_work_sync(&codec->jackpoll_work); |
32652 |
+ if (!codec->in_freeing) |
32653 |
+ snd_hda_ctls_clear(codec); |
32654 |
+@@ -792,6 +799,7 @@ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec) |
32655 |
+ remove_conn_list(codec); |
32656 |
+ snd_hdac_regmap_exit(&codec->core); |
32657 |
+ codec->configured = 0; |
32658 |
++ refcount_set(&codec->pcm_ref, 1); /* reset refcount */ |
32659 |
+ } |
32660 |
+ EXPORT_SYMBOL_GPL(snd_hda_codec_cleanup_for_unbind); |
32661 |
+ |
32662 |
+@@ -958,6 +966,8 @@ int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card, |
32663 |
+ snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8); |
32664 |
+ INIT_LIST_HEAD(&codec->conn_list); |
32665 |
+ INIT_LIST_HEAD(&codec->pcm_list_head); |
32666 |
++ refcount_set(&codec->pcm_ref, 1); |
32667 |
++ init_waitqueue_head(&codec->remove_sleep); |
32668 |
+ |
32669 |
+ INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work); |
32670 |
+ codec->depop_delay = -1; |
32671 |
+@@ -1727,8 +1737,11 @@ void snd_hda_ctls_clear(struct hda_codec *codec) |
32672 |
+ { |
32673 |
+ int i; |
32674 |
+ struct hda_nid_item *items = codec->mixers.list; |
32675 |
++ |
32676 |
++ down_write(&codec->card->controls_rwsem); |
32677 |
+ for (i = 0; i < codec->mixers.used; i++) |
32678 |
+ snd_ctl_remove(codec->card, items[i].kctl); |
32679 |
++ up_write(&codec->card->controls_rwsem); |
32680 |
+ snd_array_free(&codec->mixers); |
32681 |
+ snd_array_free(&codec->nids); |
32682 |
+ } |
32683 |
+diff --git a/sound/pci/hda/hda_controller.c b/sound/pci/hda/hda_controller.c |
32684 |
+index 930ae4002a818..75dcb14ff20ad 100644 |
32685 |
+--- a/sound/pci/hda/hda_controller.c |
32686 |
++++ b/sound/pci/hda/hda_controller.c |
32687 |
+@@ -504,7 +504,6 @@ static int azx_get_time_info(struct snd_pcm_substream *substream, |
32688 |
+ snd_pcm_gettime(substream->runtime, system_ts); |
32689 |
+ |
32690 |
+ nsec = timecounter_read(&azx_dev->core.tc); |
32691 |
+- nsec = div_u64(nsec, 3); /* can be optimized */ |
32692 |
+ if (audio_tstamp_config->report_delay) |
32693 |
+ nsec = azx_adjust_codec_delay(substream, nsec); |
32694 |
+ |
32695 |
+diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h |
32696 |
+index d22c96eb2f8fb..8621f576446b8 100644 |
32697 |
+--- a/sound/pci/hda/hda_local.h |
32698 |
++++ b/sound/pci/hda/hda_local.h |
32699 |
+@@ -137,6 +137,7 @@ int __snd_hda_add_vmaster(struct hda_codec *codec, char *name, |
32700 |
+ int snd_hda_codec_reset(struct hda_codec *codec); |
32701 |
+ void snd_hda_codec_register(struct hda_codec *codec); |
32702 |
+ void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec); |
32703 |
++void snd_hda_codec_disconnect_pcms(struct hda_codec *codec); |
32704 |
+ |
32705 |
+ #define snd_hda_regmap_sync(codec) snd_hdac_regmap_sync(&(codec)->core) |
32706 |
+ |
32707 |
+diff --git a/sound/pci/hda/patch_cs8409-tables.c b/sound/pci/hda/patch_cs8409-tables.c |
32708 |
+index 0fb0a428428b4..df0b4522babf7 100644 |
32709 |
+--- a/sound/pci/hda/patch_cs8409-tables.c |
32710 |
++++ b/sound/pci/hda/patch_cs8409-tables.c |
32711 |
+@@ -252,6 +252,7 @@ struct sub_codec cs8409_cs42l42_codec = { |
32712 |
+ .init_seq_num = ARRAY_SIZE(cs42l42_init_reg_seq), |
32713 |
+ .hp_jack_in = 0, |
32714 |
+ .mic_jack_in = 0, |
32715 |
++ .force_status_change = 1, |
32716 |
+ .paged = 1, |
32717 |
+ .suspended = 1, |
32718 |
+ .no_type_dect = 0, |
32719 |
+@@ -443,6 +444,7 @@ struct sub_codec dolphin_cs42l42_0 = { |
32720 |
+ .init_seq_num = ARRAY_SIZE(dolphin_c0_init_reg_seq), |
32721 |
+ .hp_jack_in = 0, |
32722 |
+ .mic_jack_in = 0, |
32723 |
++ .force_status_change = 1, |
32724 |
+ .paged = 1, |
32725 |
+ .suspended = 1, |
32726 |
+ .no_type_dect = 0, |
32727 |
+@@ -456,6 +458,7 @@ struct sub_codec dolphin_cs42l42_1 = { |
32728 |
+ .init_seq_num = ARRAY_SIZE(dolphin_c1_init_reg_seq), |
32729 |
+ .hp_jack_in = 0, |
32730 |
+ .mic_jack_in = 0, |
32731 |
++ .force_status_change = 1, |
32732 |
+ .paged = 1, |
32733 |
+ .suspended = 1, |
32734 |
+ .no_type_dect = 1, |
32735 |
+diff --git a/sound/pci/hda/patch_cs8409.c b/sound/pci/hda/patch_cs8409.c |
32736 |
+index 039b9f2f8e947..aff2b5abb81ea 100644 |
32737 |
+--- a/sound/pci/hda/patch_cs8409.c |
32738 |
++++ b/sound/pci/hda/patch_cs8409.c |
32739 |
+@@ -628,15 +628,17 @@ static void cs42l42_run_jack_detect(struct sub_codec *cs42l42) |
32740 |
+ cs8409_i2c_write(cs42l42, 0x1b74, 0x07); |
32741 |
+ cs8409_i2c_write(cs42l42, 0x131b, 0xFD); |
32742 |
+ cs8409_i2c_write(cs42l42, 0x1120, 0x80); |
32743 |
+- /* Wait ~100us*/ |
32744 |
+- usleep_range(100, 200); |
32745 |
++ /* Wait ~20ms*/ |
32746 |
++ usleep_range(20000, 25000); |
32747 |
+ cs8409_i2c_write(cs42l42, 0x111f, 0x77); |
32748 |
+ cs8409_i2c_write(cs42l42, 0x1120, 0xc0); |
32749 |
+ } |
32750 |
+ |
32751 |
+ static int cs42l42_handle_tip_sense(struct sub_codec *cs42l42, unsigned int reg_ts_status) |
32752 |
+ { |
32753 |
+- int status_changed = 0; |
32754 |
++ int status_changed = cs42l42->force_status_change; |
32755 |
++ |
32756 |
++ cs42l42->force_status_change = 0; |
32757 |
+ |
32758 |
+ /* TIP_SENSE INSERT/REMOVE */ |
32759 |
+ switch (reg_ts_status) { |
32760 |
+@@ -791,6 +793,7 @@ static void cs42l42_suspend(struct sub_codec *cs42l42) |
32761 |
+ cs42l42->last_page = 0; |
32762 |
+ cs42l42->hp_jack_in = 0; |
32763 |
+ cs42l42->mic_jack_in = 0; |
32764 |
++ cs42l42->force_status_change = 1; |
32765 |
+ |
32766 |
+ /* Put CS42L42 into Reset */ |
32767 |
+ gpio_data = snd_hda_codec_read(codec, CS8409_PIN_AFG, 0, AC_VERB_GET_GPIO_DATA, 0); |
32768 |
+diff --git a/sound/pci/hda/patch_cs8409.h b/sound/pci/hda/patch_cs8409.h |
32769 |
+index ade2b838590cf..d0b725c7285b6 100644 |
32770 |
+--- a/sound/pci/hda/patch_cs8409.h |
32771 |
++++ b/sound/pci/hda/patch_cs8409.h |
32772 |
+@@ -305,6 +305,7 @@ struct sub_codec { |
32773 |
+ |
32774 |
+ unsigned int hp_jack_in:1; |
32775 |
+ unsigned int mic_jack_in:1; |
32776 |
++ unsigned int force_status_change:1; |
32777 |
+ unsigned int suspended:1; |
32778 |
+ unsigned int paged:1; |
32779 |
+ unsigned int last_page; |
32780 |
+diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig |
32781 |
+index 216cea04ad704..f12c9b9426788 100644 |
32782 |
+--- a/sound/soc/codecs/Kconfig |
32783 |
++++ b/sound/soc/codecs/Kconfig |
32784 |
+@@ -235,8 +235,7 @@ config SND_SOC_ALL_CODECS |
32785 |
+ imply SND_SOC_UDA1380 |
32786 |
+ imply SND_SOC_WCD9335 |
32787 |
+ imply SND_SOC_WCD934X |
32788 |
+- imply SND_SOC_WCD937X |
32789 |
+- imply SND_SOC_WCD938X |
32790 |
++ imply SND_SOC_WCD938X_SDW |
32791 |
+ imply SND_SOC_LPASS_RX_MACRO |
32792 |
+ imply SND_SOC_LPASS_TX_MACRO |
32793 |
+ imply SND_SOC_WL1273 |
32794 |
+diff --git a/sound/soc/codecs/rt5663.c b/sound/soc/codecs/rt5663.c |
32795 |
+index be9fc58ff6812..ee09ccd448dcd 100644 |
32796 |
+--- a/sound/soc/codecs/rt5663.c |
32797 |
++++ b/sound/soc/codecs/rt5663.c |
32798 |
+@@ -3461,6 +3461,7 @@ static void rt5663_calibrate(struct rt5663_priv *rt5663) |
32799 |
+ static int rt5663_parse_dp(struct rt5663_priv *rt5663, struct device *dev) |
32800 |
+ { |
32801 |
+ int table_size; |
32802 |
++ int ret; |
32803 |
+ |
32804 |
+ device_property_read_u32(dev, "realtek,dc_offset_l_manual", |
32805 |
+ &rt5663->pdata.dc_offset_l_manual); |
32806 |
+@@ -3477,9 +3478,11 @@ static int rt5663_parse_dp(struct rt5663_priv *rt5663, struct device *dev) |
32807 |
+ table_size = sizeof(struct impedance_mapping_table) * |
32808 |
+ rt5663->pdata.impedance_sensing_num; |
32809 |
+ rt5663->imp_table = devm_kzalloc(dev, table_size, GFP_KERNEL); |
32810 |
+- device_property_read_u32_array(dev, |
32811 |
++ ret = device_property_read_u32_array(dev, |
32812 |
+ "realtek,impedance_sensing_table", |
32813 |
+ (u32 *)rt5663->imp_table, table_size); |
32814 |
++ if (ret) |
32815 |
++ return ret; |
32816 |
+ } |
32817 |
+ |
32818 |
+ return 0; |
32819 |
+@@ -3504,8 +3507,11 @@ static int rt5663_i2c_probe(struct i2c_client *i2c, |
32820 |
+ |
32821 |
+ if (pdata) |
32822 |
+ rt5663->pdata = *pdata; |
32823 |
+- else |
32824 |
+- rt5663_parse_dp(rt5663, &i2c->dev); |
32825 |
++ else { |
32826 |
++ ret = rt5663_parse_dp(rt5663, &i2c->dev); |
32827 |
++ if (ret) |
32828 |
++ return ret; |
32829 |
++ } |
32830 |
+ |
32831 |
+ for (i = 0; i < ARRAY_SIZE(rt5663->supplies); i++) |
32832 |
+ rt5663->supplies[i].supply = rt5663_supply_names[i]; |
32833 |
+diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c |
32834 |
+index 24b41881a68f8..d7d1536a4f377 100644 |
32835 |
+--- a/sound/soc/fsl/fsl_asrc.c |
32836 |
++++ b/sound/soc/fsl/fsl_asrc.c |
32837 |
+@@ -19,6 +19,7 @@ |
32838 |
+ #include "fsl_asrc.h" |
32839 |
+ |
32840 |
+ #define IDEAL_RATIO_DECIMAL_DEPTH 26 |
32841 |
++#define DIVIDER_NUM 64 |
32842 |
+ |
32843 |
+ #define pair_err(fmt, ...) \ |
32844 |
+ dev_err(&asrc->pdev->dev, "Pair %c: " fmt, 'A' + index, ##__VA_ARGS__) |
32845 |
+@@ -101,6 +102,55 @@ static unsigned char clk_map_imx8qxp[2][ASRC_CLK_MAP_LEN] = { |
32846 |
+ }, |
32847 |
+ }; |
32848 |
+ |
32849 |
++/* |
32850 |
++ * According to RM, the divider range is 1 ~ 8, |
32851 |
++ * prescaler is power of 2 from 1 ~ 128. |
32852 |
++ */ |
32853 |
++static int asrc_clk_divider[DIVIDER_NUM] = { |
32854 |
++ 1, 2, 4, 8, 16, 32, 64, 128, /* divider = 1 */ |
32855 |
++ 2, 4, 8, 16, 32, 64, 128, 256, /* divider = 2 */ |
32856 |
++ 3, 6, 12, 24, 48, 96, 192, 384, /* divider = 3 */ |
32857 |
++ 4, 8, 16, 32, 64, 128, 256, 512, /* divider = 4 */ |
32858 |
++ 5, 10, 20, 40, 80, 160, 320, 640, /* divider = 5 */ |
32859 |
++ 6, 12, 24, 48, 96, 192, 384, 768, /* divider = 6 */ |
32860 |
++ 7, 14, 28, 56, 112, 224, 448, 896, /* divider = 7 */ |
32861 |
++ 8, 16, 32, 64, 128, 256, 512, 1024, /* divider = 8 */ |
32862 |
++}; |
32863 |
++ |
32864 |
++/* |
32865 |
++ * Check if the divider is available for internal ratio mode |
32866 |
++ */ |
32867 |
++static bool fsl_asrc_divider_avail(int clk_rate, int rate, int *div) |
32868 |
++{ |
32869 |
++ u32 rem, i; |
32870 |
++ u64 n; |
32871 |
++ |
32872 |
++ if (div) |
32873 |
++ *div = 0; |
32874 |
++ |
32875 |
++ if (clk_rate == 0 || rate == 0) |
32876 |
++ return false; |
32877 |
++ |
32878 |
++ n = clk_rate; |
32879 |
++ rem = do_div(n, rate); |
32880 |
++ |
32881 |
++ if (div) |
32882 |
++ *div = n; |
32883 |
++ |
32884 |
++ if (rem != 0) |
32885 |
++ return false; |
32886 |
++ |
32887 |
++ for (i = 0; i < DIVIDER_NUM; i++) { |
32888 |
++ if (n == asrc_clk_divider[i]) |
32889 |
++ break; |
32890 |
++ } |
32891 |
++ |
32892 |
++ if (i == DIVIDER_NUM) |
32893 |
++ return false; |
32894 |
++ |
32895 |
++ return true; |
32896 |
++} |
32897 |
++ |
32898 |
+ /** |
32899 |
+ * fsl_asrc_sel_proc - Select the pre-processing and post-processing options |
32900 |
+ * @inrate: input sample rate |
32901 |
+@@ -330,12 +380,12 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate) |
32902 |
+ enum asrc_word_width input_word_width; |
32903 |
+ enum asrc_word_width output_word_width; |
32904 |
+ u32 inrate, outrate, indiv, outdiv; |
32905 |
+- u32 clk_index[2], div[2], rem[2]; |
32906 |
++ u32 clk_index[2], div[2]; |
32907 |
+ u64 clk_rate; |
32908 |
+ int in, out, channels; |
32909 |
+ int pre_proc, post_proc; |
32910 |
+ struct clk *clk; |
32911 |
+- bool ideal; |
32912 |
++ bool ideal, div_avail; |
32913 |
+ |
32914 |
+ if (!config) { |
32915 |
+ pair_err("invalid pair config\n"); |
32916 |
+@@ -415,8 +465,7 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate) |
32917 |
+ clk = asrc_priv->asrck_clk[clk_index[ideal ? OUT : IN]]; |
32918 |
+ |
32919 |
+ clk_rate = clk_get_rate(clk); |
32920 |
+- rem[IN] = do_div(clk_rate, inrate); |
32921 |
+- div[IN] = (u32)clk_rate; |
32922 |
++ div_avail = fsl_asrc_divider_avail(clk_rate, inrate, &div[IN]); |
32923 |
+ |
32924 |
+ /* |
32925 |
+ * The divider range is [1, 1024], defined by the hardware. For non- |
32926 |
+@@ -425,7 +474,7 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate) |
32927 |
+ * only result in different converting speeds. So remainder does not |
32928 |
+ * matter, as long as we keep the divider within its valid range. |
32929 |
+ */ |
32930 |
+- if (div[IN] == 0 || (!ideal && (div[IN] > 1024 || rem[IN] != 0))) { |
32931 |
++ if (div[IN] == 0 || (!ideal && !div_avail)) { |
32932 |
+ pair_err("failed to support input sample rate %dHz by asrck_%x\n", |
32933 |
+ inrate, clk_index[ideal ? OUT : IN]); |
32934 |
+ return -EINVAL; |
32935 |
+@@ -436,13 +485,12 @@ static int fsl_asrc_config_pair(struct fsl_asrc_pair *pair, bool use_ideal_rate) |
32936 |
+ clk = asrc_priv->asrck_clk[clk_index[OUT]]; |
32937 |
+ clk_rate = clk_get_rate(clk); |
32938 |
+ if (ideal && use_ideal_rate) |
32939 |
+- rem[OUT] = do_div(clk_rate, IDEAL_RATIO_RATE); |
32940 |
++ div_avail = fsl_asrc_divider_avail(clk_rate, IDEAL_RATIO_RATE, &div[OUT]); |
32941 |
+ else |
32942 |
+- rem[OUT] = do_div(clk_rate, outrate); |
32943 |
+- div[OUT] = clk_rate; |
32944 |
++ div_avail = fsl_asrc_divider_avail(clk_rate, outrate, &div[OUT]); |
32945 |
+ |
32946 |
+ /* Output divider has the same limitation as the input one */ |
32947 |
+- if (div[OUT] == 0 || (!ideal && (div[OUT] > 1024 || rem[OUT] != 0))) { |
32948 |
++ if (div[OUT] == 0 || (!ideal && !div_avail)) { |
32949 |
+ pair_err("failed to support output sample rate %dHz by asrck_%x\n", |
32950 |
+ outrate, clk_index[OUT]); |
32951 |
+ return -EINVAL; |
32952 |
+@@ -621,8 +669,7 @@ static void fsl_asrc_select_clk(struct fsl_asrc_priv *asrc_priv, |
32953 |
+ clk_index = asrc_priv->clk_map[j][i]; |
32954 |
+ clk_rate = clk_get_rate(asrc_priv->asrck_clk[clk_index]); |
32955 |
+ /* Only match a perfect clock source with no remainder */ |
32956 |
+- if (clk_rate != 0 && (clk_rate / rate[j]) <= 1024 && |
32957 |
+- (clk_rate % rate[j]) == 0) |
32958 |
++ if (fsl_asrc_divider_avail(clk_rate, rate[j], NULL)) |
32959 |
+ break; |
32960 |
+ } |
32961 |
+ |
32962 |
+diff --git a/sound/soc/fsl/fsl_mqs.c b/sound/soc/fsl/fsl_mqs.c |
32963 |
+index 69aeb0e71844d..0d4efbed41dab 100644 |
32964 |
+--- a/sound/soc/fsl/fsl_mqs.c |
32965 |
++++ b/sound/soc/fsl/fsl_mqs.c |
32966 |
+@@ -337,4 +337,4 @@ module_platform_driver(fsl_mqs_driver); |
32967 |
+ MODULE_AUTHOR("Shengjiu Wang <Shengjiu.Wang@×××.com>"); |
32968 |
+ MODULE_DESCRIPTION("MQS codec driver"); |
32969 |
+ MODULE_LICENSE("GPL v2"); |
32970 |
+-MODULE_ALIAS("platform: fsl-mqs"); |
32971 |
++MODULE_ALIAS("platform:fsl-mqs"); |
32972 |
+diff --git a/sound/soc/fsl/imx-card.c b/sound/soc/fsl/imx-card.c |
32973 |
+index 58fd0639a0698..db947180617a6 100644 |
32974 |
+--- a/sound/soc/fsl/imx-card.c |
32975 |
++++ b/sound/soc/fsl/imx-card.c |
32976 |
+@@ -120,7 +120,7 @@ struct imx_card_data { |
32977 |
+ |
32978 |
+ static struct imx_akcodec_fs_mul ak4458_fs_mul[] = { |
32979 |
+ /* Normal, < 32kHz */ |
32980 |
+- { .rmin = 8000, .rmax = 24000, .wmin = 1024, .wmax = 1024, }, |
32981 |
++ { .rmin = 8000, .rmax = 24000, .wmin = 256, .wmax = 1024, }, |
32982 |
+ /* Normal, 32kHz */ |
32983 |
+ { .rmin = 32000, .rmax = 32000, .wmin = 256, .wmax = 1024, }, |
32984 |
+ /* Normal */ |
32985 |
+@@ -151,8 +151,8 @@ static struct imx_akcodec_fs_mul ak4497_fs_mul[] = { |
32986 |
+ * Table 7 - mapping multiplier and speed mode |
32987 |
+ * Tables 8 & 9 - mapping speed mode and LRCK fs |
32988 |
+ */ |
32989 |
+- { .rmin = 8000, .rmax = 32000, .wmin = 1024, .wmax = 1024, }, /* Normal, <= 32kHz */ |
32990 |
+- { .rmin = 44100, .rmax = 48000, .wmin = 512, .wmax = 512, }, /* Normal */ |
32991 |
++ { .rmin = 8000, .rmax = 32000, .wmin = 256, .wmax = 1024, }, /* Normal, <= 32kHz */ |
32992 |
++ { .rmin = 44100, .rmax = 48000, .wmin = 256, .wmax = 512, }, /* Normal */ |
32993 |
+ { .rmin = 88200, .rmax = 96000, .wmin = 256, .wmax = 256, }, /* Double */ |
32994 |
+ { .rmin = 176400, .rmax = 192000, .wmin = 128, .wmax = 128, }, /* Quad */ |
32995 |
+ { .rmin = 352800, .rmax = 384000, .wmin = 128, .wmax = 128, }, /* Oct */ |
32996 |
+@@ -164,7 +164,7 @@ static struct imx_akcodec_fs_mul ak4497_fs_mul[] = { |
32997 |
+ * (Table 4 from datasheet) |
32998 |
+ */ |
32999 |
+ static struct imx_akcodec_fs_mul ak5558_fs_mul[] = { |
33000 |
+- { .rmin = 8000, .rmax = 32000, .wmin = 1024, .wmax = 1024, }, |
33001 |
++ { .rmin = 8000, .rmax = 32000, .wmin = 512, .wmax = 1024, }, |
33002 |
+ { .rmin = 44100, .rmax = 48000, .wmin = 512, .wmax = 512, }, |
33003 |
+ { .rmin = 88200, .rmax = 96000, .wmin = 256, .wmax = 256, }, |
33004 |
+ { .rmin = 176400, .rmax = 192000, .wmin = 128, .wmax = 128, }, |
33005 |
+@@ -247,13 +247,14 @@ static bool codec_is_akcodec(unsigned int type) |
33006 |
+ } |
33007 |
+ |
33008 |
+ static unsigned long akcodec_get_mclk_rate(struct snd_pcm_substream *substream, |
33009 |
+- struct snd_pcm_hw_params *params) |
33010 |
++ struct snd_pcm_hw_params *params, |
33011 |
++ int slots, int slot_width) |
33012 |
+ { |
33013 |
+ struct snd_soc_pcm_runtime *rtd = substream->private_data; |
33014 |
+ struct imx_card_data *data = snd_soc_card_get_drvdata(rtd->card); |
33015 |
+ const struct imx_card_plat_data *plat_data = data->plat_data; |
33016 |
+ struct dai_link_data *link_data = &data->link_data[rtd->num]; |
33017 |
+- unsigned int width = link_data->slots * link_data->slot_width; |
33018 |
++ unsigned int width = slots * slot_width; |
33019 |
+ unsigned int rate = params_rate(params); |
33020 |
+ int i; |
33021 |
+ |
33022 |
+@@ -349,7 +350,7 @@ static int imx_aif_hw_params(struct snd_pcm_substream *substream, |
33023 |
+ |
33024 |
+ /* Set MCLK freq */ |
33025 |
+ if (codec_is_akcodec(plat_data->type)) |
33026 |
+- mclk_freq = akcodec_get_mclk_rate(substream, params); |
33027 |
++ mclk_freq = akcodec_get_mclk_rate(substream, params, slots, slot_width); |
33028 |
+ else |
33029 |
+ mclk_freq = params_rate(params) * slots * slot_width; |
33030 |
+ /* Use the maximum freq from DSD512 (512*44100 = 22579200) */ |
33031 |
+@@ -553,8 +554,23 @@ static int imx_card_parse_of(struct imx_card_data *data) |
33032 |
+ link_data->cpu_sysclk_id = FSL_SAI_CLK_MAST1; |
33033 |
+ |
33034 |
+ /* sai may support mclk/bclk = 1 */ |
33035 |
+- if (of_find_property(np, "fsl,mclk-equal-bclk", NULL)) |
33036 |
++ if (of_find_property(np, "fsl,mclk-equal-bclk", NULL)) { |
33037 |
+ link_data->one2one_ratio = true; |
33038 |
++ } else { |
33039 |
++ int i; |
33040 |
++ |
33041 |
++ /* |
33042 |
++ * i.MX8MQ don't support one2one ratio, then |
33043 |
++ * with ak4497 only 16bit case is supported. |
33044 |
++ */ |
33045 |
++ for (i = 0; i < ARRAY_SIZE(ak4497_fs_mul); i++) { |
33046 |
++ if (ak4497_fs_mul[i].rmin == 705600 && |
33047 |
++ ak4497_fs_mul[i].rmax == 768000) { |
33048 |
++ ak4497_fs_mul[i].wmin = 32; |
33049 |
++ ak4497_fs_mul[i].wmax = 32; |
33050 |
++ } |
33051 |
++ } |
33052 |
++ } |
33053 |
+ } |
33054 |
+ |
33055 |
+ link->cpus->of_node = args.np; |
33056 |
+diff --git a/sound/soc/fsl/imx-hdmi.c b/sound/soc/fsl/imx-hdmi.c |
33057 |
+index 34a0dceae6216..ef8d7a65ebc61 100644 |
33058 |
+--- a/sound/soc/fsl/imx-hdmi.c |
33059 |
++++ b/sound/soc/fsl/imx-hdmi.c |
33060 |
+@@ -145,6 +145,8 @@ static int imx_hdmi_probe(struct platform_device *pdev) |
33061 |
+ data->dai.capture_only = false; |
33062 |
+ data->dai.init = imx_hdmi_init; |
33063 |
+ |
33064 |
++ put_device(&cpu_pdev->dev); |
33065 |
++ |
33066 |
+ if (of_node_name_eq(cpu_np, "sai")) { |
33067 |
+ data->cpu_priv.sysclk_id[1] = FSL_SAI_CLK_MAST1; |
33068 |
+ data->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1; |
33069 |
+diff --git a/sound/soc/intel/boards/sof_sdw.c b/sound/soc/intel/boards/sof_sdw.c |
33070 |
+index f10496206ceed..76759b2099064 100644 |
33071 |
+--- a/sound/soc/intel/boards/sof_sdw.c |
33072 |
++++ b/sound/soc/intel/boards/sof_sdw.c |
33073 |
+@@ -188,7 +188,7 @@ static const struct dmi_system_id sof_sdw_quirk_table[] = { |
33074 |
+ }, |
33075 |
+ .driver_data = (void *)(SOF_SDW_TGL_HDMI | |
33076 |
+ SOF_SDW_PCH_DMIC | |
33077 |
+- RT711_JD2), |
33078 |
++ RT711_JD1), |
33079 |
+ }, |
33080 |
+ { |
33081 |
+ /* NUC15 'Bishop County' LAPBC510 and LAPBC710 skews */ |
33082 |
+diff --git a/sound/soc/intel/catpt/dsp.c b/sound/soc/intel/catpt/dsp.c |
33083 |
+index 9c5fd18f2600f..346bec0003066 100644 |
33084 |
+--- a/sound/soc/intel/catpt/dsp.c |
33085 |
++++ b/sound/soc/intel/catpt/dsp.c |
33086 |
+@@ -65,6 +65,7 @@ static int catpt_dma_memcpy(struct catpt_dev *cdev, struct dma_chan *chan, |
33087 |
+ { |
33088 |
+ struct dma_async_tx_descriptor *desc; |
33089 |
+ enum dma_status status; |
33090 |
++ int ret; |
33091 |
+ |
33092 |
+ desc = dmaengine_prep_dma_memcpy(chan, dst_addr, src_addr, size, |
33093 |
+ DMA_CTRL_ACK); |
33094 |
+@@ -77,13 +78,22 @@ static int catpt_dma_memcpy(struct catpt_dev *cdev, struct dma_chan *chan, |
33095 |
+ catpt_updatel_shim(cdev, HMDC, |
33096 |
+ CATPT_HMDC_HDDA(CATPT_DMA_DEVID, chan->chan_id), |
33097 |
+ CATPT_HMDC_HDDA(CATPT_DMA_DEVID, chan->chan_id)); |
33098 |
+- dmaengine_submit(desc); |
33099 |
++ |
33100 |
++ ret = dma_submit_error(dmaengine_submit(desc)); |
33101 |
++ if (ret) { |
33102 |
++ dev_err(cdev->dev, "submit tx failed: %d\n", ret); |
33103 |
++ goto clear_hdda; |
33104 |
++ } |
33105 |
++ |
33106 |
+ status = dma_wait_for_async_tx(desc); |
33107 |
++ ret = (status == DMA_COMPLETE) ? 0 : -EPROTO; |
33108 |
++ |
33109 |
++clear_hdda: |
33110 |
+ /* regardless of status, disable access to HOST memory in demand mode */ |
33111 |
+ catpt_updatel_shim(cdev, HMDC, |
33112 |
+ CATPT_HMDC_HDDA(CATPT_DMA_DEVID, chan->chan_id), 0); |
33113 |
+ |
33114 |
+- return (status == DMA_COMPLETE) ? 0 : -EPROTO; |
33115 |
++ return ret; |
33116 |
+ } |
33117 |
+ |
33118 |
+ int catpt_dma_memcpy_todsp(struct catpt_dev *cdev, struct dma_chan *chan, |
33119 |
+diff --git a/sound/soc/intel/skylake/skl-pcm.c b/sound/soc/intel/skylake/skl-pcm.c |
33120 |
+index 9ecaf6a1e8475..e4aa366d356eb 100644 |
33121 |
+--- a/sound/soc/intel/skylake/skl-pcm.c |
33122 |
++++ b/sound/soc/intel/skylake/skl-pcm.c |
33123 |
+@@ -1251,7 +1251,6 @@ static int skl_platform_soc_get_time_info( |
33124 |
+ snd_pcm_gettime(substream->runtime, system_ts); |
33125 |
+ |
33126 |
+ nsec = timecounter_read(&hstr->tc); |
33127 |
+- nsec = div_u64(nsec, 3); /* can be optimized */ |
33128 |
+ if (audio_tstamp_config->report_delay) |
33129 |
+ nsec = skl_adjust_codec_delay(substream, nsec); |
33130 |
+ |
33131 |
+diff --git a/sound/soc/mediatek/mt8173/mt8173-max98090.c b/sound/soc/mediatek/mt8173/mt8173-max98090.c |
33132 |
+index fc94314bfc02f..3bdd4931316cd 100644 |
33133 |
+--- a/sound/soc/mediatek/mt8173/mt8173-max98090.c |
33134 |
++++ b/sound/soc/mediatek/mt8173/mt8173-max98090.c |
33135 |
+@@ -180,6 +180,9 @@ static int mt8173_max98090_dev_probe(struct platform_device *pdev) |
33136 |
+ if (ret) |
33137 |
+ dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", |
33138 |
+ __func__, ret); |
33139 |
++ |
33140 |
++ of_node_put(codec_node); |
33141 |
++ of_node_put(platform_node); |
33142 |
+ return ret; |
33143 |
+ } |
33144 |
+ |
33145 |
+diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c |
33146 |
+index 0f28dc2217c09..390da5bf727eb 100644 |
33147 |
+--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c |
33148 |
++++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5514.c |
33149 |
+@@ -218,6 +218,8 @@ static int mt8173_rt5650_rt5514_dev_probe(struct platform_device *pdev) |
33150 |
+ if (ret) |
33151 |
+ dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", |
33152 |
+ __func__, ret); |
33153 |
++ |
33154 |
++ of_node_put(platform_node); |
33155 |
+ return ret; |
33156 |
+ } |
33157 |
+ |
33158 |
+diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c |
33159 |
+index 077c6ee067806..c8e4e85e10575 100644 |
33160 |
+--- a/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c |
33161 |
++++ b/sound/soc/mediatek/mt8173/mt8173-rt5650-rt5676.c |
33162 |
+@@ -285,6 +285,8 @@ static int mt8173_rt5650_rt5676_dev_probe(struct platform_device *pdev) |
33163 |
+ if (ret) |
33164 |
+ dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", |
33165 |
+ __func__, ret); |
33166 |
++ |
33167 |
++ of_node_put(platform_node); |
33168 |
+ return ret; |
33169 |
+ } |
33170 |
+ |
33171 |
+diff --git a/sound/soc/mediatek/mt8173/mt8173-rt5650.c b/sound/soc/mediatek/mt8173/mt8173-rt5650.c |
33172 |
+index c28ebf891cb05..e168d31f44459 100644 |
33173 |
+--- a/sound/soc/mediatek/mt8173/mt8173-rt5650.c |
33174 |
++++ b/sound/soc/mediatek/mt8173/mt8173-rt5650.c |
33175 |
+@@ -323,6 +323,8 @@ static int mt8173_rt5650_dev_probe(struct platform_device *pdev) |
33176 |
+ if (ret) |
33177 |
+ dev_err(&pdev->dev, "%s snd_soc_register_card fail %d\n", |
33178 |
+ __func__, ret); |
33179 |
++ |
33180 |
++ of_node_put(platform_node); |
33181 |
+ return ret; |
33182 |
+ } |
33183 |
+ |
33184 |
+diff --git a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c |
33185 |
+index a4d26a6fc8492..bda103211e0bd 100644 |
33186 |
+--- a/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c |
33187 |
++++ b/sound/soc/mediatek/mt8183/mt8183-da7219-max98357.c |
33188 |
+@@ -781,7 +781,11 @@ static int mt8183_da7219_max98357_dev_probe(struct platform_device *pdev) |
33189 |
+ return ret; |
33190 |
+ } |
33191 |
+ |
33192 |
+- return devm_snd_soc_register_card(&pdev->dev, card); |
33193 |
++ ret = devm_snd_soc_register_card(&pdev->dev, card); |
33194 |
++ |
33195 |
++ of_node_put(platform_node); |
33196 |
++ of_node_put(hdmi_codec); |
33197 |
++ return ret; |
33198 |
+ } |
33199 |
+ |
33200 |
+ #ifdef CONFIG_OF |
33201 |
+diff --git a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c |
33202 |
+index 94dcbd36c8697..c7b10c48c6c22 100644 |
33203 |
+--- a/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c |
33204 |
++++ b/sound/soc/mediatek/mt8183/mt8183-mt6358-ts3a227-max98357.c |
33205 |
+@@ -780,7 +780,12 @@ mt8183_mt6358_ts3a227_max98357_dev_probe(struct platform_device *pdev) |
33206 |
+ __func__, ret); |
33207 |
+ } |
33208 |
+ |
33209 |
+- return devm_snd_soc_register_card(&pdev->dev, card); |
33210 |
++ ret = devm_snd_soc_register_card(&pdev->dev, card); |
33211 |
++ |
33212 |
++ of_node_put(platform_node); |
33213 |
++ of_node_put(ec_codec); |
33214 |
++ of_node_put(hdmi_codec); |
33215 |
++ return ret; |
33216 |
+ } |
33217 |
+ |
33218 |
+ #ifdef CONFIG_OF |
33219 |
+diff --git a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c |
33220 |
+index a606133951b70..24a5d0adec1ba 100644 |
33221 |
+--- a/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c |
33222 |
++++ b/sound/soc/mediatek/mt8192/mt8192-mt6359-rt1015-rt5682.c |
33223 |
+@@ -1172,7 +1172,11 @@ static int mt8192_mt6359_dev_probe(struct platform_device *pdev) |
33224 |
+ return ret; |
33225 |
+ } |
33226 |
+ |
33227 |
+- return devm_snd_soc_register_card(&pdev->dev, card); |
33228 |
++ ret = devm_snd_soc_register_card(&pdev->dev, card); |
33229 |
++ |
33230 |
++ of_node_put(platform_node); |
33231 |
++ of_node_put(hdmi_codec); |
33232 |
++ return ret; |
33233 |
+ } |
33234 |
+ |
33235 |
+ #ifdef CONFIG_OF |
33236 |
+diff --git a/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c |
33237 |
+index 6635c3f72eccc..2edb40fe27ccb 100644 |
33238 |
+--- a/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c |
33239 |
++++ b/sound/soc/mediatek/mt8195/mt8195-afe-pcm.c |
33240 |
+@@ -3028,7 +3028,7 @@ static const struct reg_sequence mt8195_afe_reg_defaults[] = { |
33241 |
+ |
33242 |
+ static const struct reg_sequence mt8195_cg_patch[] = { |
33243 |
+ { AUDIO_TOP_CON0, 0xfffffffb }, |
33244 |
+- { AUDIO_TOP_CON1, 0xfffffffa }, |
33245 |
++ { AUDIO_TOP_CON1, 0xfffffff8 }, |
33246 |
+ }; |
33247 |
+ |
33248 |
+ static int mt8195_afe_init_registers(struct mtk_base_afe *afe) |
33249 |
+diff --git a/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c |
33250 |
+index 5d10d2c4c991c..151914c873acd 100644 |
33251 |
+--- a/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c |
33252 |
++++ b/sound/soc/mediatek/mt8195/mt8195-dai-pcm.c |
33253 |
+@@ -80,8 +80,15 @@ static const struct snd_soc_dapm_widget mtk_dai_pcm_widgets[] = { |
33254 |
+ mtk_dai_pcm_o001_mix, |
33255 |
+ ARRAY_SIZE(mtk_dai_pcm_o001_mix)), |
33256 |
+ |
33257 |
++ SND_SOC_DAPM_SUPPLY("PCM_EN", PCM_INTF_CON1, |
33258 |
++ PCM_INTF_CON1_PCM_EN_SHIFT, 0, NULL, 0), |
33259 |
++ |
33260 |
+ SND_SOC_DAPM_INPUT("PCM1_INPUT"), |
33261 |
+ SND_SOC_DAPM_OUTPUT("PCM1_OUTPUT"), |
33262 |
++ |
33263 |
++ SND_SOC_DAPM_CLOCK_SUPPLY("aud_asrc11"), |
33264 |
++ SND_SOC_DAPM_CLOCK_SUPPLY("aud_asrc12"), |
33265 |
++ SND_SOC_DAPM_CLOCK_SUPPLY("aud_pcmif"), |
33266 |
+ }; |
33267 |
+ |
33268 |
+ static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = { |
33269 |
+@@ -97,22 +104,18 @@ static const struct snd_soc_dapm_route mtk_dai_pcm_routes[] = { |
33270 |
+ {"PCM1 Playback", NULL, "O000"}, |
33271 |
+ {"PCM1 Playback", NULL, "O001"}, |
33272 |
+ |
33273 |
++ {"PCM1 Playback", NULL, "PCM_EN"}, |
33274 |
++ {"PCM1 Playback", NULL, "aud_asrc12"}, |
33275 |
++ {"PCM1 Playback", NULL, "aud_pcmif"}, |
33276 |
++ |
33277 |
++ {"PCM1 Capture", NULL, "PCM_EN"}, |
33278 |
++ {"PCM1 Capture", NULL, "aud_asrc11"}, |
33279 |
++ {"PCM1 Capture", NULL, "aud_pcmif"}, |
33280 |
++ |
33281 |
+ {"PCM1_OUTPUT", NULL, "PCM1 Playback"}, |
33282 |
+ {"PCM1 Capture", NULL, "PCM1_INPUT"}, |
33283 |
+ }; |
33284 |
+ |
33285 |
+-static void mtk_dai_pcm_enable(struct mtk_base_afe *afe) |
33286 |
+-{ |
33287 |
+- regmap_update_bits(afe->regmap, PCM_INTF_CON1, |
33288 |
+- PCM_INTF_CON1_PCM_EN, PCM_INTF_CON1_PCM_EN); |
33289 |
+-} |
33290 |
+- |
33291 |
+-static void mtk_dai_pcm_disable(struct mtk_base_afe *afe) |
33292 |
+-{ |
33293 |
+- regmap_update_bits(afe->regmap, PCM_INTF_CON1, |
33294 |
+- PCM_INTF_CON1_PCM_EN, 0x0); |
33295 |
+-} |
33296 |
+- |
33297 |
+ static int mtk_dai_pcm_configure(struct snd_pcm_substream *substream, |
33298 |
+ struct snd_soc_dai *dai) |
33299 |
+ { |
33300 |
+@@ -207,54 +210,22 @@ static int mtk_dai_pcm_configure(struct snd_pcm_substream *substream, |
33301 |
+ } |
33302 |
+ |
33303 |
+ /* dai ops */ |
33304 |
+-static int mtk_dai_pcm_startup(struct snd_pcm_substream *substream, |
33305 |
+- struct snd_soc_dai *dai) |
33306 |
+-{ |
33307 |
+- struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); |
33308 |
+- struct mt8195_afe_private *afe_priv = afe->platform_priv; |
33309 |
+- |
33310 |
+- if (dai->component->active) |
33311 |
+- return 0; |
33312 |
+- |
33313 |
+- mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC11]); |
33314 |
+- mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC12]); |
33315 |
+- mt8195_afe_enable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_PCMIF]); |
33316 |
+- |
33317 |
+- return 0; |
33318 |
+-} |
33319 |
+- |
33320 |
+-static void mtk_dai_pcm_shutdown(struct snd_pcm_substream *substream, |
33321 |
+- struct snd_soc_dai *dai) |
33322 |
+-{ |
33323 |
+- struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); |
33324 |
+- struct mt8195_afe_private *afe_priv = afe->platform_priv; |
33325 |
+- |
33326 |
+- if (dai->component->active) |
33327 |
+- return; |
33328 |
+- |
33329 |
+- mtk_dai_pcm_disable(afe); |
33330 |
+- |
33331 |
+- mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_PCMIF]); |
33332 |
+- mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC12]); |
33333 |
+- mt8195_afe_disable_clk(afe, afe_priv->clk[MT8195_CLK_AUD_ASRC11]); |
33334 |
+-} |
33335 |
+- |
33336 |
+ static int mtk_dai_pcm_prepare(struct snd_pcm_substream *substream, |
33337 |
+ struct snd_soc_dai *dai) |
33338 |
+ { |
33339 |
+- struct mtk_base_afe *afe = snd_soc_dai_get_drvdata(dai); |
33340 |
+- int ret = 0; |
33341 |
++ int ret; |
33342 |
+ |
33343 |
+- if (snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_PLAYBACK) && |
33344 |
+- snd_soc_dai_stream_active(dai, SNDRV_PCM_STREAM_CAPTURE)) |
33345 |
++ dev_dbg(dai->dev, "%s(), id %d, stream %d, widget active p %d, c %d\n", |
33346 |
++ __func__, dai->id, substream->stream, |
33347 |
++ dai->playback_widget->active, dai->capture_widget->active); |
33348 |
++ |
33349 |
++ if (dai->playback_widget->active || dai->capture_widget->active) |
33350 |
+ return 0; |
33351 |
+ |
33352 |
+ ret = mtk_dai_pcm_configure(substream, dai); |
33353 |
+ if (ret) |
33354 |
+ return ret; |
33355 |
+ |
33356 |
+- mtk_dai_pcm_enable(afe); |
33357 |
+- |
33358 |
+ return 0; |
33359 |
+ } |
33360 |
+ |
33361 |
+@@ -316,8 +287,6 @@ static int mtk_dai_pcm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) |
33362 |
+ } |
33363 |
+ |
33364 |
+ static const struct snd_soc_dai_ops mtk_dai_pcm_ops = { |
33365 |
+- .startup = mtk_dai_pcm_startup, |
33366 |
+- .shutdown = mtk_dai_pcm_shutdown, |
33367 |
+ .prepare = mtk_dai_pcm_prepare, |
33368 |
+ .set_fmt = mtk_dai_pcm_set_fmt, |
33369 |
+ }; |
33370 |
+diff --git a/sound/soc/mediatek/mt8195/mt8195-reg.h b/sound/soc/mediatek/mt8195/mt8195-reg.h |
33371 |
+index d06f9cf85a4ec..d3871353db415 100644 |
33372 |
+--- a/sound/soc/mediatek/mt8195/mt8195-reg.h |
33373 |
++++ b/sound/soc/mediatek/mt8195/mt8195-reg.h |
33374 |
+@@ -2550,6 +2550,7 @@ |
33375 |
+ #define PCM_INTF_CON1_PCM_FMT(x) (((x) & 0x3) << 1) |
33376 |
+ #define PCM_INTF_CON1_PCM_FMT_MASK (0x3 << 1) |
33377 |
+ #define PCM_INTF_CON1_PCM_EN BIT(0) |
33378 |
++#define PCM_INTF_CON1_PCM_EN_SHIFT 0 |
33379 |
+ |
33380 |
+ /* PCM_INTF_CON2 */ |
33381 |
+ #define PCM_INTF_CON2_CLK_DOMAIN_SEL(x) (((x) & 0x3) << 23) |
33382 |
+diff --git a/sound/soc/samsung/idma.c b/sound/soc/samsung/idma.c |
33383 |
+index 66bcc2f97544b..c3f1b054e2389 100644 |
33384 |
+--- a/sound/soc/samsung/idma.c |
33385 |
++++ b/sound/soc/samsung/idma.c |
33386 |
+@@ -360,6 +360,8 @@ static int preallocate_idma_buffer(struct snd_pcm *pcm, int stream) |
33387 |
+ buf->addr = idma.lp_tx_addr; |
33388 |
+ buf->bytes = idma_hardware.buffer_bytes_max; |
33389 |
+ buf->area = (unsigned char * __force)ioremap(buf->addr, buf->bytes); |
33390 |
++ if (!buf->area) |
33391 |
++ return -ENOMEM; |
33392 |
+ |
33393 |
+ return 0; |
33394 |
+ } |
33395 |
+diff --git a/sound/soc/uniphier/Kconfig b/sound/soc/uniphier/Kconfig |
33396 |
+index aa3592ee1358b..ddfa6424c656b 100644 |
33397 |
+--- a/sound/soc/uniphier/Kconfig |
33398 |
++++ b/sound/soc/uniphier/Kconfig |
33399 |
+@@ -23,7 +23,6 @@ config SND_SOC_UNIPHIER_LD11 |
33400 |
+ tristate "UniPhier LD11/LD20 Device Driver" |
33401 |
+ depends on SND_SOC_UNIPHIER |
33402 |
+ select SND_SOC_UNIPHIER_AIO |
33403 |
+- select SND_SOC_UNIPHIER_AIO_DMA |
33404 |
+ help |
33405 |
+ This adds ASoC driver for Socionext UniPhier LD11/LD20 |
33406 |
+ input and output that can be used with other codecs. |
33407 |
+@@ -34,7 +33,6 @@ config SND_SOC_UNIPHIER_PXS2 |
33408 |
+ tristate "UniPhier PXs2 Device Driver" |
33409 |
+ depends on SND_SOC_UNIPHIER |
33410 |
+ select SND_SOC_UNIPHIER_AIO |
33411 |
+- select SND_SOC_UNIPHIER_AIO_DMA |
33412 |
+ help |
33413 |
+ This adds ASoC driver for Socionext UniPhier PXs2 |
33414 |
+ input and output that can be used with other codecs. |
33415 |
+diff --git a/sound/usb/format.c b/sound/usb/format.c |
33416 |
+index f5e676a51b30d..405dc0bf6678c 100644 |
33417 |
+--- a/sound/usb/format.c |
33418 |
++++ b/sound/usb/format.c |
33419 |
+@@ -375,7 +375,7 @@ static int parse_uac2_sample_rate_range(struct snd_usb_audio *chip, |
33420 |
+ for (rate = min; rate <= max; rate += res) { |
33421 |
+ |
33422 |
+ /* Filter out invalid rates on Presonus Studio 1810c */ |
33423 |
+- if (chip->usb_id == USB_ID(0x0194f, 0x010c) && |
33424 |
++ if (chip->usb_id == USB_ID(0x194f, 0x010c) && |
33425 |
+ !s1810c_valid_sample_rate(fp, rate)) |
33426 |
+ goto skip_rate; |
33427 |
+ |
33428 |
+diff --git a/sound/usb/mixer_quirks.c b/sound/usb/mixer_quirks.c |
33429 |
+index 823b6b8de942d..d48729e6a3b0a 100644 |
33430 |
+--- a/sound/usb/mixer_quirks.c |
33431 |
++++ b/sound/usb/mixer_quirks.c |
33432 |
+@@ -3254,7 +3254,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) |
33433 |
+ err = snd_rme_controls_create(mixer); |
33434 |
+ break; |
33435 |
+ |
33436 |
+- case USB_ID(0x0194f, 0x010c): /* Presonus Studio 1810c */ |
33437 |
++ case USB_ID(0x194f, 0x010c): /* Presonus Studio 1810c */ |
33438 |
+ err = snd_sc1810_init_mixer(mixer); |
33439 |
+ break; |
33440 |
+ case USB_ID(0x2a39, 0x3fb0): /* RME Babyface Pro FS */ |
33441 |
+diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c |
33442 |
+index 64e1c20311ed4..ab9f3da49941f 100644 |
33443 |
+--- a/sound/usb/quirks.c |
33444 |
++++ b/sound/usb/quirks.c |
33445 |
+@@ -1290,7 +1290,7 @@ int snd_usb_apply_interface_quirk(struct snd_usb_audio *chip, |
33446 |
+ if (chip->usb_id == USB_ID(0x0763, 0x2012)) |
33447 |
+ return fasttrackpro_skip_setting_quirk(chip, iface, altno); |
33448 |
+ /* presonus studio 1810c: skip altsets incompatible with device_setup */ |
33449 |
+- if (chip->usb_id == USB_ID(0x0194f, 0x010c)) |
33450 |
++ if (chip->usb_id == USB_ID(0x194f, 0x010c)) |
33451 |
+ return s1810c_skip_setting_quirk(chip, iface, altno); |
33452 |
+ |
33453 |
+ |
33454 |
+diff --git a/tools/bpf/bpftool/Documentation/Makefile b/tools/bpf/bpftool/Documentation/Makefile |
33455 |
+index c49487905cebe..f89929c7038d5 100644 |
33456 |
+--- a/tools/bpf/bpftool/Documentation/Makefile |
33457 |
++++ b/tools/bpf/bpftool/Documentation/Makefile |
33458 |
+@@ -1,6 +1,5 @@ |
33459 |
+ # SPDX-License-Identifier: GPL-2.0-only |
33460 |
+ include ../../../scripts/Makefile.include |
33461 |
+-include ../../../scripts/utilities.mak |
33462 |
+ |
33463 |
+ INSTALL ?= install |
33464 |
+ RM ?= rm -f |
33465 |
+diff --git a/tools/bpf/bpftool/Documentation/bpftool-btf.rst b/tools/bpf/bpftool/Documentation/bpftool-btf.rst |
33466 |
+index 88b28aa7431f6..4425d942dd39a 100644 |
33467 |
+--- a/tools/bpf/bpftool/Documentation/bpftool-btf.rst |
33468 |
++++ b/tools/bpf/bpftool/Documentation/bpftool-btf.rst |
33469 |
+@@ -13,7 +13,7 @@ SYNOPSIS |
33470 |
+ **bpftool** [*OPTIONS*] **btf** *COMMAND* |
33471 |
+ |
33472 |
+ *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | {**-d** | **--debug** } | |
33473 |
+- { **-B** | **--base-btf** } } |
33474 |
++ { **-B** | **--base-btf** } } |
33475 |
+ |
33476 |
+ *COMMANDS* := { **dump** | **help** } |
33477 |
+ |
33478 |
+diff --git a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst |
33479 |
+index 3e4395eede4f7..13a217a2503d8 100644 |
33480 |
+--- a/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst |
33481 |
++++ b/tools/bpf/bpftool/Documentation/bpftool-cgroup.rst |
33482 |
+@@ -13,7 +13,7 @@ SYNOPSIS |
33483 |
+ **bpftool** [*OPTIONS*] **cgroup** *COMMAND* |
33484 |
+ |
33485 |
+ *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } | |
33486 |
+- { **-f** | **--bpffs** } } |
33487 |
++ { **-f** | **--bpffs** } } |
33488 |
+ |
33489 |
+ *COMMANDS* := |
33490 |
+ { **show** | **list** | **tree** | **attach** | **detach** | **help** } |
33491 |
+diff --git a/tools/bpf/bpftool/Documentation/bpftool-gen.rst b/tools/bpf/bpftool/Documentation/bpftool-gen.rst |
33492 |
+index 2ef2f2df02799..2a137f8a4cea0 100644 |
33493 |
+--- a/tools/bpf/bpftool/Documentation/bpftool-gen.rst |
33494 |
++++ b/tools/bpf/bpftool/Documentation/bpftool-gen.rst |
33495 |
+@@ -13,7 +13,7 @@ SYNOPSIS |
33496 |
+ **bpftool** [*OPTIONS*] **gen** *COMMAND* |
33497 |
+ |
33498 |
+ *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } | |
33499 |
+- { **-L** | **--use-loader** } } |
33500 |
++ { **-L** | **--use-loader** } } |
33501 |
+ |
33502 |
+ *COMMAND* := { **object** | **skeleton** | **help** } |
33503 |
+ |
33504 |
+diff --git a/tools/bpf/bpftool/Documentation/bpftool-link.rst b/tools/bpf/bpftool/Documentation/bpftool-link.rst |
33505 |
+index 0de90f086238c..9434349636a5e 100644 |
33506 |
+--- a/tools/bpf/bpftool/Documentation/bpftool-link.rst |
33507 |
++++ b/tools/bpf/bpftool/Documentation/bpftool-link.rst |
33508 |
+@@ -13,7 +13,7 @@ SYNOPSIS |
33509 |
+ **bpftool** [*OPTIONS*] **link** *COMMAND* |
33510 |
+ |
33511 |
+ *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } | |
33512 |
+- { **-f** | **--bpffs** } | { **-n** | **--nomount** } } |
33513 |
++ { **-f** | **--bpffs** } | { **-n** | **--nomount** } } |
33514 |
+ |
33515 |
+ *COMMANDS* := { **show** | **list** | **pin** | **help** } |
33516 |
+ |
33517 |
+diff --git a/tools/bpf/bpftool/Documentation/bpftool-map.rst b/tools/bpf/bpftool/Documentation/bpftool-map.rst |
33518 |
+index d0c4abe08abab..1445cadc15d4c 100644 |
33519 |
+--- a/tools/bpf/bpftool/Documentation/bpftool-map.rst |
33520 |
++++ b/tools/bpf/bpftool/Documentation/bpftool-map.rst |
33521 |
+@@ -13,11 +13,11 @@ SYNOPSIS |
33522 |
+ **bpftool** [*OPTIONS*] **map** *COMMAND* |
33523 |
+ |
33524 |
+ *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } | |
33525 |
+- { **-f** | **--bpffs** } | { **-n** | **--nomount** } } |
33526 |
++ { **-f** | **--bpffs** } | { **-n** | **--nomount** } } |
33527 |
+ |
33528 |
+ *COMMANDS* := |
33529 |
+- { **show** | **list** | **create** | **dump** | **update** | **lookup** | **getnext** |
33530 |
+- | **delete** | **pin** | **help** } |
33531 |
++ { **show** | **list** | **create** | **dump** | **update** | **lookup** | **getnext** | |
33532 |
++ **delete** | **pin** | **help** } |
33533 |
+ |
33534 |
+ MAP COMMANDS |
33535 |
+ ============= |
33536 |
+diff --git a/tools/bpf/bpftool/Documentation/bpftool-prog.rst b/tools/bpf/bpftool/Documentation/bpftool-prog.rst |
33537 |
+index 91608cb7e44a0..f27265bd589b4 100644 |
33538 |
+--- a/tools/bpf/bpftool/Documentation/bpftool-prog.rst |
33539 |
++++ b/tools/bpf/bpftool/Documentation/bpftool-prog.rst |
33540 |
+@@ -13,12 +13,12 @@ SYNOPSIS |
33541 |
+ **bpftool** [*OPTIONS*] **prog** *COMMAND* |
33542 |
+ |
33543 |
+ *OPTIONS* := { { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } | |
33544 |
+- { **-f** | **--bpffs** } | { **-m** | **--mapcompat** } | { **-n** | **--nomount** } | |
33545 |
+- { **-L** | **--use-loader** } } |
33546 |
++ { **-f** | **--bpffs** } | { **-m** | **--mapcompat** } | { **-n** | **--nomount** } | |
33547 |
++ { **-L** | **--use-loader** } } |
33548 |
+ |
33549 |
+ *COMMANDS* := |
33550 |
+- { **show** | **list** | **dump xlated** | **dump jited** | **pin** | **load** |
33551 |
+- | **loadall** | **help** } |
33552 |
++ { **show** | **list** | **dump xlated** | **dump jited** | **pin** | **load** | |
33553 |
++ **loadall** | **help** } |
33554 |
+ |
33555 |
+ PROG COMMANDS |
33556 |
+ ============= |
33557 |
+diff --git a/tools/bpf/bpftool/Documentation/bpftool.rst b/tools/bpf/bpftool/Documentation/bpftool.rst |
33558 |
+index bb23f55bb05ad..8ac86565c501e 100644 |
33559 |
+--- a/tools/bpf/bpftool/Documentation/bpftool.rst |
33560 |
++++ b/tools/bpf/bpftool/Documentation/bpftool.rst |
33561 |
+@@ -19,14 +19,14 @@ SYNOPSIS |
33562 |
+ *OBJECT* := { **map** | **program** | **cgroup** | **perf** | **net** | **feature** } |
33563 |
+ |
33564 |
+ *OPTIONS* := { { **-V** | **--version** } | |
33565 |
+- { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } } |
33566 |
++ { **-j** | **--json** } [{ **-p** | **--pretty** }] | { **-d** | **--debug** } } |
33567 |
+ |
33568 |
+ *MAP-COMMANDS* := |
33569 |
+ { **show** | **list** | **create** | **dump** | **update** | **lookup** | **getnext** | |
33570 |
+- **delete** | **pin** | **event_pipe** | **help** } |
33571 |
++ **delete** | **pin** | **event_pipe** | **help** } |
33572 |
+ |
33573 |
+ *PROG-COMMANDS* := { **show** | **list** | **dump jited** | **dump xlated** | **pin** | |
33574 |
+- **load** | **attach** | **detach** | **help** } |
33575 |
++ **load** | **attach** | **detach** | **help** } |
33576 |
+ |
33577 |
+ *CGROUP-COMMANDS* := { **show** | **list** | **attach** | **detach** | **help** } |
33578 |
+ |
33579 |
+diff --git a/tools/bpf/bpftool/Makefile b/tools/bpf/bpftool/Makefile |
33580 |
+index d73232be1e991..cce52df3be064 100644 |
33581 |
+--- a/tools/bpf/bpftool/Makefile |
33582 |
++++ b/tools/bpf/bpftool/Makefile |
33583 |
+@@ -1,6 +1,5 @@ |
33584 |
+ # SPDX-License-Identifier: GPL-2.0-only |
33585 |
+ include ../../scripts/Makefile.include |
33586 |
+-include ../../scripts/utilities.mak |
33587 |
+ |
33588 |
+ ifeq ($(srctree),) |
33589 |
+ srctree := $(patsubst %/,%,$(dir $(CURDIR))) |
33590 |
+diff --git a/tools/bpf/bpftool/main.c b/tools/bpf/bpftool/main.c |
33591 |
+index 02eaaf065f651..d27ec4f852bbb 100644 |
33592 |
+--- a/tools/bpf/bpftool/main.c |
33593 |
++++ b/tools/bpf/bpftool/main.c |
33594 |
+@@ -402,6 +402,8 @@ int main(int argc, char **argv) |
33595 |
+ }; |
33596 |
+ int opt, ret; |
33597 |
+ |
33598 |
++ setlinebuf(stdout); |
33599 |
++ |
33600 |
+ last_do_help = do_help; |
33601 |
+ pretty_output = false; |
33602 |
+ json_output = false; |
33603 |
+diff --git a/tools/bpf/bpftool/prog.c b/tools/bpf/bpftool/prog.c |
33604 |
+index fe59404e87046..f8755beb3d9eb 100644 |
33605 |
+--- a/tools/bpf/bpftool/prog.c |
33606 |
++++ b/tools/bpf/bpftool/prog.c |
33607 |
+@@ -629,8 +629,8 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode, |
33608 |
+ char func_sig[1024]; |
33609 |
+ unsigned char *buf; |
33610 |
+ __u32 member_len; |
33611 |
++ int fd, err = -1; |
33612 |
+ ssize_t n; |
33613 |
+- int fd; |
33614 |
+ |
33615 |
+ if (mode == DUMP_JITED) { |
33616 |
+ if (info->jited_prog_len == 0 || !info->jited_prog_insns) { |
33617 |
+@@ -669,7 +669,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode, |
33618 |
+ if (fd < 0) { |
33619 |
+ p_err("can't open file %s: %s", filepath, |
33620 |
+ strerror(errno)); |
33621 |
+- return -1; |
33622 |
++ goto exit_free; |
33623 |
+ } |
33624 |
+ |
33625 |
+ n = write(fd, buf, member_len); |
33626 |
+@@ -677,7 +677,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode, |
33627 |
+ if (n != (ssize_t)member_len) { |
33628 |
+ p_err("error writing output file: %s", |
33629 |
+ n < 0 ? strerror(errno) : "short write"); |
33630 |
+- return -1; |
33631 |
++ goto exit_free; |
33632 |
+ } |
33633 |
+ |
33634 |
+ if (json_output) |
33635 |
+@@ -691,7 +691,7 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode, |
33636 |
+ info->netns_ino, |
33637 |
+ &disasm_opt); |
33638 |
+ if (!name) |
33639 |
+- return -1; |
33640 |
++ goto exit_free; |
33641 |
+ } |
33642 |
+ |
33643 |
+ if (info->nr_jited_func_lens && info->jited_func_lens) { |
33644 |
+@@ -786,9 +786,12 @@ prog_dump(struct bpf_prog_info *info, enum dump_mode mode, |
33645 |
+ kernel_syms_destroy(&dd); |
33646 |
+ } |
33647 |
+ |
33648 |
+- btf__free(btf); |
33649 |
++ err = 0; |
33650 |
+ |
33651 |
+- return 0; |
33652 |
++exit_free: |
33653 |
++ btf__free(btf); |
33654 |
++ bpf_prog_linfo__free(prog_linfo); |
33655 |
++ return err; |
33656 |
+ } |
33657 |
+ |
33658 |
+ static int do_dump(int argc, char **argv) |
33659 |
+diff --git a/tools/include/nolibc/nolibc.h b/tools/include/nolibc/nolibc.h |
33660 |
+index 3430667b0d241..3e2c6f2ed587f 100644 |
33661 |
+--- a/tools/include/nolibc/nolibc.h |
33662 |
++++ b/tools/include/nolibc/nolibc.h |
33663 |
+@@ -399,16 +399,22 @@ struct stat { |
33664 |
+ }) |
33665 |
+ |
33666 |
+ /* startup code */ |
33667 |
++/* |
33668 |
++ * x86-64 System V ABI mandates: |
33669 |
++ * 1) %rsp must be 16-byte aligned right before the function call. |
33670 |
++ * 2) The deepest stack frame should be zero (the %rbp). |
33671 |
++ * |
33672 |
++ */ |
33673 |
+ asm(".section .text\n" |
33674 |
+ ".global _start\n" |
33675 |
+ "_start:\n" |
33676 |
+ "pop %rdi\n" // argc (first arg, %rdi) |
33677 |
+ "mov %rsp, %rsi\n" // argv[] (second arg, %rsi) |
33678 |
+ "lea 8(%rsi,%rdi,8),%rdx\n" // then a NULL then envp (third arg, %rdx) |
33679 |
+- "and $-16, %rsp\n" // x86 ABI : esp must be 16-byte aligned when |
33680 |
+- "sub $8, %rsp\n" // entering the callee |
33681 |
++ "xor %ebp, %ebp\n" // zero the stack frame |
33682 |
++ "and $-16, %rsp\n" // x86 ABI : esp must be 16-byte aligned before call |
33683 |
+ "call main\n" // main() returns the status code, we'll exit with it. |
33684 |
+- "movzb %al, %rdi\n" // retrieve exit code from 8 lower bits |
33685 |
++ "mov %eax, %edi\n" // retrieve exit code (32 bit) |
33686 |
+ "mov $60, %rax\n" // NR_exit == 60 |
33687 |
+ "syscall\n" // really exit |
33688 |
+ "hlt\n" // ensure it does not return |
33689 |
+@@ -577,20 +583,28 @@ struct sys_stat_struct { |
33690 |
+ }) |
33691 |
+ |
33692 |
+ /* startup code */ |
33693 |
++/* |
33694 |
++ * i386 System V ABI mandates: |
33695 |
++ * 1) last pushed argument must be 16-byte aligned. |
33696 |
++ * 2) The deepest stack frame should be set to zero |
33697 |
++ * |
33698 |
++ */ |
33699 |
+ asm(".section .text\n" |
33700 |
+ ".global _start\n" |
33701 |
+ "_start:\n" |
33702 |
+ "pop %eax\n" // argc (first arg, %eax) |
33703 |
+ "mov %esp, %ebx\n" // argv[] (second arg, %ebx) |
33704 |
+ "lea 4(%ebx,%eax,4),%ecx\n" // then a NULL then envp (third arg, %ecx) |
33705 |
+- "and $-16, %esp\n" // x86 ABI : esp must be 16-byte aligned when |
33706 |
++ "xor %ebp, %ebp\n" // zero the stack frame |
33707 |
++ "and $-16, %esp\n" // x86 ABI : esp must be 16-byte aligned before |
33708 |
++ "sub $4, %esp\n" // the call instruction (args are aligned) |
33709 |
+ "push %ecx\n" // push all registers on the stack so that we |
33710 |
+ "push %ebx\n" // support both regparm and plain stack modes |
33711 |
+ "push %eax\n" |
33712 |
+ "call main\n" // main() returns the status code in %eax |
33713 |
+- "movzbl %al, %ebx\n" // retrieve exit code from lower 8 bits |
33714 |
+- "movl $1, %eax\n" // NR_exit == 1 |
33715 |
+- "int $0x80\n" // exit now |
33716 |
++ "mov %eax, %ebx\n" // retrieve exit code (32-bit int) |
33717 |
++ "movl $1, %eax\n" // NR_exit == 1 |
33718 |
++ "int $0x80\n" // exit now |
33719 |
+ "hlt\n" // ensure it does not |
33720 |
+ ""); |
33721 |
+ |
33722 |
+@@ -774,7 +788,6 @@ asm(".section .text\n" |
33723 |
+ "and %r3, %r1, $-8\n" // AAPCS : sp must be 8-byte aligned in the |
33724 |
+ "mov %sp, %r3\n" // callee, an bl doesn't push (lr=pc) |
33725 |
+ "bl main\n" // main() returns the status code, we'll exit with it. |
33726 |
+- "and %r0, %r0, $0xff\n" // limit exit code to 8 bits |
33727 |
+ "movs r7, $1\n" // NR_exit == 1 |
33728 |
+ "svc $0x00\n" |
33729 |
+ ""); |
33730 |
+@@ -971,7 +984,6 @@ asm(".section .text\n" |
33731 |
+ "add x2, x2, x1\n" // + argv |
33732 |
+ "and sp, x1, -16\n" // sp must be 16-byte aligned in the callee |
33733 |
+ "bl main\n" // main() returns the status code, we'll exit with it. |
33734 |
+- "and x0, x0, 0xff\n" // limit exit code to 8 bits |
33735 |
+ "mov x8, 93\n" // NR_exit == 93 |
33736 |
+ "svc #0\n" |
33737 |
+ ""); |
33738 |
+@@ -1176,7 +1188,7 @@ asm(".section .text\n" |
33739 |
+ "addiu $sp,$sp,-16\n" // the callee expects to save a0..a3 there! |
33740 |
+ "jal main\n" // main() returns the status code, we'll exit with it. |
33741 |
+ "nop\n" // delayed slot |
33742 |
+- "and $a0, $v0, 0xff\n" // limit exit code to 8 bits |
33743 |
++ "move $a0, $v0\n" // retrieve 32-bit exit code from v0 |
33744 |
+ "li $v0, 4001\n" // NR_exit == 4001 |
33745 |
+ "syscall\n" |
33746 |
+ ".end __start\n" |
33747 |
+@@ -1374,7 +1386,6 @@ asm(".section .text\n" |
33748 |
+ "add a2,a2,a1\n" // + argv |
33749 |
+ "andi sp,a1,-16\n" // sp must be 16-byte aligned |
33750 |
+ "call main\n" // main() returns the status code, we'll exit with it. |
33751 |
+- "andi a0, a0, 0xff\n" // limit exit code to 8 bits |
33752 |
+ "li a7, 93\n" // NR_exit == 93 |
33753 |
+ "ecall\n" |
33754 |
+ ""); |
33755 |
+diff --git a/tools/lib/bpf/btf.c b/tools/lib/bpf/btf.c |
33756 |
+index 1b9341ef638b0..5f3d20ae66d56 100644 |
33757 |
+--- a/tools/lib/bpf/btf.c |
33758 |
++++ b/tools/lib/bpf/btf.c |
33759 |
+@@ -2626,15 +2626,11 @@ void btf_ext__free(struct btf_ext *btf_ext) |
33760 |
+ free(btf_ext); |
33761 |
+ } |
33762 |
+ |
33763 |
+-struct btf_ext *btf_ext__new(__u8 *data, __u32 size) |
33764 |
++struct btf_ext *btf_ext__new(const __u8 *data, __u32 size) |
33765 |
+ { |
33766 |
+ struct btf_ext *btf_ext; |
33767 |
+ int err; |
33768 |
+ |
33769 |
+- err = btf_ext_parse_hdr(data, size); |
33770 |
+- if (err) |
33771 |
+- return libbpf_err_ptr(err); |
33772 |
+- |
33773 |
+ btf_ext = calloc(1, sizeof(struct btf_ext)); |
33774 |
+ if (!btf_ext) |
33775 |
+ return libbpf_err_ptr(-ENOMEM); |
33776 |
+@@ -2647,6 +2643,10 @@ struct btf_ext *btf_ext__new(__u8 *data, __u32 size) |
33777 |
+ } |
33778 |
+ memcpy(btf_ext->data, data, size); |
33779 |
+ |
33780 |
++ err = btf_ext_parse_hdr(btf_ext->data, size); |
33781 |
++ if (err) |
33782 |
++ goto done; |
33783 |
++ |
33784 |
+ if (btf_ext->hdr->hdr_len < offsetofend(struct btf_ext_header, line_info_len)) { |
33785 |
+ err = -EINVAL; |
33786 |
+ goto done; |
33787 |
+@@ -3358,8 +3358,8 @@ static long btf_hash_struct(struct btf_type *t) |
33788 |
+ } |
33789 |
+ |
33790 |
+ /* |
33791 |
+- * Check structural compatibility of two FUNC_PROTOs, ignoring referenced type |
33792 |
+- * IDs. This check is performed during type graph equivalence check and |
33793 |
++ * Check structural compatibility of two STRUCTs/UNIONs, ignoring referenced |
33794 |
++ * type IDs. This check is performed during type graph equivalence check and |
33795 |
+ * referenced types equivalence is checked separately. |
33796 |
+ */ |
33797 |
+ static bool btf_shallow_equal_struct(struct btf_type *t1, struct btf_type *t2) |
33798 |
+@@ -3730,6 +3730,31 @@ static int btf_dedup_identical_arrays(struct btf_dedup *d, __u32 id1, __u32 id2) |
33799 |
+ return btf_equal_array(t1, t2); |
33800 |
+ } |
33801 |
+ |
33802 |
++/* Check if given two types are identical STRUCT/UNION definitions */ |
33803 |
++static bool btf_dedup_identical_structs(struct btf_dedup *d, __u32 id1, __u32 id2) |
33804 |
++{ |
33805 |
++ const struct btf_member *m1, *m2; |
33806 |
++ struct btf_type *t1, *t2; |
33807 |
++ int n, i; |
33808 |
++ |
33809 |
++ t1 = btf_type_by_id(d->btf, id1); |
33810 |
++ t2 = btf_type_by_id(d->btf, id2); |
33811 |
++ |
33812 |
++ if (!btf_is_composite(t1) || btf_kind(t1) != btf_kind(t2)) |
33813 |
++ return false; |
33814 |
++ |
33815 |
++ if (!btf_shallow_equal_struct(t1, t2)) |
33816 |
++ return false; |
33817 |
++ |
33818 |
++ m1 = btf_members(t1); |
33819 |
++ m2 = btf_members(t2); |
33820 |
++ for (i = 0, n = btf_vlen(t1); i < n; i++, m1++, m2++) { |
33821 |
++ if (m1->type != m2->type) |
33822 |
++ return false; |
33823 |
++ } |
33824 |
++ return true; |
33825 |
++} |
33826 |
++ |
33827 |
+ /* |
33828 |
+ * Check equivalence of BTF type graph formed by candidate struct/union (we'll |
33829 |
+ * call it "candidate graph" in this description for brevity) to a type graph |
33830 |
+@@ -3841,6 +3866,8 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id, |
33831 |
+ |
33832 |
+ hypot_type_id = d->hypot_map[canon_id]; |
33833 |
+ if (hypot_type_id <= BTF_MAX_NR_TYPES) { |
33834 |
++ if (hypot_type_id == cand_id) |
33835 |
++ return 1; |
33836 |
+ /* In some cases compiler will generate different DWARF types |
33837 |
+ * for *identical* array type definitions and use them for |
33838 |
+ * different fields within the *same* struct. This breaks type |
33839 |
+@@ -3849,8 +3876,18 @@ static int btf_dedup_is_equiv(struct btf_dedup *d, __u32 cand_id, |
33840 |
+ * types within a single CU. So work around that by explicitly |
33841 |
+ * allowing identical array types here. |
33842 |
+ */ |
33843 |
+- return hypot_type_id == cand_id || |
33844 |
+- btf_dedup_identical_arrays(d, hypot_type_id, cand_id); |
33845 |
++ if (btf_dedup_identical_arrays(d, hypot_type_id, cand_id)) |
33846 |
++ return 1; |
33847 |
++ /* It turns out that similar situation can happen with |
33848 |
++ * struct/union sometimes, sigh... Handle the case where |
33849 |
++ * structs/unions are exactly the same, down to the referenced |
33850 |
++ * type IDs. Anything more complicated (e.g., if referenced |
33851 |
++ * types are different, but equivalent) is *way more* |
33852 |
++ * complicated and requires a many-to-many equivalence mapping. |
33853 |
++ */ |
33854 |
++ if (btf_dedup_identical_structs(d, hypot_type_id, cand_id)) |
33855 |
++ return 1; |
33856 |
++ return 0; |
33857 |
+ } |
33858 |
+ |
33859 |
+ if (btf_dedup_hypot_map_add(d, canon_id, cand_id)) |
33860 |
+diff --git a/tools/lib/bpf/btf.h b/tools/lib/bpf/btf.h |
33861 |
+index 4a711f990904b..b0ee338a0cc87 100644 |
33862 |
+--- a/tools/lib/bpf/btf.h |
33863 |
++++ b/tools/lib/bpf/btf.h |
33864 |
+@@ -80,7 +80,7 @@ LIBBPF_API int btf__get_map_kv_tids(const struct btf *btf, const char *map_name, |
33865 |
+ __u32 expected_value_size, |
33866 |
+ __u32 *key_type_id, __u32 *value_type_id); |
33867 |
+ |
33868 |
+-LIBBPF_API struct btf_ext *btf_ext__new(__u8 *data, __u32 size); |
33869 |
++LIBBPF_API struct btf_ext *btf_ext__new(const __u8 *data, __u32 size); |
33870 |
+ LIBBPF_API void btf_ext__free(struct btf_ext *btf_ext); |
33871 |
+ LIBBPF_API const void *btf_ext__get_raw_data(const struct btf_ext *btf_ext, |
33872 |
+ __u32 *size); |
33873 |
+diff --git a/tools/lib/bpf/btf_dump.c b/tools/lib/bpf/btf_dump.c |
33874 |
+index e4b483f15fb99..8c9325802793b 100644 |
33875 |
+--- a/tools/lib/bpf/btf_dump.c |
33876 |
++++ b/tools/lib/bpf/btf_dump.c |
33877 |
+@@ -2186,7 +2186,7 @@ static int btf_dump_dump_type_data(struct btf_dump *d, |
33878 |
+ __u8 bits_offset, |
33879 |
+ __u8 bit_sz) |
33880 |
+ { |
33881 |
+- int size, err; |
33882 |
++ int size, err = 0; |
33883 |
+ |
33884 |
+ size = btf_dump_type_data_check_overflow(d, t, id, data, bits_offset); |
33885 |
+ if (size < 0) |
33886 |
+diff --git a/tools/lib/bpf/gen_loader.c b/tools/lib/bpf/gen_loader.c |
33887 |
+index 8df718a6b142d..33c19590ee434 100644 |
33888 |
+--- a/tools/lib/bpf/gen_loader.c |
33889 |
++++ b/tools/lib/bpf/gen_loader.c |
33890 |
+@@ -663,9 +663,11 @@ void bpf_gen__prog_load(struct bpf_gen *gen, |
33891 |
+ debug_ret(gen, "prog_load %s insn_cnt %d", attr.prog_name, attr.insn_cnt); |
33892 |
+ /* successful or not, close btf module FDs used in extern ksyms and attach_btf_obj_fd */ |
33893 |
+ cleanup_relos(gen, insns); |
33894 |
+- if (gen->attach_kind) |
33895 |
++ if (gen->attach_kind) { |
33896 |
+ emit_sys_close_blob(gen, |
33897 |
+ attr_field(prog_load_attr, attach_btf_obj_fd)); |
33898 |
++ gen->attach_kind = 0; |
33899 |
++ } |
33900 |
+ emit_check_err(gen); |
33901 |
+ /* remember prog_fd in the stack, if successful */ |
33902 |
+ emit(gen, BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_7, |
33903 |
+diff --git a/tools/lib/bpf/libbpf.c b/tools/lib/bpf/libbpf.c |
33904 |
+index 7145463a4a562..0ad29203cbfbf 100644 |
33905 |
+--- a/tools/lib/bpf/libbpf.c |
33906 |
++++ b/tools/lib/bpf/libbpf.c |
33907 |
+@@ -8676,7 +8676,10 @@ int bpf_map__set_inner_map_fd(struct bpf_map *map, int fd) |
33908 |
+ pr_warn("error: inner_map_fd already specified\n"); |
33909 |
+ return libbpf_err(-EINVAL); |
33910 |
+ } |
33911 |
+- zfree(&map->inner_map); |
33912 |
++ if (map->inner_map) { |
33913 |
++ bpf_map__destroy(map->inner_map); |
33914 |
++ zfree(&map->inner_map); |
33915 |
++ } |
33916 |
+ map->inner_map_fd = fd; |
33917 |
+ return 0; |
33918 |
+ } |
33919 |
+diff --git a/tools/lib/bpf/linker.c b/tools/lib/bpf/linker.c |
33920 |
+index 2df880cefdaee..6b2f59ddb6918 100644 |
33921 |
+--- a/tools/lib/bpf/linker.c |
33922 |
++++ b/tools/lib/bpf/linker.c |
33923 |
+@@ -211,6 +211,7 @@ void bpf_linker__free(struct bpf_linker *linker) |
33924 |
+ } |
33925 |
+ free(linker->secs); |
33926 |
+ |
33927 |
++ free(linker->glob_syms); |
33928 |
+ free(linker); |
33929 |
+ } |
33930 |
+ |
33931 |
+@@ -2000,7 +2001,7 @@ add_sym: |
33932 |
+ static int linker_append_elf_relos(struct bpf_linker *linker, struct src_obj *obj) |
33933 |
+ { |
33934 |
+ struct src_sec *src_symtab = &obj->secs[obj->symtab_sec_idx]; |
33935 |
+- struct dst_sec *dst_symtab = &linker->secs[linker->symtab_sec_idx]; |
33936 |
++ struct dst_sec *dst_symtab; |
33937 |
+ int i, err; |
33938 |
+ |
33939 |
+ for (i = 1; i < obj->sec_cnt; i++) { |
33940 |
+@@ -2033,6 +2034,9 @@ static int linker_append_elf_relos(struct bpf_linker *linker, struct src_obj *ob |
33941 |
+ return -1; |
33942 |
+ } |
33943 |
+ |
33944 |
++ /* add_dst_sec() above could have invalidated linker->secs */ |
33945 |
++ dst_symtab = &linker->secs[linker->symtab_sec_idx]; |
33946 |
++ |
33947 |
+ /* shdr->sh_link points to SYMTAB */ |
33948 |
+ dst_sec->shdr->sh_link = linker->symtab_sec_idx; |
33949 |
+ |
33950 |
+diff --git a/tools/perf/Makefile.config b/tools/perf/Makefile.config |
33951 |
+index 3c077f61d676d..71772b20ea737 100644 |
33952 |
+--- a/tools/perf/Makefile.config |
33953 |
++++ b/tools/perf/Makefile.config |
33954 |
+@@ -143,7 +143,10 @@ FEATURE_CHECK_LDFLAGS-libcrypto = -lcrypto |
33955 |
+ ifdef CSINCLUDES |
33956 |
+ LIBOPENCSD_CFLAGS := -I$(CSINCLUDES) |
33957 |
+ endif |
33958 |
+-OPENCSDLIBS := -lopencsd_c_api -lopencsd -lstdc++ |
33959 |
++OPENCSDLIBS := -lopencsd_c_api |
33960 |
++ifeq ($(findstring -static,${LDFLAGS}),-static) |
33961 |
++ OPENCSDLIBS += -lopencsd -lstdc++ |
33962 |
++endif |
33963 |
+ ifdef CSLIBS |
33964 |
+ LIBOPENCSD_LDFLAGS := -L$(CSLIBS) |
33965 |
+ endif |
33966 |
+diff --git a/tools/perf/util/debug.c b/tools/perf/util/debug.c |
33967 |
+index 2c06abf6dcd26..65e6c22f38e4f 100644 |
33968 |
+--- a/tools/perf/util/debug.c |
33969 |
++++ b/tools/perf/util/debug.c |
33970 |
+@@ -179,7 +179,7 @@ static int trace_event_printer(enum binary_printer_ops op, |
33971 |
+ break; |
33972 |
+ case BINARY_PRINT_CHAR_DATA: |
33973 |
+ printed += color_fprintf(fp, color, "%c", |
33974 |
+- isprint(ch) ? ch : '.'); |
33975 |
++ isprint(ch) && isascii(ch) ? ch : '.'); |
33976 |
+ break; |
33977 |
+ case BINARY_PRINT_CHAR_PAD: |
33978 |
+ printed += color_fprintf(fp, color, " "); |
33979 |
+diff --git a/tools/perf/util/evsel.c b/tools/perf/util/evsel.c |
33980 |
+index dbfeceb2546c6..c87f9974c0c10 100644 |
33981 |
+--- a/tools/perf/util/evsel.c |
33982 |
++++ b/tools/perf/util/evsel.c |
33983 |
+@@ -1047,6 +1047,17 @@ void __weak arch_evsel__set_sample_weight(struct evsel *evsel) |
33984 |
+ evsel__set_sample_bit(evsel, WEIGHT); |
33985 |
+ } |
33986 |
+ |
33987 |
++static void evsel__set_default_freq_period(struct record_opts *opts, |
33988 |
++ struct perf_event_attr *attr) |
33989 |
++{ |
33990 |
++ if (opts->freq) { |
33991 |
++ attr->freq = 1; |
33992 |
++ attr->sample_freq = opts->freq; |
33993 |
++ } else { |
33994 |
++ attr->sample_period = opts->default_interval; |
33995 |
++ } |
33996 |
++} |
33997 |
++ |
33998 |
+ /* |
33999 |
+ * The enable_on_exec/disabled value strategy: |
34000 |
+ * |
34001 |
+@@ -1113,14 +1124,12 @@ void evsel__config(struct evsel *evsel, struct record_opts *opts, |
34002 |
+ * We default some events to have a default interval. But keep |
34003 |
+ * it a weak assumption overridable by the user. |
34004 |
+ */ |
34005 |
+- if (!attr->sample_period) { |
34006 |
+- if (opts->freq) { |
34007 |
+- attr->freq = 1; |
34008 |
+- attr->sample_freq = opts->freq; |
34009 |
+- } else { |
34010 |
+- attr->sample_period = opts->default_interval; |
34011 |
+- } |
34012 |
+- } |
34013 |
++ if ((evsel->is_libpfm_event && !attr->sample_period) || |
34014 |
++ (!evsel->is_libpfm_event && (!attr->sample_period || |
34015 |
++ opts->user_freq != UINT_MAX || |
34016 |
++ opts->user_interval != ULLONG_MAX))) |
34017 |
++ evsel__set_default_freq_period(opts, attr); |
34018 |
++ |
34019 |
+ /* |
34020 |
+ * If attr->freq was set (here or earlier), ask for period |
34021 |
+ * to be sampled. |
34022 |
+diff --git a/tools/perf/util/probe-event.c b/tools/perf/util/probe-event.c |
34023 |
+index b2a02c9ab8ea9..a834918a0a0d3 100644 |
34024 |
+--- a/tools/perf/util/probe-event.c |
34025 |
++++ b/tools/perf/util/probe-event.c |
34026 |
+@@ -3083,6 +3083,9 @@ static int find_probe_trace_events_from_map(struct perf_probe_event *pev, |
34027 |
+ for (j = 0; j < num_matched_functions; j++) { |
34028 |
+ sym = syms[j]; |
34029 |
+ |
34030 |
++ if (sym->type != STT_FUNC) |
34031 |
++ continue; |
34032 |
++ |
34033 |
+ /* There can be duplicated symbols in the map */ |
34034 |
+ for (i = 0; i < j; i++) |
34035 |
+ if (sym->start == syms[i]->start) { |
34036 |
+diff --git a/tools/testing/selftests/bpf/btf_helpers.c b/tools/testing/selftests/bpf/btf_helpers.c |
34037 |
+index b692e6ead9b55..0a4ad7cb2c200 100644 |
34038 |
+--- a/tools/testing/selftests/bpf/btf_helpers.c |
34039 |
++++ b/tools/testing/selftests/bpf/btf_helpers.c |
34040 |
+@@ -246,18 +246,23 @@ const char *btf_type_c_dump(const struct btf *btf) |
34041 |
+ d = btf_dump__new(btf, NULL, &opts, btf_dump_printf); |
34042 |
+ if (libbpf_get_error(d)) { |
34043 |
+ fprintf(stderr, "Failed to create btf_dump instance: %ld\n", libbpf_get_error(d)); |
34044 |
+- return NULL; |
34045 |
++ goto err_out; |
34046 |
+ } |
34047 |
+ |
34048 |
+ for (i = 1; i <= btf__get_nr_types(btf); i++) { |
34049 |
+ err = btf_dump__dump_type(d, i); |
34050 |
+ if (err) { |
34051 |
+ fprintf(stderr, "Failed to dump type [%d]: %d\n", i, err); |
34052 |
+- return NULL; |
34053 |
++ goto err_out; |
34054 |
+ } |
34055 |
+ } |
34056 |
+ |
34057 |
++ btf_dump__free(d); |
34058 |
+ fflush(buf_file); |
34059 |
+ fclose(buf_file); |
34060 |
+ return buf; |
34061 |
++err_out: |
34062 |
++ btf_dump__free(d); |
34063 |
++ fclose(buf_file); |
34064 |
++ return NULL; |
34065 |
+ } |
34066 |
+diff --git a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c |
34067 |
+index 77ac24b191d4c..dc18e5ae0febc 100644 |
34068 |
+--- a/tools/testing/selftests/bpf/prog_tests/bpf_iter.c |
34069 |
++++ b/tools/testing/selftests/bpf/prog_tests/bpf_iter.c |
34070 |
+@@ -1208,13 +1208,14 @@ static void test_task_vma(void) |
34071 |
+ goto out; |
34072 |
+ |
34073 |
+ /* Read CMP_BUFFER_SIZE (1kB) from bpf_iter. Read in small chunks |
34074 |
+- * to trigger seq_file corner cases. The expected output is much |
34075 |
+- * longer than 1kB, so the while loop will terminate. |
34076 |
++ * to trigger seq_file corner cases. |
34077 |
+ */ |
34078 |
+ len = 0; |
34079 |
+ while (len < CMP_BUFFER_SIZE) { |
34080 |
+ err = read_fd_into_buffer(iter_fd, task_vma_output + len, |
34081 |
+ min(read_size, CMP_BUFFER_SIZE - len)); |
34082 |
++ if (!err) |
34083 |
++ break; |
34084 |
+ if (CHECK(err < 0, "read_iter_fd", "read_iter_fd failed\n")) |
34085 |
+ goto out; |
34086 |
+ len += err; |
34087 |
+diff --git a/tools/testing/selftests/bpf/prog_tests/migrate_reuseport.c b/tools/testing/selftests/bpf/prog_tests/migrate_reuseport.c |
34088 |
+index 59adb4715394f..3c85247f96f95 100644 |
34089 |
+--- a/tools/testing/selftests/bpf/prog_tests/migrate_reuseport.c |
34090 |
++++ b/tools/testing/selftests/bpf/prog_tests/migrate_reuseport.c |
34091 |
+@@ -204,8 +204,8 @@ static int pass_ack(struct migrate_reuseport_test_case *test_case) |
34092 |
+ { |
34093 |
+ int err; |
34094 |
+ |
34095 |
+- err = bpf_link__detach(test_case->link); |
34096 |
+- if (!ASSERT_OK(err, "bpf_link__detach")) |
34097 |
++ err = bpf_link__destroy(test_case->link); |
34098 |
++ if (!ASSERT_OK(err, "bpf_link__destroy")) |
34099 |
+ return -1; |
34100 |
+ |
34101 |
+ test_case->link = NULL; |
34102 |
+diff --git a/tools/testing/selftests/bpf/prog_tests/skb_ctx.c b/tools/testing/selftests/bpf/prog_tests/skb_ctx.c |
34103 |
+index fafeddaad6a99..23915be6172d6 100644 |
34104 |
+--- a/tools/testing/selftests/bpf/prog_tests/skb_ctx.c |
34105 |
++++ b/tools/testing/selftests/bpf/prog_tests/skb_ctx.c |
34106 |
+@@ -105,4 +105,6 @@ void test_skb_ctx(void) |
34107 |
+ "ctx_out_mark", |
34108 |
+ "skb->mark == %u, expected %d\n", |
34109 |
+ skb.mark, 10); |
34110 |
++ |
34111 |
++ bpf_object__close(obj); |
34112 |
+ } |
34113 |
+diff --git a/tools/testing/selftests/bpf/prog_tests/tc_redirect.c b/tools/testing/selftests/bpf/prog_tests/tc_redirect.c |
34114 |
+index e7201ba29ccd6..47e3159729d21 100644 |
34115 |
+--- a/tools/testing/selftests/bpf/prog_tests/tc_redirect.c |
34116 |
++++ b/tools/testing/selftests/bpf/prog_tests/tc_redirect.c |
34117 |
+@@ -105,6 +105,13 @@ static int setns_by_fd(int nsfd) |
34118 |
+ if (!ASSERT_OK(err, "unshare")) |
34119 |
+ return err; |
34120 |
+ |
34121 |
++ /* Make our /sys mount private, so the following umount won't |
34122 |
++ * trigger the global umount in case it's shared. |
34123 |
++ */ |
34124 |
++ err = mount("none", "/sys", NULL, MS_PRIVATE, NULL); |
34125 |
++ if (!ASSERT_OK(err, "remount private /sys")) |
34126 |
++ return err; |
34127 |
++ |
34128 |
+ err = umount2("/sys", MNT_DETACH); |
34129 |
+ if (!ASSERT_OK(err, "umount2 /sys")) |
34130 |
+ return err; |
34131 |
+diff --git a/tools/testing/selftests/clone3/clone3.c b/tools/testing/selftests/clone3/clone3.c |
34132 |
+index 42be3b9258301..076cf4325f783 100644 |
34133 |
+--- a/tools/testing/selftests/clone3/clone3.c |
34134 |
++++ b/tools/testing/selftests/clone3/clone3.c |
34135 |
+@@ -52,6 +52,12 @@ static int call_clone3(uint64_t flags, size_t size, enum test_mode test_mode) |
34136 |
+ size = sizeof(struct __clone_args); |
34137 |
+ |
34138 |
+ switch (test_mode) { |
34139 |
++ case CLONE3_ARGS_NO_TEST: |
34140 |
++ /* |
34141 |
++ * Uses default 'flags' and 'SIGCHLD' |
34142 |
++ * assignment. |
34143 |
++ */ |
34144 |
++ break; |
34145 |
+ case CLONE3_ARGS_ALL_0: |
34146 |
+ args.flags = 0; |
34147 |
+ args.exit_signal = 0; |
34148 |
+diff --git a/tools/testing/selftests/ftrace/test.d/kprobe/profile.tc b/tools/testing/selftests/ftrace/test.d/kprobe/profile.tc |
34149 |
+index 98166fa3eb91c..34fb89b0c61fa 100644 |
34150 |
+--- a/tools/testing/selftests/ftrace/test.d/kprobe/profile.tc |
34151 |
++++ b/tools/testing/selftests/ftrace/test.d/kprobe/profile.tc |
34152 |
+@@ -1,6 +1,6 @@ |
34153 |
+ #!/bin/sh |
34154 |
+ # SPDX-License-Identifier: GPL-2.0 |
34155 |
+-# description: Kprobe dynamic event - adding and removing |
34156 |
++# description: Kprobe profile |
34157 |
+ # requires: kprobe_events |
34158 |
+ |
34159 |
+ ! grep -q 'myevent' kprobe_profile |
34160 |
+diff --git a/tools/testing/selftests/kselftest_harness.h b/tools/testing/selftests/kselftest_harness.h |
34161 |
+index ae0f0f33b2a6e..79a182cfa43ad 100644 |
34162 |
+--- a/tools/testing/selftests/kselftest_harness.h |
34163 |
++++ b/tools/testing/selftests/kselftest_harness.h |
34164 |
+@@ -969,7 +969,7 @@ void __run_test(struct __fixture_metadata *f, |
34165 |
+ t->passed = 1; |
34166 |
+ t->skip = 0; |
34167 |
+ t->trigger = 0; |
34168 |
+- t->step = 0; |
34169 |
++ t->step = 1; |
34170 |
+ t->no_print = 0; |
34171 |
+ memset(t->results->reason, 0, sizeof(t->results->reason)); |
34172 |
+ |
34173 |
+diff --git a/tools/testing/selftests/powerpc/security/spectre_v2.c b/tools/testing/selftests/powerpc/security/spectre_v2.c |
34174 |
+index adc2b7294e5fd..83647b8277e7d 100644 |
34175 |
+--- a/tools/testing/selftests/powerpc/security/spectre_v2.c |
34176 |
++++ b/tools/testing/selftests/powerpc/security/spectre_v2.c |
34177 |
+@@ -193,7 +193,7 @@ int spectre_v2_test(void) |
34178 |
+ * We are not vulnerable and reporting otherwise, so |
34179 |
+ * missing such a mismatch is safe. |
34180 |
+ */ |
34181 |
+- if (state == VULNERABLE) |
34182 |
++ if (miss_percent > 95) |
34183 |
+ return 4; |
34184 |
+ |
34185 |
+ return 1; |
34186 |
+diff --git a/tools/testing/selftests/powerpc/signal/.gitignore b/tools/testing/selftests/powerpc/signal/.gitignore |
34187 |
+index ce3375cd8e73e..8f6c816099a48 100644 |
34188 |
+--- a/tools/testing/selftests/powerpc/signal/.gitignore |
34189 |
++++ b/tools/testing/selftests/powerpc/signal/.gitignore |
34190 |
+@@ -4,3 +4,4 @@ signal_tm |
34191 |
+ sigfuz |
34192 |
+ sigreturn_vdso |
34193 |
+ sig_sc_double_restart |
34194 |
++sigreturn_kernel |
34195 |
+diff --git a/tools/testing/selftests/powerpc/signal/Makefile b/tools/testing/selftests/powerpc/signal/Makefile |
34196 |
+index d6ae54663aed7..84e201572466d 100644 |
34197 |
+--- a/tools/testing/selftests/powerpc/signal/Makefile |
34198 |
++++ b/tools/testing/selftests/powerpc/signal/Makefile |
34199 |
+@@ -1,5 +1,6 @@ |
34200 |
+ # SPDX-License-Identifier: GPL-2.0 |
34201 |
+ TEST_GEN_PROGS := signal signal_tm sigfuz sigreturn_vdso sig_sc_double_restart |
34202 |
++TEST_GEN_PROGS += sigreturn_kernel |
34203 |
+ |
34204 |
+ CFLAGS += -maltivec |
34205 |
+ $(OUTPUT)/signal_tm: CFLAGS += -mhtm |
34206 |
+diff --git a/tools/testing/selftests/powerpc/signal/sigreturn_kernel.c b/tools/testing/selftests/powerpc/signal/sigreturn_kernel.c |
34207 |
+new file mode 100644 |
34208 |
+index 0000000000000..0a1b6e591eeed |
34209 |
+--- /dev/null |
34210 |
++++ b/tools/testing/selftests/powerpc/signal/sigreturn_kernel.c |
34211 |
+@@ -0,0 +1,132 @@ |
34212 |
++// SPDX-License-Identifier: GPL-2.0 |
34213 |
++/* |
34214 |
++ * Test that we can't sigreturn to kernel addresses, or to kernel mode. |
34215 |
++ */ |
34216 |
++ |
34217 |
++#define _GNU_SOURCE |
34218 |
++ |
34219 |
++#include <stdio.h> |
34220 |
++#include <signal.h> |
34221 |
++#include <stdlib.h> |
34222 |
++#include <sys/types.h> |
34223 |
++#include <sys/wait.h> |
34224 |
++#include <unistd.h> |
34225 |
++ |
34226 |
++#include "utils.h" |
34227 |
++ |
34228 |
++#define MSR_PR (1ul << 14) |
34229 |
++ |
34230 |
++static volatile unsigned long long sigreturn_addr; |
34231 |
++static volatile unsigned long long sigreturn_msr_mask; |
34232 |
++ |
34233 |
++static void sigusr1_handler(int signo, siginfo_t *si, void *uc_ptr) |
34234 |
++{ |
34235 |
++ ucontext_t *uc = (ucontext_t *)uc_ptr; |
34236 |
++ |
34237 |
++ if (sigreturn_addr) |
34238 |
++ UCONTEXT_NIA(uc) = sigreturn_addr; |
34239 |
++ |
34240 |
++ if (sigreturn_msr_mask) |
34241 |
++ UCONTEXT_MSR(uc) &= sigreturn_msr_mask; |
34242 |
++} |
34243 |
++ |
34244 |
++static pid_t fork_child(void) |
34245 |
++{ |
34246 |
++ pid_t pid; |
34247 |
++ |
34248 |
++ pid = fork(); |
34249 |
++ if (pid == 0) { |
34250 |
++ raise(SIGUSR1); |
34251 |
++ exit(0); |
34252 |
++ } |
34253 |
++ |
34254 |
++ return pid; |
34255 |
++} |
34256 |
++ |
34257 |
++static int expect_segv(pid_t pid) |
34258 |
++{ |
34259 |
++ int child_ret; |
34260 |
++ |
34261 |
++ waitpid(pid, &child_ret, 0); |
34262 |
++ FAIL_IF(WIFEXITED(child_ret)); |
34263 |
++ FAIL_IF(!WIFSIGNALED(child_ret)); |
34264 |
++ FAIL_IF(WTERMSIG(child_ret) != 11); |
34265 |
++ |
34266 |
++ return 0; |
34267 |
++} |
34268 |
++ |
34269 |
++int test_sigreturn_kernel(void) |
34270 |
++{ |
34271 |
++ struct sigaction act; |
34272 |
++ int child_ret, i; |
34273 |
++ pid_t pid; |
34274 |
++ |
34275 |
++ act.sa_sigaction = sigusr1_handler; |
34276 |
++ act.sa_flags = SA_SIGINFO; |
34277 |
++ sigemptyset(&act.sa_mask); |
34278 |
++ |
34279 |
++ FAIL_IF(sigaction(SIGUSR1, &act, NULL)); |
34280 |
++ |
34281 |
++ for (i = 0; i < 2; i++) { |
34282 |
++ // Return to kernel |
34283 |
++ sigreturn_addr = 0xcull << 60; |
34284 |
++ pid = fork_child(); |
34285 |
++ expect_segv(pid); |
34286 |
++ |
34287 |
++ // Return to kernel virtual |
34288 |
++ sigreturn_addr = 0xc008ull << 48; |
34289 |
++ pid = fork_child(); |
34290 |
++ expect_segv(pid); |
34291 |
++ |
34292 |
++ // Return out of range |
34293 |
++ sigreturn_addr = 0xc010ull << 48; |
34294 |
++ pid = fork_child(); |
34295 |
++ expect_segv(pid); |
34296 |
++ |
34297 |
++ // Return to no-man's land, just below PAGE_OFFSET |
34298 |
++ sigreturn_addr = (0xcull << 60) - (64 * 1024); |
34299 |
++ pid = fork_child(); |
34300 |
++ expect_segv(pid); |
34301 |
++ |
34302 |
++ // Return to no-man's land, above TASK_SIZE_4PB |
34303 |
++ sigreturn_addr = 0x1ull << 52; |
34304 |
++ pid = fork_child(); |
34305 |
++ expect_segv(pid); |
34306 |
++ |
34307 |
++ // Return to 0xd space |
34308 |
++ sigreturn_addr = 0xdull << 60; |
34309 |
++ pid = fork_child(); |
34310 |
++ expect_segv(pid); |
34311 |
++ |
34312 |
++ // Return to 0xe space |
34313 |
++ sigreturn_addr = 0xeull << 60; |
34314 |
++ pid = fork_child(); |
34315 |
++ expect_segv(pid); |
34316 |
++ |
34317 |
++ // Return to 0xf space |
34318 |
++ sigreturn_addr = 0xfull << 60; |
34319 |
++ pid = fork_child(); |
34320 |
++ expect_segv(pid); |
34321 |
++ |
34322 |
++ // Attempt to set PR=0 for 2nd loop (should be blocked by kernel) |
34323 |
++ sigreturn_msr_mask = ~MSR_PR; |
34324 |
++ } |
34325 |
++ |
34326 |
++ printf("All children killed as expected\n"); |
34327 |
++ |
34328 |
++ // Don't change address, just MSR, should return to user as normal |
34329 |
++ sigreturn_addr = 0; |
34330 |
++ sigreturn_msr_mask = ~MSR_PR; |
34331 |
++ pid = fork_child(); |
34332 |
++ waitpid(pid, &child_ret, 0); |
34333 |
++ FAIL_IF(!WIFEXITED(child_ret)); |
34334 |
++ FAIL_IF(WIFSIGNALED(child_ret)); |
34335 |
++ FAIL_IF(WEXITSTATUS(child_ret) != 0); |
34336 |
++ |
34337 |
++ return 0; |
34338 |
++} |
34339 |
++ |
34340 |
++int main(void) |
34341 |
++{ |
34342 |
++ return test_harness(test_sigreturn_kernel, "sigreturn_kernel"); |
34343 |
++} |
34344 |
+diff --git a/tools/testing/selftests/vm/hmm-tests.c b/tools/testing/selftests/vm/hmm-tests.c |
34345 |
+index 864f126ffd78f..203323967b507 100644 |
34346 |
+--- a/tools/testing/selftests/vm/hmm-tests.c |
34347 |
++++ b/tools/testing/selftests/vm/hmm-tests.c |
34348 |
+@@ -1248,6 +1248,48 @@ TEST_F(hmm, anon_teardown) |
34349 |
+ } |
34350 |
+ } |
34351 |
+ |
34352 |
++/* |
34353 |
++ * Test memory snapshot without faulting in pages accessed by the device. |
34354 |
++ */ |
34355 |
++TEST_F(hmm, mixedmap) |
34356 |
++{ |
34357 |
++ struct hmm_buffer *buffer; |
34358 |
++ unsigned long npages; |
34359 |
++ unsigned long size; |
34360 |
++ unsigned char *m; |
34361 |
++ int ret; |
34362 |
++ |
34363 |
++ npages = 1; |
34364 |
++ size = npages << self->page_shift; |
34365 |
++ |
34366 |
++ buffer = malloc(sizeof(*buffer)); |
34367 |
++ ASSERT_NE(buffer, NULL); |
34368 |
++ |
34369 |
++ buffer->fd = -1; |
34370 |
++ buffer->size = size; |
34371 |
++ buffer->mirror = malloc(npages); |
34372 |
++ ASSERT_NE(buffer->mirror, NULL); |
34373 |
++ |
34374 |
++ |
34375 |
++ /* Reserve a range of addresses. */ |
34376 |
++ buffer->ptr = mmap(NULL, size, |
34377 |
++ PROT_READ | PROT_WRITE, |
34378 |
++ MAP_PRIVATE, |
34379 |
++ self->fd, 0); |
34380 |
++ ASSERT_NE(buffer->ptr, MAP_FAILED); |
34381 |
++ |
34382 |
++ /* Simulate a device snapshotting CPU pagetables. */ |
34383 |
++ ret = hmm_dmirror_cmd(self->fd, HMM_DMIRROR_SNAPSHOT, buffer, npages); |
34384 |
++ ASSERT_EQ(ret, 0); |
34385 |
++ ASSERT_EQ(buffer->cpages, npages); |
34386 |
++ |
34387 |
++ /* Check what the device saw. */ |
34388 |
++ m = buffer->mirror; |
34389 |
++ ASSERT_EQ(m[0], HMM_DMIRROR_PROT_READ); |
34390 |
++ |
34391 |
++ hmm_buffer_free(buffer); |
34392 |
++} |
34393 |
++ |
34394 |
+ /* |
34395 |
+ * Test memory snapshot without faulting in pages accessed by the device. |
34396 |
+ */ |