Backmerge Linus tree for some drm-fixes needed for msm and xe merges.
Unified · Split
| @@ -73,6 +73,8 @@ Andrey Ryabinin <ryabinin.a.a@gmail.com> <aryabinin@virtuozzo.com> · 72 unmodified lines | ||
| 73 | 73 | Andrzej Hajda <andrzej.hajda@intel.com> <a.hajda@samsung.com> |
| 74 | 74 | André Almeida <andrealmeid@igalia.com> <andrealmeid@collabora.com> |
| 75 | 75 | Andy Adamson <andros@citi.umich.edu> |
| 76 | +Andy Chiu <andybnac@gmail.com> <andy.chiu@sifive.com> | |
| 77 | +Andy Chiu <andybnac@gmail.com> <taochiu@synology.com> | |
| 76 | 78 | Andy Shevchenko <andy@kernel.org> <andy@smile.org.ua> |
| 77 | 79 | Andy Shevchenko <andy@kernel.org> <ext-andriy.shevchenko@nokia.com> |
| 78 | 80 | Anilkumar Kolli <quic_akolli@quicinc.com> <akolli@codeaurora.org> |
| @@ -197,18 +199,23 @@ Elliot Berman <quic_eberman@quicinc.com> <eberman@codeaurora.org> · 118 unmodified lines | ||
| 197 | 199 | Enric Balletbo i Serra <eballetbo@kernel.org> <enric.balletbo@collabora.com> |
| 198 | 200 | Enric Balletbo i Serra <eballetbo@kernel.org> <eballetbo@iseebcn.com> |
| 199 | 201 | Erik Kaneda <erik.kaneda@intel.com> <erik.schmauss@intel.com> |
| 200 | −Eugen Hristev <eugen.hristev@collabora.com> <eugen.hristev@microchip.com> | |
| 202 | +Eugen Hristev <eugen.hristev@linaro.org> <eugen.hristev@microchip.com> | |
| 203 | +Eugen Hristev <eugen.hristev@linaro.org> <eugen.hristev@collabora.com> | |
| 201 | 204 | Evgeniy Polyakov <johnpol@2ka.mipt.ru> |
| 202 | 205 | Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> <ezequiel@collabora.com> |
| 203 | 206 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason@jlekstrand.net> |
| 204 | 207 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@intel.com> |
| 205 | 208 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@collabora.com> |
| 209 | +Fangrui Song <i@maskray.me> <maskray@google.com> | |
| 206 | 210 | Felipe W Damasio <felipewd@terra.com.br> |
| 207 | 211 | Felix Kuhling <fxkuehl@gmx.de> |
| 208 | 212 | Felix Moeller <felix@derklecks.de> |
| 209 | 213 | Fenglin Wu <quic_fenglinw@quicinc.com> <fenglinw@codeaurora.org> |
| 210 | 214 | Filipe Lautert <filipe@icewall.org> |
| 211 | 215 | Finn Thain <fthain@linux-m68k.org> <fthain@telegraphics.com.au> |
| 216 | +Fiona Behrens <me@kloenk.dev> | |
| 217 | +Fiona Behrens <me@kloenk.dev> <me@kloenk.de> | |
| 218 | +Fiona Behrens <me@kloenk.dev> <fin@nyantec.com> | |
| 212 | 219 | Franck Bui-Huu <vagabon.xyz@gmail.com> |
| 213 | 220 | Frank Rowand <frowand.list@gmail.com> <frank.rowand@am.sony.com> |
| 214 | 221 | Frank Rowand <frowand.list@gmail.com> <frank.rowand@sony.com> |
| @@ -276,7 +283,7 @@ Jan Glauber <jan.glauber@gmail.com> <jglauber@cavium.com> · 61 unmodified lines | ||
| 276 | 283 | Jan Kuliga <jtkuliga.kdev@gmail.com> <jankul@alatek.krakow.pl> |
| 277 | 284 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@linux.intel.com> |
| 278 | 285 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko@profian.com> |
| 279 | −Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@tuni.fi> | |
| 286 | +Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@parity.io> | |
| 280 | 287 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com> |
| 281 | 288 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com> |
| 282 | 289 | Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com> |
| @@ -300,6 +307,11 @@ Jens Axboe <axboe@kernel.dk> <axboe@fb.com> · 17 unmodified lines | ||
| 300 | 307 | Jens Axboe <axboe@kernel.dk> <axboe@meta.com> |
| 301 | 308 | Jens Osterkamp <Jens.Osterkamp@de.ibm.com> |
| 302 | 309 | Jernej Skrabec <jernej.skrabec@gmail.com> <jernej.skrabec@siol.net> |
| 310 | +Jesper Dangaard Brouer <hawk@kernel.org> <brouer@redhat.com> | |
| 311 | +Jesper Dangaard Brouer <hawk@kernel.org> <hawk@comx.dk> | |
| 312 | +Jesper Dangaard Brouer <hawk@kernel.org> <jbrouer@redhat.com> | |
| 313 | +Jesper Dangaard Brouer <hawk@kernel.org> <jdb@comx.dk> | |
| 314 | +Jesper Dangaard Brouer <hawk@kernel.org> <netoptimizer@brouer.com> | |
| 303 | 315 | Jessica Zhang <quic_jesszhan@quicinc.com> <jesszhan@codeaurora.org> |
| 304 | 316 | Jilai Wang <quic_jilaiw@quicinc.com> <jilaiw@codeaurora.org> |
| 305 | 317 | Jiri Kosina <jikos@kernel.org> <jikos@jikos.cz> |
| @@ -1358,10 +1358,6 @@ D: Major kbuild rework during the 2.5 cycle · 1357 unmodified lines | ||
| 1358 | 1358 | D: ISDN Maintainer |
| 1359 | 1359 | S: USA |
| 1360 | 1360 | |
| 1361 | −N: Gerrit Renker | |
| 1362 | −E: gerrit@erg.abdn.ac.uk | |
| 1363 | −D: DCCP protocol support. | |
| 1364 | − | |
| 1365 | 1361 | N: Philip Gladstone |
| 1366 | 1362 | E: philip@gladstonefamily.net |
| 1367 | 1363 | D: Kernel / timekeeping stuff |
| @@ -1677,11 +1673,6 @@ W: http://www.carumba.com/ · 309 unmodified lines | ||
| 1677 | 1673 | D: bug toaster (A1 sauce makes all the difference) |
| 1678 | 1674 | D: Random linux hacker |
| 1679 | 1675 | |
| 1680 | −N: James Hogan | |
| 1681 | −E: jhogan@kernel.org | |
| 1682 | −D: Metag architecture maintainer | |
| 1683 | −D: TZ1090 SoC maintainer | |
| 1684 | − | |
| 1685 | 1676 | N: Tim Hockin |
| 1686 | 1677 | E: thockin@hockin.org |
| 1687 | 1678 | W: http://www.hockin.org/~thockin |
| @@ -1697,6 +1688,11 @@ D: hwmon subsystem maintainer · 9 unmodified lines | ||
| 1697 | 1688 | D: i2c-sis96x and i2c-stub SMBus drivers |
| 1698 | 1689 | S: USA |
| 1699 | 1690 | |
| 1691 | +N: James Hogan | |
| 1692 | +E: jhogan@kernel.org | |
| 1693 | +D: Metag architecture maintainer | |
| 1694 | +D: TZ1090 SoC maintainer | |
| 1695 | + | |
| 1700 | 1696 | N: Dirk Hohndel |
| 1701 | 1697 | E: hohndel@suse.de |
| 1702 | 1698 | D: The XFree86[tm] Project |
| @@ -1872,6 +1868,10 @@ S: K osmidomkum 723 · 169 unmodified lines | ||
| 1872 | 1868 | S: 160 00 Praha 6 |
| 1873 | 1869 | S: Czech Republic |
| 1874 | 1870 | |
| 1871 | +N: Seth Jennings | |
| 1872 | +E: sjenning@redhat.com | |
| 1873 | +D: Creation and maintenance of zswap | |
| 1874 | + | |
| 1875 | 1875 | N: Jeremy Kerr |
| 1876 | 1876 | D: Maintainer of SPU File System |
| 1877 | 1877 | |
| @@ -2188,19 +2188,6 @@ N: Mike Kravetz · 310 unmodified lines | ||
| 2188 | 2188 | E: mike.kravetz@oracle.com |
| 2189 | 2189 | D: Maintenance and development of the hugetlb subsystem |
| 2190 | 2190 | |
| 2191 | −N: Seth Jennings | |
| 2192 | −E: sjenning@redhat.com | |
| 2193 | −D: Creation and maintenance of zswap | |
| 2194 | − | |
| 2195 | −N: Dan Streetman | |
| 2196 | −E: ddstreet@ieee.org | |
| 2197 | −D: Maintenance and development of zswap | |
| 2198 | −D: Creation and maintenance of the zpool API | |
| 2199 | − | |
| 2200 | −N: Vitaly Wool | |
| 2201 | −E: vitaly.wool@konsulko.com | |
| 2202 | −D: Maintenance and development of zswap | |
| 2203 | − | |
| 2204 | 2191 | N: Andreas S. Krebs |
| 2205 | 2192 | E: akrebs@altavista.net |
| 2206 | 2193 | D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards |
| @@ -3191,6 +3178,11 @@ N: Ken Pizzini · 984 unmodified lines | ||
| 3191 | 3178 | E: ken@halcyon.com |
| 3192 | 3179 | D: CDROM driver "sonycd535" (Sony CDU-535/531) |
| 3193 | 3180 | |
| 3181 | +N: Mathieu Poirier | |
| 3182 | +E: mathieu.poirier@linaro.org | |
| 3183 | +D: CoreSight kernel subsystem, Maintainer 2014-2022 | |
| 3184 | +D: Perf tool support for CoreSight | |
| 3185 | + | |
| 3194 | 3186 | N: Stelian Pop |
| 3195 | 3187 | E: stelian@popies.net |
| 3196 | 3188 | P: 1024D/EDBB6147 7B36 0E07 04BC 11DC A7A0 D3F7 7185 9E7A EDBB 6147 |
| @@ -3300,6 +3292,10 @@ S: Schlossbergring 9 · 103 unmodified lines | ||
| 3300 | 3292 | S: 79098 Freiburg |
| 3301 | 3293 | S: Germany |
| 3302 | 3294 | |
| 3295 | +N: Gerrit Renker | |
| 3296 | +E: gerrit@erg.abdn.ac.uk | |
| 3297 | +D: DCCP protocol support. | |
| 3298 | + | |
| 3303 | 3299 | N: Thomas Renninger |
| 3304 | 3300 | E: trenn@suse.de |
| 3305 | 3301 | D: cpupowerutils |
| @@ -3576,11 +3572,6 @@ D: several improvements to system programs · 270 unmodified lines | ||
| 3576 | 3572 | S: Oldenburg |
| 3577 | 3573 | S: Germany |
| 3578 | 3574 | |
| 3579 | −N: Mathieu Poirier | |
| 3580 | −E: mathieu.poirier@linaro.org | |
| 3581 | −D: CoreSight kernel subsystem, Maintainer 2014-2022 | |
| 3582 | −D: Perf tool support for CoreSight | |
| 3583 | − | |
| 3584 | 3575 | N: Robert Schwebel |
| 3585 | 3576 | E: robert@schwebel.de |
| 3586 | 3577 | W: https://www.schwebel.de |
| @@ -3771,6 +3762,11 @@ S: Chr. Winthersvej 1 B, st.th. · 184 unmodified lines | ||
| 3771 | 3762 | S: DK-1860 Frederiksberg C |
| 3772 | 3763 | S: Denmark |
| 3773 | 3764 | |
| 3765 | +N: Dan Streetman | |
| 3766 | +E: ddstreet@ieee.org | |
| 3767 | +D: Maintenance and development of zswap | |
| 3768 | +D: Creation and maintenance of the zpool API | |
| 3769 | + | |
| 3774 | 3770 | N: Drew Sullivan |
| 3775 | 3771 | E: drew@ss.org |
| 3776 | 3772 | W: http://www.ss.org/ |
| @@ -4286,6 +4282,10 @@ S: Pipers Way · 509 unmodified lines | ||
| 4286 | 4282 | S: Swindon. SN3 1RJ |
| 4287 | 4283 | S: England |
| 4288 | 4284 | |
| 4285 | +N: Vitaly Wool | |
| 4286 | +E: vitaly.wool@konsulko.com | |
| 4287 | +D: Maintenance and development of zswap | |
| 4288 | + | |
| 4289 | 4289 | N: Chris Wright |
| 4290 | 4290 | E: chrisw@sous-sol.org |
| 4291 | 4291 | D: hacking on LSM framework and security modules. |
| @@ -223,7 +223,10 @@ are signed through the PKCS#7 message format to enforce some level of · 222 unmodified lines | ||
| 223 | 223 | authorization of the policies (prohibiting an attacker from gaining |
| 224 | 224 | unconstrained root, and deploying an "allow all" policy). These |
| 225 | 225 | policies must be signed by a certificate that chains to the |
| 226 | −``SYSTEM_TRUSTED_KEYRING``. With openssl, the policy can be signed by:: | |
| 226 | +``SYSTEM_TRUSTED_KEYRING``, or to the secondary and/or platform keyrings if | |
| 227 | +``CONFIG_IPE_POLICY_SIG_SECONDARY_KEYRING`` and/or | |
| 228 | +``CONFIG_IPE_POLICY_SIG_PLATFORM_KEYRING`` are enabled, respectively. | |
| 229 | +With openssl, the policy can be signed by:: | |
| 227 | 230 | |
| 228 | 231 | openssl smime -sign \ |
| 229 | 232 | -in "$MY_POLICY" \ |
| @@ -266,7 +269,7 @@ in the kernel. This file is write-only and accepts a PKCS#7 signed · 36 unmodified lines | ||
| 266 | 269 | policy. Two checks will always be performed on this policy: First, the |
| 267 | 270 | ``policy_names`` must match with the updated version and the existing |
| 268 | 271 | version. Second the updated policy must have a policy version greater than |
| 269 | −or equal to the currently-running version. This is to prevent rollback attacks. | |
| 272 | +the currently-running version. This is to prevent rollback attacks. | |
| 270 | 273 | |
| 271 | 274 | The ``delete`` file is used to remove a policy that is no longer needed. |
| 272 | 275 | This file is write-only and accepts a value of ``1`` to delete the policy. |
| @@ -425,8 +425,8 @@ This governor exposes only one tunable: · 424 unmodified lines | ||
| 425 | 425 | |
| 426 | 426 | ``rate_limit_us`` |
| 427 | 427 | Minimum time (in microseconds) that has to pass between two consecutive |
| 428 | − runs of governor computations (default: 1000 times the scaling driver's | |
| 429 | − transition latency). | |
| 428 | + runs of governor computations (default: 1.5 times the scaling driver's | |
| 429 | + transition latency or the maximum 2ms). | |
| 430 | 430 | |
| 431 | 431 | The purpose of this tunable is to reduce the scheduler context overhead |
| 432 | 432 | of the governor which might be excessive without it. |
| @@ -474,17 +474,17 @@ This governor exposes the following tunables: · 41 unmodified lines | ||
| 474 | 474 | This is how often the governor's worker routine should run, in |
| 475 | 475 | microseconds. |
| 476 | 476 | |
| 477 | − Typically, it is set to values of the order of 10000 (10 ms). Its | |
| 478 | − default value is equal to the value of ``cpuinfo_transition_latency`` | |
| 479 | − for each policy this governor is attached to (but since the unit here | |
| 480 | − is greater by 1000, this means that the time represented by | |
| 481 | − ``sampling_rate`` is 1000 times greater than the transition latency by | |
| 482 | − default). | |
| 477 | + Typically, it is set to values of the order of 2000 (2 ms). Its | |
| 478 | + default value is to add a 50% breathing room | |
| 479 | + to ``cpuinfo_transition_latency`` on each policy this governor is | |
| 480 | + attached to. The minimum is typically the length of two scheduler | |
| 481 | + ticks. | |
| 483 | 482 | |
| 484 | 483 | If this tunable is per-policy, the following shell command sets the time |
| 485 | − represented by it to be 750 times as high as the transition latency:: | |
| 484 | + represented by it to be 1.5 times as high as the transition latency | |
| 485 | + (the default):: | |
| 486 | 486 | |
| 487 | − # echo `$(($(cat cpuinfo_transition_latency) * 750 / 1000)) > ondemand/sampling_rate | |
| 487 | + # echo `$(($(cat cpuinfo_transition_latency) * 3 / 2)) > ondemand/sampling_rate | |
| 488 | 488 | |
| 489 | 489 | ``up_threshold`` |
| 490 | 490 | If the estimated CPU load is above this value (in percent), the governor |
| @@ -12,7 +12,10 @@ Pkeys Userspace (PKU) is a feature which can be found on: · 11 unmodified lines | ||
| 12 | 12 | * Intel server CPUs, Skylake and later |
| 13 | 13 | * Intel client CPUs, Tiger Lake (11th Gen Core) and later |
| 14 | 14 | * Future AMD CPUs |
| 15 | + * arm64 CPUs implementing the Permission Overlay Extension (FEAT_S1POE) | |
| 15 | 16 | |
| 17 | +x86_64 | |
| 18 | +====== | |
| 16 | 19 | Pkeys work by dedicating 4 previously Reserved bits in each page table entry to |
| 17 | 20 | a "protection key", giving 16 possible keys. |
| 18 | 21 | |
| @@ -28,6 +31,22 @@ register. The feature is only available in 64-bit mode, even though there is · 9 unmodified lines | ||
| 28 | 31 | theoretically space in the PAE PTEs. These permissions are enforced on data |
| 29 | 32 | access only and have no effect on instruction fetches. |
| 30 | 33 | |
| 34 | +arm64 | |
| 35 | +===== | |
| 36 | + | |
| 37 | +Pkeys use 3 bits in each page table entry, to encode a "protection key index", | |
| 38 | +giving 8 possible keys. | |
| 39 | + | |
| 40 | +Protections for each key are defined with a per-CPU user-writable system | |
| 41 | +register (POR_EL0). This is a 64-bit register encoding read, write and execute | |
| 42 | +overlay permissions for each protection key index. | |
| 43 | + | |
| 44 | +Being a CPU register, POR_EL0 is inherently thread-local, potentially giving | |
| 45 | +each thread a different set of protections from every other thread. | |
| 46 | + | |
| 47 | +Unlike x86_64, the protection key permissions also apply to instruction | |
| 48 | +fetches. | |
| 49 | + | |
| 31 | 50 | Syscalls |
| 32 | 51 | ======== |
| 33 | 52 | |
| @@ -38,11 +57,10 @@ There are 3 system calls which directly interact with pkeys:: · 4 unmodified lines | ||
| 38 | 57 | int pkey_mprotect(unsigned long start, size_t len, |
| 39 | 58 | unsigned long prot, int pkey); |
| 40 | 59 | |
| 41 | −Before a pkey can be used, it must first be allocated with | |
| 42 | −pkey_alloc(). An application calls the WRPKRU instruction | |
| 43 | −directly in order to change access permissions to memory covered | |
| 44 | −with a key. In this example WRPKRU is wrapped by a C function | |
| 45 | −called pkey_set(). | |
| 60 | +Before a pkey can be used, it must first be allocated with pkey_alloc(). An | |
| 61 | +application writes to the architecture specific CPU register directly in order | |
| 62 | +to change access permissions to memory covered with a key. In this example | |
| 63 | +this is wrapped by a C function called pkey_set(). | |
| 46 | 64 | :: |
| 47 | 65 | |
| 48 | 66 | int real_prot = PROT_READ|PROT_WRITE; |
| @@ -64,9 +82,9 @@ is no longer in use:: · 15 unmodified lines | ||
| 64 | 82 | munmap(ptr, PAGE_SIZE); |
| 65 | 83 | pkey_free(pkey); |
| 66 | 84 | |
| 67 | −.. note:: pkey_set() is a wrapper for the RDPKRU and WRPKRU instructions. | |
| 68 | − An example implementation can be found in | |
| 69 | − tools/testing/selftests/x86/protection_keys.c. | |
| 85 | +.. note:: pkey_set() is a wrapper around writing to the CPU register. | |
| 86 | + Example implementations can be found in | |
| 87 | + tools/testing/selftests/mm/pkey-{arm64,powerpc,x86}.h | |
| 70 | 88 | |
| 71 | 89 | Behavior |
| 72 | 90 | ======== |
| @@ -96,3 +114,7 @@ with a read():: · 23 unmodified lines | ||
| 96 | 114 | The kernel will send a SIGSEGV in both cases, but si_code will be set |
| 97 | 115 | to SEGV_PKERR when violating protection keys versus SEGV_ACCERR when |
| 98 | 116 | the plain mprotect() permissions are violated. |
| 117 | + | |
| 118 | +Note that kernel accesses from a kthread (such as io_uring) will use a default | |
| 119 | +value for the protection key register and so will not be consistent with | |
| 120 | +userspace's value of the register or mprotect(). | |
| @@ -0,0 +1,54 @@ | ||
| 1 | +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) | |
| 2 | +%YAML 1.2 | |
| 3 | +--- | |
| 4 | +$id: http://devicetree.org/schemas/display/elgin,jg10309-01.yaml# | |
| 5 | +$schema: http://devicetree.org/meta-schemas/core.yaml# | |
| 6 | + | |
| 7 | +title: Elgin JG10309-01 SPI-controlled display | |
| 8 | + | |
| 9 | +maintainers: | |
| 10 | + - Fabio Estevam <festevam@gmail.com> | |
| 11 | + | |
| 12 | +description: | | |
| 13 | + The Elgin JG10309-01 SPI-controlled display is used on the RV1108-Elgin-r1 | |
| 14 | + board and is a custom display. | |
| 15 | + | |
| 16 | +allOf: | |
| 17 | + - $ref: /schemas/spi/spi-peripheral-props.yaml# | |
| 18 | + | |
| 19 | +properties: | |
| 20 | + compatible: | |
| 21 | + const: elgin,jg10309-01 | |
| 22 | + | |
| 23 | + reg: | |
| 24 | + maxItems: 1 | |
| 25 | + | |
| 26 | + spi-max-frequency: | |
| 27 | + maximum: 24000000 | |
| 28 | + | |
| 29 | + spi-cpha: true | |
| 30 | + | |
| 31 | + spi-cpol: true | |
| 32 | + | |
| 33 | +required: | |
| 34 | + - compatible | |
| 35 | + - reg | |
| 36 | + - spi-cpha | |
| 37 | + - spi-cpol | |
| 38 | + | |
| 39 | +additionalProperties: false | |
| 40 | + | |
| 41 | +examples: | |
| 42 | + - | | |
| 43 | + spi { | |
| 44 | + #address-cells = <1>; | |
| 45 | + #size-cells = <0>; | |
| 46 | + | |
| 47 | + display@0 { | |
| 48 | + compatible = "elgin,jg10309-01"; | |
| 49 | + reg = <0>; | |
| 50 | + spi-max-frequency = <24000000>; | |
| 51 | + spi-cpha; | |
| 52 | + spi-cpol; | |
| 53 | + }; | |
| 54 | + }; | |
| @@ -63,6 +63,16 @@ properties: · 62 unmodified lines | ||
| 63 | 63 | - const: sleep |
| 64 | 64 | |
| 65 | 65 | power-domains: |
| 66 | + description: | | |
| 67 | + The MediaTek DPI module is typically associated with one of the | |
| 68 | + following multimedia power domains: | |
| 69 | + POWER_DOMAIN_DISPLAY | |
| 70 | + POWER_DOMAIN_VDOSYS | |
| 71 | + POWER_DOMAIN_MM | |
| 72 | + The specific power domain used varies depending on the SoC design. | |
| 73 | + | |
| 74 | + It is recommended to explicitly add the appropriate power domain | |
| 75 | + property to the DPI node in the device tree. | |
| 66 | 76 | maxItems: 1 |
| 67 | 77 | |
| 68 | 78 | port: |
| @@ -79,20 +89,6 @@ required: · 10 unmodified lines | ||
| 79 | 89 | - clock-names |
| 80 | 90 | - port |
| 81 | 91 | |
| 82 | −allOf: | |
| 83 | − - if: | |
| 84 | − not: | |
| 85 | − properties: | |
| 86 | − compatible: | |
| 87 | − contains: | |
| 88 | − enum: | |
| 89 | − - mediatek,mt6795-dpi | |
| 90 | − - mediatek,mt8173-dpi | |
| 91 | − - mediatek,mt8186-dpi | |
| 92 | − then: | |
| 93 | − properties: | |
| 94 | − power-domains: false | |
| 95 | − | |
| 96 | 92 | additionalProperties: false |
| 97 | 93 | |
| 98 | 94 | examples: |
| @@ -38,6 +38,7 @@ properties: · 37 unmodified lines | ||
| 38 | 38 | description: A phandle and PM domain specifier as defined by bindings of |
| 39 | 39 | the power controller specified by phandle. See |
| 40 | 40 | Documentation/devicetree/bindings/power/power-domain.yaml for details. |
| 41 | + maxItems: 1 | |
| 41 | 42 | |
| 42 | 43 | mediatek,gce-client-reg: |
| 43 | 44 | description: |
| @@ -57,6 +58,9 @@ properties: · 13 unmodified lines | ||
| 57 | 58 | clocks: |
| 58 | 59 | items: |
| 59 | 60 | - description: SPLIT Clock |
| 61 | + - description: Used for interfacing with the HDMI RX signal source. | |
| 62 | + - description: Paired with receiving HDMI RX metadata. | |
| 63 | + minItems: 1 | |
| 60 | 64 | |
| 61 | 65 | required: |
| 62 | 66 | - compatible |
| @@ -72,9 +76,24 @@ allOf: · 9 unmodified lines | ||
| 72 | 76 | const: mediatek,mt8195-mdp3-split |
| 73 | 77 | |
| 74 | 78 | then: |
| 79 | + properties: | |
| 80 | + clocks: | |
| 81 | + minItems: 3 | |
| 82 | + | |
| 75 | 83 | required: |
| 76 | 84 | - mediatek,gce-client-reg |
| 77 | 85 | |
| 86 | + - if: | |
| 87 | + properties: | |
| 88 | + compatible: | |
| 89 | + contains: | |
| 90 | + const: mediatek,mt8173-disp-split | |
| 91 | + | |
| 92 | + then: | |
| 93 | + properties: | |
| 94 | + clocks: | |
| 95 | + maxItems: 1 | |
| 96 | + | |
| 78 | 97 | additionalProperties: false |
| 79 | 98 | |
| 80 | 99 | examples: |
| @@ -67,6 +67,10 @@ properties: · 66 unmodified lines | ||
| 67 | 67 | A 2.5V to 3.3V supply for the external reference voltage. When omitted, |
| 68 | 68 | the internal 2.5V reference is used. |
| 69 | 69 | |
| 70 | + refin-supply: | |
| 71 | + description: | |
| 72 | + A 2.5V to 3.3V supply for external reference voltage, for ad7380-4 only. | |
| 73 | + | |
| 70 | 74 | aina-supply: |
| 71 | 75 | description: |
| 72 | 76 | The common mode voltage supply for the AINA- pin on pseudo-differential |
| @@ -135,6 +139,23 @@ allOf: · 62 unmodified lines | ||
| 135 | 139 | ainc-supply: false |
| 136 | 140 | aind-supply: false |
| 137 | 141 | |
| 142 | + # ad7380-4 uses refin-supply as external reference. | |
| 143 | + # All other chips from ad738x family use refio as optional external reference. | |
| 144 | + # When refio-supply is omitted, internal reference is used. | |
| 145 | + - if: | |
| 146 | + properties: | |
| 147 | + compatible: | |
| 148 | + enum: | |
| 149 | + - adi,ad7380-4 | |
| 150 | + then: | |
| 151 | + properties: | |
| 152 | + refio-supply: false | |
| 153 | + required: | |
| 154 | + - refin-supply | |
| 155 | + else: | |
| 156 | + properties: | |
| 157 | + refin-supply: false | |
| 158 | + | |
| 138 | 159 | examples: |
| 139 | 160 | - | |
| 140 | 161 | #include <dt-bindings/interrupt-controller/irq.h> |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | $id: http://devicetree.org/schemas/iio/dac/adi,ad5686.yaml# |
| 5 | 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | 6 | |
| 7 | −title: Analog Devices AD5360 and similar DACs | |
| 7 | +title: Analog Devices AD5360 and similar SPI DACs | |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | 10 | - Michael Hennerich <michael.hennerich@analog.com> |
| @@ -12,41 +12,22 @@ maintainers: · 1 unmodified line | ||
| 12 | 12 | |
| 13 | 13 | properties: |
| 14 | 14 | compatible: |
| 15 | − oneOf: | |
| 16 | − - description: SPI devices | |
| 17 | − enum: | |
| 18 | − - adi,ad5310r | |
| 19 | − - adi,ad5672r | |
| 20 | − - adi,ad5674r | |
| 21 | − - adi,ad5676 | |
| 22 | − - adi,ad5676r | |
| 23 | − - adi,ad5679r | |
| 24 | − - adi,ad5681r | |
| 25 | − - adi,ad5682r | |
| 26 | − - adi,ad5683 | |
| 27 | − - adi,ad5683r | |
| 28 | − - adi,ad5684 | |
| 29 | − - adi,ad5684r | |
| 30 | − - adi,ad5685r | |
| 31 | − - adi,ad5686 | |
| 32 | − - adi,ad5686r | |
| 33 | − - description: I2C devices | |
| 34 | − enum: | |
| 35 | − - adi,ad5311r | |
| 36 | − - adi,ad5337r | |
| 37 | − - adi,ad5338r | |
| 38 | − - adi,ad5671r | |
| 39 | − - adi,ad5675r | |
| 40 | − - adi,ad5691r | |
| 41 | − - adi,ad5692r | |
| 42 | − - adi,ad5693 | |
| 43 | − - adi,ad5693r | |
| 44 | − - adi,ad5694 | |
| 45 | − - adi,ad5694r | |
| 46 | − - adi,ad5695r | |
| 47 | − - adi,ad5696 | |
| 48 | − - adi,ad5696r | |
| 49 | − | |
| 15 | + enum: | |
| 16 | + - adi,ad5310r | |
| 17 | + - adi,ad5672r | |
| 18 | + - adi,ad5674r | |
| 19 | + - adi,ad5676 | |
| 20 | + - adi,ad5676r | |
| 21 | + - adi,ad5679r | |
| 22 | + - adi,ad5681r | |
| 23 | + - adi,ad5682r | |
| 24 | + - adi,ad5683 | |
| 25 | + - adi,ad5683r | |
| 26 | + - adi,ad5684 | |
| 27 | + - adi,ad5684r | |
| 28 | + - adi,ad5685r | |
| 29 | + - adi,ad5686 | |
| 30 | + - adi,ad5686r | |
| 50 | 31 | |
| 51 | 32 | reg: |
| 52 | 33 | maxItems: 1 |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | ||
| 4 | 4 | $id: http://devicetree.org/schemas/iio/dac/adi,ad5696.yaml# |
| 5 | 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# |
| 6 | 6 | |
| 7 | −title: Analog Devices AD5696 and similar multi-channel DACs | |
| 7 | +title: Analog Devices AD5696 and similar I2C multi-channel DACs | |
| 8 | 8 | |
| 9 | 9 | maintainers: |
| 10 | 10 | - Michael Auchter <michael.auchter@ni.com> |
| @@ -16,6 +16,7 @@ properties: · 5 unmodified lines | ||
| 16 | 16 | compatible: |
| 17 | 17 | enum: |
| 18 | 18 | - adi,ad5311r |
| 19 | + - adi,ad5337r | |
| 19 | 20 | - adi,ad5338r |
| 20 | 21 | - adi,ad5671r |
| 21 | 22 | - adi,ad5675r |
| @@ -82,9 +82,6 @@ allOf: · 81 unmodified lines | ||
| 82 | 82 | enum: |
| 83 | 83 | - fsl,ls1043a-extirq |
| 84 | 84 | - fsl,ls1046a-extirq |
| 85 | − - fsl,ls1088a-extirq | |
| 86 | − - fsl,ls2080a-extirq | |
| 87 | − - fsl,lx2160a-extirq | |
| 88 | 85 | then: |
| 89 | 86 | properties: |
| 90 | 87 | interrupt-map: |
| @@ -95,6 +92,29 @@ allOf: · 4 unmodified lines | ||
| 95 | 92 | - const: 0xf |
| 96 | 93 | - const: 0 |
| 97 | 94 | |
| 95 | + - if: | |
| 96 | + properties: | |
| 97 | + compatible: | |
| 98 | + contains: | |
| 99 | + enum: | |
| 100 | + - fsl,ls1088a-extirq | |
| 101 | + - fsl,ls2080a-extirq | |
| 102 | + - fsl,lx2160a-extirq | |
| 103 | +# The driver(drivers/irqchip/irq-ls-extirq.c) have not use standard DT | |
| 104 | +# function to parser interrupt-map. So it doesn't consider '#address-size' | |
| 105 | +# in parent interrupt controller, such as GIC. | |
| 106 | +# | |
| 107 | +# When dt-binding verify interrupt-map, item data matrix is spitted at | |
| 108 | +# incorrect position. Remove interrupt-map restriction because it always | |
| 109 | +# wrong. | |
| 110 | + | |
| 111 | + then: | |
| 112 | + properties: | |
| 113 | + interrupt-map-mask: | |
| 114 | + items: | |
| 115 | + - const: 0xf | |
| 116 | + - const: 0 | |
| 117 | + | |
| 98 | 118 | additionalProperties: false |
| 99 | 119 | |
| 100 | 120 | examples: |
| @@ -113,7 +113,7 @@ properties: · 112 unmodified lines | ||
| 113 | 113 | |
| 114 | 114 | msi-parent: |
| 115 | 115 | deprecated: true |
| 116 | − $ref: /schemas/types.yaml#/definitions/phandle | |
| 116 | + maxItems: 1 | |
| 117 | 117 | description: |
| 118 | 118 | Describes the MSI controller node handling message |
| 119 | 119 | interrupts for the MC. When there is no translation |
| @@ -26,6 +26,7 @@ properties: · 25 unmodified lines | ||
| 26 | 26 | - brcm,asp-v2.1-mdio |
| 27 | 27 | - brcm,asp-v2.2-mdio |
| 28 | 28 | - brcm,unimac-mdio |
| 29 | + - brcm,bcm6846-mdio | |
| 29 | 30 | |
| 30 | 31 | reg: |
| 31 | 32 | minItems: 1 |
| @@ -154,8 +154,6 @@ allOf: · 153 unmodified lines | ||
| 154 | 154 | - qcom,sm8550-qmp-gen4x2-pcie-phy |
| 155 | 155 | - qcom,sm8650-qmp-gen3x2-pcie-phy |
| 156 | 156 | - qcom,sm8650-qmp-gen4x2-pcie-phy |
| 157 | − - qcom,x1e80100-qmp-gen3x2-pcie-phy | |
| 158 | − - qcom,x1e80100-qmp-gen4x2-pcie-phy | |
| 159 | 157 | then: |
| 160 | 158 | properties: |
| 161 | 159 | clocks: |
| @@ -171,6 +169,8 @@ allOf: · 9 unmodified lines | ||
| 171 | 169 | - qcom,sc8280xp-qmp-gen3x1-pcie-phy |
| 172 | 170 | - qcom,sc8280xp-qmp-gen3x2-pcie-phy |
| 173 | 171 | - qcom,sc8280xp-qmp-gen3x4-pcie-phy |
| 172 | + - qcom,x1e80100-qmp-gen3x2-pcie-phy | |
| 173 | + - qcom,x1e80100-qmp-gen4x2-pcie-phy | |
| 174 | 174 | - qcom,x1e80100-qmp-gen4x4-pcie-phy |
| 175 | 175 | then: |
| 176 | 176 | properties: |
| @@ -201,6 +201,7 @@ allOf: · 24 unmodified lines | ||
| 201 | 201 | - qcom,sm8550-qmp-gen4x2-pcie-phy |
| 202 | 202 | - qcom,sm8650-qmp-gen4x2-pcie-phy |
| 203 | 203 | - qcom,x1e80100-qmp-gen4x2-pcie-phy |
| 204 | + - qcom,x1e80100-qmp-gen4x4-pcie-phy | |
| 204 | 205 | then: |
| 205 | 206 | properties: |
| 206 | 207 | resets: |
| @@ -102,21 +102,21 @@ properties: · 101 unmodified lines | ||
| 102 | 102 | default: 2 |
| 103 | 103 | |
| 104 | 104 | interrupts: |
| 105 | − oneOf: | |
| 106 | − - minItems: 1 | |
| 107 | − items: | |
| 108 | − - description: TX interrupt | |
| 109 | − - description: RX interrupt | |
| 110 | − - items: | |
| 111 | − - description: common/combined interrupt | |
| 105 | + minItems: 1 | |
| 106 | + maxItems: 2 | |
| 112 | 107 | |
| 113 | 108 | interrupt-names: |
| 114 | 109 | oneOf: |
| 115 | − - minItems: 1 | |
| 110 | + - description: TX interrupt | |
| 111 | + const: tx | |
| 112 | + - description: RX interrupt | |
| 113 | + const: rx | |
| 114 | + - description: TX and RX interrupts | |
| 116 | 115 | items: |
| 117 | 116 | - const: tx |
| 118 | 117 | - const: rx |
| 119 | − - const: common | |
| 118 | + - description: Common/combined interrupt | |
| 119 | + const: common | |
| 120 | 120 | |
| 121 | 121 | fck_parent: |
| 122 | 122 | $ref: /schemas/types.yaml#/definitions/string |
| @@ -48,6 +48,10 @@ properties: · 47 unmodified lines | ||
| 48 | 48 | - const: mclk_rx |
| 49 | 49 | - const: hclk |
| 50 | 50 | |
| 51 | + port: | |
| 52 | + $ref: audio-graph-port.yaml# | |
| 53 | + unevaluatedProperties: false | |
| 54 | + | |
| 51 | 55 | resets: |
| 52 | 56 | maxItems: 1 |
| 53 | 57 | |
| @@ -101,8 +101,6 @@ properties: · 100 unmodified lines | ||
| 101 | 101 | - domintech,dmard09 |
| 102 | 102 | # DMARD10: 3-axis Accelerometer |
| 103 | 103 | - domintech,dmard10 |
| 104 | − # Elgin SPI-controlled LCD | |
| 105 | − - elgin,jg10309-01 | |
| 106 | 104 | # MMA7660FC: 3-Axis Orientation/Motion Detection Sensor |
| 107 | 105 | - fsl,mma7660 |
| 108 | 106 | # MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer |
| @@ -115,7 +115,7 @@ set up cache ready for use. The following script commands are available: · 114 unmodified lines | ||
| 115 | 115 | |
| 116 | 116 | This mask can also be set through sysfs, eg:: |
| 117 | 117 | |
| 118 | − echo 5 >/sys/modules/cachefiles/parameters/debug | |
| 118 | + echo 5 > /sys/module/cachefiles/parameters/debug | |
| 119 | 119 | |
| 120 | 120 | |
| 121 | 121 | Starting the Cache |
| @@ -208,7 +208,7 @@ The filesystem must arrange to `cancel · 207 unmodified lines | ||
| 208 | 208 | such `reservations |
| 209 | 209 | <https://lore.kernel.org/linux-xfs/20220817093627.GZ3600936@dread.disaster.area/>`_ |
| 210 | 210 | because writeback will not consume the reservation. |
| 211 | −The ``iomap_file_buffered_write_punch_delalloc`` can be called from a | |
| 211 | +The ``iomap_write_delalloc_release`` can be called from a | |
| 212 | 212 | ``->iomap_end`` function to find all the clean areas of the folios |
| 213 | 213 | caching a fresh (``IOMAP_F_NEW``) delalloc mapping. |
| 214 | 214 | It takes the ``invalidate_lock``. |
| @@ -592,4 +592,3 @@ API Function Reference · 591 unmodified lines | ||
| 592 | 592 | |
| 593 | 593 | .. kernel-doc:: include/linux/netfs.h |
| 594 | 594 | .. kernel-doc:: fs/netfs/buffered_read.c |
| 595 | −.. kernel-doc:: fs/netfs/io.c | |
| @@ -41,13 +41,22 @@ supports only 1 SDO line. · 40 unmodified lines | ||
| 41 | 41 | Reference voltage |
| 42 | 42 | ----------------- |
| 43 | 43 | |
| 44 | −2 possible reference voltage sources are supported: | |
| 44 | +ad7380-4 | |
| 45 | +~~~~~~~~ | |
| 46 | + | |
| 47 | +ad7380-4 supports only an external reference voltage (2.5V to 3.3V). It must be | |
| 48 | +declared in the device tree as ``refin-supply``. | |
| 49 | + | |
| 50 | +All other devices from ad738x family | |
| 51 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 52 | + | |
| 53 | +All other devices from ad738x support 2 possible reference voltage sources: | |
| 45 | 54 | |
| 46 | 55 | - Internal reference (2.5V) |
| 47 | 56 | - External reference (2.5V to 3.3V) |
| 48 | 57 | |
| 49 | 58 | The source is determined by the device tree. If ``refio-supply`` is present, |
| 50 | −then the external reference is used, else the internal reference is used. | |
| 59 | +then it is used as external reference, else the internal reference is used. | |
| 51 | 60 | |
| 52 | 61 | Oversampling and resolution boost |
| 53 | 62 | --------------------------------- |
| @@ -7,26 +7,26 @@ The DAMON subsystem covers the files that are listed in 'DATA ACCESS MONITOR' · 6 unmodified lines | ||
| 7 | 7 | section of 'MAINTAINERS' file. |
| 8 | 8 | |
| 9 | 9 | The mailing lists for the subsystem are damon@lists.linux.dev and |
| 10 | −linux-mm@kvack.org. Patches should be made against the mm-unstable `tree | |
| 11 | −<https://git.kernel.org/akpm/mm/h/mm-unstable>` whenever possible and posted to | |
| 12 | −the mailing lists. | |
| 10 | +linux-mm@kvack.org. Patches should be made against the `mm-unstable tree | |
| 11 | +<https://git.kernel.org/akpm/mm/h/mm-unstable>`_ whenever possible and posted | |
| 12 | +to the mailing lists. | |
| 13 | 13 | |
| 14 | 14 | SCM Trees |
| 15 | 15 | --------- |
| 16 | 16 | |
| 17 | 17 | There are multiple Linux trees for DAMON development. Patches under |
| 18 | 18 | development or testing are queued in `damon/next |
| 19 | −<https://git.kernel.org/sj/h/damon/next>` by the DAMON maintainer. | |
| 19 | +<https://git.kernel.org/sj/h/damon/next>`_ by the DAMON maintainer. | |
| 20 | 20 | Sufficiently reviewed patches will be queued in `mm-unstable |
| 21 | −<https://git.kernel.org/akpm/mm/h/mm-unstable>` by the memory management | |
| 21 | +<https://git.kernel.org/akpm/mm/h/mm-unstable>`_ by the memory management | |
| 22 | 22 | subsystem maintainer. After more sufficient tests, the patches will be queued |
| 23 | −in `mm-stable <https://git.kernel.org/akpm/mm/h/mm-stable>` , and finally | |
| 23 | +in `mm-stable <https://git.kernel.org/akpm/mm/h/mm-stable>`_, and finally | |
| 24 | 24 | pull-requested to the mainline by the memory management subsystem maintainer. |
| 25 | 25 | |
| 26 | −Note again the patches for mm-unstable `tree | |
| 27 | −<https://git.kernel.org/akpm/mm/h/mm-unstable>` are queued by the memory | |
| 26 | +Note again the patches for `mm-unstable tree | |
| 27 | +<https://git.kernel.org/akpm/mm/h/mm-unstable>`_ are queued by the memory | |
| 28 | 28 | management subsystem maintainer. If the patches requires some patches in |
| 29 | −damon/next `tree <https://git.kernel.org/sj/h/damon/next>` which not yet merged | |
| 29 | +`damon/next tree <https://git.kernel.org/sj/h/damon/next>`_ which not yet merged | |
| 30 | 30 | in mm-unstable, please make sure the requirement is clearly specified. |
| 31 | 31 | |
| 32 | 32 | Submit checklist addendum |
| @@ -37,25 +37,25 @@ When making DAMON changes, you should do below. · 4 unmodified lines | ||
| 37 | 37 | - Build changes related outputs including kernel and documents. |
| 38 | 38 | - Ensure the builds introduce no new errors or warnings. |
| 39 | 39 | - Run and ensure no new failures for DAMON `selftests |
| 40 | − <https://github.com/awslabs/damon-tests/blob/master/corr/run.sh#L49>` and | |
| 40 | + <https://github.com/damonitor/damon-tests/blob/master/corr/run.sh#L49>`_ and | |
| 41 | 41 | `kunittests |
| 42 | − <https://github.com/awslabs/damon-tests/blob/master/corr/tests/kunit.sh>`. | |
| 42 | + <https://github.com/damonitor/damon-tests/blob/master/corr/tests/kunit.sh>`_. | |
| 43 | 43 | |
| 44 | 44 | Further doing below and putting the results will be helpful. |
| 45 | 45 | |
| 46 | 46 | - Run `damon-tests/corr |
| 47 | − <https://github.com/awslabs/damon-tests/tree/master/corr>` for normal | |
| 47 | + <https://github.com/damonitor/damon-tests/tree/master/corr>`_ for normal | |
| 48 | 48 | changes. |
| 49 | 49 | - Run `damon-tests/perf |
| 50 | − <https://github.com/awslabs/damon-tests/tree/master/perf>` for performance | |
| 50 | + <https://github.com/damonitor/damon-tests/tree/master/perf>`_ for performance | |
| 51 | 51 | changes. |
| 52 | 52 | |
| 53 | 53 | Key cycle dates |
| 54 | 54 | --------------- |
| 55 | 55 | |
| 56 | 56 | Patches can be sent anytime. Key cycle dates of the `mm-unstable |
| 57 | −<https://git.kernel.org/akpm/mm/h/mm-unstable>` and `mm-stable | |
| 58 | −<https://git.kernel.org/akpm/mm/h/mm-stable>` trees depend on the memory | |
| 57 | +<https://git.kernel.org/akpm/mm/h/mm-unstable>`_ and `mm-stable | |
| 58 | +<https://git.kernel.org/akpm/mm/h/mm-stable>`_ trees depend on the memory | |
| 59 | 59 | management subsystem maintainer. |
| 60 | 60 | |
| 61 | 61 | Review cadence |
| @@ -72,13 +72,13 @@ Mailing tool · 10 unmodified lines | ||
| 72 | 72 | Like many other Linux kernel subsystems, DAMON uses the mailing lists |
| 73 | 73 | (damon@lists.linux.dev and linux-mm@kvack.org) as the major communication |
| 74 | 74 | channel. There is a simple tool called `HacKerMaiL |
| 75 | −<https://github.com/damonitor/hackermail>` (``hkml``), which is for people who | |
| 75 | +<https://github.com/damonitor/hackermail>`_ (``hkml``), which is for people who | |
| 76 | 76 | are not very familiar with the mailing lists based communication. The tool |
| 77 | 77 | could be particularly helpful for DAMON community members since it is developed |
| 78 | 78 | and maintained by DAMON maintainer. The tool is also officially announced to |
| 79 | 79 | support DAMON and general Linux kernel development workflow. |
| 80 | 80 | |
| 81 | −In other words, `hkml <https://github.com/damonitor/hackermail>` is a mailing | |
| 81 | +In other words, `hkml <https://github.com/damonitor/hackermail>`_ is a mailing | |
| 82 | 82 | tool for DAMON community, which DAMON maintainer is committed to support. |
| 83 | 83 | Please feel free to try and report issues or feature requests for the tool to |
| 84 | 84 | the maintainer. |
| @@ -98,8 +98,8 @@ slots, and attendees should reserve one of those at least 24 hours before the · 13 unmodified lines | ||
| 98 | 98 | time slot, by reaching out to the maintainer. |
| 99 | 99 | |
| 100 | 100 | Schedules and available reservation time slots are available at the Google `doc |
| 101 | −<https://docs.google.com/document/d/1v43Kcj3ly4CYqmAkMaZzLiM2GEnWfgdGbZAH3mi2vpM/edit?usp=sharing>`. | |
| 101 | +<https://docs.google.com/document/d/1v43Kcj3ly4CYqmAkMaZzLiM2GEnWfgdGbZAH3mi2vpM/edit?usp=sharing>`_. | |
| 102 | 102 | There is also a public Google `calendar |
| 103 | −<https://calendar.google.com/calendar/u/0?cid=ZDIwOTA4YTMxNjc2MDQ3NTIyMmUzYTM5ZmQyM2U4NDA0ZGIwZjBiYmJlZGQxNDM0MmY4ZTRjOTE0NjdhZDRiY0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t>` | |
| 103 | +<https://calendar.google.com/calendar/u/0?cid=ZDIwOTA4YTMxNjc2MDQ3NTIyMmUzYTM5ZmQyM2U4NDA0ZGIwZjBiYmJlZGQxNDM0MmY4ZTRjOTE0NjdhZDRiY0Bncm91cC5jYWxlbmRhci5nb29nbGUuY29t>`_ | |
| 104 | 104 | that has the events. Anyone can subscribe it. DAMON maintainer will also |
| 105 | 105 | provide periodic reminder to the mailing list (damon@lists.linux.dev). |
| @@ -16,7 +16,7 @@ ii) transmit network traffic, or any other that needs raw · 15 unmodified lines | ||
| 16 | 16 | |
| 17 | 17 | Howto can be found at: |
| 18 | 18 | |
| 19 | − https://sites.google.com/site/packetmmap/ | |
| 19 | + https://web.archive.org/web/20220404160947/https://sites.google.com/site/packetmmap/ | |
| 20 | 20 | |
| 21 | 21 | Please send your comments to |
| 22 | 22 | - Ulisses Alonso Camaró <uaca@i.hate.spam.alumni.uv.es> |
| @@ -166,7 +166,8 @@ As capture, each frame contains two parts:: · 143 unmodified lines | ||
| 166 | 166 | /* bind socket to eth0 */ |
| 167 | 167 | bind(this->socket, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_ll)); |
| 168 | 168 | |
| 169 | − A complete tutorial is available at: https://sites.google.com/site/packetmmap/ | |
| 169 | + A complete tutorial is available at: | |
| 170 | + https://web.archive.org/web/20220404160947/https://sites.google.com/site/packetmmap/ | |
| 170 | 171 | |
| 171 | 172 | By default, the user should put data at:: |
| 172 | 173 | |
| @@ -9,7 +9,7 @@ segments between trusted peers. It adds a new TCP header option with · 8 unmodified lines | ||
| 9 | 9 | a Message Authentication Code (MAC). MACs are produced from the content |
| 10 | 10 | of a TCP segment using a hashing function with a password known to both peers. |
| 11 | 11 | The intent of TCP-AO is to deprecate TCP-MD5 providing better security, |
| 12 | −key rotation and support for variety of hashing algorithms. | |
| 12 | +key rotation and support for a variety of hashing algorithms. | |
| 13 | 13 | |
| 14 | 14 | 1. Introduction |
| 15 | 15 | =============== |
| @@ -164,9 +164,9 @@ A: It should not, no action needs to be performed [7.5.2.e]:: · 148 unmodified lines | ||
| 164 | 164 | is not available, no action is required (RNextKeyID of a received |
| 165 | 165 | segment needs to match the MKT’s SendID). |
| 166 | 166 | |
| 167 | −Q: How current_key is set and when does it change? It is a user-triggered | |
| 168 | −change, or is it by a request from the remote peer? Is it set by the user | |
| 169 | −explicitly, or by a matching rule? | |
| 167 | +Q: How is current_key set, and when does it change? Is it a user-triggered | |
| 168 | +change, or is it triggered by a request from the remote peer? Is it set by the | |
| 169 | +user explicitly, or by a matching rule? | |
| 170 | 170 | |
| 171 | 171 | A: current_key is set by RNextKeyID [6.1]:: |
| 172 | 172 | |
| @@ -233,8 +233,8 @@ always have one current_key [3.3]:: · 60 unmodified lines | ||
| 233 | 233 | |
| 234 | 234 | Q: Can a non-TCP-AO connection become a TCP-AO-enabled one? |
| 235 | 235 | |
| 236 | −A: No: for already established non-TCP-AO connection it would be impossible | |
| 237 | −to switch using TCP-AO as the traffic key generation requires the initial | |
| 236 | +A: No: for an already established non-TCP-AO connection it would be impossible | |
| 237 | +to switch to using TCP-AO, as the traffic key generation requires the initial | |
| 238 | 238 | sequence numbers. Paraphrasing, starting using TCP-AO would require |
| 239 | 239 | re-establishing the TCP connection. |
| 240 | 240 | |
| @@ -292,7 +292,7 @@ no transparency is really needed and modern BGP daemons already have · 51 unmodified lines | ||
| 292 | 292 | |
| 293 | 293 | Linux provides a set of ``setsockopt()s`` and ``getsockopt()s`` that let |
| 294 | 294 | userspace manage TCP-AO on a per-socket basis. In order to add/delete MKTs |
| 295 | −``TCP_AO_ADD_KEY`` and ``TCP_AO_DEL_KEY`` TCP socket options must be used | |
| 295 | +``TCP_AO_ADD_KEY`` and ``TCP_AO_DEL_KEY`` TCP socket options must be used. | |
| 296 | 296 | It is not allowed to add a key on an established non-TCP-AO connection |
| 297 | 297 | as well as to remove the last key from TCP-AO connection. |
| 298 | 298 | |
| @@ -361,7 +361,7 @@ not implemented. · 62 unmodified lines | ||
| 361 | 361 | 4. ``setsockopt()`` vs ``accept()`` race |
| 362 | 362 | ======================================== |
| 363 | 363 | |
| 364 | −In contrast with TCP-MD5 established connection which has just one key, | |
| 364 | +In contrast with an established TCP-MD5 connection which has just one key, | |
| 365 | 365 | TCP-AO connections may have many keys, which means that accepted connections |
| 366 | 366 | on a listen socket may have any amount of keys as well. As copying all those |
| 367 | 367 | keys on a first properly signed SYN would make the request socket bigger, that |
| @@ -374,7 +374,7 @@ keys from sockets that were already established, but not yet ``accept()``'ed, · 6 unmodified lines | ||
| 374 | 374 | hanging in the accept queue. |
| 375 | 375 | |
| 376 | 376 | The reverse is valid as well: if userspace adds a new key for a peer on |
| 377 | −a listener socket, the established sockets in accept queue won't | |
| 377 | +a listener socket, the established sockets in the accept queue won't | |
| 378 | 378 | have the new keys. |
| 379 | 379 | |
| 380 | 380 | At this moment, the resolution for the two races: |
| @@ -382,7 +382,7 @@ At this moment, the resolution for the two races: · 1 unmodified line | ||
| 382 | 382 | and ``setsockopt(TCP_AO_DEL_KEY)`` vs ``accept()`` is delegated to userspace. |
| 383 | 383 | This means that it's expected that userspace would check the MKTs on the socket |
| 384 | 384 | that was returned by ``accept()`` to verify that any key rotation that |
| 385 | −happened on listen socket is reflected on the newly established connection. | |
| 385 | +happened on the listen socket is reflected on the newly established connection. | |
| 386 | 386 | |
| 387 | 387 | This is a similar "do-nothing" approach to TCP-MD5 from the kernel side and |
| 388 | 388 | may be changed later by introducing new flags to ``tcp_ao_add`` |
| @@ -355,6 +355,8 @@ just do it. As a result, a sequence of smaller series gets merged quicker and · 354 unmodified lines | ||
| 355 | 355 | with better review coverage. Re-posting large series also increases the mailing |
| 356 | 356 | list traffic. |
| 357 | 357 | |
| 358 | +.. _rcs: | |
| 359 | + | |
| 358 | 360 | Local variable ordering ("reverse xmas tree", "RCS") |
| 359 | 361 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 360 | 362 | |
| @@ -391,6 +393,21 @@ APIs and helpers, especially scoped iterators. However, direct use of · 30 unmodified lines | ||
| 391 | 393 | ``__free()`` within networking core and drivers is discouraged. |
| 392 | 394 | Similar guidance applies to declaring variables mid-function. |
| 393 | 395 | |
| 396 | +Clean-up patches | |
| 397 | +~~~~~~~~~~~~~~~~ | |
| 398 | + | |
| 399 | +Netdev discourages patches which perform simple clean-ups, which are not in | |
| 400 | +the context of other work. For example: | |
| 401 | + | |
| 402 | +* Addressing ``checkpatch.pl`` warnings | |
| 403 | +* Addressing :ref:`Local variable ordering<rcs>` issues | |
| 404 | +* Conversions to device-managed APIs (``devm_`` helpers) | |
| 405 | + | |
| 406 | +This is because it is felt that the churn that such changes produce comes | |
| 407 | +at a greater cost than the value of such clean-ups. | |
| 408 | + | |
| 409 | +Conversely, spelling and grammar fixes are not discouraged. | |
| 410 | + | |
| 394 | 411 | Resending after review |
| 395 | 412 | ~~~~~~~~~~~~~~~~~~~~~~ |
| 396 | 413 | |
| @@ -30,10 +30,13 @@ tree as a dedicated branch covering multiple subsystems. · 29 unmodified lines | ||
| 30 | 30 | The main SoC tree is housed on git.kernel.org: |
| 31 | 31 | https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/ |
| 32 | 32 | |
| 33 | +Maintainers | |
| 34 | +----------- | |
| 35 | + | |
| 33 | 36 | Clearly this is quite a wide range of topics, which no one person, or even |
| 34 | 37 | small group of people are capable of maintaining. Instead, the SoC subsystem |
| 35 | −is comprised of many submaintainers, each taking care of individual platforms | |
| 36 | −and driver subdirectories. | |
| 38 | +is comprised of many submaintainers (platform maintainers), each taking care of | |
| 39 | +individual platforms and driver subdirectories. | |
| 37 | 40 | In this regard, "platform" usually refers to a series of SoCs from a given |
| 38 | 41 | vendor, for example, Nvidia's series of Tegra SoCs. Many submaintainers operate |
| 39 | 42 | on a vendor level, responsible for multiple product lines. For several reasons, |
| @@ -43,14 +46,43 @@ MAINTAINERS file. · 3 unmodified lines | ||
| 43 | 46 | |
| 44 | 47 | Most of these submaintainers have their own trees where they stage patches, |
| 45 | 48 | sending pull requests to the main SoC tree. These trees are usually, but not |
| 46 | −always, listed in MAINTAINERS. The main SoC maintainers can be reached via the | |
| 47 | −alias soc@kernel.org if there is no platform-specific maintainer, or if they | |
| 48 | −are unresponsive. | |
| 49 | +always, listed in MAINTAINERS. | |
| 49 | 50 | |
| 50 | 51 | What the SoC tree is not, however, is a location for architecture-specific code |
| 51 | 52 | changes. Each architecture has its own maintainers that are responsible for |
| 52 | 53 | architectural details, CPU errata and the like. |
| 53 | 54 | |
| 55 | +Submitting Patches for Given SoC | |
| 56 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 57 | + | |
| 58 | +All typical platform related patches should be sent via SoC submaintainers | |
| 59 | +(platform-specific maintainers). This includes also changes to per-platform or | |
| 60 | +shared defconfigs (scripts/get_maintainer.pl might not provide correct | |
| 61 | +addresses in such case). | |
| 62 | + | |
| 63 | +Submitting Patches to the Main SoC Maintainers | |
| 64 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 65 | + | |
| 66 | +The main SoC maintainers can be reached via the alias soc@kernel.org only in | |
| 67 | +following cases: | |
| 68 | + | |
| 69 | +1. There are no platform-specific maintainers. | |
| 70 | + | |
| 71 | +2. Platform-specific maintainers are unresponsive. | |
| 72 | + | |
| 73 | +3. Introducing a completely new SoC platform. Such new SoC work should be sent | |
| 74 | + first to common mailing lists, pointed out by scripts/get_maintainer.pl, for | |
| 75 | + community review. After positive community review, work should be sent to | |
| 76 | + soc@kernel.org in one patchset containing new arch/foo/Kconfig entry, DTS | |
| 77 | + files, MAINTAINERS file entry and optionally initial drivers with their | |
| 78 | + Devicetree bindings. The MAINTAINERS file entry should list new | |
| 79 | + platform-specific maintainers, who are going to be responsible for handling | |
| 80 | + patches for the platform from now on. | |
| 81 | + | |
| 82 | +Note that the soc@kernel.org is usually not the place to discuss the patches, | |
| 83 | +thus work sent to this address should be already considered as acceptable by | |
| 84 | +the community. | |
| 85 | + | |
| 54 | 86 | Information for (new) Submaintainers |
| 55 | 87 | ------------------------------------ |
| 56 | 88 | |
| @@ -17,7 +17,7 @@ Architecture Level of support Constraints · 16 unmodified lines | ||
| 17 | 17 | ============= ================ ============================================== |
| 18 | 18 | ``arm64`` Maintained Little Endian only. |
| 19 | 19 | ``loongarch`` Maintained \- |
| 20 | −``riscv`` Maintained ``riscv64`` only. | |
| 20 | +``riscv`` Maintained ``riscv64`` and LLVM/Clang only. | |
| 21 | 21 | ``um`` Maintained \- |
| 22 | 22 | ``x86`` Maintained ``x86_64`` only. |
| 23 | 23 | ============= ================ ============================================== |
| @@ -66,7 +66,7 @@ BPF scheduler and reverts all tasks back to CFS. · 65 unmodified lines | ||
| 66 | 66 | .. code-block:: none |
| 67 | 67 | |
| 68 | 68 | # make -j16 -C tools/sched_ext |
| 69 | − # tools/sched_ext/scx_simple | |
| 69 | + # tools/sched_ext/build/bin/scx_simple | |
| 70 | 70 | local=0 global=3 |
| 71 | 71 | local=5 global=24 |
| 72 | 72 | local=9 global=44 |
| @@ -23,177 +23,166 @@ applications can additionally seal security critical data at runtime. · 22 unmodified lines | ||
| 23 | 23 | A similar feature already exists in the XNU kernel with the |
| 24 | 24 | VM_FLAGS_PERMANENT flag [1] and on OpenBSD with the mimmutable syscall [2]. |
| 25 | 25 | |
| 26 | −User API | |
| 27 | −======== | |
| 28 | −mseal() | |
| 29 | −----------- | |
| 30 | −The mseal() syscall has the following signature: | |
| 31 | − | |
| 32 | −``int mseal(void addr, size_t len, unsigned long flags)`` | |
| 33 | − | |
| 34 | −**addr/len**: virtual memory address range. | |
| 35 | − | |
| 36 | −The address range set by ``addr``/``len`` must meet: | |
| 37 | − - The start address must be in an allocated VMA. | |
| 38 | − - The start address must be page aligned. | |
| 39 | − - The end address (``addr`` + ``len``) must be in an allocated VMA. | |
| 40 | − - no gap (unallocated memory) between start and end address. | |
| 41 | − | |
| 42 | −The ``len`` will be paged aligned implicitly by the kernel. | |
| 43 | − | |
| 44 | −**flags**: reserved for future use. | |
| 45 | − | |
| 46 | −**return values**: | |
| 47 | − | |
| 48 | −- ``0``: Success. | |
| 49 | − | |
| 50 | −- ``-EINVAL``: | |
| 51 | − - Invalid input ``flags``. | |
| 52 | − - The start address (``addr``) is not page aligned. | |
| 53 | − - Address range (``addr`` + ``len``) overflow. | |
| 54 | − | |
| 55 | −- ``-ENOMEM``: | |
| 56 | − - The start address (``addr``) is not allocated. | |
| 57 | − - The end address (``addr`` + ``len``) is not allocated. | |
| 58 | − - A gap (unallocated memory) between start and end address. | |
| 59 | − | |
| 60 | −- ``-EPERM``: | |
| 61 | − - sealing is supported only on 64-bit CPUs, 32-bit is not supported. | |
| 62 | − | |
| 63 | −- For above error cases, users can expect the given memory range is | |
| 64 | − unmodified, i.e. no partial update. | |
| 65 | − | |
| 66 | −- There might be other internal errors/cases not listed here, e.g. | |
| 67 | − error during merging/splitting VMAs, or the process reaching the max | |
| 68 | − number of supported VMAs. In those cases, partial updates to the given | |
| 69 | − memory range could happen. However, those cases should be rare. | |
| 70 | − | |
| 71 | −**Blocked operations after sealing**: | |
| 72 | − Unmapping, moving to another location, and shrinking the size, | |
| 73 | − via munmap() and mremap(), can leave an empty space, therefore | |
| 74 | − can be replaced with a VMA with a new set of attributes. | |
| 75 | − | |
| 76 | − Moving or expanding a different VMA into the current location, | |
| 77 | − via mremap(). | |
| 78 | − | |
| 79 | − Modifying a VMA via mmap(MAP_FIXED). | |
| 80 | − | |
| 81 | − Size expansion, via mremap(), does not appear to pose any | |
| 82 | − specific risks to sealed VMAs. It is included anyway because | |
| 83 | − the use case is unclear. In any case, users can rely on | |
| 84 | − merging to expand a sealed VMA. | |
| 85 | − | |
| 86 | − mprotect() and pkey_mprotect(). | |
| 87 | − | |
| 88 | − Some destructive madvice() behaviors (e.g. MADV_DONTNEED) | |
| 89 | − for anonymous memory, when users don't have write permission to the | |
| 90 | − memory. Those behaviors can alter region contents by discarding pages, | |
| 91 | − effectively a memset(0) for anonymous memory. | |
| 92 | − | |
| 93 | − Kernel will return -EPERM for blocked operations. | |
| 94 | − | |
| 95 | − For blocked operations, one can expect the given address is unmodified, | |
| 96 | − i.e. no partial update. Note, this is different from existing mm | |
| 97 | − system call behaviors, where partial updates are made till an error is | |
| 98 | − found and returned to userspace. To give an example: | |
| 99 | − | |
| 100 | − Assume following code sequence: | |
| 101 | − | |
| 102 | − - ptr = mmap(null, 8192, PROT_NONE); | |
| 103 | − - munmap(ptr + 4096, 4096); | |
| 104 | − - ret1 = mprotect(ptr, 8192, PROT_READ); | |
| 105 | − - mseal(ptr, 4096); | |
| 106 | − - ret2 = mprotect(ptr, 8192, PROT_NONE); | |
| 107 | − | |
| 108 | − ret1 will be -ENOMEM, the page from ptr is updated to PROT_READ. | |
| 109 | − | |
| 110 | − ret2 will be -EPERM, the page remains to be PROT_READ. | |
| 111 | − | |
| 112 | −**Note**: | |
| 113 | − | |
| 114 | −- mseal() only works on 64-bit CPUs, not 32-bit CPU. | |
| 115 | − | |
| 116 | −- users can call mseal() multiple times, mseal() on an already sealed memory | |
| 117 | − is a no-action (not error). | |
| 118 | − | |
| 119 | −- munseal() is not supported. | |
| 120 | − | |
| 121 | −Use cases: | |
| 122 | −========== | |
| 26 | +SYSCALL | |
| 27 | +======= | |
| 28 | +mseal syscall signature | |
| 29 | +----------------------- | |
| 30 | + ``int mseal(void \* addr, size_t len, unsigned long flags)`` | |
| 31 | + | |
| 32 | + **addr**/**len**: virtual memory address range. | |
| 33 | + The address range set by **addr**/**len** must meet: | |
| 34 | + - The start address must be in an allocated VMA. | |
| 35 | + - The start address must be page aligned. | |
| 36 | + - The end address (**addr** + **len**) must be in an allocated VMA. | |
| 37 | + - no gap (unallocated memory) between start and end address. | |
| 38 | + | |
| 39 | + The ``len`` will be paged aligned implicitly by the kernel. | |
| 40 | + | |
| 41 | + **flags**: reserved for future use. | |
| 42 | + | |
| 43 | + **Return values**: | |
| 44 | + - **0**: Success. | |
| 45 | + - **-EINVAL**: | |
| 46 | + * Invalid input ``flags``. | |
| 47 | + * The start address (``addr``) is not page aligned. | |
| 48 | + * Address range (``addr`` + ``len``) overflow. | |
| 49 | + - **-ENOMEM**: | |
| 50 | + * The start address (``addr``) is not allocated. | |
| 51 | + * The end address (``addr`` + ``len``) is not allocated. | |
| 52 | + * A gap (unallocated memory) between start and end address. | |
| 53 | + - **-EPERM**: | |
| 54 | + * sealing is supported only on 64-bit CPUs, 32-bit is not supported. | |
| 55 | + | |
| 56 | + **Note about error return**: | |
| 57 | + - For above error cases, users can expect the given memory range is | |
| 58 | + unmodified, i.e. no partial update. | |
| 59 | + - There might be other internal errors/cases not listed here, e.g. | |
| 60 | + error during merging/splitting VMAs, or the process reaching the maximum | |
| 61 | + number of supported VMAs. In those cases, partial updates to the given | |
| 62 | + memory range could happen. However, those cases should be rare. | |
| 63 | + | |
| 64 | + **Architecture support**: | |
| 65 | + mseal only works on 64-bit CPUs, not 32-bit CPUs. | |
| 66 | + | |
| 67 | + **Idempotent**: | |
| 68 | + users can call mseal multiple times. mseal on an already sealed memory | |
| 69 | + is a no-action (not error). | |
| 70 | + | |
| 71 | + **no munseal** | |
| 72 | + Once mapping is sealed, it can't be unsealed. The kernel should never | |
| 73 | + have munseal, this is consistent with other sealing feature, e.g. | |
| 74 | + F_SEAL_SEAL for file. | |
| 75 | + | |
| 76 | +Blocked mm syscall for sealed mapping | |
| 77 | +------------------------------------- | |
| 78 | + It might be important to note: **once the mapping is sealed, it will | |
| 79 | + stay in the process's memory until the process terminates**. | |
| 80 | + | |
| 81 | + Example:: | |
| 82 | + | |
| 83 | + *ptr = mmap(0, 4096, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); | |
| 84 | + rc = mseal(ptr, 4096, 0); | |
| 85 | + /* munmap will fail */ | |
| 86 | + rc = munmap(ptr, 4096); | |
| 87 | + assert(rc < 0); | |
| 88 | + | |
| 89 | + Blocked mm syscall: | |
| 90 | + - munmap | |
| 91 | + - mmap | |
| 92 | + - mremap | |
| 93 | + - mprotect and pkey_mprotect | |
| 94 | + - some destructive madvise behaviors: MADV_DONTNEED, MADV_FREE, | |
| 95 | + MADV_DONTNEED_LOCKED, MADV_FREE, MADV_DONTFORK, MADV_WIPEONFORK | |
| 96 | + | |
| 97 | + The first set of syscalls to block is munmap, mremap, mmap. They can | |
| 98 | + either leave an empty space in the address space, therefore allowing | |
| 99 | + replacement with a new mapping with new set of attributes, or can | |
| 100 | + overwrite the existing mapping with another mapping. | |
| 101 | + | |
| 102 | + mprotect and pkey_mprotect are blocked because they changes the | |
| 103 | + protection bits (RWX) of the mapping. | |
| 104 | + | |
| 105 | + Certain destructive madvise behaviors, specifically MADV_DONTNEED, | |
| 106 | + MADV_FREE, MADV_DONTNEED_LOCKED, and MADV_WIPEONFORK, can introduce | |
| 107 | + risks when applied to anonymous memory by threads lacking write | |
| 108 | + permissions. Consequently, these operations are prohibited under such | |
| 109 | + conditions. The aforementioned behaviors have the potential to modify | |
| 110 | + region contents by discarding pages, effectively performing a memset(0) | |
| 111 | + operation on the anonymous memory. | |
| 112 | + | |
| 113 | + Kernel will return -EPERM for blocked syscalls. | |
| 114 | + | |
| 115 | + When blocked syscall return -EPERM due to sealing, the memory regions may | |
| 116 | + or may not be changed, depends on the syscall being blocked: | |
| 117 | + | |
| 118 | + - munmap: munmap is atomic. If one of VMAs in the given range is | |
| 119 | + sealed, none of VMAs are updated. | |
| 120 | + - mprotect, pkey_mprotect, madvise: partial update might happen, e.g. | |
| 121 | + when mprotect over multiple VMAs, mprotect might update the beginning | |
| 122 | + VMAs before reaching the sealed VMA and return -EPERM. | |
| 123 | + - mmap and mremap: undefined behavior. | |
| 124 | + | |
| 125 | +Use cases | |
| 126 | +========= | |
| 123 | 127 | - glibc: |
| 124 | 128 | The dynamic linker, during loading ELF executables, can apply sealing to |
| 125 | − non-writable memory segments. | |
| 126 | − | |
| 127 | −- Chrome browser: protect some security sensitive data-structures. | |
| 129 | + mapping segments. | |
| 128 | 130 | |
| 129 | −Notes on which memory to seal: | |
| 130 | −============================== | |
| 131 | +- Chrome browser: protect some security sensitive data structures. | |
| 131 | 132 | |
| 132 | −It might be important to note that sealing changes the lifetime of a mapping, | |
| 133 | −i.e. the sealed mapping won’t be unmapped till the process terminates or the | |
| 134 | −exec system call is invoked. Applications can apply sealing to any virtual | |
| 135 | −memory region from userspace, but it is crucial to thoroughly analyze the | |
| 136 | −mapping's lifetime prior to apply the sealing. | |
| 133 | +When not to use mseal | |
| 134 | +===================== | |
| 135 | +Applications can apply sealing to any virtual memory region from userspace, | |
| 136 | +but it is *crucial to thoroughly analyze the mapping's lifetime* prior to | |
| 137 | +apply the sealing. This is because the sealed mapping *won’t be unmapped* | |
| 138 | +until the process terminates or the exec system call is invoked. | |
| 137 | 139 | |
| 138 | 140 | For example: |
| 141 | + - aio/shm | |
| 142 | + aio/shm can call mmap and munmap on behalf of userspace, e.g. | |
| 143 | + ksys_shmdt() in shm.c. The lifetimes of those mapping are not tied to | |
| 144 | + the lifetime of the process. If those memories are sealed from userspace, | |
| 145 | + then munmap will fail, causing leaks in VMA address space during the | |
| 146 | + lifetime of the process. | |
| 147 | + | |
| 148 | + - ptr allocated by malloc (heap) | |
| 149 | + Don't use mseal on the memory ptr return from malloc(). | |
| 150 | + malloc() is implemented by allocator, e.g. by glibc. Heap manager might | |
| 151 | + allocate a ptr from brk or mapping created by mmap. | |
| 152 | + If an app calls mseal on a ptr returned from malloc(), this can affect | |
| 153 | + the heap manager's ability to manage the mappings; the outcome is | |
| 154 | + non-deterministic. | |
| 155 | + | |
| 156 | + Example:: | |
| 157 | + | |
| 158 | + ptr = malloc(size); | |
| 159 | + /* don't call mseal on ptr return from malloc. */ | |
| 160 | + mseal(ptr, size); | |
| 161 | + /* free will success, allocator can't shrink heap lower than ptr */ | |
| 162 | + free(ptr); | |
| 163 | + | |
| 164 | +mseal doesn't block | |
| 165 | +=================== | |
| 166 | +In a nutshell, mseal blocks certain mm syscall from modifying some of VMA's | |
| 167 | +attributes, such as protection bits (RWX). Sealed mappings doesn't mean the | |
| 168 | +memory is immutable. | |
| 139 | 169 | |
| 140 | −- aio/shm | |
| 141 | − | |
| 142 | − aio/shm can call mmap()/munmap() on behalf of userspace, e.g. ksys_shmdt() in | |
| 143 | − shm.c. The lifetime of those mapping are not tied to the lifetime of the | |
| 144 | − process. If those memories are sealed from userspace, then munmap() will fail, | |
| 145 | − causing leaks in VMA address space during the lifetime of the process. | |
| 146 | − | |
| 147 | −- Brk (heap) | |
| 148 | − | |
| 149 | − Currently, userspace applications can seal parts of the heap by calling | |
| 150 | − malloc() and mseal(). | |
| 151 | − let's assume following calls from user space: | |
| 152 | − | |
| 153 | − - ptr = malloc(size); | |
| 154 | − - mprotect(ptr, size, RO); | |
| 155 | − - mseal(ptr, size); | |
| 156 | − - free(ptr); | |
| 157 | − | |
| 158 | − Technically, before mseal() is added, the user can change the protection of | |
| 159 | − the heap by calling mprotect(RO). As long as the user changes the protection | |
| 160 | − back to RW before free(), the memory range can be reused. | |
| 161 | − | |
| 162 | − Adding mseal() into the picture, however, the heap is then sealed partially, | |
| 163 | − the user can still free it, but the memory remains to be RO. If the address | |
| 164 | − is re-used by the heap manager for another malloc, the process might crash | |
| 165 | − soon after. Therefore, it is important not to apply sealing to any memory | |
| 166 | − that might get recycled. | |
| 167 | − | |
| 168 | − Furthermore, even if the application never calls the free() for the ptr, | |
| 169 | − the heap manager may invoke the brk system call to shrink the size of the | |
| 170 | − heap. In the kernel, the brk-shrink will call munmap(). Consequently, | |
| 171 | − depending on the location of the ptr, the outcome of brk-shrink is | |
| 172 | − nondeterministic. | |
| 173 | − | |
| 174 | − | |
| 175 | −Additional notes: | |
| 176 | −================= | |
| 177 | 170 | As Jann Horn pointed out in [3], there are still a few ways to write |
| 178 | −to RO memory, which is, in a way, by design. Those cases are not covered | |
| 179 | −by mseal(). If applications want to block such cases, sandbox tools (such as | |
| 180 | −seccomp, LSM, etc) might be considered. | |
| 171 | +to RO memory, which is, in a way, by design. And those could be blocked | |
| 172 | +by different security measures. | |
| 181 | 173 | |
| 182 | 174 | Those cases are: |
| 183 | 175 | |
| 184 | −- Write to read-only memory through /proc/self/mem interface. | |
| 185 | −- Write to read-only memory through ptrace (such as PTRACE_POKETEXT). | |
| 186 | −- userfaultfd. | |
| 176 | + - Write to read-only memory through /proc/self/mem interface (FOLL_FORCE). | |
| 177 | + - Write to read-only memory through ptrace (such as PTRACE_POKETEXT). | |
| 178 | + - userfaultfd. | |
| 187 | 179 | |
| 188 | 180 | The idea that inspired this patch comes from Stephen Röttger’s work in V8 |
| 189 | 181 | CFI [4]. Chrome browser in ChromeOS will be the first user of this API. |
| 190 | 182 | |
| 191 | −Reference: | |
| 192 | −========== | |
| 193 | −[1] https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/osfmk/mach/vm_statistics.h#L274 | |
| 194 | − | |
| 195 | −[2] https://man.openbsd.org/mimmutable.2 | |
| 196 | − | |
| 197 | −[3] https://lore.kernel.org/lkml/CAG48ez3ShUYey+ZAFsU2i1RpQn0a5eOs2hzQ426FkcgnfUGLvA@mail.gmail.com | |
| 198 | − | |
| 199 | −[4] https://docs.google.com/document/d/1O2jwK4dxI3nRcOJuPYkonhTkNQfbmwdvxQMyXgeaRHo/edit#heading=h.bvaojj9fu6hc | |
| 183 | +Reference | |
| 184 | +========= | |
| 185 | +- [1] https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/osfmk/mach/vm_statistics.h#L274 | |
| 186 | +- [2] https://man.openbsd.org/mimmutable.2 | |
| 187 | +- [3] https://lore.kernel.org/lkml/CAG48ez3ShUYey+ZAFsU2i1RpQn0a5eOs2hzQ426FkcgnfUGLvA@mail.gmail.com | |
| 188 | +- [4] https://docs.google.com/document/d/1O2jwK4dxI3nRcOJuPYkonhTkNQfbmwdvxQMyXgeaRHo/edit#heading=h.bvaojj9fu6hc | |
| @@ -8098,13 +8098,15 @@ KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS By default, KVM emulates MONITOR/MWAIT (if · 8097 unmodified lines | ||
| 8098 | 8098 | KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT is |
| 8099 | 8099 | disabled. |
| 8100 | 8100 | |
| 8101 | −KVM_X86_QUIRK_SLOT_ZAP_ALL By default, KVM invalidates all SPTEs in | |
| 8102 | − fast way for memslot deletion when VM type | |
| 8103 | − is KVM_X86_DEFAULT_VM. | |
| 8104 | − When this quirk is disabled or when VM type | |
| 8105 | − is other than KVM_X86_DEFAULT_VM, KVM zaps | |
| 8106 | − only leaf SPTEs that are within the range of | |
| 8107 | − the memslot being deleted. | |
| 8101 | +KVM_X86_QUIRK_SLOT_ZAP_ALL By default, for KVM_X86_DEFAULT_VM VMs, KVM | |
| 8102 | + invalidates all SPTEs in all memslots and | |
| 8103 | + address spaces when a memslot is deleted or | |
| 8104 | + moved. When this quirk is disabled (or the | |
| 8105 | + VM type isn't KVM_X86_DEFAULT_VM), KVM only | |
| 8106 | + ensures the backing memory of the deleted | |
| 8107 | + or moved memslot isn't reachable, i.e KVM | |
| 8108 | + _may_ invalidate only SPTEs related to the | |
| 8109 | + memslot. | |
| 8108 | 8110 | =================================== ============================================ |
| 8109 | 8111 | |
| 8110 | 8112 | 7.32 KVM_CAP_MAX_VCPU_ID |
| @@ -136,7 +136,7 @@ For direct sp, we can easily avoid it since the spte of direct sp is fixed · 135 unmodified lines | ||
| 136 | 136 | to gfn. For indirect sp, we disabled fast page fault for simplicity. |
| 137 | 137 | |
| 138 | 138 | A solution for indirect sp could be to pin the gfn, for example via |
| 139 | −kvm_vcpu_gfn_to_pfn_atomic, before the cmpxchg. After the pinning: | |
| 139 | +gfn_to_pfn_memslot_atomic, before the cmpxchg. After the pinning: | |
| 140 | 140 | |
| 141 | 141 | - We have held the refcount of pfn; that means the pfn can not be freed and |
| 142 | 142 | be reused for another gfn. |
| @@ -258,12 +258,6 @@ L: linux-acenic@sunsite.dk · 257 unmodified lines | ||
| 258 | 258 | S: Maintained |
| 259 | 259 | F: drivers/net/ethernet/alteon/acenic* |
| 260 | 260 | |
| 261 | −ACER ASPIRE 1 EMBEDDED CONTROLLER DRIVER | |
| 262 | −M: Nikita Travkin <nikita@trvn.ru> | |
| 263 | −S: Maintained | |
| 264 | −F: Documentation/devicetree/bindings/platform/acer,aspire1-ec.yaml | |
| 265 | −F: drivers/platform/arm64/acer-aspire1-ec.c | |
| 266 | − | |
| 267 | 261 | ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER |
| 268 | 262 | M: Peter Kaestle <peter@piie.net> |
| 269 | 263 | L: platform-driver-x86@vger.kernel.org |
| @@ -888,7 +882,6 @@ F: drivers/staging/media/sunxi/cedrus/ · 618 unmodified lines | ||
| 888 | 882 | |
| 889 | 883 | ALPHA PORT |
| 890 | 884 | M: Richard Henderson <richard.henderson@linaro.org> |
| 891 | −M: Ivan Kokshaysky <ink@jurassic.park.msu.ru> | |
| 892 | 885 | M: Matt Turner <mattst88@gmail.com> |
| 893 | 886 | L: linux-alpha@vger.kernel.org |
| 894 | 887 | S: Odd Fixes |
| @@ -1761,8 +1754,8 @@ F: include/uapi/linux/if_arcnet.h · 866 unmodified lines | ||
| 1761 | 1754 | ARM AND ARM64 SoC SUB-ARCHITECTURES (COMMON PARTS) |
| 1762 | 1755 | M: Arnd Bergmann <arnd@arndb.de> |
| 1763 | 1756 | M: Olof Johansson <olof@lixom.net> |
| 1764 | −M: soc@kernel.org | |
| 1765 | 1757 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1758 | +L: soc@lists.linux.dev | |
| 1766 | 1759 | S: Maintained |
| 1767 | 1760 | P: Documentation/process/maintainer-soc.rst |
| 1768 | 1761 | C: irc://irc.libera.chat/armlinux |
| @@ -2263,12 +2256,6 @@ L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) · 494 unmodified lines | ||
| 2263 | 2256 | S: Maintained |
| 2264 | 2257 | F: arch/arm/mach-ep93xx/ts72xx.c |
| 2265 | 2258 | |
| 2266 | −ARM/CIRRUS LOGIC CLPS711X ARM ARCHITECTURE | |
| 2267 | −M: Alexander Shiyan <shc_work@mail.ru> | |
| 2268 | −L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | |
| 2269 | −S: Odd Fixes | |
| 2270 | −N: clps711x | |
| 2271 | − | |
| 2272 | 2259 | ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE |
| 2273 | 2260 | M: Hartley Sweeten <hsweeten@visionengravers.com> |
| 2274 | 2261 | M: Alexander Sverdlin <alexander.sverdlin@gmail.com> |
| @@ -3815,14 +3802,6 @@ F: drivers/video/backlight/ · 1540 unmodified lines | ||
| 3815 | 3802 | F: include/linux/backlight.h |
| 3816 | 3803 | F: include/linux/pwm_backlight.h |
| 3817 | 3804 | |
| 3818 | −BAIKAL-T1 PVT HARDWARE MONITOR DRIVER | |
| 3819 | −M: Serge Semin <fancer.lancer@gmail.com> | |
| 3820 | −L: linux-hwmon@vger.kernel.org | |
| 3821 | −S: Supported | |
| 3822 | −F: Documentation/devicetree/bindings/hwmon/baikal,bt1-pvt.yaml | |
| 3823 | −F: Documentation/hwmon/bt1-pvt.rst | |
| 3824 | −F: drivers/hwmon/bt1-pvt.[ch] | |
| 3825 | − | |
| 3826 | 3805 | BARCO P50 GPIO DRIVER |
| 3827 | 3806 | M: Santosh Kumar Yadav <santoshkumar.yadav@barco.com> |
| 3828 | 3807 | M: Peter Korsgaard <peter.korsgaard@barco.com> |
| @@ -6476,7 +6455,6 @@ F: drivers/mtd/nand/raw/denali* · 2647 unmodified lines | ||
| 6476 | 6455 | |
| 6477 | 6456 | DESIGNWARE EDMA CORE IP DRIVER |
| 6478 | 6457 | M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
| 6479 | −R: Serge Semin <fancer.lancer@gmail.com> | |
| 6480 | 6458 | L: dmaengine@vger.kernel.org |
| 6481 | 6459 | S: Maintained |
| 6482 | 6460 | F: drivers/dma/dw-edma/ |
| @@ -9757,6 +9735,7 @@ F: include/dt-bindings/gpio/ · 3274 unmodified lines | ||
| 9757 | 9735 | F: include/linux/gpio.h |
| 9758 | 9736 | F: include/linux/gpio/ |
| 9759 | 9737 | F: include/linux/of_gpio.h |
| 9738 | +K: (devm_)?gpio_(request|free|direction|get|set) | |
| 9760 | 9739 | |
| 9761 | 9740 | GPIO UAPI |
| 9762 | 9741 | M: Bartosz Golaszewski <brgl@bgdev.pl> |
| @@ -9771,14 +9750,6 @@ F: drivers/gpio/gpiolib-cdev.c · 8 unmodified lines | ||
| 9771 | 9750 | F: include/uapi/linux/gpio.h |
| 9772 | 9751 | F: tools/gpio/ |
| 9773 | 9752 | |
| 9774 | −GRE DEMULTIPLEXER DRIVER | |
| 9775 | −M: Dmitry Kozlov <xeb@mail.ru> | |
| 9776 | −L: netdev@vger.kernel.org | |
| 9777 | −S: Maintained | |
| 9778 | −F: include/net/gre.h | |
| 9779 | −F: net/ipv4/gre_demux.c | |
| 9780 | −F: net/ipv4/gre_offload.c | |
| 9781 | − | |
| 9782 | 9753 | GRETH 10/100/1G Ethernet MAC device driver |
| 9783 | 9754 | M: Andreas Larsson <andreas@gaisler.com> |
| 9784 | 9755 | L: netdev@vger.kernel.org |
| @@ -10282,7 +10253,7 @@ F: Documentation/devicetree/bindings/arm/hisilicon/low-pin-count.yaml · 497 unmodified lines | ||
| 10282 | 10253 | F: drivers/bus/hisi_lpc.c |
| 10283 | 10254 | |
| 10284 | 10255 | HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3) |
| 10285 | −M: Yisen Zhuang <yisen.zhuang@huawei.com> | |
| 10256 | +M: Jian Shen <shenjian15@huawei.com> | |
| 10286 | 10257 | M: Salil Mehta <salil.mehta@huawei.com> |
| 10287 | 10258 | M: Jijie Shao <shaojijie@huawei.com> |
| 10288 | 10259 | L: netdev@vger.kernel.org |
| @@ -10291,7 +10262,7 @@ W: http://www.hisilicon.com · 2 unmodified lines | ||
| 10291 | 10262 | F: drivers/net/ethernet/hisilicon/hns3/ |
| 10292 | 10263 | |
| 10293 | 10264 | HISILICON NETWORK SUBSYSTEM DRIVER |
| 10294 | −M: Yisen Zhuang <yisen.zhuang@huawei.com> | |
| 10265 | +M: Jian Shen <shenjian15@huawei.com> | |
| 10295 | 10266 | M: Salil Mehta <salil.mehta@huawei.com> |
| 10296 | 10267 | L: netdev@vger.kernel.org |
| 10297 | 10268 | S: Maintained |
| @@ -11295,10 +11266,10 @@ F: security/integrity/ · 997 unmodified lines | ||
| 11295 | 11266 | F: security/integrity/ima/ |
| 11296 | 11267 | |
| 11297 | 11268 | INTEGRITY POLICY ENFORCEMENT (IPE) |
| 11298 | −M: Fan Wu <wufan@linux.microsoft.com> | |
| 11269 | +M: Fan Wu <wufan@kernel.org> | |
| 11299 | 11270 | L: linux-security-module@vger.kernel.org |
| 11300 | 11271 | S: Supported |
| 11301 | −T: git https://github.com/microsoft/ipe.git | |
| 11272 | +T: git git://git.kernel.org/pub/scm/linux/kernel/git/wufan/ipe.git | |
| 11302 | 11273 | F: Documentation/admin-guide/LSM/ipe.rst |
| 11303 | 11274 | F: Documentation/security/ipe.rst |
| 11304 | 11275 | F: scripts/ipe/ |
| @@ -11616,6 +11587,16 @@ F: drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c · 311 unmodified lines | ||
| 11616 | 11587 | F: drivers/crypto/intel/keembay/ocs-hcu.c |
| 11617 | 11588 | F: drivers/crypto/intel/keembay/ocs-hcu.h |
| 11618 | 11589 | |
| 11590 | +INTEL LA JOLLA COVE ADAPTER (LJCA) USB I/O EXPANDER DRIVERS | |
| 11591 | +M: Wentong Wu <wentong.wu@intel.com> | |
| 11592 | +M: Sakari Ailus <sakari.ailus@linux.intel.com> | |
| 11593 | +S: Maintained | |
| 11594 | +F: drivers/gpio/gpio-ljca.c | |
| 11595 | +F: drivers/i2c/busses/i2c-ljca.c | |
| 11596 | +F: drivers/spi/spi-ljca.c | |
| 11597 | +F: drivers/usb/misc/usb-ljca.c | |
| 11598 | +F: include/linux/usb/ljca.h | |
| 11599 | + | |
| 11619 | 11600 | INTEL MANAGEMENT ENGINE (mei) |
| 11620 | 11601 | M: Tomas Winkler <tomas.winkler@intel.com> |
| 11621 | 11602 | L: linux-kernel@vger.kernel.org |
| @@ -12254,6 +12235,7 @@ R: Dmitry Vyukov <dvyukov@google.com> · 632 unmodified lines | ||
| 12254 | 12235 | R: Vincenzo Frascino <vincenzo.frascino@arm.com> |
| 12255 | 12236 | L: kasan-dev@googlegroups.com |
| 12256 | 12237 | S: Maintained |
| 12238 | +B: https://bugzilla.kernel.org/buglist.cgi?component=Sanitizers&product=Memory%20Management | |
| 12257 | 12239 | F: Documentation/dev-tools/kasan.rst |
| 12258 | 12240 | F: arch/*/include/asm/*kasan.h |
| 12259 | 12241 | F: arch/*/mm/kasan_init* |
| @@ -12277,6 +12259,7 @@ R: Dmitry Vyukov <dvyukov@google.com> · 17 unmodified lines | ||
| 12277 | 12259 | R: Andrey Konovalov <andreyknvl@gmail.com> |
| 12278 | 12260 | L: kasan-dev@googlegroups.com |
| 12279 | 12261 | S: Maintained |
| 12262 | +B: https://bugzilla.kernel.org/buglist.cgi?component=Sanitizers&product=Memory%20Management | |
| 12280 | 12263 | F: Documentation/dev-tools/kcov.rst |
| 12281 | 12264 | F: include/linux/kcov.h |
| 12282 | 12265 | F: include/uapi/linux/kcov.h |
| @@ -12956,49 +12939,29 @@ LIBATA PATA ARASAN COMPACT FLASH CONTROLLER · 673 unmodified lines | ||
| 12956 | 12939 | M: Viresh Kumar <vireshk@kernel.org> |
| 12957 | 12940 | L: linux-ide@vger.kernel.org |
| 12958 | 12941 | S: Maintained |
| 12959 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | |
| 12960 | 12942 | F: drivers/ata/pata_arasan_cf.c |
| 12961 | 12943 | F: include/linux/pata_arasan_cf_data.h |
| 12962 | 12944 | |
| 12963 | −LIBATA PATA DRIVERS | |
| 12964 | −R: Sergey Shtylyov <s.shtylyov@omp.ru> | |
| 12965 | −L: linux-ide@vger.kernel.org | |
| 12966 | −F: drivers/ata/ata_*.c | |
| 12967 | −F: drivers/ata/pata_*.c | |
| 12968 | − | |
| 12969 | 12945 | LIBATA PATA FARADAY FTIDE010 AND GEMINI SATA BRIDGE DRIVERS |
| 12970 | 12946 | M: Linus Walleij <linus.walleij@linaro.org> |
| 12971 | 12947 | L: linux-ide@vger.kernel.org |
| 12972 | 12948 | S: Maintained |
| 12973 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | |
| 12974 | 12949 | F: drivers/ata/pata_ftide010.c |
| 12975 | 12950 | F: drivers/ata/sata_gemini.c |
| 12976 | 12951 | F: drivers/ata/sata_gemini.h |
| 12977 | 12952 | |
| 12978 | 12953 | LIBATA SATA AHCI PLATFORM devices support |
| 12979 | 12954 | M: Hans de Goede <hdegoede@redhat.com> |
| 12980 | −M: Jens Axboe <axboe@kernel.dk> | |
| 12981 | 12955 | L: linux-ide@vger.kernel.org |
| 12982 | 12956 | S: Maintained |
| 12983 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | |
| 12984 | 12957 | F: drivers/ata/ahci_platform.c |
| 12985 | 12958 | F: drivers/ata/libahci_platform.c |
| 12986 | 12959 | F: include/linux/ahci_platform.h |
| 12987 | 12960 | |
| 12988 | −LIBATA SATA AHCI SYNOPSYS DWC CONTROLLER DRIVER | |
| 12989 | −M: Serge Semin <fancer.lancer@gmail.com> | |
| 12990 | −L: linux-ide@vger.kernel.org | |
| 12991 | −S: Maintained | |
| 12992 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/dlemoal/libata.git | |
| 12993 | −F: Documentation/devicetree/bindings/ata/baikal,bt1-ahci.yaml | |
| 12994 | −F: Documentation/devicetree/bindings/ata/snps,dwc-ahci.yaml | |
| 12995 | −F: drivers/ata/ahci_dwc.c | |
| 12996 | − | |
| 12997 | 12961 | LIBATA SATA PROMISE TX2/TX4 CONTROLLER DRIVER |
| 12998 | 12962 | M: Mikael Pettersson <mikpelinux@gmail.com> |
| 12999 | 12963 | L: linux-ide@vger.kernel.org |
| 13000 | 12964 | S: Maintained |
| 13001 | −T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | |
| 13002 | 12965 | F: drivers/ata/sata_promise.* |
| 13003 | 12966 | |
| 13004 | 12967 | LIBATA SUBSYSTEM (Serial and Parallel ATA drivers) |
| @@ -14191,8 +14154,7 @@ T: git git://linuxtv.org/media_tree.git · 1186 unmodified lines | ||
| 14191 | 14154 | F: drivers/media/platform/nxp/imx-pxp.[ch] |
| 14192 | 14155 | |
| 14193 | 14156 | MEDIA DRIVERS FOR ASCOT2E |
| 14194 | −M: Sergey Kozlov <serjk@netup.ru> | |
| 14195 | −M: Abylay Ospan <aospan@netup.ru> | |
| 14157 | +M: Abylay Ospan <aospan@amazon.com> | |
| 14196 | 14158 | L: linux-media@vger.kernel.org |
| 14197 | 14159 | S: Supported |
| 14198 | 14160 | W: https://linuxtv.org |
| @@ -14209,8 +14171,7 @@ T: git git://linuxtv.org/media_tree.git · 10 unmodified lines | ||
| 14209 | 14171 | F: drivers/media/dvb-frontends/cxd2099* |
| 14210 | 14172 | |
| 14211 | 14173 | MEDIA DRIVERS FOR CXD2841ER |
| 14212 | −M: Sergey Kozlov <serjk@netup.ru> | |
| 14213 | −M: Abylay Ospan <aospan@netup.ru> | |
| 14174 | +M: Abylay Ospan <aospan@amazon.com> | |
| 14214 | 14175 | L: linux-media@vger.kernel.org |
| 14215 | 14176 | S: Supported |
| 14216 | 14177 | W: https://linuxtv.org |
| @@ -14263,7 +14224,7 @@ F: drivers/media/platform/nxp/imx7-media-csi.c · 46 unmodified lines | ||
| 14263 | 14224 | F: drivers/media/platform/nxp/imx8mq-mipi-csi2.c |
| 14264 | 14225 | |
| 14265 | 14226 | MEDIA DRIVERS FOR HELENE |
| 14266 | −M: Abylay Ospan <aospan@netup.ru> | |
| 14227 | +M: Abylay Ospan <aospan@amazon.com> | |
| 14267 | 14228 | L: linux-media@vger.kernel.org |
| 14268 | 14229 | S: Supported |
| 14269 | 14230 | W: https://linuxtv.org |
| @@ -14272,8 +14233,7 @@ T: git git://linuxtv.org/media_tree.git · 2 unmodified lines | ||
| 14272 | 14233 | F: drivers/media/dvb-frontends/helene* |
| 14273 | 14234 | |
| 14274 | 14235 | MEDIA DRIVERS FOR HORUS3A |
| 14275 | −M: Sergey Kozlov <serjk@netup.ru> | |
| 14276 | −M: Abylay Ospan <aospan@netup.ru> | |
| 14236 | +M: Abylay Ospan <aospan@amazon.com> | |
| 14277 | 14237 | L: linux-media@vger.kernel.org |
| 14278 | 14238 | S: Supported |
| 14279 | 14239 | W: https://linuxtv.org |
| @@ -14282,8 +14242,7 @@ T: git git://linuxtv.org/media_tree.git · 2 unmodified lines | ||
| 14282 | 14242 | F: drivers/media/dvb-frontends/horus3a* |
| 14283 | 14243 | |
| 14284 | 14244 | MEDIA DRIVERS FOR LNBH25 |
| 14285 | −M: Sergey Kozlov <serjk@netup.ru> | |
| 14286 | −M: Abylay Ospan <aospan@netup.ru> | |
| 14245 | +M: Abylay Ospan <aospan@amazon.com> | |
| 14287 | 14246 | L: linux-media@vger.kernel.org |
| 14288 | 14247 | S: Supported |
| 14289 | 14248 | W: https://linuxtv.org |
| @@ -14299,8 +14258,7 @@ T: git git://linuxtv.org/media_tree.git · 9 unmodified lines | ||
| 14299 | 14258 | F: drivers/media/dvb-frontends/mxl5xx* |
| 14300 | 14259 | |
| 14301 | 14260 | MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices |
| 14302 | −M: Sergey Kozlov <serjk@netup.ru> | |
| 14303 | −M: Abylay Ospan <aospan@netup.ru> | |
| 14261 | +M: Abylay Ospan <aospan@amazon.com> | |
| 14304 | 14262 | L: linux-media@vger.kernel.org |
| 14305 | 14263 | S: Supported |
| 14306 | 14264 | W: https://linuxtv.org |
| @@ -14925,9 +14883,10 @@ N: include/linux/page[-_]* · 618 unmodified lines | ||
| 14925 | 14883 | |
| 14926 | 14884 | MEMORY MAPPING |
| 14927 | 14885 | M: Andrew Morton <akpm@linux-foundation.org> |
| 14928 | −R: Liam R. Howlett <Liam.Howlett@oracle.com> | |
| 14886 | +M: Liam R. Howlett <Liam.Howlett@oracle.com> | |
| 14887 | +M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | |
| 14929 | 14888 | R: Vlastimil Babka <vbabka@suse.cz> |
| 14930 | −R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | |
| 14889 | +R: Jann Horn <jannh@google.com> | |
| 14931 | 14890 | L: linux-mm@kvack.org |
| 14932 | 14891 | S: Maintained |
| 14933 | 14892 | W: http://www.linux-mm.org |
| @@ -14950,13 +14909,6 @@ F: drivers/mtd/ · 16 unmodified lines | ||
| 14950 | 14909 | F: include/linux/mtd/ |
| 14951 | 14910 | F: include/uapi/mtd/ |
| 14952 | 14911 | |
| 14953 | −MEMSENSING MICROSYSTEMS MSA311 DRIVER | |
| 14954 | −M: Dmitry Rokosov <ddrokosov@sberdevices.ru> | |
| 14955 | −L: linux-iio@vger.kernel.org | |
| 14956 | −S: Maintained | |
| 14957 | −F: Documentation/devicetree/bindings/iio/accel/memsensing,msa311.yaml | |
| 14958 | −F: drivers/iio/accel/msa311.c | |
| 14959 | − | |
| 14960 | 14912 | MEN A21 WATCHDOG DRIVER |
| 14961 | 14913 | M: Johannes Thumshirn <morbidrsa@gmail.com> |
| 14962 | 14914 | L: linux-watchdog@vger.kernel.org |
| @@ -15101,6 +15053,7 @@ F: drivers/spi/spi-at91-usart.c · 138 unmodified lines | ||
| 15101 | 15053 | |
| 15102 | 15054 | MICROCHIP AUDIO ASOC DRIVERS |
| 15103 | 15055 | M: Claudiu Beznea <claudiu.beznea@tuxon.dev> |
| 15056 | +M: Andrei Simion <andrei.simion@microchip.com> | |
| 15104 | 15057 | L: linux-sound@vger.kernel.org |
| 15105 | 15058 | S: Supported |
| 15106 | 15059 | F: Documentation/devicetree/bindings/sound/atmel* |
| @@ -15209,6 +15162,7 @@ F: include/video/atmel_lcdc.h · 102 unmodified lines | ||
| 15209 | 15162 | |
| 15210 | 15163 | MICROCHIP MCP16502 PMIC DRIVER |
| 15211 | 15164 | M: Claudiu Beznea <claudiu.beznea@tuxon.dev> |
| 15165 | +M: Andrei Simion <andrei.simion@microchip.com> | |
| 15212 | 15166 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 15213 | 15167 | S: Supported |
| 15214 | 15168 | F: Documentation/devicetree/bindings/regulator/microchip,mcp16502.yaml |
| @@ -15290,7 +15244,6 @@ F: drivers/tty/serial/8250/8250_pci1xxxx.c · 75 unmodified lines | ||
| 15290 | 15244 | |
| 15291 | 15245 | MICROCHIP POLARFIRE FPGA DRIVERS |
| 15292 | 15246 | M: Conor Dooley <conor.dooley@microchip.com> |
| 15293 | −R: Vladimir Georgiev <v.georgiev@metrotek.ru> | |
| 15294 | 15247 | L: linux-fpga@vger.kernel.org |
| 15295 | 15248 | S: Supported |
| 15296 | 15249 | F: Documentation/devicetree/bindings/fpga/microchip,mpf-spi-fpga-mgr.yaml |
| @@ -15340,6 +15293,7 @@ F: drivers/spi/spi-atmel.* · 43 unmodified lines | ||
| 15340 | 15293 | |
| 15341 | 15294 | MICROCHIP SSC DRIVER |
| 15342 | 15295 | M: Claudiu Beznea <claudiu.beznea@tuxon.dev> |
| 15296 | +M: Andrei Simion <andrei.simion@microchip.com> | |
| 15343 | 15297 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 15344 | 15298 | S: Supported |
| 15345 | 15299 | F: Documentation/devicetree/bindings/misc/atmel-ssc.txt |
| @@ -15545,17 +15499,6 @@ F: arch/mips/ · 199 unmodified lines | ||
| 15545 | 15499 | F: drivers/platform/mips/ |
| 15546 | 15500 | F: include/dt-bindings/mips/ |
| 15547 | 15501 | |
| 15548 | −MIPS BAIKAL-T1 PLATFORM | |
| 15549 | −M: Serge Semin <fancer.lancer@gmail.com> | |
| 15550 | −L: linux-mips@vger.kernel.org | |
| 15551 | −S: Supported | |
| 15552 | −F: Documentation/devicetree/bindings/bus/baikal,bt1-*.yaml | |
| 15553 | −F: Documentation/devicetree/bindings/clock/baikal,bt1-*.yaml | |
| 15554 | −F: drivers/bus/bt1-*.c | |
| 15555 | −F: drivers/clk/baikal-t1/ | |
| 15556 | −F: drivers/memory/bt1-l2-ctl.c | |
| 15557 | −F: drivers/mtd/maps/physmap-bt1-rom.[ch] | |
| 15558 | − | |
| 15559 | 15502 | MIPS BOSTON DEVELOPMENT BOARD |
| 15560 | 15503 | M: Paul Burton <paulburton@kernel.org> |
| 15561 | 15504 | L: linux-mips@vger.kernel.org |
| @@ -15568,7 +15511,6 @@ F: include/dt-bindings/clock/boston-clock.h · 6 unmodified lines | ||
| 15568 | 15511 | |
| 15569 | 15512 | MIPS CORE DRIVERS |
| 15570 | 15513 | M: Thomas Bogendoerfer <tsbogend@alpha.franken.de> |
| 15571 | −M: Serge Semin <fancer.lancer@gmail.com> | |
| 15572 | 15514 | L: linux-mips@vger.kernel.org |
| 15573 | 15515 | S: Supported |
| 15574 | 15516 | F: drivers/bus/mips_cdmm.c |
| @@ -16104,6 +16046,7 @@ F: include/uapi/linux/net_dropmon.h · 529 unmodified lines | ||
| 16104 | 16046 | F: net/core/drop_monitor.c |
| 16105 | 16047 | |
| 16106 | 16048 | NETWORKING DRIVERS |
| 16049 | +M: Andrew Lunn <andrew+netdev@lunn.ch> | |
| 16107 | 16050 | M: "David S. Miller" <davem@davemloft.net> |
| 16108 | 16051 | M: Eric Dumazet <edumazet@google.com> |
| 16109 | 16052 | M: Jakub Kicinski <kuba@kernel.org> |
| @@ -16169,6 +16112,7 @@ M: "David S. Miller" <davem@davemloft.net> · 59 unmodified lines | ||
| 16169 | 16112 | M: Eric Dumazet <edumazet@google.com> |
| 16170 | 16113 | M: Jakub Kicinski <kuba@kernel.org> |
| 16171 | 16114 | M: Paolo Abeni <pabeni@redhat.com> |
| 16115 | +R: Simon Horman <horms@kernel.org> | |
| 16172 | 16116 | L: netdev@vger.kernel.org |
| 16173 | 16117 | S: Maintained |
| 16174 | 16118 | P: Documentation/process/maintainer-netdev.rst |
| @@ -16211,10 +16155,22 @@ F: include/uapi/linux/rtnetlink.h · 36 unmodified lines | ||
| 16211 | 16155 | F: lib/net_utils.c |
| 16212 | 16156 | F: lib/random32.c |
| 16213 | 16157 | F: net/ |
| 16158 | +F: samples/pktgen/ | |
| 16214 | 16159 | F: tools/net/ |
| 16215 | 16160 | F: tools/testing/selftests/net/ |
| 16161 | +X: Documentation/networking/mac80211-injection.rst | |
| 16162 | +X: Documentation/networking/mac80211_hwsim/ | |
| 16163 | +X: Documentation/networking/regulatory.rst | |
| 16164 | +X: include/net/cfg80211.h | |
| 16165 | +X: include/net/ieee80211_radiotap.h | |
| 16166 | +X: include/net/iw_handler.h | |
| 16167 | +X: include/net/mac80211.h | |
| 16168 | +X: include/net/wext.h | |
| 16216 | 16169 | X: net/9p/ |
| 16217 | 16170 | X: net/bluetooth/ |
| 16171 | +X: net/mac80211/ | |
| 16172 | +X: net/rfkill/ | |
| 16173 | +X: net/wireless/ | |
| 16218 | 16174 | |
| 16219 | 16175 | NETWORKING [IPSEC] |
| 16220 | 16176 | M: Steffen Klassert <steffen.klassert@secunet.com> |
| @@ -16524,12 +16480,6 @@ F: include/linux/ntb.h · 303 unmodified lines | ||
| 16524 | 16480 | F: include/linux/ntb_transport.h |
| 16525 | 16481 | F: tools/testing/selftests/ntb/ |
| 16526 | 16482 | |
| 16527 | −NTB IDT DRIVER | |
| 16528 | −M: Serge Semin <fancer.lancer@gmail.com> | |
| 16529 | −L: ntb@lists.linux.dev | |
| 16530 | −S: Supported | |
| 16531 | −F: drivers/ntb/hw/idt/ | |
| 16532 | − | |
| 16533 | 16483 | NTB INTEL DRIVER |
| 16534 | 16484 | M: Dave Jiang <dave.jiang@intel.com> |
| 16535 | 16485 | L: ntb@lists.linux.dev |
| @@ -18550,13 +18500,6 @@ F: drivers/pps/ · 2014 unmodified lines | ||
| 18550 | 18500 | F: include/linux/pps*.h |
| 18551 | 18501 | F: include/uapi/linux/pps.h |
| 18552 | 18502 | |
| 18553 | −PPTP DRIVER | |
| 18554 | −M: Dmitry Kozlov <xeb@mail.ru> | |
| 18555 | −L: netdev@vger.kernel.org | |
| 18556 | −S: Maintained | |
| 18557 | −W: http://sourceforge.net/projects/accel-pptp | |
| 18558 | −F: drivers/net/ppp/pptp.c | |
| 18559 | − | |
| 18560 | 18503 | PRESSURE STALL INFORMATION (PSI) |
| 18561 | 18504 | M: Johannes Weiner <hannes@cmpxchg.org> |
| 18562 | 18505 | M: Suren Baghdasaryan <surenb@google.com> |
| @@ -19530,6 +19473,14 @@ S: Maintained · 967 unmodified lines | ||
| 19530 | 19473 | F: Documentation/tools/rtla/ |
| 19531 | 19474 | F: tools/tracing/rtla/ |
| 19532 | 19475 | |
| 19476 | +Real-time Linux (PREEMPT_RT) | |
| 19477 | +M: Sebastian Andrzej Siewior <bigeasy@linutronix.de> | |
| 19478 | +M: Clark Williams <clrkwllms@kernel.org> | |
| 19479 | +M: Steven Rostedt <rostedt@goodmis.org> | |
| 19480 | +L: linux-rt-devel@lists.linux.dev | |
| 19481 | +S: Supported | |
| 19482 | +K: PREEMPT_RT | |
| 19483 | + | |
| 19533 | 19484 | REALTEK AUDIO CODECS |
| 19534 | 19485 | M: Oder Chiou <oder_chiou@realtek.com> |
| 19535 | 19486 | S: Maintained |
| @@ -19639,15 +19590,6 @@ S: Supported · 103 unmodified lines | ||
| 19639 | 19590 | F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml |
| 19640 | 19591 | F: drivers/i2c/busses/i2c-emev2.c |
| 19641 | 19592 | |
| 19642 | −RENESAS ETHERNET AVB DRIVER | |
| 19643 | −R: Sergey Shtylyov <s.shtylyov@omp.ru> | |
| 19644 | −L: netdev@vger.kernel.org | |
| 19645 | −L: linux-renesas-soc@vger.kernel.org | |
| 19646 | −F: Documentation/devicetree/bindings/net/renesas,etheravb.yaml | |
| 19647 | −F: drivers/net/ethernet/renesas/Kconfig | |
| 19648 | −F: drivers/net/ethernet/renesas/Makefile | |
| 19649 | −F: drivers/net/ethernet/renesas/ravb* | |
| 19650 | − | |
| 19651 | 19593 | RENESAS ETHERNET SWITCH DRIVER |
| 19652 | 19594 | R: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
| 19653 | 19595 | L: netdev@vger.kernel.org |
| @@ -19697,14 +19639,6 @@ F: Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml · 43 unmodified lines | ||
| 19697 | 19639 | F: drivers/i2c/busses/i2c-rcar.c |
| 19698 | 19640 | F: drivers/i2c/busses/i2c-sh_mobile.c |
| 19699 | 19641 | |
| 19700 | −RENESAS R-CAR SATA DRIVER | |
| 19701 | −R: Sergey Shtylyov <s.shtylyov@omp.ru> | |
| 19702 | −L: linux-ide@vger.kernel.org | |
| 19703 | −L: linux-renesas-soc@vger.kernel.org | |
| 19704 | −S: Supported | |
| 19705 | −F: Documentation/devicetree/bindings/ata/renesas,rcar-sata.yaml | |
| 19706 | −F: drivers/ata/sata_rcar.c | |
| 19707 | − | |
| 19708 | 19642 | RENESAS R-CAR THERMAL DRIVERS |
| 19709 | 19643 | M: Niklas Söderlund <niklas.soderlund@ragnatech.se> |
| 19710 | 19644 | L: linux-renesas-soc@vger.kernel.org |
| @@ -19780,16 +19714,6 @@ S: Supported · 69 unmodified lines | ||
| 19780 | 19714 | F: Documentation/devicetree/bindings/i2c/renesas,rzv2m.yaml |
| 19781 | 19715 | F: drivers/i2c/busses/i2c-rzv2m.c |
| 19782 | 19716 | |
| 19783 | −RENESAS SUPERH ETHERNET DRIVER | |
| 19784 | −R: Sergey Shtylyov <s.shtylyov@omp.ru> | |
| 19785 | −L: netdev@vger.kernel.org | |
| 19786 | −L: linux-renesas-soc@vger.kernel.org | |
| 19787 | −F: Documentation/devicetree/bindings/net/renesas,ether.yaml | |
| 19788 | −F: drivers/net/ethernet/renesas/Kconfig | |
| 19789 | −F: drivers/net/ethernet/renesas/Makefile | |
| 19790 | −F: drivers/net/ethernet/renesas/sh_eth* | |
| 19791 | −F: include/linux/sh_eth.h | |
| 19792 | − | |
| 19793 | 19717 | RENESAS USB PHY DRIVER |
| 19794 | 19718 | M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
| 19795 | 19719 | L: linux-renesas-soc@vger.kernel.org |
| @@ -21784,8 +21708,8 @@ F: drivers/accessibility/speakup/ · 1988 unmodified lines | ||
| 21784 | 21708 | SPEAR PLATFORM/CLOCK/PINCTRL SUPPORT |
| 21785 | 21709 | M: Viresh Kumar <vireshk@kernel.org> |
| 21786 | 21710 | M: Shiraz Hashim <shiraz.linux.kernel@gmail.com> |
| 21787 | −M: soc@kernel.org | |
| 21788 | 21711 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 21712 | +L: soc@lists.linux.dev | |
| 21789 | 21713 | S: Maintained |
| 21790 | 21714 | W: http://www.st.com/spear |
| 21791 | 21715 | F: arch/arm/boot/dts/st/spear* |
| @@ -22443,19 +22367,11 @@ F: drivers/tty/serial/8250/8250_lpss.c · 651 unmodified lines | ||
| 22443 | 22367 | |
| 22444 | 22368 | SYNOPSYS DESIGNWARE APB GPIO DRIVER |
| 22445 | 22369 | M: Hoan Tran <hoan@os.amperecomputing.com> |
| 22446 | −M: Serge Semin <fancer.lancer@gmail.com> | |
| 22447 | 22370 | L: linux-gpio@vger.kernel.org |
| 22448 | 22371 | S: Maintained |
| 22449 | 22372 | F: Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml |
| 22450 | 22373 | F: drivers/gpio/gpio-dwapb.c |
| 22451 | 22374 | |
| 22452 | −SYNOPSYS DESIGNWARE APB SSI DRIVER | |
| 22453 | −M: Serge Semin <fancer.lancer@gmail.com> | |
| 22454 | −L: linux-spi@vger.kernel.org | |
| 22455 | −S: Supported | |
| 22456 | −F: Documentation/devicetree/bindings/spi/snps,dw-apb-ssi.yaml | |
| 22457 | −F: drivers/spi/spi-dw* | |
| 22458 | − | |
| 22459 | 22375 | SYNOPSYS DESIGNWARE AXI DMAC DRIVER |
| 22460 | 22376 | M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> |
| 22461 | 22377 | S: Maintained |
| @@ -23299,7 +23215,7 @@ F: Documentation/devicetree/bindings/iio/adc/ti,lmp92064.yaml · 837 unmodified lines | ||
| 23299 | 23215 | F: drivers/iio/adc/ti-lmp92064.c |
| 23300 | 23216 | |
| 23301 | 23217 | TI PCM3060 ASoC CODEC DRIVER |
| 23302 | −M: Kirill Marinushkin <kmarinushkin@birdec.com> | |
| 23218 | +M: Kirill Marinushkin <k.marinushkin@gmail.com> | |
| 23303 | 23219 | L: linux-sound@vger.kernel.org |
| 23304 | 23220 | S: Maintained |
| 23305 | 23221 | F: Documentation/devicetree/bindings/sound/pcm3060.txt |
| @@ -23765,12 +23681,6 @@ L: linux-input@vger.kernel.org · 459 unmodified lines | ||
| 23765 | 23681 | S: Maintained |
| 23766 | 23682 | F: drivers/hid/hid-udraw-ps3.c |
| 23767 | 23683 | |
| 23768 | −UFS FILESYSTEM | |
| 23769 | −M: Evgeniy Dushistov <dushistov@mail.ru> | |
| 23770 | −S: Maintained | |
| 23771 | −F: Documentation/admin-guide/ufs.rst | |
| 23772 | −F: fs/ufs/ | |
| 23773 | − | |
| 23774 | 23684 | UHID USERSPACE HID IO DRIVER |
| 23775 | 23685 | M: David Rheinsberg <david@readahead.eu> |
| 23776 | 23686 | L: linux-input@vger.kernel.org |
| @@ -24073,6 +23983,7 @@ USB RAW GADGET DRIVER · 296 unmodified lines | ||
| 24073 | 23983 | R: Andrey Konovalov <andreyknvl@gmail.com> |
| 24074 | 23984 | L: linux-usb@vger.kernel.org |
| 24075 | 23985 | S: Maintained |
| 23986 | +B: https://github.com/xairy/raw-gadget/issues | |
| 24076 | 23987 | F: Documentation/usb/raw-gadget.rst |
| 24077 | 23988 | F: drivers/usb/gadget/legacy/raw_gadget.c |
| 24078 | 23989 | F: include/uapi/linux/usb/raw_gadget.h |
| @@ -24189,8 +24100,12 @@ F: drivers/usb/host/xhci* · 110 unmodified lines | ||
| 24189 | 24100 | |
| 24190 | 24101 | USER DATAGRAM PROTOCOL (UDP) |
| 24191 | 24102 | M: Willem de Bruijn <willemdebruijn.kernel@gmail.com> |
| 24103 | +L: netdev@vger.kernel.org | |
| 24192 | 24104 | S: Maintained |
| 24193 | 24105 | F: include/linux/udp.h |
| 24106 | +F: include/net/udp.h | |
| 24107 | +F: include/trace/events/udp.h | |
| 24108 | +F: include/uapi/linux/udp.h | |
| 24194 | 24109 | F: net/ipv4/udp.c |
| 24195 | 24110 | F: net/ipv6/udp.c |
| 24196 | 24111 | |
| @@ -24741,9 +24656,10 @@ F: tools/testing/vsock/ · 544 unmodified lines | ||
| 24741 | 24656 | |
| 24742 | 24657 | VMA |
| 24743 | 24658 | M: Andrew Morton <akpm@linux-foundation.org> |
| 24744 | −R: Liam R. Howlett <Liam.Howlett@oracle.com> | |
| 24659 | +M: Liam R. Howlett <Liam.Howlett@oracle.com> | |
| 24660 | +M: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | |
| 24745 | 24661 | R: Vlastimil Babka <vbabka@suse.cz> |
| 24746 | −R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | |
| 24662 | +R: Jann Horn <jannh@google.com> | |
| 24747 | 24663 | L: linux-mm@kvack.org |
| 24748 | 24664 | S: Maintained |
| 24749 | 24665 | W: https://www.linux-mm.org |
| @@ -25417,7 +25333,7 @@ F: include/xen/arm/swiotlb-xen.h · 667 unmodified lines | ||
| 25417 | 25333 | F: include/xen/swiotlb-xen.h |
| 25418 | 25334 | |
| 25419 | 25335 | XFS FILESYSTEM |
| 25420 | −M: Chandan Babu R <chandan.babu@oracle.com> | |
| 25336 | +M: Carlos Maiolino <cem@kernel.org> | |
| 25421 | 25337 | R: Darrick J. Wong <djwong@kernel.org> |
| 25422 | 25338 | L: linux-xfs@vger.kernel.org |
| 25423 | 25339 | S: Supported |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | VERSION = 6 |
| 3 | 3 | PATCHLEVEL = 12 |
| 4 | 4 | SUBLEVEL = 0 |
| 5 | −EXTRAVERSION = -rc2 | |
| 5 | +EXTRAVERSION = -rc6 | |
| 6 | 6 | NAME = Baby Opossum Posse |
| 7 | 7 | |
| 8 | 8 | # *DOCUMENTATION* |
| @@ -838,7 +838,7 @@ config CFI_CLANG · 837 unmodified lines | ||
| 838 | 838 | config CFI_ICALL_NORMALIZE_INTEGERS |
| 839 | 839 | bool "Normalize CFI tags for integers" |
| 840 | 840 | depends on CFI_CLANG |
| 841 | − depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS | |
| 841 | + depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG | |
| 842 | 842 | help |
| 843 | 843 | This option normalizes the CFI tags for integer types so that all |
| 844 | 844 | integer types of the same size and signedness receive the same CFI |
| @@ -851,21 +851,19 @@ config CFI_ICALL_NORMALIZE_INTEGERS · 6 unmodified lines | ||
| 851 | 851 | |
| 852 | 852 | This option is necessary for using CFI with Rust. If unsure, say N. |
| 853 | 853 | |
| 854 | −config HAVE_CFI_ICALL_NORMALIZE_INTEGERS | |
| 855 | − def_bool !GCOV_KERNEL && !KASAN | |
| 856 | − depends on CFI_CLANG | |
| 854 | +config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG | |
| 855 | + def_bool y | |
| 857 | 856 | depends on $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers) |
| 858 | − help | |
| 859 | − Is CFI_ICALL_NORMALIZE_INTEGERS supported with the set of compilers | |
| 860 | − currently in use? | |
| 857 | + # With GCOV/KASAN we need this fix: https://github.com/llvm/llvm-project/pull/104826 | |
| 858 | + depends on CLANG_VERSION >= 190103 || (!GCOV_KERNEL && !KASAN_GENERIC && !KASAN_SW_TAGS) | |
| 861 | 859 | |
| 862 | − This option defaults to false if GCOV or KASAN is enabled, as there is | |
| 863 | − an LLVM bug that makes normalized integers tags incompatible with | |
| 864 | − KASAN and GCOV. Kconfig currently does not have the infrastructure to | |
| 865 | − detect whether your rustc compiler contains the fix for this bug, so | |
| 866 | − it is assumed that it doesn't. If your compiler has the fix, you can | |
| 867 | − explicitly enable this option in your config file. The Kconfig logic | |
| 868 | − needed to detect this will be added in a future kernel release. | |
| 860 | +config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC | |
| 861 | + def_bool y | |
| 862 | + depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG | |
| 863 | + depends on RUSTC_VERSION >= 107900 | |
| 864 | + # With GCOV/KASAN we need this fix: https://github.com/rust-lang/rust/pull/129373 | |
| 865 | + depends on (RUSTC_LLVM_VERSION >= 190103 && RUSTC_VERSION >= 108200) || \ | |
| 866 | + (!GCOV_KERNEL && !KASAN_GENERIC && !KASAN_SW_TAGS) | |
| 869 | 867 | |
| 870 | 868 | config CFI_PERMISSIVE |
| 871 | 869 | bool "Use CFI in permissive mode" |
| @@ -77,7 +77,7 @@ · 76 unmodified lines | ||
| 77 | 77 | }; |
| 78 | 78 | |
| 79 | 79 | &hdmi { |
| 80 | − hpd-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; | |
| 80 | + hpd-gpios = <&expgpio 0 GPIO_ACTIVE_LOW>; | |
| 81 | 81 | power-domains = <&power RPI_POWER_DOMAIN_HDMI>; |
| 82 | 82 | status = "okay"; |
| 83 | 83 | }; |
| @@ -136,7 +136,7 @@ · 135 unmodified lines | ||
| 136 | 136 | }; |
| 137 | 137 | |
| 138 | 138 | cp0_mdio_pins: cp0-mdio-pins { |
| 139 | − marvell,pins = "mpp40", "mpp41"; | |
| 139 | + marvell,pins = "mpp0", "mpp1"; | |
| 140 | 140 | marvell,function = "ge"; |
| 141 | 141 | }; |
| 142 | 142 | |
| @@ -178,6 +178,7 @@ struct kvm_nvhe_init_params { · 177 unmodified lines | ||
| 178 | 178 | unsigned long hcr_el2; |
| 179 | 179 | unsigned long vttbr; |
| 180 | 180 | unsigned long vtcr; |
| 181 | + unsigned long tmp; | |
| 181 | 182 | }; |
| 182 | 183 | |
| 183 | 184 | /* |
| @@ -51,6 +51,7 @@ · 50 unmodified lines | ||
| 51 | 51 | #define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5) |
| 52 | 52 | #define KVM_REQ_SUSPEND KVM_ARCH_REQ(6) |
| 53 | 53 | #define KVM_REQ_RESYNC_PMU_EL0 KVM_ARCH_REQ(7) |
| 54 | +#define KVM_REQ_NESTED_S2_UNMAP KVM_ARCH_REQ(8) | |
| 54 | 55 | |
| 55 | 56 | #define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ |
| 56 | 57 | KVM_DIRTY_LOG_INITIALLY_SET) |
| @@ -211,6 +212,12 @@ struct kvm_s2_mmu { · 154 unmodified lines | ||
| 211 | 212 | */ |
| 212 | 213 | bool nested_stage2_enabled; |
| 213 | 214 | |
| 215 | + /* | |
| 216 | + * true when this MMU needs to be unmapped before being used for a new | |
| 217 | + * purpose. | |
| 218 | + */ | |
| 219 | + bool pending_unmap; | |
| 220 | + | |
| 214 | 221 | /* |
| 215 | 222 | * 0: Nobody is currently using this, check vttbr for validity |
| 216 | 223 | * >0: Somebody is actively using this. |
| @@ -166,7 +166,8 @@ int create_hyp_exec_mappings(phys_addr_t phys_addr, size_t size, · 165 unmodified lines | ||
| 166 | 166 | int create_hyp_stack(phys_addr_t phys_addr, unsigned long *haddr); |
| 167 | 167 | void __init free_hyp_pgds(void); |
| 168 | 168 | |
| 169 | −void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size); | |
| 169 | +void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start, | |
| 170 | + u64 size, bool may_block); | |
| 170 | 171 | void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end); |
| 171 | 172 | void kvm_stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end); |
| 172 | 173 | |
| @@ -78,6 +78,8 @@ extern void kvm_s2_mmu_iterate_by_vmid(struct kvm *kvm, u16 vmid, · 77 unmodified lines | ||
| 78 | 78 | extern void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu); |
| 79 | 79 | extern void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu); |
| 80 | 80 | |
| 81 | +extern void check_nested_vcpu_requests(struct kvm_vcpu *vcpu); | |
| 82 | + | |
| 81 | 83 | struct kvm_s2_trans { |
| 82 | 84 | phys_addr_t output; |
| 83 | 85 | unsigned long block_size; |
| @@ -124,7 +126,7 @@ extern int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu, · 40 unmodified lines | ||
| 124 | 126 | struct kvm_s2_trans *trans); |
| 125 | 127 | extern int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2); |
| 126 | 128 | extern void kvm_nested_s2_wp(struct kvm *kvm); |
| 127 | −extern void kvm_nested_s2_unmap(struct kvm *kvm); | |
| 129 | +extern void kvm_nested_s2_unmap(struct kvm *kvm, bool may_block); | |
| 128 | 130 | extern void kvm_nested_s2_flush(struct kvm *kvm); |
| 129 | 131 | |
| 130 | 132 | unsigned long compute_tlb_inval_range(struct kvm_s2_mmu *mmu, u64 val); |
| @@ -10,11 +10,9 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <asm/insn.h> |
| 11 | 11 | #include <asm/probes.h> |
| 12 | 12 | |
| 13 | −#define MAX_UINSN_BYTES AARCH64_INSN_SIZE | |
| 14 | − | |
| 15 | 13 | #define UPROBE_SWBP_INSN cpu_to_le32(BRK64_OPCODE_UPROBES) |
| 16 | 14 | #define UPROBE_SWBP_INSN_SIZE AARCH64_INSN_SIZE |
| 17 | −#define UPROBE_XOL_SLOT_BYTES MAX_UINSN_BYTES | |
| 15 | +#define UPROBE_XOL_SLOT_BYTES AARCH64_INSN_SIZE | |
| 18 | 16 | |
| 19 | 17 | typedef __le32 uprobe_opcode_t; |
| 20 | 18 | |
| @@ -23,8 +21,8 @@ struct arch_uprobe_task { · 2 unmodified lines | ||
| 23 | 21 | |
| 24 | 22 | struct arch_uprobe { |
| 25 | 23 | union { |
| 26 | − u8 insn[MAX_UINSN_BYTES]; | |
| 27 | − u8 ixol[MAX_UINSN_BYTES]; | |
| 24 | + __le32 insn; | |
| 25 | + __le32 ixol; | |
| 28 | 26 | }; |
| 29 | 27 | struct arch_probe_insn api; |
| 30 | 28 | bool simulate; |
| @@ -146,6 +146,7 @@ int main(void) · 145 unmodified lines | ||
| 146 | 146 | DEFINE(NVHE_INIT_HCR_EL2, offsetof(struct kvm_nvhe_init_params, hcr_el2)); |
| 147 | 147 | DEFINE(NVHE_INIT_VTTBR, offsetof(struct kvm_nvhe_init_params, vttbr)); |
| 148 | 148 | DEFINE(NVHE_INIT_VTCR, offsetof(struct kvm_nvhe_init_params, vtcr)); |
| 149 | + DEFINE(NVHE_INIT_TMP, offsetof(struct kvm_nvhe_init_params, tmp)); | |
| 149 | 150 | #endif |
| 150 | 151 | #ifdef CONFIG_CPU_PM |
| 151 | 152 | DEFINE(CPU_CTX_SP, offsetof(struct cpu_suspend_ctx, sp)); |
| @@ -99,10 +99,6 @@ arm_probe_decode_insn(probe_opcode_t insn, struct arch_probe_insn *api) · 98 unmodified lines | ||
| 99 | 99 | aarch64_insn_is_blr(insn) || |
| 100 | 100 | aarch64_insn_is_ret(insn)) { |
| 101 | 101 | api->handler = simulate_br_blr_ret; |
| 102 | − } else if (aarch64_insn_is_ldr_lit(insn)) { | |
| 103 | − api->handler = simulate_ldr_literal; | |
| 104 | − } else if (aarch64_insn_is_ldrsw_lit(insn)) { | |
| 105 | − api->handler = simulate_ldrsw_literal; | |
| 106 | 102 | } else { |
| 107 | 103 | /* |
| 108 | 104 | * Instruction cannot be stepped out-of-line and we don't |
| @@ -140,6 +136,17 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi) · 31 unmodified lines | ||
| 140 | 136 | probe_opcode_t insn = le32_to_cpu(*addr); |
| 141 | 137 | probe_opcode_t *scan_end = NULL; |
| 142 | 138 | unsigned long size = 0, offset = 0; |
| 139 | + struct arch_probe_insn *api = &asi->api; | |
| 140 | + | |
| 141 | + if (aarch64_insn_is_ldr_lit(insn)) { | |
| 142 | + api->handler = simulate_ldr_literal; | |
| 143 | + decoded = INSN_GOOD_NO_SLOT; | |
| 144 | + } else if (aarch64_insn_is_ldrsw_lit(insn)) { | |
| 145 | + api->handler = simulate_ldrsw_literal; | |
| 146 | + decoded = INSN_GOOD_NO_SLOT; | |
| 147 | + } else { | |
| 148 | + decoded = arm_probe_decode_insn(insn, &asi->api); | |
| 149 | + } | |
| 143 | 150 | |
| 144 | 151 | /* |
| 145 | 152 | * If there's a symbol defined in front of and near enough to |
| @@ -157,7 +164,6 @@ arm_kprobe_decode_insn(kprobe_opcode_t *addr, struct arch_specific_insn *asi) · 11 unmodified lines | ||
| 157 | 164 | else |
| 158 | 165 | scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE; |
| 159 | 166 | } |
| 160 | − decoded = arm_probe_decode_insn(insn, &asi->api); | |
| 161 | 167 | |
| 162 | 168 | if (decoded != INSN_REJECTED && scan_end) |
| 163 | 169 | if (is_probed_address_atomic(addr - 1, scan_end)) |
| @@ -171,17 +171,15 @@ simulate_tbz_tbnz(u32 opcode, long addr, struct pt_regs *regs) · 170 unmodified lines | ||
| 171 | 171 | void __kprobes |
| 172 | 172 | simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs) |
| 173 | 173 | { |
| 174 | − u64 *load_addr; | |
| 174 | + unsigned long load_addr; | |
| 175 | 175 | int xn = opcode & 0x1f; |
| 176 | − int disp; | |
| 177 | 176 | |
| 178 | − disp = ldr_displacement(opcode); | |
| 179 | − load_addr = (u64 *) (addr + disp); | |
| 177 | + load_addr = addr + ldr_displacement(opcode); | |
| 180 | 178 | |
| 181 | 179 | if (opcode & (1 << 30)) /* x0-x30 */ |
| 182 | − set_x_reg(regs, xn, *load_addr); | |
| 180 | + set_x_reg(regs, xn, READ_ONCE(*(u64 *)load_addr)); | |
| 183 | 181 | else /* w0-w30 */ |
| 184 | − set_w_reg(regs, xn, *load_addr); | |
| 182 | + set_w_reg(regs, xn, READ_ONCE(*(u32 *)load_addr)); | |
| 185 | 183 | |
| 186 | 184 | instruction_pointer_set(regs, instruction_pointer(regs) + 4); |
| 187 | 185 | } |
| @@ -189,14 +187,12 @@ simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs) · 1 unmodified line | ||
| 189 | 187 | void __kprobes |
| 190 | 188 | simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs) |
| 191 | 189 | { |
| 192 | − s32 *load_addr; | |
| 190 | + unsigned long load_addr; | |
| 193 | 191 | int xn = opcode & 0x1f; |
| 194 | − int disp; | |
| 195 | 192 | |
| 196 | − disp = ldr_displacement(opcode); | |
| 197 | − load_addr = (s32 *) (addr + disp); | |
| 193 | + load_addr = addr + ldr_displacement(opcode); | |
| 198 | 194 | |
| 199 | − set_x_reg(regs, xn, *load_addr); | |
| 195 | + set_x_reg(regs, xn, READ_ONCE(*(s32 *)load_addr)); | |
| 200 | 196 | |
| 201 | 197 | instruction_pointer_set(regs, instruction_pointer(regs) + 4); |
| 202 | 198 | } |
| @@ -42,7 +42,7 @@ int arch_uprobe_analyze_insn(struct arch_uprobe *auprobe, struct mm_struct *mm, · 41 unmodified lines | ||
| 42 | 42 | else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE)) |
| 43 | 43 | return -EINVAL; |
| 44 | 44 | |
| 45 | − insn = *(probe_opcode_t *)(&auprobe->insn[0]); | |
| 45 | + insn = le32_to_cpu(auprobe->insn); | |
| 46 | 46 | |
| 47 | 47 | switch (arm_probe_decode_insn(insn, &auprobe->api)) { |
| 48 | 48 | case INSN_REJECTED: |
| @@ -108,7 +108,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) · 59 unmodified lines | ||
| 108 | 108 | if (!auprobe->simulate) |
| 109 | 109 | return false; |
| 110 | 110 | |
| 111 | − insn = *(probe_opcode_t *)(&auprobe->insn[0]); | |
| 111 | + insn = le32_to_cpu(auprobe->insn); | |
| 112 | 112 | addr = instruction_pointer(regs); |
| 113 | 113 | |
| 114 | 114 | if (auprobe->api.handler) |
| @@ -412,6 +412,9 @@ int copy_thread(struct task_struct *p, const struct kernel_clone_args *args) · 411 unmodified lines | ||
| 412 | 412 | |
| 413 | 413 | p->thread.cpu_context.x19 = (unsigned long)args->fn; |
| 414 | 414 | p->thread.cpu_context.x20 = (unsigned long)args->fn_arg; |
| 415 | + | |
| 416 | + if (system_supports_poe()) | |
| 417 | + p->thread.por_el0 = POR_EL0_INIT; | |
| 415 | 418 | } |
| 416 | 419 | p->thread.cpu_context.pc = (unsigned long)ret_from_fork; |
| 417 | 420 | p->thread.cpu_context.sp = (unsigned long)childregs; |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | ||
| 19 | 19 | #include <linux/ratelimit.h> |
| 20 | 20 | #include <linux/rseq.h> |
| 21 | 21 | #include <linux/syscalls.h> |
| 22 | +#include <linux/pkeys.h> | |
| 22 | 23 | |
| 23 | 24 | #include <asm/daifflags.h> |
| 24 | 25 | #include <asm/debug-monitors.h> |
| @@ -66,10 +67,63 @@ struct rt_sigframe_user_layout { · 41 unmodified lines | ||
| 66 | 67 | unsigned long end_offset; |
| 67 | 68 | }; |
| 68 | 69 | |
| 70 | +/* | |
| 71 | + * Holds any EL0-controlled state that influences unprivileged memory accesses. | |
| 72 | + * This includes both accesses done in userspace and uaccess done in the kernel. | |
| 73 | + * | |
| 74 | + * This state needs to be carefully managed to ensure that it doesn't cause | |
| 75 | + * uaccess to fail when setting up the signal frame, and the signal handler | |
| 76 | + * itself also expects a well-defined state when entered. | |
| 77 | + */ | |
| 78 | +struct user_access_state { | |
| 79 | + u64 por_el0; | |
| 80 | +}; | |
| 81 | + | |
| 69 | 82 | #define BASE_SIGFRAME_SIZE round_up(sizeof(struct rt_sigframe), 16) |
| 70 | 83 | #define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16) |
| 71 | 84 | #define EXTRA_CONTEXT_SIZE round_up(sizeof(struct extra_context), 16) |
| 72 | 85 | |
| 86 | +/* | |
| 87 | + * Save the user access state into ua_state and reset it to disable any | |
| 88 | + * restrictions. | |
| 89 | + */ | |
| 90 | +static void save_reset_user_access_state(struct user_access_state *ua_state) | |
| 91 | +{ | |
| 92 | + if (system_supports_poe()) { | |
| 93 | + u64 por_enable_all = 0; | |
| 94 | + | |
| 95 | + for (int pkey = 0; pkey < arch_max_pkey(); pkey++) | |
| 96 | + por_enable_all |= POE_RXW << (pkey * POR_BITS_PER_PKEY); | |
| 97 | + | |
| 98 | + ua_state->por_el0 = read_sysreg_s(SYS_POR_EL0); | |
| 99 | + write_sysreg_s(por_enable_all, SYS_POR_EL0); | |
| 100 | + /* Ensure that any subsequent uaccess observes the updated value */ | |
| 101 | + isb(); | |
| 102 | + } | |
| 103 | +} | |
| 104 | + | |
| 105 | +/* | |
| 106 | + * Set the user access state for invoking the signal handler. | |
| 107 | + * | |
| 108 | + * No uaccess should be done after that function is called. | |
| 109 | + */ | |
| 110 | +static void set_handler_user_access_state(void) | |
| 111 | +{ | |
| 112 | + if (system_supports_poe()) | |
| 113 | + write_sysreg_s(POR_EL0_INIT, SYS_POR_EL0); | |
| 114 | +} | |
| 115 | + | |
| 116 | +/* | |
| 117 | + * Restore the user access state to the values saved in ua_state. | |
| 118 | + * | |
| 119 | + * No uaccess should be done after that function is called. | |
| 120 | + */ | |
| 121 | +static void restore_user_access_state(const struct user_access_state *ua_state) | |
| 122 | +{ | |
| 123 | + if (system_supports_poe()) | |
| 124 | + write_sysreg_s(ua_state->por_el0, SYS_POR_EL0); | |
| 125 | +} | |
| 126 | + | |
| 73 | 127 | static void init_user_layout(struct rt_sigframe_user_layout *user) |
| 74 | 128 | { |
| 75 | 129 | const size_t reserved_size = |
| @@ -261,18 +315,20 @@ static int restore_fpmr_context(struct user_ctxs *user) · 185 unmodified lines | ||
| 261 | 315 | return err; |
| 262 | 316 | } |
| 263 | 317 | |
| 264 | −static int preserve_poe_context(struct poe_context __user *ctx) | |
| 318 | +static int preserve_poe_context(struct poe_context __user *ctx, | |
| 319 | + const struct user_access_state *ua_state) | |
| 265 | 320 | { |
| 266 | 321 | int err = 0; |
| 267 | 322 | |
| 268 | 323 | __put_user_error(POE_MAGIC, &ctx->head.magic, err); |
| 269 | 324 | __put_user_error(sizeof(*ctx), &ctx->head.size, err); |
| 270 | − __put_user_error(read_sysreg_s(SYS_POR_EL0), &ctx->por_el0, err); | |
| 325 | + __put_user_error(ua_state->por_el0, &ctx->por_el0, err); | |
| 271 | 326 | |
| 272 | 327 | return err; |
| 273 | 328 | } |
| 274 | 329 | |
| 275 | −static int restore_poe_context(struct user_ctxs *user) | |
| 330 | +static int restore_poe_context(struct user_ctxs *user, | |
| 331 | + struct user_access_state *ua_state) | |
| 276 | 332 | { |
| 277 | 333 | u64 por_el0; |
| 278 | 334 | int err = 0; |
| @@ -282,7 +338,7 @@ static int restore_poe_context(struct user_ctxs *user) · 3 unmodified lines | ||
| 282 | 338 | |
| 283 | 339 | __get_user_error(por_el0, &(user->poe->por_el0), err); |
| 284 | 340 | if (!err) |
| 285 | − write_sysreg_s(por_el0, SYS_POR_EL0); | |
| 341 | + ua_state->por_el0 = por_el0; | |
| 286 | 342 | |
| 287 | 343 | return err; |
| 288 | 344 | } |
| @@ -850,7 +906,8 @@ invalid: · 561 unmodified lines | ||
| 850 | 906 | } |
| 851 | 907 | |
| 852 | 908 | static int restore_sigframe(struct pt_regs *regs, |
| 853 | − struct rt_sigframe __user *sf) | |
| 909 | + struct rt_sigframe __user *sf, | |
| 910 | + struct user_access_state *ua_state) | |
| 854 | 911 | { |
| 855 | 912 | sigset_t set; |
| 856 | 913 | int i, err; |
| @@ -899,7 +956,7 @@ static int restore_sigframe(struct pt_regs *regs, · 42 unmodified lines | ||
| 899 | 956 | err = restore_zt_context(&user); |
| 900 | 957 | |
| 901 | 958 | if (err == 0 && system_supports_poe() && user.poe) |
| 902 | − err = restore_poe_context(&user); | |
| 959 | + err = restore_poe_context(&user, ua_state); | |
| 903 | 960 | |
| 904 | 961 | return err; |
| 905 | 962 | } |
| @@ -908,6 +965,7 @@ SYSCALL_DEFINE0(rt_sigreturn) · 2 unmodified lines | ||
| 908 | 965 | { |
| 909 | 966 | struct pt_regs *regs = current_pt_regs(); |
| 910 | 967 | struct rt_sigframe __user *frame; |
| 968 | + struct user_access_state ua_state; | |
| 911 | 969 | |
| 912 | 970 | /* Always make any pending restarted system calls return -EINTR */ |
| 913 | 971 | current->restart_block.fn = do_no_restart_syscall; |
| @@ -924,12 +982,14 @@ SYSCALL_DEFINE0(rt_sigreturn) · 10 unmodified lines | ||
| 924 | 982 | if (!access_ok(frame, sizeof (*frame))) |
| 925 | 983 | goto badframe; |
| 926 | 984 | |
| 927 | − if (restore_sigframe(regs, frame)) | |
| 985 | + if (restore_sigframe(regs, frame, &ua_state)) | |
| 928 | 986 | goto badframe; |
| 929 | 987 | |
| 930 | 988 | if (restore_altstack(&frame->uc.uc_stack)) |
| 931 | 989 | goto badframe; |
| 932 | 990 | |
| 991 | + restore_user_access_state(&ua_state); | |
| 992 | + | |
| 933 | 993 | return regs->regs[0]; |
| 934 | 994 | |
| 935 | 995 | badframe: |
| @@ -1035,7 +1095,8 @@ static int setup_sigframe_layout(struct rt_sigframe_user_layout *user, · 99 unmodified lines | ||
| 1035 | 1095 | } |
| 1036 | 1096 | |
| 1037 | 1097 | static int setup_sigframe(struct rt_sigframe_user_layout *user, |
| 1038 | − struct pt_regs *regs, sigset_t *set) | |
| 1098 | + struct pt_regs *regs, sigset_t *set, | |
| 1099 | + const struct user_access_state *ua_state) | |
| 1039 | 1100 | { |
| 1040 | 1101 | int i, err = 0; |
| 1041 | 1102 | struct rt_sigframe __user *sf = user->sigframe; |
| @@ -1097,10 +1158,9 @@ static int setup_sigframe(struct rt_sigframe_user_layout *user, · 55 unmodified lines | ||
| 1097 | 1158 | struct poe_context __user *poe_ctx = |
| 1098 | 1159 | apply_user_offset(user, user->poe_offset); |
| 1099 | 1160 | |
| 1100 | − err |= preserve_poe_context(poe_ctx); | |
| 1161 | + err |= preserve_poe_context(poe_ctx, ua_state); | |
| 1101 | 1162 | } |
| 1102 | 1163 | |
| 1103 | − | |
| 1104 | 1164 | /* ZA state if present */ |
| 1105 | 1165 | if (system_supports_sme() && err == 0 && user->za_offset) { |
| 1106 | 1166 | struct za_context __user *za_ctx = |
| @@ -1237,9 +1297,6 @@ static void setup_return(struct pt_regs *regs, struct k_sigaction *ka, · 130 unmodified lines | ||
| 1237 | 1297 | sme_smstop(); |
| 1238 | 1298 | } |
| 1239 | 1299 | |
| 1240 | − if (system_supports_poe()) | |
| 1241 | − write_sysreg_s(POR_EL0_INIT, SYS_POR_EL0); | |
| 1242 | − | |
| 1243 | 1300 | if (ka->sa.sa_flags & SA_RESTORER) |
| 1244 | 1301 | sigtramp = ka->sa.sa_restorer; |
| 1245 | 1302 | else |
| @@ -1253,6 +1310,7 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, · 7 unmodified lines | ||
| 1253 | 1310 | { |
| 1254 | 1311 | struct rt_sigframe_user_layout user; |
| 1255 | 1312 | struct rt_sigframe __user *frame; |
| 1313 | + struct user_access_state ua_state; | |
| 1256 | 1314 | int err = 0; |
| 1257 | 1315 | |
| 1258 | 1316 | fpsimd_signal_preserve_current_state(); |
| @@ -1260,13 +1318,14 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, · 1 unmodified line | ||
| 1260 | 1318 | if (get_sigframe(&user, ksig, regs)) |
| 1261 | 1319 | return 1; |
| 1262 | 1320 | |
| 1321 | + save_reset_user_access_state(&ua_state); | |
| 1263 | 1322 | frame = user.sigframe; |
| 1264 | 1323 | |
| 1265 | 1324 | __put_user_error(0, &frame->uc.uc_flags, err); |
| 1266 | 1325 | __put_user_error(NULL, &frame->uc.uc_link, err); |
| 1267 | 1326 | |
| 1268 | 1327 | err |= __save_altstack(&frame->uc.uc_stack, regs->sp); |
| 1269 | − err |= setup_sigframe(&user, regs, set); | |
| 1328 | + err |= setup_sigframe(&user, regs, set, &ua_state); | |
| 1270 | 1329 | if (err == 0) { |
| 1271 | 1330 | setup_return(regs, &ksig->ka, &user, usig); |
| 1272 | 1331 | if (ksig->ka.sa.sa_flags & SA_SIGINFO) { |
| @@ -1276,6 +1335,11 @@ static int setup_rt_frame(int usig, struct ksignal *ksig, sigset_t *set, · 3 unmodified lines | ||
| 1276 | 1335 | } |
| 1277 | 1336 | } |
| 1278 | 1337 | |
| 1338 | + if (err == 0) | |
| 1339 | + set_handler_user_access_state(); | |
| 1340 | + else | |
| 1341 | + restore_user_access_state(&ua_state); | |
| 1342 | + | |
| 1279 | 1343 | return err; |
| 1280 | 1344 | } |
| 1281 | 1345 | |
| @@ -997,6 +997,9 @@ static int kvm_vcpu_suspend(struct kvm_vcpu *vcpu) · 996 unmodified lines | ||
| 997 | 997 | static int check_vcpu_requests(struct kvm_vcpu *vcpu) |
| 998 | 998 | { |
| 999 | 999 | if (kvm_request_pending(vcpu)) { |
| 1000 | + if (kvm_check_request(KVM_REQ_VM_DEAD, vcpu)) | |
| 1001 | + return -EIO; | |
| 1002 | + | |
| 1000 | 1003 | if (kvm_check_request(KVM_REQ_SLEEP, vcpu)) |
| 1001 | 1004 | kvm_vcpu_sleep(vcpu); |
| 1002 | 1005 | |
| @@ -1031,6 +1034,8 @@ static int check_vcpu_requests(struct kvm_vcpu *vcpu) · 28 unmodified lines | ||
| 1031 | 1034 | |
| 1032 | 1035 | if (kvm_dirty_ring_check_request(vcpu)) |
| 1033 | 1036 | return 0; |
| 1037 | + | |
| 1038 | + check_nested_vcpu_requests(vcpu); | |
| 1034 | 1039 | } |
| 1035 | 1040 | |
| 1036 | 1041 | return 1; |
| @@ -24,28 +24,25 @@ · 23 unmodified lines | ||
| 24 | 24 | .align 11 |
| 25 | 25 | |
| 26 | 26 | SYM_CODE_START(__kvm_hyp_init) |
| 27 | − ventry __invalid // Synchronous EL2t | |
| 28 | − ventry __invalid // IRQ EL2t | |
| 29 | − ventry __invalid // FIQ EL2t | |
| 30 | − ventry __invalid // Error EL2t | |
| 27 | + ventry . // Synchronous EL2t | |
| 28 | + ventry . // IRQ EL2t | |
| 29 | + ventry . // FIQ EL2t | |
| 30 | + ventry . // Error EL2t | |
| 31 | 31 | |
| 32 | − ventry __invalid // Synchronous EL2h | |
| 33 | − ventry __invalid // IRQ EL2h | |
| 34 | − ventry __invalid // FIQ EL2h | |
| 35 | − ventry __invalid // Error EL2h | |
| 32 | + ventry . // Synchronous EL2h | |
| 33 | + ventry . // IRQ EL2h | |
| 34 | + ventry . // FIQ EL2h | |
| 35 | + ventry . // Error EL2h | |
| 36 | 36 | |
| 37 | 37 | ventry __do_hyp_init // Synchronous 64-bit EL1 |
| 38 | − ventry __invalid // IRQ 64-bit EL1 | |
| 39 | − ventry __invalid // FIQ 64-bit EL1 | |
| 40 | − ventry __invalid // Error 64-bit EL1 | |
| 38 | + ventry . // IRQ 64-bit EL1 | |
| 39 | + ventry . // FIQ 64-bit EL1 | |
| 40 | + ventry . // Error 64-bit EL1 | |
| 41 | 41 | |
| 42 | − ventry __invalid // Synchronous 32-bit EL1 | |
| 43 | − ventry __invalid // IRQ 32-bit EL1 | |
| 44 | − ventry __invalid // FIQ 32-bit EL1 | |
| 45 | − ventry __invalid // Error 32-bit EL1 | |
| 46 | − | |
| 47 | −__invalid: | |
| 48 | − b . | |
| 42 | + ventry . // Synchronous 32-bit EL1 | |
| 43 | + ventry . // IRQ 32-bit EL1 | |
| 44 | + ventry . // FIQ 32-bit EL1 | |
| 45 | + ventry . // Error 32-bit EL1 | |
| 49 | 46 | |
| 50 | 47 | /* |
| 51 | 48 | * Only uses x0..x3 so as to not clobber callee-saved SMCCC registers. |
| @@ -76,6 +73,13 @@ __do_hyp_init: · 24 unmodified lines | ||
| 76 | 73 | eret |
| 77 | 74 | SYM_CODE_END(__kvm_hyp_init) |
| 78 | 75 | |
| 76 | +SYM_CODE_START_LOCAL(__kvm_init_el2_state) | |
| 77 | + /* Initialize EL2 CPU state to sane values. */ | |
| 78 | + init_el2_state // Clobbers x0..x2 | |
| 79 | + finalise_el2_state | |
| 80 | + ret | |
| 81 | +SYM_CODE_END(__kvm_init_el2_state) | |
| 82 | + | |
| 79 | 83 | /* |
| 80 | 84 | * Initialize the hypervisor in EL2. |
| 81 | 85 | * |
| @@ -102,9 +106,12 @@ SYM_CODE_START_LOCAL(___kvm_hyp_init) · 20 unmodified lines | ||
| 102 | 106 | // TPIDR_EL2 is used to preserve x0 across the macro maze... |
| 103 | 107 | isb |
| 104 | 108 | msr tpidr_el2, x0 |
| 105 | − init_el2_state | |
| 106 | − finalise_el2_state | |
| 109 | + str lr, [x0, #NVHE_INIT_TMP] | |
| 110 | + | |
| 111 | + bl __kvm_init_el2_state | |
| 112 | + | |
| 107 | 113 | mrs x0, tpidr_el2 |
| 114 | + ldr lr, [x0, #NVHE_INIT_TMP] | |
| 108 | 115 | |
| 109 | 116 | 1: |
| 110 | 117 | ldr x1, [x0, #NVHE_INIT_TPIDR_EL2] |
| @@ -199,9 +206,8 @@ SYM_CODE_START_LOCAL(__kvm_hyp_init_cpu) · 88 unmodified lines | ||
| 199 | 206 | |
| 200 | 207 | 2: msr SPsel, #1 // We want to use SP_EL{1,2} |
| 201 | 208 | |
| 202 | − /* Initialize EL2 CPU state to sane values. */ | |
| 203 | − init_el2_state // Clobbers x0..x2 | |
| 204 | − finalise_el2_state | |
| 209 | + bl __kvm_init_el2_state | |
| 210 | + | |
| 205 | 211 | __init_el2_nvhe_prepare_eret |
| 206 | 212 | |
| 207 | 213 | /* Enable MMU, set vectors and stack. */ |
| @@ -317,7 +317,7 @@ int kvm_smccc_call_handler(struct kvm_vcpu *vcpu) · 316 unmodified lines | ||
| 317 | 317 | * to the guest, and hide SSBS so that the |
| 318 | 318 | * guest stays protected. |
| 319 | 319 | */ |
| 320 | − if (cpus_have_final_cap(ARM64_SSBS)) | |
| 320 | + if (kvm_has_feat(vcpu->kvm, ID_AA64PFR1_EL1, SSBS, IMP)) | |
| 321 | 321 | break; |
| 322 | 322 | fallthrough; |
| 323 | 323 | case SPECTRE_UNAFFECTED: |
| @@ -428,7 +428,7 @@ int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) · 104 unmodified lines | ||
| 428 | 428 | * Convert the workaround level into an easy-to-compare number, where higher |
| 429 | 429 | * values mean better protection. |
| 430 | 430 | */ |
| 431 | −static int get_kernel_wa_level(u64 regid) | |
| 431 | +static int get_kernel_wa_level(struct kvm_vcpu *vcpu, u64 regid) | |
| 432 | 432 | { |
| 433 | 433 | switch (regid) { |
| 434 | 434 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: |
| @@ -449,7 +449,7 @@ static int get_kernel_wa_level(u64 regid) · 14 unmodified lines | ||
| 449 | 449 | * don't have any FW mitigation if SSBS is there at |
| 450 | 450 | * all times. |
| 451 | 451 | */ |
| 452 | − if (cpus_have_final_cap(ARM64_SSBS)) | |
| 452 | + if (kvm_has_feat(vcpu->kvm, ID_AA64PFR1_EL1, SSBS, IMP)) | |
| 453 | 453 | return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL; |
| 454 | 454 | fallthrough; |
| 455 | 455 | case SPECTRE_UNAFFECTED: |
| @@ -486,7 +486,7 @@ int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 30 unmodified lines | ||
| 486 | 486 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: |
| 487 | 487 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: |
| 488 | 488 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3: |
| 489 | − val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK; | |
| 489 | + val = get_kernel_wa_level(vcpu, reg->id) & KVM_REG_FEATURE_LEVEL_MASK; | |
| 490 | 490 | break; |
| 491 | 491 | case KVM_REG_ARM_STD_BMAP: |
| 492 | 492 | val = READ_ONCE(smccc_feat->std_bmap); |
| @@ -588,7 +588,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 95 unmodified lines | ||
| 588 | 588 | if (val & ~KVM_REG_FEATURE_LEVEL_MASK) |
| 589 | 589 | return -EINVAL; |
| 590 | 590 | |
| 591 | − if (get_kernel_wa_level(reg->id) < val) | |
| 591 | + if (get_kernel_wa_level(vcpu, reg->id) < val) | |
| 592 | 592 | return -EINVAL; |
| 593 | 593 | |
| 594 | 594 | return 0; |
| @@ -624,7 +624,7 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) · 29 unmodified lines | ||
| 624 | 624 | * We can deal with NOT_AVAIL on NOT_REQUIRED, but not the |
| 625 | 625 | * other way around. |
| 626 | 626 | */ |
| 627 | − if (get_kernel_wa_level(reg->id) < wa_level) | |
| 627 | + if (get_kernel_wa_level(vcpu, reg->id) < wa_level) | |
| 628 | 628 | return -EINVAL; |
| 629 | 629 | |
| 630 | 630 | return 0; |
| @@ -328,9 +328,10 @@ static void __unmap_stage2_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 · 327 unmodified lines | ||
| 328 | 328 | may_block)); |
| 329 | 329 | } |
| 330 | 330 | |
| 331 | −void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start, u64 size) | |
| 331 | +void kvm_stage2_unmap_range(struct kvm_s2_mmu *mmu, phys_addr_t start, | |
| 332 | + u64 size, bool may_block) | |
| 332 | 333 | { |
| 333 | − __unmap_stage2_range(mmu, start, size, true); | |
| 334 | + __unmap_stage2_range(mmu, start, size, may_block); | |
| 334 | 335 | } |
| 335 | 336 | |
| 336 | 337 | void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end) |
| @@ -1015,7 +1016,7 @@ static void stage2_unmap_memslot(struct kvm *kvm, · 678 unmodified lines | ||
| 1015 | 1016 | |
| 1016 | 1017 | if (!(vma->vm_flags & VM_PFNMAP)) { |
| 1017 | 1018 | gpa_t gpa = addr + (vm_start - memslot->userspace_addr); |
| 1018 | − kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, vm_end - vm_start); | |
| 1019 | + kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, vm_end - vm_start, true); | |
| 1019 | 1020 | } |
| 1020 | 1021 | hva = vm_end; |
| 1021 | 1022 | } while (hva < reg_end); |
| @@ -1042,7 +1043,7 @@ void stage2_unmap_vm(struct kvm *kvm) · 20 unmodified lines | ||
| 1042 | 1043 | kvm_for_each_memslot(memslot, bkt, slots) |
| 1043 | 1044 | stage2_unmap_memslot(kvm, memslot); |
| 1044 | 1045 | |
| 1045 | − kvm_nested_s2_unmap(kvm); | |
| 1046 | + kvm_nested_s2_unmap(kvm, true); | |
| 1046 | 1047 | |
| 1047 | 1048 | write_unlock(&kvm->mmu_lock); |
| 1048 | 1049 | mmap_read_unlock(current->mm); |
| @@ -1912,7 +1913,7 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range) · 863 unmodified lines | ||
| 1912 | 1913 | (range->end - range->start) << PAGE_SHIFT, |
| 1913 | 1914 | range->may_block); |
| 1914 | 1915 | |
| 1915 | − kvm_nested_s2_unmap(kvm); | |
| 1916 | + kvm_nested_s2_unmap(kvm, range->may_block); | |
| 1916 | 1917 | return false; |
| 1917 | 1918 | } |
| 1918 | 1919 | |
| @@ -2179,8 +2180,8 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm, · 260 unmodified lines | ||
| 2179 | 2180 | phys_addr_t size = slot->npages << PAGE_SHIFT; |
| 2180 | 2181 | |
| 2181 | 2182 | write_lock(&kvm->mmu_lock); |
| 2182 | − kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, size); | |
| 2183 | − kvm_nested_s2_unmap(kvm); | |
| 2183 | + kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, size, true); | |
| 2184 | + kvm_nested_s2_unmap(kvm, true); | |
| 2184 | 2185 | write_unlock(&kvm->mmu_lock); |
| 2185 | 2186 | } |
| 2186 | 2187 | |
| @@ -632,9 +632,9 @@ static struct kvm_s2_mmu *get_s2_mmu_nested(struct kvm_vcpu *vcpu) · 631 unmodified lines | ||
| 632 | 632 | /* Set the scene for the next search */ |
| 633 | 633 | kvm->arch.nested_mmus_next = (i + 1) % kvm->arch.nested_mmus_size; |
| 634 | 634 | |
| 635 | − /* Clear the old state */ | |
| 635 | + /* Make sure we don't forget to do the laundry */ | |
| 636 | 636 | if (kvm_s2_mmu_valid(s2_mmu)) |
| 637 | − kvm_stage2_unmap_range(s2_mmu, 0, kvm_phys_size(s2_mmu)); | |
| 637 | + s2_mmu->pending_unmap = true; | |
| 638 | 638 | |
| 639 | 639 | /* |
| 640 | 640 | * The virtual VMID (modulo CnP) will be used as a key when matching |
| @@ -650,6 +650,16 @@ static struct kvm_s2_mmu *get_s2_mmu_nested(struct kvm_vcpu *vcpu) · 9 unmodified lines | ||
| 650 | 650 | |
| 651 | 651 | out: |
| 652 | 652 | atomic_inc(&s2_mmu->refcnt); |
| 653 | + | |
| 654 | + /* | |
| 655 | + * Set the vCPU request to perform an unmap, even if the pending unmap | |
| 656 | + * originates from another vCPU. This guarantees that the MMU has been | |
| 657 | + * completely unmapped before any vCPU actually uses it, and allows | |
| 658 | + * multiple vCPUs to lend a hand with completing the unmap. | |
| 659 | + */ | |
| 660 | + if (s2_mmu->pending_unmap) | |
| 661 | + kvm_make_request(KVM_REQ_NESTED_S2_UNMAP, vcpu); | |
| 662 | + | |
| 653 | 663 | return s2_mmu; |
| 654 | 664 | } |
| 655 | 665 | |
| @@ -663,6 +673,13 @@ void kvm_init_nested_s2_mmu(struct kvm_s2_mmu *mmu) · 7 unmodified lines | ||
| 663 | 673 | |
| 664 | 674 | void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu) |
| 665 | 675 | { |
| 676 | + /* | |
| 677 | + * The vCPU kept its reference on the MMU after the last put, keep | |
| 678 | + * rolling with it. | |
| 679 | + */ | |
| 680 | + if (vcpu->arch.hw_mmu) | |
| 681 | + return; | |
| 682 | + | |
| 666 | 683 | if (is_hyp_ctxt(vcpu)) { |
| 667 | 684 | vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu; |
| 668 | 685 | } else { |
| @@ -674,10 +691,18 @@ void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu) · 5 unmodified lines | ||
| 674 | 691 | |
| 675 | 692 | void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu) |
| 676 | 693 | { |
| 677 | − if (kvm_is_nested_s2_mmu(vcpu->kvm, vcpu->arch.hw_mmu)) { | |
| 694 | + /* | |
| 695 | + * Keep a reference on the associated stage-2 MMU if the vCPU is | |
| 696 | + * scheduling out and not in WFI emulation, suggesting it is likely to | |
| 697 | + * reuse the MMU sometime soon. | |
| 698 | + */ | |
| 699 | + if (vcpu->scheduled_out && !vcpu_get_flag(vcpu, IN_WFI)) | |
| 700 | + return; | |
| 701 | + | |
| 702 | + if (kvm_is_nested_s2_mmu(vcpu->kvm, vcpu->arch.hw_mmu)) | |
| 678 | 703 | atomic_dec(&vcpu->arch.hw_mmu->refcnt); |
| 679 | − vcpu->arch.hw_mmu = NULL; | |
| 680 | − } | |
| 704 | + | |
| 705 | + vcpu->arch.hw_mmu = NULL; | |
| 681 | 706 | } |
| 682 | 707 | |
| 683 | 708 | /* |
| @@ -730,7 +755,7 @@ void kvm_nested_s2_wp(struct kvm *kvm) · 46 unmodified lines | ||
| 730 | 755 | } |
| 731 | 756 | } |
| 732 | 757 | |
| 733 | −void kvm_nested_s2_unmap(struct kvm *kvm) | |
| 758 | +void kvm_nested_s2_unmap(struct kvm *kvm, bool may_block) | |
| 734 | 759 | { |
| 735 | 760 | int i; |
| 736 | 761 | |
| @@ -740,7 +765,7 @@ void kvm_nested_s2_unmap(struct kvm *kvm) · 3 unmodified lines | ||
| 740 | 765 | struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i]; |
| 741 | 766 | |
| 742 | 767 | if (kvm_s2_mmu_valid(mmu)) |
| 743 | − kvm_stage2_unmap_range(mmu, 0, kvm_phys_size(mmu)); | |
| 768 | + kvm_stage2_unmap_range(mmu, 0, kvm_phys_size(mmu), may_block); | |
| 744 | 769 | } |
| 745 | 770 | } |
| 746 | 771 | |
| @@ -1184,3 +1209,17 @@ int kvm_init_nv_sysregs(struct kvm *kvm) · 437 unmodified lines | ||
| 1184 | 1209 | |
| 1185 | 1210 | return 0; |
| 1186 | 1211 | } |
| 1212 | + | |
| 1213 | +void check_nested_vcpu_requests(struct kvm_vcpu *vcpu) | |
| 1214 | +{ | |
| 1215 | + if (kvm_check_request(KVM_REQ_NESTED_S2_UNMAP, vcpu)) { | |
| 1216 | + struct kvm_s2_mmu *mmu = vcpu->arch.hw_mmu; | |
| 1217 | + | |
| 1218 | + write_lock(&vcpu->kvm->mmu_lock); | |
| 1219 | + if (mmu->pending_unmap) { | |
| 1220 | + kvm_stage2_unmap_range(mmu, 0, kvm_phys_size(mmu), true); | |
| 1221 | + mmu->pending_unmap = false; | |
| 1222 | + } | |
| 1223 | + write_unlock(&vcpu->kvm->mmu_lock); | |
| 1224 | + } | |
| 1225 | +} | |
| @@ -1527,6 +1527,14 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu, · 1526 unmodified lines | ||
| 1527 | 1527 | val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE); |
| 1528 | 1528 | |
| 1529 | 1529 | val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME); |
| 1530 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_RNDR_trap); | |
| 1531 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_NMI); | |
| 1532 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE_frac); | |
| 1533 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_GCS); | |
| 1534 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_THE); | |
| 1535 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTEX); | |
| 1536 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_DF2); | |
| 1537 | + val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_PFAR); | |
| 1530 | 1538 | break; |
| 1531 | 1539 | case SYS_ID_AA64PFR2_EL1: |
| 1532 | 1540 | /* We only expose FPMR */ |
| @@ -1550,7 +1558,8 @@ static u64 __kvm_read_sanitised_id_reg(const struct kvm_vcpu *vcpu, · 17 unmodified lines | ||
| 1550 | 1558 | val &= ~ID_AA64MMFR2_EL1_CCIDX_MASK; |
| 1551 | 1559 | break; |
| 1552 | 1560 | case SYS_ID_AA64MMFR3_EL1: |
| 1553 | − val &= ID_AA64MMFR3_EL1_TCRX | ID_AA64MMFR3_EL1_S1POE; | |
| 1561 | + val &= ID_AA64MMFR3_EL1_TCRX | ID_AA64MMFR3_EL1_S1POE | | |
| 1562 | + ID_AA64MMFR3_EL1_S1PIE; | |
| 1554 | 1563 | break; |
| 1555 | 1564 | case SYS_ID_MMFR4_EL1: |
| 1556 | 1565 | val &= ~ARM64_FEATURE_MASK(ID_MMFR4_EL1_CCIDX); |
| @@ -1985,7 +1994,7 @@ static u64 reset_clidr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) · 428 unmodified lines | ||
| 1985 | 1994 | * one cache line. |
| 1986 | 1995 | */ |
| 1987 | 1996 | if (kvm_has_mte(vcpu->kvm)) |
| 1988 | − clidr |= 2 << CLIDR_TTYPE_SHIFT(loc); | |
| 1997 | + clidr |= 2ULL << CLIDR_TTYPE_SHIFT(loc); | |
| 1989 | 1998 | |
| 1990 | 1999 | __vcpu_sys_reg(vcpu, r->reg) = clidr; |
| 1991 | 2000 | |
| @@ -2376,7 +2385,19 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 384 unmodified lines | ||
| 2376 | 2385 | ID_AA64PFR0_EL1_RAS | |
| 2377 | 2386 | ID_AA64PFR0_EL1_AdvSIMD | |
| 2378 | 2387 | ID_AA64PFR0_EL1_FP), }, |
| 2379 | − ID_SANITISED(ID_AA64PFR1_EL1), | |
| 2388 | + ID_WRITABLE(ID_AA64PFR1_EL1, ~(ID_AA64PFR1_EL1_PFAR | | |
| 2389 | + ID_AA64PFR1_EL1_DF2 | | |
| 2390 | + ID_AA64PFR1_EL1_MTEX | | |
| 2391 | + ID_AA64PFR1_EL1_THE | | |
| 2392 | + ID_AA64PFR1_EL1_GCS | | |
| 2393 | + ID_AA64PFR1_EL1_MTE_frac | | |
| 2394 | + ID_AA64PFR1_EL1_NMI | | |
| 2395 | + ID_AA64PFR1_EL1_RNDR_trap | | |
| 2396 | + ID_AA64PFR1_EL1_SME | | |
| 2397 | + ID_AA64PFR1_EL1_RES0 | | |
| 2398 | + ID_AA64PFR1_EL1_MPAM_frac | | |
| 2399 | + ID_AA64PFR1_EL1_RAS_frac | | |
| 2400 | + ID_AA64PFR1_EL1_MTE)), | |
| 2380 | 2401 | ID_WRITABLE(ID_AA64PFR2_EL1, ID_AA64PFR2_EL1_FPMR), |
| 2381 | 2402 | ID_UNALLOCATED(4,3), |
| 2382 | 2403 | ID_WRITABLE(ID_AA64ZFR0_EL1, ~ID_AA64ZFR0_EL1_RES0), |
| @@ -2390,7 +2411,21 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 7 unmodified lines | ||
| 2390 | 2411 | .get_user = get_id_reg, |
| 2391 | 2412 | .set_user = set_id_aa64dfr0_el1, |
| 2392 | 2413 | .reset = read_sanitised_id_aa64dfr0_el1, |
| 2393 | − .val = ID_AA64DFR0_EL1_PMUVer_MASK | | |
| 2414 | + /* | |
| 2415 | + * Prior to FEAT_Debugv8.9, the architecture defines context-aware | |
| 2416 | + * breakpoints (CTX_CMPs) as the highest numbered breakpoints (BRPs). | |
| 2417 | + * KVM does not trap + emulate the breakpoint registers, and as such | |
| 2418 | + * cannot support a layout that misaligns with the underlying hardware. | |
| 2419 | + * While it may be possible to describe a subset that aligns with | |
| 2420 | + * hardware, just prevent changes to BRPs and CTX_CMPs altogether for | |
| 2421 | + * simplicity. | |
| 2422 | + * | |
| 2423 | + * See DDI0487K.a, section D2.8.3 Breakpoint types and linking | |
| 2424 | + * of breakpoints for more details. | |
| 2425 | + */ | |
| 2426 | + .val = ID_AA64DFR0_EL1_DoubleLock_MASK | | |
| 2427 | + ID_AA64DFR0_EL1_WRPs_MASK | | |
| 2428 | + ID_AA64DFR0_EL1_PMUVer_MASK | | |
| 2394 | 2429 | ID_AA64DFR0_EL1_DebugVer_MASK, }, |
| 2395 | 2430 | ID_SANITISED(ID_AA64DFR1_EL1), |
| 2396 | 2431 | ID_UNALLOCATED(5,2), |
| @@ -2433,6 +2468,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 36 unmodified lines | ||
| 2433 | 2468 | ID_AA64MMFR2_EL1_NV | |
| 2434 | 2469 | ID_AA64MMFR2_EL1_CCIDX)), |
| 2435 | 2470 | ID_WRITABLE(ID_AA64MMFR3_EL1, (ID_AA64MMFR3_EL1_TCRX | |
| 2471 | + ID_AA64MMFR3_EL1_S1PIE | | |
| 2436 | 2472 | ID_AA64MMFR3_EL1_S1POE)), |
| 2437 | 2473 | ID_SANITISED(ID_AA64MMFR4_EL1), |
| 2438 | 2474 | ID_UNALLOCATED(7,5), |
| @@ -2903,7 +2939,7 @@ static bool handle_alle1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p, · 464 unmodified lines | ||
| 2903 | 2939 | * Drop all shadow S2s, resulting in S1/S2 TLBIs for each of the |
| 2904 | 2940 | * corresponding VMIDs. |
| 2905 | 2941 | */ |
| 2906 | − kvm_nested_s2_unmap(vcpu->kvm); | |
| 2942 | + kvm_nested_s2_unmap(vcpu->kvm, true); | |
| 2907 | 2943 | |
| 2908 | 2944 | write_unlock(&vcpu->kvm->mmu_lock); |
| 2909 | 2945 | |
| @@ -2955,7 +2991,30 @@ union tlbi_info { · 45 unmodified lines | ||
| 2955 | 2991 | static void s2_mmu_unmap_range(struct kvm_s2_mmu *mmu, |
| 2956 | 2992 | const union tlbi_info *info) |
| 2957 | 2993 | { |
| 2958 | − kvm_stage2_unmap_range(mmu, info->range.start, info->range.size); | |
| 2994 | + /* | |
| 2995 | + * The unmap operation is allowed to drop the MMU lock and block, which | |
| 2996 | + * means that @mmu could be used for a different context than the one | |
| 2997 | + * currently being invalidated. | |
| 2998 | + * | |
| 2999 | + * This behavior is still safe, as: | |
| 3000 | + * | |
| 3001 | + * 1) The vCPU(s) that recycled the MMU are responsible for invalidating | |
| 3002 | + * the entire MMU before reusing it, which still honors the intent | |
| 3003 | + * of a TLBI. | |
| 3004 | + * | |
| 3005 | + * 2) Until the guest TLBI instruction is 'retired' (i.e. increment PC | |
| 3006 | + * and ERET to the guest), other vCPUs are allowed to use stale | |
| 3007 | + * translations. | |
| 3008 | + * | |
| 3009 | + * 3) Accidentally unmapping an unrelated MMU context is nonfatal, and | |
| 3010 | + * at worst may cause more aborts for shadow stage-2 fills. | |
| 3011 | + * | |
| 3012 | + * Dropping the MMU lock also implies that shadow stage-2 fills could | |
| 3013 | + * happen behind the back of the TLBI. This is still safe, though, as | |
| 3014 | + * the L1 needs to put its stage-2 in a consistent state before doing | |
| 3015 | + * the TLBI. | |
| 3016 | + */ | |
| 3017 | + kvm_stage2_unmap_range(mmu, info->range.start, info->range.size, true); | |
| 2959 | 3018 | } |
| 2960 | 3019 | |
| 2961 | 3020 | static bool handle_vmalls12e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p, |
| @@ -3050,7 +3109,11 @@ static void s2_mmu_unmap_ipa(struct kvm_s2_mmu *mmu, · 88 unmodified lines | ||
| 3050 | 3109 | max_size = compute_tlb_inval_range(mmu, info->ipa.addr); |
| 3051 | 3110 | base_addr &= ~(max_size - 1); |
| 3052 | 3111 | |
| 3053 | − kvm_stage2_unmap_range(mmu, base_addr, max_size); | |
| 3112 | + /* | |
| 3113 | + * See comment in s2_mmu_unmap_range() for why this is allowed to | |
| 3114 | + * reschedule. | |
| 3115 | + */ | |
| 3116 | + kvm_stage2_unmap_range(mmu, base_addr, max_size, true); | |
| 3054 | 3117 | } |
| 3055 | 3118 | |
| 3056 | 3119 | static bool handle_ipas2e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p, |
| @@ -417,8 +417,28 @@ static void __kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) · 416 unmodified lines | ||
| 417 | 417 | kfree(vgic_cpu->private_irqs); |
| 418 | 418 | vgic_cpu->private_irqs = NULL; |
| 419 | 419 | |
| 420 | − if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) | |
| 420 | + if (vcpu->kvm->arch.vgic.vgic_model == KVM_DEV_TYPE_ARM_VGIC_V3) { | |
| 421 | + /* | |
| 422 | + * If this vCPU is being destroyed because of a failed creation | |
| 423 | + * then unregister the redistributor to avoid leaving behind a | |
| 424 | + * dangling pointer to the vCPU struct. | |
| 425 | + * | |
| 426 | + * vCPUs that have been successfully created (i.e. added to | |
| 427 | + * kvm->vcpu_array) get unregistered in kvm_vgic_destroy(), as | |
| 428 | + * this function gets called while holding kvm->arch.config_lock | |
| 429 | + * in the VM teardown path and would otherwise introduce a lock | |
| 430 | + * inversion w.r.t. kvm->srcu. | |
| 431 | + * | |
| 432 | + * vCPUs that failed creation are torn down outside of the | |
| 433 | + * kvm->arch.config_lock and do not get unregistered in | |
| 434 | + * kvm_vgic_destroy(), meaning it is both safe and necessary to | |
| 435 | + * do so here. | |
| 436 | + */ | |
| 437 | + if (kvm_get_vcpu_by_id(vcpu->kvm, vcpu->vcpu_id) != vcpu) | |
| 438 | + vgic_unregister_redist_iodev(vcpu); | |
| 439 | + | |
| 421 | 440 | vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF; |
| 441 | + } | |
| 422 | 442 | } |
| 423 | 443 | |
| 424 | 444 | void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) |
| @@ -524,22 +544,31 @@ int kvm_vgic_map_resources(struct kvm *kvm) · 99 unmodified lines | ||
| 524 | 544 | if (ret) |
| 525 | 545 | goto out; |
| 526 | 546 | |
| 527 | − dist->ready = true; | |
| 528 | 547 | dist_base = dist->vgic_dist_base; |
| 529 | 548 | mutex_unlock(&kvm->arch.config_lock); |
| 530 | 549 | |
| 531 | 550 | ret = vgic_register_dist_iodev(kvm, dist_base, type); |
| 532 | − if (ret) | |
| 551 | + if (ret) { | |
| 533 | 552 | kvm_err("Unable to register VGIC dist MMIO regions\n"); |
| 553 | + goto out_slots; | |
| 554 | + } | |
| 534 | 555 | |
| 556 | + /* | |
| 557 | + * kvm_io_bus_register_dev() guarantees all readers see the new MMIO | |
| 558 | + * registration before returning through synchronize_srcu(), which also | |
| 559 | + * implies a full memory barrier. As such, marking the distributor as | |
| 560 | + * 'ready' here is guaranteed to be ordered after all vCPUs having seen | |
| 561 | + * a completely configured distributor. | |
| 562 | + */ | |
| 563 | + dist->ready = true; | |
| 535 | 564 | goto out_slots; |
| 536 | 565 | out: |
| 537 | 566 | mutex_unlock(&kvm->arch.config_lock); |
| 538 | 567 | out_slots: |
| 539 | − mutex_unlock(&kvm->slots_lock); | |
| 540 | − | |
| 541 | 568 | if (ret) |
| 542 | − kvm_vgic_destroy(kvm); | |
| 569 | + kvm_vm_dead(kvm); | |
| 570 | + | |
| 571 | + mutex_unlock(&kvm->slots_lock); | |
| 543 | 572 | |
| 544 | 573 | return ret; |
| 545 | 574 | } |
| @@ -236,7 +236,12 @@ static int vgic_set_common_attr(struct kvm_device *dev, · 235 unmodified lines | ||
| 236 | 236 | |
| 237 | 237 | mutex_lock(&dev->kvm->arch.config_lock); |
| 238 | 238 | |
| 239 | − if (vgic_ready(dev->kvm) || dev->kvm->arch.vgic.nr_spis) | |
| 239 | + /* | |
| 240 | + * Either userspace has already configured NR_IRQS or | |
| 241 | + * the vgic has already been initialized and vgic_init() | |
| 242 | + * supplied a default amount of SPIs. | |
| 243 | + */ | |
| 244 | + if (dev->kvm->arch.vgic.nr_spis) | |
| 240 | 245 | ret = -EBUSY; |
| 241 | 246 | else |
| 242 | 247 | dev->kvm->arch.vgic.nr_spis = |
| @@ -2220,7 +2220,11 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im, · 2219 unmodified lines | ||
| 2220 | 2220 | emit(A64_STR64I(A64_R(20), A64_SP, regs_off + 8), ctx); |
| 2221 | 2221 | |
| 2222 | 2222 | if (flags & BPF_TRAMP_F_CALL_ORIG) { |
| 2223 | − emit_a64_mov_i64(A64_R(0), (const u64)im, ctx); | |
| 2223 | + /* for the first pass, assume the worst case */ | |
| 2224 | + if (!ctx->image) | |
| 2225 | + ctx->idx += 4; | |
| 2226 | + else | |
| 2227 | + emit_a64_mov_i64(A64_R(0), (const u64)im, ctx); | |
| 2224 | 2228 | emit_call((const u64)__bpf_tramp_enter, ctx); |
| 2225 | 2229 | } |
| 2226 | 2230 | |
| @@ -2264,7 +2268,11 @@ static int prepare_trampoline(struct jit_ctx *ctx, struct bpf_tramp_image *im, · 37 unmodified lines | ||
| 2264 | 2268 | |
| 2265 | 2269 | if (flags & BPF_TRAMP_F_CALL_ORIG) { |
| 2266 | 2270 | im->ip_epilogue = ctx->ro_image + ctx->idx; |
| 2267 | − emit_a64_mov_i64(A64_R(0), (const u64)im, ctx); | |
| 2271 | + /* for the first pass, assume the worst case */ | |
| 2272 | + if (!ctx->image) | |
| 2273 | + ctx->idx += 4; | |
| 2274 | + else | |
| 2275 | + emit_a64_mov_i64(A64_R(0), (const u64)im, ctx); | |
| 2268 | 2276 | emit_call((const u64)__bpf_tramp_exit, ctx); |
| 2269 | 2277 | } |
| 2270 | 2278 | |
| @@ -26,6 +26,10 @@ struct loongson_board_info { · 25 unmodified lines | ||
| 26 | 26 | |
| 27 | 27 | #define NR_WORDS DIV_ROUND_UP(NR_CPUS, BITS_PER_LONG) |
| 28 | 28 | |
| 29 | +/* | |
| 30 | + * The "core" of cores_per_node and cores_per_package stands for a | |
| 31 | + * logical core, which means in a SMT system it stands for a thread. | |
| 32 | + */ | |
| 29 | 33 | struct loongson_system_configuration { |
| 30 | 34 | int nr_cpus; |
| 31 | 35 | int nr_nodes; |
| @@ -16,7 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #define XRANGE_SHIFT (48) |
| 17 | 17 | |
| 18 | 18 | /* Valid address length */ |
| 19 | −#define XRANGE_SHADOW_SHIFT (PGDIR_SHIFT + PAGE_SHIFT - 3) | |
| 19 | +#define XRANGE_SHADOW_SHIFT min(cpu_vabits, VA_BITS) | |
| 20 | 20 | /* Used for taking out the valid address */ |
| 21 | 21 | #define XRANGE_SHADOW_MASK GENMASK_ULL(XRANGE_SHADOW_SHIFT - 1, 0) |
| 22 | 22 | /* One segment whole address space size */ |
| @@ -250,7 +250,7 @@ · 249 unmodified lines | ||
| 250 | 250 | #define CSR_ESTAT_IS_WIDTH 15 |
| 251 | 251 | #define CSR_ESTAT_IS (_ULCAST_(0x7fff) << CSR_ESTAT_IS_SHIFT) |
| 252 | 252 | |
| 253 | −#define LOONGARCH_CSR_ERA 0x6 /* ERA */ | |
| 253 | +#define LOONGARCH_CSR_ERA 0x6 /* Exception return address */ | |
| 254 | 254 | |
| 255 | 255 | #define LOONGARCH_CSR_BADV 0x7 /* Bad virtual address */ |
| 256 | 256 | |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | |
| 11 | 11 | #define __HAVE_ARCH_PMD_ALLOC_ONE |
| 12 | 12 | #define __HAVE_ARCH_PUD_ALLOC_ONE |
| 13 | +#define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL | |
| 13 | 14 | #include <asm-generic/pgalloc.h> |
| 14 | 15 | |
| 15 | 16 | static inline void pmd_populate_kernel(struct mm_struct *mm, |
| @@ -44,6 +45,16 @@ extern void pagetable_init(void); · 28 unmodified lines | ||
| 44 | 45 | |
| 45 | 46 | extern pgd_t *pgd_alloc(struct mm_struct *mm); |
| 46 | 47 | |
| 48 | +static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm) | |
| 49 | +{ | |
| 50 | + pte_t *pte = __pte_alloc_one_kernel(mm); | |
| 51 | + | |
| 52 | + if (pte) | |
| 53 | + kernel_pte_init(pte); | |
| 54 | + | |
| 55 | + return pte; | |
| 56 | +} | |
| 57 | + | |
| 47 | 58 | #define __pte_free_tlb(tlb, pte, address) \ |
| 48 | 59 | do { \ |
| 49 | 60 | pagetable_pte_dtor(page_ptdesc(pte)); \ |
| @@ -269,6 +269,7 @@ extern void set_pmd_at(struct mm_struct *mm, unsigned long addr, pmd_t *pmdp, pm · 268 unmodified lines | ||
| 269 | 269 | extern void pgd_init(void *addr); |
| 270 | 270 | extern void pud_init(void *addr); |
| 271 | 271 | extern void pmd_init(void *addr); |
| 272 | +extern void kernel_pte_init(void *addr); | |
| 272 | 273 | |
| 273 | 274 | /* |
| 274 | 275 | * Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that |
| @@ -325,39 +326,17 @@ static inline void set_pte(pte_t *ptep, pte_t pteval) · 50 unmodified lines | ||
| 325 | 326 | { |
| 326 | 327 | WRITE_ONCE(*ptep, pteval); |
| 327 | 328 | |
| 328 | − if (pte_val(pteval) & _PAGE_GLOBAL) { | |
| 329 | − pte_t *buddy = ptep_buddy(ptep); | |
| 330 | − /* | |
| 331 | − * Make sure the buddy is global too (if it's !none, | |
| 332 | − * it better already be global) | |
| 333 | − */ | |
| 334 | − if (pte_none(ptep_get(buddy))) { | |
| 335 | 329 | #ifdef CONFIG_SMP |
| 336 | − /* | |
| 337 | − * For SMP, multiple CPUs can race, so we need | |
| 338 | − * to do this atomically. | |
| 339 | − */ | |
| 340 | − __asm__ __volatile__( | |
| 341 | − __AMOR "$zero, %[global], %[buddy] \n" | |
| 342 | − : [buddy] "+ZB" (buddy->pte) | |
| 343 | − : [global] "r" (_PAGE_GLOBAL) | |
| 344 | − : "memory"); | |
| 345 | − | |
| 346 | − DBAR(0b11000); /* o_wrw = 0b11000 */ | |
| 347 | −#else /* !CONFIG_SMP */ | |
| 348 | − WRITE_ONCE(*buddy, __pte(pte_val(ptep_get(buddy)) | _PAGE_GLOBAL)); | |
| 349 | −#endif /* CONFIG_SMP */ | |
| 350 | − } | |
| 351 | − } | |
| 330 | + if (pte_val(pteval) & _PAGE_GLOBAL) | |
| 331 | + DBAR(0b11000); /* o_wrw = 0b11000 */ | |
| 332 | +#endif | |
| 352 | 333 | } |
| 353 | 334 | |
| 354 | 335 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) |
| 355 | 336 | { |
| 356 | − /* Preserve global status for the pair */ | |
| 357 | − if (pte_val(ptep_get(ptep_buddy(ptep))) & _PAGE_GLOBAL) | |
| 358 | − set_pte(ptep, __pte(_PAGE_GLOBAL)); | |
| 359 | − else | |
| 360 | − set_pte(ptep, __pte(0)); | |
| 337 | + pte_t pte = ptep_get(ptep); | |
| 338 | + pte_val(pte) &= _PAGE_GLOBAL; | |
| 339 | + set_pte(ptep, pte); | |
| 361 | 340 | } |
| 362 | 341 | |
| 363 | 342 | #define PGD_T_LOG2 (__builtin_ffs(sizeof(pgd_t)) - 1) |
| @@ -293,13 +293,15 @@ unsigned long stack_top(void) · 292 unmodified lines | ||
| 293 | 293 | { |
| 294 | 294 | unsigned long top = TASK_SIZE & PAGE_MASK; |
| 295 | 295 | |
| 296 | − /* Space for the VDSO & data page */ | |
| 297 | − top -= PAGE_ALIGN(current->thread.vdso->size); | |
| 298 | − top -= VVAR_SIZE; | |
| 299 | − | |
| 300 | − /* Space to randomize the VDSO base */ | |
| 301 | − if (current->flags & PF_RANDOMIZE) | |
| 302 | − top -= VDSO_RANDOMIZE_SIZE; | |
| 296 | + if (current->thread.vdso) { | |
| 297 | + /* Space for the VDSO & data page */ | |
| 298 | + top -= PAGE_ALIGN(current->thread.vdso->size); | |
| 299 | + top -= VVAR_SIZE; | |
| 300 | + | |
| 301 | + /* Space to randomize the VDSO base */ | |
| 302 | + if (current->flags & PF_RANDOMIZE) | |
| 303 | + top -= VDSO_RANDOMIZE_SIZE; | |
| 304 | + } | |
| 303 | 305 | |
| 304 | 306 | return top; |
| 305 | 307 | } |
| @@ -55,6 +55,7 @@ · 54 unmodified lines | ||
| 55 | 55 | #define SMBIOS_FREQHIGH_OFFSET 0x17 |
| 56 | 56 | #define SMBIOS_FREQLOW_MASK 0xFF |
| 57 | 57 | #define SMBIOS_CORE_PACKAGE_OFFSET 0x23 |
| 58 | +#define SMBIOS_THREAD_PACKAGE_OFFSET 0x25 | |
| 58 | 59 | #define LOONGSON_EFI_ENABLE (1 << 3) |
| 59 | 60 | |
| 60 | 61 | unsigned long fw_arg0, fw_arg1, fw_arg2; |
| @@ -125,7 +126,7 @@ static void __init parse_cpu_table(const struct dmi_header *dm) · 64 unmodified lines | ||
| 125 | 126 | cpu_clock_freq = freq_temp * 1000000; |
| 126 | 127 | |
| 127 | 128 | loongson_sysconf.cpuname = (void *)dmi_string_parse(dm, dmi_data[16]); |
| 128 | − loongson_sysconf.cores_per_package = *(dmi_data + SMBIOS_CORE_PACKAGE_OFFSET); | |
| 129 | + loongson_sysconf.cores_per_package = *(dmi_data + SMBIOS_THREAD_PACKAGE_OFFSET); | |
| 129 | 130 | |
| 130 | 131 | pr_info("CpuClock = %llu\n", cpu_clock_freq); |
| 131 | 132 | } |
| @@ -555,6 +555,9 @@ asmlinkage void noinstr do_ale(struct pt_regs *regs) · 554 unmodified lines | ||
| 555 | 555 | #else |
| 556 | 556 | unsigned int *pc; |
| 557 | 557 | |
| 558 | + if (regs->csr_prmd & CSR_PRMD_PIE) | |
| 559 | + local_irq_enable(); | |
| 560 | + | |
| 558 | 561 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->csr_badvaddr); |
| 559 | 562 | |
| 560 | 563 | /* |
| @@ -579,6 +582,8 @@ sigbus: · 18 unmodified lines | ||
| 579 | 582 | die_if_kernel("Kernel ale access", regs); |
| 580 | 583 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr); |
| 581 | 584 | out: |
| 585 | + if (regs->csr_prmd & CSR_PRMD_PIE) | |
| 586 | + local_irq_disable(); | |
| 582 | 587 | #endif |
| 583 | 588 | irqentry_exit(regs, state); |
| 584 | 589 | } |
| @@ -34,7 +34,6 @@ static union { · 33 unmodified lines | ||
| 34 | 34 | struct loongarch_vdso_data vdata; |
| 35 | 35 | } loongarch_vdso_data __page_aligned_data; |
| 36 | 36 | |
| 37 | −static struct page *vdso_pages[] = { NULL }; | |
| 38 | 37 | struct vdso_data *vdso_data = generic_vdso_data.data; |
| 39 | 38 | struct vdso_pcpu_data *vdso_pdata = loongarch_vdso_data.vdata.pdata; |
| 40 | 39 | struct vdso_rng_data *vdso_rng_data = &loongarch_vdso_data.vdata.rng_data; |
| @@ -85,10 +84,8 @@ static vm_fault_t vvar_fault(const struct vm_special_mapping *sm, · 44 unmodified lines | ||
| 85 | 84 | |
| 86 | 85 | struct loongarch_vdso_info vdso_info = { |
| 87 | 86 | .vdso = vdso_start, |
| 88 | − .size = PAGE_SIZE, | |
| 89 | 87 | .code_mapping = { |
| 90 | 88 | .name = "[vdso]", |
| 91 | − .pages = vdso_pages, | |
| 92 | 89 | .mremap = vdso_mremap, |
| 93 | 90 | }, |
| 94 | 91 | .data_mapping = { |
| @@ -103,11 +100,14 @@ static int __init init_vdso(void) · 8 unmodified lines | ||
| 103 | 100 | unsigned long i, cpu, pfn; |
| 104 | 101 | |
| 105 | 102 | BUG_ON(!PAGE_ALIGNED(vdso_info.vdso)); |
| 106 | − BUG_ON(!PAGE_ALIGNED(vdso_info.size)); | |
| 107 | 103 | |
| 108 | 104 | for_each_possible_cpu(cpu) |
| 109 | 105 | vdso_pdata[cpu].node = cpu_to_node(cpu); |
| 110 | 106 | |
| 107 | + vdso_info.size = PAGE_ALIGN(vdso_end - vdso_start); | |
| 108 | + vdso_info.code_mapping.pages = | |
| 109 | + kcalloc(vdso_info.size / PAGE_SIZE, sizeof(struct page *), GFP_KERNEL); | |
| 110 | + | |
| 111 | 111 | pfn = __phys_to_pfn(__pa_symbol(vdso_info.vdso)); |
| 112 | 112 | for (i = 0; i < vdso_info.size / PAGE_SIZE; i++) |
| 113 | 113 | vdso_info.code_mapping.pages[i] = pfn_to_page(pfn + i); |
| @@ -161,10 +161,11 @@ static void _kvm_save_timer(struct kvm_vcpu *vcpu) · 160 unmodified lines | ||
| 161 | 161 | if (kvm_vcpu_is_blocking(vcpu)) { |
| 162 | 162 | |
| 163 | 163 | /* |
| 164 | − * HRTIMER_MODE_PINNED is suggested since vcpu may run in | |
| 165 | − * the same physical cpu in next time | |
| 164 | + * HRTIMER_MODE_PINNED_HARD is suggested since vcpu may run in | |
| 165 | + * the same physical cpu in next time, and the timer should run | |
| 166 | + * in hardirq context even in the PREEMPT_RT case. | |
| 166 | 167 | */ |
| 167 | − hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED); | |
| 168 | + hrtimer_start(&vcpu->arch.swtimer, expire, HRTIMER_MODE_ABS_PINNED_HARD); | |
| 168 | 169 | } |
| 169 | 170 | } |
| 170 | 171 | |
| @@ -1457,7 +1457,7 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) · 1456 unmodified lines | ||
| 1457 | 1457 | vcpu->arch.vpid = 0; |
| 1458 | 1458 | vcpu->arch.flush_gpa = INVALID_GPA; |
| 1459 | 1459 | |
| 1460 | − hrtimer_init(&vcpu->arch.swtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED); | |
| 1460 | + hrtimer_init(&vcpu->arch.swtimer, CLOCK_MONOTONIC, HRTIMER_MODE_ABS_PINNED_HARD); | |
| 1461 | 1461 | vcpu->arch.swtimer.function = kvm_swtimer_wakeup; |
| 1462 | 1462 | |
| 1463 | 1463 | vcpu->arch.handle_exit = kvm_handle_exit; |
| @@ -201,7 +201,9 @@ pte_t * __init populate_kernel_pte(unsigned long addr) · 200 unmodified lines | ||
| 201 | 201 | pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE); |
| 202 | 202 | if (!pte) |
| 203 | 203 | panic("%s: Failed to allocate memory\n", __func__); |
| 204 | + | |
| 204 | 205 | pmd_populate_kernel(&init_mm, pmd, pte); |
| 206 | + kernel_pte_init(pte); | |
| 205 | 207 | } |
| 206 | 208 | |
| 207 | 209 | return pte_offset_kernel(pmd, addr); |
| @@ -116,6 +116,26 @@ void pud_init(void *addr) · 115 unmodified lines | ||
| 116 | 116 | EXPORT_SYMBOL_GPL(pud_init); |
| 117 | 117 | #endif |
| 118 | 118 | |
| 119 | +void kernel_pte_init(void *addr) | |
| 120 | +{ | |
| 121 | + unsigned long *p, *end; | |
| 122 | + | |
| 123 | + p = (unsigned long *)addr; | |
| 124 | + end = p + PTRS_PER_PTE; | |
| 125 | + | |
| 126 | + do { | |
| 127 | + p[0] = _PAGE_GLOBAL; | |
| 128 | + p[1] = _PAGE_GLOBAL; | |
| 129 | + p[2] = _PAGE_GLOBAL; | |
| 130 | + p[3] = _PAGE_GLOBAL; | |
| 131 | + p[4] = _PAGE_GLOBAL; | |
| 132 | + p += 8; | |
| 133 | + p[-3] = _PAGE_GLOBAL; | |
| 134 | + p[-2] = _PAGE_GLOBAL; | |
| 135 | + p[-1] = _PAGE_GLOBAL; | |
| 136 | + } while (p != end); | |
| 137 | +} | |
| 138 | + | |
| 119 | 139 | pmd_t mk_pmd(struct page *page, pgprot_t prot) |
| 120 | 140 | { |
| 121 | 141 | pmd_t pmd; |
| @@ -102,3 +102,4 @@ unsigned long __cmpxchg_small(volatile void *ptr, unsigned long old, · 101 unmodified lines | ||
| 102 | 102 | return old; |
| 103 | 103 | } |
| 104 | 104 | } |
| 105 | +EXPORT_SYMBOL(__cmpxchg_small); | |
| @@ -494,6 +494,7 @@ FixupDAR:/* Entry point for dcbx workaround. */ · 493 unmodified lines | ||
| 494 | 494 | bctr /* jump into table */ |
| 495 | 495 | 152: |
| 496 | 496 | mfdar r11 |
| 497 | + mtdar r10 | |
| 497 | 498 | mtctr r11 /* restore ctr reg from DAR */ |
| 498 | 499 | mfspr r11, SPRN_SPRG_THREAD |
| 499 | 500 | stw r10, DAR(r11) |
| @@ -282,6 +282,7 @@ int __init opal_event_init(void) · 281 unmodified lines | ||
| 282 | 282 | name, NULL); |
| 283 | 283 | if (rc) { |
| 284 | 284 | pr_warn("Error %d requesting OPAL irq %d\n", rc, (int)r->start); |
| 285 | + kfree(name); | |
| 285 | 286 | continue; |
| 286 | 287 | } |
| 287 | 288 | } |
| @@ -177,7 +177,7 @@ config RISCV · 176 unmodified lines | ||
| 177 | 177 | select HAVE_REGS_AND_STACK_ACCESS_API |
| 178 | 178 | select HAVE_RETHOOK if !XIP_KERNEL |
| 179 | 179 | select HAVE_RSEQ |
| 180 | − select HAVE_RUST if RUSTC_SUPPORTS_RISCV | |
| 180 | + select HAVE_RUST if RUSTC_SUPPORTS_RISCV && CC_IS_CLANG | |
| 181 | 181 | select HAVE_SAMPLE_FTRACE_DIRECT |
| 182 | 182 | select HAVE_SAMPLE_FTRACE_DIRECT_MULTI |
| 183 | 183 | select HAVE_STACKPROTECTOR |
| @@ -2,6 +2,12 @@ ifdef CONFIG_RELOCATABLE · 1 unmodified line | ||
| 2 | 2 | KBUILD_CFLAGS += -fno-pie |
| 3 | 3 | endif |
| 4 | 4 | |
| 5 | +ifdef CONFIG_RISCV_ALTERNATIVE_EARLY | |
| 6 | +ifdef CONFIG_FORTIFY_SOURCE | |
| 7 | +KBUILD_CFLAGS += -D__NO_FORTIFY | |
| 8 | +endif | |
| 9 | +endif | |
| 10 | + | |
| 5 | 11 | obj-$(CONFIG_ERRATA_ANDES) += andes/ |
| 6 | 12 | obj-$(CONFIG_ERRATA_SIFIVE) += sifive/ |
| 7 | 13 | obj-$(CONFIG_ERRATA_THEAD) += thead/ |
| @@ -36,6 +36,11 @@ KASAN_SANITIZE_alternative.o := n · 35 unmodified lines | ||
| 36 | 36 | KASAN_SANITIZE_cpufeature.o := n |
| 37 | 37 | KASAN_SANITIZE_sbi_ecall.o := n |
| 38 | 38 | endif |
| 39 | +ifdef CONFIG_FORTIFY_SOURCE | |
| 40 | +CFLAGS_alternative.o += -D__NO_FORTIFY | |
| 41 | +CFLAGS_cpufeature.o += -D__NO_FORTIFY | |
| 42 | +CFLAGS_sbi_ecall.o += -D__NO_FORTIFY | |
| 43 | +endif | |
| 39 | 44 | endif |
| 40 | 45 | |
| 41 | 46 | extra-y += vmlinux.lds |
| @@ -210,7 +210,7 @@ void __init __iomem *__acpi_map_table(unsigned long phys, unsigned long size) · 209 unmodified lines | ||
| 210 | 210 | if (!size) |
| 211 | 211 | return NULL; |
| 212 | 212 | |
| 213 | − return early_ioremap(phys, size); | |
| 213 | + return early_memremap(phys, size); | |
| 214 | 214 | } |
| 215 | 215 | |
| 216 | 216 | void __init __acpi_unmap_table(void __iomem *map, unsigned long size) |
| @@ -218,7 +218,7 @@ void __init __acpi_unmap_table(void __iomem *map, unsigned long size) · 1 unmodified line | ||
| 218 | 218 | if (!map || !size) |
| 219 | 219 | return; |
| 220 | 220 | |
| 221 | − early_iounmap(map, size); | |
| 221 | + early_memunmap(map, size); | |
| 222 | 222 | } |
| 223 | 223 | |
| 224 | 224 | void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size) |
| @@ -4,8 +4,6 @@ · 3 unmodified lines | ||
| 4 | 4 | * Copyright (C) 2017 SiFive |
| 5 | 5 | */ |
| 6 | 6 | |
| 7 | −#define GENERATING_ASM_OFFSETS | |
| 8 | − | |
| 9 | 7 | #include <linux/kbuild.h> |
| 10 | 8 | #include <linux/mm.h> |
| 11 | 9 | #include <linux/sched.h> |
| @@ -80,8 +80,7 @@ int populate_cache_leaves(unsigned int cpu) · 79 unmodified lines | ||
| 80 | 80 | { |
| 81 | 81 | struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); |
| 82 | 82 | struct cacheinfo *this_leaf = this_cpu_ci->info_list; |
| 83 | − struct device_node *np = of_cpu_device_node_get(cpu); | |
| 84 | − struct device_node *prev = NULL; | |
| 83 | + struct device_node *np, *prev; | |
| 85 | 84 | int levels = 1, level = 1; |
| 86 | 85 | |
| 87 | 86 | if (!acpi_disabled) { |
| @@ -105,6 +104,10 @@ int populate_cache_leaves(unsigned int cpu) · 17 unmodified lines | ||
| 105 | 104 | return 0; |
| 106 | 105 | } |
| 107 | 106 | |
| 107 | + np = of_cpu_device_node_get(cpu); | |
| 108 | + if (!np) | |
| 109 | + return -ENOENT; | |
| 110 | + | |
| 108 | 111 | if (of_property_read_bool(np, "cache-size")) |
| 109 | 112 | ci_leaf_init(this_leaf++, CACHE_TYPE_UNIFIED, level); |
| 110 | 113 | if (of_property_read_bool(np, "i-cache-size")) |
| @@ -58,7 +58,7 @@ void arch_cpuhp_cleanup_dead_cpu(unsigned int cpu) · 57 unmodified lines | ||
| 58 | 58 | if (cpu_ops->cpu_is_stopped) |
| 59 | 59 | ret = cpu_ops->cpu_is_stopped(cpu); |
| 60 | 60 | if (ret) |
| 61 | − pr_warn("CPU%d may not have stopped: %d\n", cpu, ret); | |
| 61 | + pr_warn("CPU%u may not have stopped: %d\n", cpu, ret); | |
| 62 | 62 | } |
| 63 | 63 | |
| 64 | 64 | /* |
| @@ -64,7 +64,7 @@ extra_header_fields: · 63 unmodified lines | ||
| 64 | 64 | .long efi_header_end - _start // SizeOfHeaders |
| 65 | 65 | .long 0 // CheckSum |
| 66 | 66 | .short IMAGE_SUBSYSTEM_EFI_APPLICATION // Subsystem |
| 67 | − .short 0 // DllCharacteristics | |
| 67 | + .short IMAGE_DLL_CHARACTERISTICS_NX_COMPAT // DllCharacteristics | |
| 68 | 68 | .quad 0 // SizeOfStackReserve |
| 69 | 69 | .quad 0 // SizeOfStackCommit |
| 70 | 70 | .quad 0 // SizeOfHeapReserve |
| @@ -16,8 +16,12 @@ KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS)) · 15 unmodified lines | ||
| 16 | 16 | KBUILD_CFLAGS += -mcmodel=medany |
| 17 | 17 | |
| 18 | 18 | CFLAGS_cmdline_early.o += -D__NO_FORTIFY |
| 19 | −CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY | |
| 20 | 19 | CFLAGS_fdt_early.o += -D__NO_FORTIFY |
| 20 | +# lib/string.c already defines __NO_FORTIFY | |
| 21 | +CFLAGS_ctype.o += -D__NO_FORTIFY | |
| 22 | +CFLAGS_lib-fdt.o += -D__NO_FORTIFY | |
| 23 | +CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY | |
| 24 | +CFLAGS_archrandom_early.o += -D__NO_FORTIFY | |
| 21 | 25 | |
| 22 | 26 | $(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \ |
| 23 | 27 | --remove-section=.note.gnu.property \ |
| @@ -136,8 +136,6 @@ · 135 unmodified lines | ||
| 136 | 136 | #define REG_PTR(insn, pos, regs) \ |
| 137 | 137 | (ulong *)((ulong)(regs) + REG_OFFSET(insn, pos)) |
| 138 | 138 | |
| 139 | −#define GET_RM(insn) (((insn) >> 12) & 7) | |
| 140 | − | |
| 141 | 139 | #define GET_RS1(insn, regs) (*REG_PTR(insn, SH_RS1, regs)) |
| 142 | 140 | #define GET_RS2(insn, regs) (*REG_PTR(insn, SH_RS2, regs)) |
| 143 | 141 | #define GET_RS1S(insn, regs) (*REG_PTR(RVC_RS1S(insn), 0, regs)) |
| @@ -18,6 +18,7 @@ obj-vdso = $(patsubst %, %.o, $(vdso-syms)) note.o · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | ccflags-y := -fno-stack-protector |
| 20 | 20 | ccflags-y += -DDISABLE_BRANCH_PROFILING |
| 21 | +ccflags-y += -fno-builtin | |
| 21 | 22 | |
| 22 | 23 | ifneq ($(c-gettimeofday-y),) |
| 23 | 24 | CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y) |
| @@ -55,7 +55,7 @@ struct imsic { · 54 unmodified lines | ||
| 55 | 55 | /* IMSIC SW-file */ |
| 56 | 56 | struct imsic_mrif *swfile; |
| 57 | 57 | phys_addr_t swfile_pa; |
| 58 | − spinlock_t swfile_extirq_lock; | |
| 58 | + raw_spinlock_t swfile_extirq_lock; | |
| 59 | 59 | }; |
| 60 | 60 | |
| 61 | 61 | #define imsic_vs_csr_read(__c) \ |
| @@ -622,7 +622,7 @@ static void imsic_swfile_extirq_update(struct kvm_vcpu *vcpu) · 560 unmodified lines | ||
| 622 | 622 | * interruptions between reading topei and updating pending status. |
| 623 | 623 | */ |
| 624 | 624 | |
| 625 | − spin_lock_irqsave(&imsic->swfile_extirq_lock, flags); | |
| 625 | + raw_spin_lock_irqsave(&imsic->swfile_extirq_lock, flags); | |
| 626 | 626 | |
| 627 | 627 | if (imsic_mrif_atomic_read(mrif, &mrif->eidelivery) && |
| 628 | 628 | imsic_mrif_topei(mrif, imsic->nr_eix, imsic->nr_msis)) |
| @@ -630,7 +630,7 @@ static void imsic_swfile_extirq_update(struct kvm_vcpu *vcpu) · 1 unmodified line | ||
| 630 | 630 | else |
| 631 | 631 | kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT); |
| 632 | 632 | |
| 633 | − spin_unlock_irqrestore(&imsic->swfile_extirq_lock, flags); | |
| 633 | + raw_spin_unlock_irqrestore(&imsic->swfile_extirq_lock, flags); | |
| 634 | 634 | } |
| 635 | 635 | |
| 636 | 636 | static void imsic_swfile_read(struct kvm_vcpu *vcpu, bool clear, |
| @@ -1051,7 +1051,7 @@ int kvm_riscv_vcpu_aia_imsic_init(struct kvm_vcpu *vcpu) · 414 unmodified lines | ||
| 1051 | 1051 | } |
| 1052 | 1052 | imsic->swfile = page_to_virt(swfile_page); |
| 1053 | 1053 | imsic->swfile_pa = page_to_phys(swfile_page); |
| 1054 | − spin_lock_init(&imsic->swfile_extirq_lock); | |
| 1054 | + raw_spin_lock_init(&imsic->swfile_extirq_lock); | |
| 1055 | 1055 | |
| 1056 | 1056 | /* Setup IO device */ |
| 1057 | 1057 | kvm_iodevice_init(&imsic->iodev, &imsic_iodoev_ops); |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | ||
| 18 | 18 | #define RV_MAX_REG_ARGS 8 |
| 19 | 19 | #define RV_FENTRY_NINSNS 2 |
| 20 | 20 | #define RV_FENTRY_NBYTES (RV_FENTRY_NINSNS * 4) |
| 21 | +#define RV_KCFI_NINSNS (IS_ENABLED(CONFIG_CFI_CLANG) ? 1 : 0) | |
| 21 | 22 | /* imm that allows emit_imm to emit max count insns */ |
| 22 | 23 | #define RV_MAX_COUNT_IMM 0x7FFF7FF7FF7FF7FF |
| 23 | 24 | |
| @@ -271,7 +272,8 @@ static void __build_epilogue(bool is_tail_call, struct rv_jit_context *ctx) · 247 unmodified lines | ||
| 271 | 272 | if (!is_tail_call) |
| 272 | 273 | emit_addiw(RV_REG_A0, RV_REG_A5, 0, ctx); |
| 273 | 274 | emit_jalr(RV_REG_ZERO, is_tail_call ? RV_REG_T3 : RV_REG_RA, |
| 274 | − is_tail_call ? (RV_FENTRY_NINSNS + 1) * 4 : 0, /* skip reserved nops and TCC init */ | |
| 275 | + /* kcfi, fentry and TCC init insns will be skipped on tailcall */ | |
| 276 | + is_tail_call ? (RV_KCFI_NINSNS + RV_FENTRY_NINSNS + 1) * 4 : 0, | |
| 275 | 277 | ctx); |
| 276 | 278 | } |
| 277 | 279 | |
| @@ -548,8 +550,8 @@ static void emit_atomic(u8 rd, u8 rs, s16 off, s32 imm, bool is64, · 270 unmodified lines | ||
| 548 | 550 | rv_lr_w(r0, 0, rd, 0, 0), ctx); |
| 549 | 551 | jmp_offset = ninsns_rvoff(8); |
| 550 | 552 | emit(rv_bne(RV_REG_T2, r0, jmp_offset >> 1), ctx); |
| 551 | − emit(is64 ? rv_sc_d(RV_REG_T3, rs, rd, 0, 0) : | |
| 552 | − rv_sc_w(RV_REG_T3, rs, rd, 0, 0), ctx); | |
| 553 | + emit(is64 ? rv_sc_d(RV_REG_T3, rs, rd, 0, 1) : | |
| 554 | + rv_sc_w(RV_REG_T3, rs, rd, 0, 1), ctx); | |
| 553 | 555 | jmp_offset = ninsns_rvoff(-6); |
| 554 | 556 | emit(rv_bne(RV_REG_T3, 0, jmp_offset >> 1), ctx); |
| 555 | 557 | emit(rv_fence(0x3, 0x3), ctx); |
| @@ -50,7 +50,6 @@ CONFIG_NUMA=y · 49 unmodified lines | ||
| 50 | 50 | CONFIG_HZ_100=y |
| 51 | 51 | CONFIG_CERT_STORE=y |
| 52 | 52 | CONFIG_EXPOLINE=y |
| 53 | −# CONFIG_EXPOLINE_EXTERN is not set | |
| 54 | 53 | CONFIG_EXPOLINE_AUTO=y |
| 55 | 54 | CONFIG_CHSC_SCH=y |
| 56 | 55 | CONFIG_VFIO_CCW=m |
| @@ -95,6 +94,7 @@ CONFIG_BINFMT_MISC=m · 38 unmodified lines | ||
| 95 | 94 | CONFIG_ZSWAP=y |
| 96 | 95 | CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y |
| 97 | 96 | CONFIG_ZSMALLOC_STAT=y |
| 97 | +CONFIG_SLAB_BUCKETS=y | |
| 98 | 98 | CONFIG_SLUB_STATS=y |
| 99 | 99 | # CONFIG_COMPAT_BRK is not set |
| 100 | 100 | CONFIG_MEMORY_HOTPLUG=y |
| @@ -426,6 +426,13 @@ CONFIG_DEVTMPFS_SAFE=y · 325 unmodified lines | ||
| 426 | 426 | # CONFIG_FW_LOADER is not set |
| 427 | 427 | CONFIG_CONNECTOR=y |
| 428 | 428 | CONFIG_ZRAM=y |
| 429 | +CONFIG_ZRAM_BACKEND_LZ4=y | |
| 430 | +CONFIG_ZRAM_BACKEND_LZ4HC=y | |
| 431 | +CONFIG_ZRAM_BACKEND_ZSTD=y | |
| 432 | +CONFIG_ZRAM_BACKEND_DEFLATE=y | |
| 433 | +CONFIG_ZRAM_BACKEND_842=y | |
| 434 | +CONFIG_ZRAM_BACKEND_LZO=y | |
| 435 | +CONFIG_ZRAM_DEF_COMP_DEFLATE=y | |
| 429 | 436 | CONFIG_BLK_DEV_LOOP=m |
| 430 | 437 | CONFIG_BLK_DEV_DRBD=m |
| 431 | 438 | CONFIG_BLK_DEV_NBD=m |
| @@ -486,6 +493,7 @@ CONFIG_DM_UEVENT=y · 54 unmodified lines | ||
| 486 | 493 | CONFIG_DM_FLAKEY=m |
| 487 | 494 | CONFIG_DM_VERITY=m |
| 488 | 495 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y |
| 496 | +CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING=y | |
| 489 | 497 | CONFIG_DM_SWITCH=m |
| 490 | 498 | CONFIG_DM_INTEGRITY=m |
| 491 | 499 | CONFIG_DM_VDO=m |
| @@ -535,6 +543,7 @@ CONFIG_NLMON=m · 43 unmodified lines | ||
| 535 | 543 | CONFIG_MLX4_EN=m |
| 536 | 544 | CONFIG_MLX5_CORE=m |
| 537 | 545 | CONFIG_MLX5_CORE_EN=y |
| 546 | +# CONFIG_NET_VENDOR_META is not set | |
| 538 | 547 | # CONFIG_NET_VENDOR_MICREL is not set |
| 539 | 548 | # CONFIG_NET_VENDOR_MICROCHIP is not set |
| 540 | 549 | # CONFIG_NET_VENDOR_MICROSEMI is not set |
| @@ -695,6 +704,7 @@ CONFIG_NFSD=m · 154 unmodified lines | ||
| 695 | 704 | CONFIG_NFSD_V3_ACL=y |
| 696 | 705 | CONFIG_NFSD_V4=y |
| 697 | 706 | CONFIG_NFSD_V4_SECURITY_LABEL=y |
| 707 | +# CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set | |
| 698 | 708 | CONFIG_CIFS=m |
| 699 | 709 | CONFIG_CIFS_UPCALL=y |
| 700 | 710 | CONFIG_CIFS_XATTR=y |
| @@ -740,7 +750,6 @@ CONFIG_CRYPTO_DH=m · 39 unmodified lines | ||
| 740 | 750 | CONFIG_CRYPTO_ECDH=m |
| 741 | 751 | CONFIG_CRYPTO_ECDSA=m |
| 742 | 752 | CONFIG_CRYPTO_ECRDSA=m |
| 743 | −CONFIG_CRYPTO_SM2=m | |
| 744 | 753 | CONFIG_CRYPTO_CURVE25519=m |
| 745 | 754 | CONFIG_CRYPTO_AES_TI=m |
| 746 | 755 | CONFIG_CRYPTO_ANUBIS=m |
| @@ -48,7 +48,6 @@ CONFIG_NUMA=y · 47 unmodified lines | ||
| 48 | 48 | CONFIG_HZ_100=y |
| 49 | 49 | CONFIG_CERT_STORE=y |
| 50 | 50 | CONFIG_EXPOLINE=y |
| 51 | −# CONFIG_EXPOLINE_EXTERN is not set | |
| 52 | 51 | CONFIG_EXPOLINE_AUTO=y |
| 53 | 52 | CONFIG_CHSC_SCH=y |
| 54 | 53 | CONFIG_VFIO_CCW=m |
| @@ -89,6 +88,7 @@ CONFIG_BINFMT_MISC=m · 34 unmodified lines | ||
| 89 | 88 | CONFIG_ZSWAP=y |
| 90 | 89 | CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y |
| 91 | 90 | CONFIG_ZSMALLOC_STAT=y |
| 91 | +CONFIG_SLAB_BUCKETS=y | |
| 92 | 92 | # CONFIG_COMPAT_BRK is not set |
| 93 | 93 | CONFIG_MEMORY_HOTPLUG=y |
| 94 | 94 | CONFIG_MEMORY_HOTREMOVE=y |
| @@ -416,6 +416,13 @@ CONFIG_DEVTMPFS_SAFE=y · 321 unmodified lines | ||
| 416 | 416 | # CONFIG_FW_LOADER is not set |
| 417 | 417 | CONFIG_CONNECTOR=y |
| 418 | 418 | CONFIG_ZRAM=y |
| 419 | +CONFIG_ZRAM_BACKEND_LZ4=y | |
| 420 | +CONFIG_ZRAM_BACKEND_LZ4HC=y | |
| 421 | +CONFIG_ZRAM_BACKEND_ZSTD=y | |
| 422 | +CONFIG_ZRAM_BACKEND_DEFLATE=y | |
| 423 | +CONFIG_ZRAM_BACKEND_842=y | |
| 424 | +CONFIG_ZRAM_BACKEND_LZO=y | |
| 425 | +CONFIG_ZRAM_DEF_COMP_DEFLATE=y | |
| 419 | 426 | CONFIG_BLK_DEV_LOOP=m |
| 420 | 427 | CONFIG_BLK_DEV_DRBD=m |
| 421 | 428 | CONFIG_BLK_DEV_NBD=m |
| @@ -476,6 +483,7 @@ CONFIG_DM_UEVENT=y · 54 unmodified lines | ||
| 476 | 483 | CONFIG_DM_FLAKEY=m |
| 477 | 484 | CONFIG_DM_VERITY=m |
| 478 | 485 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y |
| 486 | +CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING=y | |
| 479 | 487 | CONFIG_DM_SWITCH=m |
| 480 | 488 | CONFIG_DM_INTEGRITY=m |
| 481 | 489 | CONFIG_DM_VDO=m |
| @@ -525,6 +533,7 @@ CONFIG_NLMON=m · 43 unmodified lines | ||
| 525 | 533 | CONFIG_MLX4_EN=m |
| 526 | 534 | CONFIG_MLX5_CORE=m |
| 527 | 535 | CONFIG_MLX5_CORE_EN=y |
| 536 | +# CONFIG_NET_VENDOR_META is not set | |
| 528 | 537 | # CONFIG_NET_VENDOR_MICREL is not set |
| 529 | 538 | # CONFIG_NET_VENDOR_MICROCHIP is not set |
| 530 | 539 | # CONFIG_NET_VENDOR_MICROSEMI is not set |
| @@ -682,6 +691,7 @@ CONFIG_NFSD=m · 151 unmodified lines | ||
| 682 | 691 | CONFIG_NFSD_V3_ACL=y |
| 683 | 692 | CONFIG_NFSD_V4=y |
| 684 | 693 | CONFIG_NFSD_V4_SECURITY_LABEL=y |
| 694 | +# CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set | |
| 685 | 695 | CONFIG_CIFS=m |
| 686 | 696 | CONFIG_CIFS_UPCALL=y |
| 687 | 697 | CONFIG_CIFS_XATTR=y |
| @@ -726,7 +736,6 @@ CONFIG_CRYPTO_DH=m · 38 unmodified lines | ||
| 726 | 736 | CONFIG_CRYPTO_ECDH=m |
| 727 | 737 | CONFIG_CRYPTO_ECDSA=m |
| 728 | 738 | CONFIG_CRYPTO_ECRDSA=m |
| 729 | −CONFIG_CRYPTO_SM2=m | |
| 730 | 739 | CONFIG_CRYPTO_CURVE25519=m |
| 731 | 740 | CONFIG_CRYPTO_AES_TI=m |
| 732 | 741 | CONFIG_CRYPTO_ANUBIS=m |
| @@ -767,6 +776,7 @@ CONFIG_CRYPTO_LZ4=m · 34 unmodified lines | ||
| 767 | 776 | CONFIG_CRYPTO_LZ4HC=m |
| 768 | 777 | CONFIG_CRYPTO_ZSTD=m |
| 769 | 778 | CONFIG_CRYPTO_ANSI_CPRNG=m |
| 779 | +CONFIG_CRYPTO_JITTERENTROPY_OSR=1 | |
| 770 | 780 | CONFIG_CRYPTO_USER_API_HASH=m |
| 771 | 781 | CONFIG_CRYPTO_USER_API_SKCIPHER=m |
| 772 | 782 | CONFIG_CRYPTO_USER_API_RNG=m |
| @@ -49,6 +49,7 @@ CONFIG_ZFCP=y · 48 unmodified lines | ||
| 49 | 49 | # CONFIG_HVC_IUCV is not set |
| 50 | 50 | # CONFIG_HW_RANDOM_S390 is not set |
| 51 | 51 | # CONFIG_HMC_DRV is not set |
| 52 | +# CONFIG_S390_UV_UAPI is not set | |
| 52 | 53 | # CONFIG_S390_TAPE is not set |
| 53 | 54 | # CONFIG_VMCP is not set |
| 54 | 55 | # CONFIG_MONWRITER is not set |
| @@ -16,8 +16,10 @@ · 15 unmodified lines | ||
| 16 | 16 | #include <asm/pci_io.h> |
| 17 | 17 | |
| 18 | 18 | #define xlate_dev_mem_ptr xlate_dev_mem_ptr |
| 19 | +#define kc_xlate_dev_mem_ptr xlate_dev_mem_ptr | |
| 19 | 20 | void *xlate_dev_mem_ptr(phys_addr_t phys); |
| 20 | 21 | #define unxlate_dev_mem_ptr unxlate_dev_mem_ptr |
| 22 | +#define kc_unxlate_dev_mem_ptr unxlate_dev_mem_ptr | |
| 21 | 23 | void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr); |
| 22 | 24 | |
| 23 | 25 | #define IO_SPACE_LIMIT 0 |
| @@ -49,6 +49,7 @@ struct perf_sf_sde_regs { · 48 unmodified lines | ||
| 49 | 49 | }; |
| 50 | 50 | |
| 51 | 51 | #define perf_arch_fetch_caller_regs(regs, __ip) do { \ |
| 52 | + (regs)->psw.mask = 0; \ | |
| 52 | 53 | (regs)->psw.addr = (__ip); \ |
| 53 | 54 | (regs)->gprs[15] = (unsigned long)__builtin_frame_address(0) - \ |
| 54 | 55 | offsetof(struct stack_frame, back_chain); \ |
| @@ -77,7 +77,7 @@ static int __diag_page_ref_service(struct kvm_vcpu *vcpu) · 76 unmodified lines | ||
| 77 | 77 | vcpu->stat.instruction_diagnose_258++; |
| 78 | 78 | if (vcpu->run->s.regs.gprs[rx] & 7) |
| 79 | 79 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); |
| 80 | − rc = read_guest(vcpu, vcpu->run->s.regs.gprs[rx], rx, &parm, sizeof(parm)); | |
| 80 | + rc = read_guest_real(vcpu, vcpu->run->s.regs.gprs[rx], &parm, sizeof(parm)); | |
| 81 | 81 | if (rc) |
| 82 | 82 | return kvm_s390_inject_prog_cond(vcpu, rc); |
| 83 | 83 | if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258) |
| @@ -828,6 +828,8 @@ static int access_guest_page(struct kvm *kvm, enum gacc_mode mode, gpa_t gpa, · 827 unmodified lines | ||
| 828 | 828 | const gfn_t gfn = gpa_to_gfn(gpa); |
| 829 | 829 | int rc; |
| 830 | 830 | |
| 831 | + if (!gfn_to_memslot(kvm, gfn)) | |
| 832 | + return PGM_ADDRESSING; | |
| 831 | 833 | if (mode == GACC_STORE) |
| 832 | 834 | rc = kvm_write_guest_page(kvm, gfn, data, offset, len); |
| 833 | 835 | else |
| @@ -985,6 +987,8 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, · 151 unmodified lines | ||
| 985 | 987 | gra += fragment_len; |
| 986 | 988 | data += fragment_len; |
| 987 | 989 | } |
| 990 | + if (rc > 0) | |
| 991 | + vcpu->arch.pgm.code = rc; | |
| 988 | 992 | return rc; |
| 989 | 993 | } |
| 990 | 994 | |
| @@ -405,11 +405,12 @@ int read_guest_abs(struct kvm_vcpu *vcpu, unsigned long gpa, void *data, · 404 unmodified lines | ||
| 405 | 405 | * @len: number of bytes to copy |
| 406 | 406 | * |
| 407 | 407 | * Copy @len bytes from @data (kernel space) to @gra (guest real address). |
| 408 | − * It is up to the caller to ensure that the entire guest memory range is | |
| 409 | − * valid memory before calling this function. | |
| 410 | 408 | * Guest low address and key protection are not checked. |
| 411 | 409 | * |
| 412 | − * Returns zero on success or -EFAULT on error. | |
| 410 | + * Returns zero on success, -EFAULT when copying from @data failed, or | |
| 411 | + * PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info | |
| 412 | + * is also stored to allow injecting into the guest (if applicable) using | |
| 413 | + * kvm_s390_inject_prog_cond(). | |
| 413 | 414 | * |
| 414 | 415 | * If an error occurs data may have been copied partially to guest memory. |
| 415 | 416 | */ |
| @@ -428,11 +429,12 @@ int write_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, void *data, · 12 unmodified lines | ||
| 428 | 429 | * @len: number of bytes to copy |
| 429 | 430 | * |
| 430 | 431 | * Copy @len bytes from @gra (guest real address) to @data (kernel space). |
| 431 | − * It is up to the caller to ensure that the entire guest memory range is | |
| 432 | − * valid memory before calling this function. | |
| 433 | 432 | * Guest key protection is not checked. |
| 434 | 433 | * |
| 435 | − * Returns zero on success or -EFAULT on error. | |
| 434 | + * Returns zero on success, -EFAULT when copying to @data failed, or | |
| 435 | + * PGM_ADRESSING in case @gra is outside a memslot. In this case, pgm check info | |
| 436 | + * is also stored to allow injecting into the guest (if applicable) using | |
| 437 | + * kvm_s390_inject_prog_cond(). | |
| 436 | 438 | * |
| 437 | 439 | * If an error occurs data may have been copied partially to kernel space. |
| 438 | 440 | */ |
| @@ -280,18 +280,19 @@ static void __zpci_event_error(struct zpci_ccdf_err *ccdf) · 279 unmodified lines | ||
| 280 | 280 | goto no_pdev; |
| 281 | 281 | |
| 282 | 282 | switch (ccdf->pec) { |
| 283 | − case 0x003a: /* Service Action or Error Recovery Successful */ | |
| 283 | + case 0x002a: /* Error event concerns FMB */ | |
| 284 | + case 0x002b: | |
| 285 | + case 0x002c: | |
| 286 | + break; | |
| 287 | + case 0x0040: /* Service Action or Error Recovery Failed */ | |
| 288 | + case 0x003b: | |
| 289 | + zpci_event_io_failure(pdev, pci_channel_io_perm_failure); | |
| 290 | + break; | |
| 291 | + default: /* PCI function left in the error state attempt to recover */ | |
| 284 | 292 | ers_res = zpci_event_attempt_error_recovery(pdev); |
| 285 | 293 | if (ers_res != PCI_ERS_RESULT_RECOVERED) |
| 286 | 294 | zpci_event_io_failure(pdev, pci_channel_io_perm_failure); |
| 287 | 295 | break; |
| 288 | − default: | |
| 289 | − /* | |
| 290 | − * Mark as frozen not permanently failed because the device | |
| 291 | − * could be subsequently recovered by the platform. | |
| 292 | − */ | |
| 293 | − zpci_event_io_failure(pdev, pci_channel_io_frozen); | |
| 294 | − break; | |
| 295 | 296 | } |
| 296 | 297 | pci_dev_put(pdev); |
| 297 | 298 | no_pdev: |
| @@ -2257,6 +2257,7 @@ config RANDOMIZE_MEMORY_PHYSICAL_PADDING · 2256 unmodified lines | ||
| 2257 | 2257 | config ADDRESS_MASKING |
| 2258 | 2258 | bool "Linear Address Masking support" |
| 2259 | 2259 | depends on X86_64 |
| 2260 | + depends on COMPILE_TEST || !CPU_MITIGATIONS # wait for LASS | |
| 2260 | 2261 | help |
| 2261 | 2262 | Linear Address Masking (LAM) modifies the checking that is applied |
| 2262 | 2263 | to 64-bit linear addresses, allowing software to use of the |
| @@ -9,6 +9,8 @@ · 8 unmodified lines | ||
| 9 | 9 | #include <asm/unwind_hints.h> |
| 10 | 10 | #include <asm/segment.h> |
| 11 | 11 | #include <asm/cache.h> |
| 12 | +#include <asm/cpufeatures.h> | |
| 13 | +#include <asm/nospec-branch.h> | |
| 12 | 14 | |
| 13 | 15 | #include "calling.h" |
| 14 | 16 | |
| @@ -19,6 +21,9 @@ SYM_FUNC_START(entry_ibpb) · 4 unmodified lines | ||
| 19 | 21 | movl $PRED_CMD_IBPB, %eax |
| 20 | 22 | xorl %edx, %edx |
| 21 | 23 | wrmsr |
| 24 | + | |
| 25 | + /* Make sure IBPB clears return stack preductions too. */ | |
| 26 | + FILL_RETURN_BUFFER %rax, RSB_CLEAR_LOOPS, X86_BUG_IBPB_NO_RET | |
| 22 | 27 | RET |
| 23 | 28 | SYM_FUNC_END(entry_ibpb) |
| 24 | 29 | /* For KVM */ |
| @@ -871,6 +871,8 @@ SYM_FUNC_START(entry_SYSENTER_32) · 870 unmodified lines | ||
| 871 | 871 | |
| 872 | 872 | /* Now ready to switch the cr3 */ |
| 873 | 873 | SWITCH_TO_USER_CR3 scratch_reg=%eax |
| 874 | + /* Clobbers ZF */ | |
| 875 | + CLEAR_CPU_BUFFERS | |
| 874 | 876 | |
| 875 | 877 | /* |
| 876 | 878 | * Restore all flags except IF. (We restore IF separately because |
| @@ -881,7 +883,6 @@ SYM_FUNC_START(entry_SYSENTER_32) · 4 unmodified lines | ||
| 881 | 883 | BUG_IF_WRONG_CR3 no_user_check=1 |
| 882 | 884 | popfl |
| 883 | 885 | popl %eax |
| 884 | − CLEAR_CPU_BUFFERS | |
| 885 | 886 | |
| 886 | 887 | /* |
| 887 | 888 | * Return back to the vDSO, which will pop ecx and edx. |
| @@ -1144,7 +1145,6 @@ SYM_CODE_START(asm_exc_nmi) · 256 unmodified lines | ||
| 1144 | 1145 | |
| 1145 | 1146 | /* Not on SYSENTER stack. */ |
| 1146 | 1147 | call exc_nmi |
| 1147 | − CLEAR_CPU_BUFFERS | |
| 1148 | 1148 | jmp .Lnmi_return |
| 1149 | 1149 | |
| 1150 | 1150 | .Lnmi_from_sysenter_stack: |
| @@ -1165,6 +1165,7 @@ SYM_CODE_START(asm_exc_nmi) · 14 unmodified lines | ||
| 1165 | 1165 | |
| 1166 | 1166 | CHECK_AND_APPLY_ESPFIX |
| 1167 | 1167 | RESTORE_ALL_NMI cr3_reg=%edi pop=4 |
| 1168 | + CLEAR_CPU_BUFFERS | |
| 1168 | 1169 | jmp .Lirq_return |
| 1169 | 1170 | |
| 1170 | 1171 | #ifdef CONFIG_X86_ESPFIX32 |
| @@ -1206,6 +1207,7 @@ SYM_CODE_START(asm_exc_nmi) · 35 unmodified lines | ||
| 1206 | 1207 | * 1 - orig_ax |
| 1207 | 1208 | */ |
| 1208 | 1209 | lss (1+5+6)*4(%esp), %esp # back to espfix stack |
| 1210 | + CLEAR_CPU_BUFFERS | |
| 1209 | 1211 | jmp .Lirq_return |
| 1210 | 1212 | #endif |
| 1211 | 1213 | SYM_CODE_END(asm_exc_nmi) |
| @@ -116,7 +116,10 @@ static inline bool amd_gart_present(void) · 115 unmodified lines | ||
| 116 | 116 | |
| 117 | 117 | #define amd_nb_num(x) 0 |
| 118 | 118 | #define amd_nb_has_feature(x) false |
| 119 | −#define node_to_amd_nb(x) NULL | |
| 119 | +static inline struct amd_northbridge *node_to_amd_nb(int node) | |
| 120 | +{ | |
| 121 | + return NULL; | |
| 122 | +} | |
| 120 | 123 | #define amd_gart_present(x) false |
| 121 | 124 | |
| 122 | 125 | #endif |
| @@ -215,7 +215,7 @@ · 214 unmodified lines | ||
| 215 | 215 | #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* Disable Speculative Store Bypass. */ |
| 216 | 216 | #define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* AMD SSBD implementation via LS_CFG MSR */ |
| 217 | 217 | #define X86_FEATURE_IBRS ( 7*32+25) /* "ibrs" Indirect Branch Restricted Speculation */ |
| 218 | −#define X86_FEATURE_IBPB ( 7*32+26) /* "ibpb" Indirect Branch Prediction Barrier */ | |
| 218 | +#define X86_FEATURE_IBPB ( 7*32+26) /* "ibpb" Indirect Branch Prediction Barrier without a guaranteed RSB flush */ | |
| 219 | 219 | #define X86_FEATURE_STIBP ( 7*32+27) /* "stibp" Single Thread Indirect Branch Predictors */ |
| 220 | 220 | #define X86_FEATURE_ZEN ( 7*32+28) /* Generic flag for all Zen and newer */ |
| 221 | 221 | #define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* L1TF workaround PTE inversion */ |
| @@ -348,6 +348,7 @@ · 126 unmodified lines | ||
| 348 | 348 | #define X86_FEATURE_CPPC (13*32+27) /* "cppc" Collaborative Processor Performance Control */ |
| 349 | 349 | #define X86_FEATURE_AMD_PSFD (13*32+28) /* Predictive Store Forwarding Disable */ |
| 350 | 350 | #define X86_FEATURE_BTC_NO (13*32+29) /* Not vulnerable to Branch Type Confusion */ |
| 351 | +#define X86_FEATURE_AMD_IBPB_RET (13*32+30) /* IBPB clears return address predictor */ | |
| 351 | 352 | #define X86_FEATURE_BRS (13*32+31) /* "brs" Branch Sampling available */ |
| 352 | 353 | |
| 353 | 354 | /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ |
| @@ -523,4 +524,5 @@ · 169 unmodified lines | ||
| 523 | 524 | #define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* "div0" AMD DIV0 speculation bug */ |
| 524 | 525 | #define X86_BUG_RFDS X86_BUG(1*32 + 2) /* "rfds" CPU is vulnerable to Register File Data Sampling */ |
| 525 | 526 | #define X86_BUG_BHI X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */ |
| 527 | +#define X86_BUG_IBPB_NO_RET X86_BUG(1*32 + 4) /* "ibpb_no_ret" IBPB omits return target predictions */ | |
| 526 | 528 | #endif /* _ASM_X86_CPUFEATURES_H */ |
| @@ -323,7 +323,16 @@ · 322 unmodified lines | ||
| 323 | 323 | * Note: Only the memory operand variant of VERW clears the CPU buffers. |
| 324 | 324 | */ |
| 325 | 325 | .macro CLEAR_CPU_BUFFERS |
| 326 | − ALTERNATIVE "", __stringify(verw _ASM_RIP(mds_verw_sel)), X86_FEATURE_CLEAR_CPU_BUF | |
| 326 | +#ifdef CONFIG_X86_64 | |
| 327 | + ALTERNATIVE "", "verw mds_verw_sel(%rip)", X86_FEATURE_CLEAR_CPU_BUF | |
| 328 | +#else | |
| 329 | + /* | |
| 330 | + * In 32bit mode, the memory operand must be a %cs reference. The data | |
| 331 | + * segments may not be usable (vm86 mode), and the stack segment may not | |
| 332 | + * be flat (ESPFIX32). | |
| 333 | + */ | |
| 334 | + ALTERNATIVE "", "verw %cs:mds_verw_sel", X86_FEATURE_CLEAR_CPU_BUF | |
| 335 | +#endif | |
| 327 | 336 | .endm |
| 328 | 337 | |
| 329 | 338 | #ifdef CONFIG_X86_64 |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | typeof(sym) __ret; \ |
| 7 | 7 | asm_inline("mov %1,%0\n1:\n" \ |
| 8 | 8 | ".pushsection runtime_ptr_" #sym ",\"a\"\n\t" \ |
| 9 | − ".long 1b - %c2 - .\n\t" \ | |
| 9 | + ".long 1b - %c2 - .\n" \ | |
| 10 | 10 | ".popsection" \ |
| 11 | 11 | :"=r" (__ret) \ |
| 12 | 12 | :"i" ((unsigned long)0x0123456789abcdefull), \ |
| @@ -20,7 +20,7 @@ · 7 unmodified lines | ||
| 20 | 20 | typeof(0u+(val)) __ret = (val); \ |
| 21 | 21 | asm_inline("shrl $12,%k0\n1:\n" \ |
| 22 | 22 | ".pushsection runtime_shift_" #sym ",\"a\"\n\t" \ |
| 23 | − ".long 1b - 1 - .\n\t" \ | |
| 23 | + ".long 1b - 1 - .\n" \ | |
| 24 | 24 | ".popsection" \ |
| 25 | 25 | :"+r" (__ret)); \ |
| 26 | 26 | __ret; }) |
| @@ -12,6 +12,13 @@ · 11 unmodified lines | ||
| 12 | 12 | #include <asm/cpufeatures.h> |
| 13 | 13 | #include <asm/page.h> |
| 14 | 14 | #include <asm/percpu.h> |
| 15 | +#include <asm/runtime-const.h> | |
| 16 | + | |
| 17 | +/* | |
| 18 | + * Virtual variable: there's no actual backing store for this, | |
| 19 | + * it can purely be used as 'runtime_const_ptr(USER_PTR_MAX)' | |
| 20 | + */ | |
| 21 | +extern unsigned long USER_PTR_MAX; | |
| 15 | 22 | |
| 16 | 23 | #ifdef CONFIG_ADDRESS_MASKING |
| 17 | 24 | /* |
| @@ -46,19 +53,24 @@ static inline unsigned long __untagged_addr_remote(struct mm_struct *mm, · 28 unmodified lines | ||
| 46 | 53 | |
| 47 | 54 | #endif |
| 48 | 55 | |
| 49 | −/* | |
| 50 | − * The virtual address space space is logically divided into a kernel | |
| 51 | − * half and a user half. When cast to a signed type, user pointers | |
| 52 | − * are positive and kernel pointers are negative. | |
| 53 | − */ | |
| 54 | −#define valid_user_address(x) ((__force long)(x) >= 0) | |
| 56 | +#define valid_user_address(x) \ | |
| 57 | + ((__force unsigned long)(x) <= runtime_const_ptr(USER_PTR_MAX)) | |
| 55 | 58 | |
| 56 | 59 | /* |
| 57 | 60 | * Masking the user address is an alternative to a conditional |
| 58 | 61 | * user_access_begin that can avoid the fencing. This only works |
| 59 | 62 | * for dense accesses starting at the address. |
| 60 | 63 | */ |
| 61 | −#define mask_user_address(x) ((typeof(x))((long)(x)|((long)(x)>>63))) | |
| 64 | +static inline void __user *mask_user_address(const void __user *ptr) | |
| 65 | +{ | |
| 66 | + unsigned long mask; | |
| 67 | + asm("cmp %1,%0\n\t" | |
| 68 | + "sbb %0,%0" | |
| 69 | + :"=r" (mask) | |
| 70 | + :"r" (ptr), | |
| 71 | + "0" (runtime_const_ptr(USER_PTR_MAX))); | |
| 72 | + return (__force void __user *)(mask | (__force unsigned long)ptr); | |
| 73 | +} | |
| 62 | 74 | #define masked_user_access_begin(x) ({ \ |
| 63 | 75 | __auto_type __masked_ptr = (x); \ |
| 64 | 76 | __masked_ptr = mask_user_address(__masked_ptr); \ |
| @@ -69,23 +81,16 @@ static inline unsigned long __untagged_addr_remote(struct mm_struct *mm, · 4 unmodified lines | ||
| 69 | 81 | * arbitrary values in those bits rather then masking them off. |
| 70 | 82 | * |
| 71 | 83 | * Enforce two rules: |
| 72 | − * 1. 'ptr' must be in the user half of the address space | |
| 84 | + * 1. 'ptr' must be in the user part of the address space | |
| 73 | 85 | * 2. 'ptr+size' must not overflow into kernel addresses |
| 74 | 86 | * |
| 75 | − * Note that addresses around the sign change are not valid addresses, | |
| 76 | − * and will GP-fault even with LAM enabled if the sign bit is set (see | |
| 77 | − * "CR3.LAM_SUP" that can narrow the canonicality check if we ever | |
| 78 | − * enable it, but not remove it entirely). | |
| 79 | − * | |
| 80 | − * So the "overflow into kernel addresses" does not imply some sudden | |
| 81 | − * exact boundary at the sign bit, and we can allow a lot of slop on the | |
| 82 | − * size check. | |
| 87 | + * Note that we always have at least one guard page between the | |
| 88 | + * max user address and the non-canonical gap, allowing us to | |
| 89 | + * ignore small sizes entirely. | |
| 83 | 90 | * |
| 84 | 91 | * In fact, we could probably remove the size check entirely, since |
| 85 | 92 | * any kernel accesses will be in increasing address order starting |
| 86 | − * at 'ptr', and even if the end might be in kernel space, we'll | |
| 87 | − * hit the GP faults for non-canonical accesses before we ever get | |
| 88 | − * there. | |
| 93 | + * at 'ptr'. | |
| 89 | 94 | * |
| 90 | 95 | * That's a separate optimization, for now just handle the small |
| 91 | 96 | * constant case. |
| @@ -44,6 +44,7 @@ · 43 unmodified lines | ||
| 44 | 44 | #define PCI_DEVICE_ID_AMD_19H_M70H_DF_F4 0x14f4 |
| 45 | 45 | #define PCI_DEVICE_ID_AMD_19H_M78H_DF_F4 0x12fc |
| 46 | 46 | #define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4 0x12c4 |
| 47 | +#define PCI_DEVICE_ID_AMD_1AH_M20H_DF_F4 0x16fc | |
| 47 | 48 | #define PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4 0x124c |
| 48 | 49 | #define PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4 0x12bc |
| 49 | 50 | #define PCI_DEVICE_ID_AMD_MI200_DF_F4 0x14d4 |
| @@ -127,6 +128,7 @@ static const struct pci_device_id amd_nb_link_ids[] = { · 77 unmodified lines | ||
| 127 | 128 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F4) }, |
| 128 | 129 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) }, |
| 129 | 130 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4) }, |
| 131 | + { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M20H_DF_F4) }, | |
| 130 | 132 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4) }, |
| 131 | 133 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4) }, |
| 132 | 134 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F4) }, |
| @@ -440,7 +440,19 @@ static int lapic_timer_shutdown(struct clock_event_device *evt) · 439 unmodified lines | ||
| 440 | 440 | v = apic_read(APIC_LVTT); |
| 441 | 441 | v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); |
| 442 | 442 | apic_write(APIC_LVTT, v); |
| 443 | − apic_write(APIC_TMICT, 0); | |
| 443 | + | |
| 444 | + /* | |
| 445 | + * Setting APIC_LVT_MASKED (above) should be enough to tell | |
| 446 | + * the hardware that this timer will never fire. But AMD | |
| 447 | + * erratum 411 and some Intel CPU behavior circa 2024 say | |
| 448 | + * otherwise. Time for belt and suspenders programming: mask | |
| 449 | + * the timer _and_ zero the counter registers: | |
| 450 | + */ | |
| 451 | + if (v & APIC_LVT_TIMER_TSCDEADLINE) | |
| 452 | + wrmsrl(MSR_IA32_TSC_DEADLINE, 0); | |
| 453 | + else | |
| 454 | + apic_write(APIC_TMICT, 0); | |
| 455 | + | |
| 444 | 456 | return 0; |
| 445 | 457 | } |
| 446 | 458 | |
| @@ -1202,5 +1202,6 @@ void amd_check_microcode(void) · 1201 unmodified lines | ||
| 1202 | 1202 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) |
| 1203 | 1203 | return; |
| 1204 | 1204 | |
| 1205 | − on_each_cpu(zenbleed_check_cpu, NULL, 1); | |
| 1205 | + if (cpu_feature_enabled(X86_FEATURE_ZEN2)) | |
| 1206 | + on_each_cpu(zenbleed_check_cpu, NULL, 1); | |
| 1206 | 1207 | } |
| @@ -1115,8 +1115,25 @@ do_cmd_auto: · 1114 unmodified lines | ||
| 1115 | 1115 | |
| 1116 | 1116 | case RETBLEED_MITIGATION_IBPB: |
| 1117 | 1117 | setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); |
| 1118 | + | |
| 1119 | + /* | |
| 1120 | + * IBPB on entry already obviates the need for | |
| 1121 | + * software-based untraining so clear those in case some | |
| 1122 | + * other mitigation like SRSO has selected them. | |
| 1123 | + */ | |
| 1124 | + setup_clear_cpu_cap(X86_FEATURE_UNRET); | |
| 1125 | + setup_clear_cpu_cap(X86_FEATURE_RETHUNK); | |
| 1126 | + | |
| 1118 | 1127 | setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); |
| 1119 | 1128 | mitigate_smt = true; |
| 1129 | + | |
| 1130 | + /* | |
| 1131 | + * There is no need for RSB filling: entry_ibpb() ensures | |
| 1132 | + * all predictions, including the RSB, are invalidated, | |
| 1133 | + * regardless of IBPB implementation. | |
| 1134 | + */ | |
| 1135 | + setup_clear_cpu_cap(X86_FEATURE_RSB_VMEXIT); | |
| 1136 | + | |
| 1120 | 1137 | break; |
| 1121 | 1138 | |
| 1122 | 1139 | case RETBLEED_MITIGATION_STUFF: |
| @@ -2627,6 +2644,14 @@ static void __init srso_select_mitigation(void) · 1504 unmodified lines | ||
| 2627 | 2644 | if (has_microcode) { |
| 2628 | 2645 | setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); |
| 2629 | 2646 | srso_mitigation = SRSO_MITIGATION_IBPB; |
| 2647 | + | |
| 2648 | + /* | |
| 2649 | + * IBPB on entry already obviates the need for | |
| 2650 | + * software-based untraining so clear those in case some | |
| 2651 | + * other mitigation like Retbleed has selected them. | |
| 2652 | + */ | |
| 2653 | + setup_clear_cpu_cap(X86_FEATURE_UNRET); | |
| 2654 | + setup_clear_cpu_cap(X86_FEATURE_RETHUNK); | |
| 2630 | 2655 | } |
| 2631 | 2656 | } else { |
| 2632 | 2657 | pr_err("WARNING: kernel not compiled with MITIGATION_IBPB_ENTRY.\n"); |
| @@ -2638,6 +2663,13 @@ static void __init srso_select_mitigation(void) · 5 unmodified lines | ||
| 2638 | 2663 | if (!boot_cpu_has(X86_FEATURE_ENTRY_IBPB) && has_microcode) { |
| 2639 | 2664 | setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); |
| 2640 | 2665 | srso_mitigation = SRSO_MITIGATION_IBPB_ON_VMEXIT; |
| 2666 | + | |
| 2667 | + /* | |
| 2668 | + * There is no need for RSB filling: entry_ibpb() ensures | |
| 2669 | + * all predictions, including the RSB, are invalidated, | |
| 2670 | + * regardless of IBPB implementation. | |
| 2671 | + */ | |
| 2672 | + setup_clear_cpu_cap(X86_FEATURE_RSB_VMEXIT); | |
| 2641 | 2673 | } |
| 2642 | 2674 | } else { |
| 2643 | 2675 | pr_err("WARNING: kernel not compiled with MITIGATION_SRSO.\n"); |
| @@ -69,6 +69,7 @@ · 68 unmodified lines | ||
| 69 | 69 | #include <asm/sev.h> |
| 70 | 70 | #include <asm/tdx.h> |
| 71 | 71 | #include <asm/posted_intr.h> |
| 72 | +#include <asm/runtime-const.h> | |
| 72 | 73 | |
| 73 | 74 | #include "cpu.h" |
| 74 | 75 | |
| @@ -1443,6 +1444,9 @@ static void __init cpu_set_bug_bits(struct cpuinfo_x86 *c) · 1368 unmodified lines | ||
| 1443 | 1444 | boot_cpu_has(X86_FEATURE_HYPERVISOR))) |
| 1444 | 1445 | setup_force_cpu_bug(X86_BUG_BHI); |
| 1445 | 1446 | |
| 1447 | + if (cpu_has(c, X86_FEATURE_AMD_IBPB) && !cpu_has(c, X86_FEATURE_AMD_IBPB_RET)) | |
| 1448 | + setup_force_cpu_bug(X86_BUG_IBPB_NO_RET); | |
| 1449 | + | |
| 1446 | 1450 | if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) |
| 1447 | 1451 | return; |
| 1448 | 1452 | |
| @@ -2386,6 +2390,15 @@ void __init arch_cpu_finalize_init(void) · 937 unmodified lines | ||
| 2386 | 2390 | alternative_instructions(); |
| 2387 | 2391 | |
| 2388 | 2392 | if (IS_ENABLED(CONFIG_X86_64)) { |
| 2393 | + unsigned long USER_PTR_MAX = TASK_SIZE_MAX-1; | |
| 2394 | + | |
| 2395 | + /* | |
| 2396 | + * Enable this when LAM is gated on LASS support | |
| 2397 | + if (cpu_feature_enabled(X86_FEATURE_LAM)) | |
| 2398 | + USER_PTR_MAX = (1ul << 63) - PAGE_SIZE - 1; | |
| 2399 | + */ | |
| 2400 | + runtime_const_init(ptr, USER_PTR_MAX); | |
| 2401 | + | |
| 2389 | 2402 | /* |
| 2390 | 2403 | * Make sure the first 2MB area is not mapped by huge pages |
| 2391 | 2404 | * There are typically fixed size MTRRs in there and overlapping |
| @@ -584,7 +584,7 @@ void __init load_ucode_amd_bsp(struct early_load_data *ed, unsigned int cpuid_1_ · 583 unmodified lines | ||
| 584 | 584 | native_rdmsr(MSR_AMD64_PATCH_LEVEL, ed->new_rev, dummy); |
| 585 | 585 | } |
| 586 | 586 | |
| 587 | −static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size); | |
| 587 | +static enum ucode_state _load_microcode_amd(u8 family, const u8 *data, size_t size); | |
| 588 | 588 | |
| 589 | 589 | static int __init save_microcode_in_initrd(void) |
| 590 | 590 | { |
| @@ -605,7 +605,7 @@ static int __init save_microcode_in_initrd(void) · 14 unmodified lines | ||
| 605 | 605 | if (!desc.mc) |
| 606 | 606 | return -EINVAL; |
| 607 | 607 | |
| 608 | − ret = load_microcode_amd(x86_family(cpuid_1_eax), desc.data, desc.size); | |
| 608 | + ret = _load_microcode_amd(x86_family(cpuid_1_eax), desc.data, desc.size); | |
| 609 | 609 | if (ret > UCODE_UPDATED) |
| 610 | 610 | return -EINVAL; |
| 611 | 611 | |
| @@ -613,16 +613,19 @@ static int __init save_microcode_in_initrd(void) · 1 unmodified line | ||
| 613 | 613 | } |
| 614 | 614 | early_initcall(save_microcode_in_initrd); |
| 615 | 615 | |
| 616 | −static inline bool patch_cpus_equivalent(struct ucode_patch *p, struct ucode_patch *n) | |
| 616 | +static inline bool patch_cpus_equivalent(struct ucode_patch *p, | |
| 617 | + struct ucode_patch *n, | |
| 618 | + bool ignore_stepping) | |
| 617 | 619 | { |
| 618 | 620 | /* Zen and newer hardcode the f/m/s in the patch ID */ |
| 619 | 621 | if (x86_family(bsp_cpuid_1_eax) >= 0x17) { |
| 620 | 622 | union cpuid_1_eax p_cid = ucode_rev_to_cpuid(p->patch_id); |
| 621 | 623 | union cpuid_1_eax n_cid = ucode_rev_to_cpuid(n->patch_id); |
| 622 | 624 | |
| 623 | − /* Zap stepping */ | |
| 624 | − p_cid.stepping = 0; | |
| 625 | − n_cid.stepping = 0; | |
| 625 | + if (ignore_stepping) { | |
| 626 | + p_cid.stepping = 0; | |
| 627 | + n_cid.stepping = 0; | |
| 628 | + } | |
| 626 | 629 | |
| 627 | 630 | return p_cid.full == n_cid.full; |
| 628 | 631 | } else { |
| @@ -644,13 +647,13 @@ static struct ucode_patch *cache_find_patch(struct ucode_cpu_info *uci, u16 equi · 15 unmodified lines | ||
| 644 | 647 | WARN_ON_ONCE(!n.patch_id); |
| 645 | 648 | |
| 646 | 649 | list_for_each_entry(p, µcode_cache, plist) |
| 647 | − if (patch_cpus_equivalent(p, &n)) | |
| 650 | + if (patch_cpus_equivalent(p, &n, false)) | |
| 648 | 651 | return p; |
| 649 | 652 | |
| 650 | 653 | return NULL; |
| 651 | 654 | } |
| 652 | 655 | |
| 653 | −static inline bool patch_newer(struct ucode_patch *p, struct ucode_patch *n) | |
| 656 | +static inline int patch_newer(struct ucode_patch *p, struct ucode_patch *n) | |
| 654 | 657 | { |
| 655 | 658 | /* Zen and newer hardcode the f/m/s in the patch ID */ |
| 656 | 659 | if (x86_family(bsp_cpuid_1_eax) >= 0x17) { |
| @@ -659,6 +662,9 @@ static inline bool patch_newer(struct ucode_patch *p, struct ucode_patch *n) · 2 unmodified lines | ||
| 659 | 662 | zp.ucode_rev = p->patch_id; |
| 660 | 663 | zn.ucode_rev = n->patch_id; |
| 661 | 664 | |
| 665 | + if (zn.stepping != zp.stepping) | |
| 666 | + return -1; | |
| 667 | + | |
| 662 | 668 | return zn.rev > zp.rev; |
| 663 | 669 | } else { |
| 664 | 670 | return n->patch_id > p->patch_id; |
| @@ -668,10 +674,14 @@ static inline bool patch_newer(struct ucode_patch *p, struct ucode_patch *n) · 3 unmodified lines | ||
| 668 | 674 | static void update_cache(struct ucode_patch *new_patch) |
| 669 | 675 | { |
| 670 | 676 | struct ucode_patch *p; |
| 677 | + int ret; | |
| 671 | 678 | |
| 672 | 679 | list_for_each_entry(p, µcode_cache, plist) { |
| 673 | − if (patch_cpus_equivalent(p, new_patch)) { | |
| 674 | − if (!patch_newer(p, new_patch)) { | |
| 680 | + if (patch_cpus_equivalent(p, new_patch, true)) { | |
| 681 | + ret = patch_newer(p, new_patch); | |
| 682 | + if (ret < 0) | |
| 683 | + continue; | |
| 684 | + else if (!ret) { | |
| 675 | 685 | /* we already have the latest patch */ |
| 676 | 686 | kfree(new_patch->data); |
| 677 | 687 | kfree(new_patch); |
| @@ -944,21 +954,30 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data, · 266 unmodified lines | ||
| 944 | 954 | return UCODE_OK; |
| 945 | 955 | } |
| 946 | 956 | |
| 947 | −static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size) | |
| 957 | +static enum ucode_state _load_microcode_amd(u8 family, const u8 *data, size_t size) | |
| 948 | 958 | { |
| 949 | − struct cpuinfo_x86 *c; | |
| 950 | − unsigned int nid, cpu; | |
| 951 | − struct ucode_patch *p; | |
| 952 | 959 | enum ucode_state ret; |
| 953 | 960 | |
| 954 | 961 | /* free old equiv table */ |
| 955 | 962 | free_equiv_cpu_table(); |
| 956 | 963 | |
| 957 | 964 | ret = __load_microcode_amd(family, data, size); |
| 958 | − if (ret != UCODE_OK) { | |
| 965 | + if (ret != UCODE_OK) | |
| 959 | 966 | cleanup(); |
| 967 | + | |
| 968 | + return ret; | |
| 969 | +} | |
| 970 | + | |
| 971 | +static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t size) | |
| 972 | +{ | |
| 973 | + struct cpuinfo_x86 *c; | |
| 974 | + unsigned int nid, cpu; | |
| 975 | + struct ucode_patch *p; | |
| 976 | + enum ucode_state ret; | |
| 977 | + | |
| 978 | + ret = _load_microcode_amd(family, data, size); | |
| 979 | + if (ret != UCODE_OK) | |
| 960 | 980 | return ret; |
| 961 | − } | |
| 962 | 981 | |
| 963 | 982 | for_each_node(nid) { |
| 964 | 983 | cpu = cpumask_first(cpumask_of_node(nid)); |
| @@ -207,7 +207,7 @@ static inline bool rdt_get_mb_table(struct rdt_resource *r) · 206 unmodified lines | ||
| 207 | 207 | return false; |
| 208 | 208 | } |
| 209 | 209 | |
| 210 | −static bool __get_mem_config_intel(struct rdt_resource *r) | |
| 210 | +static __init bool __get_mem_config_intel(struct rdt_resource *r) | |
| 211 | 211 | { |
| 212 | 212 | struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); |
| 213 | 213 | union cpuid_0x10_3_eax eax; |
| @@ -241,7 +241,7 @@ static bool __get_mem_config_intel(struct rdt_resource *r) · 27 unmodified lines | ||
| 241 | 241 | return true; |
| 242 | 242 | } |
| 243 | 243 | |
| 244 | −static bool __rdt_get_mem_config_amd(struct rdt_resource *r) | |
| 244 | +static __init bool __rdt_get_mem_config_amd(struct rdt_resource *r) | |
| 245 | 245 | { |
| 246 | 246 | struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); |
| 247 | 247 | u32 eax, ebx, ecx, edx, subleaf; |
| @@ -29,10 +29,10 @@ · 28 unmodified lines | ||
| 29 | 29 | * hardware. The allocated bandwidth percentage is rounded to the next |
| 30 | 30 | * control step available on the hardware. |
| 31 | 31 | */ |
| 32 | −static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r) | |
| 32 | +static bool bw_validate(char *buf, u32 *data, struct rdt_resource *r) | |
| 33 | 33 | { |
| 34 | − unsigned long bw; | |
| 35 | 34 | int ret; |
| 35 | + u32 bw; | |
| 36 | 36 | |
| 37 | 37 | /* |
| 38 | 38 | * Only linear delay values is supported for current Intel SKUs. |
| @@ -42,16 +42,21 @@ static bool bw_validate(char *buf, unsigned long *data, struct rdt_resource *r) · 3 unmodified lines | ||
| 42 | 42 | return false; |
| 43 | 43 | } |
| 44 | 44 | |
| 45 | − ret = kstrtoul(buf, 10, &bw); | |
| 45 | + ret = kstrtou32(buf, 10, &bw); | |
| 46 | 46 | if (ret) { |
| 47 | − rdt_last_cmd_printf("Non-decimal digit in MB value %s\n", buf); | |
| 47 | + rdt_last_cmd_printf("Invalid MB value %s\n", buf); | |
| 48 | 48 | return false; |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | − if ((bw < r->membw.min_bw || bw > r->default_ctrl) && | |
| 52 | − !is_mba_sc(r)) { | |
| 53 | − rdt_last_cmd_printf("MB value %ld out of range [%d,%d]\n", bw, | |
| 54 | − r->membw.min_bw, r->default_ctrl); | |
| 51 | + /* Nothing else to do if software controller is enabled. */ | |
| 52 | + if (is_mba_sc(r)) { | |
| 53 | + *data = bw; | |
| 54 | + return true; | |
| 55 | + } | |
| 56 | + | |
| 57 | + if (bw < r->membw.min_bw || bw > r->default_ctrl) { | |
| 58 | + rdt_last_cmd_printf("MB value %u out of range [%d,%d]\n", | |
| 59 | + bw, r->membw.min_bw, r->default_ctrl); | |
| 55 | 60 | return false; |
| 56 | 61 | } |
| 57 | 62 | |
| @@ -65,7 +70,7 @@ int parse_bw(struct rdt_parse_data *data, struct resctrl_schema *s, · 7 unmodified lines | ||
| 65 | 70 | struct resctrl_staged_config *cfg; |
| 66 | 71 | u32 closid = data->rdtgrp->closid; |
| 67 | 72 | struct rdt_resource *r = s->res; |
| 68 | − unsigned long bw_val; | |
| 73 | + u32 bw_val; | |
| 69 | 74 | |
| 70 | 75 | cfg = &d->staged_config[s->conf_type]; |
| 71 | 76 | if (cfg->have_new_ctrl) { |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | ||
| 37 | 37 | #include <asm/apic.h> |
| 38 | 38 | #include <asm/apicdef.h> |
| 39 | 39 | #include <asm/hypervisor.h> |
| 40 | +#include <asm/mtrr.h> | |
| 40 | 41 | #include <asm/tlb.h> |
| 41 | 42 | #include <asm/cpuidle_haltpoll.h> |
| 42 | 43 | #include <asm/ptrace.h> |
| @@ -980,6 +981,9 @@ static void __init kvm_init_platform(void) · 937 unmodified lines | ||
| 980 | 981 | } |
| 981 | 982 | kvmclock_init(); |
| 982 | 983 | x86_platform.apic_post_init = kvm_apic_init; |
| 984 | + | |
| 985 | + /* Set WB as the default cache mode for SEV-SNP and TDX */ | |
| 986 | + mtrr_overwrite_state(NULL, 0, MTRR_TYPE_WRBACK); | |
| 983 | 987 | } |
| 984 | 988 | |
| 985 | 989 | #if defined(CONFIG_AMD_MEM_ENCRYPT) |
| @@ -261,12 +261,6 @@ static noinstr bool handle_bug(struct pt_regs *regs) · 260 unmodified lines | ||
| 261 | 261 | int ud_type; |
| 262 | 262 | u32 imm; |
| 263 | 263 | |
| 264 | − /* | |
| 265 | − * Normally @regs are unpoisoned by irqentry_enter(), but handle_bug() | |
| 266 | − * is a rare case that uses @regs without passing them to | |
| 267 | − * irqentry_enter(). | |
| 268 | − */ | |
| 269 | − kmsan_unpoison_entry_regs(regs); | |
| 270 | 264 | ud_type = decode_bug(regs->ip, &imm); |
| 271 | 265 | if (ud_type == BUG_NONE) |
| 272 | 266 | return handled; |
| @@ -275,6 +269,12 @@ static noinstr bool handle_bug(struct pt_regs *regs) · 2 unmodified lines | ||
| 275 | 269 | * All lies, just get the WARN/BUG out. |
| 276 | 270 | */ |
| 277 | 271 | instrumentation_begin(); |
| 272 | + /* | |
| 273 | + * Normally @regs are unpoisoned by irqentry_enter(), but handle_bug() | |
| 274 | + * is a rare case that uses @regs without passing them to | |
| 275 | + * irqentry_enter(). | |
| 276 | + */ | |
| 277 | + kmsan_unpoison_entry_regs(regs); | |
| 278 | 278 | /* |
| 279 | 279 | * Since we're emulating a CALL with exceptions, restore the interrupt |
| 280 | 280 | * state to what it was at the exception site. |
| @@ -358,6 +358,7 @@ SECTIONS · 357 unmodified lines | ||
| 358 | 358 | #endif |
| 359 | 359 | |
| 360 | 360 | RUNTIME_CONST_VARIABLES |
| 361 | + RUNTIME_CONST(ptr, USER_PTR_MAX) | |
| 361 | 362 | |
| 362 | 363 | . = ALIGN(PAGE_SIZE); |
| 363 | 364 | |
| @@ -1556,6 +1556,17 @@ bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range) · 1555 unmodified lines | ||
| 1556 | 1556 | { |
| 1557 | 1557 | bool flush = false; |
| 1558 | 1558 | |
| 1559 | + /* | |
| 1560 | + * To prevent races with vCPUs faulting in a gfn using stale data, | |
| 1561 | + * zapping a gfn range must be protected by mmu_invalidate_in_progress | |
| 1562 | + * (and mmu_invalidate_seq). The only exception is memslot deletion; | |
| 1563 | + * in that case, SRCU synchronization ensures that SPTEs are zapped | |
| 1564 | + * after all vCPUs have unlocked SRCU, guaranteeing that vCPUs see the | |
| 1565 | + * invalid slot. | |
| 1566 | + */ | |
| 1567 | + lockdep_assert_once(kvm->mmu_invalidate_in_progress || | |
| 1568 | + lockdep_is_held(&kvm->slots_lock)); | |
| 1569 | + | |
| 1559 | 1570 | if (kvm_memslots_have_rmaps(kvm)) |
| 1560 | 1571 | flush = __kvm_rmap_zap_gfn_range(kvm, range->slot, |
| 1561 | 1572 | range->start, range->end, |
| @@ -1884,14 +1895,10 @@ static bool sp_has_gptes(struct kvm_mmu_page *sp) · 322 unmodified lines | ||
| 1884 | 1895 | if (is_obsolete_sp((_kvm), (_sp))) { \ |
| 1885 | 1896 | } else |
| 1886 | 1897 | |
| 1887 | −#define for_each_gfn_valid_sp(_kvm, _sp, _gfn) \ | |
| 1898 | +#define for_each_gfn_valid_sp_with_gptes(_kvm, _sp, _gfn) \ | |
| 1888 | 1899 | for_each_valid_sp(_kvm, _sp, \ |
| 1889 | 1900 | &(_kvm)->arch.mmu_page_hash[kvm_page_table_hashfn(_gfn)]) \ |
| 1890 | − if ((_sp)->gfn != (_gfn)) {} else | |
| 1891 | − | |
| 1892 | −#define for_each_gfn_valid_sp_with_gptes(_kvm, _sp, _gfn) \ | |
| 1893 | − for_each_gfn_valid_sp(_kvm, _sp, _gfn) \ | |
| 1894 | − if (!sp_has_gptes(_sp)) {} else | |
| 1901 | + if ((_sp)->gfn != (_gfn) || !sp_has_gptes(_sp)) {} else | |
| 1895 | 1902 | |
| 1896 | 1903 | static bool kvm_sync_page_check(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) |
| 1897 | 1904 | { |
| @@ -7063,15 +7070,15 @@ static void kvm_mmu_zap_memslot_pages_and_flush(struct kvm *kvm, · 5165 unmodified lines | ||
| 7063 | 7070 | |
| 7064 | 7071 | /* |
| 7065 | 7072 | * Since accounting information is stored in struct kvm_arch_memory_slot, |
| 7066 | − * shadow pages deletion (e.g. unaccount_shadowed()) requires that all | |
| 7067 | − * gfns with a shadow page have a corresponding memslot. Do so before | |
| 7068 | − * the memslot goes away. | |
| 7073 | + * all MMU pages that are shadowing guest PTEs must be zapped before the | |
| 7074 | + * memslot is deleted, as freeing such pages after the memslot is freed | |
| 7075 | + * will result in use-after-free, e.g. in unaccount_shadowed(). | |
| 7069 | 7076 | */ |
| 7070 | 7077 | for (i = 0; i < slot->npages; i++) { |
| 7071 | 7078 | struct kvm_mmu_page *sp; |
| 7072 | 7079 | gfn_t gfn = slot->base_gfn + i; |
| 7073 | 7080 | |
| 7074 | − for_each_gfn_valid_sp(kvm, sp, gfn) | |
| 7081 | + for_each_gfn_valid_sp_with_gptes(kvm, sp, gfn) | |
| 7075 | 7082 | kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list); |
| 7076 | 7083 | |
| 7077 | 7084 | if (need_resched() || rwlock_needbreak(&kvm->mmu_lock)) { |
| @@ -63,8 +63,12 @@ static u64 nested_svm_get_tdp_pdptr(struct kvm_vcpu *vcpu, int index) · 62 unmodified lines | ||
| 63 | 63 | u64 pdpte; |
| 64 | 64 | int ret; |
| 65 | 65 | |
| 66 | + /* | |
| 67 | + * Note, nCR3 is "assumed" to be 32-byte aligned, i.e. the CPU ignores | |
| 68 | + * nCR3[4:0] when loading PDPTEs from memory. | |
| 69 | + */ | |
| 66 | 70 | ret = kvm_vcpu_read_guest_page(vcpu, gpa_to_gfn(cr3), &pdpte, |
| 67 | − offset_in_page(cr3) + index * 8, 8); | |
| 71 | + (cr3 & GENMASK(11, 5)) + index * 8, 8); | |
| 68 | 72 | if (ret) |
| 69 | 73 | return 0; |
| 70 | 74 | return pdpte; |
| @@ -4888,9 +4888,6 @@ void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) · 4887 unmodified lines | ||
| 4888 | 4888 | vmx->hv_deadline_tsc = -1; |
| 4889 | 4889 | kvm_set_cr8(vcpu, 0); |
| 4890 | 4890 | |
| 4891 | − vmx_segment_cache_clear(vmx); | |
| 4892 | − kvm_register_mark_available(vcpu, VCPU_EXREG_SEGMENTS); | |
| 4893 | − | |
| 4894 | 4891 | seg_setup(VCPU_SREG_CS); |
| 4895 | 4892 | vmcs_write16(GUEST_CS_SELECTOR, 0xf000); |
| 4896 | 4893 | vmcs_writel(GUEST_CS_BASE, 0xffff0000ul); |
| @@ -4917,6 +4914,9 @@ void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) · 20 unmodified lines | ||
| 4917 | 4914 | vmcs_writel(GUEST_IDTR_BASE, 0); |
| 4918 | 4915 | vmcs_write32(GUEST_IDTR_LIMIT, 0xffff); |
| 4919 | 4916 | |
| 4917 | + vmx_segment_cache_clear(vmx); | |
| 4918 | + kvm_register_mark_available(vcpu, VCPU_EXREG_SEGMENTS); | |
| 4919 | + | |
| 4920 | 4920 | vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE); |
| 4921 | 4921 | vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0); |
| 4922 | 4922 | vmcs_writel(GUEST_PENDING_DBG_EXCEPTIONS, 0); |
| @@ -39,8 +39,13 @@ · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | .macro check_range size:req |
| 41 | 41 | .if IS_ENABLED(CONFIG_X86_64) |
| 42 | − mov %rax, %rdx | |
| 43 | − sar $63, %rdx | |
| 42 | + movq $0x0123456789abcdef,%rdx | |
| 43 | + 1: | |
| 44 | + .pushsection runtime_ptr_USER_PTR_MAX,"a" | |
| 45 | + .long 1b - 8 - . | |
| 46 | + .popsection | |
| 47 | + cmp %rax, %rdx | |
| 48 | + sbb %rdx, %rdx | |
| 44 | 49 | or %rdx, %rax |
| 45 | 50 | .else |
| 46 | 51 | cmp $TASK_SIZE_MAX-\size+1, %eax |
| @@ -173,6 +173,8 @@ static void __init __snp_fixup_e820_tables(u64 pa) · 172 unmodified lines | ||
| 173 | 173 | e820__range_update(pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED); |
| 174 | 174 | e820__range_update_table(e820_table_kexec, pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED); |
| 175 | 175 | e820__range_update_table(e820_table_firmware, pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED); |
| 176 | + if (!memblock_is_region_reserved(pa, PMD_SIZE)) | |
| 177 | + memblock_reserve(pa, PMD_SIZE); | |
| 176 | 178 | } |
| 177 | 179 | } |
| 178 | 180 | |
| @@ -1032,6 +1032,10 @@ static u64 xen_do_read_msr(unsigned int msr, int *err) · 1031 unmodified lines | ||
| 1032 | 1032 | switch (msr) { |
| 1033 | 1033 | case MSR_IA32_APICBASE: |
| 1034 | 1034 | val &= ~X2APIC_ENABLE; |
| 1035 | + if (smp_processor_id() == 0) | |
| 1036 | + val |= MSR_IA32_APICBASE_BSP; | |
| 1037 | + else | |
| 1038 | + val &= ~MSR_IA32_APICBASE_BSP; | |
| 1035 | 1039 | break; |
| 1036 | 1040 | } |
| 1037 | 1041 | return val; |
| @@ -561,57 +561,33 @@ EXPORT_SYMBOL(blk_rq_append_bio); · 560 unmodified lines | ||
| 561 | 561 | /* Prepare bio for passthrough IO given ITER_BVEC iter */ |
| 562 | 562 | static int blk_rq_map_user_bvec(struct request *rq, const struct iov_iter *iter) |
| 563 | 563 | { |
| 564 | − struct request_queue *q = rq->q; | |
| 565 | − size_t nr_iter = iov_iter_count(iter); | |
| 566 | − size_t nr_segs = iter->nr_segs; | |
| 567 | − struct bio_vec *bvecs, *bvprvp = NULL; | |
| 568 | − const struct queue_limits *lim = &q->limits; | |
| 569 | − unsigned int nsegs = 0, bytes = 0; | |
| 564 | + const struct queue_limits *lim = &rq->q->limits; | |
| 565 | + unsigned int max_bytes = lim->max_hw_sectors << SECTOR_SHIFT; | |
| 566 | + unsigned int nsegs; | |
| 570 | 567 | struct bio *bio; |
| 571 | − size_t i; | |
| 568 | + int ret; | |
| 572 | 569 | |
| 573 | − if (!nr_iter || (nr_iter >> SECTOR_SHIFT) > queue_max_hw_sectors(q)) | |
| 574 | − return -EINVAL; | |
| 575 | − if (nr_segs > queue_max_segments(q)) | |
| 570 | + if (!iov_iter_count(iter) || iov_iter_count(iter) > max_bytes) | |
| 576 | 571 | return -EINVAL; |
| 577 | 572 | |
| 578 | − /* no iovecs to alloc, as we already have a BVEC iterator */ | |
| 573 | + /* reuse the bvecs from the iterator instead of allocating new ones */ | |
| 579 | 574 | bio = blk_rq_map_bio_alloc(rq, 0, GFP_KERNEL); |
| 580 | − if (bio == NULL) | |
| 575 | + if (!bio) | |
| 581 | 576 | return -ENOMEM; |
| 582 | − | |
| 583 | 577 | bio_iov_bvec_set(bio, (struct iov_iter *)iter); |
| 584 | − blk_rq_bio_prep(rq, bio, nr_segs); | |
| 585 | − | |
| 586 | − /* loop to perform a bunch of sanity checks */ | |
| 587 | − bvecs = (struct bio_vec *)iter->bvec; | |
| 588 | − for (i = 0; i < nr_segs; i++) { | |
| 589 | − struct bio_vec *bv = &bvecs[i]; | |
| 590 | 578 | |
| 591 | − /* | |
| 592 | − * If the queue doesn't support SG gaps and adding this | |
| 593 | − * offset would create a gap, fallback to copy. | |
| 594 | − */ | |
| 595 | − if (bvprvp && bvec_gap_to_prev(lim, bvprvp, bv->bv_offset)) { | |
| 596 | − blk_mq_map_bio_put(bio); | |
| 597 | − return -EREMOTEIO; | |
| 598 | − } | |
| 599 | − /* check full condition */ | |
| 600 | − if (nsegs >= nr_segs || bytes > UINT_MAX - bv->bv_len) | |
| 601 | − goto put_bio; | |
| 602 | − if (bytes + bv->bv_len > nr_iter) | |
| 603 | − goto put_bio; | |
| 604 | − if (bv->bv_offset + bv->bv_len > PAGE_SIZE) | |
| 605 | − goto put_bio; | |
| 606 | − | |
| 607 | − nsegs++; | |
| 608 | − bytes += bv->bv_len; | |
| 609 | − bvprvp = bv; | |
| 579 | + /* check that the data layout matches the hardware restrictions */ | |
| 580 | + ret = bio_split_rw_at(bio, lim, &nsegs, max_bytes); | |
| 581 | + if (ret) { | |
| 582 | + /* if we would have to split the bio, copy instead */ | |
| 583 | + if (ret > 0) | |
| 584 | + ret = -EREMOTEIO; | |
| 585 | + blk_mq_map_bio_put(bio); | |
| 586 | + return ret; | |
| 610 | 587 | } |
| 588 | + | |
| 589 | + blk_rq_bio_prep(rq, bio, nsegs); | |
| 611 | 590 | return 0; |
| 612 | −put_bio: | |
| 613 | − blk_mq_map_bio_put(bio); | |
| 614 | − return -EINVAL; | |
| 615 | 591 | } |
| 616 | 592 | |
| 617 | 593 | /** |
| @@ -4310,6 +4310,12 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, · 4309 unmodified lines | ||
| 4310 | 4310 | /* mark the queue as mq asap */ |
| 4311 | 4311 | q->mq_ops = set->ops; |
| 4312 | 4312 | |
| 4313 | + /* | |
| 4314 | + * ->tag_set has to be setup before initialize hctx, which cpuphp | |
| 4315 | + * handler needs it for checking queue mapping | |
| 4316 | + */ | |
| 4317 | + q->tag_set = set; | |
| 4318 | + | |
| 4313 | 4319 | if (blk_mq_alloc_ctxs(q)) |
| 4314 | 4320 | goto err_exit; |
| 4315 | 4321 | |
| @@ -4328,8 +4334,6 @@ int blk_mq_init_allocated_queue(struct blk_mq_tag_set *set, · 12 unmodified lines | ||
| 4328 | 4334 | INIT_WORK(&q->timeout_work, blk_mq_timeout_work); |
| 4329 | 4335 | blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ); |
| 4330 | 4336 | |
| 4331 | − q->tag_set = set; | |
| 4332 | − | |
| 4333 | 4337 | q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT; |
| 4334 | 4338 | |
| 4335 | 4339 | INIT_DELAYED_WORK(&q->requeue_work, blk_mq_requeue_work); |
| @@ -219,8 +219,8 @@ static int rq_qos_wake_function(struct wait_queue_entry *curr, · 218 unmodified lines | ||
| 219 | 219 | |
| 220 | 220 | data->got_token = true; |
| 221 | 221 | smp_wmb(); |
| 222 | − list_del_init(&curr->entry); | |
| 223 | 222 | wake_up_process(data->task); |
| 223 | + list_del_init_careful(&curr->entry); | |
| 224 | 224 | return 1; |
| 225 | 225 | } |
| 226 | 226 | |
| @@ -106,8 +106,7 @@ static struct elevator_type *__elevator_find(const char *name) · 105 unmodified lines | ||
| 106 | 106 | return NULL; |
| 107 | 107 | } |
| 108 | 108 | |
| 109 | −static struct elevator_type *elevator_find_get(struct request_queue *q, | |
| 110 | − const char *name) | |
| 109 | +static struct elevator_type *elevator_find_get(const char *name) | |
| 111 | 110 | { |
| 112 | 111 | struct elevator_type *e; |
| 113 | 112 | |
| @@ -551,7 +550,7 @@ EXPORT_SYMBOL_GPL(elv_unregister); · 437 unmodified lines | ||
| 551 | 550 | static inline bool elv_support_iosched(struct request_queue *q) |
| 552 | 551 | { |
| 553 | 552 | if (!queue_is_mq(q) || |
| 554 | − (q->tag_set && (q->tag_set->flags & BLK_MQ_F_NO_SCHED))) | |
| 553 | + (q->tag_set->flags & BLK_MQ_F_NO_SCHED)) | |
| 555 | 554 | return false; |
| 556 | 555 | return true; |
| 557 | 556 | } |
| @@ -562,14 +561,14 @@ static inline bool elv_support_iosched(struct request_queue *q) · 4 unmodified lines | ||
| 562 | 561 | */ |
| 563 | 562 | static struct elevator_type *elevator_get_default(struct request_queue *q) |
| 564 | 563 | { |
| 565 | − if (q->tag_set && q->tag_set->flags & BLK_MQ_F_NO_SCHED_BY_DEFAULT) | |
| 564 | + if (q->tag_set->flags & BLK_MQ_F_NO_SCHED_BY_DEFAULT) | |
| 566 | 565 | return NULL; |
| 567 | 566 | |
| 568 | 567 | if (q->nr_hw_queues != 1 && |
| 569 | 568 | !blk_mq_is_shared_tags(q->tag_set->flags)) |
| 570 | 569 | return NULL; |
| 571 | 570 | |
| 572 | − return elevator_find_get(q, "mq-deadline"); | |
| 571 | + return elevator_find_get("mq-deadline"); | |
| 573 | 572 | } |
| 574 | 573 | |
| 575 | 574 | /* |
| @@ -697,7 +696,7 @@ static int elevator_change(struct request_queue *q, const char *elevator_name) · 121 unmodified lines | ||
| 697 | 696 | if (q->elevator && elevator_match(q->elevator->type, elevator_name)) |
| 698 | 697 | return 0; |
| 699 | 698 | |
| 700 | − e = elevator_find_get(q, elevator_name); | |
| 699 | + e = elevator_find_get(elevator_name); | |
| 701 | 700 | if (!e) |
| 702 | 701 | return -EINVAL; |
| 703 | 702 | ret = elevator_switch(q, e); |
| @@ -709,13 +708,21 @@ int elv_iosched_load_module(struct gendisk *disk, const char *buf, · 5 unmodified lines | ||
| 709 | 708 | size_t count) |
| 710 | 709 | { |
| 711 | 710 | char elevator_name[ELV_NAME_MAX]; |
| 711 | + struct elevator_type *found; | |
| 712 | + const char *name; | |
| 712 | 713 | |
| 713 | 714 | if (!elv_support_iosched(disk->queue)) |
| 714 | 715 | return -EOPNOTSUPP; |
| 715 | 716 | |
| 716 | 717 | strscpy(elevator_name, buf, sizeof(elevator_name)); |
| 718 | + name = strstrip(elevator_name); | |
| 717 | 719 | |
| 718 | − request_module("%s-iosched", strstrip(elevator_name)); | |
| 720 | + spin_lock(&elv_list_lock); | |
| 721 | + found = __elevator_find(name); | |
| 722 | + spin_unlock(&elv_list_lock); | |
| 723 | + | |
| 724 | + if (!found) | |
| 725 | + request_module("%s-iosched", name); | |
| 719 | 726 | |
| 720 | 727 | return 0; |
| 721 | 728 | } |
| @@ -373,7 +373,7 @@ found: · 372 unmodified lines | ||
| 373 | 373 | q->cra_flags |= CRYPTO_ALG_DEAD; |
| 374 | 374 | alg = test->adult; |
| 375 | 375 | |
| 376 | − if (list_empty(&alg->cra_list)) | |
| 376 | + if (crypto_is_dead(alg)) | |
| 377 | 377 | goto complete; |
| 378 | 378 | |
| 379 | 379 | if (err == -ECANCELED) |
| @@ -1940,7 +1940,7 @@ static int __alg_test_hash(const struct hash_testvec *vecs, · 1939 unmodified lines | ||
| 1940 | 1940 | atfm = crypto_alloc_ahash(driver, type, mask); |
| 1941 | 1941 | if (IS_ERR(atfm)) { |
| 1942 | 1942 | if (PTR_ERR(atfm) == -ENOENT) |
| 1943 | − return -ENOENT; | |
| 1943 | + return 0; | |
| 1944 | 1944 | pr_err("alg: hash: failed to allocate transform for %s: %ld\n", |
| 1945 | 1945 | driver, PTR_ERR(atfm)); |
| 1946 | 1946 | return PTR_ERR(atfm); |
| @@ -2706,7 +2706,7 @@ static int alg_test_aead(const struct alg_test_desc *desc, const char *driver, · 759 unmodified lines | ||
| 2706 | 2706 | tfm = crypto_alloc_aead(driver, type, mask); |
| 2707 | 2707 | if (IS_ERR(tfm)) { |
| 2708 | 2708 | if (PTR_ERR(tfm) == -ENOENT) |
| 2709 | − return -ENOENT; | |
| 2709 | + return 0; | |
| 2710 | 2710 | pr_err("alg: aead: failed to allocate transform for %s: %ld\n", |
| 2711 | 2711 | driver, PTR_ERR(tfm)); |
| 2712 | 2712 | return PTR_ERR(tfm); |
| @@ -3285,7 +3285,7 @@ static int alg_test_skcipher(const struct alg_test_desc *desc, · 572 unmodified lines | ||
| 3285 | 3285 | tfm = crypto_alloc_skcipher(driver, type, mask); |
| 3286 | 3286 | if (IS_ERR(tfm)) { |
| 3287 | 3287 | if (PTR_ERR(tfm) == -ENOENT) |
| 3288 | − return -ENOENT; | |
| 3288 | + return 0; | |
| 3289 | 3289 | pr_err("alg: skcipher: failed to allocate transform for %s: %ld\n", |
| 3290 | 3290 | driver, PTR_ERR(tfm)); |
| 3291 | 3291 | return PTR_ERR(tfm); |
| @@ -3700,7 +3700,7 @@ static int alg_test_cipher(const struct alg_test_desc *desc, · 408 unmodified lines | ||
| 3700 | 3700 | tfm = crypto_alloc_cipher(driver, type, mask); |
| 3701 | 3701 | if (IS_ERR(tfm)) { |
| 3702 | 3702 | if (PTR_ERR(tfm) == -ENOENT) |
| 3703 | − return -ENOENT; | |
| 3703 | + return 0; | |
| 3704 | 3704 | printk(KERN_ERR "alg: cipher: Failed to load transform for " |
| 3705 | 3705 | "%s: %ld\n", driver, PTR_ERR(tfm)); |
| 3706 | 3706 | return PTR_ERR(tfm); |
| @@ -3726,7 +3726,7 @@ static int alg_test_comp(const struct alg_test_desc *desc, const char *driver, · 19 unmodified lines | ||
| 3726 | 3726 | acomp = crypto_alloc_acomp(driver, type, mask); |
| 3727 | 3727 | if (IS_ERR(acomp)) { |
| 3728 | 3728 | if (PTR_ERR(acomp) == -ENOENT) |
| 3729 | − return -ENOENT; | |
| 3729 | + return 0; | |
| 3730 | 3730 | pr_err("alg: acomp: Failed to load transform for %s: %ld\n", |
| 3731 | 3731 | driver, PTR_ERR(acomp)); |
| 3732 | 3732 | return PTR_ERR(acomp); |
| @@ -3740,7 +3740,7 @@ static int alg_test_comp(const struct alg_test_desc *desc, const char *driver, · 7 unmodified lines | ||
| 3740 | 3740 | comp = crypto_alloc_comp(driver, type, mask); |
| 3741 | 3741 | if (IS_ERR(comp)) { |
| 3742 | 3742 | if (PTR_ERR(comp) == -ENOENT) |
| 3743 | − return -ENOENT; | |
| 3743 | + return 0; | |
| 3744 | 3744 | pr_err("alg: comp: Failed to load transform for %s: %ld\n", |
| 3745 | 3745 | driver, PTR_ERR(comp)); |
| 3746 | 3746 | return PTR_ERR(comp); |
| @@ -3818,7 +3818,7 @@ static int alg_test_cprng(const struct alg_test_desc *desc, const char *driver, · 71 unmodified lines | ||
| 3818 | 3818 | rng = crypto_alloc_rng(driver, type, mask); |
| 3819 | 3819 | if (IS_ERR(rng)) { |
| 3820 | 3820 | if (PTR_ERR(rng) == -ENOENT) |
| 3821 | − return -ENOENT; | |
| 3821 | + return 0; | |
| 3822 | 3822 | printk(KERN_ERR "alg: cprng: Failed to load transform for %s: " |
| 3823 | 3823 | "%ld\n", driver, PTR_ERR(rng)); |
| 3824 | 3824 | return PTR_ERR(rng); |
| @@ -3846,12 +3846,11 @@ static int drbg_cavs_test(const struct drbg_testvec *test, int pr, · 21 unmodified lines | ||
| 3846 | 3846 | |
| 3847 | 3847 | drng = crypto_alloc_rng(driver, type, mask); |
| 3848 | 3848 | if (IS_ERR(drng)) { |
| 3849 | + kfree_sensitive(buf); | |
| 3849 | 3850 | if (PTR_ERR(drng) == -ENOENT) |
| 3850 | − goto out_no_rng; | |
| 3851 | + return 0; | |
| 3851 | 3852 | printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for " |
| 3852 | 3853 | "%s\n", driver); |
| 3853 | −out_no_rng: | |
| 3854 | − kfree_sensitive(buf); | |
| 3855 | 3854 | return PTR_ERR(drng); |
| 3856 | 3855 | } |
| 3857 | 3856 | |
| @@ -4095,7 +4094,7 @@ static int alg_test_kpp(const struct alg_test_desc *desc, const char *driver, · 237 unmodified lines | ||
| 4095 | 4094 | tfm = crypto_alloc_kpp(driver, type, mask); |
| 4096 | 4095 | if (IS_ERR(tfm)) { |
| 4097 | 4096 | if (PTR_ERR(tfm) == -ENOENT) |
| 4098 | − return -ENOENT; | |
| 4097 | + return 0; | |
| 4099 | 4098 | pr_err("alg: kpp: Failed to load tfm for %s: %ld\n", |
| 4100 | 4099 | driver, PTR_ERR(tfm)); |
| 4101 | 4100 | return PTR_ERR(tfm); |
| @@ -4325,7 +4324,7 @@ static int alg_test_akcipher(const struct alg_test_desc *desc, · 223 unmodified lines | ||
| 4325 | 4324 | tfm = crypto_alloc_akcipher(driver, type, mask); |
| 4326 | 4325 | if (IS_ERR(tfm)) { |
| 4327 | 4326 | if (PTR_ERR(tfm) == -ENOENT) |
| 4328 | − return -ENOENT; | |
| 4327 | + return 0; | |
| 4329 | 4328 | pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n", |
| 4330 | 4329 | driver, PTR_ERR(tfm)); |
| 4331 | 4330 | return PTR_ERR(tfm); |
| @@ -116,6 +116,14 @@ static int reset_pending_show(struct seq_file *s, void *v) · 115 unmodified lines | ||
| 116 | 116 | return 0; |
| 117 | 117 | } |
| 118 | 118 | |
| 119 | +static int firewall_irq_counter_show(struct seq_file *s, void *v) | |
| 120 | +{ | |
| 121 | + struct ivpu_device *vdev = seq_to_ivpu(s); | |
| 122 | + | |
| 123 | + seq_printf(s, "%d\n", atomic_read(&vdev->hw->firewall_irq_counter)); | |
| 124 | + return 0; | |
| 125 | +} | |
| 126 | + | |
| 119 | 127 | static const struct drm_debugfs_info vdev_debugfs_list[] = { |
| 120 | 128 | {"bo_list", bo_list_show, 0}, |
| 121 | 129 | {"fw_name", fw_name_show, 0}, |
| @@ -125,6 +133,7 @@ static const struct drm_debugfs_info vdev_debugfs_list[] = { · 3 unmodified lines | ||
| 125 | 133 | {"last_bootmode", last_bootmode_show, 0}, |
| 126 | 134 | {"reset_counter", reset_counter_show, 0}, |
| 127 | 135 | {"reset_pending", reset_pending_show, 0}, |
| 136 | + {"firewall_irq_counter", firewall_irq_counter_show, 0}, | |
| 128 | 137 | }; |
| 129 | 138 | |
| 130 | 139 | static int dvfs_mode_get(void *data, u64 *dvfs_mode) |
| @@ -252,6 +252,7 @@ int ivpu_hw_init(struct ivpu_device *vdev) · 251 unmodified lines | ||
| 252 | 252 | platform_init(vdev); |
| 253 | 253 | wa_init(vdev); |
| 254 | 254 | timeouts_init(vdev); |
| 255 | + atomic_set(&vdev->hw->firewall_irq_counter, 0); | |
| 255 | 256 | |
| 256 | 257 | return 0; |
| 257 | 258 | } |
| @@ -51,6 +51,7 @@ struct ivpu_hw_info { · 50 unmodified lines | ||
| 51 | 51 | int dma_bits; |
| 52 | 52 | ktime_t d0i3_entry_host_ts; |
| 53 | 53 | u64 d0i3_entry_vpu_ts; |
| 54 | + atomic_t firewall_irq_counter; | |
| 54 | 55 | }; |
| 55 | 56 | |
| 56 | 57 | int ivpu_hw_init(struct ivpu_device *vdev); |
| @@ -1073,7 +1073,10 @@ static void irq_wdt_mss_handler(struct ivpu_device *vdev) · 1072 unmodified lines | ||
| 1073 | 1073 | |
| 1074 | 1074 | static void irq_noc_firewall_handler(struct ivpu_device *vdev) |
| 1075 | 1075 | { |
| 1076 | − ivpu_pm_trigger_recovery(vdev, "NOC Firewall IRQ"); | |
| 1076 | + atomic_inc(&vdev->hw->firewall_irq_counter); | |
| 1077 | + | |
| 1078 | + ivpu_dbg(vdev, IRQ, "NOC Firewall interrupt detected, counter %d\n", | |
| 1079 | + atomic_read(&vdev->hw->firewall_irq_counter)); | |
| 1077 | 1080 | } |
| 1078 | 1081 | |
| 1079 | 1082 | /* Handler for IRQs from NPU core */ |
| @@ -496,7 +496,7 @@ static int encode_addr_size_pairs(struct dma_xfer *xfer, struct wrapper_list *wr · 495 unmodified lines | ||
| 496 | 496 | nents = sgt->nents; |
| 497 | 497 | nents_dma = nents; |
| 498 | 498 | *size = QAIC_MANAGE_EXT_MSG_LENGTH - msg_hdr_len - sizeof(**out_trans); |
| 499 | − for_each_sgtable_sg(sgt, sg, i) { | |
| 499 | + for_each_sgtable_dma_sg(sgt, sg, i) { | |
| 500 | 500 | *size -= sizeof(*asp); |
| 501 | 501 | /* Save 1K for possible follow-up transactions. */ |
| 502 | 502 | if (*size < SZ_1K) { |
| @@ -184,7 +184,7 @@ static int clone_range_of_sgt_for_slice(struct qaic_device *qdev, struct sg_tabl · 183 unmodified lines | ||
| 184 | 184 | nents = 0; |
| 185 | 185 | |
| 186 | 186 | size = size ? size : PAGE_SIZE; |
| 187 | − for (sg = sgt_in->sgl; sg; sg = sg_next(sg)) { | |
| 187 | + for_each_sgtable_dma_sg(sgt_in, sg, j) { | |
| 188 | 188 | len = sg_dma_len(sg); |
| 189 | 189 | |
| 190 | 190 | if (!len) |
| @@ -221,7 +221,7 @@ static int clone_range_of_sgt_for_slice(struct qaic_device *qdev, struct sg_tabl · 30 unmodified lines | ||
| 221 | 221 | |
| 222 | 222 | /* copy relevant sg node and fix page and length */ |
| 223 | 223 | sgn = sgf; |
| 224 | − for_each_sgtable_sg(sgt, sg, j) { | |
| 224 | + for_each_sgtable_dma_sg(sgt, sg, j) { | |
| 225 | 225 | memcpy(sg, sgn, sizeof(*sg)); |
| 226 | 226 | if (sgn == sgf) { |
| 227 | 227 | sg_dma_address(sg) += offf; |
| @@ -301,7 +301,7 @@ static int encode_reqs(struct qaic_device *qdev, struct bo_slice *slice, · 73 unmodified lines | ||
| 301 | 301 | * fence. |
| 302 | 302 | */ |
| 303 | 303 | dev_addr = req->dev_addr; |
| 304 | − for_each_sgtable_sg(slice->sgt, sg, i) { | |
| 304 | + for_each_sgtable_dma_sg(slice->sgt, sg, i) { | |
| 305 | 305 | slice->reqs[i].cmd = cmd; |
| 306 | 306 | slice->reqs[i].src_addr = cpu_to_le64(slice->dir == DMA_TO_DEVICE ? |
| 307 | 307 | sg_dma_address(sg) : dev_addr); |
| @@ -130,6 +130,17 @@ static const struct dmi_system_id dmi_lid_quirks[] = { · 129 unmodified lines | ||
| 130 | 130 | }, |
| 131 | 131 | .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN, |
| 132 | 132 | }, |
| 133 | + { | |
| 134 | + /* | |
| 135 | + * Samsung galaxybook2 ,initial _LID device notification returns | |
| 136 | + * lid closed. | |
| 137 | + */ | |
| 138 | + .matches = { | |
| 139 | + DMI_MATCH(DMI_SYS_VENDOR, "SAMSUNG ELECTRONICS CO., LTD."), | |
| 140 | + DMI_MATCH(DMI_PRODUCT_NAME, "750XED"), | |
| 141 | + }, | |
| 142 | + .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN, | |
| 143 | + }, | |
| 133 | 144 | {} |
| 134 | 145 | }; |
| 135 | 146 | |
| @@ -867,7 +867,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) · 866 unmodified lines | ||
| 867 | 867 | |
| 868 | 868 | /* Store CPU Logical ID */ |
| 869 | 869 | cpc_ptr->cpu_id = pr->id; |
| 870 | − spin_lock_init(&cpc_ptr->rmw_lock); | |
| 870 | + raw_spin_lock_init(&cpc_ptr->rmw_lock); | |
| 871 | 871 | |
| 872 | 872 | /* Parse PSD data for this CPU */ |
| 873 | 873 | ret = acpi_get_psd(cpc_ptr, handle); |
| @@ -1087,6 +1087,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) · 213 unmodified lines | ||
| 1087 | 1087 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); |
| 1088 | 1088 | struct cpc_reg *reg = ®_res->cpc_entry.reg; |
| 1089 | 1089 | struct cpc_desc *cpc_desc; |
| 1090 | + unsigned long flags; | |
| 1090 | 1091 | |
| 1091 | 1092 | size = GET_BIT_WIDTH(reg); |
| 1092 | 1093 | |
| @@ -1126,7 +1127,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) · 33 unmodified lines | ||
| 1126 | 1127 | return -ENODEV; |
| 1127 | 1128 | } |
| 1128 | 1129 | |
| 1129 | − spin_lock(&cpc_desc->rmw_lock); | |
| 1130 | + raw_spin_lock_irqsave(&cpc_desc->rmw_lock, flags); | |
| 1130 | 1131 | switch (size) { |
| 1131 | 1132 | case 8: |
| 1132 | 1133 | prev_val = readb_relaxed(vaddr); |
| @@ -1141,7 +1142,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) · 8 unmodified lines | ||
| 1141 | 1142 | prev_val = readq_relaxed(vaddr); |
| 1142 | 1143 | break; |
| 1143 | 1144 | default: |
| 1144 | − spin_unlock(&cpc_desc->rmw_lock); | |
| 1145 | + raw_spin_unlock_irqrestore(&cpc_desc->rmw_lock, flags); | |
| 1145 | 1146 | return -EFAULT; |
| 1146 | 1147 | } |
| 1147 | 1148 | val = MASK_VAL_WRITE(reg, prev_val, val); |
| @@ -1174,7 +1175,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) · 26 unmodified lines | ||
| 1174 | 1175 | } |
| 1175 | 1176 | |
| 1176 | 1177 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) |
| 1177 | − spin_unlock(&cpc_desc->rmw_lock); | |
| 1178 | + raw_spin_unlock_irqrestore(&cpc_desc->rmw_lock, flags); | |
| 1178 | 1179 | |
| 1179 | 1180 | return ret_val; |
| 1180 | 1181 | } |
| @@ -1916,9 +1917,15 @@ unsigned int cppc_perf_to_khz(struct cppc_perf_caps *caps, unsigned int perf) · 735 unmodified lines | ||
| 1916 | 1917 | u64 mul, div; |
| 1917 | 1918 | |
| 1918 | 1919 | if (caps->lowest_freq && caps->nominal_freq) { |
| 1919 | − mul = caps->nominal_freq - caps->lowest_freq; | |
| 1920 | + /* Avoid special case when nominal_freq is equal to lowest_freq */ | |
| 1921 | + if (caps->lowest_freq == caps->nominal_freq) { | |
| 1922 | + mul = caps->nominal_freq; | |
| 1923 | + div = caps->nominal_perf; | |
| 1924 | + } else { | |
| 1925 | + mul = caps->nominal_freq - caps->lowest_freq; | |
| 1926 | + div = caps->nominal_perf - caps->lowest_perf; | |
| 1927 | + } | |
| 1920 | 1928 | mul *= KHZ_PER_MHZ; |
| 1921 | − div = caps->nominal_perf - caps->lowest_perf; | |
| 1922 | 1929 | offset = caps->nominal_freq * KHZ_PER_MHZ - |
| 1923 | 1930 | div64_u64(caps->nominal_perf * mul, div); |
| 1924 | 1931 | } else { |
| @@ -1939,11 +1946,17 @@ unsigned int cppc_khz_to_perf(struct cppc_perf_caps *caps, unsigned int freq) · 14 unmodified lines | ||
| 1939 | 1946 | { |
| 1940 | 1947 | s64 retval, offset = 0; |
| 1941 | 1948 | static u64 max_khz; |
| 1942 | − u64 mul, div; | |
| 1949 | + u64 mul, div; | |
| 1943 | 1950 | |
| 1944 | 1951 | if (caps->lowest_freq && caps->nominal_freq) { |
| 1945 | − mul = caps->nominal_perf - caps->lowest_perf; | |
| 1946 | − div = caps->nominal_freq - caps->lowest_freq; | |
| 1952 | + /* Avoid special case when nominal_freq is equal to lowest_freq */ | |
| 1953 | + if (caps->lowest_freq == caps->nominal_freq) { | |
| 1954 | + mul = caps->nominal_perf; | |
| 1955 | + div = caps->nominal_freq; | |
| 1956 | + } else { | |
| 1957 | + mul = caps->nominal_perf - caps->lowest_perf; | |
| 1958 | + div = caps->nominal_freq - caps->lowest_freq; | |
| 1959 | + } | |
| 1947 | 1960 | /* |
| 1948 | 1961 | * We don't need to convert to kHz for computing offset and can |
| 1949 | 1962 | * directly use nominal_freq and lowest_freq as the div64_u64 |
| @@ -52,7 +52,7 @@ struct prm_context_buffer { · 51 unmodified lines | ||
| 52 | 52 | static LIST_HEAD(prm_module_list); |
| 53 | 53 | |
| 54 | 54 | struct prm_handler_info { |
| 55 | − guid_t guid; | |
| 55 | + efi_guid_t guid; | |
| 56 | 56 | efi_status_t (__efiapi *handler_addr)(u64, void *); |
| 57 | 57 | u64 static_data_buffer_addr; |
| 58 | 58 | u64 acpi_param_buffer_addr; |
| @@ -72,17 +72,21 @@ struct prm_module_info { · 13 unmodified lines | ||
| 72 | 72 | struct prm_handler_info handlers[] __counted_by(handler_count); |
| 73 | 73 | }; |
| 74 | 74 | |
| 75 | −static u64 efi_pa_va_lookup(u64 pa) | |
| 75 | +static u64 efi_pa_va_lookup(efi_guid_t *guid, u64 pa) | |
| 76 | 76 | { |
| 77 | 77 | efi_memory_desc_t *md; |
| 78 | 78 | u64 pa_offset = pa & ~PAGE_MASK; |
| 79 | 79 | u64 page = pa & PAGE_MASK; |
| 80 | 80 | |
| 81 | 81 | for_each_efi_memory_desc(md) { |
| 82 | − if (md->phys_addr < pa && pa < md->phys_addr + PAGE_SIZE * md->num_pages) | |
| 82 | + if ((md->attribute & EFI_MEMORY_RUNTIME) && | |
| 83 | + (md->phys_addr < pa && pa < md->phys_addr + PAGE_SIZE * md->num_pages)) { | |
| 83 | 84 | return pa_offset + md->virt_addr + page - md->phys_addr; |
| 85 | + } | |
| 84 | 86 | } |
| 85 | 87 | |
| 88 | + pr_warn("Failed to find VA for GUID: %pUL, PA: 0x%llx", guid, pa); | |
| 89 | + | |
| 86 | 90 | return 0; |
| 87 | 91 | } |
| 88 | 92 | |
| @@ -148,9 +152,15 @@ acpi_parse_prmt(union acpi_subtable_headers *header, const unsigned long end) · 59 unmodified lines | ||
| 148 | 152 | th = &tm->handlers[cur_handler]; |
| 149 | 153 | |
| 150 | 154 | guid_copy(&th->guid, (guid_t *)handler_info->handler_guid); |
| 151 | − th->handler_addr = (void *)efi_pa_va_lookup(handler_info->handler_address); | |
| 152 | − th->static_data_buffer_addr = efi_pa_va_lookup(handler_info->static_data_buffer_address); | |
| 153 | − th->acpi_param_buffer_addr = efi_pa_va_lookup(handler_info->acpi_param_buffer_address); | |
| 155 | + th->handler_addr = | |
| 156 | + (void *)efi_pa_va_lookup(&th->guid, handler_info->handler_address); | |
| 157 | + | |
| 158 | + th->static_data_buffer_addr = | |
| 159 | + efi_pa_va_lookup(&th->guid, handler_info->static_data_buffer_address); | |
| 160 | + | |
| 161 | + th->acpi_param_buffer_addr = | |
| 162 | + efi_pa_va_lookup(&th->guid, handler_info->acpi_param_buffer_address); | |
| 163 | + | |
| 154 | 164 | } while (++cur_handler < tm->handler_count && (handler_info = get_next_handler(handler_info))); |
| 155 | 165 | |
| 156 | 166 | return 0; |
| @@ -277,6 +287,13 @@ static acpi_status acpi_platformrt_space_handler(u32 function, · 120 unmodified lines | ||
| 277 | 287 | if (!handler || !module) |
| 278 | 288 | goto invalid_guid; |
| 279 | 289 | |
| 290 | + if (!handler->handler_addr || | |
| 291 | + !handler->static_data_buffer_addr || | |
| 292 | + !handler->acpi_param_buffer_addr) { | |
| 293 | + buffer->prm_status = PRM_HANDLER_ERROR; | |
| 294 | + return AE_OK; | |
| 295 | + } | |
| 296 | + | |
| 280 | 297 | ACPI_COPY_NAMESEG(context.signature, "PRMC"); |
| 281 | 298 | context.revision = 0x0; |
| 282 | 299 | context.reserved = 0x0; |
| @@ -448,73 +448,31 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = { · 447 unmodified lines | ||
| 448 | 448 | }, |
| 449 | 449 | }, |
| 450 | 450 | { |
| 451 | − /* Asus ExpertBook B1402CBA */ | |
| 451 | + /* Asus ExpertBook B1402C* */ | |
| 452 | 452 | .matches = { |
| 453 | 453 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 454 | − DMI_MATCH(DMI_BOARD_NAME, "B1402CBA"), | |
| 454 | + DMI_MATCH(DMI_BOARD_NAME, "B1402C"), | |
| 455 | 455 | }, |
| 456 | 456 | }, |
| 457 | 457 | { |
| 458 | − /* Asus ExpertBook B1402CVA */ | |
| 458 | + /* Asus ExpertBook B1502C* */ | |
| 459 | 459 | .matches = { |
| 460 | 460 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 461 | − DMI_MATCH(DMI_BOARD_NAME, "B1402CVA"), | |
| 461 | + DMI_MATCH(DMI_BOARD_NAME, "B1502C"), | |
| 462 | 462 | }, |
| 463 | 463 | }, |
| 464 | 464 | { |
| 465 | − /* Asus ExpertBook B1502CBA */ | |
| 465 | + /* Asus ExpertBook B2402 (B2402CBA / B2402FBA / B2402CVA / B2402FVA) */ | |
| 466 | 466 | .matches = { |
| 467 | 467 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 468 | − DMI_MATCH(DMI_BOARD_NAME, "B1502CBA"), | |
| 468 | + DMI_MATCH(DMI_BOARD_NAME, "B2402"), | |
| 469 | 469 | }, |
| 470 | 470 | }, |
| 471 | 471 | { |
| 472 | − /* Asus ExpertBook B1502CGA */ | |
| 472 | + /* Asus ExpertBook B2502 (B2502CBA / B2502FBA / B2502CVA / B2502FVA) */ | |
| 473 | 473 | .matches = { |
| 474 | 474 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 475 | − DMI_MATCH(DMI_BOARD_NAME, "B1502CGA"), | |
| 476 | − }, | |
| 477 | − }, | |
| 478 | − { | |
| 479 | − /* Asus ExpertBook B1502CVA */ | |
| 480 | − .matches = { | |
| 481 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 482 | − DMI_MATCH(DMI_BOARD_NAME, "B1502CVA"), | |
| 483 | − }, | |
| 484 | − }, | |
| 485 | − { | |
| 486 | − /* Asus ExpertBook B2402CBA */ | |
| 487 | − .matches = { | |
| 488 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 489 | − DMI_MATCH(DMI_BOARD_NAME, "B2402CBA"), | |
| 490 | − }, | |
| 491 | − }, | |
| 492 | − { | |
| 493 | − /* Asus ExpertBook B2402FBA */ | |
| 494 | − .matches = { | |
| 495 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 496 | − DMI_MATCH(DMI_BOARD_NAME, "B2402FBA"), | |
| 497 | − }, | |
| 498 | − }, | |
| 499 | − { | |
| 500 | − /* Asus ExpertBook B2502 */ | |
| 501 | − .matches = { | |
| 502 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 503 | − DMI_MATCH(DMI_BOARD_NAME, "B2502CBA"), | |
| 504 | − }, | |
| 505 | − }, | |
| 506 | − { | |
| 507 | − /* Asus ExpertBook B2502FBA */ | |
| 508 | − .matches = { | |
| 509 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 510 | − DMI_MATCH(DMI_BOARD_NAME, "B2502FBA"), | |
| 511 | − }, | |
| 512 | − }, | |
| 513 | − { | |
| 514 | − /* Asus ExpertBook B2502CVA */ | |
| 515 | − .matches = { | |
| 516 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 517 | − DMI_MATCH(DMI_BOARD_NAME, "B2502CVA"), | |
| 475 | + DMI_MATCH(DMI_BOARD_NAME, "B2502"), | |
| 518 | 476 | }, |
| 519 | 477 | }, |
| 520 | 478 | { |
| @@ -532,31 +490,24 @@ static const struct dmi_system_id irq1_level_low_skip_override[] = { · 11 unmodified lines | ||
| 532 | 490 | }, |
| 533 | 491 | }, |
| 534 | 492 | { |
| 535 | − /* Asus Vivobook Pro N6506MV */ | |
| 536 | − .matches = { | |
| 537 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 538 | − DMI_MATCH(DMI_BOARD_NAME, "N6506MV"), | |
| 539 | − }, | |
| 540 | − }, | |
| 541 | − { | |
| 542 | − /* Asus Vivobook Pro N6506MU */ | |
| 493 | + /* Asus Vivobook Pro N6506M* */ | |
| 543 | 494 | .matches = { |
| 544 | 495 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 545 | − DMI_MATCH(DMI_BOARD_NAME, "N6506MU"), | |
| 496 | + DMI_MATCH(DMI_BOARD_NAME, "N6506M"), | |
| 546 | 497 | }, |
| 547 | 498 | }, |
| 548 | 499 | { |
| 549 | − /* Asus Vivobook Pro N6506MJ */ | |
| 500 | + /* LG Electronics 17U70P */ | |
| 550 | 501 | .matches = { |
| 551 | − DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | |
| 552 | − DMI_MATCH(DMI_BOARD_NAME, "N6506MJ"), | |
| 502 | + DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"), | |
| 503 | + DMI_MATCH(DMI_BOARD_NAME, "17U70P"), | |
| 553 | 504 | }, |
| 554 | 505 | }, |
| 555 | 506 | { |
| 556 | − /* LG Electronics 17U70P */ | |
| 507 | + /* LG Electronics 16T90SP */ | |
| 557 | 508 | .matches = { |
| 558 | 509 | DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"), |
| 559 | − DMI_MATCH(DMI_BOARD_NAME, "17U70P"), | |
| 510 | + DMI_MATCH(DMI_BOARD_NAME, "16T90SP"), | |
| 560 | 511 | }, |
| 561 | 512 | }, |
| 562 | 513 | { } |
| @@ -651,6 +651,7 @@ void ata_scsi_cmd_error_handler(struct Scsi_Host *host, struct ata_port *ap, · 650 unmodified lines | ||
| 651 | 651 | /* the scmd has an associated qc */ |
| 652 | 652 | if (!(qc->flags & ATA_QCFLAG_EH)) { |
| 653 | 653 | /* which hasn't failed yet, timeout */ |
| 654 | + set_host_byte(scmd, DID_TIME_OUT); | |
| 654 | 655 | qc->err_mask |= AC_ERR_TIMEOUT; |
| 655 | 656 | qc->flags |= ATA_QCFLAG_EH; |
| 656 | 657 | nr_timedout++; |
| @@ -4099,10 +4100,20 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) · 3442 unmodified lines | ||
| 4099 | 4100 | |
| 4100 | 4101 | WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); |
| 4101 | 4102 | |
| 4102 | − /* Set all devices attached to the port in standby mode */ | |
| 4103 | − ata_for_each_link(link, ap, HOST_FIRST) { | |
| 4104 | − ata_for_each_dev(dev, link, ENABLED) | |
| 4105 | − ata_dev_power_set_standby(dev); | |
| 4103 | + /* | |
| 4104 | + * We will reach this point for all of the PM events: | |
| 4105 | + * PM_EVENT_SUSPEND (if runtime pm, PM_EVENT_AUTO will also be set) | |
| 4106 | + * PM_EVENT_FREEZE, and PM_EVENT_HIBERNATE. | |
| 4107 | + * | |
| 4108 | + * We do not want to perform disk spin down for PM_EVENT_FREEZE. | |
| 4109 | + * (Spin down will be performed by the subsequent PM_EVENT_HIBERNATE.) | |
| 4110 | + */ | |
| 4111 | + if (!(ap->pm_mesg.event & PM_EVENT_FREEZE)) { | |
| 4112 | + /* Set all devices attached to the port in standby mode */ | |
| 4113 | + ata_for_each_link(link, ap, HOST_FIRST) { | |
| 4114 | + ata_for_each_dev(dev, link, ENABLED) | |
| 4115 | + ata_dev_power_set_standby(dev); | |
| 4116 | + } | |
| 4106 | 4117 | } |
| 4107 | 4118 | |
| 4108 | 4119 | /* |
| @@ -26,7 +26,6 @@ · 25 unmodified lines | ||
| 26 | 26 | #include <linux/of.h> |
| 27 | 27 | #include <linux/of_device.h> |
| 28 | 28 | #include <linux/pm_runtime.h> |
| 29 | −#include <linux/rcupdate.h> | |
| 30 | 29 | #include <linux/sched/mm.h> |
| 31 | 30 | #include <linux/sched/signal.h> |
| 32 | 31 | #include <linux/slab.h> |
| @@ -2634,7 +2633,6 @@ static const char *dev_uevent_name(const struct kobject *kobj) · 2601 unmodified lines | ||
| 2634 | 2633 | static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) |
| 2635 | 2634 | { |
| 2636 | 2635 | const struct device *dev = kobj_to_dev(kobj); |
| 2637 | − struct device_driver *driver; | |
| 2638 | 2636 | int retval = 0; |
| 2639 | 2637 | |
| 2640 | 2638 | /* add device node properties if present */ |
| @@ -2663,12 +2661,8 @@ static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) · 22 unmodified lines | ||
| 2663 | 2661 | if (dev->type && dev->type->name) |
| 2664 | 2662 | add_uevent_var(env, "DEVTYPE=%s", dev->type->name); |
| 2665 | 2663 | |
| 2666 | − /* Synchronize with module_remove_driver() */ | |
| 2667 | − rcu_read_lock(); | |
| 2668 | − driver = READ_ONCE(dev->driver); | |
| 2669 | − if (driver) | |
| 2670 | − add_uevent_var(env, "DRIVER=%s", driver->name); | |
| 2671 | − rcu_read_unlock(); | |
| 2664 | + if (dev->driver) | |
| 2665 | + add_uevent_var(env, "DRIVER=%s", dev->driver->name); | |
| 2672 | 2666 | |
| 2673 | 2667 | /* Add common DT information about the device */ |
| 2674 | 2668 | of_device_uevent(dev, env); |
| @@ -2738,8 +2732,11 @@ static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, · 63 unmodified lines | ||
| 2738 | 2732 | if (!env) |
| 2739 | 2733 | return -ENOMEM; |
| 2740 | 2734 | |
| 2735 | + /* Synchronize with really_probe() */ | |
| 2736 | + device_lock(dev); | |
| 2741 | 2737 | /* let the kset specific function add its keys */ |
| 2742 | 2738 | retval = kset->uevent_ops->uevent(&dev->kobj, env); |
| 2739 | + device_unlock(dev); | |
| 2743 | 2740 | if (retval) |
| 2744 | 2741 | goto out; |
| 2745 | 2742 | |
| @@ -4037,6 +4034,41 @@ int device_for_each_child_reverse(struct device *parent, void *data, · 1291 unmodified lines | ||
| 4037 | 4034 | } |
| 4038 | 4035 | EXPORT_SYMBOL_GPL(device_for_each_child_reverse); |
| 4039 | 4036 | |
| 4037 | +/** | |
| 4038 | + * device_for_each_child_reverse_from - device child iterator in reversed order. | |
| 4039 | + * @parent: parent struct device. | |
| 4040 | + * @from: optional starting point in child list | |
| 4041 | + * @fn: function to be called for each device. | |
| 4042 | + * @data: data for the callback. | |
| 4043 | + * | |
| 4044 | + * Iterate over @parent's child devices, starting at @from, and call @fn | |
| 4045 | + * for each, passing it @data. This helper is identical to | |
| 4046 | + * device_for_each_child_reverse() when @from is NULL. | |
| 4047 | + * | |
| 4048 | + * @fn is checked each iteration. If it returns anything other than 0, | |
| 4049 | + * iteration stop and that value is returned to the caller of | |
| 4050 | + * device_for_each_child_reverse_from(); | |
| 4051 | + */ | |
| 4052 | +int device_for_each_child_reverse_from(struct device *parent, | |
| 4053 | + struct device *from, const void *data, | |
| 4054 | + int (*fn)(struct device *, const void *)) | |
| 4055 | +{ | |
| 4056 | + struct klist_iter i; | |
| 4057 | + struct device *child; | |
| 4058 | + int error = 0; | |
| 4059 | + | |
| 4060 | + if (!parent->p) | |
| 4061 | + return 0; | |
| 4062 | + | |
| 4063 | + klist_iter_init_node(&parent->p->klist_children, &i, | |
| 4064 | + (from ? &from->p->knode_parent : NULL)); | |
| 4065 | + while ((child = prev_device(&i)) && !error) | |
| 4066 | + error = fn(child, data); | |
| 4067 | + klist_iter_exit(&i); | |
| 4068 | + return error; | |
| 4069 | +} | |
| 4070 | +EXPORT_SYMBOL_GPL(device_for_each_child_reverse_from); | |
| 4071 | + | |
| 4040 | 4072 | /** |
| 4041 | 4073 | * device_find_child - device iterator for locating a particular device. |
| 4042 | 4074 | * @parent: parent struct device |
| @@ -7,7 +7,6 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <linux/errno.h> |
| 8 | 8 | #include <linux/slab.h> |
| 9 | 9 | #include <linux/string.h> |
| 10 | −#include <linux/rcupdate.h> | |
| 11 | 10 | #include "base.h" |
| 12 | 11 | |
| 13 | 12 | static char *make_driver_name(const struct device_driver *drv) |
| @@ -102,9 +101,6 @@ void module_remove_driver(const struct device_driver *drv) · 88 unmodified lines | ||
| 102 | 101 | if (!drv) |
| 103 | 102 | return; |
| 104 | 103 | |
| 105 | − /* Synchronize with dev_uevent() */ | |
| 106 | − synchronize_rcu(); | |
| 107 | − | |
| 108 | 104 | sysfs_remove_link(&drv->p->kobj, "module"); |
| 109 | 105 | |
| 110 | 106 | if (drv->owner) |
| @@ -195,6 +195,7 @@ int dev_pm_domain_attach_list(struct device *dev, · 194 unmodified lines | ||
| 195 | 195 | struct device *pd_dev = NULL; |
| 196 | 196 | int ret, i, num_pds = 0; |
| 197 | 197 | bool by_id = true; |
| 198 | + size_t size; | |
| 198 | 199 | u32 pd_flags = data ? data->pd_flags : 0; |
| 199 | 200 | u32 link_flags = pd_flags & PD_FLAG_NO_DEV_LINK ? 0 : |
| 200 | 201 | DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME; |
| @@ -217,19 +218,17 @@ int dev_pm_domain_attach_list(struct device *dev, · 16 unmodified lines | ||
| 217 | 218 | if (num_pds <= 0) |
| 218 | 219 | return 0; |
| 219 | 220 | |
| 220 | − pds = devm_kzalloc(dev, sizeof(*pds), GFP_KERNEL); | |
| 221 | + pds = kzalloc(sizeof(*pds), GFP_KERNEL); | |
| 221 | 222 | if (!pds) |
| 222 | 223 | return -ENOMEM; |
| 223 | 224 | |
| 224 | − pds->pd_devs = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_devs), | |
| 225 | − GFP_KERNEL); | |
| 226 | − if (!pds->pd_devs) | |
| 227 | − return -ENOMEM; | |
| 228 | − | |
| 229 | − pds->pd_links = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_links), | |
| 230 | − GFP_KERNEL); | |
| 231 | − if (!pds->pd_links) | |
| 232 | − return -ENOMEM; | |
| 225 | + size = sizeof(*pds->pd_devs) + sizeof(*pds->pd_links); | |
| 226 | + pds->pd_devs = kcalloc(num_pds, size, GFP_KERNEL); | |
| 227 | + if (!pds->pd_devs) { | |
| 228 | + ret = -ENOMEM; | |
| 229 | + goto free_pds; | |
| 230 | + } | |
| 231 | + pds->pd_links = (void *)(pds->pd_devs + num_pds); | |
| 233 | 232 | |
| 234 | 233 | if (link_flags && pd_flags & PD_FLAG_DEV_LINK_ON) |
| 235 | 234 | link_flags |= DL_FLAG_RPM_ACTIVE; |
| @@ -272,6 +271,9 @@ err_attach: · 36 unmodified lines | ||
| 272 | 271 | device_link_del(pds->pd_links[i]); |
| 273 | 272 | dev_pm_domain_detach(pds->pd_devs[i], true); |
| 274 | 273 | } |
| 274 | + kfree(pds->pd_devs); | |
| 275 | +free_pds: | |
| 276 | + kfree(pds); | |
| 275 | 277 | return ret; |
| 276 | 278 | } |
| 277 | 279 | EXPORT_SYMBOL_GPL(dev_pm_domain_attach_list); |
| @@ -363,6 +365,9 @@ void dev_pm_domain_detach_list(struct dev_pm_domain_list *list) · 85 unmodified lines | ||
| 363 | 365 | device_link_del(list->pd_links[i]); |
| 364 | 366 | dev_pm_domain_detach(list->pd_devs[i], true); |
| 365 | 367 | } |
| 368 | + | |
| 369 | + kfree(list->pd_devs); | |
| 370 | + kfree(list); | |
| 366 | 371 | } |
| 367 | 372 | EXPORT_SYMBOL_GPL(dev_pm_domain_detach_list); |
| 368 | 373 | |
| @@ -1364,7 +1364,6 @@ extern struct bio_set drbd_io_bio_set; · 1363 unmodified lines | ||
| 1364 | 1364 | |
| 1365 | 1365 | extern struct mutex resources_mutex; |
| 1366 | 1366 | |
| 1367 | −extern int conn_lowest_minor(struct drbd_connection *connection); | |
| 1368 | 1367 | extern enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor); |
| 1369 | 1368 | extern void drbd_destroy_device(struct kref *kref); |
| 1370 | 1369 | extern void drbd_delete_device(struct drbd_device *device); |
| @@ -471,20 +471,6 @@ void _drbd_thread_stop(struct drbd_thread *thi, int restart, int wait) · 470 unmodified lines | ||
| 471 | 471 | wait_for_completion(&thi->stop); |
| 472 | 472 | } |
| 473 | 473 | |
| 474 | −int conn_lowest_minor(struct drbd_connection *connection) | |
| 475 | −{ | |
| 476 | − struct drbd_peer_device *peer_device; | |
| 477 | − int vnr = 0, minor = -1; | |
| 478 | − | |
| 479 | − rcu_read_lock(); | |
| 480 | − peer_device = idr_get_next(&connection->peer_devices, &vnr); | |
| 481 | − if (peer_device) | |
| 482 | − minor = device_to_minor(peer_device->device); | |
| 483 | − rcu_read_unlock(); | |
| 484 | − | |
| 485 | − return minor; | |
| 486 | −} | |
| 487 | − | |
| 488 | 474 | #ifdef CONFIG_SMP |
| 489 | 475 | /* |
| 490 | 476 | * drbd_calc_cpu_mask() - Generate CPU masks, spread over all CPUs |
| @@ -2380,10 +2380,19 @@ static int ublk_ctrl_add_dev(struct io_uring_cmd *cmd) · 2379 unmodified lines | ||
| 2380 | 2380 | * TODO: provide forward progress for RECOVERY handler, so that |
| 2381 | 2381 | * unprivileged device can benefit from it |
| 2382 | 2382 | */ |
| 2383 | − if (info.flags & UBLK_F_UNPRIVILEGED_DEV) | |
| 2383 | + if (info.flags & UBLK_F_UNPRIVILEGED_DEV) { | |
| 2384 | 2384 | info.flags &= ~(UBLK_F_USER_RECOVERY_REISSUE | |
| 2385 | 2385 | UBLK_F_USER_RECOVERY); |
| 2386 | 2386 | |
| 2387 | + /* | |
| 2388 | + * For USER_COPY, we depends on userspace to fill request | |
| 2389 | + * buffer by pwrite() to ublk char device, which can't be | |
| 2390 | + * used for unprivileged device | |
| 2391 | + */ | |
| 2392 | + if (info.flags & UBLK_F_USER_COPY) | |
| 2393 | + return -EINVAL; | |
| 2394 | + } | |
| 2395 | + | |
| 2387 | 2396 | /* the created device is always owned by current user */ |
| 2388 | 2397 | ublk_store_owner_uid_gid(&info.owner_uid, &info.owner_gid); |
| 2389 | 2398 | |
| @@ -1345,10 +1345,15 @@ static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags) · 1344 unmodified lines | ||
| 1345 | 1345 | if (!urb) |
| 1346 | 1346 | return -ENOMEM; |
| 1347 | 1347 | |
| 1348 | − /* Use maximum HCI Event size so the USB stack handles | |
| 1349 | − * ZPL/short-transfer automatically. | |
| 1350 | − */ | |
| 1351 | − size = HCI_MAX_EVENT_SIZE; | |
| 1348 | + if (le16_to_cpu(data->udev->descriptor.idVendor) == 0x0a12 && | |
| 1349 | + le16_to_cpu(data->udev->descriptor.idProduct) == 0x0001) | |
| 1350 | + /* Fake CSR devices don't seem to support sort-transter */ | |
| 1351 | + size = le16_to_cpu(data->intr_ep->wMaxPacketSize); | |
| 1352 | + else | |
| 1353 | + /* Use maximum HCI Event size so the USB stack handles | |
| 1354 | + * ZPL/short-transfer automatically. | |
| 1355 | + */ | |
| 1356 | + size = HCI_MAX_EVENT_SIZE; | |
| 1352 | 1357 | |
| 1353 | 1358 | buf = kmalloc(size, mem_flags); |
| 1354 | 1359 | if (!buf) { |
| @@ -4041,8 +4046,10 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message) · 2686 unmodified lines | ||
| 4041 | 4046 | |
| 4042 | 4047 | BT_DBG("intf %p", intf); |
| 4043 | 4048 | |
| 4044 | − /* Don't suspend if there are connections */ | |
| 4045 | − if (hci_conn_count(data->hdev)) | |
| 4049 | + /* Don't auto-suspend if there are connections; external suspend calls | |
| 4050 | + * shall never fail. | |
| 4051 | + */ | |
| 4052 | + if (PMSG_IS_AUTO(message) && hci_conn_count(data->hdev)) | |
| 4046 | 4053 | return -EBUSY; |
| 4047 | 4054 | |
| 4048 | 4055 | if (data->suspend_count++) |
| @@ -2313,7 +2313,7 @@ static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi, · 2312 unmodified lines | ||
| 2313 | 2313 | return -EINVAL; |
| 2314 | 2314 | |
| 2315 | 2315 | /* Prevent arg from speculatively bypassing the length check */ |
| 2316 | − barrier_nospec(); | |
| 2316 | + arg = array_index_nospec(arg, cdi->capacity); | |
| 2317 | 2317 | |
| 2318 | 2318 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
| 2319 | 2319 | if (!info) |
| @@ -674,6 +674,16 @@ EXPORT_SYMBOL_GPL(tpm_chip_register); · 673 unmodified lines | ||
| 674 | 674 | */ |
| 675 | 675 | void tpm_chip_unregister(struct tpm_chip *chip) |
| 676 | 676 | { |
| 677 | +#ifdef CONFIG_TCG_TPM2_HMAC | |
| 678 | + int rc; | |
| 679 | + | |
| 680 | + rc = tpm_try_get_ops(chip); | |
| 681 | + if (!rc) { | |
| 682 | + tpm2_end_auth_session(chip); | |
| 683 | + tpm_put_ops(chip); | |
| 684 | + } | |
| 685 | +#endif | |
| 686 | + | |
| 677 | 687 | tpm_del_legacy_sysfs(chip); |
| 678 | 688 | if (tpm_is_hwrng_enabled(chip)) |
| 679 | 689 | hwrng_unregister(&chip->hwrng); |
| @@ -27,6 +27,9 @@ static ssize_t tpm_dev_transmit(struct tpm_chip *chip, struct tpm_space *space, · 26 unmodified lines | ||
| 27 | 27 | struct tpm_header *header = (void *)buf; |
| 28 | 28 | ssize_t ret, len; |
| 29 | 29 | |
| 30 | + if (chip->flags & TPM_CHIP_FLAG_TPM2) | |
| 31 | + tpm2_end_auth_session(chip); | |
| 32 | + | |
| 30 | 33 | ret = tpm2_prepare_space(chip, space, buf, bufsiz); |
| 31 | 34 | /* If the command is not implemented by the TPM, synthesize a |
| 32 | 35 | * response with a TPM2_RC_COMMAND_CODE return for user-space. |
| @@ -379,10 +379,12 @@ int tpm_pm_suspend(struct device *dev) · 378 unmodified lines | ||
| 379 | 379 | |
| 380 | 380 | rc = tpm_try_get_ops(chip); |
| 381 | 381 | if (!rc) { |
| 382 | − if (chip->flags & TPM_CHIP_FLAG_TPM2) | |
| 382 | + if (chip->flags & TPM_CHIP_FLAG_TPM2) { | |
| 383 | + tpm2_end_auth_session(chip); | |
| 383 | 384 | tpm2_shutdown(chip, TPM2_SU_STATE); |
| 384 | − else | |
| 385 | + } else { | |
| 385 | 386 | rc = tpm1_pm_suspend(chip, tpm_suspend_pcr); |
| 387 | + } | |
| 386 | 388 | |
| 387 | 389 | tpm_put_ops(chip); |
| 388 | 390 | } |
| @@ -333,6 +333,9 @@ void tpm_buf_append_hmac_session(struct tpm_chip *chip, struct tpm_buf *buf, · 332 unmodified lines | ||
| 333 | 333 | } |
| 334 | 334 | |
| 335 | 335 | #ifdef CONFIG_TCG_TPM2_HMAC |
| 336 | + /* The first write to /dev/tpm{rm0} will flush the session. */ | |
| 337 | + attributes |= TPM2_SA_CONTINUE_SESSION; | |
| 338 | + | |
| 336 | 339 | /* |
| 337 | 340 | * The Architecture Guide requires us to strip trailing zeros |
| 338 | 341 | * before computing the HMAC |
| @@ -484,7 +487,8 @@ static void tpm2_KDFe(u8 z[EC_PT_SZ], const char *str, u8 *pt_u, u8 *pt_v, · 145 unmodified lines | ||
| 484 | 487 | sha256_final(&sctx, out); |
| 485 | 488 | } |
| 486 | 489 | |
| 487 | −static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip) | |
| 490 | +static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip, | |
| 491 | + struct tpm2_auth *auth) | |
| 488 | 492 | { |
| 489 | 493 | struct crypto_kpp *kpp; |
| 490 | 494 | struct kpp_request *req; |
| @@ -543,7 +547,7 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip) · 52 unmodified lines | ||
| 543 | 547 | sg_set_buf(&s[0], chip->null_ec_key_x, EC_PT_SZ); |
| 544 | 548 | sg_set_buf(&s[1], chip->null_ec_key_y, EC_PT_SZ); |
| 545 | 549 | kpp_request_set_input(req, s, EC_PT_SZ*2); |
| 546 | − sg_init_one(d, chip->auth->salt, EC_PT_SZ); | |
| 550 | + sg_init_one(d, auth->salt, EC_PT_SZ); | |
| 547 | 551 | kpp_request_set_output(req, d, EC_PT_SZ); |
| 548 | 552 | crypto_kpp_compute_shared_secret(req); |
| 549 | 553 | kpp_request_free(req); |
| @@ -554,8 +558,7 @@ static void tpm_buf_append_salt(struct tpm_buf *buf, struct tpm_chip *chip) · 4 unmodified lines | ||
| 554 | 558 | * This works because KDFe fully consumes the secret before it |
| 555 | 559 | * writes the salt |
| 556 | 560 | */ |
| 557 | − tpm2_KDFe(chip->auth->salt, "SECRET", x, chip->null_ec_key_x, | |
| 558 | − chip->auth->salt); | |
| 561 | + tpm2_KDFe(auth->salt, "SECRET", x, chip->null_ec_key_x, auth->salt); | |
| 559 | 562 | |
| 560 | 563 | out: |
| 561 | 564 | crypto_free_kpp(kpp); |
| @@ -853,7 +856,9 @@ int tpm_buf_check_hmac_response(struct tpm_chip *chip, struct tpm_buf *buf, · 291 unmodified lines | ||
| 853 | 856 | if (rc) |
| 854 | 857 | /* manually close the session if it wasn't consumed */ |
| 855 | 858 | tpm2_flush_context(chip, auth->handle); |
| 856 | − memzero_explicit(auth, sizeof(*auth)); | |
| 859 | + | |
| 860 | + kfree_sensitive(auth); | |
| 861 | + chip->auth = NULL; | |
| 857 | 862 | } else { |
| 858 | 863 | /* reset for next use */ |
| 859 | 864 | auth->session = TPM_HEADER_SIZE; |
| @@ -881,7 +886,8 @@ void tpm2_end_auth_session(struct tpm_chip *chip) · 21 unmodified lines | ||
| 881 | 886 | return; |
| 882 | 887 | |
| 883 | 888 | tpm2_flush_context(chip, auth->handle); |
| 884 | − memzero_explicit(auth, sizeof(*auth)); | |
| 889 | + kfree_sensitive(auth); | |
| 890 | + chip->auth = NULL; | |
| 885 | 891 | } |
| 886 | 892 | EXPORT_SYMBOL(tpm2_end_auth_session); |
| 887 | 893 | |
| @@ -915,33 +921,37 @@ static int tpm2_parse_start_auth_session(struct tpm2_auth *auth, · 27 unmodified lines | ||
| 915 | 921 | |
| 916 | 922 | static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key) |
| 917 | 923 | { |
| 918 | − int rc; | |
| 919 | 924 | unsigned int offset = 0; /* dummy offset for null seed context */ |
| 920 | 925 | u8 name[SHA256_DIGEST_SIZE + 2]; |
| 926 | + u32 tmp_null_key; | |
| 927 | + int rc; | |
| 921 | 928 | |
| 922 | 929 | rc = tpm2_load_context(chip, chip->null_key_context, &offset, |
| 923 | − null_key); | |
| 924 | − if (rc != -EINVAL) | |
| 925 | − return rc; | |
| 930 | + &tmp_null_key); | |
| 931 | + if (rc != -EINVAL) { | |
| 932 | + if (!rc) | |
| 933 | + *null_key = tmp_null_key; | |
| 934 | + goto err; | |
| 935 | + } | |
| 926 | 936 | |
| 927 | − /* an integrity failure may mean the TPM has been reset */ | |
| 928 | − dev_err(&chip->dev, "NULL key integrity failure!\n"); | |
| 929 | − /* check the null name against what we know */ | |
| 930 | − tpm2_create_primary(chip, TPM2_RH_NULL, NULL, name); | |
| 931 | − if (memcmp(name, chip->null_key_name, sizeof(name)) == 0) | |
| 932 | − /* name unchanged, assume transient integrity failure */ | |
| 933 | − return rc; | |
| 934 | − /* | |
| 935 | − * Fatal TPM failure: the NULL seed has actually changed, so | |
| 936 | − * the TPM must have been illegally reset. All in-kernel TPM | |
| 937 | − * operations will fail because the NULL primary can't be | |
| 938 | − * loaded to salt the sessions, but disable the TPM anyway so | |
| 939 | − * userspace programmes can't be compromised by it. | |
| 940 | − */ | |
| 941 | − dev_err(&chip->dev, "NULL name has changed, disabling TPM due to interference\n"); | |
| 937 | + /* Try to re-create null key, given the integrity failure: */ | |
| 938 | + rc = tpm2_create_primary(chip, TPM2_RH_NULL, &tmp_null_key, name); | |
| 939 | + if (rc) | |
| 940 | + goto err; | |
| 941 | + | |
| 942 | + /* Return null key if the name has not been changed: */ | |
| 943 | + if (!memcmp(name, chip->null_key_name, sizeof(name))) { | |
| 944 | + *null_key = tmp_null_key; | |
| 945 | + return 0; | |
| 946 | + } | |
| 947 | + | |
| 948 | + /* Deduce from the name change TPM interference: */ | |
| 949 | + dev_err(&chip->dev, "null key integrity check failed\n"); | |
| 950 | + tpm2_flush_context(chip, tmp_null_key); | |
| 942 | 951 | chip->flags |= TPM_CHIP_FLAG_DISABLE; |
| 943 | 952 | |
| 944 | − return rc; | |
| 953 | +err: | |
| 954 | + return rc ? -ENODEV : 0; | |
| 945 | 955 | } |
| 946 | 956 | |
| 947 | 957 | /** |
| @@ -958,16 +968,20 @@ static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key) · 10 unmodified lines | ||
| 958 | 968 | */ |
| 959 | 969 | int tpm2_start_auth_session(struct tpm_chip *chip) |
| 960 | 970 | { |
| 971 | + struct tpm2_auth *auth; | |
| 961 | 972 | struct tpm_buf buf; |
| 962 | − struct tpm2_auth *auth = chip->auth; | |
| 963 | − int rc; | |
| 964 | 973 | u32 null_key; |
| 974 | + int rc; | |
| 965 | 975 | |
| 966 | − if (!auth) { | |
| 967 | − dev_warn_once(&chip->dev, "auth session is not active\n"); | |
| 976 | + if (chip->auth) { | |
| 977 | + dev_warn_once(&chip->dev, "auth session is active\n"); | |
| 968 | 978 | return 0; |
| 969 | 979 | } |
| 970 | 980 | |
| 981 | + auth = kzalloc(sizeof(*auth), GFP_KERNEL); | |
| 982 | + if (!auth) | |
| 983 | + return -ENOMEM; | |
| 984 | + | |
| 971 | 985 | rc = tpm2_load_null(chip, &null_key); |
| 972 | 986 | if (rc) |
| 973 | 987 | goto out; |
| @@ -988,7 +1002,7 @@ int tpm2_start_auth_session(struct tpm_chip *chip) · 14 unmodified lines | ||
| 988 | 1002 | tpm_buf_append(&buf, auth->our_nonce, sizeof(auth->our_nonce)); |
| 989 | 1003 | |
| 990 | 1004 | /* append encrypted salt and squirrel away unencrypted in auth */ |
| 991 | − tpm_buf_append_salt(&buf, chip); | |
| 1005 | + tpm_buf_append_salt(&buf, chip, auth); | |
| 992 | 1006 | /* session type (HMAC, audit or policy) */ |
| 993 | 1007 | tpm_buf_append_u8(&buf, TPM2_SE_HMAC); |
| 994 | 1008 | |
| @@ -1010,10 +1024,13 @@ int tpm2_start_auth_session(struct tpm_chip *chip) · 15 unmodified lines | ||
| 1010 | 1024 | |
| 1011 | 1025 | tpm_buf_destroy(&buf); |
| 1012 | 1026 | |
| 1013 | − if (rc) | |
| 1014 | − goto out; | |
| 1027 | + if (rc == TPM2_RC_SUCCESS) { | |
| 1028 | + chip->auth = auth; | |
| 1029 | + return 0; | |
| 1030 | + } | |
| 1015 | 1031 | |
| 1016 | − out: | |
| 1032 | +out: | |
| 1033 | + kfree_sensitive(auth); | |
| 1017 | 1034 | return rc; |
| 1018 | 1035 | } |
| 1019 | 1036 | EXPORT_SYMBOL(tpm2_start_auth_session); |
| @@ -1347,18 +1364,21 @@ static int tpm2_create_null_primary(struct tpm_chip *chip) · 327 unmodified lines | ||
| 1347 | 1364 | * |
| 1348 | 1365 | * Derive and context save the null primary and allocate memory in the |
| 1349 | 1366 | * struct tpm_chip for the authorizations. |
| 1367 | + * | |
| 1368 | + * Return: | |
| 1369 | + * * 0 - OK | |
| 1370 | + * * -errno - A system error | |
| 1371 | + * * TPM_RC - A TPM error | |
| 1350 | 1372 | */ |
| 1351 | 1373 | int tpm2_sessions_init(struct tpm_chip *chip) |
| 1352 | 1374 | { |
| 1353 | 1375 | int rc; |
| 1354 | 1376 | |
| 1355 | 1377 | rc = tpm2_create_null_primary(chip); |
| 1356 | − if (rc) | |
| 1357 | − dev_err(&chip->dev, "TPM: security failed (NULL seed derivation): %d\n", rc); | |
| 1358 | − | |
| 1359 | − chip->auth = kmalloc(sizeof(*chip->auth), GFP_KERNEL); | |
| 1360 | − if (!chip->auth) | |
| 1361 | − return -ENOMEM; | |
| 1378 | + if (rc) { | |
| 1379 | + dev_err(&chip->dev, "null key creation failed with %d\n", rc); | |
| 1380 | + return rc; | |
| 1381 | + } | |
| 1362 | 1382 | |
| 1363 | 1383 | return rc; |
| 1364 | 1384 | } |
| @@ -2006,25 +2006,27 @@ static int virtcons_probe(struct virtio_device *vdev) · 2005 unmodified lines | ||
| 2006 | 2006 | multiport = true; |
| 2007 | 2007 | } |
| 2008 | 2008 | |
| 2009 | − err = init_vqs(portdev); | |
| 2010 | − if (err < 0) { | |
| 2011 | − dev_err(&vdev->dev, "Error %d initializing vqs\n", err); | |
| 2012 | − goto free_chrdev; | |
| 2013 | − } | |
| 2014 | − | |
| 2015 | 2009 | spin_lock_init(&portdev->ports_lock); |
| 2016 | 2010 | INIT_LIST_HEAD(&portdev->ports); |
| 2017 | 2011 | INIT_LIST_HEAD(&portdev->list); |
| 2018 | 2012 | |
| 2019 | − virtio_device_ready(portdev->vdev); | |
| 2020 | − | |
| 2021 | 2013 | INIT_WORK(&portdev->config_work, &config_work_handler); |
| 2022 | 2014 | INIT_WORK(&portdev->control_work, &control_work_handler); |
| 2023 | 2015 | |
| 2024 | 2016 | if (multiport) { |
| 2025 | 2017 | spin_lock_init(&portdev->c_ivq_lock); |
| 2026 | 2018 | spin_lock_init(&portdev->c_ovq_lock); |
| 2019 | + } | |
| 2027 | 2020 | |
| 2021 | + err = init_vqs(portdev); | |
| 2022 | + if (err < 0) { | |
| 2023 | + dev_err(&vdev->dev, "Error %d initializing vqs\n", err); | |
| 2024 | + goto free_chrdev; | |
| 2025 | + } | |
| 2026 | + | |
| 2027 | + virtio_device_ready(portdev->vdev); | |
| 2028 | + | |
| 2029 | + if (multiport) { | |
| 2028 | 2030 | err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); |
| 2029 | 2031 | if (err < 0) { |
| 2030 | 2032 | dev_err(&vdev->dev, |
| @@ -473,7 +473,7 @@ clk_multiple_parents_mux_test_init(struct kunit *test) · 472 unmodified lines | ||
| 473 | 473 | &clk_dummy_rate_ops, |
| 474 | 474 | 0); |
| 475 | 475 | ctx->parents_ctx[0].rate = DUMMY_CLOCK_RATE_1; |
| 476 | − ret = clk_hw_register(NULL, &ctx->parents_ctx[0].hw); | |
| 476 | + ret = clk_hw_register_kunit(test, NULL, &ctx->parents_ctx[0].hw); | |
| 477 | 477 | if (ret) |
| 478 | 478 | return ret; |
| 479 | 479 | |
| @@ -481,7 +481,7 @@ clk_multiple_parents_mux_test_init(struct kunit *test) · 1 unmodified line | ||
| 481 | 481 | &clk_dummy_rate_ops, |
| 482 | 482 | 0); |
| 483 | 483 | ctx->parents_ctx[1].rate = DUMMY_CLOCK_RATE_2; |
| 484 | − ret = clk_hw_register(NULL, &ctx->parents_ctx[1].hw); | |
| 484 | + ret = clk_hw_register_kunit(test, NULL, &ctx->parents_ctx[1].hw); | |
| 485 | 485 | if (ret) |
| 486 | 486 | return ret; |
| 487 | 487 | |
| @@ -489,23 +489,13 @@ clk_multiple_parents_mux_test_init(struct kunit *test) · 1 unmodified line | ||
| 489 | 489 | ctx->hw.init = CLK_HW_INIT_PARENTS("test-mux", parents, |
| 490 | 490 | &clk_multiple_parents_mux_ops, |
| 491 | 491 | CLK_SET_RATE_PARENT); |
| 492 | − ret = clk_hw_register(NULL, &ctx->hw); | |
| 492 | + ret = clk_hw_register_kunit(test, NULL, &ctx->hw); | |
| 493 | 493 | if (ret) |
| 494 | 494 | return ret; |
| 495 | 495 | |
| 496 | 496 | return 0; |
| 497 | 497 | } |
| 498 | 498 | |
| 499 | −static void | |
| 500 | −clk_multiple_parents_mux_test_exit(struct kunit *test) | |
| 501 | −{ | |
| 502 | − struct clk_multiple_parent_ctx *ctx = test->priv; | |
| 503 | − | |
| 504 | − clk_hw_unregister(&ctx->hw); | |
| 505 | − clk_hw_unregister(&ctx->parents_ctx[0].hw); | |
| 506 | − clk_hw_unregister(&ctx->parents_ctx[1].hw); | |
| 507 | −} | |
| 508 | − | |
| 509 | 499 | /* |
| 510 | 500 | * Test that for a clock with multiple parents, clk_get_parent() |
| 511 | 501 | * actually returns the current one. |
| @@ -561,18 +551,18 @@ clk_test_multiple_parents_mux_set_range_set_parent_get_rate(struct kunit *test) · 49 unmodified lines | ||
| 561 | 551 | { |
| 562 | 552 | struct clk_multiple_parent_ctx *ctx = test->priv; |
| 563 | 553 | struct clk_hw *hw = &ctx->hw; |
| 564 | − struct clk *clk = clk_hw_get_clk(hw, NULL); | |
| 554 | + struct clk *clk = clk_hw_get_clk_kunit(test, hw, NULL); | |
| 565 | 555 | struct clk *parent1, *parent2; |
| 566 | 556 | unsigned long rate; |
| 567 | 557 | int ret; |
| 568 | 558 | |
| 569 | 559 | kunit_skip(test, "This needs to be fixed in the core."); |
| 570 | 560 | |
| 571 | − parent1 = clk_hw_get_clk(&ctx->parents_ctx[0].hw, NULL); | |
| 561 | + parent1 = clk_hw_get_clk_kunit(test, &ctx->parents_ctx[0].hw, NULL); | |
| 572 | 562 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent1); |
| 573 | 563 | KUNIT_ASSERT_TRUE(test, clk_is_match(clk_get_parent(clk), parent1)); |
| 574 | 564 | |
| 575 | − parent2 = clk_hw_get_clk(&ctx->parents_ctx[1].hw, NULL); | |
| 565 | + parent2 = clk_hw_get_clk_kunit(test, &ctx->parents_ctx[1].hw, NULL); | |
| 576 | 566 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent2); |
| 577 | 567 | |
| 578 | 568 | ret = clk_set_rate(parent1, DUMMY_CLOCK_RATE_1); |
| @@ -593,10 +583,6 @@ clk_test_multiple_parents_mux_set_range_set_parent_get_rate(struct kunit *test) · 14 unmodified lines | ||
| 593 | 583 | KUNIT_ASSERT_GT(test, rate, 0); |
| 594 | 584 | KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1 - 1000); |
| 595 | 585 | KUNIT_EXPECT_LE(test, rate, DUMMY_CLOCK_RATE_1 + 1000); |
| 596 | − | |
| 597 | − clk_put(parent2); | |
| 598 | − clk_put(parent1); | |
| 599 | − clk_put(clk); | |
| 600 | 586 | } |
| 601 | 587 | |
| 602 | 588 | static struct kunit_case clk_multiple_parents_mux_test_cases[] = { |
| @@ -617,7 +603,6 @@ static struct kunit_suite · 14 unmodified lines | ||
| 617 | 603 | clk_multiple_parents_mux_test_suite = { |
| 618 | 604 | .name = "clk-multiple-parents-mux-test", |
| 619 | 605 | .init = clk_multiple_parents_mux_test_init, |
| 620 | − .exit = clk_multiple_parents_mux_test_exit, | |
| 621 | 606 | .test_cases = clk_multiple_parents_mux_test_cases, |
| 622 | 607 | }; |
| 623 | 608 | |
| @@ -637,29 +622,20 @@ clk_orphan_transparent_multiple_parent_mux_test_init(struct kunit *test) · 13 unmodified lines | ||
| 637 | 622 | &clk_dummy_rate_ops, |
| 638 | 623 | 0); |
| 639 | 624 | ctx->parents_ctx[1].rate = DUMMY_CLOCK_INIT_RATE; |
| 640 | − ret = clk_hw_register(NULL, &ctx->parents_ctx[1].hw); | |
| 625 | + ret = clk_hw_register_kunit(test, NULL, &ctx->parents_ctx[1].hw); | |
| 641 | 626 | if (ret) |
| 642 | 627 | return ret; |
| 643 | 628 | |
| 644 | 629 | ctx->hw.init = CLK_HW_INIT_PARENTS("test-orphan-mux", parents, |
| 645 | 630 | &clk_multiple_parents_mux_ops, |
| 646 | 631 | CLK_SET_RATE_PARENT); |
| 647 | − ret = clk_hw_register(NULL, &ctx->hw); | |
| 632 | + ret = clk_hw_register_kunit(test, NULL, &ctx->hw); | |
| 648 | 633 | if (ret) |
| 649 | 634 | return ret; |
| 650 | 635 | |
| 651 | 636 | return 0; |
| 652 | 637 | } |
| 653 | 638 | |
| 654 | −static void | |
| 655 | −clk_orphan_transparent_multiple_parent_mux_test_exit(struct kunit *test) | |
| 656 | −{ | |
| 657 | − struct clk_multiple_parent_ctx *ctx = test->priv; | |
| 658 | − | |
| 659 | − clk_hw_unregister(&ctx->hw); | |
| 660 | − clk_hw_unregister(&ctx->parents_ctx[1].hw); | |
| 661 | −} | |
| 662 | − | |
| 663 | 639 | /* |
| 664 | 640 | * Test that, for a mux whose current parent hasn't been registered yet and is |
| 665 | 641 | * thus orphan, clk_get_parent() will return NULL. |
| @@ -912,7 +888,7 @@ clk_test_orphan_transparent_multiple_parent_mux_set_range_set_parent_get_rate(st · 246 unmodified lines | ||
| 912 | 888 | { |
| 913 | 889 | struct clk_multiple_parent_ctx *ctx = test->priv; |
| 914 | 890 | struct clk_hw *hw = &ctx->hw; |
| 915 | − struct clk *clk = clk_hw_get_clk(hw, NULL); | |
| 891 | + struct clk *clk = clk_hw_get_clk_kunit(test, hw, NULL); | |
| 916 | 892 | struct clk *parent; |
| 917 | 893 | unsigned long rate; |
| 918 | 894 | int ret; |
| @@ -921,7 +897,7 @@ clk_test_orphan_transparent_multiple_parent_mux_set_range_set_parent_get_rate(st · 2 unmodified lines | ||
| 921 | 897 | |
| 922 | 898 | clk_hw_set_rate_range(hw, DUMMY_CLOCK_RATE_1, DUMMY_CLOCK_RATE_2); |
| 923 | 899 | |
| 924 | − parent = clk_hw_get_clk(&ctx->parents_ctx[1].hw, NULL); | |
| 900 | + parent = clk_hw_get_clk_kunit(test, &ctx->parents_ctx[1].hw, NULL); | |
| 925 | 901 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent); |
| 926 | 902 | |
| 927 | 903 | ret = clk_set_parent(clk, parent); |
| @@ -931,9 +907,6 @@ clk_test_orphan_transparent_multiple_parent_mux_set_range_set_parent_get_rate(st · 3 unmodified lines | ||
| 931 | 907 | KUNIT_ASSERT_GT(test, rate, 0); |
| 932 | 908 | KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1); |
| 933 | 909 | KUNIT_EXPECT_LE(test, rate, DUMMY_CLOCK_RATE_2); |
| 934 | − | |
| 935 | − clk_put(parent); | |
| 936 | − clk_put(clk); | |
| 937 | 910 | } |
| 938 | 911 | |
| 939 | 912 | static struct kunit_case clk_orphan_transparent_multiple_parent_mux_test_cases[] = { |
| @@ -961,7 +934,6 @@ static struct kunit_case clk_orphan_transparent_multiple_parent_mux_test_cases[] · 21 unmodified lines | ||
| 961 | 934 | static struct kunit_suite clk_orphan_transparent_multiple_parent_mux_test_suite = { |
| 962 | 935 | .name = "clk-orphan-transparent-multiple-parent-mux-test", |
| 963 | 936 | .init = clk_orphan_transparent_multiple_parent_mux_test_init, |
| 964 | − .exit = clk_orphan_transparent_multiple_parent_mux_test_exit, | |
| 965 | 937 | .test_cases = clk_orphan_transparent_multiple_parent_mux_test_cases, |
| 966 | 938 | }; |
| 967 | 939 | |
| @@ -986,7 +958,7 @@ static int clk_single_parent_mux_test_init(struct kunit *test) · 18 unmodified lines | ||
| 986 | 958 | &clk_dummy_rate_ops, |
| 987 | 959 | 0); |
| 988 | 960 | |
| 989 | − ret = clk_hw_register(NULL, &ctx->parent_ctx.hw); | |
| 961 | + ret = clk_hw_register_kunit(test, NULL, &ctx->parent_ctx.hw); | |
| 990 | 962 | if (ret) |
| 991 | 963 | return ret; |
| 992 | 964 | |
| @@ -994,7 +966,7 @@ static int clk_single_parent_mux_test_init(struct kunit *test) · 1 unmodified line | ||
| 994 | 966 | &clk_dummy_single_parent_ops, |
| 995 | 967 | CLK_SET_RATE_PARENT); |
| 996 | 968 | |
| 997 | − ret = clk_hw_register(NULL, &ctx->hw); | |
| 969 | + ret = clk_hw_register_kunit(test, NULL, &ctx->hw); | |
| 998 | 970 | if (ret) |
| 999 | 971 | return ret; |
| 1000 | 972 | |
| @@ -1060,7 +1032,7 @@ clk_test_single_parent_mux_set_range_disjoint_child_last(struct kunit *test) · 59 unmodified lines | ||
| 1060 | 1032 | { |
| 1061 | 1033 | struct clk_single_parent_ctx *ctx = test->priv; |
| 1062 | 1034 | struct clk_hw *hw = &ctx->hw; |
| 1063 | − struct clk *clk = clk_hw_get_clk(hw, NULL); | |
| 1035 | + struct clk *clk = clk_hw_get_clk_kunit(test, hw, NULL); | |
| 1064 | 1036 | struct clk *parent; |
| 1065 | 1037 | int ret; |
| 1066 | 1038 | |
| @@ -1074,8 +1046,6 @@ clk_test_single_parent_mux_set_range_disjoint_child_last(struct kunit *test) · 7 unmodified lines | ||
| 1074 | 1046 | |
| 1075 | 1047 | ret = clk_set_rate_range(clk, 3000, 4000); |
| 1076 | 1048 | KUNIT_EXPECT_LT(test, ret, 0); |
| 1077 | − | |
| 1078 | − clk_put(clk); | |
| 1079 | 1049 | } |
| 1080 | 1050 | |
| 1081 | 1051 | /* |
| @@ -1092,7 +1062,7 @@ clk_test_single_parent_mux_set_range_disjoint_parent_last(struct kunit *test) · 10 unmodified lines | ||
| 1092 | 1062 | { |
| 1093 | 1063 | struct clk_single_parent_ctx *ctx = test->priv; |
| 1094 | 1064 | struct clk_hw *hw = &ctx->hw; |
| 1095 | − struct clk *clk = clk_hw_get_clk(hw, NULL); | |
| 1065 | + struct clk *clk = clk_hw_get_clk_kunit(test, hw, NULL); | |
| 1096 | 1066 | struct clk *parent; |
| 1097 | 1067 | int ret; |
| 1098 | 1068 | |
| @@ -1106,8 +1076,6 @@ clk_test_single_parent_mux_set_range_disjoint_parent_last(struct kunit *test) · 7 unmodified lines | ||
| 1106 | 1076 | |
| 1107 | 1077 | ret = clk_set_rate_range(parent, 3000, 4000); |
| 1108 | 1078 | KUNIT_EXPECT_LT(test, ret, 0); |
| 1109 | − | |
| 1110 | − clk_put(clk); | |
| 1111 | 1079 | } |
| 1112 | 1080 | |
| 1113 | 1081 | /* |
| @@ -1238,7 +1206,6 @@ static struct kunit_suite · 124 unmodified lines | ||
| 1238 | 1206 | clk_single_parent_mux_test_suite = { |
| 1239 | 1207 | .name = "clk-single-parent-mux-test", |
| 1240 | 1208 | .init = clk_single_parent_mux_test_init, |
| 1241 | − .exit = clk_single_parent_mux_test_exit, | |
| 1242 | 1209 | .test_cases = clk_single_parent_mux_test_cases, |
| 1243 | 1210 | }; |
| 1244 | 1211 | |
| @@ -439,7 +439,7 @@ unsigned long rockchip_clk_find_max_clk_id(struct rockchip_clk_branch *list, · 438 unmodified lines | ||
| 439 | 439 | if (list->id > max) |
| 440 | 440 | max = list->id; |
| 441 | 441 | if (list->child && list->child->id > max) |
| 442 | − max = list->id; | |
| 442 | + max = list->child->id; | |
| 443 | 443 | } |
| 444 | 444 | |
| 445 | 445 | return max; |
| @@ -1155,6 +1155,7 @@ static const struct of_device_id exynosautov920_cmu_of_match[] = { · 1154 unmodified lines | ||
| 1155 | 1155 | .compatible = "samsung,exynosautov920-cmu-peric0", |
| 1156 | 1156 | .data = &peric0_cmu_info, |
| 1157 | 1157 | }, |
| 1158 | + { } | |
| 1158 | 1159 | }; |
| 1159 | 1160 | |
| 1160 | 1161 | static struct platform_driver exynosautov920_cmu_driver __refdata = { |
| @@ -536,11 +536,16 @@ static int amd_pstate_verify(struct cpufreq_policy_data *policy) · 535 unmodified lines | ||
| 536 | 536 | |
| 537 | 537 | static int amd_pstate_update_min_max_limit(struct cpufreq_policy *policy) |
| 538 | 538 | { |
| 539 | − u32 max_limit_perf, min_limit_perf, lowest_perf; | |
| 539 | + u32 max_limit_perf, min_limit_perf, lowest_perf, max_perf; | |
| 540 | 540 | struct amd_cpudata *cpudata = policy->driver_data; |
| 541 | 541 | |
| 542 | − max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq); | |
| 543 | − min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq); | |
| 542 | + if (cpudata->boost_supported && !policy->boost_enabled) | |
| 543 | + max_perf = READ_ONCE(cpudata->nominal_perf); | |
| 544 | + else | |
| 545 | + max_perf = READ_ONCE(cpudata->highest_perf); | |
| 546 | + | |
| 547 | + max_limit_perf = div_u64(policy->max * max_perf, policy->cpuinfo.max_freq); | |
| 548 | + min_limit_perf = div_u64(policy->min * max_perf, policy->cpuinfo.max_freq); | |
| 544 | 549 | |
| 545 | 550 | lowest_perf = READ_ONCE(cpudata->lowest_perf); |
| 546 | 551 | if (min_limit_perf < lowest_perf) |
| @@ -1201,11 +1206,21 @@ static int amd_pstate_register_driver(int mode) · 654 unmodified lines | ||
| 1201 | 1206 | return -EINVAL; |
| 1202 | 1207 | |
| 1203 | 1208 | cppc_state = mode; |
| 1209 | + | |
| 1210 | + ret = amd_pstate_enable(true); | |
| 1211 | + if (ret) { | |
| 1212 | + pr_err("failed to enable cppc during amd-pstate driver registration, return %d\n", | |
| 1213 | + ret); | |
| 1214 | + amd_pstate_driver_cleanup(); | |
| 1215 | + return ret; | |
| 1216 | + } | |
| 1217 | + | |
| 1204 | 1218 | ret = cpufreq_register_driver(current_pstate_driver); |
| 1205 | 1219 | if (ret) { |
| 1206 | 1220 | amd_pstate_driver_cleanup(); |
| 1207 | 1221 | return ret; |
| 1208 | 1222 | } |
| 1223 | + | |
| 1209 | 1224 | return 0; |
| 1210 | 1225 | } |
| 1211 | 1226 | |
| @@ -1496,10 +1511,13 @@ static int amd_pstate_epp_update_limit(struct cpufreq_policy *policy) · 284 unmodified lines | ||
| 1496 | 1511 | u64 value; |
| 1497 | 1512 | s16 epp; |
| 1498 | 1513 | |
| 1499 | − max_perf = READ_ONCE(cpudata->highest_perf); | |
| 1514 | + if (cpudata->boost_supported && !policy->boost_enabled) | |
| 1515 | + max_perf = READ_ONCE(cpudata->nominal_perf); | |
| 1516 | + else | |
| 1517 | + max_perf = READ_ONCE(cpudata->highest_perf); | |
| 1500 | 1518 | min_perf = READ_ONCE(cpudata->lowest_perf); |
| 1501 | − max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq); | |
| 1502 | − min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq); | |
| 1519 | + max_limit_perf = div_u64(policy->max * max_perf, policy->cpuinfo.max_freq); | |
| 1520 | + min_limit_perf = div_u64(policy->min * max_perf, policy->cpuinfo.max_freq); | |
| 1503 | 1521 | |
| 1504 | 1522 | if (min_limit_perf < min_perf) |
| 1505 | 1523 | min_limit_perf = min_perf; |
| @@ -947,7 +947,7 @@ struct ahash_alg mv_md5_alg = { · 946 unmodified lines | ||
| 947 | 947 | .base = { |
| 948 | 948 | .cra_name = "md5", |
| 949 | 949 | .cra_driver_name = "mv-md5", |
| 950 | − .cra_priority = 300, | |
| 950 | + .cra_priority = 0, | |
| 951 | 951 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 952 | 952 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 953 | 953 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1018,7 +1018,7 @@ struct ahash_alg mv_sha1_alg = { · 64 unmodified lines | ||
| 1018 | 1018 | .base = { |
| 1019 | 1019 | .cra_name = "sha1", |
| 1020 | 1020 | .cra_driver_name = "mv-sha1", |
| 1021 | − .cra_priority = 300, | |
| 1021 | + .cra_priority = 0, | |
| 1022 | 1022 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1023 | 1023 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1024 | 1024 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1092,7 +1092,7 @@ struct ahash_alg mv_sha256_alg = { · 67 unmodified lines | ||
| 1092 | 1092 | .base = { |
| 1093 | 1093 | .cra_name = "sha256", |
| 1094 | 1094 | .cra_driver_name = "mv-sha256", |
| 1095 | − .cra_priority = 300, | |
| 1095 | + .cra_priority = 0, | |
| 1096 | 1096 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1097 | 1097 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1098 | 1098 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1302,7 +1302,7 @@ struct ahash_alg mv_ahmac_md5_alg = { · 203 unmodified lines | ||
| 1302 | 1302 | .base = { |
| 1303 | 1303 | .cra_name = "hmac(md5)", |
| 1304 | 1304 | .cra_driver_name = "mv-hmac-md5", |
| 1305 | − .cra_priority = 300, | |
| 1305 | + .cra_priority = 0, | |
| 1306 | 1306 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1307 | 1307 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1308 | 1308 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1373,7 +1373,7 @@ struct ahash_alg mv_ahmac_sha1_alg = { · 64 unmodified lines | ||
| 1373 | 1373 | .base = { |
| 1374 | 1374 | .cra_name = "hmac(sha1)", |
| 1375 | 1375 | .cra_driver_name = "mv-hmac-sha1", |
| 1376 | − .cra_priority = 300, | |
| 1376 | + .cra_priority = 0, | |
| 1377 | 1377 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1378 | 1378 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1379 | 1379 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1444,7 +1444,7 @@ struct ahash_alg mv_ahmac_sha256_alg = { · 64 unmodified lines | ||
| 1444 | 1444 | .base = { |
| 1445 | 1445 | .cra_name = "hmac(sha256)", |
| 1446 | 1446 | .cra_driver_name = "mv-hmac-sha256", |
| 1447 | − .cra_priority = 300, | |
| 1447 | + .cra_priority = 0, | |
| 1448 | 1448 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1449 | 1449 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1450 | 1450 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -60,6 +60,7 @@ config CXL_ACPI · 59 unmodified lines | ||
| 60 | 60 | default CXL_BUS |
| 61 | 61 | select ACPI_TABLE_LIB |
| 62 | 62 | select ACPI_HMAT |
| 63 | + select CXL_PORT | |
| 63 | 64 | help |
| 64 | 65 | Enable support for host managed device memory (HDM) resources |
| 65 | 66 | published by a platform's ACPI CXL memory layout description. See |
| @@ -1,13 +1,21 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0 |
| 2 | + | |
| 3 | +# Order is important here for the built-in case: | |
| 4 | +# - 'core' first for fundamental init | |
| 5 | +# - 'port' before platform root drivers like 'acpi' so that CXL-root ports | |
| 6 | +# are immediately enabled | |
| 7 | +# - 'mem' and 'pmem' before endpoint drivers so that memdevs are | |
| 8 | +# immediately enabled | |
| 9 | +# - 'pci' last, also mirrors the hardware enumeration hierarchy | |
| 2 | 10 | obj-y += core/ |
| 3 | −obj-$(CONFIG_CXL_PCI) += cxl_pci.o | |
| 4 | −obj-$(CONFIG_CXL_MEM) += cxl_mem.o | |
| 11 | +obj-$(CONFIG_CXL_PORT) += cxl_port.o | |
| 5 | 12 | obj-$(CONFIG_CXL_ACPI) += cxl_acpi.o |
| 6 | 13 | obj-$(CONFIG_CXL_PMEM) += cxl_pmem.o |
| 7 | −obj-$(CONFIG_CXL_PORT) += cxl_port.o | |
| 14 | +obj-$(CONFIG_CXL_MEM) += cxl_mem.o | |
| 15 | +obj-$(CONFIG_CXL_PCI) += cxl_pci.o | |
| 8 | 16 | |
| 9 | −cxl_mem-y := mem.o | |
| 10 | −cxl_pci-y := pci.o | |
| 17 | +cxl_port-y := port.o | |
| 11 | 18 | cxl_acpi-y := acpi.o |
| 12 | 19 | cxl_pmem-y := pmem.o security.o |
| 13 | −cxl_port-y := port.o | |
| 20 | +cxl_mem-y := mem.o | |
| 21 | +cxl_pci-y := pci.o | |
| @@ -924,6 +924,13 @@ static void __exit cxl_acpi_exit(void) · 923 unmodified lines | ||
| 924 | 924 | |
| 925 | 925 | /* load before dax_hmem sees 'Soft Reserved' CXL ranges */ |
| 926 | 926 | subsys_initcall(cxl_acpi_init); |
| 927 | + | |
| 928 | +/* | |
| 929 | + * Arrange for host-bridge ports to be active synchronous with | |
| 930 | + * cxl_acpi_probe() exit. | |
| 931 | + */ | |
| 932 | +MODULE_SOFTDEP("pre: cxl_port"); | |
| 933 | + | |
| 927 | 934 | module_exit(cxl_acpi_exit); |
| 928 | 935 | MODULE_DESCRIPTION("CXL ACPI: Platform Support"); |
| 929 | 936 | MODULE_LICENSE("GPL v2"); |
| @@ -641,6 +641,9 @@ static int cxl_endpoint_gather_bandwidth(struct cxl_region *cxlr, · 640 unmodified lines | ||
| 641 | 641 | void *ptr; |
| 642 | 642 | int rc; |
| 643 | 643 | |
| 644 | + if (!dev_is_pci(cxlds->dev)) | |
| 645 | + return -ENODEV; | |
| 646 | + | |
| 644 | 647 | if (cxlds->rcd) |
| 645 | 648 | return -ENODEV; |
| 646 | 649 | |
| @@ -712,7 +712,44 @@ static int cxl_decoder_commit(struct cxl_decoder *cxld) · 711 unmodified lines | ||
| 712 | 712 | return 0; |
| 713 | 713 | } |
| 714 | 714 | |
| 715 | −static int cxl_decoder_reset(struct cxl_decoder *cxld) | |
| 715 | +static int commit_reap(struct device *dev, const void *data) | |
| 716 | +{ | |
| 717 | + struct cxl_port *port = to_cxl_port(dev->parent); | |
| 718 | + struct cxl_decoder *cxld; | |
| 719 | + | |
| 720 | + if (!is_switch_decoder(dev) && !is_endpoint_decoder(dev)) | |
| 721 | + return 0; | |
| 722 | + | |
| 723 | + cxld = to_cxl_decoder(dev); | |
| 724 | + if (port->commit_end == cxld->id && | |
| 725 | + ((cxld->flags & CXL_DECODER_F_ENABLE) == 0)) { | |
| 726 | + port->commit_end--; | |
| 727 | + dev_dbg(&port->dev, "reap: %s commit_end: %d\n", | |
| 728 | + dev_name(&cxld->dev), port->commit_end); | |
| 729 | + } | |
| 730 | + | |
| 731 | + return 0; | |
| 732 | +} | |
| 733 | + | |
| 734 | +void cxl_port_commit_reap(struct cxl_decoder *cxld) | |
| 735 | +{ | |
| 736 | + struct cxl_port *port = to_cxl_port(cxld->dev.parent); | |
| 737 | + | |
| 738 | + lockdep_assert_held_write(&cxl_region_rwsem); | |
| 739 | + | |
| 740 | + /* | |
| 741 | + * Once the highest committed decoder is disabled, free any other | |
| 742 | + * decoders that were pinned allocated by out-of-order release. | |
| 743 | + */ | |
| 744 | + port->commit_end--; | |
| 745 | + dev_dbg(&port->dev, "reap: %s commit_end: %d\n", dev_name(&cxld->dev), | |
| 746 | + port->commit_end); | |
| 747 | + device_for_each_child_reverse_from(&port->dev, &cxld->dev, NULL, | |
| 748 | + commit_reap); | |
| 749 | +} | |
| 750 | +EXPORT_SYMBOL_NS_GPL(cxl_port_commit_reap, CXL); | |
| 751 | + | |
| 752 | +static void cxl_decoder_reset(struct cxl_decoder *cxld) | |
| 716 | 753 | { |
| 717 | 754 | struct cxl_port *port = to_cxl_port(cxld->dev.parent); |
| 718 | 755 | struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev); |
| @@ -721,14 +758,14 @@ static int cxl_decoder_reset(struct cxl_decoder *cxld) · 2 unmodified lines | ||
| 721 | 758 | u32 ctrl; |
| 722 | 759 | |
| 723 | 760 | if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0) |
| 724 | − return 0; | |
| 761 | + return; | |
| 725 | 762 | |
| 726 | − if (port->commit_end != id) { | |
| 763 | + if (port->commit_end == id) | |
| 764 | + cxl_port_commit_reap(cxld); | |
| 765 | + else | |
| 727 | 766 | dev_dbg(&port->dev, |
| 728 | 767 | "%s: out of order reset, expected decoder%d.%d\n", |
| 729 | 768 | dev_name(&cxld->dev), port->id, port->commit_end); |
| 730 | − return -EBUSY; | |
| 731 | − } | |
| 732 | 769 | |
| 733 | 770 | down_read(&cxl_dpa_rwsem); |
| 734 | 771 | ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id)); |
| @@ -741,7 +778,6 @@ static int cxl_decoder_reset(struct cxl_decoder *cxld) · 6 unmodified lines | ||
| 741 | 778 | writel(0, hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(id)); |
| 742 | 779 | up_read(&cxl_dpa_rwsem); |
| 743 | 780 | |
| 744 | − port->commit_end--; | |
| 745 | 781 | cxld->flags &= ~CXL_DECODER_F_ENABLE; |
| 746 | 782 | |
| 747 | 783 | /* Userspace is now responsible for reconfiguring this decoder */ |
| @@ -751,8 +787,6 @@ static int cxl_decoder_reset(struct cxl_decoder *cxld) · 3 unmodified lines | ||
| 751 | 787 | cxled = to_cxl_endpoint_decoder(&cxld->dev); |
| 752 | 788 | cxled->state = CXL_DECODER_STATE_MANUAL; |
| 753 | 789 | } |
| 754 | − | |
| 755 | − return 0; | |
| 756 | 790 | } |
| 757 | 791 | |
| 758 | 792 | static int cxl_setup_hdm_decoder_from_dvsec( |
| @@ -2084,11 +2084,18 @@ static void cxl_bus_remove(struct device *dev) · 2083 unmodified lines | ||
| 2084 | 2084 | |
| 2085 | 2085 | static struct workqueue_struct *cxl_bus_wq; |
| 2086 | 2086 | |
| 2087 | −static void cxl_bus_rescan_queue(struct work_struct *w) | |
| 2087 | +static int cxl_rescan_attach(struct device *dev, void *data) | |
| 2088 | 2088 | { |
| 2089 | − int rc = bus_rescan_devices(&cxl_bus_type); | |
| 2089 | + int rc = device_attach(dev); | |
| 2090 | + | |
| 2091 | + dev_vdbg(dev, "rescan: %s\n", rc ? "attach" : "detached"); | |
| 2090 | 2092 | |
| 2091 | − pr_debug("CXL bus rescan result: %d\n", rc); | |
| 2093 | + return 0; | |
| 2094 | +} | |
| 2095 | + | |
| 2096 | +static void cxl_bus_rescan_queue(struct work_struct *w) | |
| 2097 | +{ | |
| 2098 | + bus_for_each_dev(&cxl_bus_type, NULL, NULL, cxl_rescan_attach); | |
| 2092 | 2099 | } |
| 2093 | 2100 | |
| 2094 | 2101 | void cxl_bus_rescan(void) |
| @@ -232,8 +232,8 @@ static int cxl_region_invalidate_memregion(struct cxl_region *cxlr) · 231 unmodified lines | ||
| 232 | 232 | "Bypassing cpu_cache_invalidate_memregion() for testing!\n"); |
| 233 | 233 | return 0; |
| 234 | 234 | } else { |
| 235 | − dev_err(&cxlr->dev, | |
| 236 | − "Failed to synchronize CPU cache state\n"); | |
| 235 | + dev_WARN(&cxlr->dev, | |
| 236 | + "Failed to synchronize CPU cache state\n"); | |
| 237 | 237 | return -ENXIO; |
| 238 | 238 | } |
| 239 | 239 | } |
| @@ -242,19 +242,17 @@ static int cxl_region_invalidate_memregion(struct cxl_region *cxlr) · 2 unmodified lines | ||
| 242 | 242 | return 0; |
| 243 | 243 | } |
| 244 | 244 | |
| 245 | −static int cxl_region_decode_reset(struct cxl_region *cxlr, int count) | |
| 245 | +static void cxl_region_decode_reset(struct cxl_region *cxlr, int count) | |
| 246 | 246 | { |
| 247 | 247 | struct cxl_region_params *p = &cxlr->params; |
| 248 | − int i, rc = 0; | |
| 248 | + int i; | |
| 249 | 249 | |
| 250 | 250 | /* |
| 251 | − * Before region teardown attempt to flush, and if the flush | |
| 252 | − * fails cancel the region teardown for data consistency | |
| 253 | − * concerns | |
| 251 | + * Before region teardown attempt to flush, evict any data cached for | |
| 252 | + * this region, or scream loudly about missing arch / platform support | |
| 253 | + * for CXL teardown. | |
| 254 | 254 | */ |
| 255 | − rc = cxl_region_invalidate_memregion(cxlr); | |
| 256 | − if (rc) | |
| 257 | − return rc; | |
| 255 | + cxl_region_invalidate_memregion(cxlr); | |
| 258 | 256 | |
| 259 | 257 | for (i = count - 1; i >= 0; i--) { |
| 260 | 258 | struct cxl_endpoint_decoder *cxled = p->targets[i]; |
| @@ -277,23 +275,17 @@ static int cxl_region_decode_reset(struct cxl_region *cxlr, int count) · 16 unmodified lines | ||
| 277 | 275 | cxl_rr = cxl_rr_load(iter, cxlr); |
| 278 | 276 | cxld = cxl_rr->decoder; |
| 279 | 277 | if (cxld->reset) |
| 280 | − rc = cxld->reset(cxld); | |
| 281 | − if (rc) | |
| 282 | − return rc; | |
| 278 | + cxld->reset(cxld); | |
| 283 | 279 | set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags); |
| 284 | 280 | } |
| 285 | 281 | |
| 286 | 282 | endpoint_reset: |
| 287 | − rc = cxled->cxld.reset(&cxled->cxld); | |
| 288 | − if (rc) | |
| 289 | − return rc; | |
| 283 | + cxled->cxld.reset(&cxled->cxld); | |
| 290 | 284 | set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags); |
| 291 | 285 | } |
| 292 | 286 | |
| 293 | 287 | /* all decoders associated with this region have been torn down */ |
| 294 | 288 | clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags); |
| 295 | − | |
| 296 | − return 0; | |
| 297 | 289 | } |
| 298 | 290 | |
| 299 | 291 | static int commit_decoder(struct cxl_decoder *cxld) |
| @@ -409,16 +401,8 @@ static ssize_t commit_store(struct device *dev, struct device_attribute *attr, · 109 unmodified lines | ||
| 409 | 401 | * still pending. |
| 410 | 402 | */ |
| 411 | 403 | if (p->state == CXL_CONFIG_RESET_PENDING) { |
| 412 | − rc = cxl_region_decode_reset(cxlr, p->interleave_ways); | |
| 413 | − /* | |
| 414 | − * Revert to committed since there may still be active | |
| 415 | − * decoders associated with this region, or move forward | |
| 416 | − * to active to mark the reset successful | |
| 417 | − */ | |
| 418 | − if (rc) | |
| 419 | − p->state = CXL_CONFIG_COMMIT; | |
| 420 | − else | |
| 421 | − p->state = CXL_CONFIG_ACTIVE; | |
| 404 | + cxl_region_decode_reset(cxlr, p->interleave_ways); | |
| 405 | + p->state = CXL_CONFIG_ACTIVE; | |
| 422 | 406 | } |
| 423 | 407 | } |
| 424 | 408 | |
| @@ -794,26 +778,50 @@ out: · 369 unmodified lines | ||
| 794 | 778 | return rc; |
| 795 | 779 | } |
| 796 | 780 | |
| 781 | +static int check_commit_order(struct device *dev, const void *data) | |
| 782 | +{ | |
| 783 | + struct cxl_decoder *cxld = to_cxl_decoder(dev); | |
| 784 | + | |
| 785 | + /* | |
| 786 | + * if port->commit_end is not the only free decoder, then out of | |
| 787 | + * order shutdown has occurred, block further allocations until | |
| 788 | + * that is resolved | |
| 789 | + */ | |
| 790 | + if (((cxld->flags & CXL_DECODER_F_ENABLE) == 0)) | |
| 791 | + return -EBUSY; | |
| 792 | + return 0; | |
| 793 | +} | |
| 794 | + | |
| 797 | 795 | static int match_free_decoder(struct device *dev, void *data) |
| 798 | 796 | { |
| 797 | + struct cxl_port *port = to_cxl_port(dev->parent); | |
| 799 | 798 | struct cxl_decoder *cxld; |
| 800 | − int *id = data; | |
| 799 | + int rc; | |
| 801 | 800 | |
| 802 | 801 | if (!is_switch_decoder(dev)) |
| 803 | 802 | return 0; |
| 804 | 803 | |
| 805 | 804 | cxld = to_cxl_decoder(dev); |
| 806 | 805 | |
| 807 | − /* enforce ordered allocation */ | |
| 808 | − if (cxld->id != *id) | |
| 806 | + if (cxld->id != port->commit_end + 1) | |
| 809 | 807 | return 0; |
| 810 | 808 | |
| 811 | − if (!cxld->region) | |
| 812 | − return 1; | |
| 813 | − | |
| 814 | − (*id)++; | |
| 809 | + if (cxld->region) { | |
| 810 | + dev_dbg(dev->parent, | |
| 811 | + "next decoder to commit (%s) is already reserved (%s)\n", | |
| 812 | + dev_name(dev), dev_name(&cxld->region->dev)); | |
| 813 | + return 0; | |
| 814 | + } | |
| 815 | 815 | |
| 816 | − return 0; | |
| 816 | + rc = device_for_each_child_reverse_from(dev->parent, dev, NULL, | |
| 817 | + check_commit_order); | |
| 818 | + if (rc) { | |
| 819 | + dev_dbg(dev->parent, | |
| 820 | + "unable to allocate %s due to out of order shutdown\n", | |
| 821 | + dev_name(dev)); | |
| 822 | + return 0; | |
| 823 | + } | |
| 824 | + return 1; | |
| 817 | 825 | } |
| 818 | 826 | |
| 819 | 827 | static int match_auto_decoder(struct device *dev, void *data) |
| @@ -840,7 +848,6 @@ cxl_region_find_decoder(struct cxl_port *port, · 20 unmodified lines | ||
| 840 | 848 | struct cxl_region *cxlr) |
| 841 | 849 | { |
| 842 | 850 | struct device *dev; |
| 843 | − int id = 0; | |
| 844 | 851 | |
| 845 | 852 | if (port == cxled_to_port(cxled)) |
| 846 | 853 | return &cxled->cxld; |
| @@ -849,7 +856,7 @@ cxl_region_find_decoder(struct cxl_port *port, · 2 unmodified lines | ||
| 849 | 856 | dev = device_find_child(&port->dev, &cxlr->params, |
| 850 | 857 | match_auto_decoder); |
| 851 | 858 | else |
| 852 | − dev = device_find_child(&port->dev, &id, match_free_decoder); | |
| 859 | + dev = device_find_child(&port->dev, NULL, match_free_decoder); | |
| 853 | 860 | if (!dev) |
| 854 | 861 | return NULL; |
| 855 | 862 | /* |
| @@ -2054,13 +2061,7 @@ static int cxl_region_detach(struct cxl_endpoint_decoder *cxled) · 1198 unmodified lines | ||
| 2054 | 2061 | get_device(&cxlr->dev); |
| 2055 | 2062 | |
| 2056 | 2063 | if (p->state > CXL_CONFIG_ACTIVE) { |
| 2057 | − /* | |
| 2058 | − * TODO: tear down all impacted regions if a device is | |
| 2059 | − * removed out of order | |
| 2060 | − */ | |
| 2061 | − rc = cxl_region_decode_reset(cxlr, p->interleave_ways); | |
| 2062 | − if (rc) | |
| 2063 | − goto out; | |
| 2064 | + cxl_region_decode_reset(cxlr, p->interleave_ways); | |
| 2064 | 2065 | p->state = CXL_CONFIG_ACTIVE; |
| 2065 | 2066 | } |
| 2066 | 2067 | |
| @@ -279,7 +279,7 @@ TRACE_EVENT(cxl_generic_event, · 278 unmodified lines | ||
| 279 | 279 | #define CXL_GMER_MEM_EVT_TYPE_ECC_ERROR 0x00 |
| 280 | 280 | #define CXL_GMER_MEM_EVT_TYPE_INV_ADDR 0x01 |
| 281 | 281 | #define CXL_GMER_MEM_EVT_TYPE_DATA_PATH_ERROR 0x02 |
| 282 | −#define show_mem_event_type(type) __print_symbolic(type, \ | |
| 282 | +#define show_gmer_mem_event_type(type) __print_symbolic(type, \ | |
| 283 | 283 | { CXL_GMER_MEM_EVT_TYPE_ECC_ERROR, "ECC Error" }, \ |
| 284 | 284 | { CXL_GMER_MEM_EVT_TYPE_INV_ADDR, "Invalid Address" }, \ |
| 285 | 285 | { CXL_GMER_MEM_EVT_TYPE_DATA_PATH_ERROR, "Data Path Error" } \ |
| @@ -373,7 +373,7 @@ TRACE_EVENT(cxl_general_media, · 87 unmodified lines | ||
| 373 | 373 | "hpa=%llx region=%s region_uuid=%pUb", |
| 374 | 374 | __entry->dpa, show_dpa_flags(__entry->dpa_flags), |
| 375 | 375 | show_event_desc_flags(__entry->descriptor), |
| 376 | − show_mem_event_type(__entry->type), | |
| 376 | + show_gmer_mem_event_type(__entry->type), | |
| 377 | 377 | show_trans_type(__entry->transaction_type), |
| 378 | 378 | __entry->channel, __entry->rank, __entry->device, |
| 379 | 379 | __print_hex(__entry->comp_id, CXL_EVENT_GEN_MED_COMP_ID_SIZE), |
| @@ -391,6 +391,17 @@ TRACE_EVENT(cxl_general_media, · 11 unmodified lines | ||
| 391 | 391 | * DRAM Event Record defines many fields the same as the General Media Event |
| 392 | 392 | * Record. Reuse those definitions as appropriate. |
| 393 | 393 | */ |
| 394 | +#define CXL_DER_MEM_EVT_TYPE_ECC_ERROR 0x00 | |
| 395 | +#define CXL_DER_MEM_EVT_TYPE_SCRUB_MEDIA_ECC_ERROR 0x01 | |
| 396 | +#define CXL_DER_MEM_EVT_TYPE_INV_ADDR 0x02 | |
| 397 | +#define CXL_DER_MEM_EVT_TYPE_DATA_PATH_ERROR 0x03 | |
| 398 | +#define show_dram_mem_event_type(type) __print_symbolic(type, \ | |
| 399 | + { CXL_DER_MEM_EVT_TYPE_ECC_ERROR, "ECC Error" }, \ | |
| 400 | + { CXL_DER_MEM_EVT_TYPE_SCRUB_MEDIA_ECC_ERROR, "Scrub Media ECC Error" }, \ | |
| 401 | + { CXL_DER_MEM_EVT_TYPE_INV_ADDR, "Invalid Address" }, \ | |
| 402 | + { CXL_DER_MEM_EVT_TYPE_DATA_PATH_ERROR, "Data Path Error" } \ | |
| 403 | +) | |
| 404 | + | |
| 394 | 405 | #define CXL_DER_VALID_CHANNEL BIT(0) |
| 395 | 406 | #define CXL_DER_VALID_RANK BIT(1) |
| 396 | 407 | #define CXL_DER_VALID_NIBBLE BIT(2) |
| @@ -477,7 +488,7 @@ TRACE_EVENT(cxl_dram, · 80 unmodified lines | ||
| 477 | 488 | "hpa=%llx region=%s region_uuid=%pUb", |
| 478 | 489 | __entry->dpa, show_dpa_flags(__entry->dpa_flags), |
| 479 | 490 | show_event_desc_flags(__entry->descriptor), |
| 480 | − show_mem_event_type(__entry->type), | |
| 491 | + show_dram_mem_event_type(__entry->type), | |
| 481 | 492 | show_trans_type(__entry->transaction_type), |
| 482 | 493 | __entry->channel, __entry->rank, __entry->nibble_mask, |
| 483 | 494 | __entry->bank_group, __entry->bank, |
| @@ -359,7 +359,7 @@ struct cxl_decoder { · 358 unmodified lines | ||
| 359 | 359 | struct cxl_region *region; |
| 360 | 360 | unsigned long flags; |
| 361 | 361 | int (*commit)(struct cxl_decoder *cxld); |
| 362 | − int (*reset)(struct cxl_decoder *cxld); | |
| 362 | + void (*reset)(struct cxl_decoder *cxld); | |
| 363 | 363 | }; |
| 364 | 364 | |
| 365 | 365 | /* |
| @@ -730,6 +730,7 @@ static inline bool is_cxl_root(struct cxl_port *port) · 364 unmodified lines | ||
| 730 | 730 | int cxl_num_decoders_committed(struct cxl_port *port); |
| 731 | 731 | bool is_cxl_port(const struct device *dev); |
| 732 | 732 | struct cxl_port *to_cxl_port(const struct device *dev); |
| 733 | +void cxl_port_commit_reap(struct cxl_decoder *cxld); | |
| 733 | 734 | struct pci_bus; |
| 734 | 735 | int devm_cxl_register_pci_bus(struct device *host, struct device *uport_dev, |
| 735 | 736 | struct pci_bus *bus); |
| @@ -208,7 +208,22 @@ static struct cxl_driver cxl_port_driver = { · 207 unmodified lines | ||
| 208 | 208 | }, |
| 209 | 209 | }; |
| 210 | 210 | |
| 211 | −module_cxl_driver(cxl_port_driver); | |
| 211 | +static int __init cxl_port_init(void) | |
| 212 | +{ | |
| 213 | + return cxl_driver_register(&cxl_port_driver); | |
| 214 | +} | |
| 215 | +/* | |
| 216 | + * Be ready to immediately enable ports emitted by the platform CXL root | |
| 217 | + * (e.g. cxl_acpi) when CONFIG_CXL_PORT=y. | |
| 218 | + */ | |
| 219 | +subsys_initcall(cxl_port_init); | |
| 220 | + | |
| 221 | +static void __exit cxl_port_exit(void) | |
| 222 | +{ | |
| 223 | + cxl_driver_unregister(&cxl_port_driver); | |
| 224 | +} | |
| 225 | +module_exit(cxl_port_exit); | |
| 226 | + | |
| 212 | 227 | MODULE_DESCRIPTION("CXL: Port enumeration and services"); |
| 213 | 228 | MODULE_LICENSE("GPL v2"); |
| 214 | 229 | MODULE_IMPORT_NS(CXL); |
| @@ -86,7 +86,7 @@ static void dax_set_mapping(struct vm_fault *vmf, pfn_t pfn, · 85 unmodified lines | ||
| 86 | 86 | nr_pages = 1; |
| 87 | 87 | |
| 88 | 88 | pgoff = linear_page_index(vmf->vma, |
| 89 | − ALIGN(vmf->address, fault_size)); | |
| 89 | + ALIGN_DOWN(vmf->address, fault_size)); | |
| 90 | 90 | |
| 91 | 91 | for (i = 0; i < nr_pages; i++) { |
| 92 | 92 | struct page *page = pfn_to_page(pfn_t_to_pfn(pfn) + i); |
| @@ -1391,11 +1391,12 @@ static struct ep93xx_dma_engine *ep93xx_dma_of_probe(struct platform_device *pde · 1390 unmodified lines | ||
| 1391 | 1391 | INIT_LIST_HEAD(&dma_dev->channels); |
| 1392 | 1392 | for (i = 0; i < edma->num_channels; i++) { |
| 1393 | 1393 | struct ep93xx_dma_chan *edmac = &edma->channels[i]; |
| 1394 | + int len; | |
| 1394 | 1395 | |
| 1395 | 1396 | edmac->chan.device = dma_dev; |
| 1396 | 1397 | edmac->regs = devm_platform_ioremap_resource(pdev, i); |
| 1397 | 1398 | if (IS_ERR(edmac->regs)) |
| 1398 | − return edmac->regs; | |
| 1399 | + return ERR_CAST(edmac->regs); | |
| 1399 | 1400 | |
| 1400 | 1401 | edmac->irq = fwnode_irq_get(dev_fwnode(dev), i); |
| 1401 | 1402 | if (edmac->irq < 0) |
| @@ -1404,9 +1405,11 @@ static struct ep93xx_dma_engine *ep93xx_dma_of_probe(struct platform_device *pde · 2 unmodified lines | ||
| 1404 | 1405 | edmac->edma = edma; |
| 1405 | 1406 | |
| 1406 | 1407 | if (edma->m2m) |
| 1407 | − snprintf(dma_clk_name, sizeof(dma_clk_name), "m2m%u", i); | |
| 1408 | + len = snprintf(dma_clk_name, sizeof(dma_clk_name), "m2m%u", i); | |
| 1408 | 1409 | else |
| 1409 | − snprintf(dma_clk_name, sizeof(dma_clk_name), "m2p%u", i); | |
| 1410 | + len = snprintf(dma_clk_name, sizeof(dma_clk_name), "m2p%u", i); | |
| 1411 | + if (len >= sizeof(dma_clk_name)) | |
| 1412 | + return ERR_PTR(-ENOBUFS); | |
| 1410 | 1413 | |
| 1411 | 1414 | edmac->clk = devm_clk_get(dev, dma_clk_name); |
| 1412 | 1415 | if (IS_ERR(edmac->clk)) { |
| @@ -601,22 +601,25 @@ static int rz_dmac_config(struct dma_chan *chan, · 600 unmodified lines | ||
| 601 | 601 | struct rz_dmac_chan *channel = to_rz_dmac_chan(chan); |
| 602 | 602 | u32 val; |
| 603 | 603 | |
| 604 | − channel->src_per_address = config->src_addr; | |
| 605 | 604 | channel->dst_per_address = config->dst_addr; |
| 606 | − | |
| 607 | − val = rz_dmac_ds_to_val_mapping(config->dst_addr_width); | |
| 608 | − if (val == CHCFG_DS_INVALID) | |
| 609 | − return -EINVAL; | |
| 610 | − | |
| 611 | 605 | channel->chcfg &= ~CHCFG_FILL_DDS_MASK; |
| 612 | − channel->chcfg |= FIELD_PREP(CHCFG_FILL_DDS_MASK, val); | |
| 606 | + if (channel->dst_per_address) { | |
| 607 | + val = rz_dmac_ds_to_val_mapping(config->dst_addr_width); | |
| 608 | + if (val == CHCFG_DS_INVALID) | |
| 609 | + return -EINVAL; | |
| 613 | 610 | |
| 614 | − val = rz_dmac_ds_to_val_mapping(config->src_addr_width); | |
| 615 | − if (val == CHCFG_DS_INVALID) | |
| 616 | − return -EINVAL; | |
| 611 | + channel->chcfg |= FIELD_PREP(CHCFG_FILL_DDS_MASK, val); | |
| 612 | + } | |
| 617 | 613 | |
| 614 | + channel->src_per_address = config->src_addr; | |
| 618 | 615 | channel->chcfg &= ~CHCFG_FILL_SDS_MASK; |
| 619 | − channel->chcfg |= FIELD_PREP(CHCFG_FILL_SDS_MASK, val); | |
| 616 | + if (channel->src_per_address) { | |
| 617 | + val = rz_dmac_ds_to_val_mapping(config->src_addr_width); | |
| 618 | + if (val == CHCFG_DS_INVALID) | |
| 619 | + return -EINVAL; | |
| 620 | + | |
| 621 | + channel->chcfg |= FIELD_PREP(CHCFG_FILL_SDS_MASK, val); | |
| 622 | + } | |
| 620 | 623 | |
| 621 | 624 | return 0; |
| 622 | 625 | } |
| @@ -3185,27 +3185,40 @@ static int udma_configure_statictr(struct udma_chan *uc, struct udma_desc *d, · 3184 unmodified lines | ||
| 3185 | 3185 | |
| 3186 | 3186 | d->static_tr.elcnt = elcnt; |
| 3187 | 3187 | |
| 3188 | − /* | |
| 3189 | − * PDMA must to close the packet when the channel is in packet mode. | |
| 3190 | − * For TR mode when the channel is not cyclic we also need PDMA to close | |
| 3191 | − * the packet otherwise the transfer will stall because PDMA holds on | |
| 3192 | − * the data it has received from the peripheral. | |
| 3193 | − */ | |
| 3194 | 3188 | if (uc->config.pkt_mode || !uc->cyclic) { |
| 3189 | + /* | |
| 3190 | + * PDMA must close the packet when the channel is in packet mode. | |
| 3191 | + * For TR mode when the channel is not cyclic we also need PDMA | |
| 3192 | + * to close the packet otherwise the transfer will stall because | |
| 3193 | + * PDMA holds on the data it has received from the peripheral. | |
| 3194 | + */ | |
| 3195 | 3195 | unsigned int div = dev_width * elcnt; |
| 3196 | 3196 | |
| 3197 | 3197 | if (uc->cyclic) |
| 3198 | 3198 | d->static_tr.bstcnt = d->residue / d->sglen / div; |
| 3199 | 3199 | else |
| 3200 | 3200 | d->static_tr.bstcnt = d->residue / div; |
| 3201 | + } else if (uc->ud->match_data->type == DMA_TYPE_BCDMA && | |
| 3202 | + uc->config.dir == DMA_DEV_TO_MEM && | |
| 3203 | + uc->cyclic) { | |
| 3204 | + /* | |
| 3205 | + * For cyclic mode with BCDMA we have to set EOP in each TR to | |
| 3206 | + * prevent short packet errors seen on channel teardown. So the | |
| 3207 | + * PDMA must close the packet after every TR transfer by setting | |
| 3208 | + * burst count equal to the number of bytes transferred. | |
| 3209 | + */ | |
| 3210 | + struct cppi5_tr_type1_t *tr_req = d->hwdesc[0].tr_req_base; | |
| 3201 | 3211 | |
| 3202 | − if (uc->config.dir == DMA_DEV_TO_MEM && | |
| 3203 | − d->static_tr.bstcnt > uc->ud->match_data->statictr_z_mask) | |
| 3204 | − return -EINVAL; | |
| 3212 | + d->static_tr.bstcnt = | |
| 3213 | + (tr_req->icnt0 * tr_req->icnt1) / dev_width; | |
| 3205 | 3214 | } else { |
| 3206 | 3215 | d->static_tr.bstcnt = 0; |
| 3207 | 3216 | } |
| 3208 | 3217 | |
| 3218 | + if (uc->config.dir == DMA_DEV_TO_MEM && | |
| 3219 | + d->static_tr.bstcnt > uc->ud->match_data->statictr_z_mask) | |
| 3220 | + return -EINVAL; | |
| 3221 | + | |
| 3209 | 3222 | return 0; |
| 3210 | 3223 | } |
| 3211 | 3224 | |
| @@ -3450,8 +3463,9 @@ udma_prep_slave_sg(struct dma_chan *chan, struct scatterlist *sgl, · 238 unmodified lines | ||
| 3450 | 3463 | /* static TR for remote PDMA */ |
| 3451 | 3464 | if (udma_configure_statictr(uc, d, dev_width, burst)) { |
| 3452 | 3465 | dev_err(uc->ud->dev, |
| 3453 | − "%s: StaticTR Z is limited to maximum 4095 (%u)\n", | |
| 3454 | − __func__, d->static_tr.bstcnt); | |
| 3466 | + "%s: StaticTR Z is limited to maximum %u (%u)\n", | |
| 3467 | + __func__, uc->ud->match_data->statictr_z_mask, | |
| 3468 | + d->static_tr.bstcnt); | |
| 3455 | 3469 | |
| 3456 | 3470 | udma_free_hwdesc(uc, d); |
| 3457 | 3471 | kfree(d); |
| @@ -3476,6 +3490,7 @@ udma_prep_dma_cyclic_tr(struct udma_chan *uc, dma_addr_t buf_addr, · 18 unmodified lines | ||
| 3476 | 3490 | u16 tr0_cnt0, tr0_cnt1, tr1_cnt0; |
| 3477 | 3491 | unsigned int i; |
| 3478 | 3492 | int num_tr; |
| 3493 | + u32 period_csf = 0; | |
| 3479 | 3494 | |
| 3480 | 3495 | num_tr = udma_get_tr_counters(period_len, __ffs(buf_addr), &tr0_cnt0, |
| 3481 | 3496 | &tr0_cnt1, &tr1_cnt0); |
| @@ -3498,6 +3513,20 @@ udma_prep_dma_cyclic_tr(struct udma_chan *uc, dma_addr_t buf_addr, · 16 unmodified lines | ||
| 3498 | 3513 | period_addr = buf_addr | |
| 3499 | 3514 | ((u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT); |
| 3500 | 3515 | |
| 3516 | + /* | |
| 3517 | + * For BCDMA <-> PDMA transfers, the EOP flag needs to be set on the | |
| 3518 | + * last TR of a descriptor, to mark the packet as complete. | |
| 3519 | + * This is required for getting the teardown completion message in case | |
| 3520 | + * of TX, and to avoid short-packet error in case of RX. | |
| 3521 | + * | |
| 3522 | + * As we are in cyclic mode, we do not know which period might be the | |
| 3523 | + * last one, so set the flag for each period. | |
| 3524 | + */ | |
| 3525 | + if (uc->config.ep_type == PSIL_EP_PDMA_XY && | |
| 3526 | + uc->ud->match_data->type == DMA_TYPE_BCDMA) { | |
| 3527 | + period_csf = CPPI5_TR_CSF_EOP; | |
| 3528 | + } | |
| 3529 | + | |
| 3501 | 3530 | for (i = 0; i < periods; i++) { |
| 3502 | 3531 | int tr_idx = i * num_tr; |
| 3503 | 3532 | |
| @@ -3525,8 +3554,10 @@ udma_prep_dma_cyclic_tr(struct udma_chan *uc, dma_addr_t buf_addr, · 21 unmodified lines | ||
| 3525 | 3554 | } |
| 3526 | 3555 | |
| 3527 | 3556 | if (!(flags & DMA_PREP_INTERRUPT)) |
| 3528 | − cppi5_tr_csf_set(&tr_req[tr_idx].flags, | |
| 3529 | − CPPI5_TR_CSF_SUPR_EVT); | |
| 3557 | + period_csf |= CPPI5_TR_CSF_SUPR_EVT; | |
| 3558 | + | |
| 3559 | + if (period_csf) | |
| 3560 | + cppi5_tr_csf_set(&tr_req[tr_idx].flags, period_csf); | |
| 3530 | 3561 | |
| 3531 | 3562 | period_addr += period_len; |
| 3532 | 3563 | } |
| @@ -3655,8 +3686,9 @@ udma_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t buf_addr, size_t buf_len, · 122 unmodified lines | ||
| 3655 | 3686 | /* static TR for remote PDMA */ |
| 3656 | 3687 | if (udma_configure_statictr(uc, d, dev_width, burst)) { |
| 3657 | 3688 | dev_err(uc->ud->dev, |
| 3658 | − "%s: StaticTR Z is limited to maximum 4095 (%u)\n", | |
| 3659 | − __func__, d->static_tr.bstcnt); | |
| 3689 | + "%s: StaticTR Z is limited to maximum %u (%u)\n", | |
| 3690 | + __func__, uc->ud->match_data->statictr_z_mask, | |
| 3691 | + d->static_tr.bstcnt); | |
| 3660 | 3692 | |
| 3661 | 3693 | udma_free_hwdesc(uc, d); |
| 3662 | 3694 | kfree(d); |
| @@ -204,7 +204,7 @@ static struct fw_node *build_tree(struct fw_card *card, const u32 *sid, int self · 203 unmodified lines | ||
| 204 | 204 | // the node->ports array where the parent node should be. Later, |
| 205 | 205 | // when we handle the parent node, we fix up the reference. |
| 206 | 206 | ++parent_count; |
| 207 | − node->color = i; | |
| 207 | + node->color = port_index; | |
| 208 | 208 | break; |
| 209 | 209 | |
| 210 | 210 | case PHY_PACKET_SELF_ID_PORT_STATUS_CHILD: |
| @@ -481,11 +481,16 @@ static int ffa_msg_send_direct_req2(u16 src_id, u16 dst_id, const uuid_t *uuid, · 480 unmodified lines | ||
| 481 | 481 | struct ffa_send_direct_data2 *data) |
| 482 | 482 | { |
| 483 | 483 | u32 src_dst_ids = PACK_TARGET_INFO(src_id, dst_id); |
| 484 | + union { | |
| 485 | + uuid_t uuid; | |
| 486 | + __le64 regs[2]; | |
| 487 | + } uuid_regs = { .uuid = *uuid }; | |
| 484 | 488 | ffa_value_t ret, args = { |
| 485 | − .a0 = FFA_MSG_SEND_DIRECT_REQ2, .a1 = src_dst_ids, | |
| 489 | + .a0 = FFA_MSG_SEND_DIRECT_REQ2, | |
| 490 | + .a1 = src_dst_ids, | |
| 491 | + .a2 = le64_to_cpu(uuid_regs.regs[0]), | |
| 492 | + .a3 = le64_to_cpu(uuid_regs.regs[1]), | |
| 486 | 493 | }; |
| 487 | − | |
| 488 | − export_uuid((u8 *)&args.a2, uuid); | |
| 489 | 494 | memcpy((void *)&args + offsetof(ffa_value_t, a4), data, sizeof(*data)); |
| 490 | 495 | |
| 491 | 496 | invoke_ffa_fn(args, &ret); |
| @@ -496,7 +501,7 @@ static int ffa_msg_send_direct_req2(u16 src_id, u16 dst_id, const uuid_t *uuid, · 4 unmodified lines | ||
| 496 | 501 | return ffa_to_linux_errno((int)ret.a2); |
| 497 | 502 | |
| 498 | 503 | if (ret.a0 == FFA_MSG_SEND_DIRECT_RESP2) { |
| 499 | − memcpy(data, &ret.a4, sizeof(*data)); | |
| 504 | + memcpy(data, (void *)&ret + offsetof(ffa_value_t, a4), sizeof(*data)); | |
| 500 | 505 | return 0; |
| 501 | 506 | } |
| 502 | 507 | |
| @@ -2976,10 +2976,8 @@ static struct scmi_debug_info *scmi_debugfs_common_setup(struct scmi_info *info) · 2975 unmodified lines | ||
| 2976 | 2976 | dbg->top_dentry = top_dentry; |
| 2977 | 2977 | |
| 2978 | 2978 | if (devm_add_action_or_reset(info->dev, |
| 2979 | − scmi_debugfs_common_cleanup, dbg)) { | |
| 2980 | − scmi_debugfs_common_cleanup(dbg); | |
| 2979 | + scmi_debugfs_common_cleanup, dbg)) | |
| 2981 | 2980 | return NULL; |
| 2982 | − } | |
| 2983 | 2981 | |
| 2984 | 2982 | return dbg; |
| 2985 | 2983 | } |
| @@ -1,8 +1,10 @@ | ||
| 1 | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | −scmi_transport_mailbox-objs := mailbox.o | |
| 3 | −obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += scmi_transport_mailbox.o | |
| 2 | +# Keep before scmi_transport_mailbox.o to allow precedence | |
| 3 | +# while matching the compatible. | |
| 4 | 4 | scmi_transport_smc-objs := smc.o |
| 5 | 5 | obj-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += scmi_transport_smc.o |
| 6 | +scmi_transport_mailbox-objs := mailbox.o | |
| 7 | +obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += scmi_transport_mailbox.o | |
| 6 | 8 | scmi_transport_optee-objs := optee.o |
| 7 | 9 | obj-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += scmi_transport_optee.o |
| 8 | 10 | scmi_transport_virtio-objs := virtio.o |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | ||
| 25 | 25 | * @chan_platform_receiver: Optional Platform Receiver mailbox unidirectional channel |
| 26 | 26 | * @cinfo: SCMI channel info |
| 27 | 27 | * @shmem: Transmit/Receive shared memory area |
| 28 | + * @chan_lock: Lock that prevents multiple xfers from being queued | |
| 28 | 29 | */ |
| 29 | 30 | struct scmi_mailbox { |
| 30 | 31 | struct mbox_client cl; |
| @@ -33,6 +34,7 @@ struct scmi_mailbox { · 2 unmodified lines | ||
| 33 | 34 | struct mbox_chan *chan_platform_receiver; |
| 34 | 35 | struct scmi_chan_info *cinfo; |
| 35 | 36 | struct scmi_shared_mem __iomem *shmem; |
| 37 | + struct mutex chan_lock; | |
| 36 | 38 | }; |
| 37 | 39 | |
| 38 | 40 | #define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl) |
| @@ -238,6 +240,7 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, · 199 unmodified lines | ||
| 238 | 240 | |
| 239 | 241 | cinfo->transport_info = smbox; |
| 240 | 242 | smbox->cinfo = cinfo; |
| 243 | + mutex_init(&smbox->chan_lock); | |
| 241 | 244 | |
| 242 | 245 | return 0; |
| 243 | 246 | } |
| @@ -267,13 +270,23 @@ static int mailbox_send_message(struct scmi_chan_info *cinfo, · 23 unmodified lines | ||
| 267 | 270 | struct scmi_mailbox *smbox = cinfo->transport_info; |
| 268 | 271 | int ret; |
| 269 | 272 | |
| 270 | − ret = mbox_send_message(smbox->chan, xfer); | |
| 273 | + /* | |
| 274 | + * The mailbox layer has its own queue. However the mailbox queue | |
| 275 | + * confuses the per message SCMI timeouts since the clock starts when | |
| 276 | + * the message is submitted into the mailbox queue. So when multiple | |
| 277 | + * messages are queued up the clock starts on all messages instead of | |
| 278 | + * only the one inflight. | |
| 279 | + */ | |
| 280 | + mutex_lock(&smbox->chan_lock); | |
| 271 | 281 | |
| 272 | − /* mbox_send_message returns non-negative value on success, so reset */ | |
| 273 | − if (ret > 0) | |
| 274 | − ret = 0; | |
| 282 | + ret = mbox_send_message(smbox->chan, xfer); | |
| 283 | + /* mbox_send_message returns non-negative value on success */ | |
| 284 | + if (ret < 0) { | |
| 285 | + mutex_unlock(&smbox->chan_lock); | |
| 286 | + return ret; | |
| 287 | + } | |
| 275 | 288 | |
| 276 | − return ret; | |
| 289 | + return 0; | |
| 277 | 290 | } |
| 278 | 291 | |
| 279 | 292 | static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret, |
| @@ -281,13 +294,10 @@ static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret, · 1 unmodified line | ||
| 281 | 294 | { |
| 282 | 295 | struct scmi_mailbox *smbox = cinfo->transport_info; |
| 283 | 296 | |
| 284 | − /* | |
| 285 | − * NOTE: we might prefer not to need the mailbox ticker to manage the | |
| 286 | − * transfer queueing since the protocol layer queues things by itself. | |
| 287 | − * Unfortunately, we have to kick the mailbox framework after we have | |
| 288 | − * received our message. | |
| 289 | − */ | |
| 290 | 297 | mbox_client_txdone(smbox->chan, ret); |
| 298 | + | |
| 299 | + /* Release channel */ | |
| 300 | + mutex_unlock(&smbox->chan_lock); | |
| 291 | 301 | } |
| 292 | 302 | |
| 293 | 303 | static void mailbox_fetch_response(struct scmi_chan_info *cinfo, |
| @@ -763,7 +763,7 @@ static int sdei_device_freeze(struct device *dev) · 762 unmodified lines | ||
| 763 | 763 | int err; |
| 764 | 764 | |
| 765 | 765 | /* unregister private events */ |
| 766 | − cpuhp_remove_state(sdei_entry_point); | |
| 766 | + cpuhp_remove_state(sdei_hp_state); | |
| 767 | 767 | |
| 768 | 768 | err = sdei_unregister_shared(); |
| 769 | 769 | if (err) |
| @@ -406,6 +406,8 @@ static void __aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, · 405 unmodified lines | ||
| 406 | 406 | gpio->dcache[GPIO_BANK(offset)] = reg; |
| 407 | 407 | |
| 408 | 408 | iowrite32(reg, addr); |
| 409 | + /* Flush write */ | |
| 410 | + ioread32(addr); | |
| 409 | 411 | } |
| 410 | 412 | |
| 411 | 413 | static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, |
| @@ -1191,7 +1193,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev) · 779 unmodified lines | ||
| 1191 | 1193 | if (!gpio_id) |
| 1192 | 1194 | return -EINVAL; |
| 1193 | 1195 | |
| 1194 | − gpio->clk = of_clk_get(pdev->dev.of_node, 0); | |
| 1196 | + gpio->clk = devm_clk_get_enabled(&pdev->dev, NULL); | |
| 1195 | 1197 | if (IS_ERR(gpio->clk)) { |
| 1196 | 1198 | dev_warn(&pdev->dev, |
| 1197 | 1199 | "Failed to get clock from devicetree, debouncing disabled\n"); |
| @@ -234,7 +234,9 @@ static int gpio_la_poll_probe(struct platform_device *pdev) · 233 unmodified lines | ||
| 234 | 234 | if (!priv) |
| 235 | 235 | return -ENOMEM; |
| 236 | 236 | |
| 237 | − devm_mutex_init(dev, &priv->blob_lock); | |
| 237 | + ret = devm_mutex_init(dev, &priv->blob_lock); | |
| 238 | + if (ret) | |
| 239 | + return ret; | |
| 238 | 240 | |
| 239 | 241 | fops_buf_size_set(priv, GPIO_LA_DEFAULT_BUF_SIZE); |
| 240 | 242 | |
| @@ -64,7 +64,7 @@ struct gpio_desc *swnode_find_gpio(struct fwnode_handle *fwnode, · 63 unmodified lines | ||
| 64 | 64 | struct fwnode_reference_args args; |
| 65 | 65 | struct gpio_desc *desc; |
| 66 | 66 | char propname[32]; /* 32 is max size of property name */ |
| 67 | − int ret; | |
| 67 | + int ret = 0; | |
| 68 | 68 | |
| 69 | 69 | swnode = to_software_node(fwnode); |
| 70 | 70 | if (!swnode) |
| @@ -4926,6 +4926,8 @@ static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos) · 4925 unmodified lines | ||
| 4926 | 4926 | return NULL; |
| 4927 | 4927 | |
| 4928 | 4928 | s->private = priv; |
| 4929 | + if (*pos > 0) | |
| 4930 | + priv->newline = true; | |
| 4929 | 4931 | priv->idx = srcu_read_lock(&gpio_devices_srcu); |
| 4930 | 4932 | |
| 4931 | 4933 | list_for_each_entry_srcu(gdev, &gpio_devices, list, |
| @@ -4969,7 +4971,7 @@ static int gpiolib_seq_show(struct seq_file *s, void *v) · 37 unmodified lines | ||
| 4969 | 4971 | |
| 4970 | 4972 | gc = srcu_dereference(gdev->chip, &gdev->srcu); |
| 4971 | 4973 | if (!gc) { |
| 4972 | − seq_printf(s, "%s%s: (dangling chip)", | |
| 4974 | + seq_printf(s, "%s%s: (dangling chip)\n", | |
| 4973 | 4975 | priv->newline ? "\n" : "", |
| 4974 | 4976 | dev_name(&gdev->dev)); |
| 4975 | 4977 | return 0; |
| @@ -303,6 +303,7 @@ void build_unoptimized_policy_settings(enum dml_project_id project, struct dml_m · 302 unmodified lines | ||
| 303 | 303 | if (project == dml_project_dcn35 || |
| 304 | 304 | project == dml_project_dcn351) { |
| 305 | 305 | policy->DCCProgrammingAssumesScanDirectionUnknownFinal = false; |
| 306 | + policy->EnhancedPrefetchScheduleAccelerationFinal = 0; | |
| 306 | 307 | policy->AllowForPStateChangeOrStutterInVBlankFinal = dml_prefetch_support_uclk_fclk_and_stutter_if_possible; /*new*/ |
| 307 | 308 | policy->UseOnlyMaxPrefetchModes = 1; |
| 308 | 309 | } |
| @@ -242,7 +242,9 @@ static int vangogh_tables_init(struct smu_context *smu) · 241 unmodified lines | ||
| 242 | 242 | goto err0_out; |
| 243 | 243 | smu_table->metrics_time = 0; |
| 244 | 244 | |
| 245 | − smu_table->gpu_metrics_table_size = max(sizeof(struct gpu_metrics_v2_3), sizeof(struct gpu_metrics_v2_2)); | |
| 245 | + smu_table->gpu_metrics_table_size = sizeof(struct gpu_metrics_v2_2); | |
| 246 | + smu_table->gpu_metrics_table_size = max(smu_table->gpu_metrics_table_size, sizeof(struct gpu_metrics_v2_3)); | |
| 247 | + smu_table->gpu_metrics_table_size = max(smu_table->gpu_metrics_table_size, sizeof(struct gpu_metrics_v2_4)); | |
| 246 | 248 | smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL); |
| 247 | 249 | if (!smu_table->gpu_metrics_table) |
| 248 | 250 | goto err1_out; |
| @@ -2473,7 +2473,7 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, · 2472 unmodified lines | ||
| 2473 | 2473 | DpmActivityMonitorCoeffInt_t *activity_monitor = |
| 2474 | 2474 | &(activity_monitor_external.DpmActivityMonitorCoeffInt); |
| 2475 | 2475 | int workload_type, ret = 0; |
| 2476 | − u32 workload_mask; | |
| 2476 | + u32 workload_mask, selected_workload_mask; | |
| 2477 | 2477 | |
| 2478 | 2478 | smu->power_profile_mode = input[size]; |
| 2479 | 2479 | |
| @@ -2540,7 +2540,7 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, · 60 unmodified lines | ||
| 2540 | 2540 | if (workload_type < 0) |
| 2541 | 2541 | return -EINVAL; |
| 2542 | 2542 | |
| 2543 | − workload_mask = 1 << workload_type; | |
| 2543 | + selected_workload_mask = workload_mask = 1 << workload_type; | |
| 2544 | 2544 | |
| 2545 | 2545 | /* Add optimizations for SMU13.0.0/10. Reuse the power saving profile */ |
| 2546 | 2546 | if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) && |
| @@ -2560,7 +2560,7 @@ static int smu_v13_0_0_set_power_profile_mode(struct smu_context *smu, · 13 unmodified lines | ||
| 2560 | 2560 | workload_mask, |
| 2561 | 2561 | NULL); |
| 2562 | 2562 | if (!ret) |
| 2563 | − smu->workload_mask = workload_mask; | |
| 2563 | + smu->workload_mask = selected_workload_mask; | |
| 2564 | 2564 | |
| 2565 | 2565 | return ret; |
| 2566 | 2566 | } |
| @@ -29,6 +29,8 @@ static int ast_sil164_connector_helper_get_modes(struct drm_connector *connector · 28 unmodified lines | ||
| 29 | 29 | if (ast_connector->physical_status == connector_status_connected) { |
| 30 | 30 | count = drm_connector_helper_get_modes(connector); |
| 31 | 31 | } else { |
| 32 | + drm_edid_connector_update(connector, NULL); | |
| 33 | + | |
| 32 | 34 | /* |
| 33 | 35 | * There's no EDID data without a connected monitor. Set BMC- |
| 34 | 36 | * compatible modes in this case. The XGA default resolution |
| @@ -29,6 +29,8 @@ static int ast_vga_connector_helper_get_modes(struct drm_connector *connector) · 28 unmodified lines | ||
| 29 | 29 | if (ast_connector->physical_status == connector_status_connected) { |
| 30 | 30 | count = drm_connector_helper_get_modes(connector); |
| 31 | 31 | } else { |
| 32 | + drm_edid_connector_update(connector, NULL); | |
| 33 | + | |
| 32 | 34 | /* |
| 33 | 35 | * There's no EDID data without a connected monitor. Set BMC- |
| 34 | 36 | * compatible modes in this case. The XGA default resolution |
| @@ -58,9 +58,10 @@ int drm_aux_bridge_register(struct device *parent) · 57 unmodified lines | ||
| 58 | 58 | adev->id = ret; |
| 59 | 59 | adev->name = "aux_bridge"; |
| 60 | 60 | adev->dev.parent = parent; |
| 61 | − adev->dev.of_node = of_node_get(parent->of_node); | |
| 62 | 61 | adev->dev.release = drm_aux_bridge_release; |
| 63 | 62 | |
| 63 | + device_set_of_node_from_dev(&adev->dev, parent); | |
| 64 | + | |
| 64 | 65 | ret = auxiliary_device_init(adev); |
| 65 | 66 | if (ret) { |
| 66 | 67 | ida_free(&drm_aux_bridge_ida, adev->id); |
| @@ -2412,6 +2412,7 @@ static int tc_probe_bridge_endpoint(struct tc_data *tc) · 2411 unmodified lines | ||
| 2412 | 2412 | if (tc->pre_emphasis[0] < 0 || tc->pre_emphasis[0] > 2 || |
| 2413 | 2413 | tc->pre_emphasis[1] < 0 || tc->pre_emphasis[1] > 2) { |
| 2414 | 2414 | dev_err(dev, "Incorrect Pre-Emphasis setting, use either 0=0dB 1=3.5dB 2=6dB\n"); |
| 2415 | + of_node_put(node); | |
| 2415 | 2416 | return -EINVAL; |
| 2416 | 2417 | } |
| 2417 | 2418 | } |
| @@ -48,7 +48,8 @@ static void drm_fbdev_dma_fb_destroy(struct fb_info *info) · 47 unmodified lines | ||
| 48 | 48 | if (!fb_helper->dev) |
| 49 | 49 | return; |
| 50 | 50 | |
| 51 | − fb_deferred_io_cleanup(info); | |
| 51 | + if (info->fbdefio) | |
| 52 | + fb_deferred_io_cleanup(info); | |
| 52 | 53 | drm_fb_helper_fini(fb_helper); |
| 53 | 54 | |
| 54 | 55 | drm_client_buffer_vunmap(fb_helper->buffer); |
| @@ -125,9 +125,8 @@ config DRM_I915_USERPTR · 124 unmodified lines | ||
| 125 | 125 | config DRM_I915_GVT_KVMGT |
| 126 | 126 | tristate "Enable KVM host support Intel GVT-g graphics virtualization" |
| 127 | 127 | depends on DRM_I915 |
| 128 | − depends on X86 | |
| 128 | + depends on KVM_X86 | |
| 129 | 129 | depends on 64BIT |
| 130 | − depends on KVM | |
| 131 | 130 | depends on VFIO |
| 132 | 131 | select DRM_I915_GVT |
| 133 | 132 | select KVM_EXTERNAL_WRITE_TRACKING |
| @@ -90,27 +90,19 @@ static int intel_dp_mst_max_dpt_bpp(const struct intel_crtc_state *crtc_state, · 89 unmodified lines | ||
| 90 | 90 | |
| 91 | 91 | static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state, |
| 92 | 92 | const struct intel_connector *connector, |
| 93 | − bool ssc, bool dsc, int bpp_x16) | |
| 93 | + bool ssc, int dsc_slice_count, int bpp_x16) | |
| 94 | 94 | { |
| 95 | 95 | const struct drm_display_mode *adjusted_mode = |
| 96 | 96 | &crtc_state->hw.adjusted_mode; |
| 97 | 97 | unsigned long flags = DRM_DP_BW_OVERHEAD_MST; |
| 98 | − int dsc_slice_count = 0; | |
| 99 | 98 | int overhead; |
| 100 | 99 | |
| 101 | 100 | flags |= intel_dp_is_uhbr(crtc_state) ? DRM_DP_BW_OVERHEAD_UHBR : 0; |
| 102 | 101 | flags |= ssc ? DRM_DP_BW_OVERHEAD_SSC_REF_CLK : 0; |
| 103 | 102 | flags |= crtc_state->fec_enable ? DRM_DP_BW_OVERHEAD_FEC : 0; |
| 104 | 103 | |
| 105 | − if (dsc) { | |
| 106 | − int num_joined_pipes = intel_crtc_num_joined_pipes(crtc_state); | |
| 107 | − | |
| 104 | + if (dsc_slice_count) | |
| 108 | 105 | flags |= DRM_DP_BW_OVERHEAD_DSC; |
| 109 | − dsc_slice_count = intel_dp_dsc_get_slice_count(connector, | |
| 110 | − adjusted_mode->clock, | |
| 111 | − adjusted_mode->hdisplay, | |
| 112 | − num_joined_pipes); | |
| 113 | − } | |
| 114 | 106 | |
| 115 | 107 | overhead = drm_dp_bw_overhead(crtc_state->lane_count, |
| 116 | 108 | adjusted_mode->hdisplay, |
| @@ -156,6 +148,19 @@ static int intel_dp_mst_calc_pbn(int pixel_clock, int bpp_x16, int bw_overhead) · 39 unmodified lines | ||
| 156 | 148 | return DIV_ROUND_UP(effective_data_rate * 64, 54 * 1000); |
| 157 | 149 | } |
| 158 | 150 | |
| 151 | +static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connector, | |
| 152 | + const struct intel_crtc_state *crtc_state) | |
| 153 | +{ | |
| 154 | + const struct drm_display_mode *adjusted_mode = | |
| 155 | + &crtc_state->hw.adjusted_mode; | |
| 156 | + int num_joined_pipes = crtc_state->joiner_pipes; | |
| 157 | + | |
| 158 | + return intel_dp_dsc_get_slice_count(connector, | |
| 159 | + adjusted_mode->clock, | |
| 160 | + adjusted_mode->hdisplay, | |
| 161 | + num_joined_pipes); | |
| 162 | +} | |
| 163 | + | |
| 159 | 164 | static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, |
| 160 | 165 | struct intel_crtc_state *crtc_state, |
| 161 | 166 | int max_bpp, |
| @@ -175,6 +180,7 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, · 13 unmodified lines | ||
| 175 | 180 | const struct drm_display_mode *adjusted_mode = |
| 176 | 181 | &crtc_state->hw.adjusted_mode; |
| 177 | 182 | int bpp, slots = -EINVAL; |
| 183 | + int dsc_slice_count = 0; | |
| 178 | 184 | int max_dpt_bpp; |
| 179 | 185 | int ret = 0; |
| 180 | 186 | |
| @@ -206,6 +212,15 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, · 25 unmodified lines | ||
| 206 | 212 | drm_dbg_kms(&i915->drm, "Looking for slots in range min bpp %d max bpp %d\n", |
| 207 | 213 | min_bpp, max_bpp); |
| 208 | 214 | |
| 215 | + if (dsc) { | |
| 216 | + dsc_slice_count = intel_dp_mst_dsc_get_slice_count(connector, crtc_state); | |
| 217 | + if (!dsc_slice_count) { | |
| 218 | + drm_dbg_kms(&i915->drm, "Can't get valid DSC slice count\n"); | |
| 219 | + | |
| 220 | + return -ENOSPC; | |
| 221 | + } | |
| 222 | + } | |
| 223 | + | |
| 209 | 224 | for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) { |
| 210 | 225 | int local_bw_overhead; |
| 211 | 226 | int remote_bw_overhead; |
| @@ -219,9 +234,9 @@ static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, · 7 unmodified lines | ||
| 219 | 234 | intel_dp_output_bpp(crtc_state->output_format, bpp)); |
| 220 | 235 | |
| 221 | 236 | local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector, |
| 222 | − false, dsc, link_bpp_x16); | |
| 237 | + false, dsc_slice_count, link_bpp_x16); | |
| 223 | 238 | remote_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector, |
| 224 | − true, dsc, link_bpp_x16); | |
| 239 | + true, dsc_slice_count, link_bpp_x16); | |
| 225 | 240 | |
| 226 | 241 | intel_dp_mst_compute_m_n(crtc_state, connector, |
| 227 | 242 | local_bw_overhead, |
| @@ -452,6 +467,9 @@ hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector, · 224 unmodified lines | ||
| 452 | 467 | if (mode_hblank_period_ns(adjusted_mode) > hblank_limit) |
| 453 | 468 | return false; |
| 454 | 469 | |
| 470 | + if (!intel_dp_mst_dsc_get_slice_count(connector, crtc_state)) | |
| 471 | + return false; | |
| 472 | + | |
| 455 | 473 | return true; |
| 456 | 474 | } |
| 457 | 475 | |
| @@ -127,9 +127,8 @@ static void mtk_crtc_destroy(struct drm_crtc *crtc) · 126 unmodified lines | ||
| 127 | 127 | |
| 128 | 128 | mtk_mutex_put(mtk_crtc->mutex); |
| 129 | 129 | #if IS_REACHABLE(CONFIG_MTK_CMDQ) |
| 130 | − cmdq_pkt_destroy(&mtk_crtc->cmdq_client, &mtk_crtc->cmdq_handle); | |
| 131 | − | |
| 132 | 130 | if (mtk_crtc->cmdq_client.chan) { |
| 131 | + cmdq_pkt_destroy(&mtk_crtc->cmdq_client, &mtk_crtc->cmdq_handle); | |
| 133 | 132 | mbox_free_channel(mtk_crtc->cmdq_client.chan); |
| 134 | 133 | mtk_crtc->cmdq_client.chan = NULL; |
| 135 | 134 | } |
| @@ -913,6 +912,7 @@ static int mtk_crtc_init_comp_planes(struct drm_device *drm_dev, · 777 unmodified lines | ||
| 913 | 912 | BIT(pipe), |
| 914 | 913 | mtk_crtc_plane_type(mtk_crtc->layer_nr, num_planes), |
| 915 | 914 | mtk_ddp_comp_supported_rotations(comp), |
| 915 | + mtk_ddp_comp_get_blend_modes(comp), | |
| 916 | 916 | mtk_ddp_comp_get_formats(comp), |
| 917 | 917 | mtk_ddp_comp_get_num_formats(comp), i); |
| 918 | 918 | if (ret) |
| @@ -363,6 +363,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl = { · 362 unmodified lines | ||
| 363 | 363 | .layer_config = mtk_ovl_layer_config, |
| 364 | 364 | .bgclr_in_on = mtk_ovl_bgclr_in_on, |
| 365 | 365 | .bgclr_in_off = mtk_ovl_bgclr_in_off, |
| 366 | + .get_blend_modes = mtk_ovl_get_blend_modes, | |
| 366 | 367 | .get_formats = mtk_ovl_get_formats, |
| 367 | 368 | .get_num_formats = mtk_ovl_get_num_formats, |
| 368 | 369 | }; |
| @@ -416,6 +417,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl_adaptor = { · 47 unmodified lines | ||
| 416 | 417 | .disconnect = mtk_ovl_adaptor_disconnect, |
| 417 | 418 | .add = mtk_ovl_adaptor_add_comp, |
| 418 | 419 | .remove = mtk_ovl_adaptor_remove_comp, |
| 420 | + .get_blend_modes = mtk_ovl_adaptor_get_blend_modes, | |
| 419 | 421 | .get_formats = mtk_ovl_adaptor_get_formats, |
| 420 | 422 | .get_num_formats = mtk_ovl_adaptor_get_num_formats, |
| 421 | 423 | .mode_valid = mtk_ovl_adaptor_mode_valid, |
| @@ -80,6 +80,7 @@ struct mtk_ddp_comp_funcs { · 79 unmodified lines | ||
| 80 | 80 | void (*ctm_set)(struct device *dev, |
| 81 | 81 | struct drm_crtc_state *state); |
| 82 | 82 | struct device * (*dma_dev_get)(struct device *dev); |
| 83 | + u32 (*get_blend_modes)(struct device *dev); | |
| 83 | 84 | const u32 *(*get_formats)(struct device *dev); |
| 84 | 85 | size_t (*get_num_formats)(struct device *dev); |
| 85 | 86 | void (*connect)(struct device *dev, struct device *mmsys_dev, unsigned int next); |
| @@ -266,6 +267,15 @@ static inline struct device *mtk_ddp_comp_dma_dev_get(struct mtk_ddp_comp *comp) · 180 unmodified lines | ||
| 266 | 267 | return comp->dev; |
| 267 | 268 | } |
| 268 | 269 | |
| 270 | +static inline | |
| 271 | +u32 mtk_ddp_comp_get_blend_modes(struct mtk_ddp_comp *comp) | |
| 272 | +{ | |
| 273 | + if (comp->funcs && comp->funcs->get_blend_modes) | |
| 274 | + return comp->funcs->get_blend_modes(comp->dev); | |
| 275 | + | |
| 276 | + return 0; | |
| 277 | +} | |
| 278 | + | |
| 269 | 279 | static inline |
| 270 | 280 | const u32 *mtk_ddp_comp_get_formats(struct mtk_ddp_comp *comp) |
| 271 | 281 | { |
| @@ -103,6 +103,7 @@ void mtk_ovl_register_vblank_cb(struct device *dev, · 102 unmodified lines | ||
| 103 | 103 | void mtk_ovl_unregister_vblank_cb(struct device *dev); |
| 104 | 104 | void mtk_ovl_enable_vblank(struct device *dev); |
| 105 | 105 | void mtk_ovl_disable_vblank(struct device *dev); |
| 106 | +u32 mtk_ovl_get_blend_modes(struct device *dev); | |
| 106 | 107 | const u32 *mtk_ovl_get_formats(struct device *dev); |
| 107 | 108 | size_t mtk_ovl_get_num_formats(struct device *dev); |
| 108 | 109 | |
| @@ -131,6 +132,7 @@ void mtk_ovl_adaptor_start(struct device *dev); · 22 unmodified lines | ||
| 131 | 132 | void mtk_ovl_adaptor_stop(struct device *dev); |
| 132 | 133 | unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev); |
| 133 | 134 | struct device *mtk_ovl_adaptor_dma_dev_get(struct device *dev); |
| 135 | +u32 mtk_ovl_adaptor_get_blend_modes(struct device *dev); | |
| 134 | 136 | const u32 *mtk_ovl_adaptor_get_formats(struct device *dev); |
| 135 | 137 | size_t mtk_ovl_adaptor_get_num_formats(struct device *dev); |
| 136 | 138 | enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev, |
| @@ -65,8 +65,8 @@ · 64 unmodified lines | ||
| 65 | 65 | #define OVL_CON_CLRFMT_RGB (1 << 12) |
| 66 | 66 | #define OVL_CON_CLRFMT_ARGB8888 (2 << 12) |
| 67 | 67 | #define OVL_CON_CLRFMT_RGBA8888 (3 << 12) |
| 68 | −#define OVL_CON_CLRFMT_ABGR8888 (OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP) | |
| 69 | −#define OVL_CON_CLRFMT_BGRA8888 (OVL_CON_CLRFMT_ARGB8888 | OVL_CON_BYTE_SWAP) | |
| 68 | +#define OVL_CON_CLRFMT_ABGR8888 (OVL_CON_CLRFMT_ARGB8888 | OVL_CON_BYTE_SWAP) | |
| 69 | +#define OVL_CON_CLRFMT_BGRA8888 (OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP) | |
| 70 | 70 | #define OVL_CON_CLRFMT_UYVY (4 << 12) |
| 71 | 71 | #define OVL_CON_CLRFMT_YUYV (5 << 12) |
| 72 | 72 | #define OVL_CON_MTX_YUV_TO_RGB (6 << 16) |
| @@ -146,6 +146,7 @@ struct mtk_disp_ovl_data { · 73 unmodified lines | ||
| 146 | 146 | bool fmt_rgb565_is_0; |
| 147 | 147 | bool smi_id_en; |
| 148 | 148 | bool supports_afbc; |
| 149 | + const u32 blend_modes; | |
| 149 | 150 | const u32 *formats; |
| 150 | 151 | size_t num_formats; |
| 151 | 152 | bool supports_clrfmt_ext; |
| @@ -214,6 +215,13 @@ void mtk_ovl_disable_vblank(struct device *dev) · 62 unmodified lines | ||
| 214 | 215 | writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN); |
| 215 | 216 | } |
| 216 | 217 | |
| 218 | +u32 mtk_ovl_get_blend_modes(struct device *dev) | |
| 219 | +{ | |
| 220 | + struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); | |
| 221 | + | |
| 222 | + return ovl->data->blend_modes; | |
| 223 | +} | |
| 224 | + | |
| 217 | 225 | const u32 *mtk_ovl_get_formats(struct device *dev) |
| 218 | 226 | { |
| 219 | 227 | struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); |
| @@ -386,14 +394,27 @@ void mtk_ovl_layer_off(struct device *dev, unsigned int idx, · 166 unmodified lines | ||
| 386 | 394 | DISP_REG_OVL_RDMA_CTRL(idx)); |
| 387 | 395 | } |
| 388 | 396 | |
| 389 | −static unsigned int ovl_fmt_convert(struct mtk_disp_ovl *ovl, unsigned int fmt, | |
| 390 | − unsigned int blend_mode) | |
| 397 | +static unsigned int mtk_ovl_fmt_convert(struct mtk_disp_ovl *ovl, | |
| 398 | + struct mtk_plane_state *state) | |
| 391 | 399 | { |
| 392 | − /* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX" | |
| 393 | − * is defined in mediatek HW data sheet. | |
| 394 | − * The alphabet order in XXX is no relation to data | |
| 395 | − * arrangement in memory. | |
| 400 | + unsigned int fmt = state->pending.format; | |
| 401 | + unsigned int blend_mode = DRM_MODE_BLEND_COVERAGE; | |
| 402 | + | |
| 403 | + /* | |
| 404 | + * For the platforms where OVL_CON_CLRFMT_MAN is defined in the hardware data sheet | |
| 405 | + * and supports premultiplied color formats, such as OVL_CON_CLRFMT_PARGB8888. | |
| 406 | + * | |
| 407 | + * Check blend_modes in the driver data to see if premultiplied mode is supported. | |
| 408 | + * If not, use coverage mode instead to set it to the supported color formats. | |
| 409 | + * | |
| 410 | + * Current DRM assumption is that alpha is default premultiplied, so the bitmask of | |
| 411 | + * blend_modes must include BIT(DRM_MODE_BLEND_PREMULTI). Otherwise, mtk_plane_init() | |
| 412 | + * will get an error return from drm_plane_create_blend_mode_property() and | |
| 413 | + * state->base.pixel_blend_mode should not be used. | |
| 396 | 414 | */ |
| 415 | + if (ovl->data->blend_modes & BIT(DRM_MODE_BLEND_PREMULTI)) | |
| 416 | + blend_mode = state->base.pixel_blend_mode; | |
| 417 | + | |
| 397 | 418 | switch (fmt) { |
| 398 | 419 | default: |
| 399 | 420 | case DRM_FORMAT_RGB565: |
| @@ -471,20 +492,26 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, · 71 unmodified lines | ||
| 471 | 492 | return; |
| 472 | 493 | } |
| 473 | 494 | |
| 474 | − con = ovl_fmt_convert(ovl, fmt, blend_mode); | |
| 495 | + con = mtk_ovl_fmt_convert(ovl, state); | |
| 475 | 496 | if (state->base.fb) { |
| 476 | − con |= OVL_CON_AEN; | |
| 477 | 497 | con |= state->base.alpha & OVL_CON_ALPHA; |
| 478 | − } | |
| 479 | 498 | |
| 480 | − /* CONST_BLD must be enabled for XRGB formats although the alpha channel | |
| 481 | − * can be ignored, or OVL will still read the value from memory. | |
| 482 | − * For RGB888 related formats, whether CONST_BLD is enabled or not won't | |
| 483 | − * affect the result. Therefore we use !has_alpha as the condition. | |
| 484 | − */ | |
| 485 | − if ((state->base.fb && !state->base.fb->format->has_alpha) || | |
| 486 | − blend_mode == DRM_MODE_BLEND_PIXEL_NONE) | |
| 487 | − ignore_pixel_alpha = OVL_CONST_BLEND; | |
| 499 | + /* | |
| 500 | + * For blend_modes supported SoCs, always enable alpha blending. | |
| 501 | + * For blend_modes unsupported SoCs, enable alpha blending when has_alpha is set. | |
| 502 | + */ | |
| 503 | + if (blend_mode || state->base.fb->format->has_alpha) | |
| 504 | + con |= OVL_CON_AEN; | |
| 505 | + | |
| 506 | + /* | |
| 507 | + * Although the alpha channel can be ignored, CONST_BLD must be enabled | |
| 508 | + * for XRGB format, otherwise OVL will still read the value from memory. | |
| 509 | + * For RGB888 related formats, whether CONST_BLD is enabled or not won't | |
| 510 | + * affect the result. Therefore we use !has_alpha as the condition. | |
| 511 | + */ | |
| 512 | + if (blend_mode == DRM_MODE_BLEND_PIXEL_NONE || !state->base.fb->format->has_alpha) | |
| 513 | + ignore_pixel_alpha = OVL_CONST_BLEND; | |
| 514 | + } | |
| 488 | 515 | |
| 489 | 516 | if (pending->rotation & DRM_MODE_REFLECT_Y) { |
| 490 | 517 | con |= OVL_CON_VIRT_FLIP; |
| @@ -663,6 +690,9 @@ static const struct mtk_disp_ovl_data mt8192_ovl_driver_data = { · 172 unmodified lines | ||
| 663 | 690 | .layer_nr = 4, |
| 664 | 691 | .fmt_rgb565_is_0 = true, |
| 665 | 692 | .smi_id_en = true, |
| 693 | + .blend_modes = BIT(DRM_MODE_BLEND_PREMULTI) | | |
| 694 | + BIT(DRM_MODE_BLEND_COVERAGE) | | |
| 695 | + BIT(DRM_MODE_BLEND_PIXEL_NONE), | |
| 666 | 696 | .formats = mt8173_formats, |
| 667 | 697 | .num_formats = ARRAY_SIZE(mt8173_formats), |
| 668 | 698 | }; |
| @@ -673,6 +703,9 @@ static const struct mtk_disp_ovl_data mt8192_ovl_2l_driver_data = { · 4 unmodified lines | ||
| 673 | 703 | .layer_nr = 2, |
| 674 | 704 | .fmt_rgb565_is_0 = true, |
| 675 | 705 | .smi_id_en = true, |
| 706 | + .blend_modes = BIT(DRM_MODE_BLEND_PREMULTI) | | |
| 707 | + BIT(DRM_MODE_BLEND_COVERAGE) | | |
| 708 | + BIT(DRM_MODE_BLEND_PIXEL_NONE), | |
| 676 | 709 | .formats = mt8173_formats, |
| 677 | 710 | .num_formats = ARRAY_SIZE(mt8173_formats), |
| 678 | 711 | }; |
| @@ -684,6 +717,9 @@ static const struct mtk_disp_ovl_data mt8195_ovl_driver_data = { · 5 unmodified lines | ||
| 684 | 717 | .fmt_rgb565_is_0 = true, |
| 685 | 718 | .smi_id_en = true, |
| 686 | 719 | .supports_afbc = true, |
| 720 | + .blend_modes = BIT(DRM_MODE_BLEND_PREMULTI) | | |
| 721 | + BIT(DRM_MODE_BLEND_COVERAGE) | | |
| 722 | + BIT(DRM_MODE_BLEND_PIXEL_NONE), | |
| 687 | 723 | .formats = mt8195_formats, |
| 688 | 724 | .num_formats = ARRAY_SIZE(mt8195_formats), |
| 689 | 725 | .supports_clrfmt_ext = true, |
| @@ -400,6 +400,13 @@ void mtk_ovl_adaptor_disable_vblank(struct device *dev) · 399 unmodified lines | ||
| 400 | 400 | mtk_ethdr_disable_vblank(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]); |
| 401 | 401 | } |
| 402 | 402 | |
| 403 | +u32 mtk_ovl_adaptor_get_blend_modes(struct device *dev) | |
| 404 | +{ | |
| 405 | + struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev); | |
| 406 | + | |
| 407 | + return mtk_ethdr_get_blend_modes(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]); | |
| 408 | +} | |
| 409 | + | |
| 403 | 410 | const u32 *mtk_ovl_adaptor_get_formats(struct device *dev) |
| 404 | 411 | { |
| 405 | 412 | struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev); |
| @@ -145,6 +145,89 @@ struct mtk_dp_data { · 144 unmodified lines | ||
| 145 | 145 | u16 audio_m_div2_bit; |
| 146 | 146 | }; |
| 147 | 147 | |
| 148 | +static const struct mtk_dp_efuse_fmt mt8188_dp_efuse_fmt[MTK_DP_CAL_MAX] = { | |
| 149 | + [MTK_DP_CAL_GLB_BIAS_TRIM] = { | |
| 150 | + .idx = 0, | |
| 151 | + .shift = 10, | |
| 152 | + .mask = 0x1f, | |
| 153 | + .min_val = 1, | |
| 154 | + .max_val = 0x1e, | |
| 155 | + .default_val = 0xf, | |
| 156 | + }, | |
| 157 | + [MTK_DP_CAL_CLKTX_IMPSE] = { | |
| 158 | + .idx = 0, | |
| 159 | + .shift = 15, | |
| 160 | + .mask = 0xf, | |
| 161 | + .min_val = 1, | |
| 162 | + .max_val = 0xe, | |
| 163 | + .default_val = 0x8, | |
| 164 | + }, | |
| 165 | + [MTK_DP_CAL_LN_TX_IMPSEL_PMOS_0] = { | |
| 166 | + .idx = 1, | |
| 167 | + .shift = 0, | |
| 168 | + .mask = 0xf, | |
| 169 | + .min_val = 1, | |
| 170 | + .max_val = 0xe, | |
| 171 | + .default_val = 0x8, | |
| 172 | + }, | |
| 173 | + [MTK_DP_CAL_LN_TX_IMPSEL_PMOS_1] = { | |
| 174 | + .idx = 1, | |
| 175 | + .shift = 8, | |
| 176 | + .mask = 0xf, | |
| 177 | + .min_val = 1, | |
| 178 | + .max_val = 0xe, | |
| 179 | + .default_val = 0x8, | |
| 180 | + }, | |
| 181 | + [MTK_DP_CAL_LN_TX_IMPSEL_PMOS_2] = { | |
| 182 | + .idx = 1, | |
| 183 | + .shift = 16, | |
| 184 | + .mask = 0xf, | |
| 185 | + .min_val = 1, | |
| 186 | + .max_val = 0xe, | |
| 187 | + .default_val = 0x8, | |
| 188 | + }, | |
| 189 | + [MTK_DP_CAL_LN_TX_IMPSEL_PMOS_3] = { | |
| 190 | + .idx = 1, | |
| 191 | + .shift = 24, | |
| 192 | + .mask = 0xf, | |
| 193 | + .min_val = 1, | |
| 194 | + .max_val = 0xe, | |
| 195 | + .default_val = 0x8, | |
| 196 | + }, | |
| 197 | + [MTK_DP_CAL_LN_TX_IMPSEL_NMOS_0] = { | |
| 198 | + .idx = 1, | |
| 199 | + .shift = 4, | |
| 200 | + .mask = 0xf, | |
| 201 | + .min_val = 1, | |
| 202 | + .max_val = 0xe, | |
| 203 | + .default_val = 0x8, | |
| 204 | + }, | |
| 205 | + [MTK_DP_CAL_LN_TX_IMPSEL_NMOS_1] = { | |
| 206 | + .idx = 1, | |
| 207 | + .shift = 12, | |
| 208 | + .mask = 0xf, | |
| 209 | + .min_val = 1, | |
| 210 | + .max_val = 0xe, | |
| 211 | + .default_val = 0x8, | |
| 212 | + }, | |
| 213 | + [MTK_DP_CAL_LN_TX_IMPSEL_NMOS_2] = { | |
| 214 | + .idx = 1, | |
| 215 | + .shift = 20, | |
| 216 | + .mask = 0xf, | |
| 217 | + .min_val = 1, | |
| 218 | + .max_val = 0xe, | |
| 219 | + .default_val = 0x8, | |
| 220 | + }, | |
| 221 | + [MTK_DP_CAL_LN_TX_IMPSEL_NMOS_3] = { | |
| 222 | + .idx = 1, | |
| 223 | + .shift = 28, | |
| 224 | + .mask = 0xf, | |
| 225 | + .min_val = 1, | |
| 226 | + .max_val = 0xe, | |
| 227 | + .default_val = 0x8, | |
| 228 | + }, | |
| 229 | +}; | |
| 230 | + | |
| 148 | 231 | static const struct mtk_dp_efuse_fmt mt8195_edp_efuse_fmt[MTK_DP_CAL_MAX] = { |
| 149 | 232 | [MTK_DP_CAL_GLB_BIAS_TRIM] = { |
| 150 | 233 | .idx = 3, |
| @@ -2771,7 +2854,7 @@ static SIMPLE_DEV_PM_OPS(mtk_dp_pm_ops, mtk_dp_suspend, mtk_dp_resume); · 2620 unmodified lines | ||
| 2771 | 2854 | static const struct mtk_dp_data mt8188_dp_data = { |
| 2772 | 2855 | .bridge_type = DRM_MODE_CONNECTOR_DisplayPort, |
| 2773 | 2856 | .smc_cmd = MTK_DP_SIP_ATF_VIDEO_UNMUTE, |
| 2774 | − .efuse_fmt = mt8195_dp_efuse_fmt, | |
| 2857 | + .efuse_fmt = mt8188_dp_efuse_fmt, | |
| 2775 | 2858 | .audio_supported = true, |
| 2776 | 2859 | .audio_pkt_in_hblank_area = true, |
| 2777 | 2860 | .audio_m_div2_bit = MT8188_AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2, |
| @@ -145,6 +145,13 @@ static irqreturn_t mtk_ethdr_irq_handler(int irq, void *dev_id) · 144 unmodified lines | ||
| 145 | 145 | return IRQ_HANDLED; |
| 146 | 146 | } |
| 147 | 147 | |
| 148 | +u32 mtk_ethdr_get_blend_modes(struct device *dev) | |
| 149 | +{ | |
| 150 | + return BIT(DRM_MODE_BLEND_PREMULTI) | | |
| 151 | + BIT(DRM_MODE_BLEND_COVERAGE) | | |
| 152 | + BIT(DRM_MODE_BLEND_PIXEL_NONE); | |
| 153 | +} | |
| 154 | + | |
| 148 | 155 | void mtk_ethdr_layer_config(struct device *dev, unsigned int idx, |
| 149 | 156 | struct mtk_plane_state *state, |
| 150 | 157 | struct cmdq_pkt *cmdq_pkt) |
| @@ -13,6 +13,7 @@ void mtk_ethdr_clk_disable(struct device *dev); · 12 unmodified lines | ||
| 13 | 13 | void mtk_ethdr_config(struct device *dev, unsigned int w, |
| 14 | 14 | unsigned int h, unsigned int vrefresh, |
| 15 | 15 | unsigned int bpc, struct cmdq_pkt *cmdq_pkt); |
| 16 | +u32 mtk_ethdr_get_blend_modes(struct device *dev); | |
| 16 | 17 | void mtk_ethdr_layer_config(struct device *dev, unsigned int idx, |
| 17 | 18 | struct mtk_plane_state *state, |
| 18 | 19 | struct cmdq_pkt *cmdq_pkt); |
| @@ -320,8 +320,8 @@ static const struct drm_plane_helper_funcs mtk_plane_helper_funcs = { · 319 unmodified lines | ||
| 320 | 320 | |
| 321 | 321 | int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, |
| 322 | 322 | unsigned long possible_crtcs, enum drm_plane_type type, |
| 323 | − unsigned int supported_rotations, const u32 *formats, | |
| 324 | − size_t num_formats, unsigned int plane_idx) | |
| 323 | + unsigned int supported_rotations, const u32 blend_modes, | |
| 324 | + const u32 *formats, size_t num_formats, unsigned int plane_idx) | |
| 325 | 325 | { |
| 326 | 326 | int err; |
| 327 | 327 | |
| @@ -366,12 +366,11 @@ int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, · 38 unmodified lines | ||
| 366 | 366 | if (err) |
| 367 | 367 | DRM_ERROR("failed to create property: alpha\n"); |
| 368 | 368 | |
| 369 | − err = drm_plane_create_blend_mode_property(plane, | |
| 370 | − BIT(DRM_MODE_BLEND_PREMULTI) | | |
| 371 | − BIT(DRM_MODE_BLEND_COVERAGE) | | |
| 372 | − BIT(DRM_MODE_BLEND_PIXEL_NONE)); | |
| 373 | − if (err) | |
| 374 | − DRM_ERROR("failed to create property: blend_mode\n"); | |
| 369 | + if (blend_modes) { | |
| 370 | + err = drm_plane_create_blend_mode_property(plane, blend_modes); | |
| 371 | + if (err) | |
| 372 | + DRM_ERROR("failed to create property: blend_mode\n"); | |
| 373 | + } | |
| 375 | 374 | |
| 376 | 375 | drm_plane_helper_add(plane, &mtk_plane_helper_funcs); |
| 377 | 376 | |
| @@ -48,6 +48,6 @@ to_mtk_plane_state(struct drm_plane_state *state) · 47 unmodified lines | ||
| 48 | 48 | |
| 49 | 49 | int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, |
| 50 | 50 | unsigned long possible_crtcs, enum drm_plane_type type, |
| 51 | − unsigned int supported_rotations, const u32 *formats, | |
| 52 | − size_t num_formats, unsigned int plane_idx); | |
| 51 | + unsigned int supported_rotations, const u32 blend_modes, | |
| 52 | + const u32 *formats, size_t num_formats, unsigned int plane_idx); | |
| 53 | 53 | #endif |
| @@ -20,7 +20,6 @@ · 19 unmodified lines | ||
| 20 | 20 | #include <drm/drm_managed.h> |
| 21 | 21 | #include <drm/drm_module.h> |
| 22 | 22 | #include <drm/drm_pciids.h> |
| 23 | −#include <drm/drm_vblank.h> | |
| 24 | 23 | |
| 25 | 24 | #include "mgag200_drv.h" |
| 26 | 25 | |
| @@ -87,34 +86,6 @@ resource_size_t mgag200_probe_vram(void __iomem *mem, resource_size_t size) · 60 unmodified lines | ||
| 87 | 86 | return offset - 65536; |
| 88 | 87 | } |
| 89 | 88 | |
| 90 | −static irqreturn_t mgag200_irq_handler(int irq, void *arg) | |
| 91 | −{ | |
| 92 | − struct drm_device *dev = arg; | |
| 93 | − struct mga_device *mdev = to_mga_device(dev); | |
| 94 | − struct drm_crtc *crtc; | |
| 95 | − u32 status, ien; | |
| 96 | − | |
| 97 | − status = RREG32(MGAREG_STATUS); | |
| 98 | − | |
| 99 | − if (status & MGAREG_STATUS_VLINEPEN) { | |
| 100 | − ien = RREG32(MGAREG_IEN); | |
| 101 | − if (!(ien & MGAREG_IEN_VLINEIEN)) | |
| 102 | − goto out; | |
| 103 | − | |
| 104 | − crtc = drm_crtc_from_index(dev, 0); | |
| 105 | − if (WARN_ON_ONCE(!crtc)) | |
| 106 | − goto out; | |
| 107 | − drm_crtc_handle_vblank(crtc); | |
| 108 | − | |
| 109 | − WREG32(MGAREG_ICLEAR, MGAREG_ICLEAR_VLINEICLR); | |
| 110 | − | |
| 111 | − return IRQ_HANDLED; | |
| 112 | − } | |
| 113 | − | |
| 114 | −out: | |
| 115 | − return IRQ_NONE; | |
| 116 | −} | |
| 117 | − | |
| 118 | 89 | /* |
| 119 | 90 | * DRM driver |
| 120 | 91 | */ |
| @@ -199,7 +170,6 @@ int mgag200_device_init(struct mga_device *mdev, · 78 unmodified lines | ||
| 199 | 170 | const struct mgag200_device_funcs *funcs) |
| 200 | 171 | { |
| 201 | 172 | struct drm_device *dev = &mdev->base; |
| 202 | − struct pci_dev *pdev = to_pci_dev(dev->dev); | |
| 203 | 173 | u8 crtcext3, misc; |
| 204 | 174 | int ret; |
| 205 | 175 | |
| @@ -226,14 +196,6 @@ int mgag200_device_init(struct mga_device *mdev, · 20 unmodified lines | ||
| 226 | 196 | mutex_unlock(&mdev->rmmio_lock); |
| 227 | 197 | |
| 228 | 198 | WREG32(MGAREG_IEN, 0); |
| 229 | − WREG32(MGAREG_ICLEAR, MGAREG_ICLEAR_VLINEICLR); | |
| 230 | − | |
| 231 | − ret = devm_request_irq(&pdev->dev, pdev->irq, mgag200_irq_handler, IRQF_SHARED, | |
| 232 | − dev->driver->name, dev); | |
| 233 | − if (ret) { | |
| 234 | − drm_err(dev, "Failed to acquire interrupt, error %d\n", ret); | |
| 235 | − return ret; | |
| 236 | − } | |
| 237 | 199 | |
| 238 | 200 | return 0; |
| 239 | 201 | } |
| @@ -391,24 +391,17 @@ int mgag200_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_st · 390 unmodified lines | ||
| 391 | 391 | void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *old_state); |
| 392 | 392 | void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *old_state); |
| 393 | 393 | void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *old_state); |
| 394 | −bool mgag200_crtc_helper_get_scanout_position(struct drm_crtc *crtc, bool in_vblank_irq, | |
| 395 | − int *vpos, int *hpos, | |
| 396 | − ktime_t *stime, ktime_t *etime, | |
| 397 | − const struct drm_display_mode *mode); | |
| 398 | 394 | |
| 399 | 395 | #define MGAG200_CRTC_HELPER_FUNCS \ |
| 400 | 396 | .mode_valid = mgag200_crtc_helper_mode_valid, \ |
| 401 | 397 | .atomic_check = mgag200_crtc_helper_atomic_check, \ |
| 402 | 398 | .atomic_flush = mgag200_crtc_helper_atomic_flush, \ |
| 403 | 399 | .atomic_enable = mgag200_crtc_helper_atomic_enable, \ |
| 404 | − .atomic_disable = mgag200_crtc_helper_atomic_disable, \ | |
| 405 | − .get_scanout_position = mgag200_crtc_helper_get_scanout_position | |
| 400 | + .atomic_disable = mgag200_crtc_helper_atomic_disable | |
| 406 | 401 | |
| 407 | 402 | void mgag200_crtc_reset(struct drm_crtc *crtc); |
| 408 | 403 | struct drm_crtc_state *mgag200_crtc_atomic_duplicate_state(struct drm_crtc *crtc); |
| 409 | 404 | void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state); |
| 410 | −int mgag200_crtc_enable_vblank(struct drm_crtc *crtc); | |
| 411 | −void mgag200_crtc_disable_vblank(struct drm_crtc *crtc); | |
| 412 | 405 | |
| 413 | 406 | #define MGAG200_CRTC_FUNCS \ |
| 414 | 407 | .reset = mgag200_crtc_reset, \ |
| @@ -416,10 +409,7 @@ void mgag200_crtc_disable_vblank(struct drm_crtc *crtc); · 1 unmodified line | ||
| 416 | 409 | .set_config = drm_atomic_helper_set_config, \ |
| 417 | 410 | .page_flip = drm_atomic_helper_page_flip, \ |
| 418 | 411 | .atomic_duplicate_state = mgag200_crtc_atomic_duplicate_state, \ |
| 419 | − .atomic_destroy_state = mgag200_crtc_atomic_destroy_state, \ | |
| 420 | − .enable_vblank = mgag200_crtc_enable_vblank, \ | |
| 421 | − .disable_vblank = mgag200_crtc_disable_vblank, \ | |
| 422 | − .get_vblank_timestamp = drm_crtc_vblank_helper_get_vblank_timestamp | |
| 412 | + .atomic_destroy_state = mgag200_crtc_atomic_destroy_state | |
| 423 | 413 | |
| 424 | 414 | void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mode *mode, |
| 425 | 415 | bool set_vidrst); |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <drm/drm_drv.h> |
| 9 | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | 10 | #include <drm/drm_probe_helper.h> |
| 11 | −#include <drm/drm_vblank.h> | |
| 12 | 11 | |
| 13 | 12 | #include "mgag200_drv.h" |
| 14 | 13 | |
| @@ -404,9 +403,5 @@ struct mga_device *mgag200_g200_device_create(struct pci_dev *pdev, const struct · 389 unmodified lines | ||
| 404 | 403 | drm_mode_config_reset(dev); |
| 405 | 404 | drm_kms_helper_poll_init(dev); |
| 406 | 405 | |
| 407 | − ret = drm_vblank_init(dev, 1); | |
| 408 | − if (ret) | |
| 409 | − return ERR_PTR(ret); | |
| 410 | − | |
| 411 | 406 | return mdev; |
| 412 | 407 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <drm/drm_drv.h> |
| 9 | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | 10 | #include <drm/drm_probe_helper.h> |
| 11 | −#include <drm/drm_vblank.h> | |
| 12 | 11 | |
| 13 | 12 | #include "mgag200_drv.h" |
| 14 | 13 | |
| @@ -276,9 +275,5 @@ struct mga_device *mgag200_g200eh_device_create(struct pci_dev *pdev, const stru · 261 unmodified lines | ||
| 276 | 275 | drm_mode_config_reset(dev); |
| 277 | 276 | drm_kms_helper_poll_init(dev); |
| 278 | 277 | |
| 279 | − ret = drm_vblank_init(dev, 1); | |
| 280 | − if (ret) | |
| 281 | − return ERR_PTR(ret); | |
| 282 | − | |
| 283 | 278 | return mdev; |
| 284 | 279 | } |
| @@ -7,7 +7,6 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <drm/drm_drv.h> |
| 8 | 8 | #include <drm/drm_gem_atomic_helper.h> |
| 9 | 9 | #include <drm/drm_probe_helper.h> |
| 10 | −#include <drm/drm_vblank.h> | |
| 11 | 10 | |
| 12 | 11 | #include "mgag200_drv.h" |
| 13 | 12 | |
| @@ -181,9 +180,5 @@ struct mga_device *mgag200_g200eh3_device_create(struct pci_dev *pdev, · 167 unmodified lines | ||
| 181 | 180 | drm_mode_config_reset(dev); |
| 182 | 181 | drm_kms_helper_poll_init(dev); |
| 183 | 182 | |
| 184 | − ret = drm_vblank_init(dev, 1); | |
| 185 | − if (ret) | |
| 186 | − return ERR_PTR(ret); | |
| 187 | − | |
| 188 | 183 | return mdev; |
| 189 | 184 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <drm/drm_drv.h> |
| 9 | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | 10 | #include <drm/drm_probe_helper.h> |
| 11 | −#include <drm/drm_vblank.h> | |
| 12 | 11 | |
| 13 | 12 | #include "mgag200_drv.h" |
| 14 | 13 | |
| @@ -206,8 +205,6 @@ static void mgag200_g200er_crtc_helper_atomic_enable(struct drm_crtc *crtc, · 191 unmodified lines | ||
| 206 | 205 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 207 | 206 | |
| 208 | 207 | mgag200_enable_display(mdev); |
| 209 | − | |
| 210 | − drm_crtc_vblank_on(crtc); | |
| 211 | 208 | } |
| 212 | 209 | |
| 213 | 210 | static const struct drm_crtc_helper_funcs mgag200_g200er_crtc_helper_funcs = { |
| @@ -215,8 +212,7 @@ static const struct drm_crtc_helper_funcs mgag200_g200er_crtc_helper_funcs = { · 1 unmodified line | ||
| 215 | 212 | .atomic_check = mgag200_crtc_helper_atomic_check, |
| 216 | 213 | .atomic_flush = mgag200_crtc_helper_atomic_flush, |
| 217 | 214 | .atomic_enable = mgag200_g200er_crtc_helper_atomic_enable, |
| 218 | − .atomic_disable = mgag200_crtc_helper_atomic_disable, | |
| 219 | − .get_scanout_position = mgag200_crtc_helper_get_scanout_position, | |
| 215 | + .atomic_disable = mgag200_crtc_helper_atomic_disable | |
| 220 | 216 | }; |
| 221 | 217 | |
| 222 | 218 | static const struct drm_crtc_funcs mgag200_g200er_crtc_funcs = { |
| @@ -312,9 +308,5 @@ struct mga_device *mgag200_g200er_device_create(struct pci_dev *pdev, const stru · 89 unmodified lines | ||
| 312 | 308 | drm_mode_config_reset(dev); |
| 313 | 309 | drm_kms_helper_poll_init(dev); |
| 314 | 310 | |
| 315 | − ret = drm_vblank_init(dev, 1); | |
| 316 | − if (ret) | |
| 317 | − return ERR_PTR(ret); | |
| 318 | − | |
| 319 | 311 | return mdev; |
| 320 | 312 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <drm/drm_drv.h> |
| 9 | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | 10 | #include <drm/drm_probe_helper.h> |
| 11 | −#include <drm/drm_vblank.h> | |
| 12 | 11 | |
| 13 | 12 | #include "mgag200_drv.h" |
| 14 | 13 | |
| @@ -207,8 +206,6 @@ static void mgag200_g200ev_crtc_helper_atomic_enable(struct drm_crtc *crtc, · 192 unmodified lines | ||
| 207 | 206 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 208 | 207 | |
| 209 | 208 | mgag200_enable_display(mdev); |
| 210 | − | |
| 211 | − drm_crtc_vblank_on(crtc); | |
| 212 | 209 | } |
| 213 | 210 | |
| 214 | 211 | static const struct drm_crtc_helper_funcs mgag200_g200ev_crtc_helper_funcs = { |
| @@ -216,8 +213,7 @@ static const struct drm_crtc_helper_funcs mgag200_g200ev_crtc_helper_funcs = { · 1 unmodified line | ||
| 216 | 213 | .atomic_check = mgag200_crtc_helper_atomic_check, |
| 217 | 214 | .atomic_flush = mgag200_crtc_helper_atomic_flush, |
| 218 | 215 | .atomic_enable = mgag200_g200ev_crtc_helper_atomic_enable, |
| 219 | − .atomic_disable = mgag200_crtc_helper_atomic_disable, | |
| 220 | − .get_scanout_position = mgag200_crtc_helper_get_scanout_position, | |
| 216 | + .atomic_disable = mgag200_crtc_helper_atomic_disable | |
| 221 | 217 | }; |
| 222 | 218 | |
| 223 | 219 | static const struct drm_crtc_funcs mgag200_g200ev_crtc_funcs = { |
| @@ -317,9 +313,5 @@ struct mga_device *mgag200_g200ev_device_create(struct pci_dev *pdev, const stru · 93 unmodified lines | ||
| 317 | 313 | drm_mode_config_reset(dev); |
| 318 | 314 | drm_kms_helper_poll_init(dev); |
| 319 | 315 | |
| 320 | − ret = drm_vblank_init(dev, 1); | |
| 321 | − if (ret) | |
| 322 | − return ERR_PTR(ret); | |
| 323 | − | |
| 324 | 316 | return mdev; |
| 325 | 317 | } |
| @@ -7,7 +7,6 @@ · 6 unmodified lines | ||
| 7 | 7 | #include <drm/drm_drv.h> |
| 8 | 8 | #include <drm/drm_gem_atomic_helper.h> |
| 9 | 9 | #include <drm/drm_probe_helper.h> |
| 10 | −#include <drm/drm_vblank.h> | |
| 11 | 10 | |
| 12 | 11 | #include "mgag200_drv.h" |
| 13 | 12 | |
| @@ -199,9 +198,5 @@ struct mga_device *mgag200_g200ew3_device_create(struct pci_dev *pdev, · 185 unmodified lines | ||
| 199 | 198 | drm_mode_config_reset(dev); |
| 200 | 199 | drm_kms_helper_poll_init(dev); |
| 201 | 200 | |
| 202 | − ret = drm_vblank_init(dev, 1); | |
| 203 | − if (ret) | |
| 204 | − return ERR_PTR(ret); | |
| 205 | − | |
| 206 | 201 | return mdev; |
| 207 | 202 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <drm/drm_drv.h> |
| 9 | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | 10 | #include <drm/drm_probe_helper.h> |
| 11 | −#include <drm/drm_vblank.h> | |
| 12 | 11 | |
| 13 | 12 | #include "mgag200_drv.h" |
| 14 | 13 | |
| @@ -338,8 +337,6 @@ static void mgag200_g200se_crtc_helper_atomic_enable(struct drm_crtc *crtc, · 323 unmodified lines | ||
| 338 | 337 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 339 | 338 | |
| 340 | 339 | mgag200_enable_display(mdev); |
| 341 | − | |
| 342 | − drm_crtc_vblank_on(crtc); | |
| 343 | 340 | } |
| 344 | 341 | |
| 345 | 342 | static const struct drm_crtc_helper_funcs mgag200_g200se_crtc_helper_funcs = { |
| @@ -347,8 +344,7 @@ static const struct drm_crtc_helper_funcs mgag200_g200se_crtc_helper_funcs = { · 1 unmodified line | ||
| 347 | 344 | .atomic_check = mgag200_crtc_helper_atomic_check, |
| 348 | 345 | .atomic_flush = mgag200_crtc_helper_atomic_flush, |
| 349 | 346 | .atomic_enable = mgag200_g200se_crtc_helper_atomic_enable, |
| 350 | − .atomic_disable = mgag200_crtc_helper_atomic_disable, | |
| 351 | − .get_scanout_position = mgag200_crtc_helper_get_scanout_position, | |
| 347 | + .atomic_disable = mgag200_crtc_helper_atomic_disable | |
| 352 | 348 | }; |
| 353 | 349 | |
| 354 | 350 | static const struct drm_crtc_funcs mgag200_g200se_crtc_funcs = { |
| @@ -517,9 +513,5 @@ struct mga_device *mgag200_g200se_device_create(struct pci_dev *pdev, const stru · 162 unmodified lines | ||
| 517 | 513 | drm_mode_config_reset(dev); |
| 518 | 514 | drm_kms_helper_poll_init(dev); |
| 519 | 515 | |
| 520 | − ret = drm_vblank_init(dev, 1); | |
| 521 | − if (ret) | |
| 522 | − return ERR_PTR(ret); | |
| 523 | − | |
| 524 | 516 | return mdev; |
| 525 | 517 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | ||
| 8 | 8 | #include <drm/drm_drv.h> |
| 9 | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | 10 | #include <drm/drm_probe_helper.h> |
| 11 | −#include <drm/drm_vblank.h> | |
| 12 | 11 | |
| 13 | 12 | #include "mgag200_drv.h" |
| 14 | 13 | |
| @@ -323,9 +322,5 @@ struct mga_device *mgag200_g200wb_device_create(struct pci_dev *pdev, const stru · 308 unmodified lines | ||
| 323 | 322 | drm_mode_config_reset(dev); |
| 324 | 323 | drm_kms_helper_poll_init(dev); |
| 325 | 324 | |
| 326 | − ret = drm_vblank_init(dev, 1); | |
| 327 | − if (ret) | |
| 328 | − return ERR_PTR(ret); | |
| 329 | − | |
| 330 | 325 | return mdev; |
| 331 | 326 | } |
| @@ -22,7 +22,6 @@ · 21 unmodified lines | ||
| 22 | 22 | #include <drm/drm_gem_framebuffer_helper.h> |
| 23 | 23 | #include <drm/drm_panic.h> |
| 24 | 24 | #include <drm/drm_print.h> |
| 25 | −#include <drm/drm_vblank.h> | |
| 26 | 25 | |
| 27 | 26 | #include "mgag200_ddc.h" |
| 28 | 27 | #include "mgag200_drv.h" |
| @@ -227,14 +226,7 @@ void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mod · 198 unmodified lines | ||
| 227 | 226 | vblkstr = mode->crtc_vblank_start; |
| 228 | 227 | vblkend = vtotal + 1; |
| 229 | 228 | |
| 230 | − /* | |
| 231 | − * There's no VBLANK interrupt on Matrox chipsets, so we use | |
| 232 | − * the VLINE interrupt instead. It triggers when the current | |
| 233 | − * <linecomp> has been reached. For VBLANK, this is the first | |
| 234 | − * non-visible line at the bottom of the screen. Therefore, | |
| 235 | − * keep <linecomp> in sync with <vblkstr>. | |
| 236 | − */ | |
| 237 | − linecomp = vblkstr; | |
| 229 | + linecomp = vdispend; | |
| 238 | 230 | |
| 239 | 231 | misc = RREG8(MGA_MISC_IN); |
| 240 | 232 | |
| @@ -645,8 +637,6 @@ void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_s · 404 unmodified lines | ||
| 645 | 637 | struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state); |
| 646 | 638 | struct drm_device *dev = crtc->dev; |
| 647 | 639 | struct mga_device *mdev = to_mga_device(dev); |
| 648 | − struct drm_pending_vblank_event *event; | |
| 649 | − unsigned long flags; | |
| 650 | 640 | |
| 651 | 641 | if (crtc_state->enable && crtc_state->color_mgmt_changed) { |
| 652 | 642 | const struct drm_format_info *format = mgag200_crtc_state->format; |
| @@ -656,18 +646,6 @@ void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_s · 3 unmodified lines | ||
| 656 | 646 | else |
| 657 | 647 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 658 | 648 | } |
| 659 | − | |
| 660 | − event = crtc->state->event; | |
| 661 | − if (event) { | |
| 662 | − crtc->state->event = NULL; | |
| 663 | − | |
| 664 | − spin_lock_irqsave(&dev->event_lock, flags); | |
| 665 | − if (drm_crtc_vblank_get(crtc) != 0) | |
| 666 | − drm_crtc_send_vblank_event(crtc, event); | |
| 667 | − else | |
| 668 | − drm_crtc_arm_vblank_event(crtc, event); | |
| 669 | − spin_unlock_irqrestore(&dev->event_lock, flags); | |
| 670 | − } | |
| 671 | 649 | } |
| 672 | 650 | |
| 673 | 651 | void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *old_state) |
| @@ -692,44 +670,15 @@ void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_ · 18 unmodified lines | ||
| 692 | 670 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 693 | 671 | |
| 694 | 672 | mgag200_enable_display(mdev); |
| 695 | − | |
| 696 | − drm_crtc_vblank_on(crtc); | |
| 697 | 673 | } |
| 698 | 674 | |
| 699 | 675 | void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *old_state) |
| 700 | 676 | { |
| 701 | 677 | struct mga_device *mdev = to_mga_device(crtc->dev); |
| 702 | 678 | |
| 703 | − drm_crtc_vblank_off(crtc); | |
| 704 | − | |
| 705 | 679 | mgag200_disable_display(mdev); |
| 706 | 680 | } |
| 707 | 681 | |
| 708 | −bool mgag200_crtc_helper_get_scanout_position(struct drm_crtc *crtc, bool in_vblank_irq, | |
| 709 | − int *vpos, int *hpos, | |
| 710 | − ktime_t *stime, ktime_t *etime, | |
| 711 | − const struct drm_display_mode *mode) | |
| 712 | −{ | |
| 713 | − struct mga_device *mdev = to_mga_device(crtc->dev); | |
| 714 | − u32 vcount; | |
| 715 | − | |
| 716 | − if (stime) | |
| 717 | − *stime = ktime_get(); | |
| 718 | − | |
| 719 | − if (vpos) { | |
| 720 | − vcount = RREG32(MGAREG_VCOUNT); | |
| 721 | − *vpos = vcount & GENMASK(11, 0); | |
| 722 | − } | |
| 723 | − | |
| 724 | − if (hpos) | |
| 725 | − *hpos = mode->htotal >> 1; // near middle of scanline on average | |
| 726 | − | |
| 727 | − if (etime) | |
| 728 | − *etime = ktime_get(); | |
| 729 | − | |
| 730 | − return true; | |
| 731 | −} | |
| 732 | − | |
| 733 | 682 | void mgag200_crtc_reset(struct drm_crtc *crtc) |
| 734 | 683 | { |
| 735 | 684 | struct mgag200_crtc_state *mgag200_crtc_state; |
| @@ -774,30 +723,6 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_st · 38 unmodified lines | ||
| 774 | 723 | kfree(mgag200_crtc_state); |
| 775 | 724 | } |
| 776 | 725 | |
| 777 | −int mgag200_crtc_enable_vblank(struct drm_crtc *crtc) | |
| 778 | −{ | |
| 779 | − struct mga_device *mdev = to_mga_device(crtc->dev); | |
| 780 | − u32 ien; | |
| 781 | − | |
| 782 | − WREG32(MGAREG_ICLEAR, MGAREG_ICLEAR_VLINEICLR); | |
| 783 | − | |
| 784 | − ien = RREG32(MGAREG_IEN); | |
| 785 | − ien |= MGAREG_IEN_VLINEIEN; | |
| 786 | − WREG32(MGAREG_IEN, ien); | |
| 787 | − | |
| 788 | − return 0; | |
| 789 | −} | |
| 790 | − | |
| 791 | −void mgag200_crtc_disable_vblank(struct drm_crtc *crtc) | |
| 792 | −{ | |
| 793 | − struct mga_device *mdev = to_mga_device(crtc->dev); | |
| 794 | − u32 ien; | |
| 795 | − | |
| 796 | − ien = RREG32(MGAREG_IEN); | |
| 797 | − ien &= ~(MGAREG_IEN_VLINEIEN); | |
| 798 | − WREG32(MGAREG_IEN, ien); | |
| 799 | −} | |
| 800 | − | |
| 801 | 726 | /* |
| 802 | 727 | * Mode config |
| 803 | 728 | */ |
| @@ -101,9 +101,10 @@ static void get_stats_counter(struct msm_ringbuffer *ring, u32 counter, · 100 unmodified lines | ||
| 101 | 101 | } |
| 102 | 102 | |
| 103 | 103 | static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, |
| 104 | − struct msm_ringbuffer *ring, struct msm_file_private *ctx) | |
| 104 | + struct msm_ringbuffer *ring, struct msm_gem_submit *submit) | |
| 105 | 105 | { |
| 106 | 106 | bool sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1; |
| 107 | + struct msm_file_private *ctx = submit->queue->ctx; | |
| 107 | 108 | struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; |
| 108 | 109 | phys_addr_t ttbr; |
| 109 | 110 | u32 asid; |
| @@ -115,6 +116,15 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, · 5 unmodified lines | ||
| 115 | 116 | if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid)) |
| 116 | 117 | return; |
| 117 | 118 | |
| 119 | + if (adreno_gpu->info->family >= ADRENO_7XX_GEN1) { | |
| 120 | + /* Wait for previous submit to complete before continuing: */ | |
| 121 | + OUT_PKT7(ring, CP_WAIT_TIMESTAMP, 4); | |
| 122 | + OUT_RING(ring, 0); | |
| 123 | + OUT_RING(ring, lower_32_bits(rbmemptr(ring, fence))); | |
| 124 | + OUT_RING(ring, upper_32_bits(rbmemptr(ring, fence))); | |
| 125 | + OUT_RING(ring, submit->seqno - 1); | |
| 126 | + } | |
| 127 | + | |
| 118 | 128 | if (!sysprof) { |
| 119 | 129 | if (!adreno_is_a7xx(adreno_gpu)) { |
| 120 | 130 | /* Turn off protected mode to write to special registers */ |
| @@ -193,7 +203,7 @@ static void a6xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) · 72 unmodified lines | ||
| 193 | 203 | struct msm_ringbuffer *ring = submit->ring; |
| 194 | 204 | unsigned int i, ibs = 0; |
| 195 | 205 | |
| 196 | − a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx); | |
| 206 | + a6xx_set_pagetable(a6xx_gpu, ring, submit); | |
| 197 | 207 | |
| 198 | 208 | get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0), |
| 199 | 209 | rbmemptr_stats(ring, index, cpcycles_start)); |
| @@ -283,7 +293,7 @@ static void a7xx_submit(struct msm_gpu *gpu, struct msm_gem_submit *submit) · 83 unmodified lines | ||
| 283 | 293 | OUT_PKT7(ring, CP_THREAD_CONTROL, 1); |
| 284 | 294 | OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BR); |
| 285 | 295 | |
| 286 | − a6xx_set_pagetable(a6xx_gpu, ring, submit->queue->ctx); | |
| 296 | + a6xx_set_pagetable(a6xx_gpu, ring, submit); | |
| 287 | 297 | |
| 288 | 298 | get_stats_counter(ring, REG_A7XX_RBBM_PERFCTR_CP(0), |
| 289 | 299 | rbmemptr_stats(ring, index, cpcycles_start)); |
| @@ -711,12 +711,13 @@ void dpu_crtc_complete_commit(struct drm_crtc *crtc) · 710 unmodified lines | ||
| 711 | 711 | _dpu_crtc_complete_flip(crtc); |
| 712 | 712 | } |
| 713 | 713 | |
| 714 | −static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc, | |
| 714 | +static int _dpu_crtc_check_and_setup_lm_bounds(struct drm_crtc *crtc, | |
| 715 | 715 | struct drm_crtc_state *state) |
| 716 | 716 | { |
| 717 | 717 | struct dpu_crtc_state *cstate = to_dpu_crtc_state(state); |
| 718 | 718 | struct drm_display_mode *adj_mode = &state->adjusted_mode; |
| 719 | 719 | u32 crtc_split_width = adj_mode->hdisplay / cstate->num_mixers; |
| 720 | + struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); | |
| 720 | 721 | int i; |
| 721 | 722 | |
| 722 | 723 | for (i = 0; i < cstate->num_mixers; i++) { |
| @@ -727,7 +728,12 @@ static void _dpu_crtc_setup_lm_bounds(struct drm_crtc *crtc, · 4 unmodified lines | ||
| 727 | 728 | r->y2 = adj_mode->vdisplay; |
| 728 | 729 | |
| 729 | 730 | trace_dpu_crtc_setup_lm_bounds(DRMID(crtc), i, r); |
| 731 | + | |
| 732 | + if (drm_rect_width(r) > dpu_kms->catalog->caps->max_mixer_width) | |
| 733 | + return -E2BIG; | |
| 730 | 734 | } |
| 735 | + | |
| 736 | + return 0; | |
| 731 | 737 | } |
| 732 | 738 | |
| 733 | 739 | static void _dpu_crtc_get_pcc_coeff(struct drm_crtc_state *state, |
| @@ -803,7 +809,7 @@ static void dpu_crtc_atomic_begin(struct drm_crtc *crtc, · 69 unmodified lines | ||
| 803 | 809 | |
| 804 | 810 | DRM_DEBUG_ATOMIC("crtc%d\n", crtc->base.id); |
| 805 | 811 | |
| 806 | − _dpu_crtc_setup_lm_bounds(crtc, crtc->state); | |
| 812 | + _dpu_crtc_check_and_setup_lm_bounds(crtc, crtc->state); | |
| 807 | 813 | |
| 808 | 814 | /* encoder will trigger pending mask now */ |
| 809 | 815 | drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) |
| @@ -1091,9 +1097,6 @@ static void dpu_crtc_disable(struct drm_crtc *crtc, · 281 unmodified lines | ||
| 1091 | 1097 | |
| 1092 | 1098 | dpu_core_perf_crtc_update(crtc, 0); |
| 1093 | 1099 | |
| 1094 | − memset(cstate->mixers, 0, sizeof(cstate->mixers)); | |
| 1095 | − cstate->num_mixers = 0; | |
| 1096 | − | |
| 1097 | 1100 | /* disable clk & bw control until clk & bw properties are set */ |
| 1098 | 1101 | cstate->bw_control = false; |
| 1099 | 1102 | cstate->bw_split_vote = false; |
| @@ -1192,8 +1195,11 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, · 92 unmodified lines | ||
| 1192 | 1195 | if (crtc_state->active_changed) |
| 1193 | 1196 | crtc_state->mode_changed = true; |
| 1194 | 1197 | |
| 1195 | − if (cstate->num_mixers) | |
| 1196 | − _dpu_crtc_setup_lm_bounds(crtc, crtc_state); | |
| 1198 | + if (cstate->num_mixers) { | |
| 1199 | + rc = _dpu_crtc_check_and_setup_lm_bounds(crtc, crtc_state); | |
| 1200 | + if (rc) | |
| 1201 | + return rc; | |
| 1202 | + } | |
| 1197 | 1203 | |
| 1198 | 1204 | /* FIXME: move this to dpu_plane_atomic_check? */ |
| 1199 | 1205 | drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) { |
| @@ -624,6 +624,40 @@ static struct msm_display_topology dpu_encoder_get_topology( · 623 unmodified lines | ||
| 624 | 624 | return topology; |
| 625 | 625 | } |
| 626 | 626 | |
| 627 | +static void dpu_encoder_assign_crtc_resources(struct dpu_kms *dpu_kms, | |
| 628 | + struct drm_encoder *drm_enc, | |
| 629 | + struct dpu_global_state *global_state, | |
| 630 | + struct drm_crtc_state *crtc_state) | |
| 631 | +{ | |
| 632 | + struct dpu_crtc_state *cstate; | |
| 633 | + struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC]; | |
| 634 | + struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC]; | |
| 635 | + struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC]; | |
| 636 | + int num_lm, num_ctl, num_dspp, i; | |
| 637 | + | |
| 638 | + cstate = to_dpu_crtc_state(crtc_state); | |
| 639 | + | |
| 640 | + memset(cstate->mixers, 0, sizeof(cstate->mixers)); | |
| 641 | + | |
| 642 | + num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, | |
| 643 | + drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); | |
| 644 | + num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, | |
| 645 | + drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm)); | |
| 646 | + num_dspp = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, | |
| 647 | + drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp, | |
| 648 | + ARRAY_SIZE(hw_dspp)); | |
| 649 | + | |
| 650 | + for (i = 0; i < num_lm; i++) { | |
| 651 | + int ctl_idx = (i < num_ctl) ? i : (num_ctl-1); | |
| 652 | + | |
| 653 | + cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]); | |
| 654 | + cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]); | |
| 655 | + cstate->mixers[i].hw_dspp = i < num_dspp ? to_dpu_hw_dspp(hw_dspp[i]) : NULL; | |
| 656 | + } | |
| 657 | + | |
| 658 | + cstate->num_mixers = num_lm; | |
| 659 | +} | |
| 660 | + | |
| 627 | 661 | static int dpu_encoder_virt_atomic_check( |
| 628 | 662 | struct drm_encoder *drm_enc, |
| 629 | 663 | struct drm_crtc_state *crtc_state, |
| @@ -692,6 +726,9 @@ static int dpu_encoder_virt_atomic_check( · 62 unmodified lines | ||
| 692 | 726 | if (!crtc_state->active_changed || crtc_state->enable) |
| 693 | 727 | ret = dpu_rm_reserve(&dpu_kms->rm, global_state, |
| 694 | 728 | drm_enc, crtc_state, topology); |
| 729 | + if (!ret) | |
| 730 | + dpu_encoder_assign_crtc_resources(dpu_kms, drm_enc, | |
| 731 | + global_state, crtc_state); | |
| 695 | 732 | } |
| 696 | 733 | |
| 697 | 734 | trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags); |
| @@ -1093,14 +1130,11 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, · 395 unmodified lines | ||
| 1093 | 1130 | struct dpu_encoder_virt *dpu_enc; |
| 1094 | 1131 | struct msm_drm_private *priv; |
| 1095 | 1132 | struct dpu_kms *dpu_kms; |
| 1096 | − struct dpu_crtc_state *cstate; | |
| 1097 | 1133 | struct dpu_global_state *global_state; |
| 1098 | 1134 | struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC]; |
| 1099 | 1135 | struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC]; |
| 1100 | − struct dpu_hw_blk *hw_lm[MAX_CHANNELS_PER_ENC]; | |
| 1101 | − struct dpu_hw_blk *hw_dspp[MAX_CHANNELS_PER_ENC] = { NULL }; | |
| 1102 | 1136 | struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC]; |
| 1103 | − int num_lm, num_ctl, num_pp, num_dsc; | |
| 1137 | + int num_ctl, num_pp, num_dsc; | |
| 1104 | 1138 | unsigned int dsc_mask = 0; |
| 1105 | 1139 | int i; |
| 1106 | 1140 | |
| @@ -1129,11 +1163,6 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, · 22 unmodified lines | ||
| 1129 | 1163 | ARRAY_SIZE(hw_pp)); |
| 1130 | 1164 | num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, |
| 1131 | 1165 | drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); |
| 1132 | − num_lm = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, | |
| 1133 | − drm_enc->base.id, DPU_HW_BLK_LM, hw_lm, ARRAY_SIZE(hw_lm)); | |
| 1134 | − dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, | |
| 1135 | − drm_enc->base.id, DPU_HW_BLK_DSPP, hw_dspp, | |
| 1136 | − ARRAY_SIZE(hw_dspp)); | |
| 1137 | 1166 | |
| 1138 | 1167 | for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) |
| 1139 | 1168 | dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i]) |
| @@ -1159,36 +1188,23 @@ static void dpu_encoder_virt_atomic_mode_set(struct drm_encoder *drm_enc, · 19 unmodified lines | ||
| 1159 | 1188 | dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL; |
| 1160 | 1189 | } |
| 1161 | 1190 | |
| 1162 | − cstate = to_dpu_crtc_state(crtc_state); | |
| 1163 | − | |
| 1164 | − for (i = 0; i < num_lm; i++) { | |
| 1165 | − int ctl_idx = (i < num_ctl) ? i : (num_ctl-1); | |
| 1166 | − | |
| 1167 | − cstate->mixers[i].hw_lm = to_dpu_hw_mixer(hw_lm[i]); | |
| 1168 | − cstate->mixers[i].lm_ctl = to_dpu_hw_ctl(hw_ctl[ctl_idx]); | |
| 1169 | − cstate->mixers[i].hw_dspp = to_dpu_hw_dspp(hw_dspp[i]); | |
| 1170 | − } | |
| 1171 | − | |
| 1172 | − cstate->num_mixers = num_lm; | |
| 1173 | − | |
| 1174 | 1191 | for (i = 0; i < dpu_enc->num_phys_encs; i++) { |
| 1175 | 1192 | struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; |
| 1176 | 1193 | |
| 1177 | − if (!dpu_enc->hw_pp[i]) { | |
| 1194 | + phys->hw_pp = dpu_enc->hw_pp[i]; | |
| 1195 | + if (!phys->hw_pp) { | |
| 1178 | 1196 | DPU_ERROR_ENC(dpu_enc, |
| 1179 | 1197 | "no pp block assigned at idx: %d\n", i); |
| 1180 | 1198 | return; |
| 1181 | 1199 | } |
| 1182 | 1200 | |
| 1183 | − if (!hw_ctl[i]) { | |
| 1201 | + phys->hw_ctl = i < num_ctl ? to_dpu_hw_ctl(hw_ctl[i]) : NULL; | |
| 1202 | + if (!phys->hw_ctl) { | |
| 1184 | 1203 | DPU_ERROR_ENC(dpu_enc, |
| 1185 | 1204 | "no ctl block assigned at idx: %d\n", i); |
| 1186 | 1205 | return; |
| 1187 | 1206 | } |
| 1188 | 1207 | |
| 1189 | − phys->hw_pp = dpu_enc->hw_pp[i]; | |
| 1190 | − phys->hw_ctl = to_dpu_hw_ctl(hw_ctl[i]); | |
| 1191 | − | |
| 1192 | 1208 | phys->cached_mode = crtc_state->adjusted_mode; |
| 1193 | 1209 | if (phys->ops.atomic_mode_set) |
| 1194 | 1210 | phys->ops.atomic_mode_set(phys, crtc_state, conn_state); |
| @@ -302,7 +302,7 @@ static void dpu_encoder_phys_vid_setup_timing_engine( · 301 unmodified lines | ||
| 302 | 302 | intf_cfg.stream_sel = 0; /* Don't care value for video mode */ |
| 303 | 303 | intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); |
| 304 | 304 | intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc); |
| 305 | − if (phys_enc->hw_pp->merge_3d) | |
| 305 | + if (intf_cfg.mode_3d && phys_enc->hw_pp->merge_3d) | |
| 306 | 306 | intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; |
| 307 | 307 | |
| 308 | 308 | spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); |
| @@ -440,10 +440,12 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) · 131 unmodified lines | ||
| 440 | 440 | struct dpu_hw_ctl *ctl; |
| 441 | 441 | const struct msm_format *fmt; |
| 442 | 442 | u32 fmt_fourcc; |
| 443 | + u32 mode_3d; | |
| 443 | 444 | |
| 444 | 445 | ctl = phys_enc->hw_ctl; |
| 445 | 446 | fmt_fourcc = dpu_encoder_get_drm_fmt(phys_enc); |
| 446 | 447 | fmt = mdp_get_format(&phys_enc->dpu_kms->base, fmt_fourcc, 0); |
| 448 | + mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); | |
| 447 | 449 | |
| 448 | 450 | DPU_DEBUG_VIDENC(phys_enc, "\n"); |
| 449 | 451 | |
| @@ -466,7 +468,8 @@ static void dpu_encoder_phys_vid_enable(struct dpu_encoder_phys *phys_enc) · 16 unmodified lines | ||
| 466 | 468 | goto skip_flush; |
| 467 | 469 | |
| 468 | 470 | ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx); |
| 469 | − if (ctl->ops.update_pending_flush_merge_3d && phys_enc->hw_pp->merge_3d) | |
| 471 | + if (mode_3d && ctl->ops.update_pending_flush_merge_3d && | |
| 472 | + phys_enc->hw_pp->merge_3d) | |
| 470 | 473 | ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx); |
| 471 | 474 | |
| 472 | 475 | if (ctl->ops.update_pending_flush_cdm && phys_enc->hw_cdm) |
| @@ -275,6 +275,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) · 274 unmodified lines | ||
| 275 | 275 | struct dpu_hw_pingpong *hw_pp; |
| 276 | 276 | struct dpu_hw_cdm *hw_cdm; |
| 277 | 277 | u32 pending_flush = 0; |
| 278 | + u32 mode_3d; | |
| 278 | 279 | |
| 279 | 280 | if (!phys_enc) |
| 280 | 281 | return; |
| @@ -283,6 +284,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) · 2 unmodified lines | ||
| 283 | 284 | hw_pp = phys_enc->hw_pp; |
| 284 | 285 | hw_ctl = phys_enc->hw_ctl; |
| 285 | 286 | hw_cdm = phys_enc->hw_cdm; |
| 287 | + mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); | |
| 286 | 288 | |
| 287 | 289 | DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0); |
| 288 | 290 | |
| @@ -294,7 +296,8 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) · 5 unmodified lines | ||
| 294 | 296 | if (hw_ctl->ops.update_pending_flush_wb) |
| 295 | 297 | hw_ctl->ops.update_pending_flush_wb(hw_ctl, hw_wb->idx); |
| 296 | 298 | |
| 297 | − if (hw_ctl->ops.update_pending_flush_merge_3d && hw_pp && hw_pp->merge_3d) | |
| 299 | + if (mode_3d && hw_ctl->ops.update_pending_flush_merge_3d && | |
| 300 | + hw_pp && hw_pp->merge_3d) | |
| 298 | 301 | hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl, |
| 299 | 302 | hw_pp->merge_3d->idx); |
| 300 | 303 | |
| @@ -26,7 +26,7 @@ static void msm_disp_state_dump_regs(u32 **reg, u32 aligned_len, void __iomem *b · 25 unmodified lines | ||
| 26 | 26 | end_addr = base_addr + aligned_len; |
| 27 | 27 | |
| 28 | 28 | if (!(*reg)) |
| 29 | − *reg = kzalloc(len_padded, GFP_KERNEL); | |
| 29 | + *reg = kvzalloc(len_padded, GFP_KERNEL); | |
| 30 | 30 | |
| 31 | 31 | if (*reg) |
| 32 | 32 | dump_addr = *reg; |
| @@ -48,20 +48,21 @@ static void msm_disp_state_dump_regs(u32 **reg, u32 aligned_len, void __iomem *b · 15 unmodified lines | ||
| 48 | 48 | } |
| 49 | 49 | } |
| 50 | 50 | |
| 51 | −static void msm_disp_state_print_regs(u32 **reg, u32 len, void __iomem *base_addr, | |
| 52 | − struct drm_printer *p) | |
| 51 | +static void msm_disp_state_print_regs(const u32 *dump_addr, u32 len, | |
| 52 | + void __iomem *base_addr, struct drm_printer *p) | |
| 53 | 53 | { |
| 54 | 54 | int i; |
| 55 | − u32 *dump_addr = NULL; | |
| 56 | 55 | void __iomem *addr; |
| 57 | 56 | u32 num_rows; |
| 58 | 57 | |
| 58 | + if (!dump_addr) { | |
| 59 | + drm_printf(p, "Registers not stored\n"); | |
| 60 | + return; | |
| 61 | + } | |
| 62 | + | |
| 59 | 63 | addr = base_addr; |
| 60 | 64 | num_rows = len / REG_DUMP_ALIGN; |
| 61 | 65 | |
| 62 | − if (*reg) | |
| 63 | − dump_addr = *reg; | |
| 64 | − | |
| 65 | 66 | for (i = 0; i < num_rows; i++) { |
| 66 | 67 | drm_printf(p, "0x%lx : %08x %08x %08x %08x\n", |
| 67 | 68 | (unsigned long)(addr - base_addr), |
| @@ -89,7 +90,7 @@ void msm_disp_state_print(struct msm_disp_state *state, struct drm_printer *p) · 21 unmodified lines | ||
| 89 | 90 | |
| 90 | 91 | list_for_each_entry_safe(block, tmp, &state->blocks, node) { |
| 91 | 92 | drm_printf(p, "====================%s================\n", block->name); |
| 92 | − msm_disp_state_print_regs(&block->state, block->size, block->base_addr, p); | |
| 93 | + msm_disp_state_print_regs(block->state, block->size, block->base_addr, p); | |
| 93 | 94 | } |
| 94 | 95 | |
| 95 | 96 | drm_printf(p, "===================dpu drm state================\n"); |
| @@ -161,7 +162,7 @@ void msm_disp_state_free(void *data) · 65 unmodified lines | ||
| 161 | 162 | |
| 162 | 163 | list_for_each_entry_safe(block, tmp, &disp_state->blocks, node) { |
| 163 | 164 | list_del(&block->node); |
| 164 | − kfree(block->state); | |
| 165 | + kvfree(block->state); | |
| 165 | 166 | kfree(block); |
| 166 | 167 | } |
| 167 | 168 | |
| @@ -542,7 +542,7 @@ static unsigned long dsi_adjust_pclk_for_compression(const struct drm_display_mo · 541 unmodified lines | ||
| 542 | 542 | |
| 543 | 543 | int new_htotal = mode->htotal - mode->hdisplay + new_hdisplay; |
| 544 | 544 | |
| 545 | − return new_htotal * mode->vtotal * drm_mode_vrefresh(mode); | |
| 545 | + return mult_frac(mode->clock * 1000u, new_htotal, mode->htotal); | |
| 546 | 546 | } |
| 547 | 547 | |
| 548 | 548 | static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, |
| @@ -550,7 +550,7 @@ static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, · 1 unmodified line | ||
| 550 | 550 | { |
| 551 | 551 | unsigned long pclk_rate; |
| 552 | 552 | |
| 553 | − pclk_rate = mode->clock * 1000; | |
| 553 | + pclk_rate = mode->clock * 1000u; | |
| 554 | 554 | |
| 555 | 555 | if (dsc) |
| 556 | 556 | pclk_rate = dsi_adjust_pclk_for_compression(mode, dsc); |
| @@ -153,15 +153,6 @@ static inline u32 pll_get_pll_cmp(u64 fdata, unsigned long ref_clk) · 152 unmodified lines | ||
| 153 | 153 | return dividend - 1; |
| 154 | 154 | } |
| 155 | 155 | |
| 156 | −static inline u64 pll_cmp_to_fdata(u32 pll_cmp, unsigned long ref_clk) | |
| 157 | −{ | |
| 158 | − u64 fdata = ((u64)pll_cmp) * ref_clk * 10; | |
| 159 | − | |
| 160 | − do_div(fdata, HDMI_PLL_CMP_CNT); | |
| 161 | − | |
| 162 | − return fdata; | |
| 163 | −} | |
| 164 | − | |
| 165 | 156 | #define HDMI_REF_CLOCK_HZ ((u64)19200000) |
| 166 | 157 | #define HDMI_MHZ_TO_HZ ((u64)1000000) |
| 167 | 158 | static int pll_get_post_div(struct hdmi_8998_post_divider *pd, u64 bclk) |
| @@ -210,7 +210,7 @@ struct nvkm_gsp { · 209 unmodified lines | ||
| 210 | 210 | } *rm; |
| 211 | 211 | |
| 212 | 212 | struct { |
| 213 | − struct mutex mutex;; | |
| 213 | + struct mutex mutex; | |
| 214 | 214 | struct idr idr; |
| 215 | 215 | } client_id; |
| 216 | 216 | |
| @@ -193,7 +193,7 @@ static vm_fault_t nouveau_dmem_migrate_to_ram(struct vm_fault *vmf) · 192 unmodified lines | ||
| 193 | 193 | if (!spage || !(src & MIGRATE_PFN_MIGRATE)) |
| 194 | 194 | goto done; |
| 195 | 195 | |
| 196 | − dpage = alloc_page_vma(GFP_HIGHUSER, vmf->vma, vmf->address); | |
| 196 | + dpage = alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vmf->vma, vmf->address); | |
| 197 | 197 | if (!dpage) |
| 198 | 198 | goto done; |
| 199 | 199 | |
| @@ -332,7 +332,7 @@ nouveau_accel_ce_init(struct nouveau_drm *drm) · 331 unmodified lines | ||
| 332 | 332 | return; |
| 333 | 333 | } |
| 334 | 334 | |
| 335 | − ret = nouveau_channel_new(&drm->client, false, runm, NvDmaFB, NvDmaTT, &drm->cechan); | |
| 335 | + ret = nouveau_channel_new(&drm->client, true, runm, NvDmaFB, NvDmaTT, &drm->cechan); | |
| 336 | 336 | if (ret) |
| 337 | 337 | NV_ERROR(drm, "failed to create ce channel, %d\n", ret); |
| 338 | 338 | } |
| @@ -298,7 +298,7 @@ static int ivo_t109nw41_init(struct hx83102 *ctx) · 297 unmodified lines | ||
| 298 | 298 | msleep(60); |
| 299 | 299 | |
| 300 | 300 | hx83102_enable_extended_cmds(&dsi_ctx, true); |
| 301 | − mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPOWER, 0x2c, 0xed, 0xed, 0x0f, 0xcf, 0x42, | |
| 301 | + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETPOWER, 0x2c, 0xed, 0xed, 0x27, 0xe7, 0x52, | |
| 302 | 302 | 0xf5, 0x39, 0x36, 0x36, 0x36, 0x36, 0x32, 0x8b, 0x11, 0x65, 0x00, 0x88, |
| 303 | 303 | 0xfa, 0xff, 0xff, 0x8f, 0xff, 0x08, 0xd6, 0x33); |
| 304 | 304 | mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETDISP, 0x00, 0x47, 0xb0, 0x80, 0x00, 0x12, |
| @@ -343,11 +343,11 @@ static int ivo_t109nw41_init(struct hx83102 *ctx) · 38 unmodified lines | ||
| 343 | 343 | 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 344 | 344 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 345 | 345 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
| 346 | − mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGMA, 0x04, 0x04, 0x06, 0x0a, 0x0a, 0x05, | |
| 347 | − 0x12, 0x14, 0x17, 0x13, 0x2c, 0x33, 0x39, 0x4b, 0x4c, 0x56, 0x61, 0x78, | |
| 348 | − 0x7a, 0x41, 0x50, 0x68, 0x73, 0x04, 0x04, 0x06, 0x0a, 0x0a, 0x05, 0x12, | |
| 349 | − 0x14, 0x17, 0x13, 0x2c, 0x33, 0x39, 0x4b, 0x4c, 0x56, 0x61, 0x78, 0x7a, | |
| 350 | − 0x41, 0x50, 0x68, 0x73); | |
| 346 | + mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGMA, 0x00, 0x07, 0x10, 0x17, 0x1c, 0x33, | |
| 347 | + 0x48, 0x50, 0x57, 0x50, 0x68, 0x6e, 0x71, 0x7f, 0x81, 0x8a, 0x8e, 0x9b, | |
| 348 | + 0x9c, 0x4d, 0x56, 0x5d, 0x73, 0x00, 0x07, 0x10, 0x17, 0x1c, 0x33, 0x48, | |
| 349 | + 0x50, 0x57, 0x50, 0x68, 0x6e, 0x71, 0x7f, 0x81, 0x8a, 0x8e, 0x9b, 0x9c, | |
| 350 | + 0x4d, 0x56, 0x5d, 0x73); | |
| 351 | 351 | mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0x07, 0x10, 0x10, 0x1a, 0x26, 0x9e, |
| 352 | 352 | 0x00, 0x4f, 0xa0, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x12, 0x0a, 0x02, |
| 353 | 353 | 0x02, 0x00, 0x33, 0x02, 0x04, 0x18, 0x01); |
| @@ -500,6 +500,7 @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev, · 499 unmodified lines | ||
| 500 | 500 | struct panthor_fw_binary_iter *iter, |
| 501 | 501 | u32 ehdr) |
| 502 | 502 | { |
| 503 | + ssize_t vm_pgsz = panthor_vm_page_size(ptdev->fw->vm); | |
| 503 | 504 | struct panthor_fw_binary_section_entry_hdr hdr; |
| 504 | 505 | struct panthor_fw_section *section; |
| 505 | 506 | u32 section_size; |
| @@ -528,8 +529,7 @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev, · 22 unmodified lines | ||
| 528 | 529 | return -EINVAL; |
| 529 | 530 | } |
| 530 | 531 | |
| 531 | − if ((hdr.va.start & ~PAGE_MASK) != 0 || | |
| 532 | − (hdr.va.end & ~PAGE_MASK) != 0) { | |
| 532 | + if (!IS_ALIGNED(hdr.va.start, vm_pgsz) || !IS_ALIGNED(hdr.va.end, vm_pgsz)) { | |
| 533 | 533 | drm_err(&ptdev->base, "Firmware corrupted, virtual addresses not page aligned: 0x%x-0x%x\n", |
| 534 | 534 | hdr.va.start, hdr.va.end); |
| 535 | 535 | return -EINVAL; |
| @@ -44,8 +44,7 @@ void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo) · 43 unmodified lines | ||
| 44 | 44 | to_panthor_bo(bo->obj)->exclusive_vm_root_gem != panthor_vm_root_gem(vm))) |
| 45 | 45 | goto out_free_bo; |
| 46 | 46 | |
| 47 | − ret = panthor_vm_unmap_range(vm, bo->va_node.start, | |
| 48 | − panthor_kernel_bo_size(bo)); | |
| 47 | + ret = panthor_vm_unmap_range(vm, bo->va_node.start, bo->va_node.size); | |
| 49 | 48 | if (ret) |
| 50 | 49 | goto out_free_bo; |
| 51 | 50 | |
| @@ -95,10 +94,16 @@ panthor_kernel_bo_create(struct panthor_device *ptdev, struct panthor_vm *vm, · 43 unmodified lines | ||
| 95 | 94 | } |
| 96 | 95 | |
| 97 | 96 | bo = to_panthor_bo(&obj->base); |
| 98 | − size = obj->base.size; | |
| 99 | 97 | kbo->obj = &obj->base; |
| 100 | 98 | bo->flags = bo_flags; |
| 101 | 99 | |
| 100 | + /* The system and GPU MMU page size might differ, which becomes a | |
| 101 | + * problem for FW sections that need to be mapped at explicit address | |
| 102 | + * since our PAGE_SIZE alignment might cover a VA range that's | |
| 103 | + * expected to be used for another section. | |
| 104 | + * Make sure we never map more than we need. | |
| 105 | + */ | |
| 106 | + size = ALIGN(size, panthor_vm_page_size(vm)); | |
| 102 | 107 | ret = panthor_vm_alloc_va(vm, gpu_va, size, &kbo->va_node); |
| 103 | 108 | if (ret) |
| 104 | 109 | goto err_put_obj; |
| @@ -826,6 +826,14 @@ void panthor_vm_idle(struct panthor_vm *vm) · 825 unmodified lines | ||
| 826 | 826 | mutex_unlock(&ptdev->mmu->as.slots_lock); |
| 827 | 827 | } |
| 828 | 828 | |
| 829 | +u32 panthor_vm_page_size(struct panthor_vm *vm) | |
| 830 | +{ | |
| 831 | + const struct io_pgtable *pgt = io_pgtable_ops_to_pgtable(vm->pgtbl_ops); | |
| 832 | + u32 pg_shift = ffs(pgt->cfg.pgsize_bitmap) - 1; | |
| 833 | + | |
| 834 | + return 1u << pg_shift; | |
| 835 | +} | |
| 836 | + | |
| 829 | 837 | static void panthor_vm_stop(struct panthor_vm *vm) |
| 830 | 838 | { |
| 831 | 839 | drm_sched_stop(&vm->sched, NULL); |
| @@ -1025,12 +1033,13 @@ int · 193 unmodified lines | ||
| 1025 | 1033 | panthor_vm_alloc_va(struct panthor_vm *vm, u64 va, u64 size, |
| 1026 | 1034 | struct drm_mm_node *va_node) |
| 1027 | 1035 | { |
| 1036 | + ssize_t vm_pgsz = panthor_vm_page_size(vm); | |
| 1028 | 1037 | int ret; |
| 1029 | 1038 | |
| 1030 | − if (!size || (size & ~PAGE_MASK)) | |
| 1039 | + if (!size || !IS_ALIGNED(size, vm_pgsz)) | |
| 1031 | 1040 | return -EINVAL; |
| 1032 | 1041 | |
| 1033 | − if (va != PANTHOR_VM_KERNEL_AUTO_VA && (va & ~PAGE_MASK)) | |
| 1042 | + if (va != PANTHOR_VM_KERNEL_AUTO_VA && !IS_ALIGNED(va, vm_pgsz)) | |
| 1034 | 1043 | return -EINVAL; |
| 1035 | 1044 | |
| 1036 | 1045 | mutex_lock(&vm->mm_lock); |
| @@ -2366,11 +2375,12 @@ panthor_vm_bind_prepare_op_ctx(struct drm_file *file, · 1329 unmodified lines | ||
| 2366 | 2375 | const struct drm_panthor_vm_bind_op *op, |
| 2367 | 2376 | struct panthor_vm_op_ctx *op_ctx) |
| 2368 | 2377 | { |
| 2378 | + ssize_t vm_pgsz = panthor_vm_page_size(vm); | |
| 2369 | 2379 | struct drm_gem_object *gem; |
| 2370 | 2380 | int ret; |
| 2371 | 2381 | |
| 2372 | 2382 | /* Aligned on page size. */ |
| 2373 | − if ((op->va | op->size) & ~PAGE_MASK) | |
| 2383 | + if (!IS_ALIGNED(op->va | op->size, vm_pgsz)) | |
| 2374 | 2384 | return -EINVAL; |
| 2375 | 2385 | |
| 2376 | 2386 | switch (op->flags & DRM_PANTHOR_VM_BIND_OP_TYPE_MASK) { |
| @@ -30,6 +30,7 @@ panthor_vm_get_bo_for_va(struct panthor_vm *vm, u64 va, u64 *bo_offset); · 29 unmodified lines | ||
| 30 | 30 | |
| 31 | 31 | int panthor_vm_active(struct panthor_vm *vm); |
| 32 | 32 | void panthor_vm_idle(struct panthor_vm *vm); |
| 33 | +u32 panthor_vm_page_size(struct panthor_vm *vm); | |
| 33 | 34 | int panthor_vm_as(struct panthor_vm *vm); |
| 34 | 35 | int panthor_vm_flush_all(struct panthor_vm *vm); |
| 35 | 36 | |
| @@ -602,10 +602,11 @@ struct panthor_group { · 601 unmodified lines | ||
| 602 | 602 | * @timedout: True when a timeout occurred on any of the queues owned by |
| 603 | 603 | * this group. |
| 604 | 604 | * |
| 605 | − * Timeouts can be reported by drm_sched or by the FW. In any case, any | |
| 606 | − * timeout situation is unrecoverable, and the group becomes useless. | |
| 607 | − * We simply wait for all references to be dropped so we can release the | |
| 608 | − * group object. | |
| 605 | + * Timeouts can be reported by drm_sched or by the FW. If a reset is required, | |
| 606 | + * and the group can't be suspended, this also leads to a timeout. In any case, | |
| 607 | + * any timeout situation is unrecoverable, and the group becomes useless. We | |
| 608 | + * simply wait for all references to be dropped so we can release the group | |
| 609 | + * object. | |
| 609 | 610 | */ |
| 610 | 611 | bool timedout; |
| 611 | 612 | |
| @@ -2687,6 +2688,12 @@ void panthor_sched_suspend(struct panthor_device *ptdev) · 2075 unmodified lines | ||
| 2687 | 2688 | csgs_upd_ctx_init(&upd_ctx); |
| 2688 | 2689 | while (slot_mask) { |
| 2689 | 2690 | u32 csg_id = ffs(slot_mask) - 1; |
| 2691 | + struct panthor_csg_slot *csg_slot = &sched->csg_slots[csg_id]; | |
| 2692 | + | |
| 2693 | + /* We consider group suspension failures as fatal and flag the | |
| 2694 | + * group as unusable by setting timedout=true. | |
| 2695 | + */ | |
| 2696 | + csg_slot->group->timedout = true; | |
| 2690 | 2697 | |
| 2691 | 2698 | csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id, |
| 2692 | 2699 | CSG_STATE_TERMINATE, |
| @@ -3688,6 +3695,11 @@ panthor_job_create(struct panthor_file *pfile, · 995 unmodified lines | ||
| 3688 | 3695 | goto err_put_job; |
| 3689 | 3696 | } |
| 3690 | 3697 | |
| 3698 | + if (!group_can_run(job->group)) { | |
| 3699 | + ret = -EINVAL; | |
| 3700 | + goto err_put_job; | |
| 3701 | + } | |
| 3702 | + | |
| 3691 | 3703 | if (job->queue_idx >= job->group->queue_count || |
| 3692 | 3704 | !job->group->queues[job->queue_idx]) { |
| 3693 | 3705 | ret = -EINVAL; |
| @@ -87,6 +87,12 @@ · 86 unmodified lines | ||
| 87 | 87 | #define CREATE_TRACE_POINTS |
| 88 | 88 | #include "gpu_scheduler_trace.h" |
| 89 | 89 | |
| 90 | +#ifdef CONFIG_LOCKDEP | |
| 91 | +static struct lockdep_map drm_sched_lockdep_map = { | |
| 92 | + .name = "drm_sched_lockdep_map" | |
| 93 | +}; | |
| 94 | +#endif | |
| 95 | + | |
| 90 | 96 | #define to_drm_sched_job(sched_job) \ |
| 91 | 97 | container_of((sched_job), struct drm_sched_job, queue_node) |
| 92 | 98 | |
| @@ -1286,7 +1292,13 @@ int drm_sched_init(struct drm_gpu_scheduler *sched, · 1193 unmodified lines | ||
| 1286 | 1292 | sched->submit_wq = submit_wq; |
| 1287 | 1293 | sched->own_submit_wq = false; |
| 1288 | 1294 | } else { |
| 1289 | − sched->submit_wq = alloc_ordered_workqueue(name, 0); | |
| 1295 | +#ifdef CONFIG_LOCKDEP | |
| 1296 | + sched->submit_wq = alloc_ordered_workqueue_lockdep_map(name, | |
| 1297 | + WQ_MEM_RECLAIM, | |
| 1298 | + &drm_sched_lockdep_map); | |
| 1299 | +#else | |
| 1300 | + sched->submit_wq = alloc_ordered_workqueue(name, WQ_MEM_RECLAIM); | |
| 1301 | +#endif | |
| 1290 | 1302 | if (!sched->submit_wq) |
| 1291 | 1303 | return -ENOMEM; |
| 1292 | 1304 | |
| @@ -1156,8 +1156,8 @@ static int host1x_drm_probe(struct host1x_device *dev) · 1155 unmodified lines | ||
| 1156 | 1156 | |
| 1157 | 1157 | if (host1x_drm_wants_iommu(dev) && device_iommu_mapped(dma_dev)) { |
| 1158 | 1158 | tegra->domain = iommu_paging_domain_alloc(dma_dev); |
| 1159 | − if (!tegra->domain) { | |
| 1160 | − err = -ENOMEM; | |
| 1159 | + if (IS_ERR(tegra->domain)) { | |
| 1160 | + err = PTR_ERR(tegra->domain); | |
| 1161 | 1161 | goto free; |
| 1162 | 1162 | } |
| 1163 | 1163 | |
| @@ -996,7 +996,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb(struct kunit *test) · 995 unmodified lines | ||
| 996 | 996 | unsigned long long rate; |
| 997 | 997 | struct drm_device *drm = &priv->drm; |
| 998 | 998 | |
| 999 | − mode = drm_display_mode_from_cea_vic(drm, 16); | |
| 999 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); | |
| 1000 | 1000 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1001 | 1001 | |
| 1002 | 1002 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); |
| @@ -1017,7 +1017,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc(struct kunit *test) · 14 unmodified lines | ||
| 1017 | 1017 | unsigned long long rate; |
| 1018 | 1018 | struct drm_device *drm = &priv->drm; |
| 1019 | 1019 | |
| 1020 | − mode = drm_display_mode_from_cea_vic(drm, 16); | |
| 1020 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); | |
| 1021 | 1021 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1022 | 1022 | |
| 1023 | 1023 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); |
| @@ -1038,7 +1038,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb_10bpc_vic_1(struct kunit *t · 14 unmodified lines | ||
| 1038 | 1038 | unsigned long long rate; |
| 1039 | 1039 | struct drm_device *drm = &priv->drm; |
| 1040 | 1040 | |
| 1041 | − mode = drm_display_mode_from_cea_vic(drm, 1); | |
| 1041 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); | |
| 1042 | 1042 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1043 | 1043 | |
| 1044 | 1044 | rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB); |
| @@ -1056,7 +1056,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc(struct kunit *test) · 11 unmodified lines | ||
| 1056 | 1056 | unsigned long long rate; |
| 1057 | 1057 | struct drm_device *drm = &priv->drm; |
| 1058 | 1058 | |
| 1059 | − mode = drm_display_mode_from_cea_vic(drm, 16); | |
| 1059 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); | |
| 1060 | 1060 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1061 | 1061 | |
| 1062 | 1062 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); |
| @@ -1077,7 +1077,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb_12bpc_vic_1(struct kunit *t · 14 unmodified lines | ||
| 1077 | 1077 | unsigned long long rate; |
| 1078 | 1078 | struct drm_device *drm = &priv->drm; |
| 1079 | 1079 | |
| 1080 | − mode = drm_display_mode_from_cea_vic(drm, 1); | |
| 1080 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); | |
| 1081 | 1081 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1082 | 1082 | |
| 1083 | 1083 | rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB); |
| @@ -1095,7 +1095,7 @@ static void drm_test_drm_hdmi_compute_mode_clock_rgb_double(struct kunit *test) · 11 unmodified lines | ||
| 1095 | 1095 | unsigned long long rate; |
| 1096 | 1096 | struct drm_device *drm = &priv->drm; |
| 1097 | 1097 | |
| 1098 | − mode = drm_display_mode_from_cea_vic(drm, 6); | |
| 1098 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, 6); | |
| 1099 | 1099 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1100 | 1100 | |
| 1101 | 1101 | KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); |
| @@ -1118,7 +1118,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv420_valid(struct kunit · 16 unmodified lines | ||
| 1118 | 1118 | unsigned long long rate; |
| 1119 | 1119 | unsigned int vic = *(unsigned int *)test->param_value; |
| 1120 | 1120 | |
| 1121 | − mode = drm_display_mode_from_cea_vic(drm, vic); | |
| 1121 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic); | |
| 1122 | 1122 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1123 | 1123 | |
| 1124 | 1124 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); |
| @@ -1155,7 +1155,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv420_10_bpc(struct kuni · 30 unmodified lines | ||
| 1155 | 1155 | drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; |
| 1156 | 1156 | unsigned long long rate; |
| 1157 | 1157 | |
| 1158 | − mode = drm_display_mode_from_cea_vic(drm, vic); | |
| 1158 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic); | |
| 1159 | 1159 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1160 | 1160 | |
| 1161 | 1161 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); |
| @@ -1180,7 +1180,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv420_12_bpc(struct kuni · 18 unmodified lines | ||
| 1180 | 1180 | drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; |
| 1181 | 1181 | unsigned long long rate; |
| 1182 | 1182 | |
| 1183 | − mode = drm_display_mode_from_cea_vic(drm, vic); | |
| 1183 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, vic); | |
| 1184 | 1184 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1185 | 1185 | |
| 1186 | 1186 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); |
| @@ -1203,7 +1203,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv422_8_bpc(struct kunit · 16 unmodified lines | ||
| 1203 | 1203 | struct drm_device *drm = &priv->drm; |
| 1204 | 1204 | unsigned long long rate; |
| 1205 | 1205 | |
| 1206 | − mode = drm_display_mode_from_cea_vic(drm, 16); | |
| 1206 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); | |
| 1207 | 1207 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1208 | 1208 | |
| 1209 | 1209 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); |
| @@ -1225,7 +1225,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv422_10_bpc(struct kuni · 15 unmodified lines | ||
| 1225 | 1225 | struct drm_device *drm = &priv->drm; |
| 1226 | 1226 | unsigned long long rate; |
| 1227 | 1227 | |
| 1228 | − mode = drm_display_mode_from_cea_vic(drm, 16); | |
| 1228 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); | |
| 1229 | 1229 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1230 | 1230 | |
| 1231 | 1231 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); |
| @@ -1247,7 +1247,7 @@ static void drm_test_connector_hdmi_compute_mode_clock_yuv422_12_bpc(struct kuni · 15 unmodified lines | ||
| 1247 | 1247 | struct drm_device *drm = &priv->drm; |
| 1248 | 1248 | unsigned long long rate; |
| 1249 | 1249 | |
| 1250 | − mode = drm_display_mode_from_cea_vic(drm, 16); | |
| 1250 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, 16); | |
| 1251 | 1251 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1252 | 1252 | |
| 1253 | 1253 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); |
| @@ -441,7 +441,7 @@ static void drm_test_check_broadcast_rgb_auto_cea_mode_vic_1(struct kunit *test) · 440 unmodified lines | ||
| 441 | 441 | ctx = drm_kunit_helper_acquire_ctx_alloc(test); |
| 442 | 442 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); |
| 443 | 443 | |
| 444 | − mode = drm_display_mode_from_cea_vic(drm, 1); | |
| 444 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); | |
| 445 | 445 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 446 | 446 | |
| 447 | 447 | drm = &priv->drm; |
| @@ -555,7 +555,7 @@ static void drm_test_check_broadcast_rgb_full_cea_mode_vic_1(struct kunit *test) · 107 unmodified lines | ||
| 555 | 555 | ctx = drm_kunit_helper_acquire_ctx_alloc(test); |
| 556 | 556 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); |
| 557 | 557 | |
| 558 | − mode = drm_display_mode_from_cea_vic(drm, 1); | |
| 558 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); | |
| 559 | 559 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 560 | 560 | |
| 561 | 561 | drm = &priv->drm; |
| @@ -671,7 +671,7 @@ static void drm_test_check_broadcast_rgb_limited_cea_mode_vic_1(struct kunit *te · 109 unmodified lines | ||
| 671 | 671 | ctx = drm_kunit_helper_acquire_ctx_alloc(test); |
| 672 | 672 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); |
| 673 | 673 | |
| 674 | − mode = drm_display_mode_from_cea_vic(drm, 1); | |
| 674 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); | |
| 675 | 675 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 676 | 676 | |
| 677 | 677 | drm = &priv->drm; |
| @@ -1263,7 +1263,7 @@ static void drm_test_check_output_bpc_format_vic_1(struct kunit *test) · 585 unmodified lines | ||
| 1263 | 1263 | ctx = drm_kunit_helper_acquire_ctx_alloc(test); |
| 1264 | 1264 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); |
| 1265 | 1265 | |
| 1266 | − mode = drm_display_mode_from_cea_vic(drm, 1); | |
| 1266 | + mode = drm_kunit_display_mode_from_cea_vic(test, drm, 1); | |
| 1267 | 1267 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1268 | 1268 | |
| 1269 | 1269 | /* |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | ||
| 3 | 3 | #include <drm/drm_atomic.h> |
| 4 | 4 | #include <drm/drm_atomic_helper.h> |
| 5 | 5 | #include <drm/drm_drv.h> |
| 6 | +#include <drm/drm_edid.h> | |
| 6 | 7 | #include <drm/drm_fourcc.h> |
| 7 | 8 | #include <drm/drm_kunit_helpers.h> |
| 8 | 9 | #include <drm/drm_managed.h> |
| @@ -311,6 +312,47 @@ drm_kunit_helper_create_crtc(struct kunit *test, · 302 unmodified lines | ||
| 311 | 312 | } |
| 312 | 313 | EXPORT_SYMBOL_GPL(drm_kunit_helper_create_crtc); |
| 313 | 314 | |
| 315 | +static void kunit_action_drm_mode_destroy(void *ptr) | |
| 316 | +{ | |
| 317 | + struct drm_display_mode *mode = ptr; | |
| 318 | + | |
| 319 | + drm_mode_destroy(NULL, mode); | |
| 320 | +} | |
| 321 | + | |
| 322 | +/** | |
| 323 | + * drm_kunit_display_mode_from_cea_vic() - return a mode for CEA VIC | |
| 324 | + for a KUnit test | |
| 325 | + * @test: The test context object | |
| 326 | + * @dev: DRM device | |
| 327 | + * @video_code: CEA VIC of the mode | |
| 328 | + * | |
| 329 | + * Creates a new mode matching the specified CEA VIC for a KUnit test. | |
| 330 | + * | |
| 331 | + * Resources will be cleaned up automatically. | |
| 332 | + * | |
| 333 | + * Returns: A new drm_display_mode on success or NULL on failure | |
| 334 | + */ | |
| 335 | +struct drm_display_mode * | |
| 336 | +drm_kunit_display_mode_from_cea_vic(struct kunit *test, struct drm_device *dev, | |
| 337 | + u8 video_code) | |
| 338 | +{ | |
| 339 | + struct drm_display_mode *mode; | |
| 340 | + int ret; | |
| 341 | + | |
| 342 | + mode = drm_display_mode_from_cea_vic(dev, video_code); | |
| 343 | + if (!mode) | |
| 344 | + return NULL; | |
| 345 | + | |
| 346 | + ret = kunit_add_action_or_reset(test, | |
| 347 | + kunit_action_drm_mode_destroy, | |
| 348 | + mode); | |
| 349 | + if (ret) | |
| 350 | + return NULL; | |
| 351 | + | |
| 352 | + return mode; | |
| 353 | +} | |
| 354 | +EXPORT_SYMBOL_GPL(drm_kunit_display_mode_from_cea_vic); | |
| 355 | + | |
| 314 | 356 | MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>"); |
| 315 | 357 | MODULE_DESCRIPTION("KUnit test suite helper functions"); |
| 316 | 358 | MODULE_LICENSE("GPL"); |
| @@ -306,6 +306,11 @@ void v3d_perfmon_open_file(struct v3d_file_priv *v3d_priv) · 305 unmodified lines | ||
| 306 | 306 | static int v3d_perfmon_idr_del(int id, void *elem, void *data) |
| 307 | 307 | { |
| 308 | 308 | struct v3d_perfmon *perfmon = elem; |
| 309 | + struct v3d_dev *v3d = (struct v3d_dev *)data; | |
| 310 | + | |
| 311 | + /* If the active perfmon is being destroyed, stop it first */ | |
| 312 | + if (perfmon == v3d->active_perfmon) | |
| 313 | + v3d_perfmon_stop(v3d, perfmon, false); | |
| 309 | 314 | |
| 310 | 315 | v3d_perfmon_put(perfmon); |
| 311 | 316 | |
| @@ -314,8 +319,10 @@ static int v3d_perfmon_idr_del(int id, void *elem, void *data) · 2 unmodified lines | ||
| 314 | 319 | |
| 315 | 320 | void v3d_perfmon_close_file(struct v3d_file_priv *v3d_priv) |
| 316 | 321 | { |
| 322 | + struct v3d_dev *v3d = v3d_priv->v3d; | |
| 323 | + | |
| 317 | 324 | mutex_lock(&v3d_priv->perfmon.lock); |
| 318 | − idr_for_each(&v3d_priv->perfmon.idr, v3d_perfmon_idr_del, NULL); | |
| 325 | + idr_for_each(&v3d_priv->perfmon.idr, v3d_perfmon_idr_del, v3d); | |
| 319 | 326 | idr_destroy(&v3d_priv->perfmon.idr); |
| 320 | 327 | mutex_unlock(&v3d_priv->perfmon.lock); |
| 321 | 328 | mutex_destroy(&v3d_priv->perfmon.lock); |
| @@ -116,6 +116,11 @@ void vc4_perfmon_open_file(struct vc4_file *vc4file) · 115 unmodified lines | ||
| 116 | 116 | static int vc4_perfmon_idr_del(int id, void *elem, void *data) |
| 117 | 117 | { |
| 118 | 118 | struct vc4_perfmon *perfmon = elem; |
| 119 | + struct vc4_dev *vc4 = (struct vc4_dev *)data; | |
| 120 | + | |
| 121 | + /* If the active perfmon is being destroyed, stop it first */ | |
| 122 | + if (perfmon == vc4->active_perfmon) | |
| 123 | + vc4_perfmon_stop(vc4, perfmon, false); | |
| 119 | 124 | |
| 120 | 125 | vc4_perfmon_put(perfmon); |
| 121 | 126 | |
| @@ -130,7 +135,7 @@ void vc4_perfmon_close_file(struct vc4_file *vc4file) · 8 unmodified lines | ||
| 130 | 135 | return; |
| 131 | 136 | |
| 132 | 137 | mutex_lock(&vc4file->perfmon.lock); |
| 133 | − idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, NULL); | |
| 138 | + idr_for_each(&vc4file->perfmon.idr, vc4_perfmon_idr_del, vc4); | |
| 134 | 139 | idr_destroy(&vc4file->perfmon.idr); |
| 135 | 140 | mutex_unlock(&vc4file->perfmon.lock); |
| 136 | 141 | mutex_destroy(&vc4file->perfmon.lock); |
| @@ -635,10 +635,8 @@ out: · 634 unmodified lines | ||
| 635 | 635 | kunmap_atomic(d.src_addr); |
| 636 | 636 | if (d.dst_addr) |
| 637 | 637 | kunmap_atomic(d.dst_addr); |
| 638 | − if (src_pages) | |
| 639 | − kvfree(src_pages); | |
| 640 | − if (dst_pages) | |
| 641 | − kvfree(dst_pages); | |
| 638 | + kvfree(src_pages); | |
| 639 | + kvfree(dst_pages); | |
| 642 | 640 | |
| 643 | 641 | return ret; |
| 644 | 642 | } |
| @@ -62,7 +62,7 @@ · 61 unmodified lines | ||
| 62 | 62 | #define VMWGFX_DRIVER_MINOR 20 |
| 63 | 63 | #define VMWGFX_DRIVER_PATCHLEVEL 0 |
| 64 | 64 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) |
| 65 | −#define VMWGFX_MAX_DISPLAYS 16 | |
| 65 | +#define VMWGFX_NUM_DISPLAY_UNITS 8 | |
| 66 | 66 | #define VMWGFX_CMD_BOUNCE_INIT_SIZE 32768 |
| 67 | 67 | |
| 68 | 68 | #define VMWGFX_MIN_INITIAL_WIDTH 1280 |
| @@ -82,7 +82,7 @@ · 13 unmodified lines | ||
| 82 | 82 | #define VMWGFX_NUM_GB_CONTEXT 256 |
| 83 | 83 | #define VMWGFX_NUM_GB_SHADER 20000 |
| 84 | 84 | #define VMWGFX_NUM_GB_SURFACE 32768 |
| 85 | −#define VMWGFX_NUM_GB_SCREEN_TARGET VMWGFX_MAX_DISPLAYS | |
| 85 | +#define VMWGFX_NUM_GB_SCREEN_TARGET VMWGFX_NUM_DISPLAY_UNITS | |
| 86 | 86 | #define VMWGFX_NUM_DXCONTEXT 256 |
| 87 | 87 | #define VMWGFX_NUM_DXQUERY 512 |
| 88 | 88 | #define VMWGFX_NUM_MOB (VMWGFX_NUM_GB_CONTEXT +\ |
| @@ -1283,7 +1283,6 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, · 1282 unmodified lines | ||
| 1283 | 1283 | { |
| 1284 | 1284 | struct drm_device *dev = &dev_priv->drm; |
| 1285 | 1285 | struct vmw_framebuffer_surface *vfbs; |
| 1286 | − enum SVGA3dSurfaceFormat format; | |
| 1287 | 1286 | struct vmw_surface *surface; |
| 1288 | 1287 | int ret; |
| 1289 | 1288 | |
| @@ -1320,34 +1319,6 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, · 30 unmodified lines | ||
| 1320 | 1319 | return -EINVAL; |
| 1321 | 1320 | } |
| 1322 | 1321 | |
| 1323 | − switch (mode_cmd->pixel_format) { | |
| 1324 | − case DRM_FORMAT_ARGB8888: | |
| 1325 | − format = SVGA3D_A8R8G8B8; | |
| 1326 | − break; | |
| 1327 | − case DRM_FORMAT_XRGB8888: | |
| 1328 | − format = SVGA3D_X8R8G8B8; | |
| 1329 | − break; | |
| 1330 | − case DRM_FORMAT_RGB565: | |
| 1331 | − format = SVGA3D_R5G6B5; | |
| 1332 | − break; | |
| 1333 | − case DRM_FORMAT_XRGB1555: | |
| 1334 | − format = SVGA3D_A1R5G5B5; | |
| 1335 | − break; | |
| 1336 | − default: | |
| 1337 | − DRM_ERROR("Invalid pixel format: %p4cc\n", | |
| 1338 | − &mode_cmd->pixel_format); | |
| 1339 | − return -EINVAL; | |
| 1340 | − } | |
| 1341 | − | |
| 1342 | − /* | |
| 1343 | − * For DX, surface format validation is done when surface->scanout | |
| 1344 | − * is set. | |
| 1345 | − */ | |
| 1346 | − if (!has_sm4_context(dev_priv) && format != surface->metadata.format) { | |
| 1347 | − DRM_ERROR("Invalid surface format for requested mode.\n"); | |
| 1348 | − return -EINVAL; | |
| 1349 | − } | |
| 1350 | − | |
| 1351 | 1322 | vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL); |
| 1352 | 1323 | if (!vfbs) { |
| 1353 | 1324 | ret = -ENOMEM; |
| @@ -1539,6 +1510,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, · 185 unmodified lines | ||
| 1539 | 1510 | DRM_ERROR("Surface size cannot exceed %dx%d\n", |
| 1540 | 1511 | dev_priv->texture_max_width, |
| 1541 | 1512 | dev_priv->texture_max_height); |
| 1513 | + ret = -EINVAL; | |
| 1542 | 1514 | goto err_out; |
| 1543 | 1515 | } |
| 1544 | 1516 | |
| @@ -2225,7 +2197,7 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, · 680 unmodified lines | ||
| 2225 | 2197 | struct drm_mode_config *mode_config = &dev->mode_config; |
| 2226 | 2198 | struct drm_vmw_update_layout_arg *arg = |
| 2227 | 2199 | (struct drm_vmw_update_layout_arg *)data; |
| 2228 | − void __user *user_rects; | |
| 2200 | + const void __user *user_rects; | |
| 2229 | 2201 | struct drm_vmw_rect *rects; |
| 2230 | 2202 | struct drm_rect *drm_rects; |
| 2231 | 2203 | unsigned rects_size; |
| @@ -2237,6 +2209,8 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, · 5 unmodified lines | ||
| 2237 | 2209 | VMWGFX_MIN_INITIAL_HEIGHT}; |
| 2238 | 2210 | vmw_du_update_layout(dev_priv, 1, &def_rect); |
| 2239 | 2211 | return 0; |
| 2212 | + } else if (arg->num_outputs > VMWGFX_NUM_DISPLAY_UNITS) { | |
| 2213 | + return -E2BIG; | |
| 2240 | 2214 | } |
| 2241 | 2215 | |
| 2242 | 2216 | rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect); |
| @@ -199,9 +199,6 @@ struct vmw_kms_dirty { · 198 unmodified lines | ||
| 199 | 199 | s32 unit_y2; |
| 200 | 200 | }; |
| 201 | 201 | |
| 202 | −#define VMWGFX_NUM_DISPLAY_UNITS 8 | |
| 203 | − | |
| 204 | − | |
| 205 | 202 | #define vmw_framebuffer_to_vfb(x) \ |
| 206 | 203 | container_of(x, struct vmw_framebuffer, base) |
| 207 | 204 | #define vmw_framebuffer_to_vfbs(x) \ |
| @@ -886,6 +886,10 @@ static int vmw_stdu_connector_atomic_check(struct drm_connector *conn, · 885 unmodified lines | ||
| 886 | 886 | struct drm_crtc_state *new_crtc_state; |
| 887 | 887 | |
| 888 | 888 | conn_state = drm_atomic_get_connector_state(state, conn); |
| 889 | + | |
| 890 | + if (IS_ERR(conn_state)) | |
| 891 | + return PTR_ERR(conn_state); | |
| 892 | + | |
| 889 | 893 | du = vmw_connector_to_stdu(conn); |
| 890 | 894 | |
| 891 | 895 | if (!conn_state->crtc) |
| @@ -2276,9 +2276,12 @@ int vmw_dumb_create(struct drm_file *file_priv, · 2275 unmodified lines | ||
| 2276 | 2276 | const struct SVGA3dSurfaceDesc *desc = vmw_surface_get_desc(format); |
| 2277 | 2277 | SVGA3dSurfaceAllFlags flags = SVGA3D_SURFACE_HINT_TEXTURE | |
| 2278 | 2278 | SVGA3D_SURFACE_HINT_RENDERTARGET | |
| 2279 | − SVGA3D_SURFACE_SCREENTARGET | | |
| 2280 | − SVGA3D_SURFACE_BIND_SHADER_RESOURCE | | |
| 2281 | − SVGA3D_SURFACE_BIND_RENDER_TARGET; | |
| 2279 | + SVGA3D_SURFACE_SCREENTARGET; | |
| 2280 | + | |
| 2281 | + if (vmw_surface_is_dx_screen_target_format(format)) { | |
| 2282 | + flags |= SVGA3D_SURFACE_BIND_SHADER_RESOURCE | | |
| 2283 | + SVGA3D_SURFACE_BIND_RENDER_TARGET; | |
| 2284 | + } | |
| 2282 | 2285 | |
| 2283 | 2286 | /* |
| 2284 | 2287 | * Without mob support we're just going to use raw memory buffer |
| @@ -410,12 +410,6 @@ · 409 unmodified lines | ||
| 410 | 410 | |
| 411 | 411 | #define XE2LPM_SCRATCH3_LBCF XE_REG_MCR(0xb654) |
| 412 | 412 | |
| 413 | −#define XE2LPM_L3SQCREG2 XE_REG_MCR(0xb604) | |
| 414 | − | |
| 415 | −#define XE2LPM_L3SQCREG3 XE_REG_MCR(0xb608) | |
| 416 | − | |
| 417 | −#define XE2LPM_SCRATCH3_LBCF XE_REG_MCR(0xb654) | |
| 418 | − | |
| 419 | 413 | #define XE2LPM_L3SQCREG5 XE_REG_MCR(0xb658) |
| 420 | 414 | |
| 421 | 415 | #define XE2_TDF_CTRL XE_REG(0xb418) |
| @@ -115,9 +115,15 @@ static int __domain_wait(struct xe_gt *gt, struct xe_force_wake_domain *domain, · 114 unmodified lines | ||
| 115 | 115 | XE_FORCE_WAKE_ACK_TIMEOUT_MS * USEC_PER_MSEC, |
| 116 | 116 | &value, true); |
| 117 | 117 | if (ret) |
| 118 | − xe_gt_notice(gt, "Force wake domain %d failed to ack %s (%pe) reg[%#x] = %#x\n", | |
| 119 | − domain->id, str_wake_sleep(wake), ERR_PTR(ret), | |
| 120 | − domain->reg_ack.addr, value); | |
| 118 | + xe_gt_err(gt, "Force wake domain %d failed to ack %s (%pe) reg[%#x] = %#x\n", | |
| 119 | + domain->id, str_wake_sleep(wake), ERR_PTR(ret), | |
| 120 | + domain->reg_ack.addr, value); | |
| 121 | + if (value == ~0) { | |
| 122 | + xe_gt_err(gt, | |
| 123 | + "Force wake domain %d: %s. MMIO unreliable (forcewake register returns 0xFFFFFFFF)!\n", | |
| 124 | + domain->id, str_wake_sleep(wake)); | |
| 125 | + ret = -EIO; | |
| 126 | + } | |
| 121 | 127 | |
| 122 | 128 | return ret; |
| 123 | 129 | } |
| @@ -401,6 +401,16 @@ static void ggtt_invalidate_gt_tlb(struct xe_gt *gt) · 400 unmodified lines | ||
| 401 | 401 | |
| 402 | 402 | static void xe_ggtt_invalidate(struct xe_ggtt *ggtt) |
| 403 | 403 | { |
| 404 | + struct xe_device *xe = tile_to_xe(ggtt->tile); | |
| 405 | + | |
| 406 | + /* | |
| 407 | + * XXX: Barrier for GGTT pages. Unsure exactly why this required but | |
| 408 | + * without this LNL is having issues with the GuC reading scratch page | |
| 409 | + * vs. correct GGTT page. Not particularly a hot code path so blindly | |
| 410 | + * do a mmio read here which results in GuC reading correct GGTT page. | |
| 411 | + */ | |
| 412 | + xe_mmio_read32(&xe_root_mmio_gt(xe)->mmio, VF_CAP_REG); | |
| 413 | + | |
| 404 | 414 | /* Each GT in a tile has its own TLB to cache GGTT lookups */ |
| 405 | 415 | ggtt_invalidate_gt_tlb(ggtt->tile->primary_gt); |
| 406 | 416 | ggtt_invalidate_gt_tlb(ggtt->tile->media_gt); |
| @@ -1018,6 +1018,24 @@ retry_same_fence: · 1017 unmodified lines | ||
| 1018 | 1018 | |
| 1019 | 1019 | ret = wait_event_timeout(ct->g2h_fence_wq, g2h_fence.done, HZ); |
| 1020 | 1020 | |
| 1021 | + /* | |
| 1022 | + * Occasionally it is seen that the G2H worker starts running after a delay of more than | |
| 1023 | + * a second even after being queued and activated by the Linux workqueue subsystem. This | |
| 1024 | + * leads to G2H timeout error. The root cause of issue lies with scheduling latency of | |
| 1025 | + * Lunarlake Hybrid CPU. Issue dissappears if we disable Lunarlake atom cores from BIOS | |
| 1026 | + * and this is beyond xe kmd. | |
| 1027 | + * | |
| 1028 | + * TODO: Drop this change once workqueue scheduling delay issue is fixed on LNL Hybrid CPU. | |
| 1029 | + */ | |
| 1030 | + if (!ret) { | |
| 1031 | + flush_work(&ct->g2h_worker); | |
| 1032 | + if (g2h_fence.done) { | |
| 1033 | + xe_gt_warn(gt, "G2H fence %u, action %04x, done\n", | |
| 1034 | + g2h_fence.seqno, action[0]); | |
| 1035 | + ret = 1; | |
| 1036 | + } | |
| 1037 | + } | |
| 1038 | + | |
| 1021 | 1039 | /* |
| 1022 | 1040 | * Ensure we serialize with completion side to prevent UAF with fence going out of scope on |
| 1023 | 1041 | * the stack, since we have no clue if it will fire after the timeout before we can erase |
| @@ -225,80 +225,11 @@ static bool exec_queue_killed_or_banned_or_wedged(struct xe_exec_queue *q) · 224 unmodified lines | ||
| 225 | 225 | EXEC_QUEUE_STATE_BANNED)); |
| 226 | 226 | } |
| 227 | 227 | |
| 228 | −#ifdef CONFIG_PROVE_LOCKING | |
| 229 | −static int alloc_submit_wq(struct xe_guc *guc) | |
| 230 | −{ | |
| 231 | − int i; | |
| 232 | − | |
| 233 | − for (i = 0; i < NUM_SUBMIT_WQ; ++i) { | |
| 234 | − guc->submission_state.submit_wq_pool[i] = | |
| 235 | − alloc_ordered_workqueue("submit_wq", 0); | |
| 236 | − if (!guc->submission_state.submit_wq_pool[i]) | |
| 237 | − goto err_free; | |
| 238 | − } | |
| 239 | − | |
| 240 | − return 0; | |
| 241 | − | |
| 242 | −err_free: | |
| 243 | − while (i) | |
| 244 | − destroy_workqueue(guc->submission_state.submit_wq_pool[--i]); | |
| 245 | − | |
| 246 | − return -ENOMEM; | |
| 247 | −} | |
| 248 | − | |
| 249 | −static void free_submit_wq(struct xe_guc *guc) | |
| 250 | −{ | |
| 251 | − int i; | |
| 252 | − | |
| 253 | − for (i = 0; i < NUM_SUBMIT_WQ; ++i) | |
| 254 | − destroy_workqueue(guc->submission_state.submit_wq_pool[i]); | |
| 255 | −} | |
| 256 | − | |
| 257 | −static struct workqueue_struct *get_submit_wq(struct xe_guc *guc) | |
| 258 | −{ | |
| 259 | − int idx = guc->submission_state.submit_wq_idx++ % NUM_SUBMIT_WQ; | |
| 260 | − | |
| 261 | − return guc->submission_state.submit_wq_pool[idx]; | |
| 262 | −} | |
| 263 | −#else | |
| 264 | −static int alloc_submit_wq(struct xe_guc *guc) | |
| 265 | −{ | |
| 266 | − return 0; | |
| 267 | −} | |
| 268 | − | |
| 269 | −static void free_submit_wq(struct xe_guc *guc) | |
| 270 | −{ | |
| 271 | − | |
| 272 | −} | |
| 273 | − | |
| 274 | −static struct workqueue_struct *get_submit_wq(struct xe_guc *guc) | |
| 275 | −{ | |
| 276 | − return NULL; | |
| 277 | −} | |
| 278 | −#endif | |
| 279 | − | |
| 280 | −static void xe_guc_submit_fini(struct xe_guc *guc) | |
| 281 | −{ | |
| 282 | − struct xe_device *xe = guc_to_xe(guc); | |
| 283 | − struct xe_gt *gt = guc_to_gt(guc); | |
| 284 | − int ret; | |
| 285 | − | |
| 286 | − ret = wait_event_timeout(guc->submission_state.fini_wq, | |
| 287 | − xa_empty(&guc->submission_state.exec_queue_lookup), | |
| 288 | − HZ * 5); | |
| 289 | − | |
| 290 | − drain_workqueue(xe->destroy_wq); | |
| 291 | − | |
| 292 | − xe_gt_assert(gt, ret); | |
| 293 | −} | |
| 294 | − | |
| 295 | 228 | static void guc_submit_fini(struct drm_device *drm, void *arg) |
| 296 | 229 | { |
| 297 | 230 | struct xe_guc *guc = arg; |
| 298 | 231 | |
| 299 | − xe_guc_submit_fini(guc); | |
| 300 | 232 | xa_destroy(&guc->submission_state.exec_queue_lookup); |
| 301 | − free_submit_wq(guc); | |
| 302 | 233 | } |
| 303 | 234 | |
| 304 | 235 | static void guc_submit_wedged_fini(void *arg) |
| @@ -360,10 +291,6 @@ int xe_guc_submit_init(struct xe_guc *guc, unsigned int num_ids) · 55 unmodified lines | ||
| 360 | 291 | if (err) |
| 361 | 292 | return err; |
| 362 | 293 | |
| 363 | − err = alloc_submit_wq(guc); | |
| 364 | − if (err) | |
| 365 | − return err; | |
| 366 | − | |
| 367 | 294 | gt->exec_queue_ops = &guc_exec_queue_ops; |
| 368 | 295 | |
| 369 | 296 | xa_init(&guc->submission_state.exec_queue_lookup); |
| @@ -990,12 +917,22 @@ static void xe_guc_exec_queue_lr_cleanup(struct work_struct *w) · 620 unmodified lines | ||
| 990 | 917 | static bool check_timeout(struct xe_exec_queue *q, struct xe_sched_job *job) |
| 991 | 918 | { |
| 992 | 919 | struct xe_gt *gt = guc_to_gt(exec_queue_to_guc(q)); |
| 993 | − u32 ctx_timestamp = xe_lrc_ctx_timestamp(q->lrc[0]); | |
| 994 | − u32 ctx_job_timestamp = xe_lrc_ctx_job_timestamp(q->lrc[0]); | |
| 920 | + u32 ctx_timestamp, ctx_job_timestamp; | |
| 995 | 921 | u32 timeout_ms = q->sched_props.job_timeout_ms; |
| 996 | 922 | u32 diff; |
| 997 | 923 | u64 running_time_ms; |
| 998 | 924 | |
| 925 | + if (!xe_sched_job_started(job)) { | |
| 926 | + xe_gt_warn(gt, "Check job timeout: seqno=%u, lrc_seqno=%u, guc_id=%d, not started", | |
| 927 | + xe_sched_job_seqno(job), xe_sched_job_lrc_seqno(job), | |
| 928 | + q->guc->id); | |
| 929 | + | |
| 930 | + return xe_sched_invalidate_job(job, 2); | |
| 931 | + } | |
| 932 | + | |
| 933 | + ctx_timestamp = xe_lrc_ctx_timestamp(q->lrc[0]); | |
| 934 | + ctx_job_timestamp = xe_lrc_ctx_job_timestamp(q->lrc[0]); | |
| 935 | + | |
| 999 | 936 | /* |
| 1000 | 937 | * Counter wraps at ~223s at the usual 19.2MHz, be paranoid catch |
| 1001 | 938 | * possible overflows with a high timeout. |
| @@ -1124,10 +1061,6 @@ guc_exec_queue_timedout_job(struct drm_sched_job *drm_job) · 122 unmodified lines | ||
| 1124 | 1061 | exec_queue_killed_or_banned_or_wedged(q) || |
| 1125 | 1062 | exec_queue_destroyed(q); |
| 1126 | 1063 | |
| 1127 | − /* Job hasn't started, can't be timed out */ | |
| 1128 | − if (!skip_timeout_check && !xe_sched_job_started(job)) | |
| 1129 | − goto rearm; | |
| 1130 | − | |
| 1131 | 1064 | /* |
| 1132 | 1065 | * If devcoredump not captured and GuC capture for the job is not ready |
| 1133 | 1066 | * do manual capture first and decide later if we need to use it |
| @@ -1499,8 +1432,7 @@ static int guc_exec_queue_init(struct xe_exec_queue *q) · 365 unmodified lines | ||
| 1499 | 1432 | timeout = (q->vm && xe_vm_in_lr_mode(q->vm)) ? MAX_SCHEDULE_TIMEOUT : |
| 1500 | 1433 | msecs_to_jiffies(q->sched_props.job_timeout_ms); |
| 1501 | 1434 | err = xe_sched_init(&ge->sched, &drm_sched_ops, &xe_sched_ops, |
| 1502 | − get_submit_wq(guc), | |
| 1503 | − q->lrc[0]->ring.size / MAX_JOB_SIZE_BYTES, 64, | |
| 1435 | + NULL, q->lrc[0]->ring.size / MAX_JOB_SIZE_BYTES, 64, | |
| 1504 | 1436 | timeout, guc_to_gt(guc)->ordered_wq, NULL, |
| 1505 | 1437 | q->name, gt_to_xe(q->gt)->drm.dev); |
| 1506 | 1438 | if (err) |
| @@ -1817,8 +1749,13 @@ void xe_guc_submit_stop(struct xe_guc *guc) · 310 unmodified lines | ||
| 1817 | 1749 | |
| 1818 | 1750 | mutex_lock(&guc->submission_state.lock); |
| 1819 | 1751 | |
| 1820 | − xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) | |
| 1752 | + xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) { | |
| 1753 | + /* Prevent redundant attempts to stop parallel queues */ | |
| 1754 | + if (q->guc->id != index) | |
| 1755 | + continue; | |
| 1756 | + | |
| 1821 | 1757 | guc_exec_queue_stop(guc, q); |
| 1758 | + } | |
| 1822 | 1759 | |
| 1823 | 1760 | mutex_unlock(&guc->submission_state.lock); |
| 1824 | 1761 | |
| @@ -1856,8 +1793,13 @@ int xe_guc_submit_start(struct xe_guc *guc) · 31 unmodified lines | ||
| 1856 | 1793 | |
| 1857 | 1794 | mutex_lock(&guc->submission_state.lock); |
| 1858 | 1795 | atomic_dec(&guc->submission_state.stopped); |
| 1859 | − xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) | |
| 1796 | + xa_for_each(&guc->submission_state.exec_queue_lookup, index, q) { | |
| 1797 | + /* Prevent redundant attempts to start parallel queues */ | |
| 1798 | + if (q->guc->id != index) | |
| 1799 | + continue; | |
| 1800 | + | |
| 1860 | 1801 | guc_exec_queue_start(q); |
| 1802 | + } | |
| 1861 | 1803 | mutex_unlock(&guc->submission_state.lock); |
| 1862 | 1804 | |
| 1863 | 1805 | wake_up_all(&guc->ct.wq); |
| @@ -74,13 +74,6 @@ struct xe_guc { · 73 unmodified lines | ||
| 74 | 74 | atomic_t stopped; |
| 75 | 75 | /** @submission_state.lock: protects submission state */ |
| 76 | 76 | struct mutex lock; |
| 77 | −#ifdef CONFIG_PROVE_LOCKING | |
| 78 | −#define NUM_SUBMIT_WQ 256 | |
| 79 | − /** @submission_state.submit_wq_pool: submission ordered workqueues pool */ | |
| 80 | − struct workqueue_struct *submit_wq_pool[NUM_SUBMIT_WQ]; | |
| 81 | − /** @submission_state.submit_wq_idx: submission ordered workqueue index */ | |
| 82 | − int submit_wq_idx; | |
| 83 | −#endif | |
| 84 | 77 | /** @submission_state.enabled: submission is enabled */ |
| 85 | 78 | bool enabled; |
| 86 | 79 | /** @submission_state.fini_wq: submit fini wait queue */ |
| @@ -54,8 +54,9 @@ static struct xe_user_fence *user_fence_create(struct xe_device *xe, u64 addr, · 53 unmodified lines | ||
| 54 | 54 | { |
| 55 | 55 | struct xe_user_fence *ufence; |
| 56 | 56 | u64 __user *ptr = u64_to_user_ptr(addr); |
| 57 | + u64 __maybe_unused prefetch_val; | |
| 57 | 58 | |
| 58 | − if (!access_ok(ptr, sizeof(*ptr))) | |
| 59 | + if (get_user(prefetch_val, ptr)) | |
| 59 | 60 | return ERR_PTR(-EFAULT); |
| 60 | 61 | |
| 61 | 62 | ufence = kzalloc(sizeof(*ufence), GFP_KERNEL); |
| @@ -236,9 +236,9 @@ int amd_sfh_hid_client_init(struct amd_mp2_dev *privdata) · 235 unmodified lines | ||
| 236 | 236 | cl_data->in_data = in_data; |
| 237 | 237 | |
| 238 | 238 | for (i = 0; i < cl_data->num_hid_devices; i++) { |
| 239 | − in_data->sensor_virt_addr[i] = dma_alloc_coherent(dev, sizeof(int) * 8, | |
| 240 | − &cl_data->sensor_dma_addr[i], | |
| 241 | − GFP_KERNEL); | |
| 239 | + in_data->sensor_virt_addr[i] = dmam_alloc_coherent(dev, sizeof(int) * 8, | |
| 240 | + &cl_data->sensor_dma_addr[i], | |
| 241 | + GFP_KERNEL); | |
| 242 | 242 | if (!in_data->sensor_virt_addr[i]) { |
| 243 | 243 | rc = -ENOMEM; |
| 244 | 244 | goto cleanup; |
| @@ -331,7 +331,6 @@ cleanup: · 86 unmodified lines | ||
| 331 | 331 | int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) |
| 332 | 332 | { |
| 333 | 333 | struct amdtp_cl_data *cl_data = privdata->cl_data; |
| 334 | − struct amd_input_data *in_data = cl_data->in_data; | |
| 335 | 334 | int i, status; |
| 336 | 335 | |
| 337 | 336 | for (i = 0; i < cl_data->num_hid_devices; i++) { |
| @@ -351,12 +350,5 @@ int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) · 13 unmodified lines | ||
| 351 | 350 | cancel_delayed_work_sync(&cl_data->work_buffer); |
| 352 | 351 | amdtp_hid_remove(cl_data); |
| 353 | 352 | |
| 354 | − for (i = 0; i < cl_data->num_hid_devices; i++) { | |
| 355 | − if (in_data->sensor_virt_addr[i]) { | |
| 356 | − dma_free_coherent(&privdata->pdev->dev, 8 * sizeof(int), | |
| 357 | − in_data->sensor_virt_addr[i], | |
| 358 | − cl_data->sensor_dma_addr[i]); | |
| 359 | − } | |
| 360 | − } | |
| 361 | 353 | return 0; |
| 362 | 354 | } |
| @@ -509,6 +509,7 @@ · 508 unmodified lines | ||
| 509 | 509 | #define I2C_DEVICE_ID_GOODIX_01E8 0x01e8 |
| 510 | 510 | #define I2C_DEVICE_ID_GOODIX_01E9 0x01e9 |
| 511 | 511 | #define I2C_DEVICE_ID_GOODIX_01F0 0x01f0 |
| 512 | +#define I2C_DEVICE_ID_GOODIX_0D42 0x0d42 | |
| 512 | 513 | |
| 513 | 514 | #define USB_VENDOR_ID_GOODTOUCH 0x1aad |
| 514 | 515 | #define USB_DEVICE_ID_GOODTOUCH_000f 0x000f |
| @@ -868,6 +869,7 @@ · 353 unmodified lines | ||
| 868 | 869 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539 |
| 869 | 870 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f |
| 870 | 871 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a |
| 872 | +#define USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER 0xc548 | |
| 871 | 873 | #define USB_DEVICE_ID_SPACETRAVELLER 0xc623 |
| 872 | 874 | #define USB_DEVICE_ID_SPACENAVIGATOR 0xc626 |
| 873 | 875 | #define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 |
| @@ -1036,6 +1038,8 @@ · 162 unmodified lines | ||
| 1036 | 1038 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056 |
| 1037 | 1039 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057 |
| 1038 | 1040 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES 0xc058 |
| 1041 | +#define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES 0x430c | |
| 1042 | +#define USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES 0x431e | |
| 1039 | 1043 | |
| 1040 | 1044 | #define USB_VENDOR_ID_PANASONIC 0x04da |
| 1041 | 1045 | #define USB_DEVICE_ID_PANABOARD_UBT780 0x1044 |
| @@ -473,6 +473,7 @@ static int lenovo_input_mapping(struct hid_device *hdev, · 472 unmodified lines | ||
| 473 | 473 | return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field, |
| 474 | 474 | usage, bit, max); |
| 475 | 475 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 476 | + case USB_DEVICE_ID_LENOVO_X1_TAB3: | |
| 476 | 477 | return lenovo_input_mapping_x1_tab_kbd(hdev, hi, field, usage, bit, max); |
| 477 | 478 | default: |
| 478 | 479 | return 0; |
| @@ -583,6 +584,7 @@ static ssize_t attr_fn_lock_store(struct device *dev, · 104 unmodified lines | ||
| 583 | 584 | break; |
| 584 | 585 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 585 | 586 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 587 | + case USB_DEVICE_ID_LENOVO_X1_TAB3: | |
| 586 | 588 | ret = lenovo_led_set_tp10ubkbd(hdev, TP10UBKBD_FN_LOCK_LED, value); |
| 587 | 589 | if (ret) |
| 588 | 590 | return ret; |
| @@ -776,6 +778,7 @@ static int lenovo_event(struct hid_device *hdev, struct hid_field *field, · 187 unmodified lines | ||
| 776 | 778 | return lenovo_event_cptkbd(hdev, field, usage, value); |
| 777 | 779 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 778 | 780 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 781 | + case USB_DEVICE_ID_LENOVO_X1_TAB3: | |
| 779 | 782 | return lenovo_event_tp10ubkbd(hdev, field, usage, value); |
| 780 | 783 | default: |
| 781 | 784 | return 0; |
| @@ -1056,6 +1059,7 @@ static int lenovo_led_brightness_set(struct led_classdev *led_cdev, · 274 unmodified lines | ||
| 1056 | 1059 | break; |
| 1057 | 1060 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 1058 | 1061 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 1062 | + case USB_DEVICE_ID_LENOVO_X1_TAB3: | |
| 1059 | 1063 | ret = lenovo_led_set_tp10ubkbd(hdev, tp10ubkbd_led[led_nr], value); |
| 1060 | 1064 | break; |
| 1061 | 1065 | } |
| @@ -1286,6 +1290,7 @@ static int lenovo_probe(struct hid_device *hdev, · 224 unmodified lines | ||
| 1286 | 1290 | break; |
| 1287 | 1291 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 1288 | 1292 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 1293 | + case USB_DEVICE_ID_LENOVO_X1_TAB3: | |
| 1289 | 1294 | ret = lenovo_probe_tp10ubkbd(hdev); |
| 1290 | 1295 | break; |
| 1291 | 1296 | default: |
| @@ -1372,6 +1377,7 @@ static void lenovo_remove(struct hid_device *hdev) · 80 unmodified lines | ||
| 1372 | 1377 | break; |
| 1373 | 1378 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 1374 | 1379 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 1380 | + case USB_DEVICE_ID_LENOVO_X1_TAB3: | |
| 1375 | 1381 | lenovo_remove_tp10ubkbd(hdev); |
| 1376 | 1382 | break; |
| 1377 | 1383 | } |
| @@ -1421,6 +1427,8 @@ static const struct hid_device_id lenovo_devices[] = { · 43 unmodified lines | ||
| 1421 | 1427 | */ |
| 1422 | 1428 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 1423 | 1429 | USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_TAB) }, |
| 1430 | + { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | |
| 1431 | + USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_TAB3) }, | |
| 1424 | 1432 | { } |
| 1425 | 1433 | }; |
| 1426 | 1434 | |
| @@ -2026,6 +2026,10 @@ static const struct hid_device_id mt_devices[] = { · 2025 unmodified lines | ||
| 2026 | 2026 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, |
| 2027 | 2027 | USB_VENDOR_ID_ELAN, 0x3148) }, |
| 2028 | 2028 | |
| 2029 | + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU, | |
| 2030 | + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, | |
| 2031 | + USB_VENDOR_ID_ELAN, 0x32ae) }, | |
| 2032 | + | |
| 2029 | 2033 | /* Elitegroup panel */ |
| 2030 | 2034 | { .driver_data = MT_CLS_SERIAL, |
| 2031 | 2035 | MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP, |
| @@ -2095,6 +2099,11 @@ static const struct hid_device_id mt_devices[] = { · 63 unmodified lines | ||
| 2095 | 2099 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, |
| 2096 | 2100 | 0x347d, 0x7853) }, |
| 2097 | 2101 | |
| 2102 | + /* HONOR MagicBook Art 14 touchpad */ | |
| 2103 | + { .driver_data = MT_CLS_VTL, | |
| 2104 | + HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, | |
| 2105 | + 0x35cc, 0x0104) }, | |
| 2106 | + | |
| 2098 | 2107 | /* Ilitek dual touch panel */ |
| 2099 | 2108 | { .driver_data = MT_CLS_NSMU, |
| 2100 | 2109 | MT_USB_DEVICE(USB_VENDOR_ID_ILITEK, |
| @@ -2137,6 +2146,10 @@ static const struct hid_device_id mt_devices[] = { · 36 unmodified lines | ||
| 2137 | 2146 | HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH_WIN_8, |
| 2138 | 2147 | USB_VENDOR_ID_LOGITECH, |
| 2139 | 2148 | USB_DEVICE_ID_LOGITECH_CASA_TOUCHPAD) }, |
| 2149 | + { .driver_data = MT_CLS_WIN_8_FORCE_MULTI_INPUT_NSMU, | |
| 2150 | + HID_DEVICE(BUS_USB, HID_GROUP_MULTITOUCH_WIN_8, | |
| 2151 | + USB_VENDOR_ID_LOGITECH, | |
| 2152 | + USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER) }, | |
| 2140 | 2153 | |
| 2141 | 2154 | /* MosArt panels */ |
| 2142 | 2155 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, |
| @@ -38,8 +38,10 @@ · 37 unmodified lines | ||
| 38 | 38 | (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) |
| 39 | 39 | |
| 40 | 40 | #define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0) |
| 41 | +#define PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS BIT(1) | |
| 41 | 42 | |
| 42 | 43 | #define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */ |
| 44 | +#define PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT 220 /* ms */ | |
| 43 | 45 | |
| 44 | 46 | struct plt_drv_data { |
| 45 | 47 | unsigned long device_type; |
| @@ -137,6 +139,21 @@ static int plantronics_event(struct hid_device *hdev, struct hid_field *field, · 91 unmodified lines | ||
| 137 | 139 | |
| 138 | 140 | drv_data->last_volume_key_ts = cur_ts; |
| 139 | 141 | } |
| 142 | + if (drv_data->quirks & PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS) { | |
| 143 | + unsigned long prev_ts, cur_ts; | |
| 144 | + | |
| 145 | + /* Usages are filtered in plantronics_usages. */ | |
| 146 | + | |
| 147 | + if (!value) /* Handle key presses only. */ | |
| 148 | + return 0; | |
| 149 | + | |
| 150 | + prev_ts = drv_data->last_volume_key_ts; | |
| 151 | + cur_ts = jiffies; | |
| 152 | + if (jiffies_to_msecs(cur_ts - prev_ts) <= PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT) | |
| 153 | + return 1; /* Ignore the followed opposite volume key. */ | |
| 154 | + | |
| 155 | + drv_data->last_volume_key_ts = cur_ts; | |
| 156 | + } | |
| 140 | 157 | |
| 141 | 158 | return 0; |
| 142 | 159 | } |
| @@ -210,6 +227,12 @@ static const struct hid_device_id plantronics_devices[] = { · 67 unmodified lines | ||
| 210 | 227 | { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, |
| 211 | 228 | USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES), |
| 212 | 229 | .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS }, |
| 230 | + { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, | |
| 231 | + USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3325_SERIES), | |
| 232 | + .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS }, | |
| 233 | + { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, | |
| 234 | + USB_DEVICE_ID_PLANTRONICS_ENCOREPRO_500_SERIES), | |
| 235 | + .driver_data = PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS }, | |
| 213 | 236 | { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, |
| 214 | 237 | { } |
| 215 | 238 | }; |
| @@ -50,6 +50,7 @@ · 49 unmodified lines | ||
| 50 | 50 | #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(3) |
| 51 | 51 | #define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(4) |
| 52 | 52 | #define I2C_HID_QUIRK_NO_SLEEP_ON_SUSPEND BIT(5) |
| 53 | +#define I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME BIT(6) | |
| 53 | 54 | |
| 54 | 55 | /* Command opcodes */ |
| 55 | 56 | #define I2C_HID_OPCODE_RESET 0x01 |
| @@ -140,6 +141,8 @@ static const struct i2c_hid_quirks { · 84 unmodified lines | ||
| 140 | 141 | { USB_VENDOR_ID_ELAN, HID_ANY_ID, |
| 141 | 142 | I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET | |
| 142 | 143 | I2C_HID_QUIRK_BOGUS_IRQ }, |
| 144 | + { I2C_VENDOR_ID_GOODIX, I2C_DEVICE_ID_GOODIX_0D42, | |
| 145 | + I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME }, | |
| 143 | 146 | { 0, 0 } |
| 144 | 147 | }; |
| 145 | 148 | |
| @@ -981,6 +984,13 @@ static int i2c_hid_core_resume(struct i2c_hid *ihid) · 835 unmodified lines | ||
| 981 | 984 | return -ENXIO; |
| 982 | 985 | } |
| 983 | 986 | |
| 987 | + /* On Goodix 27c6:0d42 wait extra time before device wakeup. | |
| 988 | + * It's not clear why but if we send wakeup too early, the device will | |
| 989 | + * never trigger input interrupts. | |
| 990 | + */ | |
| 991 | + if (ihid->quirks & I2C_HID_QUIRK_DELAY_WAKEUP_AFTER_RESUME) | |
| 992 | + msleep(1500); | |
| 993 | + | |
| 984 | 994 | /* Instead of resetting device, simply powers the device on. This |
| 985 | 995 | * solves "incomplete reports" on Raydium devices 2386:3118 and |
| 986 | 996 | * 2386:4B33 and fixes various SIS touchscreens no longer sending |
| @@ -635,7 +635,7 @@ static int ish_fw_xfer_direct_dma(struct ishtp_cl_data *client_data, · 634 unmodified lines | ||
| 635 | 635 | const struct firmware *fw, |
| 636 | 636 | const struct shim_fw_info fw_info) |
| 637 | 637 | { |
| 638 | − int rv; | |
| 638 | + int rv = 0; | |
| 639 | 639 | void *dma_buf; |
| 640 | 640 | dma_addr_t dma_buf_phy; |
| 641 | 641 | u32 fragment_offset, fragment_size, payload_max_size; |
| @@ -2567,6 +2567,8 @@ static void wacom_wac_pen_report(struct hid_device *hdev, · 2566 unmodified lines | ||
| 2567 | 2567 | /* Going into range select tool */ |
| 2568 | 2568 | if (wacom_wac->hid_data.invert_state) |
| 2569 | 2569 | wacom_wac->tool[0] = BTN_TOOL_RUBBER; |
| 2570 | + else if (wacom_wac->features.quirks & WACOM_QUIRK_AESPEN) | |
| 2571 | + wacom_wac->tool[0] = BTN_TOOL_PEN; | |
| 2570 | 2572 | else if (wacom_wac->id[0]) |
| 2571 | 2573 | wacom_wac->tool[0] = wacom_intuos_get_tool_type(wacom_wac->id[0]); |
| 2572 | 2574 | else |
| @@ -162,6 +162,7 @@ config SENSORS_ADM9240 · 161 unmodified lines | ||
| 162 | 162 | tristate "Analog Devices ADM9240 and compatibles" |
| 163 | 163 | depends on I2C |
| 164 | 164 | select HWMON_VID |
| 165 | + select REGMAP_I2C | |
| 165 | 166 | help |
| 166 | 167 | If you say yes here you get support for Analog Devices ADM9240, |
| 167 | 168 | Dallas DS1780, National Semiconductor LM81 sensor chips. |
| @@ -223,6 +224,7 @@ config SENSORS_ADT7462 · 55 unmodified lines | ||
| 223 | 224 | config SENSORS_ADT7470 |
| 224 | 225 | tristate "Analog Devices ADT7470" |
| 225 | 226 | depends on I2C |
| 227 | + select REGMAP_I2C | |
| 226 | 228 | help |
| 227 | 229 | If you say yes here you get support for the Analog Devices |
| 228 | 230 | ADT7470 temperature monitoring chips. |
| @@ -999,6 +1001,7 @@ config SENSORS_LTC2990 · 770 unmodified lines | ||
| 999 | 1001 | config SENSORS_LTC2991 |
| 1000 | 1002 | tristate "Analog Devices LTC2991" |
| 1001 | 1003 | depends on I2C |
| 1004 | + select REGMAP_I2C | |
| 1002 | 1005 | help |
| 1003 | 1006 | If you say yes here you get support for Analog Devices LTC2991 |
| 1004 | 1007 | Octal I2C Voltage, Current, and Temperature Monitor. The LTC2991 |
| @@ -1146,6 +1149,7 @@ config SENSORS_MAX1619 · 141 unmodified lines | ||
| 1146 | 1149 | config SENSORS_MAX1668 |
| 1147 | 1150 | tristate "Maxim MAX1668 and compatibles" |
| 1148 | 1151 | depends on I2C |
| 1152 | + select REGMAP_I2C | |
| 1149 | 1153 | help |
| 1150 | 1154 | If you say yes here you get support for MAX1668, MAX1989 and |
| 1151 | 1155 | MAX1805 chips. |
| @@ -1275,6 +1279,7 @@ config SENSORS_MAX31790 · 123 unmodified lines | ||
| 1275 | 1279 | config SENSORS_MC34VR500 |
| 1276 | 1280 | tristate "NXP MC34VR500 hardware monitoring driver" |
| 1277 | 1281 | depends on I2C |
| 1282 | + select REGMAP_I2C | |
| 1278 | 1283 | help |
| 1279 | 1284 | If you say yes here you get support for the temperature and input |
| 1280 | 1285 | voltage sensors of the NXP MC34VR500. |
| @@ -2312,6 +2317,7 @@ config SENSORS_TMP464 · 1031 unmodified lines | ||
| 2312 | 2317 | config SENSORS_TMP513 |
| 2313 | 2318 | tristate "Texas Instruments TMP513 and compatibles" |
| 2314 | 2319 | depends on I2C |
| 2320 | + select REGMAP_I2C | |
| 2315 | 2321 | help |
| 2316 | 2322 | If you say yes here you get support for Texas Instruments TMP512, |
| 2317 | 2323 | and TMP513 temperature and power supply sensor chips. |
| @@ -1735,11 +1735,10 @@ static int adt7475_pwm_properties_parse_args(struct fwnode_handle *fwnode, · 1734 unmodified lines | ||
| 1735 | 1735 | static int adt7475_fan_pwm_config(struct i2c_client *client) |
| 1736 | 1736 | { |
| 1737 | 1737 | struct adt7475_data *data = i2c_get_clientdata(client); |
| 1738 | − struct fwnode_handle *child; | |
| 1739 | 1738 | struct adt7475_pwm_config cfg = {}; |
| 1740 | 1739 | int ret; |
| 1741 | 1740 | |
| 1742 | − device_for_each_child_node(&client->dev, child) { | |
| 1741 | + device_for_each_child_node_scoped(&client->dev, child) { | |
| 1743 | 1742 | if (!fwnode_property_present(child, "pwms")) |
| 1744 | 1743 | continue; |
| 1745 | 1744 | |
| @@ -358,7 +358,7 @@ static const struct m10bmc_sdata n6000bmc_temp_tbl[] = { · 357 unmodified lines | ||
| 358 | 358 | { 0x4f0, 0x4f4, 0x4f8, 0x52c, 0x0, 500, "Board Top Near FPGA Temperature" }, |
| 359 | 359 | { 0x4fc, 0x500, 0x504, 0x52c, 0x0, 500, "Board Bottom Near CVL Temperature" }, |
| 360 | 360 | { 0x508, 0x50c, 0x510, 0x52c, 0x0, 500, "Board Top East Near VRs Temperature" }, |
| 361 | − { 0x514, 0x518, 0x51c, 0x52c, 0x0, 500, "Columbiaville Die Temperature" }, | |
| 361 | + { 0x514, 0x518, 0x51c, 0x52c, 0x0, 500, "CVL Die Temperature" }, | |
| 362 | 362 | { 0x520, 0x524, 0x528, 0x52c, 0x0, 500, "Board Rear Side Temperature" }, |
| 363 | 363 | { 0x530, 0x534, 0x538, 0x52c, 0x0, 500, "Board Front Side Temperature" }, |
| 364 | 364 | { 0x53c, 0x540, 0x544, 0x0, 0x0, 500, "QSFP1 Case Temperature" }, |
| @@ -417,7 +417,7 @@ static int jc42_detect(struct i2c_client *client, struct i2c_board_info *info) · 416 unmodified lines | ||
| 417 | 417 | return -ENODEV; |
| 418 | 418 | |
| 419 | 419 | if ((devid & TSE2004_DEVID_MASK) == TSE2004_DEVID && |
| 420 | − (cap & 0x00e7) != 0x00e7) | |
| 420 | + (cap & 0x0062) != 0x0062) | |
| 421 | 421 | return -ENODEV; |
| 422 | 422 | |
| 423 | 423 | for (i = 0; i < ARRAY_SIZE(jc42_chips); i++) { |
| @@ -447,6 +447,8 @@ config IIO_ST_ACCEL_SPI_3AXIS · 446 unmodified lines | ||
| 447 | 447 | |
| 448 | 448 | config IIO_KX022A |
| 449 | 449 | tristate |
| 450 | + select IIO_BUFFER | |
| 451 | + select IIO_TRIGGERED_BUFFER | |
| 450 | 452 | |
| 451 | 453 | config IIO_KX022A_SPI |
| 452 | 454 | tristate "Kionix KX022A tri-axis digital accelerometer SPI interface" |
| @@ -1218,7 +1218,8 @@ static int bma400_activity_event_en(struct bma400_data *data, · 1217 unmodified lines | ||
| 1218 | 1218 | static int bma400_tap_event_en(struct bma400_data *data, |
| 1219 | 1219 | enum iio_event_direction dir, int state) |
| 1220 | 1220 | { |
| 1221 | − unsigned int mask, field_value; | |
| 1221 | + unsigned int mask; | |
| 1222 | + unsigned int field_value = 0; | |
| 1222 | 1223 | int ret; |
| 1223 | 1224 | |
| 1224 | 1225 | /* |
| @@ -52,6 +52,8 @@ config AD4695 · 51 unmodified lines | ||
| 52 | 52 | tristate "Analog Device AD4695 ADC Driver" |
| 53 | 53 | depends on SPI |
| 54 | 54 | select REGMAP_SPI |
| 55 | + select IIO_BUFFER | |
| 56 | + select IIO_TRIGGERED_BUFFER | |
| 55 | 57 | help |
| 56 | 58 | Say yes here to build support for Analog Devices AD4695 and similar |
| 57 | 59 | analog to digital converters (ADC). |
| @@ -328,6 +330,8 @@ config AD7923 · 270 unmodified lines | ||
| 328 | 330 | config AD7944 |
| 329 | 331 | tristate "Analog Devices AD7944 and similar ADCs driver" |
| 330 | 332 | depends on SPI |
| 333 | + select IIO_BUFFER | |
| 334 | + select IIO_TRIGGERED_BUFFER | |
| 331 | 335 | help |
| 332 | 336 | Say yes here to build support for Analog Devices |
| 333 | 337 | AD7944, AD7985, AD7986 ADCs. |
| @@ -1481,6 +1485,8 @@ config TI_ADS8344 · 1147 unmodified lines | ||
| 1481 | 1485 | config TI_ADS8688 |
| 1482 | 1486 | tristate "Texas Instruments ADS8688" |
| 1483 | 1487 | depends on SPI |
| 1488 | + select IIO_BUFFER | |
| 1489 | + select IIO_TRIGGERED_BUFFER | |
| 1484 | 1490 | help |
| 1485 | 1491 | If you say yes here you get support for Texas Instruments ADS8684 and |
| 1486 | 1492 | and ADS8688 ADC chips |
| @@ -1491,6 +1497,8 @@ config TI_ADS8688 · 4 unmodified lines | ||
| 1491 | 1497 | config TI_ADS124S08 |
| 1492 | 1498 | tristate "Texas Instruments ADS124S08" |
| 1493 | 1499 | depends on SPI |
| 1500 | + select IIO_BUFFER | |
| 1501 | + select IIO_TRIGGERED_BUFFER | |
| 1494 | 1502 | help |
| 1495 | 1503 | If you say yes here you get support for Texas Instruments ADS124S08 |
| 1496 | 1504 | and ADS124S06 ADC chips |
| @@ -1525,6 +1533,9 @@ config TI_AM335X_ADC · 28 unmodified lines | ||
| 1525 | 1533 | config TI_LMP92064 |
| 1526 | 1534 | tristate "Texas Instruments LMP92064 ADC driver" |
| 1527 | 1535 | depends on SPI |
| 1536 | + select REGMAP_SPI | |
| 1537 | + select IIO_BUFFER | |
| 1538 | + select IIO_TRIGGERED_BUFFER | |
| 1528 | 1539 | help |
| 1529 | 1540 | Say yes here to build support for the LMP92064 Precision Current and Voltage |
| 1530 | 1541 | sensor. |
| @@ -637,7 +637,7 @@ static int ad7124_write_raw(struct iio_dev *indio_dev, · 636 unmodified lines | ||
| 637 | 637 | |
| 638 | 638 | switch (info) { |
| 639 | 639 | case IIO_CHAN_INFO_SAMP_FREQ: |
| 640 | − if (val2 != 0) { | |
| 640 | + if (val2 != 0 || val == 0) { | |
| 641 | 641 | ret = -EINVAL; |
| 642 | 642 | break; |
| 643 | 643 | } |
| @@ -75,6 +75,7 @@ · 74 unmodified lines | ||
| 75 | 75 | #define T_CONVERT_NS 190 /* conversion time */ |
| 76 | 76 | #define T_CONVERT_0_NS 10 /* 1st conversion start time (oversampling) */ |
| 77 | 77 | #define T_CONVERT_X_NS 500 /* xth conversion start time (oversampling) */ |
| 78 | +#define T_POWERUP_US 5000 /* Power up */ | |
| 78 | 79 | |
| 79 | 80 | struct ad7380_timing_specs { |
| 80 | 81 | const unsigned int t_csh_ns; /* CS minimum high time */ |
| @@ -86,6 +87,9 @@ struct ad7380_chip_info { · 5 unmodified lines | ||
| 86 | 87 | unsigned int num_channels; |
| 87 | 88 | unsigned int num_simult_channels; |
| 88 | 89 | bool has_mux; |
| 90 | + const char * const *supplies; | |
| 91 | + unsigned int num_supplies; | |
| 92 | + bool external_ref_only; | |
| 89 | 93 | const char * const *vcm_supplies; |
| 90 | 94 | unsigned int num_vcm_supplies; |
| 91 | 95 | const unsigned long *available_scan_masks; |
| @@ -243,6 +247,10 @@ DEFINE_AD7380_8_CHANNEL(ad7386_4_channels, 16, 0, u); · 151 unmodified lines | ||
| 243 | 247 | DEFINE_AD7380_8_CHANNEL(ad7387_4_channels, 14, 0, u); |
| 244 | 248 | DEFINE_AD7380_8_CHANNEL(ad7388_4_channels, 12, 0, u); |
| 245 | 249 | |
| 250 | +static const char * const ad7380_supplies[] = { | |
| 251 | + "vcc", "vlogic", | |
| 252 | +}; | |
| 253 | + | |
| 246 | 254 | static const char * const ad7380_2_channel_vcm_supplies[] = { |
| 247 | 255 | "aina", "ainb", |
| 248 | 256 | }; |
| @@ -338,6 +346,8 @@ static const struct ad7380_chip_info ad7380_chip_info = { · 89 unmodified lines | ||
| 338 | 346 | .channels = ad7380_channels, |
| 339 | 347 | .num_channels = ARRAY_SIZE(ad7380_channels), |
| 340 | 348 | .num_simult_channels = 2, |
| 349 | + .supplies = ad7380_supplies, | |
| 350 | + .num_supplies = ARRAY_SIZE(ad7380_supplies), | |
| 341 | 351 | .available_scan_masks = ad7380_2_channel_scan_masks, |
| 342 | 352 | .timing_specs = &ad7380_timing, |
| 343 | 353 | }; |
| @@ -347,6 +357,8 @@ static const struct ad7380_chip_info ad7381_chip_info = { · 3 unmodified lines | ||
| 347 | 357 | .channels = ad7381_channels, |
| 348 | 358 | .num_channels = ARRAY_SIZE(ad7381_channels), |
| 349 | 359 | .num_simult_channels = 2, |
| 360 | + .supplies = ad7380_supplies, | |
| 361 | + .num_supplies = ARRAY_SIZE(ad7380_supplies), | |
| 350 | 362 | .available_scan_masks = ad7380_2_channel_scan_masks, |
| 351 | 363 | .timing_specs = &ad7380_timing, |
| 352 | 364 | }; |
| @@ -356,6 +368,8 @@ static const struct ad7380_chip_info ad7383_chip_info = { · 3 unmodified lines | ||
| 356 | 368 | .channels = ad7383_channels, |
| 357 | 369 | .num_channels = ARRAY_SIZE(ad7383_channels), |
| 358 | 370 | .num_simult_channels = 2, |
| 371 | + .supplies = ad7380_supplies, | |
| 372 | + .num_supplies = ARRAY_SIZE(ad7380_supplies), | |
| 359 | 373 | .vcm_supplies = ad7380_2_channel_vcm_supplies, |
| 360 | 374 | .num_vcm_supplies = ARRAY_SIZE(ad7380_2_channel_vcm_supplies), |
| 361 | 375 | .available_scan_masks = ad7380_2_channel_scan_masks, |
| @@ -367,6 +381,8 @@ static const struct ad7380_chip_info ad7384_chip_info = { · 5 unmodified lines | ||
| 367 | 381 | .channels = ad7384_channels, |
| 368 | 382 | .num_channels = ARRAY_SIZE(ad7384_channels), |
| 369 | 383 | .num_simult_channels = 2, |
| 384 | + .supplies = ad7380_supplies, | |
| 385 | + .num_supplies = ARRAY_SIZE(ad7380_supplies), | |
| 370 | 386 | .vcm_supplies = ad7380_2_channel_vcm_supplies, |
| 371 | 387 | .num_vcm_supplies = ARRAY_SIZE(ad7380_2_channel_vcm_supplies), |
| 372 | 388 | .available_scan_masks = ad7380_2_channel_scan_masks, |
| @@ -378,6 +394,8 @@ static const struct ad7380_chip_info ad7386_chip_info = { · 5 unmodified lines | ||
| 378 | 394 | .channels = ad7386_channels, |
| 379 | 395 | .num_channels = ARRAY_SIZE(ad7386_channels), |
| 380 | 396 | .num_simult_channels = 2, |
| 397 | + .supplies = ad7380_supplies, | |
| 398 | + .num_supplies = ARRAY_SIZE(ad7380_supplies), | |
| 381 | 399 | .has_mux = true, |
| 382 | 400 | .available_scan_masks = ad7380_2x2_channel_scan_masks, |
| 383 | 401 | .timing_specs = &ad7380_timing, |
| @@ -388,6 +406,8 @@ static const struct ad7380_chip_info ad7387_chip_info = { · 4 unmodified lines | ||
| 388 | 406 | .channels = ad7387_channels, |
| 389 | 407 | .num_channels = ARRAY_SIZE(ad7387_channels), |
| 390 | 408 | .num_simult_channels = 2, |
| 409 | + .supplies = ad7380_supplies, | |
| 410 | + .num_supplies = ARRAY_SIZE(ad7380_supplies), | |
| 391 | 411 | .has_mux = true, |
| 392 | 412 | .available_scan_masks = ad7380_2x2_channel_scan_masks, |
| 393 | 413 | .timing_specs = &ad7380_timing, |
| @@ -398,6 +418,8 @@ static const struct ad7380_chip_info ad7388_chip_info = { · 4 unmodified lines | ||
| 398 | 418 | .channels = ad7388_channels, |
| 399 | 419 | .num_channels = ARRAY_SIZE(ad7388_channels), |
| 400 | 420 | .num_simult_channels = 2, |
| 421 | + .supplies = ad7380_supplies, | |
| 422 | + .num_supplies = ARRAY_SIZE(ad7380_supplies), | |
| 401 | 423 | .has_mux = true, |
| 402 | 424 | .available_scan_masks = ad7380_2x2_channel_scan_masks, |
| 403 | 425 | .timing_specs = &ad7380_timing, |
| @@ -408,6 +430,9 @@ static const struct ad7380_chip_info ad7380_4_chip_info = { · 4 unmodified lines | ||
| 408 | 430 | .channels = ad7380_4_channels, |
| 409 | 431 | .num_channels = ARRAY_SIZE(ad7380_4_channels), |
| 410 | 432 | .num_simult_channels = 4, |
| 433 | + .supplies = ad7380_supplies, | |
| 434 | + .num_supplies = ARRAY_SIZE(ad7380_supplies), | |
| 435 | + .external_ref_only = true, | |
| 411 | 436 | .available_scan_masks = ad7380_4_channel_scan_masks, |
| 412 | 437 | .timing_specs = &ad7380_4_timing, |
| 413 | 438 | }; |
| @@ -417,6 +442,8 @@ static const struct ad7380_chip_info ad7381_4_chip_info = { · 3 unmodified lines | ||
| 417 | 442 | .channels = ad7381_4_channels, |
| 418 | 443 | .num_channels = ARRAY_SIZE(ad7381_4_channels), |
| 419 | 444 | .num_simult_channels = 4, |
| 445 | + .supplies = ad7380_supplies, | |
| 446 | + .num_supplies = ARRAY_SIZE(ad7380_supplies), | |
| 420 | 447 | .available_scan_masks = ad7380_4_channel_scan_masks, |
| 421 | 448 | .timing_specs = &ad7380_4_timing, |
| 422 | 449 | }; |
| @@ -426,6 +453,8 @@ static const struct ad7380_chip_info ad7383_4_chip_info = { · 3 unmodified lines | ||
| 426 | 453 | .channels = ad7383_4_channels, |
| 427 | 454 | .num_channels = ARRAY_SIZE(ad7383_4_channels), |
| 428 | 455 | .num_simult_channels = 4, |
| 456 | + .supplies = ad7380_supplies, | |
| 457 | + .num_supplies = ARRAY_SIZE(ad7380_supplies), | |
| 429 | 458 | .vcm_supplies = ad7380_4_channel_vcm_supplies, |
| 430 | 459 | .num_vcm_supplies = ARRAY_SIZE(ad7380_4_channel_vcm_supplies), |
| 431 | 460 | .available_scan_masks = ad7380_4_channel_scan_masks, |
| @@ -437,6 +466,8 @@ static const struct ad7380_chip_info ad7384_4_chip_info = { · 5 unmodified lines | ||
| 437 | 466 | .channels = ad7384_4_channels, |
| 438 | 467 | .num_channels = ARRAY_SIZE(ad7384_4_channels), |
| 439 | 468 | .num_simult_channels = 4, |
| 469 | + .supplies = ad7380_supplies, | |
| 470 | + .num_supplies = ARRAY_SIZE(ad7380_supplies), | |
| 440 | 471 | .vcm_supplies = ad7380_4_channel_vcm_supplies, |
| 441 | 472 | .num_vcm_supplies = ARRAY_SIZE(ad7380_4_channel_vcm_supplies), |
| 442 | 473 | .available_scan_masks = ad7380_4_channel_scan_masks, |
| @@ -448,6 +479,8 @@ static const struct ad7380_chip_info ad7386_4_chip_info = { · 5 unmodified lines | ||
| 448 | 479 | .channels = ad7386_4_channels, |
| 449 | 480 | .num_channels = ARRAY_SIZE(ad7386_4_channels), |
| 450 | 481 | .num_simult_channels = 4, |
| 482 | + .supplies = ad7380_supplies, | |
| 483 | + .num_supplies = ARRAY_SIZE(ad7380_supplies), | |
| 451 | 484 | .has_mux = true, |
| 452 | 485 | .available_scan_masks = ad7380_2x4_channel_scan_masks, |
| 453 | 486 | .timing_specs = &ad7380_4_timing, |
| @@ -458,6 +491,8 @@ static const struct ad7380_chip_info ad7387_4_chip_info = { · 4 unmodified lines | ||
| 458 | 491 | .channels = ad7387_4_channels, |
| 459 | 492 | .num_channels = ARRAY_SIZE(ad7387_4_channels), |
| 460 | 493 | .num_simult_channels = 4, |
| 494 | + .supplies = ad7380_supplies, | |
| 495 | + .num_supplies = ARRAY_SIZE(ad7380_supplies), | |
| 461 | 496 | .has_mux = true, |
| 462 | 497 | .available_scan_masks = ad7380_2x4_channel_scan_masks, |
| 463 | 498 | .timing_specs = &ad7380_4_timing, |
| @@ -468,6 +503,8 @@ static const struct ad7380_chip_info ad7388_4_chip_info = { · 4 unmodified lines | ||
| 468 | 503 | .channels = ad7388_4_channels, |
| 469 | 504 | .num_channels = ARRAY_SIZE(ad7388_4_channels), |
| 470 | 505 | .num_simult_channels = 4, |
| 506 | + .supplies = ad7380_supplies, | |
| 507 | + .num_supplies = ARRAY_SIZE(ad7380_supplies), | |
| 471 | 508 | .has_mux = true, |
| 472 | 509 | .available_scan_masks = ad7380_2x4_channel_scan_masks, |
| 473 | 510 | .timing_specs = &ad7380_4_timing, |
| @@ -956,7 +993,7 @@ static const struct iio_info ad7380_info = { · 482 unmodified lines | ||
| 956 | 993 | .debugfs_reg_access = &ad7380_debugfs_reg_access, |
| 957 | 994 | }; |
| 958 | 995 | |
| 959 | −static int ad7380_init(struct ad7380_state *st, struct regulator *vref) | |
| 996 | +static int ad7380_init(struct ad7380_state *st, bool external_ref_en) | |
| 960 | 997 | { |
| 961 | 998 | int ret; |
| 962 | 999 | |
| @@ -968,13 +1005,13 @@ static int ad7380_init(struct ad7380_state *st, struct regulator *vref) · 5 unmodified lines | ||
| 968 | 1005 | if (ret < 0) |
| 969 | 1006 | return ret; |
| 970 | 1007 | |
| 971 | − /* select internal or external reference voltage */ | |
| 972 | − ret = regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG1, | |
| 973 | − AD7380_CONFIG1_REFSEL, | |
| 974 | − FIELD_PREP(AD7380_CONFIG1_REFSEL, | |
| 975 | − vref ? 1 : 0)); | |
| 976 | − if (ret < 0) | |
| 977 | − return ret; | |
| 1008 | + if (external_ref_en) { | |
| 1009 | + /* select external reference voltage */ | |
| 1010 | + ret = regmap_set_bits(st->regmap, AD7380_REG_ADDR_CONFIG1, | |
| 1011 | + AD7380_CONFIG1_REFSEL); | |
| 1012 | + if (ret < 0) | |
| 1013 | + return ret; | |
| 1014 | + } | |
| 978 | 1015 | |
| 979 | 1016 | /* This is the default value after reset. */ |
| 980 | 1017 | st->oversampling_ratio = 1; |
| @@ -987,16 +1024,11 @@ static int ad7380_init(struct ad7380_state *st, struct regulator *vref) · 6 unmodified lines | ||
| 987 | 1024 | FIELD_PREP(AD7380_CONFIG2_SDO, 1)); |
| 988 | 1025 | } |
| 989 | 1026 | |
| 990 | −static void ad7380_regulator_disable(void *p) | |
| 991 | −{ | |
| 992 | − regulator_disable(p); | |
| 993 | −} | |
| 994 | − | |
| 995 | 1027 | static int ad7380_probe(struct spi_device *spi) |
| 996 | 1028 | { |
| 997 | 1029 | struct iio_dev *indio_dev; |
| 998 | 1030 | struct ad7380_state *st; |
| 999 | − struct regulator *vref; | |
| 1031 | + bool external_ref_en; | |
| 1000 | 1032 | int ret, i; |
| 1001 | 1033 | |
| 1002 | 1034 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); |
| @@ -1009,36 +1041,38 @@ static int ad7380_probe(struct spi_device *spi) · 6 unmodified lines | ||
| 1009 | 1041 | if (!st->chip_info) |
| 1010 | 1042 | return dev_err_probe(&spi->dev, -EINVAL, "missing match data\n"); |
| 1011 | 1043 | |
| 1012 | − vref = devm_regulator_get_optional(&spi->dev, "refio"); | |
| 1013 | − if (IS_ERR(vref)) { | |
| 1014 | − if (PTR_ERR(vref) != -ENODEV) | |
| 1015 | − return dev_err_probe(&spi->dev, PTR_ERR(vref), | |
| 1016 | − "Failed to get refio regulator\n"); | |
| 1017 | − | |
| 1018 | − vref = NULL; | |
| 1019 | − } | |
| 1044 | + ret = devm_regulator_bulk_get_enable(&spi->dev, st->chip_info->num_supplies, | |
| 1045 | + st->chip_info->supplies); | |
| 1020 | 1046 | |
| 1021 | − /* | |
| 1022 | − * If there is no REFIO supply, then it means that we are using | |
| 1023 | − * the internal 2.5V reference, otherwise REFIO is reference voltage. | |
| 1024 | − */ | |
| 1025 | − if (vref) { | |
| 1026 | − ret = regulator_enable(vref); | |
| 1027 | − if (ret) | |
| 1028 | − return ret; | |
| 1029 | − | |
| 1030 | − ret = devm_add_action_or_reset(&spi->dev, | |
| 1031 | − ad7380_regulator_disable, vref); | |
| 1032 | − if (ret) | |
| 1033 | − return ret; | |
| 1047 | + if (ret) | |
| 1048 | + return dev_err_probe(&spi->dev, ret, | |
| 1049 | + "Failed to enable power supplies\n"); | |
| 1050 | + fsleep(T_POWERUP_US); | |
| 1034 | 1051 | |
| 1035 | − ret = regulator_get_voltage(vref); | |
| 1052 | + if (st->chip_info->external_ref_only) { | |
| 1053 | + ret = devm_regulator_get_enable_read_voltage(&spi->dev, | |
| 1054 | + "refin"); | |
| 1036 | 1055 | if (ret < 0) |
| 1037 | − return ret; | |
| 1056 | + return dev_err_probe(&spi->dev, ret, | |
| 1057 | + "Failed to get refin regulator\n"); | |
| 1038 | 1058 | |
| 1039 | 1059 | st->vref_mv = ret / 1000; |
| 1060 | + | |
| 1061 | + /* these chips don't have a register bit for this */ | |
| 1062 | + external_ref_en = false; | |
| 1040 | 1063 | } else { |
| 1041 | − st->vref_mv = AD7380_INTERNAL_REF_MV; | |
| 1064 | + /* | |
| 1065 | + * If there is no REFIO supply, then it means that we are using | |
| 1066 | + * the internal reference, otherwise REFIO is reference voltage. | |
| 1067 | + */ | |
| 1068 | + ret = devm_regulator_get_enable_read_voltage(&spi->dev, | |
| 1069 | + "refio"); | |
| 1070 | + if (ret < 0 && ret != -ENODEV) | |
| 1071 | + return dev_err_probe(&spi->dev, ret, | |
| 1072 | + "Failed to get refio regulator\n"); | |
| 1073 | + | |
| 1074 | + external_ref_en = ret != -ENODEV; | |
| 1075 | + st->vref_mv = external_ref_en ? ret / 1000 : AD7380_INTERNAL_REF_MV; | |
| 1042 | 1076 | } |
| 1043 | 1077 | |
| 1044 | 1078 | if (st->chip_info->num_vcm_supplies > ARRAY_SIZE(st->vcm_mv)) |
| @@ -1050,27 +1084,13 @@ static int ad7380_probe(struct spi_device *spi) · 5 unmodified lines | ||
| 1050 | 1084 | * input pin. |
| 1051 | 1085 | */ |
| 1052 | 1086 | for (i = 0; i < st->chip_info->num_vcm_supplies; i++) { |
| 1053 | − struct regulator *vcm; | |
| 1054 | − | |
| 1055 | − vcm = devm_regulator_get(&spi->dev, | |
| 1056 | − st->chip_info->vcm_supplies[i]); | |
| 1057 | − if (IS_ERR(vcm)) | |
| 1058 | − return dev_err_probe(&spi->dev, PTR_ERR(vcm), | |
| 1059 | − "Failed to get %s regulator\n", | |
| 1060 | − st->chip_info->vcm_supplies[i]); | |
| 1087 | + const char *vcm = st->chip_info->vcm_supplies[i]; | |
| 1061 | 1088 | |
| 1062 | − ret = regulator_enable(vcm); | |
| 1063 | − if (ret) | |
| 1064 | − return ret; | |
| 1065 | − | |
| 1066 | − ret = devm_add_action_or_reset(&spi->dev, | |
| 1067 | − ad7380_regulator_disable, vcm); | |
| 1068 | − if (ret) | |
| 1069 | − return ret; | |
| 1070 | − | |
| 1071 | − ret = regulator_get_voltage(vcm); | |
| 1089 | + ret = devm_regulator_get_enable_read_voltage(&spi->dev, vcm); | |
| 1072 | 1090 | if (ret < 0) |
| 1073 | − return ret; | |
| 1091 | + return dev_err_probe(&spi->dev, ret, | |
| 1092 | + "Failed to get %s regulator\n", | |
| 1093 | + vcm); | |
| 1074 | 1094 | |
| 1075 | 1095 | st->vcm_mv[i] = ret / 1000; |
| 1076 | 1096 | } |
| @@ -1135,7 +1155,7 @@ static int ad7380_probe(struct spi_device *spi) · 58 unmodified lines | ||
| 1135 | 1155 | if (ret) |
| 1136 | 1156 | return ret; |
| 1137 | 1157 | |
| 1138 | − ret = ad7380_init(st, vref); | |
| 1158 | + ret = ad7380_init(st, external_ref_en); | |
| 1139 | 1159 | if (ret) |
| 1140 | 1160 | return ret; |
| 1141 | 1161 | |
| @@ -27,6 +27,7 @@ config AD8366 · 26 unmodified lines | ||
| 27 | 27 | config ADA4250 |
| 28 | 28 | tristate "Analog Devices ADA4250 Instrumentation Amplifier" |
| 29 | 29 | depends on SPI |
| 30 | + select REGMAP_SPI | |
| 30 | 31 | help |
| 31 | 32 | Say yes here to build support for Analog Devices ADA4250 |
| 32 | 33 | SPI Amplifier's support. The driver provides direct access via |
| @@ -80,6 +80,8 @@ config ENS160 · 79 unmodified lines | ||
| 80 | 80 | tristate "ScioSense ENS160 sensor driver" |
| 81 | 81 | depends on (I2C || SPI) |
| 82 | 82 | select REGMAP |
| 83 | + select IIO_BUFFER | |
| 84 | + select IIO_TRIGGERED_BUFFER | |
| 83 | 85 | select ENS160_I2C if I2C |
| 84 | 86 | select ENS160_SPI if SPI |
| 85 | 87 | help |
| @@ -32,7 +32,7 @@ static ssize_t _hid_sensor_set_report_latency(struct device *dev, · 31 unmodified lines | ||
| 32 | 32 | latency = integer * 1000 + fract / 1000; |
| 33 | 33 | ret = hid_sensor_set_report_latency(attrb, latency); |
| 34 | 34 | if (ret < 0) |
| 35 | − return len; | |
| 35 | + return ret; | |
| 36 | 36 | |
| 37 | 37 | attrb->latency_ms = hid_sensor_get_report_latency(attrb); |
| 38 | 38 | |
| @@ -9,6 +9,8 @@ menu "Digital to analog converters" · 8 unmodified lines | ||
| 9 | 9 | config AD3552R |
| 10 | 10 | tristate "Analog Devices AD3552R DAC driver" |
| 11 | 11 | depends on SPI_MASTER |
| 12 | + select IIO_BUFFER | |
| 13 | + select IIO_TRIGGERED_BUFFER | |
| 12 | 14 | help |
| 13 | 15 | Say yes here to build support for Analog Devices AD3552R |
| 14 | 16 | Digital to Analog Converter. |
| @@ -252,6 +254,8 @@ config AD5764 · 237 unmodified lines | ||
| 252 | 254 | config AD5766 |
| 253 | 255 | tristate "Analog Devices AD5766/AD5767 DAC driver" |
| 254 | 256 | depends on SPI_MASTER |
| 257 | + select IIO_BUFFER | |
| 258 | + select IIO_TRIGGERED_BUFFER | |
| 255 | 259 | help |
| 256 | 260 | Say yes here to build support for Analog Devices AD5766, AD5767 |
| 257 | 261 | Digital to Analog Converter. |
| @@ -262,6 +266,7 @@ config AD5766 · 4 unmodified lines | ||
| 262 | 266 | config AD5770R |
| 263 | 267 | tristate "Analog Devices AD5770R IDAC driver" |
| 264 | 268 | depends on SPI_MASTER |
| 269 | + select REGMAP_SPI | |
| 265 | 270 | help |
| 266 | 271 | Say yes here to build support for Analog Devices AD5770R Digital to |
| 267 | 272 | Analog Converter. |
| @@ -353,6 +358,7 @@ config LPC18XX_DAC · 85 unmodified lines | ||
| 353 | 358 | config LTC1660 |
| 354 | 359 | tristate "Linear Technology LTC1660/LTC1665 DAC SPI driver" |
| 355 | 360 | depends on SPI |
| 361 | + select REGMAP_SPI | |
| 356 | 362 | help |
| 357 | 363 | Say yes here to build support for Linear Technology |
| 358 | 364 | LTC1660 and LTC1665 Digital to Analog Converters. |
| @@ -374,7 +380,7 @@ config LTC2632 · 15 unmodified lines | ||
| 374 | 380 | config LTC2664 |
| 375 | 381 | tristate "Analog Devices LTC2664 and LTC2672 DAC SPI driver" |
| 376 | 382 | depends on SPI |
| 377 | − select REGMAP | |
| 383 | + select REGMAP_SPI | |
| 378 | 384 | help |
| 379 | 385 | Say yes here to build support for Analog Devices |
| 380 | 386 | LTC2664 and LTC2672 converters (DAC). |
| @@ -483,6 +489,7 @@ config STM32_DAC · 102 unmodified lines | ||
| 483 | 489 | |
| 484 | 490 | config STM32_DAC_CORE |
| 485 | 491 | tristate |
| 492 | + select REGMAP_MMIO | |
| 486 | 493 | |
| 487 | 494 | config TI_DAC082S085 |
| 488 | 495 | tristate "Texas Instruments 8/10/12-bit 2/4-channel DAC driver" |
| @@ -516,7 +516,7 @@ static int ltc2664_channel_config(struct ltc2664_state *st) · 515 unmodified lines | ||
| 516 | 516 | const struct ltc2664_chip_info *chip_info = st->chip_info; |
| 517 | 517 | struct device *dev = &st->spi->dev; |
| 518 | 518 | u32 reg, tmp[2], mspan; |
| 519 | − int ret, span = 0; | |
| 519 | + int ret; | |
| 520 | 520 | |
| 521 | 521 | mspan = LTC2664_MSPAN_SOFTSPAN; |
| 522 | 522 | ret = device_property_read_u32(dev, "adi,manual-span-operation-config", |
| @@ -579,20 +579,21 @@ static int ltc2664_channel_config(struct ltc2664_state *st) · 56 unmodified lines | ||
| 579 | 579 | ret = fwnode_property_read_u32_array(child, "output-range-microvolt", |
| 580 | 580 | tmp, ARRAY_SIZE(tmp)); |
| 581 | 581 | if (!ret && mspan == LTC2664_MSPAN_SOFTSPAN) { |
| 582 | − chan->span = ltc2664_set_span(st, tmp[0] / 1000, | |
| 583 | − tmp[1] / 1000, reg); | |
| 584 | − if (span < 0) | |
| 585 | − return dev_err_probe(dev, span, | |
| 582 | + ret = ltc2664_set_span(st, tmp[0] / 1000, tmp[1] / 1000, reg); | |
| 583 | + if (ret < 0) | |
| 584 | + return dev_err_probe(dev, ret, | |
| 586 | 585 | "Failed to set span\n"); |
| 586 | + chan->span = ret; | |
| 587 | 587 | } |
| 588 | 588 | |
| 589 | 589 | ret = fwnode_property_read_u32_array(child, "output-range-microamp", |
| 590 | 590 | tmp, ARRAY_SIZE(tmp)); |
| 591 | 591 | if (!ret) { |
| 592 | − chan->span = ltc2664_set_span(st, 0, tmp[1] / 1000, reg); | |
| 593 | − if (span < 0) | |
| 594 | − return dev_err_probe(dev, span, | |
| 592 | + ret = ltc2664_set_span(st, 0, tmp[1] / 1000, reg); | |
| 593 | + if (ret < 0) | |
| 594 | + return dev_err_probe(dev, ret, | |
| 595 | 595 | "Failed to set span\n"); |
| 596 | + chan->span = ret; | |
| 596 | 597 | } |
| 597 | 598 | } |
| 598 | 599 | |
| @@ -53,6 +53,7 @@ config ADF4371 · 52 unmodified lines | ||
| 53 | 53 | config ADF4377 |
| 54 | 54 | tristate "Analog Devices ADF4377 Microwave Wideband Synthesizer" |
| 55 | 55 | depends on SPI && COMMON_CLK |
| 56 | + select REGMAP_SPI | |
| 56 | 57 | help |
| 57 | 58 | Say yes here to build support for Analog Devices ADF4377 Microwave |
| 58 | 59 | Wideband Synthesizer. |
| @@ -91,25 +92,26 @@ config ADMV1014 · 32 unmodified lines | ||
| 91 | 92 | module will be called admv1014. |
| 92 | 93 | |
| 93 | 94 | config ADMV4420 |
| 94 | − tristate "Analog Devices ADMV4420 K Band Downconverter" | |
| 95 | − depends on SPI | |
| 96 | − help | |
| 97 | − Say yes here to build support for Analog Devices K Band | |
| 98 | − Downconverter with integrated Fractional-N PLL and VCO. | |
| 95 | + tristate "Analog Devices ADMV4420 K Band Downconverter" | |
| 96 | + depends on SPI | |
| 97 | + select REGMAP_SPI | |
| 98 | + help | |
| 99 | + Say yes here to build support for Analog Devices K Band | |
| 100 | + Downconverter with integrated Fractional-N PLL and VCO. | |
| 99 | 101 | |
| 100 | − To compile this driver as a module, choose M here: the | |
| 101 | − module will be called admv4420. | |
| 102 | + To compile this driver as a module, choose M here: the | |
| 103 | + module will be called admv4420. | |
| 102 | 104 | |
| 103 | 105 | config ADRF6780 |
| 104 | − tristate "Analog Devices ADRF6780 Microwave Upconverter" | |
| 105 | − depends on SPI | |
| 106 | − depends on COMMON_CLK | |
| 107 | − help | |
| 108 | − Say yes here to build support for Analog Devices ADRF6780 | |
| 109 | − 5.9 GHz to 23.6 GHz, Wideband, Microwave Upconverter. | |
| 110 | − | |
| 111 | − To compile this driver as a module, choose M here: the | |
| 112 | − module will be called adrf6780. | |
| 106 | + tristate "Analog Devices ADRF6780 Microwave Upconverter" | |
| 107 | + depends on SPI | |
| 108 | + depends on COMMON_CLK | |
| 109 | + help | |
| 110 | + Say yes here to build support for Analog Devices ADRF6780 | |
| 111 | + 5.9 GHz to 23.6 GHz, Wideband, Microwave Upconverter. | |
| 112 | + | |
| 113 | + To compile this driver as a module, choose M here: the | |
| 114 | + module will be called adrf6780. | |
| 113 | 115 | |
| 114 | 116 | endmenu |
| 115 | 117 | endmenu |
| @@ -2172,7 +2172,6 @@ int bmi323_core_probe(struct device *dev) · 2171 unmodified lines | ||
| 2172 | 2172 | } |
| 2173 | 2173 | EXPORT_SYMBOL_NS_GPL(bmi323_core_probe, IIO_BMI323); |
| 2174 | 2174 | |
| 2175 | −#if defined(CONFIG_PM) | |
| 2176 | 2175 | static int bmi323_core_runtime_suspend(struct device *dev) |
| 2177 | 2176 | { |
| 2178 | 2177 | struct iio_dev *indio_dev = dev_get_drvdata(dev); |
| @@ -2199,12 +2198,12 @@ static int bmi323_core_runtime_suspend(struct device *dev) · 20 unmodified lines | ||
| 2199 | 2198 | } |
| 2200 | 2199 | |
| 2201 | 2200 | for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_ext_reg_savestate); i++) { |
| 2202 | − ret = bmi323_read_ext_reg(data, bmi323_reg_savestate[i], | |
| 2203 | − &savestate->reg_settings[i]); | |
| 2201 | + ret = bmi323_read_ext_reg(data, bmi323_ext_reg_savestate[i], | |
| 2202 | + &savestate->ext_reg_settings[i]); | |
| 2204 | 2203 | if (ret) { |
| 2205 | 2204 | dev_err(data->dev, |
| 2206 | 2205 | "Error reading bmi323 external reg 0x%x: %d\n", |
| 2207 | − bmi323_reg_savestate[i], ret); | |
| 2206 | + bmi323_ext_reg_savestate[i], ret); | |
| 2208 | 2207 | return ret; |
| 2209 | 2208 | } |
| 2210 | 2209 | } |
| @@ -2232,8 +2231,10 @@ static int bmi323_core_runtime_resume(struct device *dev) · 21 unmodified lines | ||
| 2232 | 2231 | * after being reset in the lower power state by runtime-pm. |
| 2233 | 2232 | */ |
| 2234 | 2233 | ret = bmi323_init(data); |
| 2235 | − if (!ret) | |
| 2234 | + if (ret) { | |
| 2235 | + dev_err(data->dev, "Device power-on and init failed: %d", ret); | |
| 2236 | 2236 | return ret; |
| 2237 | + } | |
| 2237 | 2238 | |
| 2238 | 2239 | /* Register must be cleared before changing an active config */ |
| 2239 | 2240 | ret = regmap_write(data->regmap, BMI323_FEAT_IO0_REG, 0); |
| @@ -2243,12 +2244,12 @@ static int bmi323_core_runtime_resume(struct device *dev) · 3 unmodified lines | ||
| 2243 | 2244 | } |
| 2244 | 2245 | |
| 2245 | 2246 | for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_ext_reg_savestate); i++) { |
| 2246 | − ret = bmi323_write_ext_reg(data, bmi323_reg_savestate[i], | |
| 2247 | − savestate->reg_settings[i]); | |
| 2247 | + ret = bmi323_write_ext_reg(data, bmi323_ext_reg_savestate[i], | |
| 2248 | + savestate->ext_reg_settings[i]); | |
| 2248 | 2249 | if (ret) { |
| 2249 | 2250 | dev_err(data->dev, |
| 2250 | 2251 | "Error writing bmi323 external reg 0x%x: %d\n", |
| 2251 | − bmi323_reg_savestate[i], ret); | |
| 2252 | + bmi323_ext_reg_savestate[i], ret); | |
| 2252 | 2253 | return ret; |
| 2253 | 2254 | } |
| 2254 | 2255 | } |
| @@ -2293,11 +2294,9 @@ static int bmi323_core_runtime_resume(struct device *dev) · 38 unmodified lines | ||
| 2293 | 2294 | return iio_device_resume_triggering(indio_dev); |
| 2294 | 2295 | } |
| 2295 | 2296 | |
| 2296 | −#endif | |
| 2297 | − | |
| 2298 | 2297 | const struct dev_pm_ops bmi323_core_pm_ops = { |
| 2299 | − SET_RUNTIME_PM_OPS(bmi323_core_runtime_suspend, | |
| 2300 | − bmi323_core_runtime_resume, NULL) | |
| 2298 | + RUNTIME_PM_OPS(bmi323_core_runtime_suspend, | |
| 2299 | + bmi323_core_runtime_resume, NULL) | |
| 2301 | 2300 | }; |
| 2302 | 2301 | EXPORT_SYMBOL_NS_GPL(bmi323_core_pm_ops, IIO_BMI323); |
| 2303 | 2302 | |
| @@ -307,13 +307,15 @@ static int iio_gts_build_avail_scale_table(struct iio_gts *gts) · 306 unmodified lines | ||
| 307 | 307 | if (ret) |
| 308 | 308 | goto err_free_out; |
| 309 | 309 | |
| 310 | + for (i = 0; i < gts->num_itime; i++) | |
| 311 | + kfree(per_time_gains[i]); | |
| 310 | 312 | kfree(per_time_gains); |
| 311 | 313 | gts->per_time_avail_scale_tables = per_time_scales; |
| 312 | 314 | |
| 313 | 315 | return 0; |
| 314 | 316 | |
| 315 | 317 | err_free_out: |
| 316 | − for (i--; i; i--) { | |
| 318 | + for (i--; i >= 0; i--) { | |
| 317 | 319 | kfree(per_time_scales[i]); |
| 318 | 320 | kfree(per_time_gains[i]); |
| 319 | 321 | } |
| @@ -335,6 +335,8 @@ config ROHM_BU27008 · 334 unmodified lines | ||
| 335 | 335 | depends on I2C |
| 336 | 336 | select REGMAP_I2C |
| 337 | 337 | select IIO_GTS_HELPER |
| 338 | + select IIO_BUFFER | |
| 339 | + select IIO_TRIGGERED_BUFFER | |
| 338 | 340 | help |
| 339 | 341 | Enable support for the ROHM BU27008 color sensor. |
| 340 | 342 | The ROHM BU27008 is a sensor with 5 photodiodes (red, green, |
| @@ -138,6 +138,10 @@ static const struct opt3001_scale opt3001_scales[] = { · 137 unmodified lines | ||
| 138 | 138 | .val = 20966, |
| 139 | 139 | .val2 = 400000, |
| 140 | 140 | }, |
| 141 | + { | |
| 142 | + .val = 41932, | |
| 143 | + .val2 = 800000, | |
| 144 | + }, | |
| 141 | 145 | { |
| 142 | 146 | .val = 83865, |
| 143 | 147 | .val2 = 600000, |
| @@ -99,9 +99,8 @@ static const char * const period_values[] = { · 98 unmodified lines | ||
| 99 | 99 | static ssize_t in_illuminance_period_available_show(struct device *dev, |
| 100 | 100 | struct device_attribute *attr, char *buf) |
| 101 | 101 | { |
| 102 | + struct veml6030_data *data = iio_priv(dev_to_iio_dev(dev)); | |
| 102 | 103 | int ret, reg, x; |
| 103 | − struct iio_dev *indio_dev = i2c_get_clientdata(to_i2c_client(dev)); | |
| 104 | − struct veml6030_data *data = iio_priv(indio_dev); | |
| 105 | 104 | |
| 106 | 105 | ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, ®); |
| 107 | 106 | if (ret) { |
| @@ -523,7 +522,7 @@ static int veml6030_read_raw(struct iio_dev *indio_dev, · 415 unmodified lines | ||
| 523 | 522 | } |
| 524 | 523 | if (mask == IIO_CHAN_INFO_PROCESSED) { |
| 525 | 524 | *val = (reg * data->cur_resolution) / 10000; |
| 526 | − *val2 = (reg * data->cur_resolution) % 10000; | |
| 525 | + *val2 = (reg * data->cur_resolution) % 10000 * 100; | |
| 527 | 526 | return IIO_VAL_INT_PLUS_MICRO; |
| 528 | 527 | } |
| 529 | 528 | *val = reg; |
| @@ -780,7 +779,7 @@ static int veml6030_hw_init(struct iio_dev *indio_dev) · 250 unmodified lines | ||
| 780 | 779 | |
| 781 | 780 | /* Cache currently active measurement parameters */ |
| 782 | 781 | data->cur_gain = 3; |
| 783 | − data->cur_resolution = 4608; | |
| 782 | + data->cur_resolution = 5376; | |
| 784 | 783 | data->cur_integration_time = 3; |
| 785 | 784 | |
| 786 | 785 | return ret; |
| @@ -11,6 +11,8 @@ config AF8133J · 10 unmodified lines | ||
| 11 | 11 | depends on I2C |
| 12 | 12 | depends on OF |
| 13 | 13 | select REGMAP_I2C |
| 14 | + select IIO_BUFFER | |
| 15 | + select IIO_TRIGGERED_BUFFER | |
| 14 | 16 | help |
| 15 | 17 | Say yes here to build support for Voltafield AF8133J I2C-based |
| 16 | 18 | 3-axis magnetometer chip. |
| @@ -19,6 +19,9 @@ config ABP060MG · 18 unmodified lines | ||
| 19 | 19 | config ROHM_BM1390 |
| 20 | 20 | tristate "ROHM BM1390GLV-Z pressure sensor driver" |
| 21 | 21 | depends on I2C |
| 22 | + select REGMAP_I2C | |
| 23 | + select IIO_BUFFER | |
| 24 | + select IIO_TRIGGERED_BUFFER | |
| 22 | 25 | help |
| 23 | 26 | Support for the ROHM BM1390 pressure sensor. The BM1390GLV-Z |
| 24 | 27 | can measure pressures ranging from 300 hPa to 1300 hPa with |
| @@ -253,6 +256,7 @@ config MS5637 · 228 unmodified lines | ||
| 253 | 256 | config SDP500 |
| 254 | 257 | tristate "Sensirion SDP500 differential pressure sensor I2C driver" |
| 255 | 258 | depends on I2C |
| 259 | + select CRC8 | |
| 256 | 260 | help |
| 257 | 261 | Say Y here to build support for Sensirion SDP500 differential pressure |
| 258 | 262 | sensor I2C driver. |
| @@ -86,6 +86,8 @@ config LIDAR_LITE_V2 · 85 unmodified lines | ||
| 86 | 86 | config MB1232 |
| 87 | 87 | tristate "MaxSonar I2CXL family ultrasonic sensors" |
| 88 | 88 | depends on I2C |
| 89 | + select IIO_BUFFER | |
| 90 | + select IIO_TRIGGERED_BUFFER | |
| 89 | 91 | help |
| 90 | 92 | Say Y to build a driver for the ultrasonic sensors I2CXL of |
| 91 | 93 | MaxBotix which have an i2c interface. It can be used to measure |
| @@ -31,6 +31,9 @@ config AD2S1210 · 30 unmodified lines | ||
| 31 | 31 | depends on SPI |
| 32 | 32 | depends on COMMON_CLK |
| 33 | 33 | depends on GPIOLIB || COMPILE_TEST |
| 34 | + select REGMAP | |
| 35 | + select IIO_BUFFER | |
| 36 | + select IIO_TRIGGERED_BUFFER | |
| 34 | 37 | help |
| 35 | 38 | Say yes here to build support for Analog Devices spi resolver |
| 36 | 39 | to digital converters, ad2s1210, provides direct access via sysfs. |
| @@ -269,6 +269,8 @@ rdma_find_ndev_for_src_ip_rcu(struct net *net, const struct sockaddr *src_in) · 268 unmodified lines | ||
| 269 | 269 | break; |
| 270 | 270 | #endif |
| 271 | 271 | } |
| 272 | + if (!ret && dev && is_vlan_dev(dev)) | |
| 273 | + dev = vlan_dev_real_dev(dev); | |
| 272 | 274 | return ret ? ERR_PTR(ret) : dev; |
| 273 | 275 | } |
| 274 | 276 | |
| @@ -2816,6 +2816,8 @@ int rdma_nl_notify_event(struct ib_device *device, u32 port_num, · 2815 unmodified lines | ||
| 2816 | 2816 | nlh = nlmsg_put(skb, 0, 0, |
| 2817 | 2817 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_MONITOR), |
| 2818 | 2818 | 0, 0); |
| 2819 | + if (!nlh) | |
| 2820 | + goto err_free; | |
| 2819 | 2821 | |
| 2820 | 2822 | switch (type) { |
| 2821 | 2823 | case RDMA_REGISTER_EVENT: |
| @@ -366,7 +366,7 @@ int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev, · 365 unmodified lines | ||
| 366 | 366 | goto done; |
| 367 | 367 | } |
| 368 | 368 | } |
| 369 | − if (rdev->pacing.dbr_pacing) | |
| 369 | + if (rdev->pacing.dbr_pacing && bnxt_qplib_is_chip_gen_p5_p7(rdev->chip_ctx)) | |
| 370 | 370 | bnxt_re_copy_db_pacing_stats(rdev, stats); |
| 371 | 371 | } |
| 372 | 372 | |
| @@ -1307,7 +1307,11 @@ static int bnxt_re_init_sq_attr(struct bnxt_re_qp *qp, · 1306 unmodified lines | ||
| 1307 | 1307 | 0 : BNXT_QPLIB_RESERVED_QP_WRS; |
| 1308 | 1308 | entries = bnxt_re_init_depth(entries + diff + 1, uctx); |
| 1309 | 1309 | sq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + diff + 1); |
| 1310 | − sq->max_sw_wqe = bnxt_qplib_get_depth(sq, qplqp->wqe_mode, true); | |
| 1310 | + if (qplqp->wqe_mode == BNXT_QPLIB_WQE_MODE_VARIABLE) | |
| 1311 | + sq->max_sw_wqe = bnxt_qplib_get_depth(sq, qplqp->wqe_mode, true); | |
| 1312 | + else | |
| 1313 | + sq->max_sw_wqe = sq->max_wqe; | |
| 1314 | + | |
| 1311 | 1315 | } |
| 1312 | 1316 | sq->q_full_delta = diff + 1; |
| 1313 | 1317 | /* |
| @@ -188,8 +188,11 @@ static int bnxt_re_setup_chip_ctx(struct bnxt_re_dev *rdev) · 187 unmodified lines | ||
| 188 | 188 | |
| 189 | 189 | bnxt_re_set_db_offset(rdev); |
| 190 | 190 | rc = bnxt_qplib_map_db_bar(&rdev->qplib_res); |
| 191 | − if (rc) | |
| 191 | + if (rc) { | |
| 192 | + kfree(rdev->chip_ctx); | |
| 193 | + rdev->chip_ctx = NULL; | |
| 192 | 194 | return rc; |
| 195 | + } | |
| 193 | 196 | |
| 194 | 197 | if (bnxt_qplib_determine_atomics(en_dev->pdev)) |
| 195 | 198 | ibdev_info(&rdev->ibdev, |
| @@ -531,6 +534,7 @@ static bool is_dbr_fifo_full(struct bnxt_re_dev *rdev) · 335 unmodified lines | ||
| 531 | 534 | static void __wait_for_fifo_occupancy_below_th(struct bnxt_re_dev *rdev) |
| 532 | 535 | { |
| 533 | 536 | struct bnxt_qplib_db_pacing_data *pacing_data = rdev->qplib_res.pacing_data; |
| 537 | + u32 retry_fifo_check = 1000; | |
| 534 | 538 | u32 fifo_occup; |
| 535 | 539 | |
| 536 | 540 | /* loop shouldn't run infintely as the occupancy usually goes |
| @@ -544,6 +548,14 @@ static void __wait_for_fifo_occupancy_below_th(struct bnxt_re_dev *rdev) · 7 unmodified lines | ||
| 544 | 548 | |
| 545 | 549 | if (fifo_occup < pacing_data->pacing_th) |
| 546 | 550 | break; |
| 551 | + if (!retry_fifo_check--) { | |
| 552 | + dev_info_once(rdev_to_dev(rdev), | |
| 553 | + "%s: fifo_occup = 0x%xfifo_max_depth = 0x%x pacing_th = 0x%x\n", | |
| 554 | + __func__, fifo_occup, pacing_data->fifo_max_depth, | |
| 555 | + pacing_data->pacing_th); | |
| 556 | + break; | |
| 557 | + } | |
| 558 | + | |
| 547 | 559 | } |
| 548 | 560 | } |
| 549 | 561 | |
| @@ -957,7 +969,7 @@ static int bnxt_re_register_ib(struct bnxt_re_dev *rdev) · 407 unmodified lines | ||
| 957 | 969 | return ib_register_device(ibdev, "bnxt_re%d", &rdev->en_dev->pdev->dev); |
| 958 | 970 | } |
| 959 | 971 | |
| 960 | −static struct bnxt_re_dev *bnxt_re_dev_add(struct bnxt_aux_priv *aux_priv, | |
| 972 | +static struct bnxt_re_dev *bnxt_re_dev_add(struct auxiliary_device *adev, | |
| 961 | 973 | struct bnxt_en_dev *en_dev) |
| 962 | 974 | { |
| 963 | 975 | struct bnxt_re_dev *rdev; |
| @@ -973,6 +985,7 @@ static struct bnxt_re_dev *bnxt_re_dev_add(struct bnxt_aux_priv *aux_priv, · 9 unmodified lines | ||
| 973 | 985 | rdev->nb.notifier_call = NULL; |
| 974 | 986 | rdev->netdev = en_dev->net; |
| 975 | 987 | rdev->en_dev = en_dev; |
| 988 | + rdev->adev = adev; | |
| 976 | 989 | rdev->id = rdev->en_dev->pdev->devfn; |
| 977 | 990 | INIT_LIST_HEAD(&rdev->qp_list); |
| 978 | 991 | mutex_init(&rdev->qp_lock); |
| @@ -1025,12 +1038,15 @@ static int bnxt_re_handle_unaffi_async_event(struct creq_func_event · 46 unmodified lines | ||
| 1025 | 1038 | static int bnxt_re_handle_qp_async_event(struct creq_qp_event *qp_event, |
| 1026 | 1039 | struct bnxt_re_qp *qp) |
| 1027 | 1040 | { |
| 1028 | − struct bnxt_re_srq *srq = container_of(qp->qplib_qp.srq, struct bnxt_re_srq, | |
| 1029 | − qplib_srq); | |
| 1030 | 1041 | struct creq_qp_error_notification *err_event; |
| 1042 | + struct bnxt_re_srq *srq = NULL; | |
| 1031 | 1043 | struct ib_event event = {}; |
| 1032 | 1044 | unsigned int flags; |
| 1033 | 1045 | |
| 1046 | + if (qp->qplib_qp.srq) | |
| 1047 | + srq = container_of(qp->qplib_qp.srq, struct bnxt_re_srq, | |
| 1048 | + qplib_srq); | |
| 1049 | + | |
| 1034 | 1050 | if (qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR && |
| 1035 | 1051 | rdma_is_kernel_res(&qp->ib_qp.res)) { |
| 1036 | 1052 | flags = bnxt_re_lock_cqs(qp); |
| @@ -1258,15 +1274,9 @@ static int bnxt_re_cqn_handler(struct bnxt_qplib_nq *nq, · 221 unmodified lines | ||
| 1258 | 1274 | { |
| 1259 | 1275 | struct bnxt_re_cq *cq = container_of(handle, struct bnxt_re_cq, |
| 1260 | 1276 | qplib_cq); |
| 1261 | − u32 *cq_ptr; | |
| 1262 | 1277 | |
| 1263 | − if (cq->ib_cq.comp_handler) { | |
| 1264 | − if (cq->uctx_cq_page) { | |
| 1265 | − cq_ptr = (u32 *)cq->uctx_cq_page; | |
| 1266 | − *cq_ptr = cq->qplib_cq.toggle; | |
| 1267 | − } | |
| 1278 | + if (cq->ib_cq.comp_handler) | |
| 1268 | 1279 | (*cq->ib_cq.comp_handler)(&cq->ib_cq, cq->ib_cq.cq_context); |
| 1269 | − } | |
| 1270 | 1280 | |
| 1271 | 1281 | return 0; |
| 1272 | 1282 | } |
| @@ -1823,7 +1833,6 @@ static void bnxt_re_update_en_info_rdev(struct bnxt_re_dev *rdev, · 550 unmodified lines | ||
| 1823 | 1833 | */ |
| 1824 | 1834 | rtnl_lock(); |
| 1825 | 1835 | en_info->rdev = rdev; |
| 1826 | − rdev->adev = adev; | |
| 1827 | 1836 | rtnl_unlock(); |
| 1828 | 1837 | } |
| 1829 | 1838 | |
| @@ -1840,7 +1849,7 @@ static int bnxt_re_add_device(struct auxiliary_device *adev, u8 op_type) · 10 unmodified lines | ||
| 1840 | 1849 | en_dev = en_info->en_dev; |
| 1841 | 1850 | |
| 1842 | 1851 | |
| 1843 | − rdev = bnxt_re_dev_add(aux_priv, en_dev); | |
| 1852 | + rdev = bnxt_re_dev_add(adev, en_dev); | |
| 1844 | 1853 | if (!rdev || !rdev_to_dev(rdev)) { |
| 1845 | 1854 | rc = -ENOMEM; |
| 1846 | 1855 | goto exit; |
| @@ -1865,12 +1874,14 @@ static int bnxt_re_add_device(struct auxiliary_device *adev, u8 op_type) · 18 unmodified lines | ||
| 1865 | 1874 | rdev->nb.notifier_call = NULL; |
| 1866 | 1875 | pr_err("%s: Cannot register to netdevice_notifier", |
| 1867 | 1876 | ROCE_DRV_MODULE_NAME); |
| 1868 | − return rc; | |
| 1877 | + goto re_dev_unreg; | |
| 1869 | 1878 | } |
| 1870 | 1879 | bnxt_re_setup_cc(rdev, true); |
| 1871 | 1880 | |
| 1872 | 1881 | return 0; |
| 1873 | 1882 | |
| 1883 | +re_dev_unreg: | |
| 1884 | + ib_unregister_device(&rdev->ibdev); | |
| 1874 | 1885 | re_dev_uninit: |
| 1875 | 1886 | bnxt_re_update_en_info_rdev(NULL, en_info, adev); |
| 1876 | 1887 | bnxt_re_dev_uninit(rdev, BNXT_RE_COMPLETE_REMOVE); |
| @@ -2014,15 +2025,7 @@ static int bnxt_re_probe(struct auxiliary_device *adev, · 137 unmodified lines | ||
| 2014 | 2025 | auxiliary_set_drvdata(adev, en_info); |
| 2015 | 2026 | |
| 2016 | 2027 | rc = bnxt_re_add_device(adev, BNXT_RE_COMPLETE_INIT); |
| 2017 | − if (rc) | |
| 2018 | − goto err; | |
| 2019 | 2028 | mutex_unlock(&bnxt_re_mutex); |
| 2020 | − return 0; | |
| 2021 | − | |
| 2022 | −err: | |
| 2023 | − mutex_unlock(&bnxt_re_mutex); | |
| 2024 | − bnxt_re_remove(adev); | |
| 2025 | − | |
| 2026 | 2029 | return rc; |
| 2027 | 2030 | } |
| 2028 | 2031 | |
| @@ -327,6 +327,7 @@ static void bnxt_qplib_service_nq(struct tasklet_struct *t) · 326 unmodified lines | ||
| 327 | 327 | case NQ_BASE_TYPE_CQ_NOTIFICATION: |
| 328 | 328 | { |
| 329 | 329 | struct nq_cn *nqcne = (struct nq_cn *)nqe; |
| 330 | + struct bnxt_re_cq *cq_p; | |
| 330 | 331 | |
| 331 | 332 | q_handle = le32_to_cpu(nqcne->cq_handle_low); |
| 332 | 333 | q_handle |= (u64)le32_to_cpu(nqcne->cq_handle_high) |
| @@ -337,6 +338,10 @@ static void bnxt_qplib_service_nq(struct tasklet_struct *t) · 4 unmodified lines | ||
| 337 | 338 | cq->toggle = (le16_to_cpu(nqe->info10_type) & |
| 338 | 339 | NQ_CN_TOGGLE_MASK) >> NQ_CN_TOGGLE_SFT; |
| 339 | 340 | cq->dbinfo.toggle = cq->toggle; |
| 341 | + cq_p = container_of(cq, struct bnxt_re_cq, qplib_cq); | |
| 342 | + if (cq_p->uctx_cq_page) | |
| 343 | + *((u32 *)cq_p->uctx_cq_page) = cq->toggle; | |
| 344 | + | |
| 340 | 345 | bnxt_qplib_armen_db(&cq->dbinfo, |
| 341 | 346 | DBC_DBC_TYPE_CQ_ARMENA); |
| 342 | 347 | spin_lock_bh(&cq->compl_lock); |
| @@ -1527,9 +1532,11 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res, · 1184 unmodified lines | ||
| 1527 | 1532 | u32 tbl_indx; |
| 1528 | 1533 | int rc; |
| 1529 | 1534 | |
| 1535 | + spin_lock_bh(&rcfw->tbl_lock); | |
| 1530 | 1536 | tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw); |
| 1531 | 1537 | rcfw->qp_tbl[tbl_indx].qp_id = BNXT_QPLIB_QP_ID_INVALID; |
| 1532 | 1538 | rcfw->qp_tbl[tbl_indx].qp_handle = NULL; |
| 1539 | + spin_unlock_bh(&rcfw->tbl_lock); | |
| 1533 | 1540 | |
| 1534 | 1541 | bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req, |
| 1535 | 1542 | CMDQ_BASE_OPCODE_DESTROY_QP, |
| @@ -1540,8 +1547,10 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res, · 4 unmodified lines | ||
| 1540 | 1547 | sizeof(resp), 0); |
| 1541 | 1548 | rc = bnxt_qplib_rcfw_send_message(rcfw, &msg); |
| 1542 | 1549 | if (rc) { |
| 1550 | + spin_lock_bh(&rcfw->tbl_lock); | |
| 1543 | 1551 | rcfw->qp_tbl[tbl_indx].qp_id = qp->id; |
| 1544 | 1552 | rcfw->qp_tbl[tbl_indx].qp_handle = qp; |
| 1553 | + spin_unlock_bh(&rcfw->tbl_lock); | |
| 1545 | 1554 | return rc; |
| 1546 | 1555 | } |
| 1547 | 1556 | |
| @@ -170,7 +170,7 @@ struct bnxt_qplib_swqe { · 169 unmodified lines | ||
| 170 | 170 | }; |
| 171 | 171 | u32 q_key; |
| 172 | 172 | u32 dst_qp; |
| 173 | − u16 avid; | |
| 173 | + u32 avid; | |
| 174 | 174 | } send; |
| 175 | 175 | |
| 176 | 176 | /* Send Raw Ethernet and QP1 */ |
| @@ -290,7 +290,6 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, · 289 unmodified lines | ||
| 290 | 290 | struct bnxt_qplib_hwq *hwq; |
| 291 | 291 | u32 sw_prod, cmdq_prod; |
| 292 | 292 | struct pci_dev *pdev; |
| 293 | − unsigned long flags; | |
| 294 | 293 | u16 cookie; |
| 295 | 294 | u8 *preq; |
| 296 | 295 | |
| @@ -301,7 +300,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, · 4 unmodified lines | ||
| 301 | 300 | /* Cmdq are in 16-byte units, each request can consume 1 or more |
| 302 | 301 | * cmdqe |
| 303 | 302 | */ |
| 304 | − spin_lock_irqsave(&hwq->lock, flags); | |
| 303 | + spin_lock_bh(&hwq->lock); | |
| 305 | 304 | required_slots = bnxt_qplib_get_cmd_slots(msg->req); |
| 306 | 305 | free_slots = HWQ_FREE_SLOTS(hwq); |
| 307 | 306 | cookie = cmdq->seq_num & RCFW_MAX_COOKIE_VALUE; |
| @@ -311,7 +310,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, · 3 unmodified lines | ||
| 311 | 310 | dev_info_ratelimited(&pdev->dev, |
| 312 | 311 | "CMDQ is full req/free %d/%d!", |
| 313 | 312 | required_slots, free_slots); |
| 314 | − spin_unlock_irqrestore(&hwq->lock, flags); | |
| 313 | + spin_unlock_bh(&hwq->lock); | |
| 315 | 314 | return -EAGAIN; |
| 316 | 315 | } |
| 317 | 316 | if (msg->block) |
| @@ -367,7 +366,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, · 49 unmodified lines | ||
| 367 | 366 | wmb(); |
| 368 | 367 | writel(cmdq_prod, cmdq->cmdq_mbox.prod); |
| 369 | 368 | writel(RCFW_CMDQ_TRIG_VAL, cmdq->cmdq_mbox.db); |
| 370 | − spin_unlock_irqrestore(&hwq->lock, flags); | |
| 369 | + spin_unlock_bh(&hwq->lock); | |
| 371 | 370 | /* Return the CREQ response pointer */ |
| 372 | 371 | return 0; |
| 373 | 372 | } |
| @@ -486,7 +485,6 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw, · 112 unmodified lines | ||
| 486 | 485 | { |
| 487 | 486 | struct creq_qp_event *evnt = (struct creq_qp_event *)msg->resp; |
| 488 | 487 | struct bnxt_qplib_crsqe *crsqe; |
| 489 | − unsigned long flags; | |
| 490 | 488 | u16 cookie; |
| 491 | 489 | int rc; |
| 492 | 490 | u8 opcode; |
| @@ -512,12 +510,12 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw, · 19 unmodified lines | ||
| 512 | 510 | rc = __poll_for_resp(rcfw, cookie); |
| 513 | 511 | |
| 514 | 512 | if (rc) { |
| 515 | − spin_lock_irqsave(&rcfw->cmdq.hwq.lock, flags); | |
| 513 | + spin_lock_bh(&rcfw->cmdq.hwq.lock); | |
| 516 | 514 | crsqe = &rcfw->crsqe_tbl[cookie]; |
| 517 | 515 | crsqe->is_waiter_alive = false; |
| 518 | 516 | if (rc == -ENODEV) |
| 519 | 517 | set_bit(FIRMWARE_STALL_DETECTED, &rcfw->cmdq.flags); |
| 520 | − spin_unlock_irqrestore(&rcfw->cmdq.hwq.lock, flags); | |
| 518 | + spin_unlock_bh(&rcfw->cmdq.hwq.lock); | |
| 521 | 519 | return -ETIMEDOUT; |
| 522 | 520 | } |
| 523 | 521 | |
| @@ -525,7 +523,7 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw, · 1 unmodified line | ||
| 525 | 523 | /* failed with status */ |
| 526 | 524 | dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x status %#x\n", |
| 527 | 525 | cookie, opcode, evnt->status); |
| 528 | − rc = -EFAULT; | |
| 526 | + rc = -EIO; | |
| 529 | 527 | } |
| 530 | 528 | |
| 531 | 529 | return rc; |
| @@ -628,7 +626,6 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, · 96 unmodified lines | ||
| 628 | 626 | u16 cookie, blocked = 0; |
| 629 | 627 | bool is_waiter_alive; |
| 630 | 628 | struct pci_dev *pdev; |
| 631 | − unsigned long flags; | |
| 632 | 629 | u32 wait_cmds = 0; |
| 633 | 630 | int rc = 0; |
| 634 | 631 | |
| @@ -637,17 +634,21 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, · 2 unmodified lines | ||
| 637 | 634 | case CREQ_QP_EVENT_EVENT_QP_ERROR_NOTIFICATION: |
| 638 | 635 | err_event = (struct creq_qp_error_notification *)qp_event; |
| 639 | 636 | qp_id = le32_to_cpu(err_event->xid); |
| 637 | + spin_lock(&rcfw->tbl_lock); | |
| 640 | 638 | tbl_indx = map_qp_id_to_tbl_indx(qp_id, rcfw); |
| 641 | 639 | qp = rcfw->qp_tbl[tbl_indx].qp_handle; |
| 640 | + if (!qp) { | |
| 641 | + spin_unlock(&rcfw->tbl_lock); | |
| 642 | + break; | |
| 643 | + } | |
| 644 | + bnxt_qplib_mark_qp_error(qp); | |
| 645 | + rc = rcfw->creq.aeq_handler(rcfw, qp_event, qp); | |
| 646 | + spin_unlock(&rcfw->tbl_lock); | |
| 642 | 647 | dev_dbg(&pdev->dev, "Received QP error notification\n"); |
| 643 | 648 | dev_dbg(&pdev->dev, |
| 644 | 649 | "qpid 0x%x, req_err=0x%x, resp_err=0x%x\n", |
| 645 | 650 | qp_id, err_event->req_err_state_reason, |
| 646 | 651 | err_event->res_err_state_reason); |
| 647 | − if (!qp) | |
| 648 | − break; | |
| 649 | − bnxt_qplib_mark_qp_error(qp); | |
| 650 | − rc = rcfw->creq.aeq_handler(rcfw, qp_event, qp); | |
| 651 | 652 | break; |
| 652 | 653 | default: |
| 653 | 654 | /* |
| @@ -659,8 +660,7 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, · 5 unmodified lines | ||
| 659 | 660 | * |
| 660 | 661 | */ |
| 661 | 662 | |
| 662 | − spin_lock_irqsave_nested(&hwq->lock, flags, | |
| 663 | − SINGLE_DEPTH_NESTING); | |
| 663 | + spin_lock_nested(&hwq->lock, SINGLE_DEPTH_NESTING); | |
| 664 | 664 | cookie = le16_to_cpu(qp_event->cookie); |
| 665 | 665 | blocked = cookie & RCFW_CMD_IS_BLOCKING; |
| 666 | 666 | cookie &= RCFW_MAX_COOKIE_VALUE; |
| @@ -672,7 +672,7 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, · 5 unmodified lines | ||
| 672 | 672 | dev_info(&pdev->dev, |
| 673 | 673 | "rcfw timedout: cookie = %#x, free_slots = %d", |
| 674 | 674 | cookie, crsqe->free_slots); |
| 675 | − spin_unlock_irqrestore(&hwq->lock, flags); | |
| 675 | + spin_unlock(&hwq->lock); | |
| 676 | 676 | return rc; |
| 677 | 677 | } |
| 678 | 678 | |
| @@ -720,7 +720,7 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, · 41 unmodified lines | ||
| 720 | 720 | __destroy_timedout_ah(rcfw, |
| 721 | 721 | (struct creq_create_ah_resp *) |
| 722 | 722 | qp_event); |
| 723 | − spin_unlock_irqrestore(&hwq->lock, flags); | |
| 723 | + spin_unlock(&hwq->lock); | |
| 724 | 724 | } |
| 725 | 725 | *num_wait += wait_cmds; |
| 726 | 726 | return rc; |
| @@ -734,12 +734,11 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t) · 7 unmodified lines | ||
| 734 | 734 | u32 type, budget = CREQ_ENTRY_POLL_BUDGET; |
| 735 | 735 | struct bnxt_qplib_hwq *hwq = &creq->hwq; |
| 736 | 736 | struct creq_base *creqe; |
| 737 | − unsigned long flags; | |
| 738 | 737 | u32 num_wakeup = 0; |
| 739 | 738 | u32 hw_polled = 0; |
| 740 | 739 | |
| 741 | 740 | /* Service the CREQ until budget is over */ |
| 742 | − spin_lock_irqsave(&hwq->lock, flags); | |
| 741 | + spin_lock_bh(&hwq->lock); | |
| 743 | 742 | while (budget > 0) { |
| 744 | 743 | creqe = bnxt_qplib_get_qe(hwq, hwq->cons, NULL); |
| 745 | 744 | if (!CREQ_CMP_VALID(creqe, creq->creq_db.dbinfo.flags)) |
| @@ -782,7 +781,7 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t) · 36 unmodified lines | ||
| 782 | 781 | if (hw_polled) |
| 783 | 782 | bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, |
| 784 | 783 | rcfw->res->cctx, true); |
| 785 | − spin_unlock_irqrestore(&hwq->lock, flags); | |
| 784 | + spin_unlock_bh(&hwq->lock); | |
| 786 | 785 | if (num_wakeup) |
| 787 | 786 | wake_up_nr(&rcfw->cmdq.waitq, num_wakeup); |
| 788 | 787 | } |
| @@ -978,6 +977,7 @@ int bnxt_qplib_alloc_rcfw_channel(struct bnxt_qplib_res *res, · 189 unmodified lines | ||
| 978 | 977 | GFP_KERNEL); |
| 979 | 978 | if (!rcfw->qp_tbl) |
| 980 | 979 | goto fail; |
| 980 | + spin_lock_init(&rcfw->tbl_lock); | |
| 981 | 981 | |
| 982 | 982 | rcfw->max_timeout = res->cctx->hwrm_cmd_max_timeout; |
| 983 | 983 | |
| @@ -224,6 +224,8 @@ struct bnxt_qplib_rcfw { · 223 unmodified lines | ||
| 224 | 224 | struct bnxt_qplib_crsqe *crsqe_tbl; |
| 225 | 225 | int qp_tbl_size; |
| 226 | 226 | struct bnxt_qplib_qp_node *qp_tbl; |
| 227 | + /* To synchronize the qp-handle hash table */ | |
| 228 | + spinlock_t tbl_lock; | |
| 227 | 229 | u64 oos_prev; |
| 228 | 230 | u32 init_oos_stats; |
| 229 | 231 | u32 cmdq_depth; |
| @@ -244,6 +244,8 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq, · 243 unmodified lines | ||
| 244 | 244 | sginfo.pgsize = npde * pg_size; |
| 245 | 245 | sginfo.npages = 1; |
| 246 | 246 | rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], &sginfo); |
| 247 | + if (rc) | |
| 248 | + goto fail; | |
| 247 | 249 | |
| 248 | 250 | /* Alloc PBL pages */ |
| 249 | 251 | sginfo.npages = npbl; |
| @@ -255,22 +257,9 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq, · 5 unmodified lines | ||
| 255 | 257 | dst_virt_ptr = |
| 256 | 258 | (dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr; |
| 257 | 259 | src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr; |
| 258 | − if (hwq_attr->type == HWQ_TYPE_MR) { | |
| 259 | − /* For MR it is expected that we supply only 1 contigous | |
| 260 | − * page i.e only 1 entry in the PDL that will contain | |
| 261 | − * all the PBLs for the user supplied memory region | |
| 262 | − */ | |
| 263 | − for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; | |
| 264 | − i++) | |
| 265 | − dst_virt_ptr[0][i] = src_phys_ptr[i] | | |
| 266 | − flag; | |
| 267 | − } else { | |
| 268 | − for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; | |
| 269 | − i++) | |
| 270 | − dst_virt_ptr[PTR_PG(i)][PTR_IDX(i)] = | |
| 271 | − src_phys_ptr[i] | | |
| 272 | − PTU_PDE_VALID; | |
| 273 | − } | |
| 260 | + for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; i++) | |
| 261 | + dst_virt_ptr[0][i] = src_phys_ptr[i] | flag; | |
| 262 | + | |
| 274 | 263 | /* Alloc or init PTEs */ |
| 275 | 264 | rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_2], |
| 276 | 265 | hwq_attr->sginfo); |
| @@ -140,6 +140,8 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, · 139 unmodified lines | ||
| 140 | 140 | min_t(u32, sb->max_sge_var_wqe, BNXT_VAR_MAX_SGE) : 6; |
| 141 | 141 | attr->max_cq = le32_to_cpu(sb->max_cq); |
| 142 | 142 | attr->max_cq_wqes = le32_to_cpu(sb->max_cqe); |
| 143 | + if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx)) | |
| 144 | + attr->max_cq_wqes = min_t(u32, BNXT_QPLIB_MAX_CQ_WQES, attr->max_cq_wqes); | |
| 143 | 145 | attr->max_cq_sges = attr->max_qp_sges; |
| 144 | 146 | attr->max_mr = le32_to_cpu(sb->max_mr); |
| 145 | 147 | attr->max_mw = le32_to_cpu(sb->max_mw); |
| @@ -157,7 +159,14 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, · 11 unmodified lines | ||
| 157 | 159 | if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx)) |
| 158 | 160 | attr->l2_db_size = (sb->l2_db_space_size + 1) * |
| 159 | 161 | (0x01 << RCFW_DBR_BASE_PAGE_SHIFT); |
| 160 | − attr->max_sgid = BNXT_QPLIB_NUM_GIDS_SUPPORTED; | |
| 162 | + /* | |
| 163 | + * Read the max gid supported by HW. | |
| 164 | + * For each entry in HW GID in HW table, we consume 2 | |
| 165 | + * GID entries in the kernel GID table. So max_gid reported | |
| 166 | + * to stack can be up to twice the value reported by the HW, up to 256 gids. | |
| 167 | + */ | |
| 168 | + attr->max_sgid = le32_to_cpu(sb->max_gid); | |
| 169 | + attr->max_sgid = min_t(u32, BNXT_QPLIB_NUM_GIDS_SUPPORTED, 2 * attr->max_sgid); | |
| 161 | 170 | attr->dev_cap_flags = le16_to_cpu(sb->dev_cap_flags); |
| 162 | 171 | attr->dev_cap_flags2 = le16_to_cpu(sb->dev_cap_ext_flags_2); |
| 163 | 172 | |
| @@ -56,6 +56,7 @@ struct bnxt_qplib_dev_attr { · 55 unmodified lines | ||
| 56 | 56 | u32 max_qp_wqes; |
| 57 | 57 | u32 max_qp_sges; |
| 58 | 58 | u32 max_cq; |
| 59 | +#define BNXT_QPLIB_MAX_CQ_WQES 0xfffff | |
| 59 | 60 | u32 max_cq_wqes; |
| 60 | 61 | u32 max_cq_sges; |
| 61 | 62 | u32 max_mr; |
| @@ -2086,7 +2086,7 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip, · 2085 unmodified lines | ||
| 2086 | 2086 | err = -ENOMEM; |
| 2087 | 2087 | if (n->dev->flags & IFF_LOOPBACK) { |
| 2088 | 2088 | if (iptype == 4) |
| 2089 | − pdev = ip_dev_find(&init_net, *(__be32 *)peer_ip); | |
| 2089 | + pdev = __ip_dev_find(&init_net, *(__be32 *)peer_ip, false); | |
| 2090 | 2090 | else if (IS_ENABLED(CONFIG_IPV6)) |
| 2091 | 2091 | for_each_netdev(&init_net, pdev) { |
| 2092 | 2092 | if (ipv6_chk_addr(&init_net, |
| @@ -2101,12 +2101,12 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip, · 8 unmodified lines | ||
| 2101 | 2101 | err = -ENODEV; |
| 2102 | 2102 | goto out; |
| 2103 | 2103 | } |
| 2104 | + if (is_vlan_dev(pdev)) | |
| 2105 | + pdev = vlan_dev_real_dev(pdev); | |
| 2104 | 2106 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, |
| 2105 | 2107 | n, pdev, rt_tos2priority(tos)); |
| 2106 | − if (!ep->l2t) { | |
| 2107 | − dev_put(pdev); | |
| 2108 | + if (!ep->l2t) | |
| 2108 | 2109 | goto out; |
| 2109 | − } | |
| 2110 | 2110 | ep->mtu = pdev->mtu; |
| 2111 | 2111 | ep->tx_chan = cxgb4_port_chan(pdev); |
| 2112 | 2112 | ep->smac_idx = ((struct port_info *)netdev_priv(pdev))->smt_idx; |
| @@ -2119,7 +2119,6 @@ static int import_ep(struct c4iw_ep *ep, int iptype, __u8 *peer_ip, · 6 unmodified lines | ||
| 2119 | 2119 | ep->rss_qid = cdev->rdev.lldi.rxq_ids[ |
| 2120 | 2120 | cxgb4_port_idx(pdev) * step]; |
| 2121 | 2121 | set_tcp_window(ep, (struct port_info *)netdev_priv(pdev)); |
| 2122 | − dev_put(pdev); | |
| 2123 | 2122 | } else { |
| 2124 | 2123 | pdev = get_real_dev(n->dev); |
| 2125 | 2124 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, |
| @@ -473,6 +473,7 @@ static const struct ib_device_ops c4iw_dev_ops = { · 472 unmodified lines | ||
| 473 | 473 | .fill_res_cq_entry = c4iw_fill_res_cq_entry, |
| 474 | 474 | .fill_res_cm_id_entry = c4iw_fill_res_cm_id_entry, |
| 475 | 475 | .fill_res_mr_entry = c4iw_fill_res_mr_entry, |
| 476 | + .fill_res_qp_entry = c4iw_fill_res_qp_entry, | |
| 476 | 477 | .get_dev_fw_str = get_dev_fw_str, |
| 477 | 478 | .get_dma_mr = c4iw_get_dma_mr, |
| 478 | 479 | .get_hw_stats = c4iw_get_mib, |
| @@ -3631,7 +3631,7 @@ void irdma_free_lsmm_rsrc(struct irdma_qp *iwqp) · 3630 unmodified lines | ||
| 3631 | 3631 | /** |
| 3632 | 3632 | * irdma_accept - registered call for connection to be accepted |
| 3633 | 3633 | * @cm_id: cm information for passive connection |
| 3634 | − * @conn_param: accpet parameters | |
| 3634 | + * @conn_param: accept parameters | |
| 3635 | 3635 | */ |
| 3636 | 3636 | int irdma_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) |
| 3637 | 3637 | { |
| @@ -4268,14 +4268,14 @@ static int __mlx5_ib_modify_qp(struct ib_qp *ibqp, · 4267 unmodified lines | ||
| 4268 | 4268 | MLX5_SET(qpc, qpc, retry_count, attr->retry_cnt); |
| 4269 | 4269 | |
| 4270 | 4270 | if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && attr->max_rd_atomic) |
| 4271 | − MLX5_SET(qpc, qpc, log_sra_max, ilog2(attr->max_rd_atomic)); | |
| 4271 | + MLX5_SET(qpc, qpc, log_sra_max, fls(attr->max_rd_atomic - 1)); | |
| 4272 | 4272 | |
| 4273 | 4273 | if (attr_mask & IB_QP_SQ_PSN) |
| 4274 | 4274 | MLX5_SET(qpc, qpc, next_send_psn, attr->sq_psn); |
| 4275 | 4275 | |
| 4276 | 4276 | if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC && attr->max_dest_rd_atomic) |
| 4277 | 4277 | MLX5_SET(qpc, qpc, log_rra_max, |
| 4278 | − ilog2(attr->max_dest_rd_atomic)); | |
| 4278 | + fls(attr->max_dest_rd_atomic - 1)); | |
| 4279 | 4279 | |
| 4280 | 4280 | if (attr_mask & (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC)) { |
| 4281 | 4281 | err = set_qpc_atomic_flags(qp, attr, attr_mask, qpc); |
| @@ -331,6 +331,8 @@ static int siw_tcp_sendpages(struct socket *s, struct page **page, int offset, · 330 unmodified lines | ||
| 331 | 331 | msg.msg_flags &= ~MSG_MORE; |
| 332 | 332 | |
| 333 | 333 | tcp_rate_check_app_limited(sk); |
| 334 | + if (!sendpage_ok(page[i])) | |
| 335 | + msg.msg_flags &= ~MSG_SPLICE_PAGES; | |
| 334 | 336 | bvec_set_page(&bvec, page[i], bytes, offset); |
| 335 | 337 | iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size); |
| 336 | 338 | |
| @@ -68,6 +68,8 @@ MODULE_LICENSE("Dual BSD/GPL"); · 67 unmodified lines | ||
| 68 | 68 | static u64 srpt_service_guid; |
| 69 | 69 | static DEFINE_SPINLOCK(srpt_dev_lock); /* Protects srpt_dev_list. */ |
| 70 | 70 | static LIST_HEAD(srpt_dev_list); /* List of srpt_device structures. */ |
| 71 | +static DEFINE_MUTEX(srpt_mc_mutex); /* Protects srpt_memory_caches. */ | |
| 72 | +static DEFINE_XARRAY(srpt_memory_caches); /* See also srpt_memory_cache_entry */ | |
| 71 | 73 | |
| 72 | 74 | static unsigned srp_max_req_size = DEFAULT_MAX_REQ_SIZE; |
| 73 | 75 | module_param(srp_max_req_size, int, 0444); |
| @@ -105,6 +107,63 @@ static void srpt_recv_done(struct ib_cq *cq, struct ib_wc *wc); · 31 unmodified lines | ||
| 105 | 107 | static void srpt_send_done(struct ib_cq *cq, struct ib_wc *wc); |
| 106 | 108 | static void srpt_process_wait_list(struct srpt_rdma_ch *ch); |
| 107 | 109 | |
| 110 | +/* Type of the entries in srpt_memory_caches. */ | |
| 111 | +struct srpt_memory_cache_entry { | |
| 112 | + refcount_t ref; | |
| 113 | + struct kmem_cache *c; | |
| 114 | +}; | |
| 115 | + | |
| 116 | +static struct kmem_cache *srpt_cache_get(unsigned int object_size) | |
| 117 | +{ | |
| 118 | + struct srpt_memory_cache_entry *e; | |
| 119 | + char name[32]; | |
| 120 | + void *res; | |
| 121 | + | |
| 122 | + guard(mutex)(&srpt_mc_mutex); | |
| 123 | + e = xa_load(&srpt_memory_caches, object_size); | |
| 124 | + if (e) { | |
| 125 | + refcount_inc(&e->ref); | |
| 126 | + return e->c; | |
| 127 | + } | |
| 128 | + snprintf(name, sizeof(name), "srpt-%u", object_size); | |
| 129 | + e = kmalloc(sizeof(*e), GFP_KERNEL); | |
| 130 | + if (!e) | |
| 131 | + return NULL; | |
| 132 | + refcount_set(&e->ref, 1); | |
| 133 | + e->c = kmem_cache_create(name, object_size, /*align=*/512, 0, NULL); | |
| 134 | + if (!e->c) | |
| 135 | + goto free_entry; | |
| 136 | + res = xa_store(&srpt_memory_caches, object_size, e, GFP_KERNEL); | |
| 137 | + if (xa_is_err(res)) | |
| 138 | + goto destroy_cache; | |
| 139 | + return e->c; | |
| 140 | + | |
| 141 | +destroy_cache: | |
| 142 | + kmem_cache_destroy(e->c); | |
| 143 | + | |
| 144 | +free_entry: | |
| 145 | + kfree(e); | |
| 146 | + return NULL; | |
| 147 | +} | |
| 148 | + | |
| 149 | +static void srpt_cache_put(struct kmem_cache *c) | |
| 150 | +{ | |
| 151 | + struct srpt_memory_cache_entry *e = NULL; | |
| 152 | + unsigned long object_size; | |
| 153 | + | |
| 154 | + guard(mutex)(&srpt_mc_mutex); | |
| 155 | + xa_for_each(&srpt_memory_caches, object_size, e) | |
| 156 | + if (e->c == c) | |
| 157 | + break; | |
| 158 | + if (WARN_ON_ONCE(!e)) | |
| 159 | + return; | |
| 160 | + if (!refcount_dec_and_test(&e->ref)) | |
| 161 | + return; | |
| 162 | + WARN_ON_ONCE(xa_erase(&srpt_memory_caches, object_size) != e); | |
| 163 | + kmem_cache_destroy(e->c); | |
| 164 | + kfree(e); | |
| 165 | +} | |
| 166 | + | |
| 108 | 167 | /* |
| 109 | 168 | * The only allowed channel state changes are those that change the channel |
| 110 | 169 | * state into a state with a higher numerical value. Hence the new > prev test. |
| @@ -2119,13 +2178,13 @@ static void srpt_release_channel_work(struct work_struct *w) · 2008 unmodified lines | ||
| 2119 | 2178 | ch->sport->sdev, ch->rq_size, |
| 2120 | 2179 | ch->rsp_buf_cache, DMA_TO_DEVICE); |
| 2121 | 2180 | |
| 2122 | − kmem_cache_destroy(ch->rsp_buf_cache); | |
| 2181 | + srpt_cache_put(ch->rsp_buf_cache); | |
| 2123 | 2182 | |
| 2124 | 2183 | srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_recv_ring, |
| 2125 | 2184 | sdev, ch->rq_size, |
| 2126 | 2185 | ch->req_buf_cache, DMA_FROM_DEVICE); |
| 2127 | 2186 | |
| 2128 | − kmem_cache_destroy(ch->req_buf_cache); | |
| 2187 | + srpt_cache_put(ch->req_buf_cache); | |
| 2129 | 2188 | |
| 2130 | 2189 | kref_put(&ch->kref, srpt_free_ch); |
| 2131 | 2190 | } |
| @@ -2245,8 +2304,7 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev, · 113 unmodified lines | ||
| 2245 | 2304 | INIT_LIST_HEAD(&ch->cmd_wait_list); |
| 2246 | 2305 | ch->max_rsp_size = ch->sport->port_attrib.srp_max_rsp_size; |
| 2247 | 2306 | |
| 2248 | − ch->rsp_buf_cache = kmem_cache_create("srpt-rsp-buf", ch->max_rsp_size, | |
| 2249 | − 512, 0, NULL); | |
| 2307 | + ch->rsp_buf_cache = srpt_cache_get(ch->max_rsp_size); | |
| 2250 | 2308 | if (!ch->rsp_buf_cache) |
| 2251 | 2309 | goto free_ch; |
| 2252 | 2310 | |
| @@ -2280,8 +2338,7 @@ static int srpt_cm_req_recv(struct srpt_device *const sdev, · 27 unmodified lines | ||
| 2280 | 2338 | alignment_offset = round_up(imm_data_offset, 512) - |
| 2281 | 2339 | imm_data_offset; |
| 2282 | 2340 | req_sz = alignment_offset + imm_data_offset + srp_max_req_size; |
| 2283 | − ch->req_buf_cache = kmem_cache_create("srpt-req-buf", req_sz, | |
| 2284 | − 512, 0, NULL); | |
| 2341 | + ch->req_buf_cache = srpt_cache_get(req_sz); | |
| 2285 | 2342 | if (!ch->req_buf_cache) |
| 2286 | 2343 | goto free_rsp_ring; |
| 2287 | 2344 | |
| @@ -2478,7 +2535,7 @@ free_recv_ring: · 190 unmodified lines | ||
| 2478 | 2535 | ch->req_buf_cache, DMA_FROM_DEVICE); |
| 2479 | 2536 | |
| 2480 | 2537 | free_recv_cache: |
| 2481 | − kmem_cache_destroy(ch->req_buf_cache); | |
| 2538 | + srpt_cache_put(ch->req_buf_cache); | |
| 2482 | 2539 | |
| 2483 | 2540 | free_rsp_ring: |
| 2484 | 2541 | srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring, |
| @@ -2486,7 +2543,7 @@ free_rsp_ring: · 1 unmodified line | ||
| 2486 | 2543 | ch->rsp_buf_cache, DMA_TO_DEVICE); |
| 2487 | 2544 | |
| 2488 | 2545 | free_rsp_cache: |
| 2489 | − kmem_cache_destroy(ch->rsp_buf_cache); | |
| 2546 | + srpt_cache_put(ch->rsp_buf_cache); | |
| 2490 | 2547 | |
| 2491 | 2548 | free_ch: |
| 2492 | 2549 | if (rdma_cm_id) |
| @@ -3055,7 +3112,7 @@ static void srpt_free_srq(struct srpt_device *sdev) · 562 unmodified lines | ||
| 3055 | 3112 | srpt_free_ioctx_ring((struct srpt_ioctx **)sdev->ioctx_ring, sdev, |
| 3056 | 3113 | sdev->srq_size, sdev->req_buf_cache, |
| 3057 | 3114 | DMA_FROM_DEVICE); |
| 3058 | − kmem_cache_destroy(sdev->req_buf_cache); | |
| 3115 | + srpt_cache_put(sdev->req_buf_cache); | |
| 3059 | 3116 | sdev->srq = NULL; |
| 3060 | 3117 | } |
| 3061 | 3118 | |
| @@ -3082,8 +3139,7 @@ static int srpt_alloc_srq(struct srpt_device *sdev) · 20 unmodified lines | ||
| 3082 | 3139 | pr_debug("create SRQ #wr= %d max_allow=%d dev= %s\n", sdev->srq_size, |
| 3083 | 3140 | sdev->device->attrs.max_srq_wr, dev_name(&device->dev)); |
| 3084 | 3141 | |
| 3085 | − sdev->req_buf_cache = kmem_cache_create("srpt-srq-req-buf", | |
| 3086 | − srp_max_req_size, 0, 0, NULL); | |
| 3142 | + sdev->req_buf_cache = srpt_cache_get(srp_max_req_size); | |
| 3087 | 3143 | if (!sdev->req_buf_cache) |
| 3088 | 3144 | goto free_srq; |
| 3089 | 3145 | |
| @@ -3105,7 +3161,7 @@ static int srpt_alloc_srq(struct srpt_device *sdev) · 15 unmodified lines | ||
| 3105 | 3161 | return 0; |
| 3106 | 3162 | |
| 3107 | 3163 | free_cache: |
| 3108 | − kmem_cache_destroy(sdev->req_buf_cache); | |
| 3164 | + srpt_cache_put(sdev->req_buf_cache); | |
| 3109 | 3165 | |
| 3110 | 3166 | free_srq: |
| 3111 | 3167 | ib_destroy_srq(srq); |
| @@ -119,12 +119,12 @@ static void input_pass_values(struct input_dev *dev, · 118 unmodified lines | ||
| 119 | 119 | |
| 120 | 120 | handle = rcu_dereference(dev->grab); |
| 121 | 121 | if (handle) { |
| 122 | − count = handle->handler->events(handle, vals, count); | |
| 122 | + count = handle->handle_events(handle, vals, count); | |
| 123 | 123 | } else { |
| 124 | 124 | list_for_each_entry_rcu(handle, &dev->h_list, d_node) |
| 125 | 125 | if (handle->open) { |
| 126 | − count = handle->handler->events(handle, vals, | |
| 127 | − count); | |
| 126 | + count = handle->handle_events(handle, vals, | |
| 127 | + count); | |
| 128 | 128 | if (!count) |
| 129 | 129 | break; |
| 130 | 130 | } |
| @@ -2534,57 +2534,6 @@ static int input_handler_check_methods(const struct input_handler *handler) · 2403 unmodified lines | ||
| 2534 | 2534 | return 0; |
| 2535 | 2535 | } |
| 2536 | 2536 | |
| 2537 | −/* | |
| 2538 | − * An implementation of input_handler's events() method that simply | |
| 2539 | − * invokes handler->event() method for each event one by one. | |
| 2540 | − */ | |
| 2541 | −static unsigned int input_handler_events_default(struct input_handle *handle, | |
| 2542 | − struct input_value *vals, | |
| 2543 | − unsigned int count) | |
| 2544 | −{ | |
| 2545 | − struct input_handler *handler = handle->handler; | |
| 2546 | − struct input_value *v; | |
| 2547 | − | |
| 2548 | − for (v = vals; v != vals + count; v++) | |
| 2549 | − handler->event(handle, v->type, v->code, v->value); | |
| 2550 | − | |
| 2551 | − return count; | |
| 2552 | −} | |
| 2553 | − | |
| 2554 | −/* | |
| 2555 | − * An implementation of input_handler's events() method that invokes | |
| 2556 | − * handler->filter() method for each event one by one and removes events | |
| 2557 | − * that were filtered out from the "vals" array. | |
| 2558 | − */ | |
| 2559 | −static unsigned int input_handler_events_filter(struct input_handle *handle, | |
| 2560 | − struct input_value *vals, | |
| 2561 | − unsigned int count) | |
| 2562 | −{ | |
| 2563 | − struct input_handler *handler = handle->handler; | |
| 2564 | − struct input_value *end = vals; | |
| 2565 | − struct input_value *v; | |
| 2566 | − | |
| 2567 | − for (v = vals; v != vals + count; v++) { | |
| 2568 | − if (handler->filter(handle, v->type, v->code, v->value)) | |
| 2569 | − continue; | |
| 2570 | − if (end != v) | |
| 2571 | − *end = *v; | |
| 2572 | − end++; | |
| 2573 | − } | |
| 2574 | − | |
| 2575 | − return end - vals; | |
| 2576 | −} | |
| 2577 | − | |
| 2578 | −/* | |
| 2579 | − * An implementation of input_handler's events() method that does nothing. | |
| 2580 | − */ | |
| 2581 | −static unsigned int input_handler_events_null(struct input_handle *handle, | |
| 2582 | − struct input_value *vals, | |
| 2583 | − unsigned int count) | |
| 2584 | −{ | |
| 2585 | − return count; | |
| 2586 | −} | |
| 2587 | − | |
| 2588 | 2537 | /** |
| 2589 | 2538 | * input_register_handler - register a new input handler |
| 2590 | 2539 | * @handler: handler to be registered |
| @@ -2604,13 +2553,6 @@ int input_register_handler(struct input_handler *handler) · 13 unmodified lines | ||
| 2604 | 2553 | |
| 2605 | 2554 | INIT_LIST_HEAD(&handler->h_list); |
| 2606 | 2555 | |
| 2607 | − if (handler->filter) | |
| 2608 | − handler->events = input_handler_events_filter; | |
| 2609 | − else if (handler->event) | |
| 2610 | − handler->events = input_handler_events_default; | |
| 2611 | − else if (!handler->events) | |
| 2612 | − handler->events = input_handler_events_null; | |
| 2613 | − | |
| 2614 | 2556 | error = mutex_lock_interruptible(&input_mutex); |
| 2615 | 2557 | if (error) |
| 2616 | 2558 | return error; |
| @@ -2684,6 +2626,75 @@ int input_handler_for_each_handle(struct input_handler *handler, void *data, · 67 unmodified lines | ||
| 2684 | 2626 | } |
| 2685 | 2627 | EXPORT_SYMBOL(input_handler_for_each_handle); |
| 2686 | 2628 | |
| 2629 | +/* | |
| 2630 | + * An implementation of input_handle's handle_events() method that simply | |
| 2631 | + * invokes handler->event() method for each event one by one. | |
| 2632 | + */ | |
| 2633 | +static unsigned int input_handle_events_default(struct input_handle *handle, | |
| 2634 | + struct input_value *vals, | |
| 2635 | + unsigned int count) | |
| 2636 | +{ | |
| 2637 | + struct input_handler *handler = handle->handler; | |
| 2638 | + struct input_value *v; | |
| 2639 | + | |
| 2640 | + for (v = vals; v != vals + count; v++) | |
| 2641 | + handler->event(handle, v->type, v->code, v->value); | |
| 2642 | + | |
| 2643 | + return count; | |
| 2644 | +} | |
| 2645 | + | |
| 2646 | +/* | |
| 2647 | + * An implementation of input_handle's handle_events() method that invokes | |
| 2648 | + * handler->filter() method for each event one by one and removes events | |
| 2649 | + * that were filtered out from the "vals" array. | |
| 2650 | + */ | |
| 2651 | +static unsigned int input_handle_events_filter(struct input_handle *handle, | |
| 2652 | + struct input_value *vals, | |
| 2653 | + unsigned int count) | |
| 2654 | +{ | |
| 2655 | + struct input_handler *handler = handle->handler; | |
| 2656 | + struct input_value *end = vals; | |
| 2657 | + struct input_value *v; | |
| 2658 | + | |
| 2659 | + for (v = vals; v != vals + count; v++) { | |
| 2660 | + if (handler->filter(handle, v->type, v->code, v->value)) | |
| 2661 | + continue; | |
| 2662 | + if (end != v) | |
| 2663 | + *end = *v; | |
| 2664 | + end++; | |
| 2665 | + } | |
| 2666 | + | |
| 2667 | + return end - vals; | |
| 2668 | +} | |
| 2669 | + | |
| 2670 | +/* | |
| 2671 | + * An implementation of input_handle's handle_events() method that does nothing. | |
| 2672 | + */ | |
| 2673 | +static unsigned int input_handle_events_null(struct input_handle *handle, | |
| 2674 | + struct input_value *vals, | |
| 2675 | + unsigned int count) | |
| 2676 | +{ | |
| 2677 | + return count; | |
| 2678 | +} | |
| 2679 | + | |
| 2680 | +/* | |
| 2681 | + * Sets up appropriate handle->event_handler based on the input_handler | |
| 2682 | + * associated with the handle. | |
| 2683 | + */ | |
| 2684 | +static void input_handle_setup_event_handler(struct input_handle *handle) | |
| 2685 | +{ | |
| 2686 | + struct input_handler *handler = handle->handler; | |
| 2687 | + | |
| 2688 | + if (handler->filter) | |
| 2689 | + handle->handle_events = input_handle_events_filter; | |
| 2690 | + else if (handler->event) | |
| 2691 | + handle->handle_events = input_handle_events_default; | |
| 2692 | + else if (handler->events) | |
| 2693 | + handle->handle_events = handler->events; | |
| 2694 | + else | |
| 2695 | + handle->handle_events = input_handle_events_null; | |
| 2696 | +} | |
| 2697 | + | |
| 2687 | 2698 | /** |
| 2688 | 2699 | * input_register_handle - register a new input handle |
| 2689 | 2700 | * @handle: handle to register |
| @@ -2701,6 +2712,7 @@ int input_register_handle(struct input_handle *handle) · 11 unmodified lines | ||
| 2701 | 2712 | struct input_dev *dev = handle->dev; |
| 2702 | 2713 | int error; |
| 2703 | 2714 | |
| 2715 | + input_handle_setup_event_handler(handle); | |
| 2704 | 2716 | /* |
| 2705 | 2717 | * We take dev->mutex here to prevent race with |
| 2706 | 2718 | * input_release_device(). |
| @@ -218,6 +218,7 @@ static const struct xpad_device { · 217 unmodified lines | ||
| 218 | 218 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, |
| 219 | 219 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX }, |
| 220 | 220 | { 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, |
| 221 | + { 0x0db0, 0x1901, "Micro Star International Xbox360 Controller for Windows", 0, XTYPE_XBOX360 }, | |
| 221 | 222 | { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX }, |
| 222 | 223 | { 0x0e4c, 0x1103, "Radica Gamester Reflex", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX }, |
| 223 | 224 | { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX }, |
| @@ -373,6 +374,7 @@ static const struct xpad_device { · 149 unmodified lines | ||
| 373 | 374 | { 0x294b, 0x3404, "Snakebyte GAMEPAD RGB X", 0, XTYPE_XBOXONE }, |
| 374 | 375 | { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE }, |
| 375 | 376 | { 0x2dc8, 0x3106, "8BitDo Pro 2 Wired Controller", 0, XTYPE_XBOX360 }, |
| 377 | + { 0x2dc8, 0x310a, "8BitDo Ultimate 2C Wireless Controller", 0, XTYPE_XBOX360 }, | |
| 376 | 378 | { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE }, |
| 377 | 379 | { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 }, |
| 378 | 380 | { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 }, |
| @@ -492,6 +494,7 @@ static const struct usb_device_id xpad_table[] = { · 113 unmodified lines | ||
| 492 | 494 | XPAD_XBOX360_VENDOR(0x07ff), /* Mad Catz Gamepad */ |
| 493 | 495 | XPAD_XBOXONE_VENDOR(0x0b05), /* ASUS controllers */ |
| 494 | 496 | XPAD_XBOX360_VENDOR(0x0c12), /* Zeroplus X-Box 360 controllers */ |
| 497 | + XPAD_XBOX360_VENDOR(0x0db0), /* Micro Star International X-Box 360 controllers */ | |
| 495 | 498 | XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f Xbox 360 controllers */ |
| 496 | 499 | XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f Xbox One controllers */ |
| 497 | 500 | XPAD_XBOX360_VENDOR(0x0f0d), /* Hori controllers */ |
| @@ -822,7 +822,8 @@ static int adp5588_suspend(struct device *dev) · 821 unmodified lines | ||
| 822 | 822 | { |
| 823 | 823 | struct i2c_client *client = to_i2c_client(dev); |
| 824 | 824 | |
| 825 | − disable_irq(client->irq); | |
| 825 | + if (client->irq) | |
| 826 | + disable_irq(client->irq); | |
| 826 | 827 | |
| 827 | 828 | return 0; |
| 828 | 829 | } |
| @@ -831,7 +832,8 @@ static int adp5588_resume(struct device *dev) · 2 unmodified lines | ||
| 831 | 832 | { |
| 832 | 833 | struct i2c_client *client = to_i2c_client(dev); |
| 833 | 834 | |
| 834 | − enable_irq(client->irq); | |
| 835 | + if (client->irq) | |
| 836 | + enable_irq(client->irq); | |
| 835 | 837 | |
| 836 | 838 | return 0; |
| 837 | 839 | } |
| @@ -1121,6 +1121,14 @@ static void edt_ft5x06_ts_set_regs(struct edt_ft5x06_ts_data *tsdata) · 1120 unmodified lines | ||
| 1121 | 1121 | } |
| 1122 | 1122 | } |
| 1123 | 1123 | |
| 1124 | +static void edt_ft5x06_exit_regmap(void *arg) | |
| 1125 | +{ | |
| 1126 | + struct edt_ft5x06_ts_data *data = arg; | |
| 1127 | + | |
| 1128 | + if (!IS_ERR_OR_NULL(data->regmap)) | |
| 1129 | + regmap_exit(data->regmap); | |
| 1130 | +} | |
| 1131 | + | |
| 1124 | 1132 | static void edt_ft5x06_disable_regulators(void *arg) |
| 1125 | 1133 | { |
| 1126 | 1134 | struct edt_ft5x06_ts_data *data = arg; |
| @@ -1154,6 +1162,16 @@ static int edt_ft5x06_ts_probe(struct i2c_client *client) · 27 unmodified lines | ||
| 1154 | 1162 | return PTR_ERR(tsdata->regmap); |
| 1155 | 1163 | } |
| 1156 | 1164 | |
| 1165 | + /* | |
| 1166 | + * We are not using devm_regmap_init_i2c() and instead install a | |
| 1167 | + * custom action because we may replace regmap with M06-specific one | |
| 1168 | + * and we need to make sure that it will not be released too early. | |
| 1169 | + */ | |
| 1170 | + error = devm_add_action_or_reset(&client->dev, edt_ft5x06_exit_regmap, | |
| 1171 | + tsdata); | |
| 1172 | + if (error) | |
| 1173 | + return error; | |
| 1174 | + | |
| 1157 | 1175 | chip_data = device_get_match_data(&client->dev); |
| 1158 | 1176 | if (!chip_data) |
| 1159 | 1177 | chip_data = (const struct edt_i2c_chip_data *)id->driver_data; |
| @@ -1347,7 +1365,6 @@ static void edt_ft5x06_ts_remove(struct i2c_client *client) · 187 unmodified lines | ||
| 1347 | 1365 | struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client); |
| 1348 | 1366 | |
| 1349 | 1367 | edt_ft5x06_ts_teardown_debugfs(tsdata); |
| 1350 | − regmap_exit(tsdata->regmap); | |
| 1351 | 1368 | } |
| 1352 | 1369 | |
| 1353 | 1370 | static int edt_ft5x06_ts_suspend(struct device *dev) |
| @@ -645,19 +645,29 @@ static int zinitix_ts_probe(struct i2c_client *client) · 644 unmodified lines | ||
| 645 | 645 | return error; |
| 646 | 646 | } |
| 647 | 647 | |
| 648 | − bt541->num_keycodes = device_property_count_u32(&client->dev, "linux,keycodes"); | |
| 649 | − if (bt541->num_keycodes > ARRAY_SIZE(bt541->keycodes)) { | |
| 650 | − dev_err(&client->dev, "too many keys defined (%d)\n", bt541->num_keycodes); | |
| 651 | − return -EINVAL; | |
| 652 | − } | |
| 648 | + if (device_property_present(&client->dev, "linux,keycodes")) { | |
| 649 | + bt541->num_keycodes = device_property_count_u32(&client->dev, | |
| 650 | + "linux,keycodes"); | |
| 651 | + if (bt541->num_keycodes < 0) { | |
| 652 | + dev_err(&client->dev, "Failed to count keys (%d)\n", | |
| 653 | + bt541->num_keycodes); | |
| 654 | + return bt541->num_keycodes; | |
| 655 | + } else if (bt541->num_keycodes > ARRAY_SIZE(bt541->keycodes)) { | |
| 656 | + dev_err(&client->dev, "Too many keys defined (%d)\n", | |
| 657 | + bt541->num_keycodes); | |
| 658 | + return -EINVAL; | |
| 659 | + } | |
| 653 | 660 | |
| 654 | − error = device_property_read_u32_array(&client->dev, "linux,keycodes", | |
| 655 | − bt541->keycodes, | |
| 656 | − bt541->num_keycodes); | |
| 657 | − if (error) { | |
| 658 | − dev_err(&client->dev, | |
| 659 | − "Unable to parse \"linux,keycodes\" property: %d\n", error); | |
| 660 | − return error; | |
| 661 | + error = device_property_read_u32_array(&client->dev, | |
| 662 | + "linux,keycodes", | |
| 663 | + bt541->keycodes, | |
| 664 | + bt541->num_keycodes); | |
| 665 | + if (error) { | |
| 666 | + dev_err(&client->dev, | |
| 667 | + "Unable to parse \"linux,keycodes\" property: %d\n", | |
| 668 | + error); | |
| 669 | + return error; | |
| 670 | + } | |
| 661 | 671 | } |
| 662 | 672 | |
| 663 | 673 | error = zinitix_init_input_dev(bt541); |
| @@ -1420,7 +1420,7 @@ static int arm_smmu_alloc_cd_tables(struct arm_smmu_master *master) · 1419 unmodified lines | ||
| 1420 | 1420 | cd_table->s1fmt = STRTAB_STE_0_S1FMT_LINEAR; |
| 1421 | 1421 | cd_table->linear.num_ents = max_contexts; |
| 1422 | 1422 | |
| 1423 | − l1size = max_contexts * sizeof(struct arm_smmu_cd), | |
| 1423 | + l1size = max_contexts * sizeof(struct arm_smmu_cd); | |
| 1424 | 1424 | cd_table->linear.table = dma_alloc_coherent(smmu->dev, l1size, |
| 1425 | 1425 | &cd_table->cdtab_dma, |
| 1426 | 1426 | GFP_KERNEL); |
| @@ -3625,7 +3625,7 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu) · 2198 unmodified lines | ||
| 3625 | 3625 | u32 l1size; |
| 3626 | 3626 | struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg; |
| 3627 | 3627 | unsigned int last_sid_idx = |
| 3628 | − arm_smmu_strtab_l1_idx((1 << smmu->sid_bits) - 1); | |
| 3628 | + arm_smmu_strtab_l1_idx((1ULL << smmu->sid_bits) - 1); | |
| 3629 | 3629 | |
| 3630 | 3630 | /* Calculate the L1 size, capped to the SIDSIZE. */ |
| 3631 | 3631 | cfg->l2.num_l1_ents = min(last_sid_idx + 1, STRTAB_MAX_L1_ENTRIES); |
| @@ -130,7 +130,7 @@ int arm_mmu500_reset(struct arm_smmu_device *smmu) · 129 unmodified lines | ||
| 130 | 130 | |
| 131 | 131 | /* |
| 132 | 132 | * Disable MMU-500's not-particularly-beneficial next-page |
| 133 | − * prefetcher for the sake of errata #841119 and #826419. | |
| 133 | + * prefetcher for the sake of at least 5 known errata. | |
| 134 | 134 | */ |
| 135 | 135 | for (i = 0; i < smmu->num_context_banks; ++i) { |
| 136 | 136 | reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR); |
| @@ -138,7 +138,7 @@ int arm_mmu500_reset(struct arm_smmu_device *smmu) · 1 unmodified line | ||
| 138 | 138 | arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_ACTLR, reg); |
| 139 | 139 | reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR); |
| 140 | 140 | if (reg & ARM_MMU500_ACTLR_CPRE) |
| 141 | − dev_warn_once(smmu->dev, "Failed to disable prefetcher [errata #841119 and #826419], check ACR.CACHE_LOCK\n"); | |
| 141 | + dev_warn_once(smmu->dev, "Failed to disable prefetcher for errata workarounds, check SACR.CACHE_LOCK\n"); | |
| 142 | 142 | } |
| 143 | 143 | |
| 144 | 144 | return 0; |
| @@ -3340,8 +3340,10 @@ static int domain_context_clear_one_cb(struct pci_dev *pdev, u16 alias, void *op · 3339 unmodified lines | ||
| 3340 | 3340 | */ |
| 3341 | 3341 | static void domain_context_clear(struct device_domain_info *info) |
| 3342 | 3342 | { |
| 3343 | − if (!dev_is_pci(info->dev)) | |
| 3343 | + if (!dev_is_pci(info->dev)) { | |
| 3344 | 3344 | domain_context_clear_one(info, info->bus, info->devfn); |
| 3345 | + return; | |
| 3346 | + } | |
| 3345 | 3347 | |
| 3346 | 3348 | pci_for_each_dma_alias(to_pci_dev(info->dev), |
| 3347 | 3349 | &domain_context_clear_one_cb, info); |
| @@ -45,13 +45,6 @@ config ARM_GIC_V3_ITS · 44 unmodified lines | ||
| 45 | 45 | select IRQ_MSI_LIB |
| 46 | 46 | default ARM_GIC_V3 |
| 47 | 47 | |
| 48 | −config ARM_GIC_V3_ITS_PCI | |
| 49 | − bool | |
| 50 | − depends on ARM_GIC_V3_ITS | |
| 51 | − depends on PCI | |
| 52 | − depends on PCI_MSI | |
| 53 | − default ARM_GIC_V3_ITS | |
| 54 | − | |
| 55 | 48 | config ARM_GIC_V3_ITS_FSL_MC |
| 56 | 49 | bool |
| 57 | 50 | depends on ARM_GIC_V3_ITS |
| @@ -797,8 +797,8 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its, · 796 unmodified lines | ||
| 797 | 797 | its_encode_valid(cmd, desc->its_vmapp_cmd.valid); |
| 798 | 798 | |
| 799 | 799 | if (!desc->its_vmapp_cmd.valid) { |
| 800 | + alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count); | |
| 800 | 801 | if (is_v4_1(its)) { |
| 801 | − alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count); | |
| 802 | 802 | its_encode_alloc(cmd, alloc); |
| 803 | 803 | /* |
| 804 | 804 | * Unmapping a VPE is self-synchronizing on GICv4.1, |
| @@ -817,13 +817,13 @@ static struct its_vpe *its_build_vmapp_cmd(struct its_node *its, · 12 unmodified lines | ||
| 817 | 817 | its_encode_vpt_addr(cmd, vpt_addr); |
| 818 | 818 | its_encode_vpt_size(cmd, LPI_NRBITS - 1); |
| 819 | 819 | |
| 820 | + alloc = !atomic_fetch_inc(&desc->its_vmapp_cmd.vpe->vmapp_count); | |
| 821 | + | |
| 820 | 822 | if (!is_v4_1(its)) |
| 821 | 823 | goto out; |
| 822 | 824 | |
| 823 | 825 | vconf_addr = virt_to_phys(page_address(desc->its_vmapp_cmd.vpe->its_vm->vprop_page)); |
| 824 | 826 | |
| 825 | − alloc = !atomic_fetch_inc(&desc->its_vmapp_cmd.vpe->vmapp_count); | |
| 826 | − | |
| 827 | 827 | its_encode_alloc(cmd, alloc); |
| 828 | 828 | |
| 829 | 829 | /* |
| @@ -3806,6 +3806,23 @@ static int its_vpe_set_affinity(struct irq_data *d, · 2976 unmodified lines | ||
| 3806 | 3806 | struct cpumask *table_mask; |
| 3807 | 3807 | unsigned long flags; |
| 3808 | 3808 | |
| 3809 | + /* | |
| 3810 | + * Check if we're racing against a VPE being destroyed, for | |
| 3811 | + * which we don't want to allow a VMOVP. | |
| 3812 | + */ | |
| 3813 | + if (!atomic_read(&vpe->vmapp_count)) { | |
| 3814 | + if (gic_requires_eager_mapping()) | |
| 3815 | + return -EINVAL; | |
| 3816 | + | |
| 3817 | + /* | |
| 3818 | + * If we lazily map the VPEs, this isn't an error and | |
| 3819 | + * we can exit cleanly. | |
| 3820 | + */ | |
| 3821 | + cpu = cpumask_first(mask_val); | |
| 3822 | + irq_data_update_effective_affinity(d, cpumask_of(cpu)); | |
| 3823 | + return IRQ_SET_MASK_OK_DONE; | |
| 3824 | + } | |
| 3825 | + | |
| 3809 | 3826 | /* |
| 3810 | 3827 | * Changing affinity is mega expensive, so let's be as lazy as |
| 3811 | 3828 | * we can and only do it if we really have to. Also, if mapped |
| @@ -4463,9 +4480,8 @@ static int its_vpe_init(struct its_vpe *vpe) · 651 unmodified lines | ||
| 4463 | 4480 | raw_spin_lock_init(&vpe->vpe_lock); |
| 4464 | 4481 | vpe->vpe_id = vpe_id; |
| 4465 | 4482 | vpe->vpt_page = vpt_page; |
| 4466 | − if (gic_rdists->has_rvpeid) | |
| 4467 | − atomic_set(&vpe->vmapp_count, 0); | |
| 4468 | − else | |
| 4483 | + atomic_set(&vpe->vmapp_count, 0); | |
| 4484 | + if (!gic_rdists->has_rvpeid) | |
| 4469 | 4485 | vpe->vpe_proxy_event = -1; |
| 4470 | 4486 | |
| 4471 | 4487 | return 0; |
| @@ -37,7 +37,7 @@ static struct chip_props ocelot_props = { · 36 unmodified lines | ||
| 37 | 37 | .reg_off_ena_clr = 0x1c, |
| 38 | 38 | .reg_off_ena_set = 0x20, |
| 39 | 39 | .reg_off_ident = 0x38, |
| 40 | − .reg_off_trigger = 0x5c, | |
| 40 | + .reg_off_trigger = 0x4, | |
| 41 | 41 | .n_irq = 24, |
| 42 | 42 | }; |
| 43 | 43 | |
| @@ -70,7 +70,7 @@ static struct chip_props jaguar2_props = { · 26 unmodified lines | ||
| 70 | 70 | .reg_off_ena_clr = 0x1c, |
| 71 | 71 | .reg_off_ena_set = 0x20, |
| 72 | 72 | .reg_off_ident = 0x38, |
| 73 | − .reg_off_trigger = 0x5c, | |
| 73 | + .reg_off_trigger = 0x4, | |
| 74 | 74 | .n_irq = 29, |
| 75 | 75 | }; |
| 76 | 76 | |
| @@ -84,6 +84,12 @@ static void ocelot_irq_unmask(struct irq_data *data) · 7 unmodified lines | ||
| 84 | 84 | u32 val; |
| 85 | 85 | |
| 86 | 86 | irq_gc_lock(gc); |
| 87 | + /* | |
| 88 | + * Clear sticky bits for edge mode interrupts. | |
| 89 | + * Serval has only one trigger register replication, but the adjacent | |
| 90 | + * register is always read as zero, so there's no need to handle this | |
| 91 | + * case separately. | |
| 92 | + */ | |
| 87 | 93 | val = irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 0)) | |
| 88 | 94 | irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 1)); |
| 89 | 95 | if (!(val & mask)) |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | ||
| 8 | 8 | */ |
| 9 | 9 | |
| 10 | 10 | #include <linux/bitfield.h> |
| 11 | +#include <linux/cleanup.h> | |
| 11 | 12 | #include <linux/clk.h> |
| 12 | 13 | #include <linux/err.h> |
| 13 | 14 | #include <linux/io.h> |
| @@ -530,12 +531,12 @@ static int rzg2l_irqc_parse_interrupts(struct rzg2l_irqc_priv *priv, · 516 unmodified lines | ||
| 530 | 531 | static int rzg2l_irqc_common_init(struct device_node *node, struct device_node *parent, |
| 531 | 532 | const struct irq_chip *irq_chip) |
| 532 | 533 | { |
| 534 | + struct platform_device *pdev = of_find_device_by_node(node); | |
| 535 | + struct device *dev __free(put_device) = pdev ? &pdev->dev : NULL; | |
| 533 | 536 | struct irq_domain *irq_domain, *parent_domain; |
| 534 | − struct platform_device *pdev; | |
| 535 | 537 | struct reset_control *resetn; |
| 536 | 538 | int ret; |
| 537 | 539 | |
| 538 | − pdev = of_find_device_by_node(node); | |
| 539 | 540 | if (!pdev) |
| 540 | 541 | return -ENODEV; |
| 541 | 542 | |
| @@ -591,6 +592,17 @@ static int rzg2l_irqc_common_init(struct device_node *node, struct device_node * · 49 unmodified lines | ||
| 591 | 592 | |
| 592 | 593 | register_syscore_ops(&rzg2l_irqc_syscore_ops); |
| 593 | 594 | |
| 595 | + /* | |
| 596 | + * Prevent the cleanup function from invoking put_device by assigning | |
| 597 | + * NULL to dev. | |
| 598 | + * | |
| 599 | + * make coccicheck will complain about missing put_device calls, but | |
| 600 | + * those are false positives, as dev will be automatically "put" via | |
| 601 | + * __free_put_device on the failing path. | |
| 602 | + * On the successful path we don't actually want to "put" dev. | |
| 603 | + */ | |
| 604 | + dev = NULL; | |
| 605 | + | |
| 594 | 606 | return 0; |
| 595 | 607 | |
| 596 | 608 | pm_put: |
| @@ -341,7 +341,7 @@ int imsic_irqdomain_init(void) · 340 unmodified lines | ||
| 341 | 341 | imsic->fwnode, global->hart_index_bits, global->guest_index_bits); |
| 342 | 342 | pr_info("%pfwP: group-index-bits: %d, group-index-shift: %d\n", |
| 343 | 343 | imsic->fwnode, global->group_index_bits, global->group_index_shift); |
| 344 | − pr_info("%pfwP: per-CPU IDs %d at base PPN %pa\n", | |
| 344 | + pr_info("%pfwP: per-CPU IDs %d at base address %pa\n", | |
| 345 | 345 | imsic->fwnode, global->nr_ids, &global->base_addr); |
| 346 | 346 | pr_info("%pfwP: total %d interrupts available\n", |
| 347 | 347 | imsic->fwnode, num_possible_cpus() * (global->nr_ids - 1)); |
| @@ -265,7 +265,7 @@ struct rintc_data { · 264 unmodified lines | ||
| 265 | 265 | }; |
| 266 | 266 | |
| 267 | 267 | static u32 nr_rintc; |
| 268 | −static struct rintc_data *rintc_acpi_data[NR_CPUS]; | |
| 268 | +static struct rintc_data **rintc_acpi_data; | |
| 269 | 269 | |
| 270 | 270 | #define for_each_matching_plic(_plic_id) \ |
| 271 | 271 | unsigned int _plic; \ |
| @@ -329,13 +329,30 @@ int acpi_rintc_get_imsic_mmio_info(u32 index, struct resource *res) · 57 unmodified lines | ||
| 329 | 329 | return 0; |
| 330 | 330 | } |
| 331 | 331 | |
| 332 | +static int __init riscv_intc_acpi_match(union acpi_subtable_headers *header, | |
| 333 | + const unsigned long end) | |
| 334 | +{ | |
| 335 | + return 0; | |
| 336 | +} | |
| 337 | + | |
| 332 | 338 | static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header, |
| 333 | 339 | const unsigned long end) |
| 334 | 340 | { |
| 335 | 341 | struct acpi_madt_rintc *rintc; |
| 336 | 342 | struct fwnode_handle *fn; |
| 343 | + int count; | |
| 337 | 344 | int rc; |
| 338 | 345 | |
| 346 | + if (!rintc_acpi_data) { | |
| 347 | + count = acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, riscv_intc_acpi_match, 0); | |
| 348 | + if (count <= 0) | |
| 349 | + return -EINVAL; | |
| 350 | + | |
| 351 | + rintc_acpi_data = kcalloc(count, sizeof(*rintc_acpi_data), GFP_KERNEL); | |
| 352 | + if (!rintc_acpi_data) | |
| 353 | + return -ENOMEM; | |
| 354 | + } | |
| 355 | + | |
| 339 | 356 | rintc = (struct acpi_madt_rintc *)header; |
| 340 | 357 | rintc_acpi_data[nr_rintc] = kzalloc(sizeof(*rintc_acpi_data[0]), GFP_KERNEL); |
| 341 | 358 | if (!rintc_acpi_data[nr_rintc]) |
| @@ -126,16 +126,6 @@ static inline void plic_irq_toggle(const struct cpumask *mask, · 125 unmodified lines | ||
| 126 | 126 | } |
| 127 | 127 | } |
| 128 | 128 | |
| 129 | −static void plic_irq_enable(struct irq_data *d) | |
| 130 | −{ | |
| 131 | − plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 1); | |
| 132 | −} | |
| 133 | − | |
| 134 | −static void plic_irq_disable(struct irq_data *d) | |
| 135 | −{ | |
| 136 | − plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 0); | |
| 137 | −} | |
| 138 | − | |
| 139 | 129 | static void plic_irq_unmask(struct irq_data *d) |
| 140 | 130 | { |
| 141 | 131 | struct plic_priv *priv = irq_data_get_irq_chip_data(d); |
| @@ -150,6 +140,17 @@ static void plic_irq_mask(struct irq_data *d) · 8 unmodified lines | ||
| 150 | 140 | writel(0, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID); |
| 151 | 141 | } |
| 152 | 142 | |
| 143 | +static void plic_irq_enable(struct irq_data *d) | |
| 144 | +{ | |
| 145 | + plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 1); | |
| 146 | + plic_irq_unmask(d); | |
| 147 | +} | |
| 148 | + | |
| 149 | +static void plic_irq_disable(struct irq_data *d) | |
| 150 | +{ | |
| 151 | + plic_irq_toggle(irq_data_get_effective_affinity_mask(d), d, 0); | |
| 152 | +} | |
| 153 | + | |
| 153 | 154 | static void plic_irq_eoi(struct irq_data *d) |
| 154 | 155 | { |
| 155 | 156 | struct plic_handler *handler = this_cpu_ptr(&plic_handlers); |
| @@ -626,8 +627,10 @@ static int plic_probe(struct fwnode_handle *fwnode) · 470 unmodified lines | ||
| 626 | 627 | |
| 627 | 628 | handler->enable_save = kcalloc(DIV_ROUND_UP(nr_irqs, 32), |
| 628 | 629 | sizeof(*handler->enable_save), GFP_KERNEL); |
| 629 | − if (!handler->enable_save) | |
| 630 | + if (!handler->enable_save) { | |
| 631 | + error = -ENOMEM; | |
| 630 | 632 | goto fail_cleanup_contexts; |
| 633 | + } | |
| 631 | 634 | done: |
| 632 | 635 | for (hwirq = 1; hwirq <= nr_irqs; hwirq++) { |
| 633 | 636 | plic_toggle(handler, hwirq, 0); |
| @@ -639,8 +642,10 @@ done: · 5 unmodified lines | ||
| 639 | 642 | |
| 640 | 643 | priv->irqdomain = irq_domain_create_linear(fwnode, nr_irqs + 1, |
| 641 | 644 | &plic_irqdomain_ops, priv); |
| 642 | − if (WARN_ON(!priv->irqdomain)) | |
| 645 | + if (WARN_ON(!priv->irqdomain)) { | |
| 646 | + error = -ENOMEM; | |
| 643 | 647 | goto fail_cleanup_contexts; |
| 648 | + } | |
| 644 | 649 | |
| 645 | 650 | /* |
| 646 | 651 | * We can have multiple PLIC instances so setup global state |
| @@ -546,6 +546,26 @@ static int mddev_set_closing_and_sync_blockdev(struct mddev *mddev, int opener_n · 545 unmodified lines | ||
| 546 | 546 | return 0; |
| 547 | 547 | } |
| 548 | 548 | |
| 549 | +/* | |
| 550 | + * The only difference from bio_chain_endio() is that the current | |
| 551 | + * bi_status of bio does not affect the bi_status of parent. | |
| 552 | + */ | |
| 553 | +static void md_end_flush(struct bio *bio) | |
| 554 | +{ | |
| 555 | + struct bio *parent = bio->bi_private; | |
| 556 | + | |
| 557 | + /* | |
| 558 | + * If any flush io error before the power failure, | |
| 559 | + * disk data may be lost. | |
| 560 | + */ | |
| 561 | + if (bio->bi_status) | |
| 562 | + pr_err("md: %pg flush io error %d\n", bio->bi_bdev, | |
| 563 | + blk_status_to_errno(bio->bi_status)); | |
| 564 | + | |
| 565 | + bio_put(bio); | |
| 566 | + bio_endio(parent); | |
| 567 | +} | |
| 568 | + | |
| 549 | 569 | bool md_flush_request(struct mddev *mddev, struct bio *bio) |
| 550 | 570 | { |
| 551 | 571 | struct md_rdev *rdev; |
| @@ -565,7 +585,9 @@ bool md_flush_request(struct mddev *mddev, struct bio *bio) · 13 unmodified lines | ||
| 565 | 585 | new = bio_alloc_bioset(rdev->bdev, 0, |
| 566 | 586 | REQ_OP_WRITE | REQ_PREFLUSH, GFP_NOIO, |
| 567 | 587 | &mddev->bio_set); |
| 568 | − bio_chain(new, bio); | |
| 588 | + new->bi_private = bio; | |
| 589 | + new->bi_end_io = md_end_flush; | |
| 590 | + bio_inc_remaining(bio); | |
| 569 | 591 | submit_bio(new); |
| 570 | 592 | } |
| 571 | 593 | |
| @@ -4061,9 +4061,12 @@ static int raid10_run(struct mddev *mddev) · 4060 unmodified lines | ||
| 4061 | 4061 | } |
| 4062 | 4062 | |
| 4063 | 4063 | if (!mddev_is_dm(conf->mddev)) { |
| 4064 | − ret = raid10_set_queue_limits(mddev); | |
| 4065 | − if (ret) | |
| 4064 | + int err = raid10_set_queue_limits(mddev); | |
| 4065 | + | |
| 4066 | + if (err) { | |
| 4067 | + ret = err; | |
| 4066 | 4068 | goto out_free_conf; |
| 4069 | + } | |
| 4067 | 4070 | } |
| 4068 | 4071 | |
| 4069 | 4072 | /* need to check that every block has at least one working mirror */ |
| @@ -16,7 +16,8 @@ config MISC_RTSX_PCI · 15 unmodified lines | ||
| 16 | 16 | select MFD_CORE |
| 17 | 17 | help |
| 18 | 18 | This supports for Realtek PCI-Express card reader including rts5209, |
| 19 | − rts5227, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411, rts5260. | |
| 19 | + rts5227, rts5228, rts522A, rts5229, rts5249, rts524A, rts525A, rtl8411, | |
| 20 | + rts5260, rts5261, rts5264. | |
| 20 | 21 | Realtek card readers support access to many types of memory cards, |
| 21 | 22 | such as Memory Stick, Memory Stick Pro, Secure Digital and |
| 22 | 23 | MultiMediaCard. |
| @@ -364,6 +364,7 @@ static int pci1xxxx_otp_eeprom_probe(struct auxiliary_device *aux_dev, · 363 unmodified lines | ||
| 364 | 364 | if (is_eeprom_responsive(priv)) { |
| 365 | 365 | priv->nvmem_config_eeprom.type = NVMEM_TYPE_EEPROM; |
| 366 | 366 | priv->nvmem_config_eeprom.name = EEPROM_NAME; |
| 367 | + priv->nvmem_config_eeprom.id = NVMEM_DEVID_AUTO; | |
| 367 | 368 | priv->nvmem_config_eeprom.dev = &aux_dev->dev; |
| 368 | 369 | priv->nvmem_config_eeprom.owner = THIS_MODULE; |
| 369 | 370 | priv->nvmem_config_eeprom.reg_read = pci1xxxx_eeprom_read; |
| @@ -383,6 +384,7 @@ static int pci1xxxx_otp_eeprom_probe(struct auxiliary_device *aux_dev, · 13 unmodified lines | ||
| 383 | 384 | |
| 384 | 385 | priv->nvmem_config_otp.type = NVMEM_TYPE_OTP; |
| 385 | 386 | priv->nvmem_config_otp.name = OTP_NAME; |
| 387 | + priv->nvmem_config_otp.id = NVMEM_DEVID_AUTO; | |
| 386 | 388 | priv->nvmem_config_otp.dev = &aux_dev->dev; |
| 387 | 389 | priv->nvmem_config_otp.owner = THIS_MODULE; |
| 388 | 390 | priv->nvmem_config_otp.reg_read = pci1xxxx_otp_read; |
| @@ -321,7 +321,7 @@ void mei_io_cb_free(struct mei_cl_cb *cb) · 320 unmodified lines | ||
| 321 | 321 | return; |
| 322 | 322 | |
| 323 | 323 | list_del(&cb->list); |
| 324 | − kfree(cb->buf.data); | |
| 324 | + kvfree(cb->buf.data); | |
| 325 | 325 | kfree(cb->ext_hdr); |
| 326 | 326 | kfree(cb); |
| 327 | 327 | } |
| @@ -497,7 +497,7 @@ struct mei_cl_cb *mei_cl_alloc_cb(struct mei_cl *cl, size_t length, · 169 unmodified lines | ||
| 497 | 497 | if (length == 0) |
| 498 | 498 | return cb; |
| 499 | 499 | |
| 500 | − cb->buf.data = kmalloc(roundup(length, MEI_SLOT_SIZE), GFP_KERNEL); | |
| 500 | + cb->buf.data = kvmalloc(roundup(length, MEI_SLOT_SIZE), GFP_KERNEL); | |
| 501 | 501 | if (!cb->buf.data) { |
| 502 | 502 | mei_io_cb_free(cb); |
| 503 | 503 | return NULL; |
| @@ -258,7 +258,6 @@ static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr) · 257 unmodified lines | ||
| 258 | 258 | int lcpu; |
| 259 | 259 | |
| 260 | 260 | BUG_ON(dsr_bytes > GRU_NUM_KERNEL_DSR_BYTES); |
| 261 | − preempt_disable(); | |
| 262 | 261 | bs = gru_lock_kernel_context(-1); |
| 263 | 262 | lcpu = uv_blade_processor_id(); |
| 264 | 263 | *cb = bs->kernel_cb + lcpu * GRU_HANDLE_STRIDE; |
| @@ -272,7 +271,6 @@ static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr) · 7 unmodified lines | ||
| 272 | 271 | static void gru_free_cpu_resources(void *cb, void *dsr) |
| 273 | 272 | { |
| 274 | 273 | gru_unlock_kernel_context(uv_numa_blade_id()); |
| 275 | − preempt_enable(); | |
| 276 | 274 | } |
| 277 | 275 | |
| 278 | 276 | /* |
| @@ -937,10 +937,8 @@ vm_fault_t gru_fault(struct vm_fault *vmf) · 936 unmodified lines | ||
| 937 | 937 | |
| 938 | 938 | again: |
| 939 | 939 | mutex_lock(>s->ts_ctxlock); |
| 940 | − preempt_disable(); | |
| 941 | 940 | |
| 942 | 941 | if (gru_check_context_placement(gts)) { |
| 943 | − preempt_enable(); | |
| 944 | 942 | mutex_unlock(>s->ts_ctxlock); |
| 945 | 943 | gru_unload_context(gts, 1); |
| 946 | 944 | return VM_FAULT_NOPAGE; |
| @@ -949,7 +947,6 @@ again: · 2 unmodified lines | ||
| 949 | 947 | if (!gts->ts_gru) { |
| 950 | 948 | STAT(load_user_context); |
| 951 | 949 | if (!gru_assign_gru_context(gts)) { |
| 952 | − preempt_enable(); | |
| 953 | 950 | mutex_unlock(>s->ts_ctxlock); |
| 954 | 951 | set_current_state(TASK_INTERRUPTIBLE); |
| 955 | 952 | schedule_timeout(GRU_ASSIGN_DELAY); /* true hack ZZZ */ |
| @@ -965,7 +962,6 @@ again: · 9 unmodified lines | ||
| 965 | 962 | vma->vm_page_prot); |
| 966 | 963 | } |
| 967 | 964 | |
| 968 | − preempt_enable(); | |
| 969 | 965 | mutex_unlock(>s->ts_ctxlock); |
| 970 | 966 | |
| 971 | 967 | return VM_FAULT_NOPAGE; |
| @@ -65,7 +65,6 @@ static struct gru_tlb_global_handle *get_lock_tgh_handle(struct gru_state · 64 unmodified lines | ||
| 65 | 65 | struct gru_tlb_global_handle *tgh; |
| 66 | 66 | int n; |
| 67 | 67 | |
| 68 | − preempt_disable(); | |
| 69 | 68 | if (uv_numa_blade_id() == gru->gs_blade_id) |
| 70 | 69 | n = get_on_blade_tgh(gru); |
| 71 | 70 | else |
| @@ -79,7 +78,6 @@ static struct gru_tlb_global_handle *get_lock_tgh_handle(struct gru_state · 7 unmodified lines | ||
| 79 | 78 | static void get_unlock_tgh_handle(struct gru_tlb_global_handle *tgh) |
| 80 | 79 | { |
| 81 | 80 | unlock_tgh_handle(tgh); |
| 82 | − preempt_enable(); | |
| 83 | 81 | } |
| 84 | 82 | |
| 85 | 83 | /* |
| @@ -388,7 +388,8 @@ static struct gendisk *mmc_alloc_disk(struct mmc_queue *mq, · 387 unmodified lines | ||
| 388 | 388 | |
| 389 | 389 | blk_queue_rq_timeout(mq->queue, 60 * HZ); |
| 390 | 390 | |
| 391 | − dma_set_max_seg_size(mmc_dev(host), queue_max_segment_size(mq->queue)); | |
| 391 | + if (mmc_dev(host)->dma_parms) | |
| 392 | + dma_set_max_seg_size(mmc_dev(host), queue_max_segment_size(mq->queue)); | |
| 392 | 393 | |
| 393 | 394 | INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler); |
| 394 | 395 | INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work); |
| @@ -38,9 +38,8 @@ struct mvsd_host { · 37 unmodified lines | ||
| 38 | 38 | unsigned int xfer_mode; |
| 39 | 39 | unsigned int intr_en; |
| 40 | 40 | unsigned int ctrl; |
| 41 | − bool use_pio; | |
| 42 | − struct sg_mapping_iter sg_miter; | |
| 43 | 41 | unsigned int pio_size; |
| 42 | + void *pio_ptr; | |
| 44 | 43 | unsigned int sg_frags; |
| 45 | 44 | unsigned int ns_per_clk; |
| 46 | 45 | unsigned int clock; |
| @@ -115,18 +114,11 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data) · 68 unmodified lines | ||
| 115 | 114 | * data when the buffer is not aligned on a 64 byte |
| 116 | 115 | * boundary. |
| 117 | 116 | */ |
| 118 | − unsigned int miter_flags = SG_MITER_ATOMIC; /* Used from IRQ */ | |
| 119 | − | |
| 120 | − if (data->flags & MMC_DATA_READ) | |
| 121 | − miter_flags |= SG_MITER_TO_SG; | |
| 122 | − else | |
| 123 | − miter_flags |= SG_MITER_FROM_SG; | |
| 124 | − | |
| 125 | 117 | host->pio_size = data->blocks * data->blksz; |
| 126 | − sg_miter_start(&host->sg_miter, data->sg, data->sg_len, miter_flags); | |
| 118 | + host->pio_ptr = sg_virt(data->sg); | |
| 127 | 119 | if (!nodma) |
| 128 | − dev_dbg(host->dev, "fallback to PIO for data\n"); | |
| 129 | − host->use_pio = true; | |
| 120 | + dev_dbg(host->dev, "fallback to PIO for data at 0x%p size %d\n", | |
| 121 | + host->pio_ptr, host->pio_size); | |
| 130 | 122 | return 1; |
| 131 | 123 | } else { |
| 132 | 124 | dma_addr_t phys_addr; |
| @@ -137,7 +129,6 @@ static int mvsd_setup_data(struct mvsd_host *host, struct mmc_data *data) · 4 unmodified lines | ||
| 137 | 129 | phys_addr = sg_dma_address(data->sg); |
| 138 | 130 | mvsd_write(MVSD_SYS_ADDR_LOW, (u32)phys_addr & 0xffff); |
| 139 | 131 | mvsd_write(MVSD_SYS_ADDR_HI, (u32)phys_addr >> 16); |
| 140 | − host->use_pio = false; | |
| 141 | 132 | return 0; |
| 142 | 133 | } |
| 143 | 134 | } |
| @@ -297,8 +288,8 @@ static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data, · 153 unmodified lines | ||
| 297 | 288 | { |
| 298 | 289 | void __iomem *iobase = host->base; |
| 299 | 290 | |
| 300 | − if (host->use_pio) { | |
| 301 | − sg_miter_stop(&host->sg_miter); | |
| 291 | + if (host->pio_ptr) { | |
| 292 | + host->pio_ptr = NULL; | |
| 302 | 293 | host->pio_size = 0; |
| 303 | 294 | } else { |
| 304 | 295 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_frags, |
| @@ -353,12 +344,9 @@ static u32 mvsd_finish_data(struct mvsd_host *host, struct mmc_data *data, · 48 unmodified lines | ||
| 353 | 344 | static irqreturn_t mvsd_irq(int irq, void *dev) |
| 354 | 345 | { |
| 355 | 346 | struct mvsd_host *host = dev; |
| 356 | − struct sg_mapping_iter *sgm = &host->sg_miter; | |
| 357 | 347 | void __iomem *iobase = host->base; |
| 358 | 348 | u32 intr_status, intr_done_mask; |
| 359 | 349 | int irq_handled = 0; |
| 360 | − u16 *p; | |
| 361 | − int s; | |
| 362 | 350 | |
| 363 | 351 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 364 | 352 | dev_dbg(host->dev, "intr 0x%04x intr_en 0x%04x hw_state 0x%04x\n", |
| @@ -382,36 +370,15 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 17 unmodified lines | ||
| 382 | 370 | spin_lock(&host->lock); |
| 383 | 371 | |
| 384 | 372 | /* PIO handling, if needed. Messy business... */ |
| 385 | − if (host->use_pio) { | |
| 386 | − /* | |
| 387 | − * As we set sgm->consumed this always gives a valid buffer | |
| 388 | − * position. | |
| 389 | − */ | |
| 390 | − if (!sg_miter_next(sgm)) { | |
| 391 | − /* This should not happen */ | |
| 392 | − dev_err(host->dev, "ran out of scatter segments\n"); | |
| 393 | − spin_unlock(&host->lock); | |
| 394 | − host->intr_en &= | |
| 395 | − ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W | | |
| 396 | − MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W); | |
| 397 | − mvsd_write(MVSD_NOR_INTR_EN, host->intr_en); | |
| 398 | − return IRQ_HANDLED; | |
| 399 | − } | |
| 400 | − p = sgm->addr; | |
| 401 | − s = sgm->length; | |
| 402 | − if (s > host->pio_size) | |
| 403 | − s = host->pio_size; | |
| 404 | − } | |
| 405 | − | |
| 406 | − if (host->use_pio && | |
| 373 | + if (host->pio_size && | |
| 407 | 374 | (intr_status & host->intr_en & |
| 408 | 375 | (MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) { |
| 409 | − | |
| 376 | + u16 *p = host->pio_ptr; | |
| 377 | + int s = host->pio_size; | |
| 410 | 378 | while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) { |
| 411 | 379 | readsw(iobase + MVSD_FIFO, p, 16); |
| 412 | 380 | p += 16; |
| 413 | 381 | s -= 32; |
| 414 | − sgm->consumed += 32; | |
| 415 | 382 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 416 | 383 | } |
| 417 | 384 | /* |
| @@ -424,7 +391,6 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 6 unmodified lines | ||
| 424 | 391 | put_unaligned(mvsd_read(MVSD_FIFO), p++); |
| 425 | 392 | put_unaligned(mvsd_read(MVSD_FIFO), p++); |
| 426 | 393 | s -= 4; |
| 427 | − sgm->consumed += 4; | |
| 428 | 394 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 429 | 395 | } |
| 430 | 396 | if (s && s < 4 && (intr_status & MVSD_NOR_RX_READY)) { |
| @@ -432,13 +398,10 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 1 unmodified line | ||
| 432 | 398 | val[0] = mvsd_read(MVSD_FIFO); |
| 433 | 399 | val[1] = mvsd_read(MVSD_FIFO); |
| 434 | 400 | memcpy(p, ((void *)&val) + 4 - s, s); |
| 435 | − sgm->consumed += s; | |
| 436 | 401 | s = 0; |
| 437 | 402 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 438 | 403 | } |
| 439 | − /* PIO transfer done */ | |
| 440 | − host->pio_size -= sgm->consumed; | |
| 441 | − if (host->pio_size == 0) { | |
| 404 | + if (s == 0) { | |
| 442 | 405 | host->intr_en &= |
| 443 | 406 | ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W); |
| 444 | 407 | mvsd_write(MVSD_NOR_INTR_EN, host->intr_en); |
| @@ -450,10 +413,14 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 5 unmodified lines | ||
| 450 | 413 | } |
| 451 | 414 | dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n", |
| 452 | 415 | s, intr_status, mvsd_read(MVSD_HW_STATE)); |
| 416 | + host->pio_ptr = p; | |
| 417 | + host->pio_size = s; | |
| 453 | 418 | irq_handled = 1; |
| 454 | − } else if (host->use_pio && | |
| 419 | + } else if (host->pio_size && | |
| 455 | 420 | (intr_status & host->intr_en & |
| 456 | 421 | (MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W))) { |
| 422 | + u16 *p = host->pio_ptr; | |
| 423 | + int s = host->pio_size; | |
| 457 | 424 | /* |
| 458 | 425 | * The TX_FIFO_8W bit is unreliable. When set, bursting |
| 459 | 426 | * 16 halfwords all at once in the FIFO drops data. Actually |
| @@ -464,7 +431,6 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 4 unmodified lines | ||
| 464 | 431 | mvsd_write(MVSD_FIFO, get_unaligned(p++)); |
| 465 | 432 | mvsd_write(MVSD_FIFO, get_unaligned(p++)); |
| 466 | 433 | s -= 4; |
| 467 | − sgm->consumed += 4; | |
| 468 | 434 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 469 | 435 | } |
| 470 | 436 | if (s < 4) { |
| @@ -473,13 +439,10 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 2 unmodified lines | ||
| 473 | 439 | memcpy(((void *)&val) + 4 - s, p, s); |
| 474 | 440 | mvsd_write(MVSD_FIFO, val[0]); |
| 475 | 441 | mvsd_write(MVSD_FIFO, val[1]); |
| 476 | − sgm->consumed += s; | |
| 477 | 442 | s = 0; |
| 478 | 443 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 479 | 444 | } |
| 480 | − /* PIO transfer done */ | |
| 481 | − host->pio_size -= sgm->consumed; | |
| 482 | − if (host->pio_size == 0) { | |
| 445 | + if (s == 0) { | |
| 483 | 446 | host->intr_en &= |
| 484 | 447 | ~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W); |
| 485 | 448 | mvsd_write(MVSD_NOR_INTR_EN, host->intr_en); |
| @@ -487,6 +450,8 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 1 unmodified line | ||
| 487 | 450 | } |
| 488 | 451 | dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n", |
| 489 | 452 | s, intr_status, mvsd_read(MVSD_HW_STATE)); |
| 453 | + host->pio_ptr = p; | |
| 454 | + host->pio_size = s; | |
| 490 | 455 | irq_handled = 1; |
| 491 | 456 | } |
| 492 | 457 | |
| @@ -852,6 +852,14 @@ static void th1520_sdhci_reset(struct sdhci_host *host, u8 mask) · 851 unmodified lines | ||
| 852 | 852 | |
| 853 | 853 | sdhci_reset(host, mask); |
| 854 | 854 | |
| 855 | + /* The T-Head 1520 SoC does not comply with the SDHCI specification | |
| 856 | + * regarding the "Software Reset for CMD line should clear 'Command | |
| 857 | + * Complete' in the Normal Interrupt Status Register." Clear the bit | |
| 858 | + * here to compensate for this quirk. | |
| 859 | + */ | |
| 860 | + if (mask & SDHCI_RESET_CMD) | |
| 861 | + sdhci_writel(host, SDHCI_INT_RESPONSE, SDHCI_INT_STATUS); | |
| 862 | + | |
| 855 | 863 | if (priv->flags & FLAG_IO_FIXED_1V8) { |
| 856 | 864 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
| 857 | 865 | if (!(ctrl_2 & SDHCI_CTRL_VDD_180)) { |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | ||
| 27 | 27 | #include <linux/phylink.h> |
| 28 | 28 | #include <linux/etherdevice.h> |
| 29 | 29 | #include <linux/if_bridge.h> |
| 30 | +#include <linux/if_vlan.h> | |
| 30 | 31 | #include <net/dsa.h> |
| 31 | 32 | |
| 32 | 33 | #include "b53_regs.h" |
| @@ -224,6 +225,9 @@ static const struct b53_mib_desc b53_mibs_58xx[] = { · 191 unmodified lines | ||
| 224 | 225 | |
| 225 | 226 | #define B53_MIBS_58XX_SIZE ARRAY_SIZE(b53_mibs_58xx) |
| 226 | 227 | |
| 228 | +#define B53_MAX_MTU_25 (1536 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) | |
| 229 | +#define B53_MAX_MTU (9720 - ETH_HLEN - VLAN_HLEN - ETH_FCS_LEN) | |
| 230 | + | |
| 227 | 231 | static int b53_do_vlan_op(struct b53_device *dev, u8 op) |
| 228 | 232 | { |
| 229 | 233 | unsigned int i; |
| @@ -2254,20 +2258,25 @@ static int b53_change_mtu(struct dsa_switch *ds, int port, int mtu) · 2024 unmodified lines | ||
| 2254 | 2258 | bool allow_10_100; |
| 2255 | 2259 | |
| 2256 | 2260 | if (is5325(dev) || is5365(dev)) |
| 2257 | − return -EOPNOTSUPP; | |
| 2261 | + return 0; | |
| 2258 | 2262 | |
| 2259 | 2263 | if (!dsa_is_cpu_port(ds, port)) |
| 2260 | 2264 | return 0; |
| 2261 | 2265 | |
| 2262 | − enable_jumbo = (mtu >= JMS_MIN_SIZE); | |
| 2263 | − allow_10_100 = (dev->chip_id == BCM583XX_DEVICE_ID); | |
| 2266 | + enable_jumbo = (mtu > ETH_DATA_LEN); | |
| 2267 | + allow_10_100 = !is63xx(dev); | |
| 2264 | 2268 | |
| 2265 | 2269 | return b53_set_jumbo(dev, enable_jumbo, allow_10_100); |
| 2266 | 2270 | } |
| 2267 | 2271 | |
| 2268 | 2272 | static int b53_get_max_mtu(struct dsa_switch *ds, int port) |
| 2269 | 2273 | { |
| 2270 | − return JMS_MAX_SIZE; | |
| 2274 | + struct b53_device *dev = ds->priv; | |
| 2275 | + | |
| 2276 | + if (is5325(dev) || is5365(dev)) | |
| 2277 | + return B53_MAX_MTU_25; | |
| 2278 | + | |
| 2279 | + return B53_MAX_MTU; | |
| 2271 | 2280 | } |
| 2272 | 2281 | |
| 2273 | 2282 | static const struct phylink_mac_ops b53_phylink_mac_ops = { |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/module.h> |
| 7 | 7 | #include <linux/gpio/consumer.h> |
| 8 | 8 | #include <linux/regmap.h> |
| 9 | +#include <linux/iopoll.h> | |
| 9 | 10 | #include <linux/mutex.h> |
| 10 | 11 | #include <linux/mii.h> |
| 11 | 12 | #include <linux/of.h> |
| @@ -839,6 +840,8 @@ static void lan9303_handle_reset(struct lan9303 *chip) · 827 unmodified lines | ||
| 839 | 840 | if (!chip->reset_gpio) |
| 840 | 841 | return; |
| 841 | 842 | |
| 843 | + gpiod_set_value_cansleep(chip->reset_gpio, 1); | |
| 844 | + | |
| 842 | 845 | if (chip->reset_duration != 0) |
| 843 | 846 | msleep(chip->reset_duration); |
| 844 | 847 | |
| @@ -864,8 +867,34 @@ static int lan9303_disable_processing(struct lan9303 *chip) · 19 unmodified lines | ||
| 864 | 867 | static int lan9303_check_device(struct lan9303 *chip) |
| 865 | 868 | { |
| 866 | 869 | int ret; |
| 870 | + int err; | |
| 867 | 871 | u32 reg; |
| 868 | 872 | |
| 873 | + /* In I2C-managed configurations this polling loop will clash with | |
| 874 | + * switch's reading of EEPROM right after reset and this behaviour is | |
| 875 | + * not configurable. While lan9303_read() already has quite long retry | |
| 876 | + * timeout, seems not all cases are being detected as arbitration error. | |
| 877 | + * | |
| 878 | + * According to datasheet, EEPROM loader has 30ms timeout (in case of | |
| 879 | + * missing EEPROM). | |
| 880 | + * | |
| 881 | + * Loading of the largest supported EEPROM is expected to take at least | |
| 882 | + * 5.9s. | |
| 883 | + */ | |
| 884 | + err = read_poll_timeout(lan9303_read, ret, | |
| 885 | + !ret && reg & LAN9303_HW_CFG_READY, | |
| 886 | + 20000, 6000000, false, | |
| 887 | + chip->regmap, LAN9303_HW_CFG, ®); | |
| 888 | + if (ret) { | |
| 889 | + dev_err(chip->dev, "failed to read HW_CFG reg: %pe\n", | |
| 890 | + ERR_PTR(ret)); | |
| 891 | + return ret; | |
| 892 | + } | |
| 893 | + if (err) { | |
| 894 | + dev_err(chip->dev, "HW_CFG not ready: 0x%08x\n", reg); | |
| 895 | + return err; | |
| 896 | + } | |
| 897 | + | |
| 869 | 898 | ret = lan9303_read(chip->regmap, LAN9303_CHIP_REV, ®); |
| 870 | 899 | if (ret) { |
| 871 | 900 | dev_err(chip->dev, "failed to read chip revision register: %d\n", |
| @@ -2733,26 +2733,27 @@ static u32 ksz_get_phy_flags(struct dsa_switch *ds, int port) · 2732 unmodified lines | ||
| 2733 | 2733 | return MICREL_KSZ8_P1_ERRATA; |
| 2734 | 2734 | break; |
| 2735 | 2735 | case KSZ8567_CHIP_ID: |
| 2736 | + /* KSZ8567R Errata DS80000752C Module 4 */ | |
| 2737 | + case KSZ8765_CHIP_ID: | |
| 2738 | + case KSZ8794_CHIP_ID: | |
| 2739 | + case KSZ8795_CHIP_ID: | |
| 2740 | + /* KSZ879x/KSZ877x/KSZ876x Errata DS80000687C Module 2 */ | |
| 2736 | 2741 | case KSZ9477_CHIP_ID: |
| 2742 | + /* KSZ9477S Errata DS80000754A Module 4 */ | |
| 2737 | 2743 | case KSZ9567_CHIP_ID: |
| 2744 | + /* KSZ9567S Errata DS80000756A Module 4 */ | |
| 2738 | 2745 | case KSZ9896_CHIP_ID: |
| 2746 | + /* KSZ9896C Errata DS80000757A Module 3 */ | |
| 2739 | 2747 | case KSZ9897_CHIP_ID: |
| 2740 | − /* KSZ9477 Errata DS80000754C | |
| 2741 | − * | |
| 2742 | − * Module 4: Energy Efficient Ethernet (EEE) feature select must | |
| 2743 | − * be manually disabled | |
| 2748 | + /* KSZ9897R Errata DS80000758C Module 4 */ | |
| 2749 | + /* Energy Efficient Ethernet (EEE) feature select must be manually disabled | |
| 2744 | 2750 | * The EEE feature is enabled by default, but it is not fully |
| 2745 | 2751 | * operational. It must be manually disabled through register |
| 2746 | 2752 | * controls. If not disabled, the PHY ports can auto-negotiate |
| 2747 | 2753 | * to enable EEE, and this feature can cause link drops when |
| 2748 | 2754 | * linked to another device supporting EEE. |
| 2749 | 2755 | * |
| 2750 | − * The same item appears in the errata for the KSZ9567, KSZ9896, | |
| 2751 | − * and KSZ9897. | |
| 2752 | − * | |
| 2753 | − * A similar item appears in the errata for the KSZ8567, but | |
| 2754 | − * provides an alternative workaround. For now, use the simple | |
| 2755 | − * workaround of disabling the EEE feature for this device too. | |
| 2756 | + * The same item appears in the errata for all switches above. | |
| 2756 | 2757 | */ |
| 2757 | 2758 | return MICREL_NO_EEE; |
| 2758 | 2759 | } |
| @@ -6347,7 +6347,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { · 6346 unmodified lines | ||
| 6347 | 6347 | .invalid_port_mask = BIT(1) | BIT(2) | BIT(8), |
| 6348 | 6348 | .num_internal_phys = 5, |
| 6349 | 6349 | .internal_phys_offset = 3, |
| 6350 | − .max_vid = 4095, | |
| 6350 | + .max_vid = 8191, | |
| 6351 | 6351 | .max_sid = 63, |
| 6352 | 6352 | .port_base_addr = 0x0, |
| 6353 | 6353 | .phy_base_addr = 0x0, |
| @@ -206,6 +206,7 @@ struct mv88e6xxx_gpio_ops; · 205 unmodified lines | ||
| 206 | 206 | struct mv88e6xxx_avb_ops; |
| 207 | 207 | struct mv88e6xxx_ptp_ops; |
| 208 | 208 | struct mv88e6xxx_pcs_ops; |
| 209 | +struct mv88e6xxx_cc_coeffs; | |
| 209 | 210 | |
| 210 | 211 | struct mv88e6xxx_irq { |
| 211 | 212 | u16 masked; |
| @@ -408,6 +409,7 @@ struct mv88e6xxx_chip { · 196 unmodified lines | ||
| 408 | 409 | struct cyclecounter tstamp_cc; |
| 409 | 410 | struct timecounter tstamp_tc; |
| 410 | 411 | struct delayed_work overflow_work; |
| 412 | + const struct mv88e6xxx_cc_coeffs *cc_coeffs; | |
| 411 | 413 | |
| 412 | 414 | struct ptp_clock *ptp_clock; |
| 413 | 415 | struct ptp_clock_info ptp_clock_info; |
| @@ -731,10 +733,6 @@ struct mv88e6xxx_ptp_ops { · 317 unmodified lines | ||
| 731 | 733 | int arr1_sts_reg; |
| 732 | 734 | int dep_sts_reg; |
| 733 | 735 | u32 rx_filters; |
| 734 | − u32 cc_shift; | |
| 735 | − u32 cc_mult; | |
| 736 | − u32 cc_mult_num; | |
| 737 | − u32 cc_mult_dem; | |
| 738 | 736 | }; |
| 739 | 737 | |
| 740 | 738 | struct mv88e6xxx_pcs_ops { |
| @@ -1713,6 +1713,7 @@ int mv88e6393x_port_set_policy(struct mv88e6xxx_chip *chip, int port, · 1712 unmodified lines | ||
| 1713 | 1713 | ptr = shift / 8; |
| 1714 | 1714 | shift %= 8; |
| 1715 | 1715 | mask >>= ptr * 8; |
| 1716 | + ptr <<= 8; | |
| 1716 | 1717 | |
| 1717 | 1718 | err = mv88e6393x_port_policy_read(chip, port, ptr, ®); |
| 1718 | 1719 | if (err) |
| @@ -18,6 +18,13 @@ · 17 unmodified lines | ||
| 18 | 18 | |
| 19 | 19 | #define MV88E6XXX_MAX_ADJ_PPB 1000000 |
| 20 | 20 | |
| 21 | +struct mv88e6xxx_cc_coeffs { | |
| 22 | + u32 cc_shift; | |
| 23 | + u32 cc_mult; | |
| 24 | + u32 cc_mult_num; | |
| 25 | + u32 cc_mult_dem; | |
| 26 | +}; | |
| 27 | + | |
| 21 | 28 | /* Family MV88E6250: |
| 22 | 29 | * Raw timestamps are in units of 10-ns clock periods. |
| 23 | 30 | * |
| @@ -25,22 +32,43 @@ · 1 unmodified line | ||
| 25 | 32 | * simplifies to |
| 26 | 33 | * clkadj = scaled_ppm * 2^7 / 5^5 |
| 27 | 34 | */ |
| 28 | −#define MV88E6250_CC_SHIFT 28 | |
| 29 | −#define MV88E6250_CC_MULT (10 << MV88E6250_CC_SHIFT) | |
| 30 | −#define MV88E6250_CC_MULT_NUM (1 << 7) | |
| 31 | −#define MV88E6250_CC_MULT_DEM 3125ULL | |
| 35 | +#define MV88E6XXX_CC_10NS_SHIFT 28 | |
| 36 | +static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_10ns_coeffs = { | |
| 37 | + .cc_shift = MV88E6XXX_CC_10NS_SHIFT, | |
| 38 | + .cc_mult = 10 << MV88E6XXX_CC_10NS_SHIFT, | |
| 39 | + .cc_mult_num = 1 << 7, | |
| 40 | + .cc_mult_dem = 3125ULL, | |
| 41 | +}; | |
| 32 | 42 | |
| 33 | −/* Other families: | |
| 43 | +/* Other families except MV88E6393X in internal clock mode: | |
| 34 | 44 | * Raw timestamps are in units of 8-ns clock periods. |
| 35 | 45 | * |
| 36 | 46 | * clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16) |
| 37 | 47 | * simplifies to |
| 38 | 48 | * clkadj = scaled_ppm * 2^9 / 5^6 |
| 39 | 49 | */ |
| 40 | −#define MV88E6XXX_CC_SHIFT 28 | |
| 41 | −#define MV88E6XXX_CC_MULT (8 << MV88E6XXX_CC_SHIFT) | |
| 42 | −#define MV88E6XXX_CC_MULT_NUM (1 << 9) | |
| 43 | −#define MV88E6XXX_CC_MULT_DEM 15625ULL | |
| 50 | +#define MV88E6XXX_CC_8NS_SHIFT 28 | |
| 51 | +static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_8ns_coeffs = { | |
| 52 | + .cc_shift = MV88E6XXX_CC_8NS_SHIFT, | |
| 53 | + .cc_mult = 8 << MV88E6XXX_CC_8NS_SHIFT, | |
| 54 | + .cc_mult_num = 1 << 9, | |
| 55 | + .cc_mult_dem = 15625ULL | |
| 56 | +}; | |
| 57 | + | |
| 58 | +/* Family MV88E6393X using internal clock: | |
| 59 | + * Raw timestamps are in units of 4-ns clock periods. | |
| 60 | + * | |
| 61 | + * clkadj = scaled_ppm * 4*2^28 / (10^6 * 2^16) | |
| 62 | + * simplifies to | |
| 63 | + * clkadj = scaled_ppm * 2^8 / 5^6 | |
| 64 | + */ | |
| 65 | +#define MV88E6XXX_CC_4NS_SHIFT 28 | |
| 66 | +static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_4ns_coeffs = { | |
| 67 | + .cc_shift = MV88E6XXX_CC_4NS_SHIFT, | |
| 68 | + .cc_mult = 4 << MV88E6XXX_CC_4NS_SHIFT, | |
| 69 | + .cc_mult_num = 1 << 8, | |
| 70 | + .cc_mult_dem = 15625ULL | |
| 71 | +}; | |
| 44 | 72 | |
| 45 | 73 | #define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100) |
| 46 | 74 | |
| @@ -83,6 +111,33 @@ static int mv88e6352_set_gpio_func(struct mv88e6xxx_chip *chip, int pin, · 36 unmodified lines | ||
| 83 | 111 | return chip->info->ops->gpio_ops->set_pctl(chip, pin, func); |
| 84 | 112 | } |
| 85 | 113 | |
| 114 | +static const struct mv88e6xxx_cc_coeffs * | |
| 115 | +mv88e6xxx_cc_coeff_get(struct mv88e6xxx_chip *chip) | |
| 116 | +{ | |
| 117 | + u16 period_ps; | |
| 118 | + int err; | |
| 119 | + | |
| 120 | + err = mv88e6xxx_tai_read(chip, MV88E6XXX_TAI_CLOCK_PERIOD, &period_ps, 1); | |
| 121 | + if (err) { | |
| 122 | + dev_err(chip->dev, "failed to read cycle counter period: %d\n", | |
| 123 | + err); | |
| 124 | + return ERR_PTR(err); | |
| 125 | + } | |
| 126 | + | |
| 127 | + switch (period_ps) { | |
| 128 | + case 4000: | |
| 129 | + return &mv88e6xxx_cc_4ns_coeffs; | |
| 130 | + case 8000: | |
| 131 | + return &mv88e6xxx_cc_8ns_coeffs; | |
| 132 | + case 10000: | |
| 133 | + return &mv88e6xxx_cc_10ns_coeffs; | |
| 134 | + default: | |
| 135 | + dev_err(chip->dev, "unexpected cycle counter period of %u ps\n", | |
| 136 | + period_ps); | |
| 137 | + return ERR_PTR(-ENODEV); | |
| 138 | + } | |
| 139 | +} | |
| 140 | + | |
| 86 | 141 | static u64 mv88e6352_ptp_clock_read(const struct cyclecounter *cc) |
| 87 | 142 | { |
| 88 | 143 | struct mv88e6xxx_chip *chip = cc_to_chip(cc); |
| @@ -204,7 +259,6 @@ out: · 115 unmodified lines | ||
| 204 | 259 | static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) |
| 205 | 260 | { |
| 206 | 261 | struct mv88e6xxx_chip *chip = ptp_to_chip(ptp); |
| 207 | − const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops; | |
| 208 | 262 | int neg_adj = 0; |
| 209 | 263 | u32 diff, mult; |
| 210 | 264 | u64 adj; |
| @@ -214,10 +268,10 @@ static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) · 3 unmodified lines | ||
| 214 | 268 | scaled_ppm = -scaled_ppm; |
| 215 | 269 | } |
| 216 | 270 | |
| 217 | − mult = ptp_ops->cc_mult; | |
| 218 | − adj = ptp_ops->cc_mult_num; | |
| 271 | + mult = chip->cc_coeffs->cc_mult; | |
| 272 | + adj = chip->cc_coeffs->cc_mult_num; | |
| 219 | 273 | adj *= scaled_ppm; |
| 220 | − diff = div_u64(adj, ptp_ops->cc_mult_dem); | |
| 274 | + diff = div_u64(adj, chip->cc_coeffs->cc_mult_dem); | |
| 221 | 275 | |
| 222 | 276 | mv88e6xxx_reg_lock(chip); |
| 223 | 277 | |
| @@ -364,10 +418,6 @@ const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = { · 140 unmodified lines | ||
| 364 | 418 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 365 | 419 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 366 | 420 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), |
| 367 | − .cc_shift = MV88E6XXX_CC_SHIFT, | |
| 368 | − .cc_mult = MV88E6XXX_CC_MULT, | |
| 369 | − .cc_mult_num = MV88E6XXX_CC_MULT_NUM, | |
| 370 | − .cc_mult_dem = MV88E6XXX_CC_MULT_DEM, | |
| 371 | 421 | }; |
| 372 | 422 | |
| 373 | 423 | const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = { |
| @@ -391,10 +441,6 @@ const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = { · 17 unmodified lines | ||
| 391 | 441 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 392 | 442 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 393 | 443 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), |
| 394 | − .cc_shift = MV88E6250_CC_SHIFT, | |
| 395 | − .cc_mult = MV88E6250_CC_MULT, | |
| 396 | − .cc_mult_num = MV88E6250_CC_MULT_NUM, | |
| 397 | − .cc_mult_dem = MV88E6250_CC_MULT_DEM, | |
| 398 | 444 | }; |
| 399 | 445 | |
| 400 | 446 | const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = { |
| @@ -418,10 +464,6 @@ const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = { · 17 unmodified lines | ||
| 418 | 464 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 419 | 465 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 420 | 466 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), |
| 421 | − .cc_shift = MV88E6XXX_CC_SHIFT, | |
| 422 | − .cc_mult = MV88E6XXX_CC_MULT, | |
| 423 | − .cc_mult_num = MV88E6XXX_CC_MULT_NUM, | |
| 424 | − .cc_mult_dem = MV88E6XXX_CC_MULT_DEM, | |
| 425 | 467 | }; |
| 426 | 468 | |
| 427 | 469 | const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = { |
| @@ -446,10 +488,6 @@ const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = { · 18 unmodified lines | ||
| 446 | 488 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 447 | 489 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 448 | 490 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), |
| 449 | − .cc_shift = MV88E6XXX_CC_SHIFT, | |
| 450 | − .cc_mult = MV88E6XXX_CC_MULT, | |
| 451 | − .cc_mult_num = MV88E6XXX_CC_MULT_NUM, | |
| 452 | − .cc_mult_dem = MV88E6XXX_CC_MULT_DEM, | |
| 453 | 491 | }; |
| 454 | 492 | |
| 455 | 493 | static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc) |
| @@ -462,10 +500,10 @@ static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc) · 6 unmodified lines | ||
| 462 | 500 | return 0; |
| 463 | 501 | } |
| 464 | 502 | |
| 465 | −/* With a 125MHz input clock, the 32-bit timestamp counter overflows in ~34.3 | |
| 503 | +/* With a 250MHz input clock, the 32-bit timestamp counter overflows in ~17.2 | |
| 466 | 504 | * seconds; this task forces periodic reads so that we don't miss any. |
| 467 | 505 | */ |
| 468 | −#define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 16) | |
| 506 | +#define MV88E6XXX_TAI_OVERFLOW_PERIOD (HZ * 8) | |
| 469 | 507 | static void mv88e6xxx_ptp_overflow_check(struct work_struct *work) |
| 470 | 508 | { |
| 471 | 509 | struct delayed_work *dw = to_delayed_work(work); |
| @@ -484,11 +522,15 @@ int mv88e6xxx_ptp_setup(struct mv88e6xxx_chip *chip) · 12 unmodified lines | ||
| 484 | 522 | int i; |
| 485 | 523 | |
| 486 | 524 | /* Set up the cycle counter */ |
| 525 | + chip->cc_coeffs = mv88e6xxx_cc_coeff_get(chip); | |
| 526 | + if (IS_ERR(chip->cc_coeffs)) | |
| 527 | + return PTR_ERR(chip->cc_coeffs); | |
| 528 | + | |
| 487 | 529 | memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc)); |
| 488 | 530 | chip->tstamp_cc.read = mv88e6xxx_ptp_clock_read; |
| 489 | 531 | chip->tstamp_cc.mask = CYCLECOUNTER_MASK(32); |
| 490 | − chip->tstamp_cc.mult = ptp_ops->cc_mult; | |
| 491 | − chip->tstamp_cc.shift = ptp_ops->cc_shift; | |
| 532 | + chip->tstamp_cc.mult = chip->cc_coeffs->cc_mult; | |
| 533 | + chip->tstamp_cc.shift = chip->cc_coeffs->cc_shift; | |
| 492 | 534 | |
| 493 | 535 | timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc, |
| 494 | 536 | ktime_to_ns(ktime_get_real())); |
| @@ -3158,7 +3158,6 @@ static int sja1105_setup(struct dsa_switch *ds) · 3157 unmodified lines | ||
| 3158 | 3158 | * TPID is ETH_P_SJA1105, and the VLAN ID is the port pvid. |
| 3159 | 3159 | */ |
| 3160 | 3160 | ds->vlan_filtering_is_global = true; |
| 3161 | − ds->untag_bridge_pvid = true; | |
| 3162 | 3161 | ds->fdb_isolation = true; |
| 3163 | 3162 | ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES; |
| 3164 | 3163 | |
| @@ -851,7 +851,6 @@ static int vsc73xx_setup(struct dsa_switch *ds) · 850 unmodified lines | ||
| 851 | 851 | |
| 852 | 852 | dev_info(vsc->dev, "set up the switch\n"); |
| 853 | 853 | |
| 854 | − ds->untag_bridge_pvid = true; | |
| 855 | 854 | ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES; |
| 856 | 855 | ds->fdb_isolation = true; |
| 857 | 856 | |
| @@ -318,11 +318,11 @@ static int adin1110_read_fifo(struct adin1110_port_priv *port_priv) · 317 unmodified lines | ||
| 318 | 318 | * from the ADIN1110 frame header. |
| 319 | 319 | */ |
| 320 | 320 | if (frame_size < ADIN1110_FRAME_HEADER_LEN + ADIN1110_FEC_LEN) |
| 321 | − return ret; | |
| 321 | + return -EINVAL; | |
| 322 | 322 | |
| 323 | 323 | round_len = adin1110_round_len(frame_size); |
| 324 | 324 | if (round_len < 0) |
| 325 | − return ret; | |
| 325 | + return -EINVAL; | |
| 326 | 326 | |
| 327 | 327 | frame_size_no_fcs = frame_size - ADIN1110_FRAME_HEADER_LEN - ADIN1110_FEC_LEN; |
| 328 | 328 | memset(priv->data, 0, ADIN1110_RD_HEADER_LEN); |
| @@ -484,7 +484,7 @@ greth_start_xmit_gbit(struct sk_buff *skb, struct net_device *dev) · 483 unmodified lines | ||
| 484 | 484 | |
| 485 | 485 | if (unlikely(skb->len > MAX_FRAME_SIZE)) { |
| 486 | 486 | dev->stats.tx_errors++; |
| 487 | − goto out; | |
| 487 | + goto len_error; | |
| 488 | 488 | } |
| 489 | 489 | |
| 490 | 490 | /* Save skb pointer. */ |
| @@ -575,6 +575,7 @@ frag_map_error: · 84 unmodified lines | ||
| 575 | 575 | map_error: |
| 576 | 576 | if (net_ratelimit()) |
| 577 | 577 | dev_warn(greth->dev, "Could not create TX DMA mapping\n"); |
| 578 | +len_error: | |
| 578 | 579 | dev_kfree_skb(skb); |
| 579 | 580 | out: |
| 580 | 581 | return err; |
| @@ -105,10 +105,6 @@ static struct net_device * __init mvme147lance_probe(void) · 104 unmodified lines | ||
| 105 | 105 | macaddr[3] = address&0xff; |
| 106 | 106 | eth_hw_addr_set(dev, macaddr); |
| 107 | 107 | |
| 108 | − printk("%s: MVME147 at 0x%08lx, irq %d, Hardware Address %pM\n", | |
| 109 | − dev->name, dev->base_addr, MVME147_LANCE_IRQ, | |
| 110 | − dev->dev_addr); | |
| 111 | − | |
| 112 | 108 | lp = netdev_priv(dev); |
| 113 | 109 | lp->ram = __get_dma_pages(GFP_ATOMIC, 3); /* 32K */ |
| 114 | 110 | if (!lp->ram) { |
| @@ -138,6 +134,9 @@ static struct net_device * __init mvme147lance_probe(void) · 23 unmodified lines | ||
| 138 | 134 | return ERR_PTR(err); |
| 139 | 135 | } |
| 140 | 136 | |
| 137 | + netdev_info(dev, "MVME147 at 0x%08lx, irq %d, Hardware Address %pM\n", | |
| 138 | + dev->base_addr, MVME147_LANCE_IRQ, dev->dev_addr); | |
| 139 | + | |
| 141 | 140 | return dev; |
| 142 | 141 | } |
| 143 | 142 | |
| @@ -322,6 +322,7 @@ static netdev_tx_t bcmasp_xmit(struct sk_buff *skb, struct net_device *dev) · 321 unmodified lines | ||
| 322 | 322 | } |
| 323 | 323 | /* Rewind so we do not have a hole */ |
| 324 | 324 | spb_index = intf->tx_spb_index; |
| 325 | + dev_kfree_skb(skb); | |
| 325 | 326 | return NETDEV_TX_OK; |
| 326 | 327 | } |
| 327 | 328 | |
| @@ -1359,6 +1359,7 @@ static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb, · 1358 unmodified lines | ||
| 1359 | 1359 | netif_err(priv, tx_err, dev, "DMA map failed at %p (len=%d)\n", |
| 1360 | 1360 | skb->data, skb_len); |
| 1361 | 1361 | ret = NETDEV_TX_OK; |
| 1362 | + dev_kfree_skb_any(skb); | |
| 1362 | 1363 | goto out; |
| 1363 | 1364 | } |
| 1364 | 1365 | |
| @@ -2254,10 +2254,11 @@ static int bnxt_rx_pkt(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, · 2253 unmodified lines | ||
| 2254 | 2254 | |
| 2255 | 2255 | if (!bnxt_get_rx_ts_p5(bp, &ts, cmpl_ts)) { |
| 2256 | 2256 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; |
| 2257 | + unsigned long flags; | |
| 2257 | 2258 | |
| 2258 | − spin_lock_bh(&ptp->ptp_lock); | |
| 2259 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 2259 | 2260 | ns = timecounter_cyc2time(&ptp->tc, ts); |
| 2260 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 2261 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 2261 | 2262 | memset(skb_hwtstamps(skb), 0, |
| 2262 | 2263 | sizeof(*skb_hwtstamps(skb))); |
| 2263 | 2264 | skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns); |
| @@ -2757,17 +2758,18 @@ static int bnxt_async_event_process(struct bnxt *bp, · 493 unmodified lines | ||
| 2757 | 2758 | case ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_FLAGS_PHC_RTC_UPDATE: |
| 2758 | 2759 | if (BNXT_PTP_USE_RTC(bp)) { |
| 2759 | 2760 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; |
| 2761 | + unsigned long flags; | |
| 2760 | 2762 | u64 ns; |
| 2761 | 2763 | |
| 2762 | 2764 | if (!ptp) |
| 2763 | 2765 | goto async_event_process_exit; |
| 2764 | 2766 | |
| 2765 | − spin_lock_bh(&ptp->ptp_lock); | |
| 2767 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 2766 | 2768 | bnxt_ptp_update_current_time(bp); |
| 2767 | 2769 | ns = (((u64)BNXT_EVENT_PHC_RTC_UPDATE(data1) << |
| 2768 | 2770 | BNXT_PHC_BITS) | ptp->current_time); |
| 2769 | 2771 | bnxt_ptp_rtc_timecounter_init(ptp, ns); |
| 2770 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 2772 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 2771 | 2773 | } |
| 2772 | 2774 | break; |
| 2773 | 2775 | } |
| @@ -13494,9 +13496,11 @@ static void bnxt_force_fw_reset(struct bnxt *bp) · 10720 unmodified lines | ||
| 13494 | 13496 | return; |
| 13495 | 13497 | |
| 13496 | 13498 | if (ptp) { |
| 13497 | − spin_lock_bh(&ptp->ptp_lock); | |
| 13499 | + unsigned long flags; | |
| 13500 | + | |
| 13501 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 13498 | 13502 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); |
| 13499 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 13503 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 13500 | 13504 | } else { |
| 13501 | 13505 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); |
| 13502 | 13506 | } |
| @@ -13561,9 +13565,11 @@ void bnxt_fw_reset(struct bnxt *bp) · 58 unmodified lines | ||
| 13561 | 13565 | int n = 0, tmo; |
| 13562 | 13566 | |
| 13563 | 13567 | if (ptp) { |
| 13564 | − spin_lock_bh(&ptp->ptp_lock); | |
| 13568 | + unsigned long flags; | |
| 13569 | + | |
| 13570 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 13565 | 13571 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); |
| 13566 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 13572 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 13567 | 13573 | } else { |
| 13568 | 13574 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); |
| 13569 | 13575 | } |
| @@ -62,13 +62,14 @@ static int bnxt_ptp_settime(struct ptp_clock_info *ptp_info, · 61 unmodified lines | ||
| 62 | 62 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 63 | 63 | ptp_info); |
| 64 | 64 | u64 ns = timespec64_to_ns(ts); |
| 65 | + unsigned long flags; | |
| 65 | 66 | |
| 66 | 67 | if (BNXT_PTP_USE_RTC(ptp->bp)) |
| 67 | 68 | return bnxt_ptp_cfg_settime(ptp->bp, ns); |
| 68 | 69 | |
| 69 | − spin_lock_bh(&ptp->ptp_lock); | |
| 70 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 70 | 71 | timecounter_init(&ptp->tc, &ptp->cc, ns); |
| 71 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 72 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 72 | 73 | return 0; |
| 73 | 74 | } |
| 74 | 75 | |
| @@ -100,13 +101,14 @@ static int bnxt_refclk_read(struct bnxt *bp, struct ptp_system_timestamp *sts, · 25 unmodified lines | ||
| 100 | 101 | static void bnxt_ptp_get_current_time(struct bnxt *bp) |
| 101 | 102 | { |
| 102 | 103 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; |
| 104 | + unsigned long flags; | |
| 103 | 105 | |
| 104 | 106 | if (!ptp) |
| 105 | 107 | return; |
| 106 | − spin_lock_bh(&ptp->ptp_lock); | |
| 108 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 107 | 109 | WRITE_ONCE(ptp->old_time, ptp->current_time); |
| 108 | 110 | bnxt_refclk_read(bp, NULL, &ptp->current_time); |
| 109 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 111 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 110 | 112 | } |
| 111 | 113 | |
| 112 | 114 | static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts, |
| @@ -149,17 +151,18 @@ static int bnxt_ptp_gettimex(struct ptp_clock_info *ptp_info, · 36 unmodified lines | ||
| 149 | 151 | { |
| 150 | 152 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 151 | 153 | ptp_info); |
| 154 | + unsigned long flags; | |
| 152 | 155 | u64 ns, cycles; |
| 153 | 156 | int rc; |
| 154 | 157 | |
| 155 | − spin_lock_bh(&ptp->ptp_lock); | |
| 158 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 156 | 159 | rc = bnxt_refclk_read(ptp->bp, sts, &cycles); |
| 157 | 160 | if (rc) { |
| 158 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 161 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 159 | 162 | return rc; |
| 160 | 163 | } |
| 161 | 164 | ns = timecounter_cyc2time(&ptp->tc, cycles); |
| 162 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 165 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 163 | 166 | *ts = ns_to_timespec64(ns); |
| 164 | 167 | |
| 165 | 168 | return 0; |
| @@ -177,6 +180,7 @@ void bnxt_ptp_update_current_time(struct bnxt *bp) · 11 unmodified lines | ||
| 177 | 180 | static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta) |
| 178 | 181 | { |
| 179 | 182 | struct hwrm_port_mac_cfg_input *req; |
| 183 | + unsigned long flags; | |
| 180 | 184 | int rc; |
| 181 | 185 | |
| 182 | 186 | rc = hwrm_req_init(ptp->bp, req, HWRM_PORT_MAC_CFG); |
| @@ -190,9 +194,9 @@ static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta) · 7 unmodified lines | ||
| 190 | 194 | if (rc) { |
| 191 | 195 | netdev_err(ptp->bp->dev, "ptp adjphc failed. rc = %x\n", rc); |
| 192 | 196 | } else { |
| 193 | − spin_lock_bh(&ptp->ptp_lock); | |
| 197 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 194 | 198 | bnxt_ptp_update_current_time(ptp->bp); |
| 195 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 199 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 196 | 200 | } |
| 197 | 201 | |
| 198 | 202 | return rc; |
| @@ -202,13 +206,14 @@ static int bnxt_ptp_adjtime(struct ptp_clock_info *ptp_info, s64 delta) · 3 unmodified lines | ||
| 202 | 206 | { |
| 203 | 207 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 204 | 208 | ptp_info); |
| 209 | + unsigned long flags; | |
| 205 | 210 | |
| 206 | 211 | if (BNXT_PTP_USE_RTC(ptp->bp)) |
| 207 | 212 | return bnxt_ptp_adjphc(ptp, delta); |
| 208 | 213 | |
| 209 | − spin_lock_bh(&ptp->ptp_lock); | |
| 214 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 210 | 215 | timecounter_adjtime(&ptp->tc, delta); |
| 211 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 216 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 212 | 217 | return 0; |
| 213 | 218 | } |
| 214 | 219 | |
| @@ -236,14 +241,15 @@ static int bnxt_ptp_adjfine(struct ptp_clock_info *ptp_info, long scaled_ppm) · 21 unmodified lines | ||
| 236 | 241 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 237 | 242 | ptp_info); |
| 238 | 243 | struct bnxt *bp = ptp->bp; |
| 244 | + unsigned long flags; | |
| 239 | 245 | |
| 240 | 246 | if (!BNXT_MH(bp)) |
| 241 | 247 | return bnxt_ptp_adjfine_rtc(bp, scaled_ppm); |
| 242 | 248 | |
| 243 | − spin_lock_bh(&ptp->ptp_lock); | |
| 249 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 244 | 250 | timecounter_read(&ptp->tc); |
| 245 | 251 | ptp->cc.mult = adjust_by_scaled_ppm(ptp->cmult, scaled_ppm); |
| 246 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 252 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 247 | 253 | return 0; |
| 248 | 254 | } |
| 249 | 255 | |
| @@ -251,12 +257,13 @@ void bnxt_ptp_pps_event(struct bnxt *bp, u32 data1, u32 data2) · 1 unmodified line | ||
| 251 | 257 | { |
| 252 | 258 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; |
| 253 | 259 | struct ptp_clock_event event; |
| 260 | + unsigned long flags; | |
| 254 | 261 | u64 ns, pps_ts; |
| 255 | 262 | |
| 256 | 263 | pps_ts = EVENT_PPS_TS(data2, data1); |
| 257 | − spin_lock_bh(&ptp->ptp_lock); | |
| 264 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 258 | 265 | ns = timecounter_cyc2time(&ptp->tc, pps_ts); |
| 259 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 266 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 260 | 267 | |
| 261 | 268 | switch (EVENT_DATA2_PPS_EVENT_TYPE(data2)) { |
| 262 | 269 | case ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_EVENT_TYPE_INTERNAL: |
| @@ -393,16 +400,17 @@ static int bnxt_get_target_cycles(struct bnxt_ptp_cfg *ptp, u64 target_ns, · 130 unmodified lines | ||
| 393 | 400 | { |
| 394 | 401 | u64 cycles_now; |
| 395 | 402 | u64 nsec_now, nsec_delta; |
| 403 | + unsigned long flags; | |
| 396 | 404 | int rc; |
| 397 | 405 | |
| 398 | − spin_lock_bh(&ptp->ptp_lock); | |
| 406 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 399 | 407 | rc = bnxt_refclk_read(ptp->bp, NULL, &cycles_now); |
| 400 | 408 | if (rc) { |
| 401 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 409 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 402 | 410 | return rc; |
| 403 | 411 | } |
| 404 | 412 | nsec_now = timecounter_cyc2time(&ptp->tc, cycles_now); |
| 405 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 413 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 406 | 414 | |
| 407 | 415 | nsec_delta = target_ns - nsec_now; |
| 408 | 416 | *cycles_delta = div64_u64(nsec_delta << ptp->cc.shift, ptp->cc.mult); |
| @@ -689,6 +697,7 @@ static int bnxt_stamp_tx_skb(struct bnxt *bp, int slot) · 280 unmodified lines | ||
| 689 | 697 | struct skb_shared_hwtstamps timestamp; |
| 690 | 698 | struct bnxt_ptp_tx_req *txts_req; |
| 691 | 699 | unsigned long now = jiffies; |
| 700 | + unsigned long flags; | |
| 692 | 701 | u64 ts = 0, ns = 0; |
| 693 | 702 | u32 tmo = 0; |
| 694 | 703 | int rc; |
| @@ -702,9 +711,9 @@ static int bnxt_stamp_tx_skb(struct bnxt *bp, int slot) · 7 unmodified lines | ||
| 702 | 711 | tmo, slot); |
| 703 | 712 | if (!rc) { |
| 704 | 713 | memset(×tamp, 0, sizeof(timestamp)); |
| 705 | − spin_lock_bh(&ptp->ptp_lock); | |
| 714 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 706 | 715 | ns = timecounter_cyc2time(&ptp->tc, ts); |
| 707 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 716 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 708 | 717 | timestamp.hwtstamp = ns_to_ktime(ns); |
| 709 | 718 | skb_tstamp_tx(txts_req->tx_skb, ×tamp); |
| 710 | 719 | ptp->stats.ts_pkts++; |
| @@ -730,6 +739,7 @@ static long bnxt_ptp_ts_aux_work(struct ptp_clock_info *ptp_info) · 19 unmodified lines | ||
| 730 | 739 | unsigned long now = jiffies; |
| 731 | 740 | struct bnxt *bp = ptp->bp; |
| 732 | 741 | u16 cons = ptp->txts_cons; |
| 742 | + unsigned long flags; | |
| 733 | 743 | u32 num_requests; |
| 734 | 744 | int rc = 0; |
| 735 | 745 | |
| @@ -757,9 +767,9 @@ next_slot: · 21 unmodified lines | ||
| 757 | 767 | bnxt_ptp_get_current_time(bp); |
| 758 | 768 | ptp->next_period = now + HZ; |
| 759 | 769 | if (time_after_eq(now, ptp->next_overflow_check)) { |
| 760 | − spin_lock_bh(&ptp->ptp_lock); | |
| 770 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 761 | 771 | timecounter_read(&ptp->tc); |
| 762 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 772 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 763 | 773 | ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD; |
| 764 | 774 | } |
| 765 | 775 | if (rc == -EAGAIN) |
| @@ -819,6 +829,7 @@ void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi, · 53 unmodified lines | ||
| 819 | 829 | u32 opaque = tscmp->tx_ts_cmp_opaque; |
| 820 | 830 | struct bnxt_tx_ring_info *txr; |
| 821 | 831 | struct bnxt_sw_tx_bd *tx_buf; |
| 832 | + unsigned long flags; | |
| 822 | 833 | u64 ts, ns; |
| 823 | 834 | u16 cons; |
| 824 | 835 | |
| @@ -833,9 +844,9 @@ void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi, · 8 unmodified lines | ||
| 833 | 844 | le32_to_cpu(tscmp->tx_ts_cmp_flags_type), |
| 834 | 845 | le32_to_cpu(tscmp->tx_ts_cmp_errors_v)); |
| 835 | 846 | } else { |
| 836 | − spin_lock_bh(&ptp->ptp_lock); | |
| 847 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 837 | 848 | ns = timecounter_cyc2time(&ptp->tc, ts); |
| 838 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 849 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 839 | 850 | timestamp.hwtstamp = ns_to_ktime(ns); |
| 840 | 851 | skb_tstamp_tx(tx_buf->skb, ×tamp); |
| 841 | 852 | } |
| @@ -975,6 +986,7 @@ void bnxt_ptp_rtc_timecounter_init(struct bnxt_ptp_cfg *ptp, u64 ns) · 133 unmodified lines | ||
| 975 | 986 | int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg) |
| 976 | 987 | { |
| 977 | 988 | struct timespec64 tsp; |
| 989 | + unsigned long flags; | |
| 978 | 990 | u64 ns; |
| 979 | 991 | int rc; |
| 980 | 992 | |
| @@ -993,9 +1005,9 @@ int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg) · 12 unmodified lines | ||
| 993 | 1005 | if (rc) |
| 994 | 1006 | return rc; |
| 995 | 1007 | } |
| 996 | − spin_lock_bh(&bp->ptp_cfg->ptp_lock); | |
| 1008 | + spin_lock_irqsave(&bp->ptp_cfg->ptp_lock, flags); | |
| 997 | 1009 | bnxt_ptp_rtc_timecounter_init(bp->ptp_cfg, ns); |
| 998 | − spin_unlock_bh(&bp->ptp_cfg->ptp_lock); | |
| 1010 | + spin_unlock_irqrestore(&bp->ptp_cfg->ptp_lock, flags); | |
| 999 | 1011 | |
| 1000 | 1012 | return 0; |
| 1001 | 1013 | } |
| @@ -1063,10 +1075,12 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg) · 61 unmodified lines | ||
| 1063 | 1075 | atomic64_set(&ptp->stats.ts_err, 0); |
| 1064 | 1076 | |
| 1065 | 1077 | if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { |
| 1066 | − spin_lock_bh(&ptp->ptp_lock); | |
| 1078 | + unsigned long flags; | |
| 1079 | + | |
| 1080 | + spin_lock_irqsave(&ptp->ptp_lock, flags); | |
| 1067 | 1081 | bnxt_refclk_read(bp, NULL, &ptp->current_time); |
| 1068 | 1082 | WRITE_ONCE(ptp->old_time, ptp->current_time); |
| 1069 | − spin_unlock_bh(&ptp->ptp_lock); | |
| 1083 | + spin_unlock_irqrestore(&ptp->ptp_lock, flags); | |
| 1070 | 1084 | ptp_schedule_worker(ptp->ptp_clock, 0); |
| 1071 | 1085 | } |
| 1072 | 1086 | ptp->txts_tmo = BNXT_PTP_DFLT_TX_TMO; |
| @@ -146,11 +146,13 @@ struct bnxt_ptp_cfg { · 145 unmodified lines | ||
| 146 | 146 | }; |
| 147 | 147 | |
| 148 | 148 | #if BITS_PER_LONG == 32 |
| 149 | −#define BNXT_READ_TIME64(ptp, dst, src) \ | |
| 150 | −do { \ | |
| 151 | − spin_lock_bh(&(ptp)->ptp_lock); \ | |
| 152 | − (dst) = (src); \ | |
| 153 | − spin_unlock_bh(&(ptp)->ptp_lock); \ | |
| 149 | +#define BNXT_READ_TIME64(ptp, dst, src) \ | |
| 150 | +do { \ | |
| 151 | + unsigned long flags; \ | |
| 152 | + \ | |
| 153 | + spin_lock_irqsave(&(ptp)->ptp_lock, flags); \ | |
| 154 | + (dst) = (src); \ | |
| 155 | + spin_unlock_irqrestore(&(ptp)->ptp_lock, flags); \ | |
| 154 | 156 | } while (0) |
| 155 | 157 | #else |
| 156 | 158 | #define BNXT_READ_TIME64(ptp, dst, src) \ |
| @@ -930,9 +930,6 @@ static int macb_mdiobus_register(struct macb *bp) · 929 unmodified lines | ||
| 930 | 930 | return ret; |
| 931 | 931 | } |
| 932 | 932 | |
| 933 | − if (of_phy_is_fixed_link(np)) | |
| 934 | − return mdiobus_register(bp->mii_bus); | |
| 935 | − | |
| 936 | 933 | /* Only create the PHY from the device tree if at least one PHY is |
| 937 | 934 | * described. Otherwise scan the entire MDIO bus. We do this to support |
| 938 | 935 | * old device tree that did not follow the best practices and did not |
| @@ -953,8 +950,19 @@ static int macb_mdiobus_register(struct macb *bp) · 14 unmodified lines | ||
| 953 | 950 | |
| 954 | 951 | static int macb_mii_init(struct macb *bp) |
| 955 | 952 | { |
| 953 | + struct device_node *child, *np = bp->pdev->dev.of_node; | |
| 956 | 954 | int err = -ENXIO; |
| 957 | 955 | |
| 956 | + /* With fixed-link, we don't need to register the MDIO bus, | |
| 957 | + * except if we have a child named "mdio" in the device tree. | |
| 958 | + * In that case, some devices may be attached to the MACB's MDIO bus. | |
| 959 | + */ | |
| 960 | + child = of_get_child_by_name(np, "mdio"); | |
| 961 | + if (child) | |
| 962 | + of_node_put(child); | |
| 963 | + else if (of_phy_is_fixed_link(np)) | |
| 964 | + return macb_mii_probe(bp->dev); | |
| 965 | + | |
| 958 | 966 | /* Enable management port */ |
| 959 | 967 | macb_writel(bp, NCR, MACB_BIT(MPE)); |
| 960 | 968 | |
| @@ -1381,10 +1381,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) · 1380 unmodified lines | ||
| 1381 | 1381 | be_get_wrb_params_from_skb(adapter, skb, &wrb_params); |
| 1382 | 1382 | |
| 1383 | 1383 | wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); |
| 1384 | − if (unlikely(!wrb_cnt)) { | |
| 1385 | − dev_kfree_skb_any(skb); | |
| 1386 | − goto drop; | |
| 1387 | − } | |
| 1384 | + if (unlikely(!wrb_cnt)) | |
| 1385 | + goto drop_skb; | |
| 1388 | 1386 | |
| 1389 | 1387 | /* if os2bmc is enabled and if the pkt is destined to bmc, |
| 1390 | 1388 | * enqueue the pkt a 2nd time with mgmt bit set. |
| @@ -1393,7 +1391,7 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) · 2 unmodified lines | ||
| 1393 | 1391 | BE_WRB_F_SET(wrb_params.features, OS2BMC, 1); |
| 1394 | 1392 | wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); |
| 1395 | 1393 | if (unlikely(!wrb_cnt)) |
| 1396 | − goto drop; | |
| 1394 | + goto drop_skb; | |
| 1397 | 1395 | else |
| 1398 | 1396 | skb_get(skb); |
| 1399 | 1397 | } |
| @@ -1407,6 +1405,8 @@ static netdev_tx_t be_xmit(struct sk_buff *skb, struct net_device *netdev) · 7 unmodified lines | ||
| 1407 | 1405 | be_xmit_flush(adapter, txo); |
| 1408 | 1406 | |
| 1409 | 1407 | return NETDEV_TX_OK; |
| 1408 | +drop_skb: | |
| 1409 | + dev_kfree_skb_any(skb); | |
| 1410 | 1410 | drop: |
| 1411 | 1411 | tx_stats(txo)->tx_drv_drops++; |
| 1412 | 1412 | /* Flush the already enqueued tx requests */ |
| @@ -1906,7 +1906,12 @@ static int ftgmac100_probe(struct platform_device *pdev) · 1905 unmodified lines | ||
| 1906 | 1906 | goto err_phy_connect; |
| 1907 | 1907 | } |
| 1908 | 1908 | |
| 1909 | − phydev = fixed_phy_register(PHY_POLL, &ncsi_phy_status, NULL); | |
| 1909 | + phydev = fixed_phy_register(PHY_POLL, &ncsi_phy_status, np); | |
| 1910 | + if (IS_ERR(phydev)) { | |
| 1911 | + dev_err(&pdev->dev, "failed to register fixed PHY device\n"); | |
| 1912 | + err = PTR_ERR(phydev); | |
| 1913 | + goto err_phy_connect; | |
| 1914 | + } | |
| 1910 | 1915 | err = phy_connect_direct(netdev, phydev, ftgmac100_adjust_link, |
| 1911 | 1916 | PHY_INTERFACE_MODE_MII); |
| 1912 | 1917 | if (err) { |
| @@ -902,6 +902,7 @@ static bool enetc_clean_tx_ring(struct enetc_bdr *tx_ring, int napi_budget) · 901 unmodified lines | ||
| 902 | 902 | |
| 903 | 903 | if (unlikely(tx_frm_cnt && netif_carrier_ok(ndev) && |
| 904 | 904 | __netif_subqueue_stopped(ndev, tx_ring->index) && |
| 905 | + !test_bit(ENETC_TX_DOWN, &priv->flags) && | |
| 905 | 906 | (enetc_bd_unused(tx_ring) >= ENETC_TXBDS_MAX_NEEDED))) { |
| 906 | 907 | netif_wake_subqueue(ndev, tx_ring->index); |
| 907 | 908 | } |
| @@ -1377,6 +1378,9 @@ int enetc_xdp_xmit(struct net_device *ndev, int num_frames, · 469 unmodified lines | ||
| 1377 | 1378 | int xdp_tx_bd_cnt, i, k; |
| 1378 | 1379 | int xdp_tx_frm_cnt = 0; |
| 1379 | 1380 | |
| 1381 | + if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags))) | |
| 1382 | + return -ENETDOWN; | |
| 1383 | + | |
| 1380 | 1384 | enetc_lock_mdio(); |
| 1381 | 1385 | |
| 1382 | 1386 | tx_ring = priv->xdp_tx_ring[smp_processor_id()]; |
| @@ -1521,7 +1525,6 @@ static void enetc_xdp_drop(struct enetc_bdr *rx_ring, int rx_ring_first, · 138 unmodified lines | ||
| 1521 | 1525 | &rx_ring->rx_swbd[rx_ring_first]); |
| 1522 | 1526 | enetc_bdr_idx_inc(rx_ring, &rx_ring_first); |
| 1523 | 1527 | } |
| 1524 | − rx_ring->stats.xdp_drops++; | |
| 1525 | 1528 | } |
| 1526 | 1529 | |
| 1527 | 1530 | static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, |
| @@ -1586,6 +1589,7 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, · 58 unmodified lines | ||
| 1586 | 1589 | fallthrough; |
| 1587 | 1590 | case XDP_DROP: |
| 1588 | 1591 | enetc_xdp_drop(rx_ring, orig_i, i); |
| 1592 | + rx_ring->stats.xdp_drops++; | |
| 1589 | 1593 | break; |
| 1590 | 1594 | case XDP_PASS: |
| 1591 | 1595 | rxbd = orig_rxbd; |
| @@ -1602,6 +1606,12 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, · 10 unmodified lines | ||
| 1602 | 1606 | break; |
| 1603 | 1607 | case XDP_TX: |
| 1604 | 1608 | tx_ring = priv->xdp_tx_ring[rx_ring->index]; |
| 1609 | + if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags))) { | |
| 1610 | + enetc_xdp_drop(rx_ring, orig_i, i); | |
| 1611 | + tx_ring->stats.xdp_tx_drops++; | |
| 1612 | + break; | |
| 1613 | + } | |
| 1614 | + | |
| 1605 | 1615 | xdp_tx_bd_cnt = enetc_rx_swbd_to_xdp_tx_swbd(xdp_tx_arr, |
| 1606 | 1616 | rx_ring, |
| 1607 | 1617 | orig_i, i); |
| @@ -2223,18 +2233,24 @@ static void enetc_enable_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) · 615 unmodified lines | ||
| 2223 | 2233 | enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr); |
| 2224 | 2234 | } |
| 2225 | 2235 | |
| 2226 | −static void enetc_enable_bdrs(struct enetc_ndev_priv *priv) | |
| 2236 | +static void enetc_enable_rx_bdrs(struct enetc_ndev_priv *priv) | |
| 2227 | 2237 | { |
| 2228 | 2238 | struct enetc_hw *hw = &priv->si->hw; |
| 2229 | 2239 | int i; |
| 2230 | 2240 | |
| 2231 | − for (i = 0; i < priv->num_tx_rings; i++) | |
| 2232 | − enetc_enable_txbdr(hw, priv->tx_ring[i]); | |
| 2233 | − | |
| 2234 | 2241 | for (i = 0; i < priv->num_rx_rings; i++) |
| 2235 | 2242 | enetc_enable_rxbdr(hw, priv->rx_ring[i]); |
| 2236 | 2243 | } |
| 2237 | 2244 | |
| 2245 | +static void enetc_enable_tx_bdrs(struct enetc_ndev_priv *priv) | |
| 2246 | +{ | |
| 2247 | + struct enetc_hw *hw = &priv->si->hw; | |
| 2248 | + int i; | |
| 2249 | + | |
| 2250 | + for (i = 0; i < priv->num_tx_rings; i++) | |
| 2251 | + enetc_enable_txbdr(hw, priv->tx_ring[i]); | |
| 2252 | +} | |
| 2253 | + | |
| 2238 | 2254 | static void enetc_disable_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) |
| 2239 | 2255 | { |
| 2240 | 2256 | int idx = rx_ring->index; |
| @@ -2251,18 +2267,24 @@ static void enetc_disable_txbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) · 10 unmodified lines | ||
| 2251 | 2267 | enetc_txbdr_wr(hw, idx, ENETC_TBMR, 0); |
| 2252 | 2268 | } |
| 2253 | 2269 | |
| 2254 | −static void enetc_disable_bdrs(struct enetc_ndev_priv *priv) | |
| 2270 | +static void enetc_disable_rx_bdrs(struct enetc_ndev_priv *priv) | |
| 2255 | 2271 | { |
| 2256 | 2272 | struct enetc_hw *hw = &priv->si->hw; |
| 2257 | 2273 | int i; |
| 2258 | 2274 | |
| 2259 | − for (i = 0; i < priv->num_tx_rings; i++) | |
| 2260 | − enetc_disable_txbdr(hw, priv->tx_ring[i]); | |
| 2261 | − | |
| 2262 | 2275 | for (i = 0; i < priv->num_rx_rings; i++) |
| 2263 | 2276 | enetc_disable_rxbdr(hw, priv->rx_ring[i]); |
| 2264 | 2277 | } |
| 2265 | 2278 | |
| 2279 | +static void enetc_disable_tx_bdrs(struct enetc_ndev_priv *priv) | |
| 2280 | +{ | |
| 2281 | + struct enetc_hw *hw = &priv->si->hw; | |
| 2282 | + int i; | |
| 2283 | + | |
| 2284 | + for (i = 0; i < priv->num_tx_rings; i++) | |
| 2285 | + enetc_disable_txbdr(hw, priv->tx_ring[i]); | |
| 2286 | +} | |
| 2287 | + | |
| 2266 | 2288 | static void enetc_wait_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring) |
| 2267 | 2289 | { |
| 2268 | 2290 | int delay = 8, timeout = 100; |
| @@ -2460,9 +2482,13 @@ void enetc_start(struct net_device *ndev) · 191 unmodified lines | ||
| 2460 | 2482 | enable_irq(irq); |
| 2461 | 2483 | } |
| 2462 | 2484 | |
| 2463 | − enetc_enable_bdrs(priv); | |
| 2485 | + enetc_enable_tx_bdrs(priv); | |
| 2486 | + | |
| 2487 | + enetc_enable_rx_bdrs(priv); | |
| 2464 | 2488 | |
| 2465 | 2489 | netif_tx_start_all_queues(ndev); |
| 2490 | + | |
| 2491 | + clear_bit(ENETC_TX_DOWN, &priv->flags); | |
| 2466 | 2492 | } |
| 2467 | 2493 | EXPORT_SYMBOL_GPL(enetc_start); |
| 2468 | 2494 | |
| @@ -2520,9 +2546,15 @@ void enetc_stop(struct net_device *ndev) · 51 unmodified lines | ||
| 2520 | 2546 | struct enetc_ndev_priv *priv = netdev_priv(ndev); |
| 2521 | 2547 | int i; |
| 2522 | 2548 | |
| 2549 | + set_bit(ENETC_TX_DOWN, &priv->flags); | |
| 2550 | + | |
| 2523 | 2551 | netif_tx_stop_all_queues(ndev); |
| 2524 | 2552 | |
| 2525 | − enetc_disable_bdrs(priv); | |
| 2553 | + enetc_disable_rx_bdrs(priv); | |
| 2554 | + | |
| 2555 | + enetc_wait_bdrs(priv); | |
| 2556 | + | |
| 2557 | + enetc_disable_tx_bdrs(priv); | |
| 2526 | 2558 | |
| 2527 | 2559 | for (i = 0; i < priv->bdr_int_num; i++) { |
| 2528 | 2560 | int irq = pci_irq_vector(priv->si->pdev, |
| @@ -2533,8 +2565,6 @@ void enetc_stop(struct net_device *ndev) · 4 unmodified lines | ||
| 2533 | 2565 | napi_disable(&priv->int_vector[i]->napi); |
| 2534 | 2566 | } |
| 2535 | 2567 | |
| 2536 | − enetc_wait_bdrs(priv); | |
| 2537 | − | |
| 2538 | 2568 | enetc_clear_interrupts(priv); |
| 2539 | 2569 | } |
| 2540 | 2570 | EXPORT_SYMBOL_GPL(enetc_stop); |
| @@ -325,6 +325,7 @@ enum enetc_active_offloads { · 324 unmodified lines | ||
| 325 | 325 | |
| 326 | 326 | enum enetc_flags_bit { |
| 327 | 327 | ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS = 0, |
| 328 | + ENETC_TX_DOWN, | |
| 328 | 329 | }; |
| 329 | 330 | |
| 330 | 331 | /* interrupt coalescing modes */ |
| @@ -1077,7 +1077,8 @@ fec_restart(struct net_device *ndev) · 1076 unmodified lines | ||
| 1077 | 1077 | u32 rcntl = OPT_FRAME_SIZE | 0x04; |
| 1078 | 1078 | u32 ecntl = FEC_ECR_ETHEREN; |
| 1079 | 1079 | |
| 1080 | − fec_ptp_save_state(fep); | |
| 1080 | + if (fep->bufdesc_ex) | |
| 1081 | + fec_ptp_save_state(fep); | |
| 1081 | 1082 | |
| 1082 | 1083 | /* Whack a reset. We should wait for this. |
| 1083 | 1084 | * For i.MX6SX SOC, enet use AXI bus, we use disable MAC |
| @@ -1340,7 +1341,8 @@ fec_stop(struct net_device *ndev) · 256 unmodified lines | ||
| 1340 | 1341 | netdev_err(ndev, "Graceful transmit stop did not complete!\n"); |
| 1341 | 1342 | } |
| 1342 | 1343 | |
| 1343 | − fec_ptp_save_state(fep); | |
| 1344 | + if (fep->bufdesc_ex) | |
| 1345 | + fec_ptp_save_state(fep); | |
| 1344 | 1346 | |
| 1345 | 1347 | /* Whack a reset. We should wait for this. |
| 1346 | 1348 | * For i.MX6SX SOC, enet use AXI bus, we use disable MAC |
| @@ -197,55 +197,67 @@ static int mac_probe(struct platform_device *_of_dev) · 196 unmodified lines | ||
| 197 | 197 | err = -EINVAL; |
| 198 | 198 | goto _return_of_node_put; |
| 199 | 199 | } |
| 200 | + mac_dev->fman_dev = &of_dev->dev; | |
| 200 | 201 | |
| 201 | 202 | /* Get the FMan cell-index */ |
| 202 | 203 | err = of_property_read_u32(dev_node, "cell-index", &val); |
| 203 | 204 | if (err) { |
| 204 | 205 | dev_err(dev, "failed to read cell-index for %pOF\n", dev_node); |
| 205 | 206 | err = -EINVAL; |
| 206 | − goto _return_of_node_put; | |
| 207 | + goto _return_dev_put; | |
| 207 | 208 | } |
| 208 | 209 | /* cell-index 0 => FMan id 1 */ |
| 209 | 210 | fman_id = (u8)(val + 1); |
| 210 | 211 | |
| 211 | − priv->fman = fman_bind(&of_dev->dev); | |
| 212 | + priv->fman = fman_bind(mac_dev->fman_dev); | |
| 212 | 213 | if (!priv->fman) { |
| 213 | 214 | dev_err(dev, "fman_bind(%pOF) failed\n", dev_node); |
| 214 | 215 | err = -ENODEV; |
| 215 | − goto _return_of_node_put; | |
| 216 | + goto _return_dev_put; | |
| 216 | 217 | } |
| 217 | 218 | |
| 219 | + /* Two references have been taken in of_find_device_by_node() | |
| 220 | + * and fman_bind(). Release one of them here. The second one | |
| 221 | + * will be released in mac_remove(). | |
| 222 | + */ | |
| 223 | + put_device(mac_dev->fman_dev); | |
| 218 | 224 | of_node_put(dev_node); |
| 225 | + dev_node = NULL; | |
| 219 | 226 | |
| 220 | 227 | /* Get the address of the memory mapped registers */ |
| 221 | 228 | mac_dev->res = platform_get_mem_or_io(_of_dev, 0); |
| 222 | 229 | if (!mac_dev->res) { |
| 223 | 230 | dev_err(dev, "could not get registers\n"); |
| 224 | − return -EINVAL; | |
| 231 | + err = -EINVAL; | |
| 232 | + goto _return_dev_put; | |
| 225 | 233 | } |
| 226 | 234 | |
| 227 | 235 | err = devm_request_resource(dev, fman_get_mem_region(priv->fman), |
| 228 | 236 | mac_dev->res); |
| 229 | 237 | if (err) { |
| 230 | 238 | dev_err_probe(dev, err, "could not request resource\n"); |
| 231 | − return err; | |
| 239 | + goto _return_dev_put; | |
| 232 | 240 | } |
| 233 | 241 | |
| 234 | 242 | mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start, |
| 235 | 243 | resource_size(mac_dev->res)); |
| 236 | 244 | if (!mac_dev->vaddr) { |
| 237 | 245 | dev_err(dev, "devm_ioremap() failed\n"); |
| 238 | − return -EIO; | |
| 246 | + err = -EIO; | |
| 247 | + goto _return_dev_put; | |
| 239 | 248 | } |
| 240 | 249 | |
| 241 | − if (!of_device_is_available(mac_node)) | |
| 242 | − return -ENODEV; | |
| 250 | + if (!of_device_is_available(mac_node)) { | |
| 251 | + err = -ENODEV; | |
| 252 | + goto _return_dev_put; | |
| 253 | + } | |
| 243 | 254 | |
| 244 | 255 | /* Get the cell-index */ |
| 245 | 256 | err = of_property_read_u32(mac_node, "cell-index", &val); |
| 246 | 257 | if (err) { |
| 247 | 258 | dev_err(dev, "failed to read cell-index for %pOF\n", mac_node); |
| 248 | − return -EINVAL; | |
| 259 | + err = -EINVAL; | |
| 260 | + goto _return_dev_put; | |
| 249 | 261 | } |
| 250 | 262 | priv->cell_index = (u8)val; |
| 251 | 263 | |
| @@ -259,22 +271,26 @@ static int mac_probe(struct platform_device *_of_dev) · 7 unmodified lines | ||
| 259 | 271 | if (unlikely(nph < 0)) { |
| 260 | 272 | dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n", |
| 261 | 273 | mac_node); |
| 262 | − return nph; | |
| 274 | + err = nph; | |
| 275 | + goto _return_dev_put; | |
| 263 | 276 | } |
| 264 | 277 | |
| 265 | 278 | if (nph != ARRAY_SIZE(mac_dev->port)) { |
| 266 | 279 | dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n", |
| 267 | 280 | mac_node); |
| 268 | − return -EINVAL; | |
| 281 | + err = -EINVAL; | |
| 282 | + goto _return_dev_put; | |
| 269 | 283 | } |
| 270 | 284 | |
| 271 | − for (i = 0; i < ARRAY_SIZE(mac_dev->port); i++) { | |
| 285 | + /* PORT_NUM determines the size of the port array */ | |
| 286 | + for (i = 0; i < PORT_NUM; i++) { | |
| 272 | 287 | /* Find the port node */ |
| 273 | 288 | dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i); |
| 274 | 289 | if (!dev_node) { |
| 275 | 290 | dev_err(dev, "of_parse_phandle(%pOF, fsl,fman-ports) failed\n", |
| 276 | 291 | mac_node); |
| 277 | − return -EINVAL; | |
| 292 | + err = -EINVAL; | |
| 293 | + goto _return_dev_arr_put; | |
| 278 | 294 | } |
| 279 | 295 | |
| 280 | 296 | of_dev = of_find_device_by_node(dev_node); |
| @@ -282,17 +298,24 @@ static int mac_probe(struct platform_device *_of_dev) · 1 unmodified line | ||
| 282 | 298 | dev_err(dev, "of_find_device_by_node(%pOF) failed\n", |
| 283 | 299 | dev_node); |
| 284 | 300 | err = -EINVAL; |
| 285 | − goto _return_of_node_put; | |
| 301 | + goto _return_dev_arr_put; | |
| 286 | 302 | } |
| 303 | + mac_dev->fman_port_devs[i] = &of_dev->dev; | |
| 287 | 304 | |
| 288 | − mac_dev->port[i] = fman_port_bind(&of_dev->dev); | |
| 305 | + mac_dev->port[i] = fman_port_bind(mac_dev->fman_port_devs[i]); | |
| 289 | 306 | if (!mac_dev->port[i]) { |
| 290 | 307 | dev_err(dev, "dev_get_drvdata(%pOF) failed\n", |
| 291 | 308 | dev_node); |
| 292 | 309 | err = -EINVAL; |
| 293 | − goto _return_of_node_put; | |
| 310 | + goto _return_dev_arr_put; | |
| 294 | 311 | } |
| 312 | + /* Two references have been taken in of_find_device_by_node() | |
| 313 | + * and fman_port_bind(). Release one of them here. The second | |
| 314 | + * one will be released in mac_remove(). | |
| 315 | + */ | |
| 316 | + put_device(mac_dev->fman_port_devs[i]); | |
| 295 | 317 | of_node_put(dev_node); |
| 318 | + dev_node = NULL; | |
| 296 | 319 | } |
| 297 | 320 | |
| 298 | 321 | /* Get the PHY connection type */ |
| @@ -312,7 +335,7 @@ static int mac_probe(struct platform_device *_of_dev) · 13 unmodified lines | ||
| 312 | 335 | |
| 313 | 336 | err = init(mac_dev, mac_node, ¶ms); |
| 314 | 337 | if (err < 0) |
| 315 | − return err; | |
| 338 | + goto _return_dev_arr_put; | |
| 316 | 339 | |
| 317 | 340 | if (!is_zero_ether_addr(mac_dev->addr)) |
| 318 | 341 | dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr); |
| @@ -327,6 +350,12 @@ static int mac_probe(struct platform_device *_of_dev) · 8 unmodified lines | ||
| 327 | 350 | |
| 328 | 351 | return err; |
| 329 | 352 | |
| 353 | +_return_dev_arr_put: | |
| 354 | + /* mac_dev is kzalloc'ed */ | |
| 355 | + for (i = 0; i < PORT_NUM; i++) | |
| 356 | + put_device(mac_dev->fman_port_devs[i]); | |
| 357 | +_return_dev_put: | |
| 358 | + put_device(mac_dev->fman_dev); | |
| 330 | 359 | _return_of_node_put: |
| 331 | 360 | of_node_put(dev_node); |
| 332 | 361 | return err; |
| @@ -335,6 +364,11 @@ _return_of_node_put: · 2 unmodified lines | ||
| 335 | 364 | static void mac_remove(struct platform_device *pdev) |
| 336 | 365 | { |
| 337 | 366 | struct mac_device *mac_dev = platform_get_drvdata(pdev); |
| 367 | + int i; | |
| 368 | + | |
| 369 | + for (i = 0; i < PORT_NUM; i++) | |
| 370 | + put_device(mac_dev->fman_port_devs[i]); | |
| 371 | + put_device(mac_dev->fman_dev); | |
| 338 | 372 | |
| 339 | 373 | platform_device_unregister(mac_dev->priv->eth_dev); |
| 340 | 374 | } |
| @@ -19,12 +19,13 @@ · 18 unmodified lines | ||
| 19 | 19 | struct fman_mac; |
| 20 | 20 | struct mac_priv_s; |
| 21 | 21 | |
| 22 | +#define PORT_NUM 2 | |
| 22 | 23 | struct mac_device { |
| 23 | 24 | void __iomem *vaddr; |
| 24 | 25 | struct device *dev; |
| 25 | 26 | struct resource *res; |
| 26 | 27 | u8 addr[ETH_ALEN]; |
| 27 | − struct fman_port *port[2]; | |
| 28 | + struct fman_port *port[PORT_NUM]; | |
| 28 | 29 | struct phylink *phylink; |
| 29 | 30 | struct phylink_config phylink_config; |
| 30 | 31 | phy_interface_t phy_if; |
| @@ -52,6 +53,9 @@ struct mac_device { · 21 unmodified lines | ||
| 52 | 53 | |
| 53 | 54 | struct fman_mac *fman_mac; |
| 54 | 55 | struct mac_priv_s *priv; |
| 56 | + | |
| 57 | + struct device *fman_dev; | |
| 58 | + struct device *fman_port_devs[PORT_NUM]; | |
| 55 | 59 | }; |
| 56 | 60 | |
| 57 | 61 | static inline struct mac_device |
| @@ -1293,8 +1293,10 @@ static ssize_t hns3_dbg_read(struct file *filp, char __user *buffer, · 1292 unmodified lines | ||
| 1293 | 1293 | |
| 1294 | 1294 | /* save the buffer addr until the last read operation */ |
| 1295 | 1295 | *save_buf = read_buf; |
| 1296 | + } | |
| 1296 | 1297 | |
| 1297 | − /* get data ready for the first time to read */ | |
| 1298 | + /* get data ready for the first time to read */ | |
| 1299 | + if (!*ppos) { | |
| 1298 | 1300 | ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd, |
| 1299 | 1301 | read_buf, hns3_dbg_cmd[index].buf_len); |
| 1300 | 1302 | if (ret) |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <linux/irq.h> |
| 12 | 12 | #include <linux/ip.h> |
| 13 | 13 | #include <linux/ipv6.h> |
| 14 | +#include <linux/iommu.h> | |
| 14 | 15 | #include <linux/module.h> |
| 15 | 16 | #include <linux/pci.h> |
| 16 | 17 | #include <linux/skbuff.h> |
| @@ -380,6 +381,24 @@ static const struct hns3_rx_ptype hns3_rx_ptype_tbl[] = { · 363 unmodified lines | ||
| 380 | 381 | #define HNS3_INVALID_PTYPE \ |
| 381 | 382 | ARRAY_SIZE(hns3_rx_ptype_tbl) |
| 382 | 383 | |
| 384 | +static void hns3_dma_map_sync(struct device *dev, unsigned long iova) | |
| 385 | +{ | |
| 386 | + struct iommu_domain *domain = iommu_get_domain_for_dev(dev); | |
| 387 | + struct iommu_iotlb_gather iotlb_gather; | |
| 388 | + size_t granule; | |
| 389 | + | |
| 390 | + if (!domain || !iommu_is_dma_domain(domain)) | |
| 391 | + return; | |
| 392 | + | |
| 393 | + granule = 1 << __ffs(domain->pgsize_bitmap); | |
| 394 | + iova = ALIGN_DOWN(iova, granule); | |
| 395 | + iotlb_gather.start = iova; | |
| 396 | + iotlb_gather.end = iova + granule - 1; | |
| 397 | + iotlb_gather.pgsize = granule; | |
| 398 | + | |
| 399 | + iommu_iotlb_sync(domain, &iotlb_gather); | |
| 400 | +} | |
| 401 | + | |
| 383 | 402 | static irqreturn_t hns3_irq_handle(int irq, void *vector) |
| 384 | 403 | { |
| 385 | 404 | struct hns3_enet_tqp_vector *tqp_vector = vector; |
| @@ -1032,6 +1051,8 @@ static bool hns3_can_use_tx_sgl(struct hns3_enet_ring *ring, · 646 unmodified lines | ||
| 1032 | 1051 | static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring) |
| 1033 | 1052 | { |
| 1034 | 1053 | u32 alloc_size = ring->tqp->handle->kinfo.tx_spare_buf_size; |
| 1054 | + struct net_device *netdev = ring_to_netdev(ring); | |
| 1055 | + struct hns3_nic_priv *priv = netdev_priv(netdev); | |
| 1035 | 1056 | struct hns3_tx_spare *tx_spare; |
| 1036 | 1057 | struct page *page; |
| 1037 | 1058 | dma_addr_t dma; |
| @@ -1073,6 +1094,7 @@ static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring) · 35 unmodified lines | ||
| 1073 | 1094 | tx_spare->buf = page_address(page); |
| 1074 | 1095 | tx_spare->len = PAGE_SIZE << order; |
| 1075 | 1096 | ring->tx_spare = tx_spare; |
| 1097 | + ring->tx_copybreak = priv->tx_copybreak; | |
| 1076 | 1098 | return; |
| 1077 | 1099 | |
| 1078 | 1100 | dma_mapping_error: |
| @@ -1724,7 +1746,9 @@ static int hns3_map_and_fill_desc(struct hns3_enet_ring *ring, void *priv, · 645 unmodified lines | ||
| 1724 | 1746 | unsigned int type) |
| 1725 | 1747 | { |
| 1726 | 1748 | struct hns3_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use]; |
| 1749 | + struct hnae3_handle *handle = ring->tqp->handle; | |
| 1727 | 1750 | struct device *dev = ring_to_dev(ring); |
| 1751 | + struct hnae3_ae_dev *ae_dev; | |
| 1728 | 1752 | unsigned int size; |
| 1729 | 1753 | dma_addr_t dma; |
| 1730 | 1754 | |
| @@ -1756,6 +1780,13 @@ static int hns3_map_and_fill_desc(struct hns3_enet_ring *ring, void *priv, · 25 unmodified lines | ||
| 1756 | 1780 | return -ENOMEM; |
| 1757 | 1781 | } |
| 1758 | 1782 | |
| 1783 | + /* Add a SYNC command to sync io-pgtale to avoid errors in pgtable | |
| 1784 | + * prefetch | |
| 1785 | + */ | |
| 1786 | + ae_dev = hns3_get_ae_dev(handle); | |
| 1787 | + if (ae_dev->dev_version >= HNAE3_DEVICE_VERSION_V3) | |
| 1788 | + hns3_dma_map_sync(dev, dma); | |
| 1789 | + | |
| 1759 | 1790 | desc_cb->priv = priv; |
| 1760 | 1791 | desc_cb->length = size; |
| 1761 | 1792 | desc_cb->dma = dma; |
| @@ -2452,7 +2483,6 @@ static int hns3_nic_set_features(struct net_device *netdev, · 690 unmodified lines | ||
| 2452 | 2483 | return ret; |
| 2453 | 2484 | } |
| 2454 | 2485 | |
| 2455 | − netdev->features = features; | |
| 2456 | 2486 | return 0; |
| 2457 | 2487 | } |
| 2458 | 2488 | |
| @@ -4868,6 +4898,30 @@ static void hns3_nic_dealloc_vector_data(struct hns3_nic_priv *priv) · 2409 unmodified lines | ||
| 4868 | 4898 | devm_kfree(&pdev->dev, priv->tqp_vector); |
| 4869 | 4899 | } |
| 4870 | 4900 | |
| 4901 | +static void hns3_update_tx_spare_buf_config(struct hns3_nic_priv *priv) | |
| 4902 | +{ | |
| 4903 | +#define HNS3_MIN_SPARE_BUF_SIZE (2 * 1024 * 1024) | |
| 4904 | +#define HNS3_MAX_PACKET_SIZE (64 * 1024) | |
| 4905 | + | |
| 4906 | + struct iommu_domain *domain = iommu_get_domain_for_dev(priv->dev); | |
| 4907 | + struct hnae3_ae_dev *ae_dev = hns3_get_ae_dev(priv->ae_handle); | |
| 4908 | + struct hnae3_handle *handle = priv->ae_handle; | |
| 4909 | + | |
| 4910 | + if (ae_dev->dev_version < HNAE3_DEVICE_VERSION_V3) | |
| 4911 | + return; | |
| 4912 | + | |
| 4913 | + if (!(domain && iommu_is_dma_domain(domain))) | |
| 4914 | + return; | |
| 4915 | + | |
| 4916 | + priv->min_tx_copybreak = HNS3_MAX_PACKET_SIZE; | |
| 4917 | + priv->min_tx_spare_buf_size = HNS3_MIN_SPARE_BUF_SIZE; | |
| 4918 | + | |
| 4919 | + if (priv->tx_copybreak < priv->min_tx_copybreak) | |
| 4920 | + priv->tx_copybreak = priv->min_tx_copybreak; | |
| 4921 | + if (handle->kinfo.tx_spare_buf_size < priv->min_tx_spare_buf_size) | |
| 4922 | + handle->kinfo.tx_spare_buf_size = priv->min_tx_spare_buf_size; | |
| 4923 | +} | |
| 4924 | + | |
| 4871 | 4925 | static void hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv, |
| 4872 | 4926 | unsigned int ring_type) |
| 4873 | 4927 | { |
| @@ -5101,6 +5155,7 @@ int hns3_init_all_ring(struct hns3_nic_priv *priv) · 227 unmodified lines | ||
| 5101 | 5155 | int i, j; |
| 5102 | 5156 | int ret; |
| 5103 | 5157 | |
| 5158 | + hns3_update_tx_spare_buf_config(priv); | |
| 5104 | 5159 | for (i = 0; i < ring_num; i++) { |
| 5105 | 5160 | ret = hns3_alloc_ring_memory(&priv->ring[i]); |
| 5106 | 5161 | if (ret) { |
| @@ -5305,6 +5360,8 @@ static int hns3_client_init(struct hnae3_handle *handle) · 198 unmodified lines | ||
| 5305 | 5360 | priv->ae_handle = handle; |
| 5306 | 5361 | priv->tx_timeout_count = 0; |
| 5307 | 5362 | priv->max_non_tso_bd_num = ae_dev->dev_specs.max_non_tso_bd_num; |
| 5363 | + priv->min_tx_copybreak = 0; | |
| 5364 | + priv->min_tx_spare_buf_size = 0; | |
| 5308 | 5365 | set_bit(HNS3_NIC_STATE_DOWN, &priv->state); |
| 5309 | 5366 | |
| 5310 | 5367 | handle->msg_enable = netif_msg_init(debug, DEFAULT_MSG_LEVEL); |
| @@ -596,6 +596,8 @@ struct hns3_nic_priv { · 595 unmodified lines | ||
| 596 | 596 | struct hns3_enet_coalesce rx_coal; |
| 597 | 597 | u32 tx_copybreak; |
| 598 | 598 | u32 rx_copybreak; |
| 599 | + u32 min_tx_copybreak; | |
| 600 | + u32 min_tx_spare_buf_size; | |
| 599 | 601 | }; |
| 600 | 602 | |
| 601 | 603 | union l3_hdr_info { |
| @@ -1933,6 +1933,31 @@ static int hns3_set_tx_spare_buf_size(struct net_device *netdev, · 1932 unmodified lines | ||
| 1933 | 1933 | return ret; |
| 1934 | 1934 | } |
| 1935 | 1935 | |
| 1936 | +static int hns3_check_tx_copybreak(struct net_device *netdev, u32 copybreak) | |
| 1937 | +{ | |
| 1938 | + struct hns3_nic_priv *priv = netdev_priv(netdev); | |
| 1939 | + | |
| 1940 | + if (copybreak < priv->min_tx_copybreak) { | |
| 1941 | + netdev_err(netdev, "tx copybreak %u should be no less than %u!\n", | |
| 1942 | + copybreak, priv->min_tx_copybreak); | |
| 1943 | + return -EINVAL; | |
| 1944 | + } | |
| 1945 | + return 0; | |
| 1946 | +} | |
| 1947 | + | |
| 1948 | +static int hns3_check_tx_spare_buf_size(struct net_device *netdev, u32 buf_size) | |
| 1949 | +{ | |
| 1950 | + struct hns3_nic_priv *priv = netdev_priv(netdev); | |
| 1951 | + | |
| 1952 | + if (buf_size < priv->min_tx_spare_buf_size) { | |
| 1953 | + netdev_err(netdev, | |
| 1954 | + "tx spare buf size %u should be no less than %u!\n", | |
| 1955 | + buf_size, priv->min_tx_spare_buf_size); | |
| 1956 | + return -EINVAL; | |
| 1957 | + } | |
| 1958 | + return 0; | |
| 1959 | +} | |
| 1960 | + | |
| 1936 | 1961 | static int hns3_set_tunable(struct net_device *netdev, |
| 1937 | 1962 | const struct ethtool_tunable *tuna, |
| 1938 | 1963 | const void *data) |
| @@ -1949,6 +1974,10 @@ static int hns3_set_tunable(struct net_device *netdev, · 10 unmodified lines | ||
| 1949 | 1974 | |
| 1950 | 1975 | switch (tuna->id) { |
| 1951 | 1976 | case ETHTOOL_TX_COPYBREAK: |
| 1977 | + ret = hns3_check_tx_copybreak(netdev, *(u32 *)data); | |
| 1978 | + if (ret) | |
| 1979 | + return ret; | |
| 1980 | + | |
| 1952 | 1981 | priv->tx_copybreak = *(u32 *)data; |
| 1953 | 1982 | |
| 1954 | 1983 | for (i = 0; i < h->kinfo.num_tqps; i++) |
| @@ -1963,6 +1992,10 @@ static int hns3_set_tunable(struct net_device *netdev, · 8 unmodified lines | ||
| 1963 | 1992 | |
| 1964 | 1993 | break; |
| 1965 | 1994 | case ETHTOOL_TX_COPYBREAK_BUF_SIZE: |
| 1995 | + ret = hns3_check_tx_spare_buf_size(netdev, *(u32 *)data); | |
| 1996 | + if (ret) | |
| 1997 | + return ret; | |
| 1998 | + | |
| 1966 | 1999 | old_tx_spare_buf_size = h->kinfo.tx_spare_buf_size; |
| 1967 | 2000 | new_tx_spare_buf_size = *(u32 *)data; |
| 1968 | 2001 | netdev_info(netdev, "request to set tx spare buf size from %u to %u\n", |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/etherdevice.h> |
| 7 | 7 | #include <linux/init.h> |
| 8 | 8 | #include <linux/interrupt.h> |
| 9 | +#include <linux/irq.h> | |
| 9 | 10 | #include <linux/kernel.h> |
| 10 | 11 | #include <linux/module.h> |
| 11 | 12 | #include <linux/netdevice.h> |
| @@ -3584,6 +3585,17 @@ static int hclge_set_vf_link_state(struct hnae3_handle *handle, int vf, · 3572 unmodified lines | ||
| 3584 | 3585 | return ret; |
| 3585 | 3586 | } |
| 3586 | 3587 | |
| 3588 | +static void hclge_set_reset_pending(struct hclge_dev *hdev, | |
| 3589 | + enum hnae3_reset_type reset_type) | |
| 3590 | +{ | |
| 3591 | + /* When an incorrect reset type is executed, the get_reset_level | |
| 3592 | + * function generates the HNAE3_NONE_RESET flag. As a result, this | |
| 3593 | + * type do not need to pending. | |
| 3594 | + */ | |
| 3595 | + if (reset_type != HNAE3_NONE_RESET) | |
| 3596 | + set_bit(reset_type, &hdev->reset_pending); | |
| 3597 | +} | |
| 3598 | + | |
| 3587 | 3599 | static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) |
| 3588 | 3600 | { |
| 3589 | 3601 | u32 cmdq_src_reg, msix_src_reg, hw_err_src_reg; |
| @@ -3604,7 +3616,7 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) · 14 unmodified lines | ||
| 3604 | 3616 | */ |
| 3605 | 3617 | if (BIT(HCLGE_VECTOR0_IMPRESET_INT_B) & msix_src_reg) { |
| 3606 | 3618 | dev_info(&hdev->pdev->dev, "IMP reset interrupt\n"); |
| 3607 | − set_bit(HNAE3_IMP_RESET, &hdev->reset_pending); | |
| 3619 | + hclge_set_reset_pending(hdev, HNAE3_IMP_RESET); | |
| 3608 | 3620 | set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state); |
| 3609 | 3621 | *clearval = BIT(HCLGE_VECTOR0_IMPRESET_INT_B); |
| 3610 | 3622 | hdev->rst_stats.imp_rst_cnt++; |
| @@ -3614,7 +3626,7 @@ static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) · 3 unmodified lines | ||
| 3614 | 3626 | if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & msix_src_reg) { |
| 3615 | 3627 | dev_info(&hdev->pdev->dev, "global reset interrupt\n"); |
| 3616 | 3628 | set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state); |
| 3617 | − set_bit(HNAE3_GLOBAL_RESET, &hdev->reset_pending); | |
| 3629 | + hclge_set_reset_pending(hdev, HNAE3_GLOBAL_RESET); | |
| 3618 | 3630 | *clearval = BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B); |
| 3619 | 3631 | hdev->rst_stats.global_rst_cnt++; |
| 3620 | 3632 | return HCLGE_VECTOR0_EVENT_RST; |
| @@ -3769,7 +3781,7 @@ static int hclge_misc_irq_init(struct hclge_dev *hdev) · 148 unmodified lines | ||
| 3769 | 3781 | snprintf(hdev->misc_vector.name, HNAE3_INT_NAME_LEN, "%s-misc-%s", |
| 3770 | 3782 | HCLGE_NAME, pci_name(hdev->pdev)); |
| 3771 | 3783 | ret = request_irq(hdev->misc_vector.vector_irq, hclge_misc_irq_handle, |
| 3772 | − 0, hdev->misc_vector.name, hdev); | |
| 3784 | + IRQ_NOAUTOEN, hdev->misc_vector.name, hdev); | |
| 3773 | 3785 | if (ret) { |
| 3774 | 3786 | hclge_free_vector(hdev, 0); |
| 3775 | 3787 | dev_err(&hdev->pdev->dev, "request misc irq(%d) fail\n", |
| @@ -4062,7 +4074,7 @@ static void hclge_do_reset(struct hclge_dev *hdev) · 286 unmodified lines | ||
| 4062 | 4074 | case HNAE3_FUNC_RESET: |
| 4063 | 4075 | dev_info(&pdev->dev, "PF reset requested\n"); |
| 4064 | 4076 | /* schedule again to check later */ |
| 4065 | − set_bit(HNAE3_FUNC_RESET, &hdev->reset_pending); | |
| 4077 | + hclge_set_reset_pending(hdev, HNAE3_FUNC_RESET); | |
| 4066 | 4078 | hclge_reset_task_schedule(hdev); |
| 4067 | 4079 | break; |
| 4068 | 4080 | default: |
| @@ -4096,6 +4108,8 @@ static enum hnae3_reset_type hclge_get_reset_level(struct hnae3_ae_dev *ae_dev, · 27 unmodified lines | ||
| 4096 | 4108 | clear_bit(HNAE3_FLR_RESET, addr); |
| 4097 | 4109 | } |
| 4098 | 4110 | |
| 4111 | + clear_bit(HNAE3_NONE_RESET, addr); | |
| 4112 | + | |
| 4099 | 4113 | if (hdev->reset_type != HNAE3_NONE_RESET && |
| 4100 | 4114 | rst_level < hdev->reset_type) |
| 4101 | 4115 | return HNAE3_NONE_RESET; |
| @@ -4237,7 +4251,7 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev) · 135 unmodified lines | ||
| 4237 | 4251 | return false; |
| 4238 | 4252 | } else if (hdev->rst_stats.reset_fail_cnt < MAX_RESET_FAIL_CNT) { |
| 4239 | 4253 | hdev->rst_stats.reset_fail_cnt++; |
| 4240 | − set_bit(hdev->reset_type, &hdev->reset_pending); | |
| 4254 | + hclge_set_reset_pending(hdev, hdev->reset_type); | |
| 4241 | 4255 | dev_info(&hdev->pdev->dev, |
| 4242 | 4256 | "re-schedule reset task(%u)\n", |
| 4243 | 4257 | hdev->rst_stats.reset_fail_cnt); |
| @@ -4480,8 +4494,20 @@ static void hclge_reset_event(struct pci_dev *pdev, struct hnae3_handle *handle) · 236 unmodified lines | ||
| 4480 | 4494 | static void hclge_set_def_reset_request(struct hnae3_ae_dev *ae_dev, |
| 4481 | 4495 | enum hnae3_reset_type rst_type) |
| 4482 | 4496 | { |
| 4497 | +#define HCLGE_SUPPORT_RESET_TYPE \ | |
| 4498 | + (BIT(HNAE3_FLR_RESET) | BIT(HNAE3_FUNC_RESET) | \ | |
| 4499 | + BIT(HNAE3_GLOBAL_RESET) | BIT(HNAE3_IMP_RESET)) | |
| 4500 | + | |
| 4483 | 4501 | struct hclge_dev *hdev = ae_dev->priv; |
| 4484 | 4502 | |
| 4503 | + if (!(BIT(rst_type) & HCLGE_SUPPORT_RESET_TYPE)) { | |
| 4504 | + /* To prevent reset triggered by hclge_reset_event */ | |
| 4505 | + set_bit(HNAE3_NONE_RESET, &hdev->default_reset_request); | |
| 4506 | + dev_warn(&hdev->pdev->dev, "unsupported reset type %d\n", | |
| 4507 | + rst_type); | |
| 4508 | + return; | |
| 4509 | + } | |
| 4510 | + | |
| 4485 | 4511 | set_bit(rst_type, &hdev->default_reset_request); |
| 4486 | 4512 | } |
| 4487 | 4513 | |
| @@ -11891,9 +11917,6 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) · 7403 unmodified lines | ||
| 11891 | 11917 | |
| 11892 | 11918 | hclge_init_rxd_adv_layout(hdev); |
| 11893 | 11919 | |
| 11894 | − /* Enable MISC vector(vector0) */ | |
| 11895 | − hclge_enable_vector(&hdev->misc_vector, true); | |
| 11896 | − | |
| 11897 | 11920 | ret = hclge_init_wol(hdev); |
| 11898 | 11921 | if (ret) |
| 11899 | 11922 | dev_warn(&pdev->dev, |
| @@ -11906,6 +11929,10 @@ static int hclge_init_ae_dev(struct hnae3_ae_dev *ae_dev) · 6 unmodified lines | ||
| 11906 | 11929 | hclge_state_init(hdev); |
| 11907 | 11930 | hdev->last_reset_time = jiffies; |
| 11908 | 11931 | |
| 11932 | + /* Enable MISC vector(vector0) */ | |
| 11933 | + enable_irq(hdev->misc_vector.vector_irq); | |
| 11934 | + hclge_enable_vector(&hdev->misc_vector, true); | |
| 11935 | + | |
| 11909 | 11936 | dev_info(&hdev->pdev->dev, "%s driver initialization finished.\n", |
| 11910 | 11937 | HCLGE_DRIVER_NAME); |
| 11911 | 11938 | |
| @@ -12311,7 +12338,7 @@ static void hclge_uninit_ae_dev(struct hnae3_ae_dev *ae_dev) · 399 unmodified lines | ||
| 12311 | 12338 | |
| 12312 | 12339 | /* Disable MISC vector(vector0) */ |
| 12313 | 12340 | hclge_enable_vector(&hdev->misc_vector, false); |
| 12314 | − synchronize_irq(hdev->misc_vector.vector_irq); | |
| 12341 | + disable_irq(hdev->misc_vector.vector_irq); | |
| 12315 | 12342 | |
| 12316 | 12343 | /* Disable all hw interrupts */ |
| 12317 | 12344 | hclge_config_mac_tnl_int(hdev, false); |
| @@ -58,6 +58,9 @@ bool hclge_ptp_set_tx_info(struct hnae3_handle *handle, struct sk_buff *skb) · 57 unmodified lines | ||
| 58 | 58 | struct hclge_dev *hdev = vport->back; |
| 59 | 59 | struct hclge_ptp *ptp = hdev->ptp; |
| 60 | 60 | |
| 61 | + if (!ptp) | |
| 62 | + return false; | |
| 63 | + | |
| 61 | 64 | if (!test_bit(HCLGE_PTP_FLAG_TX_EN, &ptp->flags) || |
| 62 | 65 | test_and_set_bit(HCLGE_STATE_PTP_TX_HANDLING, &hdev->state)) { |
| 63 | 66 | ptp->tx_skipped++; |
| @@ -510,9 +510,9 @@ out: · 509 unmodified lines | ||
| 510 | 510 | static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data, |
| 511 | 511 | struct hnae3_knic_private_info *kinfo) |
| 512 | 512 | { |
| 513 | −#define HCLGE_RING_REG_OFFSET 0x200 | |
| 514 | 513 | #define HCLGE_RING_INT_REG_OFFSET 0x4 |
| 515 | 514 | |
| 515 | + struct hnae3_queue *tqp; | |
| 516 | 516 | int i, j, reg_num; |
| 517 | 517 | int data_num_sum; |
| 518 | 518 | u32 *reg = data; |
| @@ -533,10 +533,11 @@ static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data, · 14 unmodified lines | ||
| 533 | 533 | reg_num = ARRAY_SIZE(ring_reg_addr_list); |
| 534 | 534 | for (j = 0; j < kinfo->num_tqps; j++) { |
| 535 | 535 | reg += hclge_reg_get_tlv(HCLGE_REG_TAG_RING, reg_num, reg); |
| 536 | + tqp = kinfo->tqp[j]; | |
| 536 | 537 | for (i = 0; i < reg_num; i++) |
| 537 | − *reg++ = hclge_read_dev(&hdev->hw, | |
| 538 | − ring_reg_addr_list[i] + | |
| 539 | − HCLGE_RING_REG_OFFSET * j); | |
| 538 | + *reg++ = readl_relaxed(tqp->io_base - | |
| 539 | + HCLGE_TQP_REG_OFFSET + | |
| 540 | + ring_reg_addr_list[i]); | |
| 540 | 541 | } |
| 541 | 542 | data_num_sum += (reg_num + HCLGE_REG_TLV_SPACE) * kinfo->num_tqps; |
| 542 | 543 | |
| @@ -1395,6 +1395,17 @@ static int hclgevf_notify_roce_client(struct hclgevf_dev *hdev, · 1394 unmodified lines | ||
| 1395 | 1395 | return ret; |
| 1396 | 1396 | } |
| 1397 | 1397 | |
| 1398 | +static void hclgevf_set_reset_pending(struct hclgevf_dev *hdev, | |
| 1399 | + enum hnae3_reset_type reset_type) | |
| 1400 | +{ | |
| 1401 | + /* When an incorrect reset type is executed, the get_reset_level | |
| 1402 | + * function generates the HNAE3_NONE_RESET flag. As a result, this | |
| 1403 | + * type do not need to pending. | |
| 1404 | + */ | |
| 1405 | + if (reset_type != HNAE3_NONE_RESET) | |
| 1406 | + set_bit(reset_type, &hdev->reset_pending); | |
| 1407 | +} | |
| 1408 | + | |
| 1398 | 1409 | static int hclgevf_reset_wait(struct hclgevf_dev *hdev) |
| 1399 | 1410 | { |
| 1400 | 1411 | #define HCLGEVF_RESET_WAIT_US 20000 |
| @@ -1544,7 +1555,7 @@ static void hclgevf_reset_err_handle(struct hclgevf_dev *hdev) · 143 unmodified lines | ||
| 1544 | 1555 | hdev->rst_stats.rst_fail_cnt); |
| 1545 | 1556 | |
| 1546 | 1557 | if (hdev->rst_stats.rst_fail_cnt < HCLGEVF_RESET_MAX_FAIL_CNT) |
| 1547 | − set_bit(hdev->reset_type, &hdev->reset_pending); | |
| 1558 | + hclgevf_set_reset_pending(hdev, hdev->reset_type); | |
| 1548 | 1559 | |
| 1549 | 1560 | if (hclgevf_is_reset_pending(hdev)) { |
| 1550 | 1561 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); |
| @@ -1664,6 +1675,8 @@ static enum hnae3_reset_type hclgevf_get_reset_level(unsigned long *addr) · 113 unmodified lines | ||
| 1664 | 1675 | clear_bit(HNAE3_FLR_RESET, addr); |
| 1665 | 1676 | } |
| 1666 | 1677 | |
| 1678 | + clear_bit(HNAE3_NONE_RESET, addr); | |
| 1679 | + | |
| 1667 | 1680 | return rst_level; |
| 1668 | 1681 | } |
| 1669 | 1682 | |
| @@ -1673,14 +1686,15 @@ static void hclgevf_reset_event(struct pci_dev *pdev, · 3 unmodified lines | ||
| 1673 | 1686 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev); |
| 1674 | 1687 | struct hclgevf_dev *hdev = ae_dev->priv; |
| 1675 | 1688 | |
| 1676 | − dev_info(&hdev->pdev->dev, "received reset request from VF enet\n"); | |
| 1677 | − | |
| 1678 | 1689 | if (hdev->default_reset_request) |
| 1679 | 1690 | hdev->reset_level = |
| 1680 | 1691 | hclgevf_get_reset_level(&hdev->default_reset_request); |
| 1681 | 1692 | else |
| 1682 | 1693 | hdev->reset_level = HNAE3_VF_FUNC_RESET; |
| 1683 | 1694 | |
| 1695 | + dev_info(&hdev->pdev->dev, "received reset request from VF enet, reset level is %d\n", | |
| 1696 | + hdev->reset_level); | |
| 1697 | + | |
| 1684 | 1698 | /* reset of this VF requested */ |
| 1685 | 1699 | set_bit(HCLGEVF_RESET_REQUESTED, &hdev->reset_state); |
| 1686 | 1700 | hclgevf_reset_task_schedule(hdev); |
| @@ -1691,8 +1705,20 @@ static void hclgevf_reset_event(struct pci_dev *pdev, · 4 unmodified lines | ||
| 1691 | 1705 | static void hclgevf_set_def_reset_request(struct hnae3_ae_dev *ae_dev, |
| 1692 | 1706 | enum hnae3_reset_type rst_type) |
| 1693 | 1707 | { |
| 1708 | +#define HCLGEVF_SUPPORT_RESET_TYPE \ | |
| 1709 | + (BIT(HNAE3_VF_RESET) | BIT(HNAE3_VF_FUNC_RESET) | \ | |
| 1710 | + BIT(HNAE3_VF_PF_FUNC_RESET) | BIT(HNAE3_VF_FULL_RESET) | \ | |
| 1711 | + BIT(HNAE3_FLR_RESET) | BIT(HNAE3_VF_EXP_RESET)) | |
| 1712 | + | |
| 1694 | 1713 | struct hclgevf_dev *hdev = ae_dev->priv; |
| 1695 | 1714 | |
| 1715 | + if (!(BIT(rst_type) & HCLGEVF_SUPPORT_RESET_TYPE)) { | |
| 1716 | + /* To prevent reset triggered by hclge_reset_event */ | |
| 1717 | + set_bit(HNAE3_NONE_RESET, &hdev->default_reset_request); | |
| 1718 | + dev_info(&hdev->pdev->dev, "unsupported reset type %d\n", | |
| 1719 | + rst_type); | |
| 1720 | + return; | |
| 1721 | + } | |
| 1696 | 1722 | set_bit(rst_type, &hdev->default_reset_request); |
| 1697 | 1723 | } |
| 1698 | 1724 | |
| @@ -1849,14 +1875,14 @@ static void hclgevf_reset_service_task(struct hclgevf_dev *hdev) · 150 unmodified lines | ||
| 1849 | 1875 | */ |
| 1850 | 1876 | if (hdev->reset_attempts > HCLGEVF_MAX_RESET_ATTEMPTS_CNT) { |
| 1851 | 1877 | /* prepare for full reset of stack + pcie interface */ |
| 1852 | − set_bit(HNAE3_VF_FULL_RESET, &hdev->reset_pending); | |
| 1878 | + hclgevf_set_reset_pending(hdev, HNAE3_VF_FULL_RESET); | |
| 1853 | 1879 | |
| 1854 | 1880 | /* "defer" schedule the reset task again */ |
| 1855 | 1881 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); |
| 1856 | 1882 | } else { |
| 1857 | 1883 | hdev->reset_attempts++; |
| 1858 | 1884 | |
| 1859 | − set_bit(hdev->reset_level, &hdev->reset_pending); | |
| 1885 | + hclgevf_set_reset_pending(hdev, hdev->reset_level); | |
| 1860 | 1886 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); |
| 1861 | 1887 | } |
| 1862 | 1888 | hclgevf_reset_task_schedule(hdev); |
| @@ -1979,7 +2005,7 @@ static enum hclgevf_evt_cause hclgevf_check_evt_cause(struct hclgevf_dev *hdev, · 116 unmodified lines | ||
| 1979 | 2005 | rst_ing_reg = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING); |
| 1980 | 2006 | dev_info(&hdev->pdev->dev, |
| 1981 | 2007 | "receive reset interrupt 0x%x!\n", rst_ing_reg); |
| 1982 | − set_bit(HNAE3_VF_RESET, &hdev->reset_pending); | |
| 2008 | + hclgevf_set_reset_pending(hdev, HNAE3_VF_RESET); | |
| 1983 | 2009 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); |
| 1984 | 2010 | set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state); |
| 1985 | 2011 | *clearval = ~(1U << HCLGEVF_VECTOR0_RST_INT_B); |
| @@ -2289,6 +2315,7 @@ static void hclgevf_state_init(struct hclgevf_dev *hdev) · 303 unmodified lines | ||
| 2289 | 2315 | clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state); |
| 2290 | 2316 | |
| 2291 | 2317 | INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task); |
| 2318 | + timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); | |
| 2292 | 2319 | |
| 2293 | 2320 | mutex_init(&hdev->mbx_resp.mbx_mutex); |
| 2294 | 2321 | sema_init(&hdev->reset_sem, 1); |
| @@ -2988,7 +3015,6 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) · 693 unmodified lines | ||
| 2988 | 3015 | HCLGEVF_DRIVER_NAME); |
| 2989 | 3016 | |
| 2990 | 3017 | hclgevf_task_schedule(hdev, round_jiffies_relative(HZ)); |
| 2991 | − timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); | |
| 2992 | 3018 | |
| 2993 | 3019 | return 0; |
| 2994 | 3020 | |
| @@ -123,10 +123,10 @@ int hclgevf_get_regs_len(struct hnae3_handle *handle) · 122 unmodified lines | ||
| 123 | 123 | void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, |
| 124 | 124 | void *data) |
| 125 | 125 | { |
| 126 | −#define HCLGEVF_RING_REG_OFFSET 0x200 | |
| 127 | 126 | #define HCLGEVF_RING_INT_REG_OFFSET 0x4 |
| 128 | 127 | |
| 129 | 128 | struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); |
| 129 | + struct hnae3_queue *tqp; | |
| 130 | 130 | int i, j, reg_um; |
| 131 | 131 | u32 *reg = data; |
| 132 | 132 | |
| @@ -147,10 +147,11 @@ void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, · 14 unmodified lines | ||
| 147 | 147 | reg_um = ARRAY_SIZE(ring_reg_addr_list); |
| 148 | 148 | for (j = 0; j < hdev->num_tqps; j++) { |
| 149 | 149 | reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_um, reg); |
| 150 | + tqp = &hdev->htqp[j].q; | |
| 150 | 151 | for (i = 0; i < reg_um; i++) |
| 151 | − *reg++ = hclgevf_read_dev(&hdev->hw, | |
| 152 | − ring_reg_addr_list[i] + | |
| 153 | − HCLGEVF_RING_REG_OFFSET * j); | |
| 152 | + *reg++ = readl_relaxed(tqp->io_base - | |
| 153 | + HCLGEVF_TQP_REG_OFFSET + | |
| 154 | + ring_reg_addr_list[i]); | |
| 154 | 155 | } |
| 155 | 156 | |
| 156 | 157 | reg_um = ARRAY_SIZE(tqp_intr_reg_addr_list); |
| @@ -1012,6 +1012,7 @@ sun3_82586_send_packet(struct sk_buff *skb, struct net_device *dev) · 1011 unmodified lines | ||
| 1012 | 1012 | if(skb->len > XMIT_BUFF_SIZE) |
| 1013 | 1013 | { |
| 1014 | 1014 | printk("%s: Sorry, max. framelength is %d bytes. The length of your frame is %d bytes.\n",dev->name,XMIT_BUFF_SIZE,skb->len); |
| 1015 | + dev_kfree_skb(skb); | |
| 1015 | 1016 | return NETDEV_TX_OK; |
| 1016 | 1017 | } |
| 1017 | 1018 | |
| @@ -578,7 +578,7 @@ static int mal_probe(struct platform_device *ofdev) · 577 unmodified lines | ||
| 578 | 578 | printk(KERN_ERR "%pOF: Support for 405EZ not enabled!\n", |
| 579 | 579 | ofdev->dev.of_node); |
| 580 | 580 | err = -ENODEV; |
| 581 | − goto fail; | |
| 581 | + goto fail_unmap; | |
| 582 | 582 | #endif |
| 583 | 583 | } |
| 584 | 584 | |
| @@ -742,6 +742,8 @@ static void mal_remove(struct platform_device *ofdev) · 157 unmodified lines | ||
| 742 | 742 | |
| 743 | 743 | free_netdev(mal->dummy_dev); |
| 744 | 744 | |
| 745 | + dcr_unmap(mal->dcr_host, 0x100); | |
| 746 | + | |
| 745 | 747 | dma_free_coherent(&ofdev->dev, |
| 746 | 748 | sizeof(struct mal_descriptor) * |
| 747 | 749 | (NUM_TX_BUFF * mal->num_tx_chans + |
| @@ -2472,9 +2472,11 @@ static netdev_tx_t ibmvnic_xmit(struct sk_buff *skb, struct net_device *netdev) · 2471 unmodified lines | ||
| 2472 | 2472 | /* if we are going to send_subcrq_direct this then we need to |
| 2473 | 2473 | * update the checksum before copying the data into ltb. Essentially |
| 2474 | 2474 | * these packets force disable CSO so that we can guarantee that |
| 2475 | − * FW does not need header info and we can send direct. | |
| 2475 | + * FW does not need header info and we can send direct. Also, vnic | |
| 2476 | + * server must be able to xmit standard packets without header data | |
| 2476 | 2477 | */ |
| 2477 | − if (!skb_is_gso(skb) && !ind_bufp->index && !netdev_xmit_more()) { | |
| 2478 | + if (*hdrs == 0 && !skb_is_gso(skb) && | |
| 2479 | + !ind_bufp->index && !netdev_xmit_more()) { | |
| 2478 | 2480 | use_scrq_send_direct = true; |
| 2479 | 2481 | if (skb->ip_summed == CHECKSUM_PARTIAL && |
| 2480 | 2482 | skb_checksum_help(skb)) |
| @@ -108,8 +108,8 @@ struct e1000_hw; · 107 unmodified lines | ||
| 108 | 108 | #define E1000_DEV_ID_PCH_RPL_I219_V22 0x0DC8 |
| 109 | 109 | #define E1000_DEV_ID_PCH_MTP_I219_LM18 0x550A |
| 110 | 110 | #define E1000_DEV_ID_PCH_MTP_I219_V18 0x550B |
| 111 | −#define E1000_DEV_ID_PCH_MTP_I219_LM19 0x550C | |
| 112 | −#define E1000_DEV_ID_PCH_MTP_I219_V19 0x550D | |
| 111 | +#define E1000_DEV_ID_PCH_ADP_I219_LM19 0x550C | |
| 112 | +#define E1000_DEV_ID_PCH_ADP_I219_V19 0x550D | |
| 113 | 113 | #define E1000_DEV_ID_PCH_LNP_I219_LM20 0x550E |
| 114 | 114 | #define E1000_DEV_ID_PCH_LNP_I219_V20 0x550F |
| 115 | 115 | #define E1000_DEV_ID_PCH_LNP_I219_LM21 0x5510 |
| @@ -7899,10 +7899,10 @@ static const struct pci_device_id e1000_pci_tbl[] = { · 7898 unmodified lines | ||
| 7899 | 7899 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V17), board_pch_adp }, |
| 7900 | 7900 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_LM22), board_pch_adp }, |
| 7901 | 7901 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_V22), board_pch_adp }, |
| 7902 | + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_LM19), board_pch_adp }, | |
| 7903 | + { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V19), board_pch_adp }, | |
| 7902 | 7904 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM18), board_pch_mtp }, |
| 7903 | 7905 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V18), board_pch_mtp }, |
| 7904 | − { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM19), board_pch_mtp }, | |
| 7905 | − { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V19), board_pch_mtp }, | |
| 7906 | 7906 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM20), board_pch_mtp }, |
| 7907 | 7907 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V20), board_pch_mtp }, |
| 7908 | 7908 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM21), board_pch_mtp }, |
| @@ -1734,6 +1734,7 @@ struct i40e_mac_filter *i40e_add_mac_filter(struct i40e_vsi *vsi, · 1733 unmodified lines | ||
| 1734 | 1734 | struct hlist_node *h; |
| 1735 | 1735 | int bkt; |
| 1736 | 1736 | |
| 1737 | + lockdep_assert_held(&vsi->mac_filter_hash_lock); | |
| 1737 | 1738 | if (vsi->info.pvid) |
| 1738 | 1739 | return i40e_add_filter(vsi, macaddr, |
| 1739 | 1740 | le16_to_cpu(vsi->info.pvid)); |
| @@ -2213,8 +2213,10 @@ static int i40e_vc_get_vf_resources_msg(struct i40e_vf *vf, u8 *msg) · 2212 unmodified lines | ||
| 2213 | 2213 | vfres->vsi_res[0].qset_handle |
| 2214 | 2214 | = le16_to_cpu(vsi->info.qs_handle[0]); |
| 2215 | 2215 | if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_USO) && !vf->pf_set_mac) { |
| 2216 | + spin_lock_bh(&vsi->mac_filter_hash_lock); | |
| 2216 | 2217 | i40e_del_mac_filter(vsi, vf->default_lan_addr.addr); |
| 2217 | 2218 | eth_zero_addr(vf->default_lan_addr.addr); |
| 2219 | + spin_unlock_bh(&vsi->mac_filter_hash_lock); | |
| 2218 | 2220 | } |
| 2219 | 2221 | ether_addr_copy(vfres->vsi_res[0].default_mac_addr, |
| 2220 | 2222 | vf->default_lan_addr.addr); |
| @@ -989,5 +989,11 @@ ice_devlink_port_new(struct devlink *devlink, · 988 unmodified lines | ||
| 989 | 989 | if (err) |
| 990 | 990 | return err; |
| 991 | 991 | |
| 992 | + if (!ice_is_eswitch_mode_switchdev(pf)) { | |
| 993 | + NL_SET_ERR_MSG_MOD(extack, | |
| 994 | + "SF ports are only supported in eswitch switchdev mode"); | |
| 995 | + return -EOPNOTSUPP; | |
| 996 | + } | |
| 997 | + | |
| 992 | 998 | return ice_alloc_dynamic_port(pf, new_attr, extack, devlink_port); |
| 993 | 999 | } |
| @@ -31,7 +31,7 @@ static const struct ice_tunnel_type_scan tnls[] = { · 30 unmodified lines | ||
| 31 | 31 | * Verifies various attributes of the package file, including length, format |
| 32 | 32 | * version, and the requirement of at least one segment. |
| 33 | 33 | */ |
| 34 | −static enum ice_ddp_state ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len) | |
| 34 | +static enum ice_ddp_state ice_verify_pkg(const struct ice_pkg_hdr *pkg, u32 len) | |
| 35 | 35 | { |
| 36 | 36 | u32 seg_count; |
| 37 | 37 | u32 i; |
| @@ -57,13 +57,13 @@ static enum ice_ddp_state ice_verify_pkg(struct ice_pkg_hdr *pkg, u32 len) · 19 unmodified lines | ||
| 57 | 57 | /* all segments must fit within length */ |
| 58 | 58 | for (i = 0; i < seg_count; i++) { |
| 59 | 59 | u32 off = le32_to_cpu(pkg->seg_offset[i]); |
| 60 | − struct ice_generic_seg_hdr *seg; | |
| 60 | + const struct ice_generic_seg_hdr *seg; | |
| 61 | 61 | |
| 62 | 62 | /* segment header must fit */ |
| 63 | 63 | if (len < off + sizeof(*seg)) |
| 64 | 64 | return ICE_DDP_PKG_INVALID_FILE; |
| 65 | 65 | |
| 66 | − seg = (struct ice_generic_seg_hdr *)((u8 *)pkg + off); | |
| 66 | + seg = (void *)pkg + off; | |
| 67 | 67 | |
| 68 | 68 | /* segment body must fit */ |
| 69 | 69 | if (len < off + le32_to_cpu(seg->seg_size)) |
| @@ -119,13 +119,13 @@ static enum ice_ddp_state ice_chk_pkg_version(struct ice_pkg_ver *pkg_ver) · 49 unmodified lines | ||
| 119 | 119 | * |
| 120 | 120 | * This helper function validates a buffer's header. |
| 121 | 121 | */ |
| 122 | −static struct ice_buf_hdr *ice_pkg_val_buf(struct ice_buf *buf) | |
| 122 | +static const struct ice_buf_hdr *ice_pkg_val_buf(const struct ice_buf *buf) | |
| 123 | 123 | { |
| 124 | − struct ice_buf_hdr *hdr; | |
| 124 | + const struct ice_buf_hdr *hdr; | |
| 125 | 125 | u16 section_count; |
| 126 | 126 | u16 data_end; |
| 127 | 127 | |
| 128 | − hdr = (struct ice_buf_hdr *)buf->buf; | |
| 128 | + hdr = (const struct ice_buf_hdr *)buf->buf; | |
| 129 | 129 | /* verify data */ |
| 130 | 130 | section_count = le16_to_cpu(hdr->section_count); |
| 131 | 131 | if (section_count < ICE_MIN_S_COUNT || section_count > ICE_MAX_S_COUNT) |
| @@ -165,8 +165,8 @@ static struct ice_buf_table *ice_find_buf_table(struct ice_seg *ice_seg) · 33 unmodified lines | ||
| 165 | 165 | * unexpected value has been detected (for example an invalid section count or |
| 166 | 166 | * an invalid buffer end value). |
| 167 | 167 | */ |
| 168 | −static struct ice_buf_hdr *ice_pkg_enum_buf(struct ice_seg *ice_seg, | |
| 169 | − struct ice_pkg_enum *state) | |
| 168 | +static const struct ice_buf_hdr *ice_pkg_enum_buf(struct ice_seg *ice_seg, | |
| 169 | + struct ice_pkg_enum *state) | |
| 170 | 170 | { |
| 171 | 171 | if (ice_seg) { |
| 172 | 172 | state->buf_table = ice_find_buf_table(ice_seg); |
| @@ -1800,9 +1800,9 @@ int ice_update_pkg(struct ice_hw *hw, struct ice_buf *bufs, u32 count) · 1627 unmodified lines | ||
| 1800 | 1800 | * success it returns a pointer to the segment header, otherwise it will |
| 1801 | 1801 | * return NULL. |
| 1802 | 1802 | */ |
| 1803 | −static struct ice_generic_seg_hdr * | |
| 1803 | +static const struct ice_generic_seg_hdr * | |
| 1804 | 1804 | ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type, |
| 1805 | − struct ice_pkg_hdr *pkg_hdr) | |
| 1805 | + const struct ice_pkg_hdr *pkg_hdr) | |
| 1806 | 1806 | { |
| 1807 | 1807 | u32 i; |
| 1808 | 1808 | |
| @@ -1813,11 +1813,9 @@ ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type, · 4 unmodified lines | ||
| 1813 | 1813 | |
| 1814 | 1814 | /* Search all package segments for the requested segment type */ |
| 1815 | 1815 | for (i = 0; i < le32_to_cpu(pkg_hdr->seg_count); i++) { |
| 1816 | − struct ice_generic_seg_hdr *seg; | |
| 1816 | + const struct ice_generic_seg_hdr *seg; | |
| 1817 | 1817 | |
| 1818 | − seg = (struct ice_generic_seg_hdr | |
| 1819 | − *)((u8 *)pkg_hdr + | |
| 1820 | − le32_to_cpu(pkg_hdr->seg_offset[i])); | |
| 1818 | + seg = (void *)pkg_hdr + le32_to_cpu(pkg_hdr->seg_offset[i]); | |
| 1821 | 1819 | |
| 1822 | 1820 | if (le32_to_cpu(seg->seg_type) == seg_type) |
| 1823 | 1821 | return seg; |
| @@ -2354,12 +2352,12 @@ ice_get_set_tx_topo(struct ice_hw *hw, u8 *buf, u16 buf_size, · 530 unmodified lines | ||
| 2354 | 2352 | * |
| 2355 | 2353 | * Return: zero when update was successful, negative values otherwise. |
| 2356 | 2354 | */ |
| 2357 | −int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len) | |
| 2355 | +int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len) | |
| 2358 | 2356 | { |
| 2359 | − u8 *current_topo, *new_topo = NULL; | |
| 2360 | − struct ice_run_time_cfg_seg *seg; | |
| 2361 | − struct ice_buf_hdr *section; | |
| 2362 | − struct ice_pkg_hdr *pkg_hdr; | |
| 2357 | + u8 *new_topo = NULL, *topo __free(kfree) = NULL; | |
| 2358 | + const struct ice_run_time_cfg_seg *seg; | |
| 2359 | + const struct ice_buf_hdr *section; | |
| 2360 | + const struct ice_pkg_hdr *pkg_hdr; | |
| 2363 | 2361 | enum ice_ddp_state state; |
| 2364 | 2362 | u16 offset, size = 0; |
| 2365 | 2363 | u32 reg = 0; |
| @@ -2375,15 +2373,13 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len) · 9 unmodified lines | ||
| 2375 | 2373 | return -EOPNOTSUPP; |
| 2376 | 2374 | } |
| 2377 | 2375 | |
| 2378 | − current_topo = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL); | |
| 2379 | − if (!current_topo) | |
| 2376 | + topo = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL); | |
| 2377 | + if (!topo) | |
| 2380 | 2378 | return -ENOMEM; |
| 2381 | 2379 | |
| 2382 | − /* Get the current Tx topology */ | |
| 2383 | − status = ice_get_set_tx_topo(hw, current_topo, ICE_AQ_MAX_BUF_LEN, NULL, | |
| 2384 | − &flags, false); | |
| 2385 | − | |
| 2386 | − kfree(current_topo); | |
| 2380 | + /* Get the current Tx topology flags */ | |
| 2381 | + status = ice_get_set_tx_topo(hw, topo, ICE_AQ_MAX_BUF_LEN, NULL, &flags, | |
| 2382 | + false); | |
| 2387 | 2383 | |
| 2388 | 2384 | if (status) { |
| 2389 | 2385 | ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n"); |
| @@ -2419,7 +2415,7 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len) · 29 unmodified lines | ||
| 2419 | 2415 | goto update_topo; |
| 2420 | 2416 | } |
| 2421 | 2417 | |
| 2422 | − pkg_hdr = (struct ice_pkg_hdr *)buf; | |
| 2418 | + pkg_hdr = (const struct ice_pkg_hdr *)buf; | |
| 2423 | 2419 | state = ice_verify_pkg(pkg_hdr, len); |
| 2424 | 2420 | if (state) { |
| 2425 | 2421 | ice_debug(hw, ICE_DBG_INIT, "Failed to verify pkg (err: %d)\n", |
| @@ -2428,7 +2424,7 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len) · 2 unmodified lines | ||
| 2428 | 2424 | } |
| 2429 | 2425 | |
| 2430 | 2426 | /* Find runtime configuration segment */ |
| 2431 | − seg = (struct ice_run_time_cfg_seg *) | |
| 2427 | + seg = (const struct ice_run_time_cfg_seg *) | |
| 2432 | 2428 | ice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE_RUN_TIME_CFG, pkg_hdr); |
| 2433 | 2429 | if (!seg) { |
| 2434 | 2430 | ice_debug(hw, ICE_DBG_INIT, "5 layer topology segment is missing\n"); |
| @@ -2461,8 +2457,10 @@ int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len) · 26 unmodified lines | ||
| 2461 | 2457 | return -EIO; |
| 2462 | 2458 | } |
| 2463 | 2459 | |
| 2464 | − /* Get the new topology buffer */ | |
| 2465 | − new_topo = ((u8 *)section) + offset; | |
| 2460 | + /* Get the new topology buffer, reuse current topo copy mem */ | |
| 2461 | + static_assert(ICE_PKG_BUF_SIZE == ICE_AQ_MAX_BUF_LEN); | |
| 2462 | + new_topo = topo; | |
| 2463 | + memcpy(new_topo, (u8 *)section + offset, size); | |
| 2466 | 2464 | |
| 2467 | 2465 | update_topo: |
| 2468 | 2466 | /* Acquire global lock to make sure that set topology issued |
| @@ -438,7 +438,7 @@ struct ice_pkg_enum { · 437 unmodified lines | ||
| 438 | 438 | u32 buf_idx; |
| 439 | 439 | |
| 440 | 440 | u32 type; |
| 441 | − struct ice_buf_hdr *buf; | |
| 441 | + const struct ice_buf_hdr *buf; | |
| 442 | 442 | u32 sect_idx; |
| 443 | 443 | void *sect; |
| 444 | 444 | u32 sect_type; |
| @@ -467,6 +467,6 @@ ice_pkg_enum_entry(struct ice_seg *ice_seg, struct ice_pkg_enum *state, · 22 unmodified lines | ||
| 467 | 467 | void *ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state, |
| 468 | 468 | u32 sect_type); |
| 469 | 469 | |
| 470 | −int ice_cfg_tx_topo(struct ice_hw *hw, u8 *buf, u32 len); | |
| 470 | +int ice_cfg_tx_topo(struct ice_hw *hw, const void *buf, u32 len); | |
| 471 | 471 | |
| 472 | 472 | #endif |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | ||
| 10 | 10 | #define ICE_DPLL_PIN_IDX_INVALID 0xff |
| 11 | 11 | #define ICE_DPLL_RCLK_NUM_PER_PF 1 |
| 12 | 12 | #define ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT 25 |
| 13 | +#define ICE_DPLL_PIN_GEN_RCLK_FREQ 1953125 | |
| 13 | 14 | |
| 14 | 15 | /** |
| 15 | 16 | * enum ice_dpll_pin_type - enumerate ice pin types: |
| @@ -656,6 +657,8 @@ ice_dpll_output_state_set(const struct dpll_pin *pin, void *pin_priv, · 640 unmodified lines | ||
| 656 | 657 | struct ice_dpll_pin *p = pin_priv; |
| 657 | 658 | struct ice_dpll *d = dpll_priv; |
| 658 | 659 | |
| 660 | + if (state == DPLL_PIN_STATE_SELECTABLE) | |
| 661 | + return -EINVAL; | |
| 659 | 662 | if (!enable && p->state[d->dpll_idx] == DPLL_PIN_STATE_DISCONNECTED) |
| 660 | 663 | return 0; |
| 661 | 664 | |
| @@ -1843,6 +1846,8 @@ ice_dpll_init_rclk_pins(struct ice_pf *pf, struct ice_dpll_pin *pin, · 1181 unmodified lines | ||
| 1843 | 1846 | struct dpll_pin *parent; |
| 1844 | 1847 | int ret, i; |
| 1845 | 1848 | |
| 1849 | + if (WARN_ON((!vsi || !vsi->netdev))) | |
| 1850 | + return -EINVAL; | |
| 1846 | 1851 | ret = ice_dpll_get_pins(pf, pin, start_idx, ICE_DPLL_RCLK_NUM_PER_PF, |
| 1847 | 1852 | pf->dplls.clock_id); |
| 1848 | 1853 | if (ret) |
| @@ -1858,8 +1863,6 @@ ice_dpll_init_rclk_pins(struct ice_pf *pf, struct ice_dpll_pin *pin, · 9 unmodified lines | ||
| 1858 | 1863 | if (ret) |
| 1859 | 1864 | goto unregister_pins; |
| 1860 | 1865 | } |
| 1861 | − if (WARN_ON((!vsi || !vsi->netdev))) | |
| 1862 | − return -EINVAL; | |
| 1863 | 1866 | dpll_netdev_pin_set(vsi->netdev, pf->dplls.rclk.pin); |
| 1864 | 1867 | |
| 1865 | 1868 | return 0; |
| @@ -2061,6 +2064,73 @@ static int ice_dpll_init_worker(struct ice_pf *pf) · 195 unmodified lines | ||
| 2061 | 2064 | return 0; |
| 2062 | 2065 | } |
| 2063 | 2066 | |
| 2067 | +/** | |
| 2068 | + * ice_dpll_init_info_pins_generic - initializes generic pins info | |
| 2069 | + * @pf: board private structure | |
| 2070 | + * @input: if input pins initialized | |
| 2071 | + * | |
| 2072 | + * Init information for generic pins, cache them in PF's pins structures. | |
| 2073 | + * | |
| 2074 | + * Return: | |
| 2075 | + * * 0 - success | |
| 2076 | + * * negative - init failure reason | |
| 2077 | + */ | |
| 2078 | +static int ice_dpll_init_info_pins_generic(struct ice_pf *pf, bool input) | |
| 2079 | +{ | |
| 2080 | + struct ice_dpll *de = &pf->dplls.eec, *dp = &pf->dplls.pps; | |
| 2081 | + static const char labels[][sizeof("99")] = { | |
| 2082 | + "0", "1", "2", "3", "4", "5", "6", "7", "8", | |
| 2083 | + "9", "10", "11", "12", "13", "14", "15" }; | |
| 2084 | + u32 cap = DPLL_PIN_CAPABILITIES_STATE_CAN_CHANGE; | |
| 2085 | + enum ice_dpll_pin_type pin_type; | |
| 2086 | + int i, pin_num, ret = -EINVAL; | |
| 2087 | + struct ice_dpll_pin *pins; | |
| 2088 | + u32 phase_adj_max; | |
| 2089 | + | |
| 2090 | + if (input) { | |
| 2091 | + pin_num = pf->dplls.num_inputs; | |
| 2092 | + pins = pf->dplls.inputs; | |
| 2093 | + phase_adj_max = pf->dplls.input_phase_adj_max; | |
| 2094 | + pin_type = ICE_DPLL_PIN_TYPE_INPUT; | |
| 2095 | + cap |= DPLL_PIN_CAPABILITIES_PRIORITY_CAN_CHANGE; | |
| 2096 | + } else { | |
| 2097 | + pin_num = pf->dplls.num_outputs; | |
| 2098 | + pins = pf->dplls.outputs; | |
| 2099 | + phase_adj_max = pf->dplls.output_phase_adj_max; | |
| 2100 | + pin_type = ICE_DPLL_PIN_TYPE_OUTPUT; | |
| 2101 | + } | |
| 2102 | + if (pin_num > ARRAY_SIZE(labels)) | |
| 2103 | + return ret; | |
| 2104 | + | |
| 2105 | + for (i = 0; i < pin_num; i++) { | |
| 2106 | + pins[i].idx = i; | |
| 2107 | + pins[i].prop.board_label = labels[i]; | |
| 2108 | + pins[i].prop.phase_range.min = phase_adj_max; | |
| 2109 | + pins[i].prop.phase_range.max = -phase_adj_max; | |
| 2110 | + pins[i].prop.capabilities = cap; | |
| 2111 | + pins[i].pf = pf; | |
| 2112 | + ret = ice_dpll_pin_state_update(pf, &pins[i], pin_type, NULL); | |
| 2113 | + if (ret) | |
| 2114 | + break; | |
| 2115 | + if (input && pins[i].freq == ICE_DPLL_PIN_GEN_RCLK_FREQ) | |
| 2116 | + pins[i].prop.type = DPLL_PIN_TYPE_MUX; | |
| 2117 | + else | |
| 2118 | + pins[i].prop.type = DPLL_PIN_TYPE_EXT; | |
| 2119 | + if (!input) | |
| 2120 | + continue; | |
| 2121 | + ret = ice_aq_get_cgu_ref_prio(&pf->hw, de->dpll_idx, i, | |
| 2122 | + &de->input_prio[i]); | |
| 2123 | + if (ret) | |
| 2124 | + break; | |
| 2125 | + ret = ice_aq_get_cgu_ref_prio(&pf->hw, dp->dpll_idx, i, | |
| 2126 | + &dp->input_prio[i]); | |
| 2127 | + if (ret) | |
| 2128 | + break; | |
| 2129 | + } | |
| 2130 | + | |
| 2131 | + return ret; | |
| 2132 | +} | |
| 2133 | + | |
| 2064 | 2134 | /** |
| 2065 | 2135 | * ice_dpll_init_info_direct_pins - initializes direct pins info |
| 2066 | 2136 | * @pf: board private structure |
| @@ -2099,6 +2169,8 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf, · 32 unmodified lines | ||
| 2099 | 2169 | default: |
| 2100 | 2170 | return -EINVAL; |
| 2101 | 2171 | } |
| 2172 | + if (num_pins != ice_cgu_get_num_pins(hw, input)) | |
| 2173 | + return ice_dpll_init_info_pins_generic(pf, input); | |
| 2102 | 2174 | |
| 2103 | 2175 | for (i = 0; i < num_pins; i++) { |
| 2104 | 2176 | caps = 0; |
| @@ -582,10 +582,13 @@ ice_eswitch_br_switchdev_event(struct notifier_block *nb, · 581 unmodified lines | ||
| 582 | 582 | return NOTIFY_DONE; |
| 583 | 583 | } |
| 584 | 584 | |
| 585 | −static void ice_eswitch_br_fdb_flush(struct ice_esw_br *bridge) | |
| 585 | +void ice_eswitch_br_fdb_flush(struct ice_esw_br *bridge) | |
| 586 | 586 | { |
| 587 | 587 | struct ice_esw_br_fdb_entry *entry, *tmp; |
| 588 | 588 | |
| 589 | + if (!bridge) | |
| 590 | + return; | |
| 591 | + | |
| 589 | 592 | list_for_each_entry_safe(entry, tmp, &bridge->fdb_list, list) |
| 590 | 593 | ice_eswitch_br_fdb_entry_notify_and_cleanup(bridge, entry); |
| 591 | 594 | } |
| @@ -117,5 +117,6 @@ void · 116 unmodified lines | ||
| 117 | 117 | ice_eswitch_br_offloads_deinit(struct ice_pf *pf); |
| 118 | 118 | int |
| 119 | 119 | ice_eswitch_br_offloads_init(struct ice_pf *pf); |
| 120 | +void ice_eswitch_br_fdb_flush(struct ice_esw_br *bridge); | |
| 120 | 121 | |
| 121 | 122 | #endif /* _ICE_ESWITCH_BR_H_ */ |
| @@ -87,7 +87,8 @@ ice_indr_setup_tc_cb(struct net_device *netdev, struct Qdisc *sch, · 86 unmodified lines | ||
| 87 | 87 | |
| 88 | 88 | bool netif_is_ice(const struct net_device *dev) |
| 89 | 89 | { |
| 90 | − return dev && (dev->netdev_ops == &ice_netdev_ops); | |
| 90 | + return dev && (dev->netdev_ops == &ice_netdev_ops || | |
| 91 | + dev->netdev_ops == &ice_netdev_safe_mode_ops); | |
| 91 | 92 | } |
| 92 | 93 | |
| 93 | 94 | /** |
| @@ -520,25 +521,6 @@ static void ice_pf_dis_all_vsi(struct ice_pf *pf, bool locked) · 426 unmodified lines | ||
| 520 | 521 | pf->vf_agg_node[node].num_vsis = 0; |
| 521 | 522 | } |
| 522 | 523 | |
| 523 | −/** | |
| 524 | − * ice_clear_sw_switch_recipes - clear switch recipes | |
| 525 | − * @pf: board private structure | |
| 526 | − * | |
| 527 | − * Mark switch recipes as not created in sw structures. There are cases where | |
| 528 | − * rules (especially advanced rules) need to be restored, either re-read from | |
| 529 | − * hardware or added again. For example after the reset. 'recp_created' flag | |
| 530 | − * prevents from doing that and need to be cleared upfront. | |
| 531 | − */ | |
| 532 | −static void ice_clear_sw_switch_recipes(struct ice_pf *pf) | |
| 533 | −{ | |
| 534 | − struct ice_sw_recipe *recp; | |
| 535 | − u8 i; | |
| 536 | − | |
| 537 | − recp = pf->hw.switch_info->recp_list; | |
| 538 | − for (i = 0; i < ICE_MAX_NUM_RECIPES; i++) | |
| 539 | − recp[i].recp_created = false; | |
| 540 | −} | |
| 541 | − | |
| 542 | 524 | /** |
| 543 | 525 | * ice_prepare_for_reset - prep for reset |
| 544 | 526 | * @pf: board private structure |
| @@ -575,8 +557,9 @@ ice_prepare_for_reset(struct ice_pf *pf, enum ice_reset_req reset_type) · 30 unmodified lines | ||
| 575 | 557 | mutex_unlock(&pf->vfs.table_lock); |
| 576 | 558 | |
| 577 | 559 | if (ice_is_eswitch_mode_switchdev(pf)) { |
| 578 | − if (reset_type != ICE_RESET_PFR) | |
| 579 | − ice_clear_sw_switch_recipes(pf); | |
| 560 | + rtnl_lock(); | |
| 561 | + ice_eswitch_br_fdb_flush(pf->eswitch.br_offloads->bridge); | |
| 562 | + rtnl_unlock(); | |
| 580 | 563 | } |
| 581 | 564 | |
| 582 | 565 | /* release ADQ specific HW and SW resources */ |
| @@ -4536,16 +4519,10 @@ ice_init_tx_topology(struct ice_hw *hw, const struct firmware *firmware) · 3953 unmodified lines | ||
| 4536 | 4519 | u8 num_tx_sched_layers = hw->num_tx_sched_layers; |
| 4537 | 4520 | struct ice_pf *pf = hw->back; |
| 4538 | 4521 | struct device *dev; |
| 4539 | − u8 *buf_copy; | |
| 4540 | 4522 | int err; |
| 4541 | 4523 | |
| 4542 | 4524 | dev = ice_pf_to_dev(pf); |
| 4543 | − /* ice_cfg_tx_topo buf argument is not a constant, | |
| 4544 | − * so we have to make a copy | |
| 4545 | − */ | |
| 4546 | − buf_copy = kmemdup(firmware->data, firmware->size, GFP_KERNEL); | |
| 4547 | − | |
| 4548 | − err = ice_cfg_tx_topo(hw, buf_copy, firmware->size); | |
| 4525 | + err = ice_cfg_tx_topo(hw, firmware->data, firmware->size); | |
| 4549 | 4526 | if (!err) { |
| 4550 | 4527 | if (hw->num_tx_sched_layers > num_tx_sched_layers) |
| 4551 | 4528 | dev_info(dev, "Tx scheduling layers switching feature disabled\n"); |
| @@ -4773,14 +4750,12 @@ int ice_init_dev(struct ice_pf *pf) · 221 unmodified lines | ||
| 4773 | 4750 | ice_init_feature_support(pf); |
| 4774 | 4751 | |
| 4775 | 4752 | err = ice_init_ddp_config(hw, pf); |
| 4776 | − if (err) | |
| 4777 | − return err; | |
| 4778 | 4753 | |
| 4779 | 4754 | /* if ice_init_ddp_config fails, ICE_FLAG_ADV_FEATURES bit won't be |
| 4780 | 4755 | * set in pf->state, which will cause ice_is_safe_mode to return |
| 4781 | 4756 | * true |
| 4782 | 4757 | */ |
| 4783 | − if (ice_is_safe_mode(pf)) { | |
| 4758 | + if (err || ice_is_safe_mode(pf)) { | |
| 4784 | 4759 | /* we already got function/device capabilities but these don't |
| 4785 | 4760 | * reflect what the driver needs to do in safe mode. Instead of |
| 4786 | 4761 | * adding conditional logic everywhere to ignore these |
| @@ -34,7 +34,6 @@ static const struct ice_cgu_pin_desc ice_e810t_sfp_cgu_inputs[] = { · 33 unmodified lines | ||
| 34 | 34 | ARRAY_SIZE(ice_cgu_pin_freq_common), ice_cgu_pin_freq_common }, |
| 35 | 35 | { "GNSS-1PPS", ZL_REF4P, DPLL_PIN_TYPE_GNSS, |
| 36 | 36 | ARRAY_SIZE(ice_cgu_pin_freq_1_hz), ice_cgu_pin_freq_1_hz }, |
| 37 | − { "OCXO", ZL_REF4N, DPLL_PIN_TYPE_INT_OSCILLATOR, 0, }, | |
| 38 | 37 | }; |
| 39 | 38 | |
| 40 | 39 | static const struct ice_cgu_pin_desc ice_e810t_qsfp_cgu_inputs[] = { |
| @@ -52,7 +51,6 @@ static const struct ice_cgu_pin_desc ice_e810t_qsfp_cgu_inputs[] = { · 11 unmodified lines | ||
| 52 | 51 | ARRAY_SIZE(ice_cgu_pin_freq_common), ice_cgu_pin_freq_common }, |
| 53 | 52 | { "GNSS-1PPS", ZL_REF4P, DPLL_PIN_TYPE_GNSS, |
| 54 | 53 | ARRAY_SIZE(ice_cgu_pin_freq_1_hz), ice_cgu_pin_freq_1_hz }, |
| 55 | − { "OCXO", ZL_REF4N, DPLL_PIN_TYPE_INT_OSCILLATOR, }, | |
| 56 | 54 | }; |
| 57 | 55 | |
| 58 | 56 | static const struct ice_cgu_pin_desc ice_e810t_sfp_cgu_outputs[] = { |
| @@ -5964,6 +5962,25 @@ ice_cgu_get_pin_desc(struct ice_hw *hw, bool input, int *size) · 5905 unmodified lines | ||
| 5964 | 5962 | return t; |
| 5965 | 5963 | } |
| 5966 | 5964 | |
| 5965 | +/** | |
| 5966 | + * ice_cgu_get_num_pins - get pin description array size | |
| 5967 | + * @hw: pointer to the hw struct | |
| 5968 | + * @input: if request is done against input or output pins | |
| 5969 | + * | |
| 5970 | + * Return: size of pin description array for given hw. | |
| 5971 | + */ | |
| 5972 | +int ice_cgu_get_num_pins(struct ice_hw *hw, bool input) | |
| 5973 | +{ | |
| 5974 | + const struct ice_cgu_pin_desc *t; | |
| 5975 | + int size; | |
| 5976 | + | |
| 5977 | + t = ice_cgu_get_pin_desc(hw, input, &size); | |
| 5978 | + if (t) | |
| 5979 | + return size; | |
| 5980 | + | |
| 5981 | + return 0; | |
| 5982 | +} | |
| 5983 | + | |
| 5967 | 5984 | /** |
| 5968 | 5985 | * ice_cgu_get_pin_type - get pin's type |
| 5969 | 5986 | * @hw: pointer to the hw struct |
| @@ -404,6 +404,7 @@ int ice_read_sma_ctrl_e810t(struct ice_hw *hw, u8 *data); · 403 unmodified lines | ||
| 404 | 404 | int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data); |
| 405 | 405 | int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data); |
| 406 | 406 | bool ice_is_pca9575_present(struct ice_hw *hw); |
| 407 | +int ice_cgu_get_num_pins(struct ice_hw *hw, bool input); | |
| 407 | 408 | enum dpll_pin_type ice_cgu_get_pin_type(struct ice_hw *hw, u8 pin, bool input); |
| 408 | 409 | struct dpll_pin_frequency * |
| 409 | 410 | ice_cgu_get_pin_freq_supp(struct ice_hw *hw, u8 pin, bool input, u8 *num); |
| @@ -1096,8 +1096,10 @@ int ice_sriov_set_msix_vec_count(struct pci_dev *vf_dev, int msix_vec_count) · 1095 unmodified lines | ||
| 1096 | 1096 | return -ENOENT; |
| 1097 | 1097 | |
| 1098 | 1098 | vsi = ice_get_vf_vsi(vf); |
| 1099 | − if (!vsi) | |
| 1099 | + if (!vsi) { | |
| 1100 | + ice_put_vf(vf); | |
| 1100 | 1101 | return -ENOENT; |
| 1102 | + } | |
| 1101 | 1103 | |
| 1102 | 1104 | prev_msix = vf->num_msix; |
| 1103 | 1105 | prev_queues = vf->num_vf_qs; |
| @@ -1119,7 +1121,10 @@ int ice_sriov_set_msix_vec_count(struct pci_dev *vf_dev, int msix_vec_count) · 15 unmodified lines | ||
| 1119 | 1121 | if (vf->first_vector_idx < 0) |
| 1120 | 1122 | goto unroll; |
| 1121 | 1123 | |
| 1122 | − if (ice_vf_reconfig_vsi(vf) || ice_vf_init_host_cfg(vf, vsi)) { | |
| 1124 | + vsi->req_txq = queues; | |
| 1125 | + vsi->req_rxq = queues; | |
| 1126 | + | |
| 1127 | + if (ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT)) { | |
| 1123 | 1128 | /* Try to rebuild with previous values */ |
| 1124 | 1129 | needs_rebuild = true; |
| 1125 | 1130 | goto unroll; |
| @@ -1142,12 +1147,16 @@ unroll: · 16 unmodified lines | ||
| 1142 | 1147 | vf->num_msix = prev_msix; |
| 1143 | 1148 | vf->num_vf_qs = prev_queues; |
| 1144 | 1149 | vf->first_vector_idx = ice_sriov_get_irqs(pf, vf->num_msix); |
| 1145 | − if (vf->first_vector_idx < 0) | |
| 1150 | + if (vf->first_vector_idx < 0) { | |
| 1151 | + ice_put_vf(vf); | |
| 1146 | 1152 | return -EINVAL; |
| 1153 | + } | |
| 1147 | 1154 | |
| 1148 | 1155 | if (needs_rebuild) { |
| 1149 | − ice_vf_reconfig_vsi(vf); | |
| 1150 | − ice_vf_init_host_cfg(vf, vsi); | |
| 1156 | + vsi->req_txq = prev_queues; | |
| 1157 | + vsi->req_rxq = prev_queues; | |
| 1158 | + | |
| 1159 | + ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT); | |
| 1151 | 1160 | } |
| 1152 | 1161 | |
| 1153 | 1162 | ice_ena_vf_mappings(vf); |
| @@ -6322,8 +6322,6 @@ ice_replay_vsi_fltr(struct ice_hw *hw, u16 vsi_handle, u8 recp_id, · 6321 unmodified lines | ||
| 6322 | 6322 | if (!itr->vsi_list_info || |
| 6323 | 6323 | !test_bit(vsi_handle, itr->vsi_list_info->vsi_map)) |
| 6324 | 6324 | continue; |
| 6325 | − /* Clearing it so that the logic can add it back */ | |
| 6326 | − clear_bit(vsi_handle, itr->vsi_list_info->vsi_map); | |
| 6327 | 6325 | f_entry.fltr_info.vsi_handle = vsi_handle; |
| 6328 | 6326 | f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; |
| 6329 | 6327 | /* update the src in case it is VSI num */ |
| @@ -819,6 +819,17 @@ ice_eswitch_add_tc_fltr(struct ice_vsi *vsi, struct ice_tc_flower_fltr *fltr) · 818 unmodified lines | ||
| 819 | 819 | rule_info.sw_act.flag |= ICE_FLTR_TX; |
| 820 | 820 | rule_info.sw_act.src = vsi->idx; |
| 821 | 821 | rule_info.flags_info.act = ICE_SINGLE_ACT_LAN_ENABLE; |
| 822 | + /* This is a specific case. The destination VSI index is | |
| 823 | + * overwritten by the source VSI index. This type of filter | |
| 824 | + * should allow the packet to go to the LAN, not to the | |
| 825 | + * VSI passed here. It should set LAN_EN bit only. However, | |
| 826 | + * the VSI must be a valid one. Setting source VSI index | |
| 827 | + * here is safe. Even if the result from switch is set LAN_EN | |
| 828 | + * and LB_EN (which normally will pass the packet to this VSI) | |
| 829 | + * packet won't be seen on the VSI, because local loopback is | |
| 830 | + * turned off. | |
| 831 | + */ | |
| 832 | + rule_info.sw_act.vsi_handle = vsi->idx; | |
| 822 | 833 | } else { |
| 823 | 834 | /* VF to VF */ |
| 824 | 835 | rule_info.sw_act.flag |= ICE_FLTR_TX; |
| @@ -256,7 +256,7 @@ static void ice_vf_pre_vsi_rebuild(struct ice_vf *vf) · 255 unmodified lines | ||
| 256 | 256 | * |
| 257 | 257 | * It brings the VSI down and then reconfigures it with the hardware. |
| 258 | 258 | */ |
| 259 | −int ice_vf_reconfig_vsi(struct ice_vf *vf) | |
| 259 | +static int ice_vf_reconfig_vsi(struct ice_vf *vf) | |
| 260 | 260 | { |
| 261 | 261 | struct ice_vsi *vsi = ice_get_vf_vsi(vf); |
| 262 | 262 | struct ice_pf *pf = vf->pf; |
| @@ -335,6 +335,13 @@ static int ice_vf_rebuild_host_vlan_cfg(struct ice_vf *vf, struct ice_vsi *vsi) · 72 unmodified lines | ||
| 335 | 335 | |
| 336 | 336 | err = vlan_ops->add_vlan(vsi, &vf->port_vlan_info); |
| 337 | 337 | } else { |
| 338 | + /* clear possible previous port vlan config */ | |
| 339 | + err = ice_vsi_clear_port_vlan(vsi); | |
| 340 | + if (err) { | |
| 341 | + dev_err(dev, "failed to clear port VLAN via VSI parameters for VF %u, error %d\n", | |
| 342 | + vf->vf_id, err); | |
| 343 | + return err; | |
| 344 | + } | |
| 338 | 345 | err = ice_vsi_add_vlan_zero(vsi); |
| 339 | 346 | } |
| 340 | 347 | |
| @@ -23,7 +23,6 @@ · 22 unmodified lines | ||
| 23 | 23 | #warning "Only include ice_vf_lib_private.h in CONFIG_PCI_IOV virtualization files" |
| 24 | 24 | #endif |
| 25 | 25 | |
| 26 | −int ice_vf_reconfig_vsi(struct ice_vf *vf); | |
| 27 | 26 | void ice_initialize_vf_entry(struct ice_vf *vf); |
| 28 | 27 | void ice_dis_vf_qs(struct ice_vf *vf); |
| 29 | 28 | int ice_check_vf_init(struct ice_vf *vf); |
| @@ -787,3 +787,60 @@ int ice_vsi_clear_outer_port_vlan(struct ice_vsi *vsi) · 786 unmodified lines | ||
| 787 | 787 | kfree(ctxt); |
| 788 | 788 | return err; |
| 789 | 789 | } |
| 790 | + | |
| 791 | +int ice_vsi_clear_port_vlan(struct ice_vsi *vsi) | |
| 792 | +{ | |
| 793 | + struct ice_hw *hw = &vsi->back->hw; | |
| 794 | + struct ice_vsi_ctx *ctxt; | |
| 795 | + int err; | |
| 796 | + | |
| 797 | + ctxt = kzalloc(sizeof(*ctxt), GFP_KERNEL); | |
| 798 | + if (!ctxt) | |
| 799 | + return -ENOMEM; | |
| 800 | + | |
| 801 | + ctxt->info = vsi->info; | |
| 802 | + | |
| 803 | + ctxt->info.port_based_outer_vlan = 0; | |
| 804 | + ctxt->info.port_based_inner_vlan = 0; | |
| 805 | + | |
| 806 | + ctxt->info.inner_vlan_flags = | |
| 807 | + FIELD_PREP(ICE_AQ_VSI_INNER_VLAN_TX_MODE_M, | |
| 808 | + ICE_AQ_VSI_INNER_VLAN_TX_MODE_ALL); | |
| 809 | + if (ice_is_dvm_ena(hw)) { | |
| 810 | + ctxt->info.inner_vlan_flags |= | |
| 811 | + FIELD_PREP(ICE_AQ_VSI_INNER_VLAN_EMODE_M, | |
| 812 | + ICE_AQ_VSI_INNER_VLAN_EMODE_NOTHING); | |
| 813 | + ctxt->info.outer_vlan_flags = | |
| 814 | + FIELD_PREP(ICE_AQ_VSI_OUTER_VLAN_TX_MODE_M, | |
| 815 | + ICE_AQ_VSI_OUTER_VLAN_TX_MODE_ALL); | |
| 816 | + ctxt->info.outer_vlan_flags |= | |
| 817 | + FIELD_PREP(ICE_AQ_VSI_OUTER_TAG_TYPE_M, | |
| 818 | + ICE_AQ_VSI_OUTER_TAG_VLAN_8100); | |
| 819 | + ctxt->info.outer_vlan_flags |= | |
| 820 | + ICE_AQ_VSI_OUTER_VLAN_EMODE_NOTHING << | |
| 821 | + ICE_AQ_VSI_OUTER_VLAN_EMODE_S; | |
| 822 | + } | |
| 823 | + | |
| 824 | + ctxt->info.sw_flags2 &= ~ICE_AQ_VSI_SW_FLAG_RX_VLAN_PRUNE_ENA; | |
| 825 | + ctxt->info.valid_sections = | |
| 826 | + cpu_to_le16(ICE_AQ_VSI_PROP_OUTER_TAG_VALID | | |
| 827 | + ICE_AQ_VSI_PROP_VLAN_VALID | | |
| 828 | + ICE_AQ_VSI_PROP_SW_VALID); | |
| 829 | + | |
| 830 | + err = ice_update_vsi(hw, vsi->idx, ctxt, NULL); | |
| 831 | + if (err) { | |
| 832 | + dev_err(ice_pf_to_dev(vsi->back), "update VSI for clearing port based VLAN failed, err %d aq_err %s\n", | |
| 833 | + err, ice_aq_str(hw->adminq.sq_last_status)); | |
| 834 | + } else { | |
| 835 | + vsi->info.port_based_outer_vlan = | |
| 836 | + ctxt->info.port_based_outer_vlan; | |
| 837 | + vsi->info.port_based_inner_vlan = | |
| 838 | + ctxt->info.port_based_inner_vlan; | |
| 839 | + vsi->info.outer_vlan_flags = ctxt->info.outer_vlan_flags; | |
| 840 | + vsi->info.inner_vlan_flags = ctxt->info.inner_vlan_flags; | |
| 841 | + vsi->info.sw_flags2 = ctxt->info.sw_flags2; | |
| 842 | + } | |
| 843 | + | |
| 844 | + kfree(ctxt); | |
| 845 | + return err; | |
| 846 | +} | |
| @@ -36,5 +36,6 @@ int ice_vsi_ena_outer_insertion(struct ice_vsi *vsi, u16 tpid); · 35 unmodified lines | ||
| 36 | 36 | int ice_vsi_dis_outer_insertion(struct ice_vsi *vsi); |
| 37 | 37 | int ice_vsi_set_outer_port_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan); |
| 38 | 38 | int ice_vsi_clear_outer_port_vlan(struct ice_vsi *vsi); |
| 39 | +int ice_vsi_clear_port_vlan(struct ice_vsi *vsi); | |
| 39 | 40 | |
| 40 | 41 | #endif /* _ICE_VSI_VLAN_LIB_H_ */ |
| @@ -99,6 +99,7 @@ static int idpf_vf_intr_reg_init(struct idpf_vport *vport) · 98 unmodified lines | ||
| 99 | 99 | intr->dyn_ctl_intena_m = VF_INT_DYN_CTLN_INTENA_M; |
| 100 | 100 | intr->dyn_ctl_intena_msk_m = VF_INT_DYN_CTLN_INTENA_MSK_M; |
| 101 | 101 | intr->dyn_ctl_itridx_s = VF_INT_DYN_CTLN_ITR_INDX_S; |
| 102 | + intr->dyn_ctl_intrvl_s = VF_INT_DYN_CTLN_INTERVAL_S; | |
| 102 | 103 | intr->dyn_ctl_wb_on_itr_m = VF_INT_DYN_CTLN_WB_ON_ITR_M; |
| 103 | 104 | |
| 104 | 105 | spacing = IDPF_ITR_IDX_SPACING(reg_vals[vec_id].itrn_index_spacing, |
| @@ -666,7 +666,7 @@ idpf_vc_xn_forward_reply(struct idpf_adapter *adapter, · 665 unmodified lines | ||
| 666 | 666 | |
| 667 | 667 | if (ctlq_msg->data_len) { |
| 668 | 668 | payload = ctlq_msg->ctx.indirect.payload->va; |
| 669 | − payload_size = ctlq_msg->ctx.indirect.payload->size; | |
| 669 | + payload_size = ctlq_msg->data_len; | |
| 670 | 670 | } |
| 671 | 671 | |
| 672 | 672 | xn->reply_sz = payload_size; |
| @@ -1295,10 +1295,6 @@ int idpf_send_create_vport_msg(struct idpf_adapter *adapter, · 622 unmodified lines | ||
| 1295 | 1295 | err = reply_sz; |
| 1296 | 1296 | goto free_vport_params; |
| 1297 | 1297 | } |
| 1298 | − if (reply_sz < IDPF_CTLQ_MAX_BUF_LEN) { | |
| 1299 | − err = -EIO; | |
| 1300 | − goto free_vport_params; | |
| 1301 | − } | |
| 1302 | 1298 | |
| 1303 | 1299 | return 0; |
| 1304 | 1300 | |
| @@ -2602,9 +2598,6 @@ int idpf_send_get_rx_ptype_msg(struct idpf_vport *vport) · 1297 unmodified lines | ||
| 2602 | 2598 | if (reply_sz < 0) |
| 2603 | 2599 | return reply_sz; |
| 2604 | 2600 | |
| 2605 | − if (reply_sz < IDPF_CTLQ_MAX_BUF_LEN) | |
| 2606 | − return -EIO; | |
| 2607 | − | |
| 2608 | 2601 | ptypes_recvd += le16_to_cpu(ptype_info->num_ptypes); |
| 2609 | 2602 | if (ptypes_recvd > max_ptype) |
| 2610 | 2603 | return -EINVAL; |
| @@ -3088,9 +3081,9 @@ void idpf_vc_core_deinit(struct idpf_adapter *adapter) · 477 unmodified lines | ||
| 3088 | 3081 | if (!test_bit(IDPF_VC_CORE_INIT, adapter->flags)) |
| 3089 | 3082 | return; |
| 3090 | 3083 | |
| 3091 | − idpf_vc_xn_shutdown(adapter->vcxn_mngr); | |
| 3092 | 3084 | idpf_deinit_task(adapter); |
| 3093 | 3085 | idpf_intr_rel(adapter); |
| 3086 | + idpf_vc_xn_shutdown(adapter->vcxn_mngr); | |
| 3094 | 3087 | |
| 3095 | 3088 | cancel_delayed_work_sync(&adapter->serv_task); |
| 3096 | 3089 | cancel_delayed_work_sync(&adapter->mbx_task); |
| @@ -907,7 +907,7 @@ static int igb_request_msix(struct igb_adapter *adapter) · 906 unmodified lines | ||
| 907 | 907 | int i, err = 0, vector = 0, free_vector = 0; |
| 908 | 908 | |
| 909 | 909 | err = request_irq(adapter->msix_entries[vector].vector, |
| 910 | − igb_msix_other, 0, netdev->name, adapter); | |
| 910 | + igb_msix_other, IRQF_NO_THREAD, netdev->name, adapter); | |
| 911 | 911 | if (err) |
| 912 | 912 | goto err_out; |
| 913 | 913 | |
| @@ -9651,6 +9651,10 @@ static void igb_io_resume(struct pci_dev *pdev) · 8737 unmodified lines | ||
| 9651 | 9651 | struct igb_adapter *adapter = netdev_priv(netdev); |
| 9652 | 9652 | |
| 9653 | 9653 | if (netif_running(netdev)) { |
| 9654 | + if (!test_bit(__IGB_DOWN, &adapter->state)) { | |
| 9655 | + dev_dbg(&pdev->dev, "Resuming from non-fatal error, do nothing.\n"); | |
| 9656 | + return; | |
| 9657 | + } | |
| 9654 | 9658 | if (igb_up(adapter)) { |
| 9655 | 9659 | dev_err(&pdev->dev, "igb_up failed after reset\n"); |
| 9656 | 9660 | return; |
| @@ -336,6 +336,51 @@ static int octep_oq_check_hw_for_pkts(struct octep_device *oct, · 335 unmodified lines | ||
| 336 | 336 | return new_pkts; |
| 337 | 337 | } |
| 338 | 338 | |
| 339 | +/** | |
| 340 | + * octep_oq_next_pkt() - Move to the next packet in Rx queue. | |
| 341 | + * | |
| 342 | + * @oq: Octeon Rx queue data structure. | |
| 343 | + * @buff_info: Current packet buffer info. | |
| 344 | + * @read_idx: Current packet index in the ring. | |
| 345 | + * @desc_used: Current packet descriptor number. | |
| 346 | + * | |
| 347 | + * Free the resources associated with a packet. | |
| 348 | + * Increment packet index in the ring and packet descriptor number. | |
| 349 | + */ | |
| 350 | +static void octep_oq_next_pkt(struct octep_oq *oq, | |
| 351 | + struct octep_rx_buffer *buff_info, | |
| 352 | + u32 *read_idx, u32 *desc_used) | |
| 353 | +{ | |
| 354 | + dma_unmap_page(oq->dev, oq->desc_ring[*read_idx].buffer_ptr, | |
| 355 | + PAGE_SIZE, DMA_FROM_DEVICE); | |
| 356 | + buff_info->page = NULL; | |
| 357 | + (*read_idx)++; | |
| 358 | + (*desc_used)++; | |
| 359 | + if (*read_idx == oq->max_count) | |
| 360 | + *read_idx = 0; | |
| 361 | +} | |
| 362 | + | |
| 363 | +/** | |
| 364 | + * octep_oq_drop_rx() - Free the resources associated with a packet. | |
| 365 | + * | |
| 366 | + * @oq: Octeon Rx queue data structure. | |
| 367 | + * @buff_info: Current packet buffer info. | |
| 368 | + * @read_idx: Current packet index in the ring. | |
| 369 | + * @desc_used: Current packet descriptor number. | |
| 370 | + * | |
| 371 | + */ | |
| 372 | +static void octep_oq_drop_rx(struct octep_oq *oq, | |
| 373 | + struct octep_rx_buffer *buff_info, | |
| 374 | + u32 *read_idx, u32 *desc_used) | |
| 375 | +{ | |
| 376 | + int data_len = buff_info->len - oq->max_single_buffer_size; | |
| 377 | + | |
| 378 | + while (data_len > 0) { | |
| 379 | + octep_oq_next_pkt(oq, buff_info, read_idx, desc_used); | |
| 380 | + data_len -= oq->buffer_size; | |
| 381 | + }; | |
| 382 | +} | |
| 383 | + | |
| 339 | 384 | /** |
| 340 | 385 | * __octep_oq_process_rx() - Process hardware Rx queue and push to stack. |
| 341 | 386 | * |
| @@ -367,10 +412,7 @@ static int __octep_oq_process_rx(struct octep_device *oct, · 25 unmodified lines | ||
| 367 | 412 | desc_used = 0; |
| 368 | 413 | for (pkt = 0; pkt < pkts_to_process; pkt++) { |
| 369 | 414 | buff_info = (struct octep_rx_buffer *)&oq->buff_info[read_idx]; |
| 370 | − dma_unmap_page(oq->dev, oq->desc_ring[read_idx].buffer_ptr, | |
| 371 | − PAGE_SIZE, DMA_FROM_DEVICE); | |
| 372 | 415 | resp_hw = page_address(buff_info->page); |
| 373 | − buff_info->page = NULL; | |
| 374 | 416 | |
| 375 | 417 | /* Swap the length field that is in Big-Endian to CPU */ |
| 376 | 418 | buff_info->len = be64_to_cpu(resp_hw->length); |
| @@ -394,36 +436,33 @@ static int __octep_oq_process_rx(struct octep_device *oct, · 17 unmodified lines | ||
| 394 | 436 | data_offset = OCTEP_OQ_RESP_HW_SIZE; |
| 395 | 437 | rx_ol_flags = 0; |
| 396 | 438 | } |
| 439 | + | |
| 440 | + octep_oq_next_pkt(oq, buff_info, &read_idx, &desc_used); | |
| 441 | + | |
| 442 | + skb = build_skb((void *)resp_hw, PAGE_SIZE); | |
| 443 | + if (!skb) { | |
| 444 | + octep_oq_drop_rx(oq, buff_info, | |
| 445 | + &read_idx, &desc_used); | |
| 446 | + oq->stats.alloc_failures++; | |
| 447 | + continue; | |
| 448 | + } | |
| 449 | + skb_reserve(skb, data_offset); | |
| 450 | + | |
| 397 | 451 | rx_bytes += buff_info->len; |
| 398 | 452 | |
| 399 | 453 | if (buff_info->len <= oq->max_single_buffer_size) { |
| 400 | − skb = build_skb((void *)resp_hw, PAGE_SIZE); | |
| 401 | − skb_reserve(skb, data_offset); | |
| 402 | 454 | skb_put(skb, buff_info->len); |
| 403 | − read_idx++; | |
| 404 | − desc_used++; | |
| 405 | − if (read_idx == oq->max_count) | |
| 406 | − read_idx = 0; | |
| 407 | 455 | } else { |
| 408 | 456 | struct skb_shared_info *shinfo; |
| 409 | 457 | u16 data_len; |
| 410 | 458 | |
| 411 | − skb = build_skb((void *)resp_hw, PAGE_SIZE); | |
| 412 | − skb_reserve(skb, data_offset); | |
| 413 | 459 | /* Head fragment includes response header(s); |
| 414 | 460 | * subsequent fragments contains only data. |
| 415 | 461 | */ |
| 416 | 462 | skb_put(skb, oq->max_single_buffer_size); |
| 417 | − read_idx++; | |
| 418 | − desc_used++; | |
| 419 | − if (read_idx == oq->max_count) | |
| 420 | − read_idx = 0; | |
| 421 | − | |
| 422 | 463 | shinfo = skb_shinfo(skb); |
| 423 | 464 | data_len = buff_info->len - oq->max_single_buffer_size; |
| 424 | 465 | while (data_len) { |
| 425 | − dma_unmap_page(oq->dev, oq->desc_ring[read_idx].buffer_ptr, | |
| 426 | − PAGE_SIZE, DMA_FROM_DEVICE); | |
| 427 | 466 | buff_info = (struct octep_rx_buffer *) |
| 428 | 467 | &oq->buff_info[read_idx]; |
| 429 | 468 | if (data_len < oq->buffer_size) { |
| @@ -438,11 +477,8 @@ static int __octep_oq_process_rx(struct octep_device *oct, · 8 unmodified lines | ||
| 438 | 477 | buff_info->page, 0, |
| 439 | 478 | buff_info->len, |
| 440 | 479 | buff_info->len); |
| 441 | − buff_info->page = NULL; | |
| 442 | − read_idx++; | |
| 443 | − desc_used++; | |
| 444 | − if (read_idx == oq->max_count) | |
| 445 | − read_idx = 0; | |
| 480 | + | |
| 481 | + octep_oq_next_pkt(oq, buff_info, &read_idx, &desc_used); | |
| 446 | 482 | } |
| 447 | 483 | } |
| 448 | 484 | |
| @@ -2411,7 +2411,7 @@ static int nix_smq_flush(struct rvu *rvu, int blkaddr, · 2410 unmodified lines | ||
| 2411 | 2411 | NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link)); |
| 2412 | 2412 | if (!(cfg & BIT_ULL(12))) |
| 2413 | 2413 | continue; |
| 2414 | − bmap |= (1 << i); | |
| 2414 | + bmap |= BIT_ULL(i); | |
| 2415 | 2415 | cfg &= ~BIT_ULL(12); |
| 2416 | 2416 | rvu_write64(rvu, blkaddr, |
| 2417 | 2417 | NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link), cfg); |
| @@ -2432,7 +2432,7 @@ static int nix_smq_flush(struct rvu *rvu, int blkaddr, · 14 unmodified lines | ||
| 2432 | 2432 | |
| 2433 | 2433 | /* Set NIX_AF_TL3_TL2_LINKX_CFG[ENA] for the TL3/TL2 queue */ |
| 2434 | 2434 | for (i = 0; i < (rvu->hw->cgx_links + rvu->hw->lbk_links); i++) { |
| 2435 | − if (!(bmap & (1 << i))) | |
| 2435 | + if (!(bmap & BIT_ULL(i))) | |
| 2436 | 2436 | continue; |
| 2437 | 2437 | cfg = rvu_read64(rvu, blkaddr, |
| 2438 | 2438 | NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link)); |
| @@ -2471,10 +2471,6 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, · 2470 unmodified lines | ||
| 2471 | 2471 | e->dma_addr = addr; |
| 2472 | 2472 | e->dma_len = len; |
| 2473 | 2473 | |
| 2474 | − airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), | |
| 2475 | − TX_RING_CPU_IDX_MASK, | |
| 2476 | − FIELD_PREP(TX_RING_CPU_IDX_MASK, index)); | |
| 2477 | − | |
| 2478 | 2474 | data = skb_frag_address(frag); |
| 2479 | 2475 | len = skb_frag_size(frag); |
| 2480 | 2476 | } |
| @@ -2483,6 +2479,11 @@ static netdev_tx_t airoha_dev_xmit(struct sk_buff *skb, · 2 unmodified lines | ||
| 2483 | 2479 | q->queued += i; |
| 2484 | 2480 | |
| 2485 | 2481 | skb_tx_timestamp(skb); |
| 2482 | + if (!netdev_xmit_more()) | |
| 2483 | + airoha_qdma_rmw(qdma, REG_TX_CPU_IDX(qid), | |
| 2484 | + TX_RING_CPU_IDX_MASK, | |
| 2485 | + FIELD_PREP(TX_RING_CPU_IDX_MASK, q->head)); | |
| 2486 | + | |
| 2486 | 2487 | if (q->ndesc - q->queued < q->free_thr) |
| 2487 | 2488 | netif_tx_stop_queue(txq); |
| 2488 | 2489 | |
| @@ -1171,7 +1171,7 @@ static int mtk_init_fq_dma(struct mtk_eth *eth) · 1170 unmodified lines | ||
| 1171 | 1171 | if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) |
| 1172 | 1172 | return -ENOMEM; |
| 1173 | 1173 | |
| 1174 | − for (i = 0; i < cnt; i++) { | |
| 1174 | + for (i = 0; i < len; i++) { | |
| 1175 | 1175 | struct mtk_tx_dma_v2 *txd; |
| 1176 | 1176 | |
| 1177 | 1177 | txd = eth->scratch_ring + (j * MTK_FQ_DMA_LENGTH + i) * soc->tx.desc_size; |
| @@ -91,8 +91,8 @@ enum mtk_wed_dummy_cr_idx { · 90 unmodified lines | ||
| 91 | 91 | #define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin" |
| 92 | 92 | #define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin" |
| 93 | 93 | #define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin" |
| 94 | −#define MT7988_FIRMWARE_WO0 "mediatek/mt7988_wo_0.bin" | |
| 95 | −#define MT7988_FIRMWARE_WO1 "mediatek/mt7988_wo_1.bin" | |
| 94 | +#define MT7988_FIRMWARE_WO0 "mediatek/mt7988/mt7988_wo_0.bin" | |
| 95 | +#define MT7988_FIRMWARE_WO1 "mediatek/mt7988/mt7988_wo_1.bin" | |
| 96 | 96 | |
| 97 | 97 | #define MTK_WO_MCU_CFG_LS_BASE 0 |
| 98 | 98 | #define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000) |
| @@ -1765,6 +1765,10 @@ static void mlx5_cmd_comp_handler(struct mlx5_core_dev *dev, u64 vec, bool force · 1764 unmodified lines | ||
| 1765 | 1765 | } |
| 1766 | 1766 | } |
| 1767 | 1767 | |
| 1768 | +#define MLX5_MAX_MANAGE_PAGES_CMD_ENT 1 | |
| 1769 | +#define MLX5_CMD_MASK ((1UL << (cmd->vars.max_reg_cmds + \ | |
| 1770 | + MLX5_MAX_MANAGE_PAGES_CMD_ENT)) - 1) | |
| 1771 | + | |
| 1768 | 1772 | static void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev) |
| 1769 | 1773 | { |
| 1770 | 1774 | struct mlx5_cmd *cmd = &dev->cmd; |
| @@ -1776,7 +1780,7 @@ static void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev) · 5 unmodified lines | ||
| 1776 | 1780 | /* wait for pending handlers to complete */ |
| 1777 | 1781 | mlx5_eq_synchronize_cmd_irq(dev); |
| 1778 | 1782 | spin_lock_irqsave(&dev->cmd.alloc_lock, flags); |
| 1779 | − vector = ~dev->cmd.vars.bitmask & ((1ul << (1 << dev->cmd.vars.log_sz)) - 1); | |
| 1783 | + vector = ~dev->cmd.vars.bitmask & MLX5_CMD_MASK; | |
| 1780 | 1784 | if (!vector) |
| 1781 | 1785 | goto no_trig; |
| 1782 | 1786 | |
| @@ -2361,7 +2365,7 @@ int mlx5_cmd_enable(struct mlx5_core_dev *dev) · 578 unmodified lines | ||
| 2361 | 2365 | |
| 2362 | 2366 | cmd->state = MLX5_CMDIF_STATE_DOWN; |
| 2363 | 2367 | cmd->vars.max_reg_cmds = (1 << cmd->vars.log_sz) - 1; |
| 2364 | − cmd->vars.bitmask = (1UL << cmd->vars.max_reg_cmds) - 1; | |
| 2368 | + cmd->vars.bitmask = MLX5_CMD_MASK; | |
| 2365 | 2369 | |
| 2366 | 2370 | sema_init(&cmd->vars.sem, cmd->vars.max_reg_cmds); |
| 2367 | 2371 | sema_init(&cmd->vars.pages_sem, 1); |
| @@ -6509,7 +6509,9 @@ static void _mlx5e_remove(struct auxiliary_device *adev) · 6508 unmodified lines | ||
| 6509 | 6509 | mlx5e_dcbnl_delete_app(priv); |
| 6510 | 6510 | unregister_netdev(priv->netdev); |
| 6511 | 6511 | _mlx5e_suspend(adev, false); |
| 6512 | − priv->profile->cleanup(priv); | |
| 6512 | + /* Avoid cleanup if profile rollback failed. */ | |
| 6513 | + if (priv->profile) | |
| 6514 | + priv->profile->cleanup(priv); | |
| 6513 | 6515 | mlx5e_destroy_netdev(priv); |
| 6514 | 6516 | mlx5e_devlink_port_unregister(mlx5e_dev); |
| 6515 | 6517 | mlx5e_destroy_devlink(mlx5e_dev); |
| @@ -1061,6 +1061,12 @@ int mlx5_comp_eqn_get(struct mlx5_core_dev *dev, u16 vecidx, int *eqn) · 1060 unmodified lines | ||
| 1061 | 1061 | struct mlx5_eq_comp *eq; |
| 1062 | 1062 | int ret = 0; |
| 1063 | 1063 | |
| 1064 | + if (vecidx >= table->max_comp_eqs) { | |
| 1065 | + mlx5_core_dbg(dev, "Requested vector index %u should be less than %u", | |
| 1066 | + vecidx, table->max_comp_eqs); | |
| 1067 | + return -EINVAL; | |
| 1068 | + } | |
| 1069 | + | |
| 1064 | 1070 | mutex_lock(&table->comp_lock); |
| 1065 | 1071 | eq = xa_load(&table->comp_eqs, vecidx); |
| 1066 | 1072 | if (eq) { |
| @@ -1489,7 +1489,7 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int num_vfs) · 1488 unmodified lines | ||
| 1489 | 1489 | } |
| 1490 | 1490 | |
| 1491 | 1491 | if (err) |
| 1492 | − goto abort; | |
| 1492 | + goto err_esw_enable; | |
| 1493 | 1493 | |
| 1494 | 1494 | esw->fdb_table.flags |= MLX5_ESW_FDB_CREATED; |
| 1495 | 1495 | |
| @@ -1503,7 +1503,8 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int num_vfs) · 7 unmodified lines | ||
| 1503 | 1503 | |
| 1504 | 1504 | return 0; |
| 1505 | 1505 | |
| 1506 | −abort: | |
| 1506 | +err_esw_enable: | |
| 1507 | + mlx5_eq_notifier_unregister(esw->dev, &esw->nb); | |
| 1507 | 1508 | mlx5_esw_acls_ns_cleanup(esw); |
| 1508 | 1509 | return err; |
| 1509 | 1510 | } |
| @@ -691,7 +691,6 @@ static int hws_bwc_matcher_move(struct mlx5hws_bwc_matcher *bwc_matcher) · 690 unmodified lines | ||
| 691 | 691 | static int |
| 692 | 692 | hws_bwc_matcher_rehash_size(struct mlx5hws_bwc_matcher *bwc_matcher) |
| 693 | 693 | { |
| 694 | − u32 num_of_rules; | |
| 695 | 694 | int ret; |
| 696 | 695 | |
| 697 | 696 | /* If the current matcher size is already at its max size, we can't |
| @@ -705,8 +704,7 @@ hws_bwc_matcher_rehash_size(struct mlx5hws_bwc_matcher *bwc_matcher) · 7 unmodified lines | ||
| 705 | 704 | * Need to check again if we really need rehash. |
| 706 | 705 | * If the reason for rehash was size, but not any more - skip rehash. |
| 707 | 706 | */ |
| 708 | − num_of_rules = __atomic_load_n(&bwc_matcher->num_of_rules, __ATOMIC_RELAXED); | |
| 709 | − if (!hws_bwc_matcher_rehash_size_needed(bwc_matcher, num_of_rules)) | |
| 707 | + if (!hws_bwc_matcher_rehash_size_needed(bwc_matcher, bwc_matcher->num_of_rules)) | |
| 710 | 708 | return 0; |
| 711 | 709 | |
| 712 | 710 | /* Now we're done all the checking - do the rehash: |
| @@ -46,6 +46,7 @@ struct mlx5hws_context { · 45 unmodified lines | ||
| 46 | 46 | struct mlx5hws_send_engine *send_queue; |
| 47 | 47 | size_t queues; |
| 48 | 48 | struct mutex *bwc_send_queue_locks; /* protect BWC queues */ |
| 49 | + struct lock_class_key *bwc_lock_class_keys; | |
| 49 | 50 | struct list_head tbl_list; |
| 50 | 51 | struct mlx5hws_context_debug_info debug_info; |
| 51 | 52 | struct xarray peer_ctx_xa; |
| @@ -1925,7 +1925,7 @@ mlx5hws_definer_calc_layout(struct mlx5hws_context *ctx, · 1924 unmodified lines | ||
| 1925 | 1925 | ret = hws_definer_conv_match_params_to_hl(ctx, mt, match_hl); |
| 1926 | 1926 | if (ret) { |
| 1927 | 1927 | mlx5hws_err(ctx, "Failed to convert items to header layout\n"); |
| 1928 | − goto free_fc; | |
| 1928 | + goto free_match_hl; | |
| 1929 | 1929 | } |
| 1930 | 1930 | |
| 1931 | 1931 | /* Find the match definer layout for header layout match union */ |
| @@ -1946,7 +1946,7 @@ mlx5hws_definer_calc_layout(struct mlx5hws_context *ctx, · 14 unmodified lines | ||
| 1946 | 1946 | |
| 1947 | 1947 | free_fc: |
| 1948 | 1948 | kfree(mt->fc); |
| 1949 | − | |
| 1949 | +free_match_hl: | |
| 1950 | 1950 | kfree(match_hl); |
| 1951 | 1951 | return ret; |
| 1952 | 1952 | } |
| @@ -941,14 +941,18 @@ static void __hws_send_queues_close(struct mlx5hws_context *ctx, u16 queues) · 940 unmodified lines | ||
| 941 | 941 | |
| 942 | 942 | static void hws_send_queues_bwc_locks_destroy(struct mlx5hws_context *ctx) |
| 943 | 943 | { |
| 944 | − int bwc_queues = ctx->queues - 1; | |
| 944 | + int bwc_queues = mlx5hws_bwc_queues(ctx); | |
| 945 | 945 | int i; |
| 946 | 946 | |
| 947 | 947 | if (!mlx5hws_context_bwc_supported(ctx)) |
| 948 | 948 | return; |
| 949 | 949 | |
| 950 | − for (i = 0; i < bwc_queues; i++) | |
| 950 | + for (i = 0; i < bwc_queues; i++) { | |
| 951 | 951 | mutex_destroy(&ctx->bwc_send_queue_locks[i]); |
| 952 | + lockdep_unregister_key(ctx->bwc_lock_class_keys + i); | |
| 953 | + } | |
| 954 | + | |
| 955 | + kfree(ctx->bwc_lock_class_keys); | |
| 952 | 956 | kfree(ctx->bwc_send_queue_locks); |
| 953 | 957 | } |
| 954 | 958 | |
| @@ -977,10 +981,22 @@ static int hws_bwc_send_queues_init(struct mlx5hws_context *ctx) · 22 unmodified lines | ||
| 977 | 981 | if (!ctx->bwc_send_queue_locks) |
| 978 | 982 | return -ENOMEM; |
| 979 | 983 | |
| 980 | − for (i = 0; i < bwc_queues; i++) | |
| 984 | + ctx->bwc_lock_class_keys = kcalloc(bwc_queues, | |
| 985 | + sizeof(*ctx->bwc_lock_class_keys), | |
| 986 | + GFP_KERNEL); | |
| 987 | + if (!ctx->bwc_lock_class_keys) | |
| 988 | + goto err_lock_class_keys; | |
| 989 | + | |
| 990 | + for (i = 0; i < bwc_queues; i++) { | |
| 981 | 991 | mutex_init(&ctx->bwc_send_queue_locks[i]); |
| 992 | + lockdep_register_key(ctx->bwc_lock_class_keys + i); | |
| 993 | + } | |
| 982 | 994 | |
| 983 | 995 | return 0; |
| 996 | + | |
| 997 | +err_lock_class_keys: | |
| 998 | + kfree(ctx->bwc_send_queue_locks); | |
| 999 | + return -ENOMEM; | |
| 984 | 1000 | } |
| 985 | 1001 | |
| 986 | 1002 | int mlx5hws_send_queues_open(struct mlx5hws_context *ctx, |
| @@ -389,15 +389,27 @@ static void mlxsw_pci_wqe_frag_unmap(struct mlxsw_pci *mlxsw_pci, char *wqe, · 388 unmodified lines | ||
| 389 | 389 | dma_unmap_single(&pdev->dev, mapaddr, frag_len, direction); |
| 390 | 390 | } |
| 391 | 391 | |
| 392 | −static struct sk_buff *mlxsw_pci_rdq_build_skb(struct page *pages[], | |
| 392 | +static struct sk_buff *mlxsw_pci_rdq_build_skb(struct mlxsw_pci_queue *q, | |
| 393 | + struct page *pages[], | |
| 393 | 394 | u16 byte_count) |
| 394 | 395 | { |
| 396 | + struct mlxsw_pci_queue *cq = q->u.rdq.cq; | |
| 395 | 397 | unsigned int linear_data_size; |
| 398 | + struct page_pool *page_pool; | |
| 396 | 399 | struct sk_buff *skb; |
| 397 | 400 | int page_index = 0; |
| 398 | 401 | bool linear_only; |
| 399 | 402 | void *data; |
| 400 | 403 | |
| 404 | + linear_only = byte_count + MLXSW_PCI_RX_BUF_SW_OVERHEAD <= PAGE_SIZE; | |
| 405 | + linear_data_size = linear_only ? byte_count : | |
| 406 | + PAGE_SIZE - | |
| 407 | + MLXSW_PCI_RX_BUF_SW_OVERHEAD; | |
| 408 | + | |
| 409 | + page_pool = cq->u.cq.page_pool; | |
| 410 | + page_pool_dma_sync_for_cpu(page_pool, pages[page_index], | |
| 411 | + MLXSW_PCI_SKB_HEADROOM, linear_data_size); | |
| 412 | + | |
| 401 | 413 | data = page_address(pages[page_index]); |
| 402 | 414 | net_prefetch(data); |
| 403 | 415 | |
| @@ -405,11 +417,6 @@ static struct sk_buff *mlxsw_pci_rdq_build_skb(struct page *pages[], · 1 unmodified line | ||
| 405 | 417 | if (unlikely(!skb)) |
| 406 | 418 | return ERR_PTR(-ENOMEM); |
| 407 | 419 | |
| 408 | − linear_only = byte_count + MLXSW_PCI_RX_BUF_SW_OVERHEAD <= PAGE_SIZE; | |
| 409 | − linear_data_size = linear_only ? byte_count : | |
| 410 | − PAGE_SIZE - | |
| 411 | − MLXSW_PCI_RX_BUF_SW_OVERHEAD; | |
| 412 | − | |
| 413 | 420 | skb_reserve(skb, MLXSW_PCI_SKB_HEADROOM); |
| 414 | 421 | skb_put(skb, linear_data_size); |
| 415 | 422 | |
| @@ -425,6 +432,7 @@ static struct sk_buff *mlxsw_pci_rdq_build_skb(struct page *pages[], · 9 unmodified lines | ||
| 425 | 432 | |
| 426 | 433 | page = pages[page_index]; |
| 427 | 434 | frag_size = min(byte_count, PAGE_SIZE); |
| 435 | + page_pool_dma_sync_for_cpu(page_pool, page, 0, frag_size); | |
| 428 | 436 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, |
| 429 | 437 | page, 0, frag_size, PAGE_SIZE); |
| 430 | 438 | byte_count -= frag_size; |
| @@ -760,7 +768,7 @@ static void mlxsw_pci_cqe_rdq_handle(struct mlxsw_pci *mlxsw_pci, · 329 unmodified lines | ||
| 760 | 768 | if (err) |
| 761 | 769 | goto out; |
| 762 | 770 | |
| 763 | − skb = mlxsw_pci_rdq_build_skb(pages, byte_count); | |
| 771 | + skb = mlxsw_pci_rdq_build_skb(q, pages, byte_count); | |
| 764 | 772 | if (IS_ERR(skb)) { |
| 765 | 773 | dev_err_ratelimited(&pdev->dev, "Failed to build skb for RDQ\n"); |
| 766 | 774 | mlxsw_pci_rdq_pages_recycle(q, pages, num_sg_entries); |
| @@ -988,12 +996,13 @@ static int mlxsw_pci_cq_page_pool_init(struct mlxsw_pci_queue *q, · 221 unmodified lines | ||
| 988 | 996 | if (cq_type != MLXSW_PCI_CQ_RDQ) |
| 989 | 997 | return 0; |
| 990 | 998 | |
| 991 | − pp_params.flags = PP_FLAG_DMA_MAP; | |
| 999 | + pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV; | |
| 992 | 1000 | pp_params.pool_size = MLXSW_PCI_WQE_COUNT * mlxsw_pci->num_sg_entries; |
| 993 | 1001 | pp_params.nid = dev_to_node(&mlxsw_pci->pdev->dev); |
| 994 | 1002 | pp_params.dev = &mlxsw_pci->pdev->dev; |
| 995 | 1003 | pp_params.napi = &q->u.cq.napi; |
| 996 | 1004 | pp_params.dma_dir = DMA_FROM_DEVICE; |
| 1005 | + pp_params.max_len = PAGE_SIZE; | |
| 997 | 1006 | |
| 998 | 1007 | page_pool = page_pool_create(&pp_params); |
| 999 | 1008 | if (IS_ERR(page_pool)) |
| @@ -481,11 +481,33 @@ mlxsw_sp_ipip_ol_netdev_change_gre6(struct mlxsw_sp *mlxsw_sp, · 480 unmodified lines | ||
| 481 | 481 | struct mlxsw_sp_ipip_entry *ipip_entry, |
| 482 | 482 | struct netlink_ext_ack *extack) |
| 483 | 483 | { |
| 484 | + u32 new_kvdl_index, old_kvdl_index = ipip_entry->dip_kvdl_index; | |
| 485 | + struct in6_addr old_addr6 = ipip_entry->parms.daddr.addr6; | |
| 484 | 486 | struct mlxsw_sp_ipip_parms new_parms; |
| 487 | + int err; | |
| 485 | 488 | |
| 486 | 489 | new_parms = mlxsw_sp_ipip_netdev_parms_init_gre6(ipip_entry->ol_dev); |
| 487 | − return mlxsw_sp_ipip_ol_netdev_change_gre(mlxsw_sp, ipip_entry, | |
| 488 | − &new_parms, extack); | |
| 490 | + | |
| 491 | + err = mlxsw_sp_ipv6_addr_kvdl_index_get(mlxsw_sp, | |
| 492 | + &new_parms.daddr.addr6, | |
| 493 | + &new_kvdl_index); | |
| 494 | + if (err) | |
| 495 | + return err; | |
| 496 | + ipip_entry->dip_kvdl_index = new_kvdl_index; | |
| 497 | + | |
| 498 | + err = mlxsw_sp_ipip_ol_netdev_change_gre(mlxsw_sp, ipip_entry, | |
| 499 | + &new_parms, extack); | |
| 500 | + if (err) | |
| 501 | + goto err_change_gre; | |
| 502 | + | |
| 503 | + mlxsw_sp_ipv6_addr_put(mlxsw_sp, &old_addr6); | |
| 504 | + | |
| 505 | + return 0; | |
| 506 | + | |
| 507 | +err_change_gre: | |
| 508 | + ipip_entry->dip_kvdl_index = old_kvdl_index; | |
| 509 | + mlxsw_sp_ipv6_addr_put(mlxsw_sp, &new_parms.daddr.addr6); | |
| 510 | + return err; | |
| 489 | 511 | } |
| 490 | 512 | |
| 491 | 513 | static int |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | ||
| 16 | 16 | #include "spectrum.h" |
| 17 | 17 | #include "spectrum_ptp.h" |
| 18 | 18 | #include "core.h" |
| 19 | +#include "txheader.h" | |
| 19 | 20 | |
| 20 | 21 | #define MLXSW_SP1_PTP_CLOCK_CYCLES_SHIFT 29 |
| 21 | 22 | #define MLXSW_SP1_PTP_CLOCK_FREQ_KHZ 156257 /* 6.4nSec */ |
| @@ -1684,6 +1685,12 @@ int mlxsw_sp_ptp_txhdr_construct(struct mlxsw_core *mlxsw_core, · 1662 unmodified lines | ||
| 1684 | 1685 | struct sk_buff *skb, |
| 1685 | 1686 | const struct mlxsw_tx_info *tx_info) |
| 1686 | 1687 | { |
| 1688 | + if (skb_cow_head(skb, MLXSW_TXHDR_LEN)) { | |
| 1689 | + this_cpu_inc(mlxsw_sp_port->pcpu_stats->tx_dropped); | |
| 1690 | + dev_kfree_skb_any(skb); | |
| 1691 | + return -ENOMEM; | |
| 1692 | + } | |
| 1693 | + | |
| 1687 | 1694 | mlxsw_sp_txhdr_construct(skb, tx_info); |
| 1688 | 1695 | return 0; |
| 1689 | 1696 | } |
| @@ -3197,7 +3197,6 @@ mlxsw_sp_nexthop_sh_counter_get(struct mlxsw_sp *mlxsw_sp, · 3196 unmodified lines | ||
| 3197 | 3197 | { |
| 3198 | 3198 | struct mlxsw_sp_nexthop_group *nh_grp = nh->nhgi->nh_grp; |
| 3199 | 3199 | struct mlxsw_sp_nexthop_counter *nhct; |
| 3200 | − void *ptr; | |
| 3201 | 3200 | int err; |
| 3202 | 3201 | |
| 3203 | 3202 | nhct = xa_load(&nh_grp->nhgi->nexthop_counters, nh->id); |
| @@ -3210,12 +3209,10 @@ mlxsw_sp_nexthop_sh_counter_get(struct mlxsw_sp *mlxsw_sp, · 6 unmodified lines | ||
| 3210 | 3209 | if (IS_ERR(nhct)) |
| 3211 | 3210 | return nhct; |
| 3212 | 3211 | |
| 3213 | − ptr = xa_store(&nh_grp->nhgi->nexthop_counters, nh->id, nhct, | |
| 3214 | − GFP_KERNEL); | |
| 3215 | − if (IS_ERR(ptr)) { | |
| 3216 | − err = PTR_ERR(ptr); | |
| 3212 | + err = xa_err(xa_store(&nh_grp->nhgi->nexthop_counters, nh->id, nhct, | |
| 3213 | + GFP_KERNEL)); | |
| 3214 | + if (err) | |
| 3217 | 3215 | goto err_store; |
| 3218 | − } | |
| 3219 | 3216 | |
| 3220 | 3217 | return nhct; |
| 3221 | 3218 | |
| @@ -401,28 +401,21 @@ static int lan743x_ptpci_settime64(struct ptp_clock_info *ptpci, · 400 unmodified lines | ||
| 401 | 401 | u32 nano_seconds = 0; |
| 402 | 402 | u32 seconds = 0; |
| 403 | 403 | |
| 404 | − if (ts) { | |
| 405 | − if (ts->tv_sec > 0xFFFFFFFFLL || | |
| 406 | − ts->tv_sec < 0) { | |
| 407 | − netif_warn(adapter, drv, adapter->netdev, | |
| 408 | − "ts->tv_sec out of range, %lld\n", | |
| 409 | − ts->tv_sec); | |
| 410 | − return -ERANGE; | |
| 411 | − } | |
| 412 | − if (ts->tv_nsec >= 1000000000L || | |
| 413 | − ts->tv_nsec < 0) { | |
| 414 | − netif_warn(adapter, drv, adapter->netdev, | |
| 415 | − "ts->tv_nsec out of range, %ld\n", | |
| 416 | − ts->tv_nsec); | |
| 417 | − return -ERANGE; | |
| 418 | − } | |
| 419 | − seconds = ts->tv_sec; | |
| 420 | − nano_seconds = ts->tv_nsec; | |
| 421 | − lan743x_ptp_clock_set(adapter, seconds, nano_seconds, 0); | |
| 422 | − } else { | |
| 423 | − netif_warn(adapter, drv, adapter->netdev, "ts == NULL\n"); | |
| 424 | − return -EINVAL; | |
| 404 | + if (ts->tv_sec > 0xFFFFFFFFLL) { | |
| 405 | + netif_warn(adapter, drv, adapter->netdev, | |
| 406 | + "ts->tv_sec out of range, %lld\n", | |
| 407 | + ts->tv_sec); | |
| 408 | + return -ERANGE; | |
| 409 | + } | |
| 410 | + if (ts->tv_nsec < 0) { | |
| 411 | + netif_warn(adapter, drv, adapter->netdev, | |
| 412 | + "ts->tv_nsec out of range, %ld\n", | |
| 413 | + ts->tv_nsec); | |
| 414 | + return -ERANGE; | |
| 425 | 415 | } |
| 416 | + seconds = ts->tv_sec; | |
| 417 | + nano_seconds = ts->tv_nsec; | |
| 418 | + lan743x_ptp_clock_set(adapter, seconds, nano_seconds, 0); | |
| 426 | 419 | |
| 427 | 420 | return 0; |
| 428 | 421 | } |
| @@ -31,10 +31,10 @@ static u64 sparx5_mirror_port_get(struct sparx5 *sparx5, u32 idx) · 30 unmodified lines | ||
| 31 | 31 | /* Add port to mirror (only front ports) */ |
| 32 | 32 | static void sparx5_mirror_port_add(struct sparx5 *sparx5, u32 idx, u32 portno) |
| 33 | 33 | { |
| 34 | − u32 val, reg = portno; | |
| 34 | + u64 reg = portno; | |
| 35 | + u32 val; | |
| 35 | 36 | |
| 36 | − reg = portno / BITS_PER_BYTE; | |
| 37 | − val = BIT(portno % BITS_PER_BYTE); | |
| 37 | + val = BIT(do_div(reg, 32)); | |
| 38 | 38 | |
| 39 | 39 | if (reg == 0) |
| 40 | 40 | return spx5_rmw(val, val, sparx5, ANA_AC_PROBE_PORT_CFG(idx)); |
| @@ -45,10 +45,10 @@ static void sparx5_mirror_port_add(struct sparx5 *sparx5, u32 idx, u32 portno) · 4 unmodified lines | ||
| 45 | 45 | /* Delete port from mirror (only front ports) */ |
| 46 | 46 | static void sparx5_mirror_port_del(struct sparx5 *sparx5, u32 idx, u32 portno) |
| 47 | 47 | { |
| 48 | − u32 val, reg = portno; | |
| 48 | + u64 reg = portno; | |
| 49 | + u32 val; | |
| 49 | 50 | |
| 50 | − reg = portno / BITS_PER_BYTE; | |
| 51 | − val = BIT(portno % BITS_PER_BYTE); | |
| 51 | + val = BIT(do_div(reg, 32)); | |
| 52 | 52 | |
| 53 | 53 | if (reg == 0) |
| 54 | 54 | return spx5_rmw(0, val, sparx5, ANA_AC_PROBE_PORT_CFG(idx)); |
| @@ -1444,6 +1444,8 @@ static void vcap_api_encode_rule_test(struct kunit *test) · 1443 unmodified lines | ||
| 1444 | 1444 | |
| 1445 | 1445 | ret = vcap_del_rule(&test_vctrl, &test_netdev, id); |
| 1446 | 1446 | KUNIT_EXPECT_EQ(test, 0, ret); |
| 1447 | + | |
| 1448 | + vcap_free_rule(rule); | |
| 1447 | 1449 | } |
| 1448 | 1450 | |
| 1449 | 1451 | static void vcap_api_set_rule_counter_test(struct kunit *test) |
| @@ -4682,7 +4682,9 @@ static irqreturn_t rtl8169_interrupt(int irq, void *dev_instance) · 4681 unmodified lines | ||
| 4682 | 4682 | if ((status & 0xffff) == 0xffff || !(status & tp->irq_mask)) |
| 4683 | 4683 | return IRQ_NONE; |
| 4684 | 4684 | |
| 4685 | − if (unlikely(status & SYSErr)) { | |
| 4685 | + /* At least RTL8168fp may unexpectedly set the SYSErr bit */ | |
| 4686 | + if (unlikely(status & SYSErr && | |
| 4687 | + tp->mac_version <= RTL_GIGA_MAC_VER_06)) { | |
| 4686 | 4688 | rtl8169_pcierr_interrupt(tp->dev); |
| 4687 | 4689 | goto out; |
| 4688 | 4690 | } |
| @@ -1750,20 +1750,19 @@ static int ravb_get_ts_info(struct net_device *ndev, · 1749 unmodified lines | ||
| 1750 | 1750 | struct ravb_private *priv = netdev_priv(ndev); |
| 1751 | 1751 | const struct ravb_hw_info *hw_info = priv->info; |
| 1752 | 1752 | |
| 1753 | − info->so_timestamping = | |
| 1754 | − SOF_TIMESTAMPING_TX_SOFTWARE | | |
| 1755 | − SOF_TIMESTAMPING_TX_HARDWARE | | |
| 1756 | − SOF_TIMESTAMPING_RX_HARDWARE | | |
| 1757 | − SOF_TIMESTAMPING_RAW_HARDWARE; | |
| 1758 | − info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON); | |
| 1759 | − info->rx_filters = | |
| 1760 | − (1 << HWTSTAMP_FILTER_NONE) | | |
| 1761 | − (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | | |
| 1762 | − (1 << HWTSTAMP_FILTER_ALL); | |
| 1763 | − if (hw_info->gptp || hw_info->ccc_gac) | |
| 1753 | + if (hw_info->gptp || hw_info->ccc_gac) { | |
| 1754 | + info->so_timestamping = | |
| 1755 | + SOF_TIMESTAMPING_TX_SOFTWARE | | |
| 1756 | + SOF_TIMESTAMPING_TX_HARDWARE | | |
| 1757 | + SOF_TIMESTAMPING_RX_HARDWARE | | |
| 1758 | + SOF_TIMESTAMPING_RAW_HARDWARE; | |
| 1759 | + info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON); | |
| 1760 | + info->rx_filters = | |
| 1761 | + (1 << HWTSTAMP_FILTER_NONE) | | |
| 1762 | + (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | | |
| 1763 | + (1 << HWTSTAMP_FILTER_ALL); | |
| 1764 | 1764 | info->phc_index = ptp_clock_index(priv->ptp.clock); |
| 1765 | − else | |
| 1766 | − info->phc_index = 0; | |
| 1765 | + } | |
| 1767 | 1766 | |
| 1768 | 1767 | return 0; |
| 1769 | 1768 | } |
| @@ -1057,6 +1057,7 @@ static netdev_tx_t rtsn_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 1056 unmodified lines | ||
| 1057 | 1057 | if (skb->len >= TX_DS) { |
| 1058 | 1058 | priv->stats.tx_dropped++; |
| 1059 | 1059 | priv->stats.tx_errors++; |
| 1060 | + dev_kfree_skb_any(skb); | |
| 1060 | 1061 | goto out; |
| 1061 | 1062 | } |
| 1062 | 1063 | |
| @@ -1260,7 +1260,8 @@ static int efx_poll(struct napi_struct *napi, int budget) · 1259 unmodified lines | ||
| 1260 | 1260 | |
| 1261 | 1261 | spent = efx_process_channel(channel, budget); |
| 1262 | 1262 | |
| 1263 | − xdp_do_flush(); | |
| 1263 | + if (budget) | |
| 1264 | + xdp_do_flush(); | |
| 1264 | 1265 | |
| 1265 | 1266 | if (spent < budget) { |
| 1266 | 1267 | if (efx_channel_has_rx_queue(channel) && |
| @@ -1285,7 +1285,8 @@ static int efx_poll(struct napi_struct *napi, int budget) · 1284 unmodified lines | ||
| 1285 | 1285 | |
| 1286 | 1286 | spent = efx_process_channel(channel, budget); |
| 1287 | 1287 | |
| 1288 | − xdp_do_flush(); | |
| 1288 | + if (budget) | |
| 1289 | + xdp_do_flush(); | |
| 1289 | 1290 | |
| 1290 | 1291 | if (spent < budget) { |
| 1291 | 1292 | if (efx_channel_has_rx_queue(channel) && |
| @@ -127,10 +127,12 @@ static int mgbe_uphy_lane_bringup_serdes_up(struct net_device *ndev, void *mgbe_ · 126 unmodified lines | ||
| 127 | 127 | value &= ~XPCS_WRAP_UPHY_RX_CONTROL_AUX_RX_IDDQ; |
| 128 | 128 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 129 | 129 | |
| 130 | + usleep_range(10, 20); /* 50ns min delay needed as per HW design */ | |
| 130 | 131 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 131 | 132 | value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_SLEEP; |
| 132 | 133 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 133 | 134 | |
| 135 | + usleep_range(10, 20); /* 500ns min delay needed as per HW design */ | |
| 134 | 136 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 135 | 137 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CAL_EN; |
| 136 | 138 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| @@ -143,22 +145,30 @@ static int mgbe_uphy_lane_bringup_serdes_up(struct net_device *ndev, void *mgbe_ · 6 unmodified lines | ||
| 143 | 145 | return err; |
| 144 | 146 | } |
| 145 | 147 | |
| 148 | + usleep_range(10, 20); /* 50ns min delay needed as per HW design */ | |
| 146 | 149 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 147 | 150 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_DATA_EN; |
| 148 | 151 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 149 | 152 | |
| 150 | 153 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 151 | − value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET; | |
| 154 | + value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_PCS_PHY_RDY; | |
| 152 | 155 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 153 | 156 | |
| 157 | + usleep_range(10, 20); /* 50ns min delay needed as per HW design */ | |
| 154 | 158 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 155 | − value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET; | |
| 159 | + value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET; | |
| 156 | 160 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 157 | 161 | |
| 162 | + usleep_range(10, 20); /* 50ns min delay needed as per HW design */ | |
| 158 | 163 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 159 | 164 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_PCS_PHY_RDY; |
| 160 | 165 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 161 | 166 | |
| 167 | + msleep(30); /* 30ms delay needed as per HW design */ | |
| 168 | + value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | |
| 169 | + value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_CDR_RESET; | |
| 170 | + writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | |
| 171 | + | |
| 162 | 172 | err = readl_poll_timeout(mgbe->xpcs + XPCS_WRAP_IRQ_STATUS, value, |
| 163 | 173 | value & XPCS_WRAP_IRQ_STATUS_PCS_LINK_STS, |
| 164 | 174 | 500, 500 * 2000); |
| @@ -203,8 +203,12 @@ static void _dwmac4_dump_dma_regs(struct stmmac_priv *priv, · 202 unmodified lines | ||
| 203 | 203 | readl(ioaddr + DMA_CHAN_TX_CONTROL(dwmac4_addrs, channel)); |
| 204 | 204 | reg_space[DMA_CHAN_RX_CONTROL(default_addrs, channel) / 4] = |
| 205 | 205 | readl(ioaddr + DMA_CHAN_RX_CONTROL(dwmac4_addrs, channel)); |
| 206 | + reg_space[DMA_CHAN_TX_BASE_ADDR_HI(default_addrs, channel) / 4] = | |
| 207 | + readl(ioaddr + DMA_CHAN_TX_BASE_ADDR_HI(dwmac4_addrs, channel)); | |
| 206 | 208 | reg_space[DMA_CHAN_TX_BASE_ADDR(default_addrs, channel) / 4] = |
| 207 | 209 | readl(ioaddr + DMA_CHAN_TX_BASE_ADDR(dwmac4_addrs, channel)); |
| 210 | + reg_space[DMA_CHAN_RX_BASE_ADDR_HI(default_addrs, channel) / 4] = | |
| 211 | + readl(ioaddr + DMA_CHAN_RX_BASE_ADDR_HI(dwmac4_addrs, channel)); | |
| 208 | 212 | reg_space[DMA_CHAN_RX_BASE_ADDR(default_addrs, channel) / 4] = |
| 209 | 213 | readl(ioaddr + DMA_CHAN_RX_BASE_ADDR(dwmac4_addrs, channel)); |
| 210 | 214 | reg_space[DMA_CHAN_TX_END_ADDR(default_addrs, channel) / 4] = |
| @@ -225,8 +229,12 @@ static void _dwmac4_dump_dma_regs(struct stmmac_priv *priv, · 14 unmodified lines | ||
| 225 | 229 | readl(ioaddr + DMA_CHAN_CUR_TX_DESC(dwmac4_addrs, channel)); |
| 226 | 230 | reg_space[DMA_CHAN_CUR_RX_DESC(default_addrs, channel) / 4] = |
| 227 | 231 | readl(ioaddr + DMA_CHAN_CUR_RX_DESC(dwmac4_addrs, channel)); |
| 232 | + reg_space[DMA_CHAN_CUR_TX_BUF_ADDR_HI(default_addrs, channel) / 4] = | |
| 233 | + readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR_HI(dwmac4_addrs, channel)); | |
| 228 | 234 | reg_space[DMA_CHAN_CUR_TX_BUF_ADDR(default_addrs, channel) / 4] = |
| 229 | 235 | readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR(dwmac4_addrs, channel)); |
| 236 | + reg_space[DMA_CHAN_CUR_RX_BUF_ADDR_HI(default_addrs, channel) / 4] = | |
| 237 | + readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR_HI(dwmac4_addrs, channel)); | |
| 230 | 238 | reg_space[DMA_CHAN_CUR_RX_BUF_ADDR(default_addrs, channel) / 4] = |
| 231 | 239 | readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR(dwmac4_addrs, channel)); |
| 232 | 240 | reg_space[DMA_CHAN_STATUS(default_addrs, channel) / 4] = |
| @@ -127,7 +127,9 @@ static inline u32 dma_chanx_base_addr(const struct dwmac4_addrs *addrs, · 126 unmodified lines | ||
| 127 | 127 | #define DMA_CHAN_SLOT_CTRL_STATUS(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x3c) |
| 128 | 128 | #define DMA_CHAN_CUR_TX_DESC(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x44) |
| 129 | 129 | #define DMA_CHAN_CUR_RX_DESC(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x4c) |
| 130 | +#define DMA_CHAN_CUR_TX_BUF_ADDR_HI(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x50) | |
| 130 | 131 | #define DMA_CHAN_CUR_TX_BUF_ADDR(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x54) |
| 132 | +#define DMA_CHAN_CUR_RX_BUF_ADDR_HI(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x58) | |
| 131 | 133 | #define DMA_CHAN_CUR_RX_BUF_ADDR(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x5c) |
| 132 | 134 | #define DMA_CHAN_STATUS(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x60) |
| 133 | 135 | |
| @@ -2035,7 +2035,7 @@ static int __alloc_dma_rx_desc_resources(struct stmmac_priv *priv, · 2034 unmodified lines | ||
| 2035 | 2035 | rx_q->queue_index = queue; |
| 2036 | 2036 | rx_q->priv_data = priv; |
| 2037 | 2037 | |
| 2038 | − pp_params.flags = PP_FLAG_DMA_MAP | (xdp_prog ? PP_FLAG_DMA_SYNC_DEV : 0); | |
| 2038 | + pp_params.flags = PP_FLAG_DMA_MAP | PP_FLAG_DMA_SYNC_DEV; | |
| 2039 | 2039 | pp_params.pool_size = dma_conf->dma_rx_size; |
| 2040 | 2040 | num_pages = DIV_ROUND_UP(dma_conf->dma_buf_sz, PAGE_SIZE); |
| 2041 | 2041 | pp_params.order = ilog2(num_pages); |
| @@ -4304,11 +4304,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) · 2262 unmodified lines | ||
| 4304 | 4304 | if (dma_mapping_error(priv->device, des)) |
| 4305 | 4305 | goto dma_map_err; |
| 4306 | 4306 | |
| 4307 | − tx_q->tx_skbuff_dma[first_entry].buf = des; | |
| 4308 | − tx_q->tx_skbuff_dma[first_entry].len = skb_headlen(skb); | |
| 4309 | − tx_q->tx_skbuff_dma[first_entry].map_as_page = false; | |
| 4310 | − tx_q->tx_skbuff_dma[first_entry].buf_type = STMMAC_TXBUF_T_SKB; | |
| 4311 | − | |
| 4312 | 4307 | if (priv->dma_cap.addr64 <= 32) { |
| 4313 | 4308 | first->des0 = cpu_to_le32(des); |
| 4314 | 4309 | |
| @@ -4327,6 +4322,23 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev) · 12 unmodified lines | ||
| 4327 | 4322 | |
| 4328 | 4323 | stmmac_tso_allocator(priv, des, tmp_pay_len, (nfrags == 0), queue); |
| 4329 | 4324 | |
| 4325 | + /* In case two or more DMA transmit descriptors are allocated for this | |
| 4326 | + * non-paged SKB data, the DMA buffer address should be saved to | |
| 4327 | + * tx_q->tx_skbuff_dma[].buf corresponding to the last descriptor, | |
| 4328 | + * and leave the other tx_q->tx_skbuff_dma[].buf as NULL to guarantee | |
| 4329 | + * that stmmac_tx_clean() does not unmap the entire DMA buffer too early | |
| 4330 | + * since the tail areas of the DMA buffer can be accessed by DMA engine | |
| 4331 | + * sooner or later. | |
| 4332 | + * By saving the DMA buffer address to tx_q->tx_skbuff_dma[].buf | |
| 4333 | + * corresponding to the last descriptor, stmmac_tx_clean() will unmap | |
| 4334 | + * this DMA buffer right after the DMA engine completely finishes the | |
| 4335 | + * full buffer transmission. | |
| 4336 | + */ | |
| 4337 | + tx_q->tx_skbuff_dma[tx_q->cur_tx].buf = des; | |
| 4338 | + tx_q->tx_skbuff_dma[tx_q->cur_tx].len = skb_headlen(skb); | |
| 4339 | + tx_q->tx_skbuff_dma[tx_q->cur_tx].map_as_page = false; | |
| 4340 | + tx_q->tx_skbuff_dma[tx_q->cur_tx].buf_type = STMMAC_TXBUF_T_SKB; | |
| 4341 | + | |
| 4330 | 4342 | /* Prepare fragments */ |
| 4331 | 4343 | for (i = 0; i < nfrags; i++) { |
| 4332 | 4344 | const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; |
| @@ -2744,10 +2744,9 @@ am65_cpsw_nuss_init_port_ndev(struct am65_cpsw_common *common, u32 port_idx) · 2743 unmodified lines | ||
| 2744 | 2744 | return 0; |
| 2745 | 2745 | |
| 2746 | 2746 | /* alloc netdev */ |
| 2747 | − port->ndev = devm_alloc_etherdev_mqs(common->dev, | |
| 2748 | − sizeof(struct am65_cpsw_ndev_priv), | |
| 2749 | − AM65_CPSW_MAX_QUEUES, | |
| 2750 | − AM65_CPSW_MAX_QUEUES); | |
| 2747 | + port->ndev = alloc_etherdev_mqs(sizeof(struct am65_cpsw_ndev_priv), | |
| 2748 | + AM65_CPSW_MAX_QUEUES, | |
| 2749 | + AM65_CPSW_MAX_QUEUES); | |
| 2751 | 2750 | if (!port->ndev) { |
| 2752 | 2751 | dev_err(dev, "error allocating slave net_device %u\n", |
| 2753 | 2752 | port->port_id); |
| @@ -2868,8 +2867,12 @@ static void am65_cpsw_nuss_cleanup_ndev(struct am65_cpsw_common *common) · 114 unmodified lines | ||
| 2868 | 2867 | |
| 2869 | 2868 | for (i = 0; i < common->port_num; i++) { |
| 2870 | 2869 | port = &common->ports[i]; |
| 2871 | − if (port->ndev && port->ndev->reg_state == NETREG_REGISTERED) | |
| 2870 | + if (!port->ndev) | |
| 2871 | + continue; | |
| 2872 | + if (port->ndev->reg_state == NETREG_REGISTERED) | |
| 2872 | 2873 | unregister_netdev(port->ndev); |
| 2874 | + free_netdev(port->ndev); | |
| 2875 | + port->ndev = NULL; | |
| 2873 | 2876 | } |
| 2874 | 2877 | } |
| 2875 | 2878 | |
| @@ -3613,16 +3616,17 @@ static int am65_cpsw_nuss_probe(struct platform_device *pdev) · 737 unmodified lines | ||
| 3613 | 3616 | |
| 3614 | 3617 | ret = am65_cpsw_nuss_init_ndevs(common); |
| 3615 | 3618 | if (ret) |
| 3616 | − goto err_free_phylink; | |
| 3619 | + goto err_ndevs_clear; | |
| 3617 | 3620 | |
| 3618 | 3621 | ret = am65_cpsw_nuss_register_ndevs(common); |
| 3619 | 3622 | if (ret) |
| 3620 | − goto err_free_phylink; | |
| 3623 | + goto err_ndevs_clear; | |
| 3621 | 3624 | |
| 3622 | 3625 | pm_runtime_put(dev); |
| 3623 | 3626 | return 0; |
| 3624 | 3627 | |
| 3625 | −err_free_phylink: | |
| 3628 | +err_ndevs_clear: | |
| 3629 | + am65_cpsw_nuss_cleanup_ndev(common); | |
| 3626 | 3630 | am65_cpsw_nuss_phylink_cleanup(common); |
| 3627 | 3631 | am65_cpts_release(common->cpts); |
| 3628 | 3632 | err_of_clear: |
| @@ -3652,13 +3656,13 @@ static void am65_cpsw_nuss_remove(struct platform_device *pdev) · 23 unmodified lines | ||
| 3652 | 3656 | return; |
| 3653 | 3657 | } |
| 3654 | 3658 | |
| 3655 | − am65_cpsw_unregister_devlink(common); | |
| 3656 | 3659 | am65_cpsw_unregister_notifiers(common); |
| 3657 | 3660 | |
| 3658 | 3661 | /* must unregister ndevs here because DD release_driver routine calls |
| 3659 | 3662 | * dma_deconfigure(dev) before devres_release_all(dev) |
| 3660 | 3663 | */ |
| 3661 | 3664 | am65_cpsw_nuss_cleanup_ndev(common); |
| 3665 | + am65_cpsw_unregister_devlink(common); | |
| 3662 | 3666 | am65_cpsw_nuss_phylink_cleanup(common); |
| 3663 | 3667 | am65_cpts_release(common->cpts); |
| 3664 | 3668 | am65_cpsw_disable_serdes_phy(common); |
| @@ -735,6 +735,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask, · 734 unmodified lines | ||
| 735 | 735 | u8 fid_c1; |
| 736 | 736 | |
| 737 | 737 | tbl = prueth->vlan_tbl; |
| 738 | + spin_lock(&prueth->vtbl_lock); | |
| 738 | 739 | fid_c1 = tbl[vid].fid_c1; |
| 739 | 740 | |
| 740 | 741 | /* FID_C1: bit0..2 port membership mask, |
| @@ -750,6 +751,7 @@ void icssg_vtbl_modify(struct prueth_emac *emac, u8 vid, u8 port_mask, · 9 unmodified lines | ||
| 750 | 751 | } |
| 751 | 752 | |
| 752 | 753 | tbl[vid].fid_c1 = fid_c1; |
| 754 | + spin_unlock(&prueth->vtbl_lock); | |
| 753 | 755 | } |
| 754 | 756 | EXPORT_SYMBOL_GPL(icssg_vtbl_modify); |
| 755 | 757 | |
| @@ -1442,6 +1442,7 @@ static int prueth_probe(struct platform_device *pdev) · 1441 unmodified lines | ||
| 1442 | 1442 | icss_iep_init_fw(prueth->iep1); |
| 1443 | 1443 | } |
| 1444 | 1444 | |
| 1445 | + spin_lock_init(&prueth->vtbl_lock); | |
| 1445 | 1446 | /* setup netdev interfaces */ |
| 1446 | 1447 | if (eth0_node) { |
| 1447 | 1448 | ret = prueth_netdev_init(prueth, eth0_node); |
| @@ -296,6 +296,8 @@ struct prueth { · 295 unmodified lines | ||
| 296 | 296 | bool is_switchmode_supported; |
| 297 | 297 | unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN]; |
| 298 | 298 | int default_vlan; |
| 299 | + /** @vtbl_lock: Lock for vtbl in shared memory */ | |
| 300 | + spinlock_t vtbl_lock; | |
| 299 | 301 | }; |
| 300 | 302 | |
| 301 | 303 | struct emac_tx_ts_response { |
| @@ -1051,6 +1051,7 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 1050 unmodified lines | ||
| 1051 | 1051 | if (net_ratelimit()) |
| 1052 | 1052 | netdev_err(ndev, "TX DMA mapping error\n"); |
| 1053 | 1053 | ndev->stats.tx_dropped++; |
| 1054 | + dev_kfree_skb_any(skb); | |
| 1054 | 1055 | return NETDEV_TX_OK; |
| 1055 | 1056 | } |
| 1056 | 1057 | desc_set_phys_addr(lp, phys, cur_p); |
| @@ -1071,6 +1072,7 @@ axienet_start_xmit(struct sk_buff *skb, struct net_device *ndev) · 14 unmodified lines | ||
| 1071 | 1072 | ndev->stats.tx_dropped++; |
| 1072 | 1073 | axienet_free_tx_chain(lp, orig_tail_ptr, ii + 1, |
| 1073 | 1074 | true, NULL, 0); |
| 1075 | + dev_kfree_skb_any(skb); | |
| 1074 | 1076 | return NETDEV_TX_OK; |
| 1075 | 1077 | } |
| 1076 | 1078 | desc_set_phys_addr(lp, phys, cur_p); |
| @@ -1702,20 +1702,24 @@ static int gtp_encap_enable(struct gtp_dev *gtp, struct nlattr *data[]) · 1701 unmodified lines | ||
| 1702 | 1702 | return -EINVAL; |
| 1703 | 1703 | |
| 1704 | 1704 | if (data[IFLA_GTP_FD0]) { |
| 1705 | − u32 fd0 = nla_get_u32(data[IFLA_GTP_FD0]); | |
| 1705 | + int fd0 = nla_get_u32(data[IFLA_GTP_FD0]); | |
| 1706 | 1706 | |
| 1707 | − sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp); | |
| 1708 | − if (IS_ERR(sk0)) | |
| 1709 | − return PTR_ERR(sk0); | |
| 1707 | + if (fd0 >= 0) { | |
| 1708 | + sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp); | |
| 1709 | + if (IS_ERR(sk0)) | |
| 1710 | + return PTR_ERR(sk0); | |
| 1711 | + } | |
| 1710 | 1712 | } |
| 1711 | 1713 | |
| 1712 | 1714 | if (data[IFLA_GTP_FD1]) { |
| 1713 | − u32 fd1 = nla_get_u32(data[IFLA_GTP_FD1]); | |
| 1715 | + int fd1 = nla_get_u32(data[IFLA_GTP_FD1]); | |
| 1714 | 1716 | |
| 1715 | − sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp); | |
| 1716 | − if (IS_ERR(sk1u)) { | |
| 1717 | − gtp_encap_disable_sock(sk0); | |
| 1718 | − return PTR_ERR(sk1u); | |
| 1717 | + if (fd1 >= 0) { | |
| 1718 | + sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp); | |
| 1719 | + if (IS_ERR(sk1u)) { | |
| 1720 | + gtp_encap_disable_sock(sk0); | |
| 1721 | + return PTR_ERR(sk1u); | |
| 1722 | + } | |
| 1719 | 1723 | } |
| 1720 | 1724 | } |
| 1721 | 1725 | |
| @@ -2798,6 +2798,31 @@ static struct hv_driver netvsc_drv = { · 2797 unmodified lines | ||
| 2798 | 2798 | }, |
| 2799 | 2799 | }; |
| 2800 | 2800 | |
| 2801 | +/* Set VF's namespace same as the synthetic NIC */ | |
| 2802 | +static void netvsc_event_set_vf_ns(struct net_device *ndev) | |
| 2803 | +{ | |
| 2804 | + struct net_device_context *ndev_ctx = netdev_priv(ndev); | |
| 2805 | + struct net_device *vf_netdev; | |
| 2806 | + int ret; | |
| 2807 | + | |
| 2808 | + vf_netdev = rtnl_dereference(ndev_ctx->vf_netdev); | |
| 2809 | + if (!vf_netdev) | |
| 2810 | + return; | |
| 2811 | + | |
| 2812 | + if (!net_eq(dev_net(ndev), dev_net(vf_netdev))) { | |
| 2813 | + ret = dev_change_net_namespace(vf_netdev, dev_net(ndev), | |
| 2814 | + "eth%d"); | |
| 2815 | + if (ret) | |
| 2816 | + netdev_err(vf_netdev, | |
| 2817 | + "Cannot move to same namespace as %s: %d\n", | |
| 2818 | + ndev->name, ret); | |
| 2819 | + else | |
| 2820 | + netdev_info(vf_netdev, | |
| 2821 | + "Moved VF to namespace with: %s\n", | |
| 2822 | + ndev->name); | |
| 2823 | + } | |
| 2824 | +} | |
| 2825 | + | |
| 2801 | 2826 | /* |
| 2802 | 2827 | * On Hyper-V, every VF interface is matched with a corresponding |
| 2803 | 2828 | * synthetic interface. The synthetic interface is presented first |
| @@ -2810,6 +2835,11 @@ static int netvsc_netdev_event(struct notifier_block *this, · 6 unmodified lines | ||
| 2810 | 2835 | struct net_device *event_dev = netdev_notifier_info_to_dev(ptr); |
| 2811 | 2836 | int ret = 0; |
| 2812 | 2837 | |
| 2838 | + if (event_dev->netdev_ops == &device_ops && event == NETDEV_REGISTER) { | |
| 2839 | + netvsc_event_set_vf_ns(event_dev); | |
| 2840 | + return NOTIFY_DONE; | |
| 2841 | + } | |
| 2842 | + | |
| 2813 | 2843 | ret = check_dev_is_matching_vf(event_dev); |
| 2814 | 2844 | if (ret != 0) |
| 2815 | 2845 | return NOTIFY_DONE; |
| @@ -154,19 +154,6 @@ static struct macsec_rx_sa *macsec_rxsa_get(struct macsec_rx_sa __rcu *ptr) · 153 unmodified lines | ||
| 154 | 154 | return sa; |
| 155 | 155 | } |
| 156 | 156 | |
| 157 | −static struct macsec_rx_sa *macsec_active_rxsa_get(struct macsec_rx_sc *rx_sc) | |
| 158 | −{ | |
| 159 | − struct macsec_rx_sa *sa = NULL; | |
| 160 | − int an; | |
| 161 | − | |
| 162 | − for (an = 0; an < MACSEC_NUM_AN; an++) { | |
| 163 | − sa = macsec_rxsa_get(rx_sc->sa[an]); | |
| 164 | − if (sa) | |
| 165 | − break; | |
| 166 | − } | |
| 167 | − return sa; | |
| 168 | −} | |
| 169 | − | |
| 170 | 157 | static void free_rx_sc_rcu(struct rcu_head *head) |
| 171 | 158 | { |
| 172 | 159 | struct macsec_rx_sc *rx_sc = container_of(head, struct macsec_rx_sc, rcu_head); |
| @@ -1208,15 +1195,12 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) · 1035 unmodified lines | ||
| 1208 | 1195 | /* If validateFrames is Strict or the C bit in the |
| 1209 | 1196 | * SecTAG is set, discard |
| 1210 | 1197 | */ |
| 1211 | − struct macsec_rx_sa *active_rx_sa = macsec_active_rxsa_get(rx_sc); | |
| 1212 | 1198 | if (hdr->tci_an & MACSEC_TCI_C || |
| 1213 | 1199 | secy->validate_frames == MACSEC_VALIDATE_STRICT) { |
| 1214 | 1200 | u64_stats_update_begin(&rxsc_stats->syncp); |
| 1215 | 1201 | rxsc_stats->stats.InPktsNotUsingSA++; |
| 1216 | 1202 | u64_stats_update_end(&rxsc_stats->syncp); |
| 1217 | 1203 | DEV_STATS_INC(secy->netdev, rx_errors); |
| 1218 | − if (active_rx_sa) | |
| 1219 | − this_cpu_inc(active_rx_sa->stats->InPktsNotUsingSA); | |
| 1220 | 1204 | goto drop_nosa; |
| 1221 | 1205 | } |
| 1222 | 1206 | |
| @@ -1226,8 +1210,6 @@ static rx_handler_result_t macsec_handle_frame(struct sk_buff **pskb) · 3 unmodified lines | ||
| 1226 | 1210 | u64_stats_update_begin(&rxsc_stats->syncp); |
| 1227 | 1211 | rxsc_stats->stats.InPktsUnusedSA++; |
| 1228 | 1212 | u64_stats_update_end(&rxsc_stats->syncp); |
| 1229 | − if (active_rx_sa) | |
| 1230 | − this_cpu_inc(active_rx_sa->stats->InPktsUnusedSA); | |
| 1231 | 1213 | goto deliver; |
| 1232 | 1214 | } |
| 1233 | 1215 | |
| @@ -3816,8 +3798,7 @@ static void macsec_free_netdev(struct net_device *dev) · 2582 unmodified lines | ||
| 3816 | 3798 | { |
| 3817 | 3799 | struct macsec_dev *macsec = macsec_priv(dev); |
| 3818 | 3800 | |
| 3819 | − if (macsec->secy.tx_sc.md_dst) | |
| 3820 | − metadata_dst_free(macsec->secy.tx_sc.md_dst); | |
| 3801 | + dst_release(&macsec->secy.tx_sc.md_dst->dst); | |
| 3821 | 3802 | free_percpu(macsec->stats); |
| 3822 | 3803 | free_percpu(macsec->secy.tx_sc.stats); |
| 3823 | 3804 | |
| @@ -588,6 +588,9 @@ static int mctp_i2c_header_create(struct sk_buff *skb, struct net_device *dev, · 587 unmodified lines | ||
| 588 | 588 | if (len > MCTP_I2C_MAXMTU) |
| 589 | 589 | return -EMSGSIZE; |
| 590 | 590 | |
| 591 | + if (!daddr || !saddr) | |
| 592 | + return -EINVAL; | |
| 593 | + | |
| 591 | 594 | lldst = *((u8 *)daddr); |
| 592 | 595 | llsrc = *((u8 *)saddr); |
| 593 | 596 | |
| @@ -337,6 +337,7 @@ static const struct of_device_id unimac_mdio_ids[] = { · 336 unmodified lines | ||
| 337 | 337 | { .compatible = "brcm,asp-v2.2-mdio", }, |
| 338 | 338 | { .compatible = "brcm,asp-v2.1-mdio", }, |
| 339 | 339 | { .compatible = "brcm,asp-v2.0-mdio", }, |
| 340 | + { .compatible = "brcm,bcm6846-mdio", }, | |
| 340 | 341 | { .compatible = "brcm,genet-mdio-v5", }, |
| 341 | 342 | { .compatible = "brcm,genet-mdio-v4", }, |
| 342 | 343 | { .compatible = "brcm,genet-mdio-v3", }, |
| @@ -1161,8 +1161,14 @@ static void send_ext_msg_udp(struct netconsole_target *nt, const char *msg, · 1160 unmodified lines | ||
| 1161 | 1161 | |
| 1162 | 1162 | this_chunk = min(userdata_len - sent_userdata, |
| 1163 | 1163 | MAX_PRINT_CHUNK - preceding_bytes); |
| 1164 | − if (WARN_ON_ONCE(this_chunk <= 0)) | |
| 1164 | + if (WARN_ON_ONCE(this_chunk < 0)) | |
| 1165 | + /* this_chunk could be zero if all the previous | |
| 1166 | + * message used all the buffer. This is not a | |
| 1167 | + * problem, userdata will be sent in the next | |
| 1168 | + * iteration | |
| 1169 | + */ | |
| 1165 | 1170 | return; |
| 1171 | + | |
| 1166 | 1172 | memcpy(buf + this_header + this_offset, |
| 1167 | 1173 | userdata + sent_userdata, |
| 1168 | 1174 | this_chunk); |
| @@ -836,7 +836,8 @@ static void nsim_dev_trap_report_work(struct work_struct *work) · 835 unmodified lines | ||
| 836 | 836 | nsim_dev = nsim_trap_data->nsim_dev; |
| 837 | 837 | |
| 838 | 838 | if (!devl_trylock(priv_to_devlink(nsim_dev))) { |
| 839 | − schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, 1); | |
| 839 | + queue_delayed_work(system_unbound_wq, | |
| 840 | + &nsim_dev->trap_data->trap_report_dw, 1); | |
| 840 | 841 | return; |
| 841 | 842 | } |
| 842 | 843 | |
| @@ -848,11 +849,12 @@ static void nsim_dev_trap_report_work(struct work_struct *work) · 5 unmodified lines | ||
| 848 | 849 | continue; |
| 849 | 850 | |
| 850 | 851 | nsim_dev_trap_report(nsim_dev_port); |
| 852 | + cond_resched(); | |
| 851 | 853 | } |
| 852 | 854 | devl_unlock(priv_to_devlink(nsim_dev)); |
| 853 | − | |
| 854 | − schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, | |
| 855 | − msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); | |
| 855 | + queue_delayed_work(system_unbound_wq, | |
| 856 | + &nsim_dev->trap_data->trap_report_dw, | |
| 857 | + msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); | |
| 856 | 858 | } |
| 857 | 859 | |
| 858 | 860 | static int nsim_dev_traps_init(struct devlink *devlink) |
| @@ -907,8 +909,9 @@ static int nsim_dev_traps_init(struct devlink *devlink) · 48 unmodified lines | ||
| 907 | 909 | |
| 908 | 910 | INIT_DELAYED_WORK(&nsim_dev->trap_data->trap_report_dw, |
| 909 | 911 | nsim_dev_trap_report_work); |
| 910 | − schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, | |
| 911 | − msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); | |
| 912 | + queue_delayed_work(system_unbound_wq, | |
| 913 | + &nsim_dev->trap_data->trap_report_dw, | |
| 914 | + msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); | |
| 912 | 915 | |
| 913 | 916 | return 0; |
| 914 | 917 | |
| @@ -1377,10 +1377,12 @@ static ssize_t nsim_nexthop_bucket_activity_write(struct file *file, · 1376 unmodified lines | ||
| 1377 | 1377 | |
| 1378 | 1378 | if (pos != 0) |
| 1379 | 1379 | return -EINVAL; |
| 1380 | − if (size > sizeof(buf)) | |
| 1380 | + if (size > sizeof(buf) - 1) | |
| 1381 | 1381 | return -EINVAL; |
| 1382 | 1382 | if (copy_from_user(buf, user_buf, size)) |
| 1383 | 1383 | return -EFAULT; |
| 1384 | + buf[size] = 0; | |
| 1385 | + | |
| 1384 | 1386 | if (sscanf(buf, "%u %hu", &nhid, &bucket_index) != 2) |
| 1385 | 1387 | return -EINVAL; |
| 1386 | 1388 | |
| @@ -537,12 +537,6 @@ static int aqcs109_config_init(struct phy_device *phydev) · 536 unmodified lines | ||
| 537 | 537 | if (!ret) |
| 538 | 538 | aqr107_chip_info(phydev); |
| 539 | 539 | |
| 540 | − /* AQCS109 belongs to a chip family partially supporting 10G and 5G. | |
| 541 | − * PMA speed ability bits are the same for all members of the family, | |
| 542 | − * AQCS109 however supports speeds up to 2.5G only. | |
| 543 | − */ | |
| 544 | − phy_set_max_speed(phydev, SPEED_2500); | |
| 545 | − | |
| 546 | 540 | return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT); |
| 547 | 541 | } |
| 548 | 542 | |
| @@ -731,6 +725,31 @@ static int aqr113c_fill_interface_modes(struct phy_device *phydev) · 182 unmodified lines | ||
| 731 | 725 | return aqr107_fill_interface_modes(phydev); |
| 732 | 726 | } |
| 733 | 727 | |
| 728 | +static int aqr115c_get_features(struct phy_device *phydev) | |
| 729 | +{ | |
| 730 | + unsigned long *supported = phydev->supported; | |
| 731 | + | |
| 732 | + /* PHY supports speeds up to 2.5G with autoneg. PMA capabilities | |
| 733 | + * are not useful. | |
| 734 | + */ | |
| 735 | + linkmode_or(supported, supported, phy_gbit_features); | |
| 736 | + linkmode_set_bit(ETHTOOL_LINK_MODE_2500baseT_Full_BIT, supported); | |
| 737 | + | |
| 738 | + return 0; | |
| 739 | +} | |
| 740 | + | |
| 741 | +static int aqr111_get_features(struct phy_device *phydev) | |
| 742 | +{ | |
| 743 | + /* PHY supports speeds up to 5G with autoneg. PMA capabilities | |
| 744 | + * are not useful. | |
| 745 | + */ | |
| 746 | + aqr115c_get_features(phydev); | |
| 747 | + linkmode_set_bit(ETHTOOL_LINK_MODE_5000baseT_Full_BIT, | |
| 748 | + phydev->supported); | |
| 749 | + | |
| 750 | + return 0; | |
| 751 | +} | |
| 752 | + | |
| 734 | 753 | static int aqr113c_config_init(struct phy_device *phydev) |
| 735 | 754 | { |
| 736 | 755 | int ret; |
| @@ -767,15 +786,6 @@ static int aqr107_probe(struct phy_device *phydev) · 30 unmodified lines | ||
| 767 | 786 | return aqr_hwmon_probe(phydev); |
| 768 | 787 | } |
| 769 | 788 | |
| 770 | −static int aqr111_config_init(struct phy_device *phydev) | |
| 771 | −{ | |
| 772 | − /* AQR111 reports supporting speed up to 10G, | |
| 773 | − * however only speeds up to 5G are supported. | |
| 774 | − */ | |
| 775 | − phy_set_max_speed(phydev, SPEED_5000); | |
| 776 | − | |
| 777 | − return aqr107_config_init(phydev); | |
| 778 | −} | |
| 779 | 789 | |
| 780 | 790 | static struct phy_driver aqr_driver[] = { |
| 781 | 791 | { |
| @@ -853,6 +863,7 @@ static struct phy_driver aqr_driver[] = { · 71 unmodified lines | ||
| 853 | 863 | .get_sset_count = aqr107_get_sset_count, |
| 854 | 864 | .get_strings = aqr107_get_strings, |
| 855 | 865 | .get_stats = aqr107_get_stats, |
| 866 | + .get_features = aqr115c_get_features, | |
| 856 | 867 | .link_change_notify = aqr107_link_change_notify, |
| 857 | 868 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 858 | 869 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, |
| @@ -865,7 +876,7 @@ static struct phy_driver aqr_driver[] = { · 6 unmodified lines | ||
| 865 | 876 | .name = "Aquantia AQR111", |
| 866 | 877 | .probe = aqr107_probe, |
| 867 | 878 | .get_rate_matching = aqr107_get_rate_matching, |
| 868 | − .config_init = aqr111_config_init, | |
| 879 | + .config_init = aqr107_config_init, | |
| 869 | 880 | .config_aneg = aqr_config_aneg, |
| 870 | 881 | .config_intr = aqr_config_intr, |
| 871 | 882 | .handle_interrupt = aqr_handle_interrupt, |
| @@ -877,6 +888,7 @@ static struct phy_driver aqr_driver[] = { · 5 unmodified lines | ||
| 877 | 888 | .get_sset_count = aqr107_get_sset_count, |
| 878 | 889 | .get_strings = aqr107_get_strings, |
| 879 | 890 | .get_stats = aqr107_get_stats, |
| 891 | + .get_features = aqr111_get_features, | |
| 880 | 892 | .link_change_notify = aqr107_link_change_notify, |
| 881 | 893 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 882 | 894 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, |
| @@ -889,7 +901,7 @@ static struct phy_driver aqr_driver[] = { · 6 unmodified lines | ||
| 889 | 901 | .name = "Aquantia AQR111B0", |
| 890 | 902 | .probe = aqr107_probe, |
| 891 | 903 | .get_rate_matching = aqr107_get_rate_matching, |
| 892 | − .config_init = aqr111_config_init, | |
| 904 | + .config_init = aqr107_config_init, | |
| 893 | 905 | .config_aneg = aqr_config_aneg, |
| 894 | 906 | .config_intr = aqr_config_intr, |
| 895 | 907 | .handle_interrupt = aqr_handle_interrupt, |
| @@ -901,6 +913,7 @@ static struct phy_driver aqr_driver[] = { · 5 unmodified lines | ||
| 901 | 913 | .get_sset_count = aqr107_get_sset_count, |
| 902 | 914 | .get_strings = aqr107_get_strings, |
| 903 | 915 | .get_stats = aqr107_get_stats, |
| 916 | + .get_features = aqr111_get_features, | |
| 904 | 917 | .link_change_notify = aqr107_link_change_notify, |
| 905 | 918 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 906 | 919 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, |
| @@ -1010,7 +1023,7 @@ static struct phy_driver aqr_driver[] = { · 103 unmodified lines | ||
| 1010 | 1023 | .name = "Aquantia AQR114C", |
| 1011 | 1024 | .probe = aqr107_probe, |
| 1012 | 1025 | .get_rate_matching = aqr107_get_rate_matching, |
| 1013 | − .config_init = aqr111_config_init, | |
| 1026 | + .config_init = aqr107_config_init, | |
| 1014 | 1027 | .config_aneg = aqr_config_aneg, |
| 1015 | 1028 | .config_intr = aqr_config_intr, |
| 1016 | 1029 | .handle_interrupt = aqr_handle_interrupt, |
| @@ -1022,6 +1035,7 @@ static struct phy_driver aqr_driver[] = { · 5 unmodified lines | ||
| 1022 | 1035 | .get_sset_count = aqr107_get_sset_count, |
| 1023 | 1036 | .get_strings = aqr107_get_strings, |
| 1024 | 1037 | .get_stats = aqr107_get_stats, |
| 1038 | + .get_features = aqr111_get_features, | |
| 1025 | 1039 | .link_change_notify = aqr107_link_change_notify, |
| 1026 | 1040 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 1027 | 1041 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, |
| @@ -1046,6 +1060,7 @@ static struct phy_driver aqr_driver[] = { · 18 unmodified lines | ||
| 1046 | 1060 | .get_sset_count = aqr107_get_sset_count, |
| 1047 | 1061 | .get_strings = aqr107_get_strings, |
| 1048 | 1062 | .get_stats = aqr107_get_stats, |
| 1063 | + .get_features = aqr115c_get_features, | |
| 1049 | 1064 | .link_change_notify = aqr107_link_change_notify, |
| 1050 | 1065 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 1051 | 1066 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, |
| @@ -132,7 +132,7 @@ static int bcm84881_aneg_done(struct phy_device *phydev) · 131 unmodified lines | ||
| 132 | 132 | |
| 133 | 133 | bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR); |
| 134 | 134 | if (bmsr < 0) |
| 135 | − return val; | |
| 135 | + return bmsr; | |
| 136 | 136 | |
| 137 | 137 | return !!(val & MDIO_AN_STAT1_COMPLETE) && |
| 138 | 138 | !!(bmsr & BMSR_ANEGCOMPLETE); |
| @@ -158,7 +158,7 @@ static int bcm84881_read_status(struct phy_device *phydev) · 19 unmodified lines | ||
| 158 | 158 | |
| 159 | 159 | bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR); |
| 160 | 160 | if (bmsr < 0) |
| 161 | − return val; | |
| 161 | + return bmsr; | |
| 162 | 162 | |
| 163 | 163 | phydev->autoneg_complete = !!(val & MDIO_AN_STAT1_COMPLETE) && |
| 164 | 164 | !!(bmsr & BMSR_ANEGCOMPLETE); |
| @@ -45,8 +45,8 @@ · 44 unmodified lines | ||
| 45 | 45 | /* Control Register 2 bits */ |
| 46 | 46 | #define DP83822_FX_ENABLE BIT(14) |
| 47 | 47 | |
| 48 | −#define DP83822_HW_RESET BIT(15) | |
| 49 | −#define DP83822_SW_RESET BIT(14) | |
| 48 | +#define DP83822_SW_RESET BIT(15) | |
| 49 | +#define DP83822_DIG_RESTART BIT(14) | |
| 50 | 50 | |
| 51 | 51 | /* PHY STS bits */ |
| 52 | 52 | #define DP83822_PHYSTS_DUPLEX BIT(2) |
| @@ -645,7 +645,6 @@ static int dp83869_configure_fiber(struct phy_device *phydev, · 644 unmodified lines | ||
| 645 | 645 | phydev->supported); |
| 646 | 646 | |
| 647 | 647 | linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); |
| 648 | − linkmode_set_bit(ADVERTISED_FIBRE, phydev->advertising); | |
| 649 | 648 | |
| 650 | 649 | if (dp83869->mode == DP83869_RGMII_1000_BASE) { |
| 651 | 650 | linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, |
| @@ -3326,10 +3326,11 @@ static __maybe_unused int phy_led_hw_is_supported(struct led_classdev *led_cdev, · 3325 unmodified lines | ||
| 3326 | 3326 | |
| 3327 | 3327 | static void phy_leds_unregister(struct phy_device *phydev) |
| 3328 | 3328 | { |
| 3329 | − struct phy_led *phyled; | |
| 3329 | + struct phy_led *phyled, *tmp; | |
| 3330 | 3330 | |
| 3331 | − list_for_each_entry(phyled, &phydev->leds, list) { | |
| 3331 | + list_for_each_entry_safe(phyled, tmp, &phydev->leds, list) { | |
| 3332 | 3332 | led_classdev_unregister(&phyled->led_cdev); |
| 3333 | + list_del(&phyled->list); | |
| 3333 | 3334 | } |
| 3334 | 3335 | } |
| 3335 | 3336 | |
| @@ -1081,6 +1081,16 @@ static int rtl8221b_vn_cg_c45_match_phy_device(struct phy_device *phydev) · 1080 unmodified lines | ||
| 1081 | 1081 | return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true); |
| 1082 | 1082 | } |
| 1083 | 1083 | |
| 1084 | +static int rtl8251b_c22_match_phy_device(struct phy_device *phydev) | |
| 1085 | +{ | |
| 1086 | + return rtlgen_is_c45_match(phydev, RTL_8251B, false); | |
| 1087 | +} | |
| 1088 | + | |
| 1089 | +static int rtl8251b_c45_match_phy_device(struct phy_device *phydev) | |
| 1090 | +{ | |
| 1091 | + return rtlgen_is_c45_match(phydev, RTL_8251B, true); | |
| 1092 | +} | |
| 1093 | + | |
| 1084 | 1094 | static int rtlgen_resume(struct phy_device *phydev) |
| 1085 | 1095 | { |
| 1086 | 1096 | int ret = genphy_resume(phydev); |
| @@ -1418,7 +1428,7 @@ static struct phy_driver realtek_drvs[] = { · 331 unmodified lines | ||
| 1418 | 1428 | .suspend = genphy_c45_pma_suspend, |
| 1419 | 1429 | .resume = rtlgen_c45_resume, |
| 1420 | 1430 | }, { |
| 1421 | − PHY_ID_MATCH_EXACT(0x001cc862), | |
| 1431 | + .match_phy_device = rtl8251b_c45_match_phy_device, | |
| 1422 | 1432 | .name = "RTL8251B 5Gbps PHY", |
| 1423 | 1433 | .get_features = rtl822x_get_features, |
| 1424 | 1434 | .config_aneg = rtl822x_config_aneg, |
| @@ -1427,6 +1437,18 @@ static struct phy_driver realtek_drvs[] = { · 2 unmodified lines | ||
| 1427 | 1437 | .resume = rtlgen_resume, |
| 1428 | 1438 | .read_page = rtl821x_read_page, |
| 1429 | 1439 | .write_page = rtl821x_write_page, |
| 1440 | + }, { | |
| 1441 | + .match_phy_device = rtl8251b_c22_match_phy_device, | |
| 1442 | + .name = "RTL8126A-internal 5Gbps PHY", | |
| 1443 | + .get_features = rtl822x_get_features, | |
| 1444 | + .config_aneg = rtl822x_config_aneg, | |
| 1445 | + .read_status = rtl822x_read_status, | |
| 1446 | + .suspend = genphy_suspend, | |
| 1447 | + .resume = rtlgen_resume, | |
| 1448 | + .read_page = rtl821x_read_page, | |
| 1449 | + .write_page = rtl821x_write_page, | |
| 1450 | + .read_mmd = rtl822x_read_mmd, | |
| 1451 | + .write_mmd = rtl822x_write_mmd, | |
| 1430 | 1452 | }, { |
| 1431 | 1453 | PHY_ID_MATCH_EXACT(0x001ccad0), |
| 1432 | 1454 | .name = "RTL8224 2.5Gbps PHY", |
| @@ -815,7 +815,7 @@ plip_send_packet(struct net_device *dev, struct net_local *nl, · 814 unmodified lines | ||
| 815 | 815 | return HS_TIMEOUT; |
| 816 | 816 | } |
| 817 | 817 | } |
| 818 | − break; | |
| 818 | + fallthrough; | |
| 819 | 819 | |
| 820 | 820 | case PLIP_PK_LENGTH_LSB: |
| 821 | 821 | if (plip_send(nibble_timeout, dev, |
| @@ -542,7 +542,7 @@ ppp_async_encode(struct asyncppp *ap) · 541 unmodified lines | ||
| 542 | 542 | * and 7 (code-reject) must be sent as though no options |
| 543 | 543 | * had been negotiated. |
| 544 | 544 | */ |
| 545 | − islcp = proto == PPP_LCP && 1 <= data[2] && data[2] <= 7; | |
| 545 | + islcp = proto == PPP_LCP && count >= 3 && 1 <= data[2] && data[2] <= 7; | |
| 546 | 546 | |
| 547 | 547 | if (i == 0) { |
| 548 | 548 | if (islcp) |
| @@ -113,7 +113,7 @@ static void pse_release_pis(struct pse_controller_dev *pcdev) · 112 unmodified lines | ||
| 113 | 113 | { |
| 114 | 114 | int i; |
| 115 | 115 | |
| 116 | − for (i = 0; i <= pcdev->nr_lines; i++) { | |
| 116 | + for (i = 0; i < pcdev->nr_lines; i++) { | |
| 117 | 117 | of_node_put(pcdev->pi[i].pairset[0].np); |
| 118 | 118 | of_node_put(pcdev->pi[i].pairset[1].np); |
| 119 | 119 | of_node_put(pcdev->pi[i].np); |
| @@ -647,7 +647,7 @@ static int of_pse_match_pi(struct pse_controller_dev *pcdev, · 527 unmodified lines | ||
| 647 | 647 | { |
| 648 | 648 | int i; |
| 649 | 649 | |
| 650 | − for (i = 0; i <= pcdev->nr_lines; i++) { | |
| 650 | + for (i = 0; i < pcdev->nr_lines; i++) { | |
| 651 | 651 | if (pcdev->pi[i].np == np) |
| 652 | 652 | return i; |
| 653 | 653 | } |
| @@ -785,6 +785,17 @@ static int pse_ethtool_c33_set_config(struct pse_control *psec, · 131 unmodified lines | ||
| 785 | 785 | */ |
| 786 | 786 | switch (config->c33_admin_control) { |
| 787 | 787 | case ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED: |
| 788 | + /* We could have mismatch between admin_state_enabled and | |
| 789 | + * state reported by regulator_is_enabled. This can occur when | |
| 790 | + * the PI is forcibly turn off by the controller. Call | |
| 791 | + * regulator_disable on that case to fix the counters state. | |
| 792 | + */ | |
| 793 | + if (psec->pcdev->pi[psec->id].admin_state_enabled && | |
| 794 | + !regulator_is_enabled(psec->ps)) { | |
| 795 | + err = regulator_disable(psec->ps); | |
| 796 | + if (err) | |
| 797 | + break; | |
| 798 | + } | |
| 788 | 799 | if (!psec->pcdev->pi[psec->id].admin_state_enabled) |
| 789 | 800 | err = regulator_enable(psec->ps); |
| 790 | 801 | break; |
| @@ -643,46 +643,57 @@ bad: · 642 unmodified lines | ||
| 643 | 643 | int |
| 644 | 644 | slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) |
| 645 | 645 | { |
| 646 | − struct cstate *cs; | |
| 647 | − unsigned ihl; | |
| 648 | − | |
| 646 | + const struct tcphdr *th; | |
| 649 | 647 | unsigned char index; |
| 648 | + struct iphdr *iph; | |
| 649 | + struct cstate *cs; | |
| 650 | + unsigned int ihl; | |
| 650 | 651 | |
| 651 | − if(isize < 20) { | |
| 652 | − /* The packet is shorter than a legal IP header */ | |
| 652 | + /* The packet is shorter than a legal IP header. | |
| 653 | + * Also make sure isize is positive. | |
| 654 | + */ | |
| 655 | + if (isize < (int)sizeof(struct iphdr)) { | |
| 656 | +runt: | |
| 653 | 657 | comp->sls_i_runt++; |
| 654 | − return slhc_toss( comp ); | |
| 658 | + return slhc_toss(comp); | |
| 655 | 659 | } |
| 660 | + iph = (struct iphdr *)icp; | |
| 656 | 661 | /* Peek at the IP header's IHL field to find its length */ |
| 657 | − ihl = icp[0] & 0xf; | |
| 658 | − if(ihl < 20 / 4){ | |
| 659 | − /* The IP header length field is too small */ | |
| 660 | − comp->sls_i_runt++; | |
| 661 | − return slhc_toss( comp ); | |
| 662 | − } | |
| 663 | − index = icp[9]; | |
| 664 | − icp[9] = IPPROTO_TCP; | |
| 662 | + ihl = iph->ihl; | |
| 663 | + /* The IP header length field is too small, | |
| 664 | + * or packet is shorter than the IP header followed | |
| 665 | + * by minimal tcp header. | |
| 666 | + */ | |
| 667 | + if (ihl < 5 || isize < ihl * 4 + sizeof(struct tcphdr)) | |
| 668 | + goto runt; | |
| 669 | + | |
| 670 | + index = iph->protocol; | |
| 671 | + iph->protocol = IPPROTO_TCP; | |
| 665 | 672 | |
| 666 | 673 | if (ip_fast_csum(icp, ihl)) { |
| 667 | 674 | /* Bad IP header checksum; discard */ |
| 668 | 675 | comp->sls_i_badcheck++; |
| 669 | − return slhc_toss( comp ); | |
| 676 | + return slhc_toss(comp); | |
| 670 | 677 | } |
| 671 | − if(index > comp->rslot_limit) { | |
| 678 | + if (index > comp->rslot_limit) { | |
| 672 | 679 | comp->sls_i_error++; |
| 673 | 680 | return slhc_toss(comp); |
| 674 | 681 | } |
| 675 | − | |
| 682 | + th = (struct tcphdr *)(icp + ihl * 4); | |
| 683 | + if (th->doff < sizeof(struct tcphdr) / 4) | |
| 684 | + goto runt; | |
| 685 | + if (isize < ihl * 4 + th->doff * 4) | |
| 686 | + goto runt; | |
| 676 | 687 | /* Update local state */ |
| 677 | 688 | cs = &comp->rstate[comp->recv_current = index]; |
| 678 | 689 | comp->flags &=~ SLF_TOSS; |
| 679 | − memcpy(&cs->cs_ip,icp,20); | |
| 680 | − memcpy(&cs->cs_tcp,icp + ihl*4,20); | |
| 690 | + memcpy(&cs->cs_ip, iph, sizeof(*iph)); | |
| 691 | + memcpy(&cs->cs_tcp, th, sizeof(*th)); | |
| 681 | 692 | if (ihl > 5) |
| 682 | − memcpy(cs->cs_ipopt, icp + sizeof(struct iphdr), (ihl - 5) * 4); | |
| 683 | − if (cs->cs_tcp.doff > 5) | |
| 684 | − memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4); | |
| 685 | − cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2; | |
| 693 | + memcpy(cs->cs_ipopt, &iph[1], (ihl - 5) * 4); | |
| 694 | + if (th->doff > 5) | |
| 695 | + memcpy(cs->cs_tcpopt, &th[1], (th->doff - 5) * 4); | |
| 696 | + cs->cs_hsize = ihl*2 + th->doff*2; | |
| 686 | 697 | cs->initialized = true; |
| 687 | 698 | /* Put headers back on packet |
| 688 | 699 | * Neither header checksum is recalculated |
| @@ -1076,6 +1076,7 @@ static const struct usb_device_id products[] = { · 1075 unmodified lines | ||
| 1076 | 1076 | USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7), |
| 1077 | 1077 | .driver_info = (unsigned long)&qmi_wwan_info, |
| 1078 | 1078 | }, |
| 1079 | + {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0122)}, /* Quectel RG650V */ | |
| 1079 | 1080 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ |
| 1080 | 1081 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ |
| 1081 | 1082 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ |
| @@ -1426,6 +1427,7 @@ static const struct usb_device_id products[] = { · 344 unmodified lines | ||
| 1426 | 1427 | {QMI_FIXED_INTF(0x2c7c, 0x0296, 4)}, /* Quectel BG96 */ |
| 1427 | 1428 | {QMI_QUIRK_SET_DTR(0x2c7c, 0x030e, 4)}, /* Quectel EM05GV2 */ |
| 1428 | 1429 | {QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */ |
| 1430 | + {QMI_QUIRK_SET_DTR(0x2cb7, 0x0112, 0)}, /* Fibocom FG132 */ | |
| 1429 | 1431 | {QMI_FIXED_INTF(0x0489, 0xe0b4, 0)}, /* Foxconn T77W968 LTE */ |
| 1430 | 1432 | {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/ |
| 1431 | 1433 | {QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */ |
| @@ -10069,6 +10069,7 @@ static const struct usb_device_id rtl8152_table[] = { · 10068 unmodified lines | ||
| 10069 | 10069 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x3062) }, |
| 10070 | 10070 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x3069) }, |
| 10071 | 10071 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x3082) }, |
| 10072 | + { USB_DEVICE(VENDOR_ID_LENOVO, 0x3098) }, | |
| 10072 | 10073 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x7205) }, |
| 10073 | 10074 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x720c) }, |
| 10074 | 10075 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x7214) }, |
| @@ -1767,7 +1767,8 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) · 1766 unmodified lines | ||
| 1767 | 1767 | // can rename the link if it knows better. |
| 1768 | 1768 | if ((dev->driver_info->flags & FLAG_ETHER) != 0 && |
| 1769 | 1769 | ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 || |
| 1770 | − (net->dev_addr [0] & 0x02) == 0)) | |
| 1770 | + /* somebody touched it*/ | |
| 1771 | + !is_zero_ether_addr(net->dev_addr))) | |
| 1771 | 1772 | strscpy(net->name, "eth%d", sizeof(net->name)); |
| 1772 | 1773 | /* WLAN devices should always be named "wlan%d" */ |
| 1773 | 1774 | if ((dev->driver_info->flags & FLAG_WLAN) != 0) |
| @@ -1870,6 +1871,7 @@ out1: · 96 unmodified lines | ||
| 1870 | 1871 | * may trigger an error resubmitting itself and, worse, |
| 1871 | 1872 | * schedule a timer. So we kill it all just in case. |
| 1872 | 1873 | */ |
| 1874 | + usbnet_mark_going_away(dev); | |
| 1873 | 1875 | cancel_work_sync(&dev->kevent); |
| 1874 | 1876 | del_timer_sync(&dev->delay); |
| 1875 | 1877 | free_netdev(net); |
| @@ -4155,7 +4155,7 @@ struct virtnet_stats_ctx { · 4154 unmodified lines | ||
| 4155 | 4155 | u32 desc_num[3]; |
| 4156 | 4156 | |
| 4157 | 4157 | /* The actual supported stat types. */ |
| 4158 | − u32 bitmap[3]; | |
| 4158 | + u64 bitmap[3]; | |
| 4159 | 4159 | |
| 4160 | 4160 | /* Used to calculate the reply buffer size. */ |
| 4161 | 4161 | u32 size[3]; |
| @@ -148,7 +148,7 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter, · 147 unmodified lines | ||
| 148 | 148 | } else { /* XDP buffer from page pool */ |
| 149 | 149 | page = virt_to_page(xdpf->data); |
| 150 | 150 | tbi->dma_addr = page_pool_get_dma_addr(page) + |
| 151 | − VMXNET3_XDP_HEADROOM; | |
| 151 | + (xdpf->data - (void *)xdpf); | |
| 152 | 152 | dma_sync_single_for_device(&adapter->pdev->dev, |
| 153 | 153 | tbi->dma_addr, buf_size, |
| 154 | 154 | DMA_TO_DEVICE); |
| @@ -4913,9 +4913,13 @@ static int __init vxlan_init_module(void) · 4912 unmodified lines | ||
| 4913 | 4913 | if (rc) |
| 4914 | 4914 | goto out4; |
| 4915 | 4915 | |
| 4916 | − vxlan_vnifilter_init(); | |
| 4916 | + rc = vxlan_vnifilter_init(); | |
| 4917 | + if (rc) | |
| 4918 | + goto out5; | |
| 4917 | 4919 | |
| 4918 | 4920 | return 0; |
| 4921 | +out5: | |
| 4922 | + rtnl_link_unregister(&vxlan_link_ops); | |
| 4919 | 4923 | out4: |
| 4920 | 4924 | unregister_switchdev_notifier(&vxlan_switchdev_notifier_block); |
| 4921 | 4925 | out3: |
| @@ -202,7 +202,7 @@ int vxlan_vni_in_use(struct net *src_net, struct vxlan_dev *vxlan, · 201 unmodified lines | ||
| 202 | 202 | int vxlan_vnigroup_init(struct vxlan_dev *vxlan); |
| 203 | 203 | void vxlan_vnigroup_uninit(struct vxlan_dev *vxlan); |
| 204 | 204 | |
| 205 | −void vxlan_vnifilter_init(void); | |
| 205 | +int vxlan_vnifilter_init(void); | |
| 206 | 206 | void vxlan_vnifilter_uninit(void); |
| 207 | 207 | void vxlan_vnifilter_count(struct vxlan_dev *vxlan, __be32 vni, |
| 208 | 208 | struct vxlan_vni_node *vninode, |
| @@ -992,19 +992,18 @@ static int vxlan_vnifilter_process(struct sk_buff *skb, struct nlmsghdr *nlh, · 991 unmodified lines | ||
| 992 | 992 | return err; |
| 993 | 993 | } |
| 994 | 994 | |
| 995 | −void vxlan_vnifilter_init(void) | |
| 995 | +static const struct rtnl_msg_handler vxlan_vnifilter_rtnl_msg_handlers[] = { | |
| 996 | + {THIS_MODULE, PF_BRIDGE, RTM_GETTUNNEL, NULL, vxlan_vnifilter_dump, 0}, | |
| 997 | + {THIS_MODULE, PF_BRIDGE, RTM_NEWTUNNEL, vxlan_vnifilter_process, NULL, 0}, | |
| 998 | + {THIS_MODULE, PF_BRIDGE, RTM_DELTUNNEL, vxlan_vnifilter_process, NULL, 0}, | |
| 999 | +}; | |
| 1000 | + | |
| 1001 | +int vxlan_vnifilter_init(void) | |
| 996 | 1002 | { |
| 997 | − rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_GETTUNNEL, NULL, | |
| 998 | − vxlan_vnifilter_dump, 0); | |
| 999 | − rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_NEWTUNNEL, | |
| 1000 | − vxlan_vnifilter_process, NULL, 0); | |
| 1001 | − rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_DELTUNNEL, | |
| 1002 | − vxlan_vnifilter_process, NULL, 0); | |
| 1003 | + return rtnl_register_many(vxlan_vnifilter_rtnl_msg_handlers); | |
| 1003 | 1004 | } |
| 1004 | 1005 | |
| 1005 | 1006 | void vxlan_vnifilter_uninit(void) |
| 1006 | 1007 | { |
| 1007 | − rtnl_unregister(PF_BRIDGE, RTM_GETTUNNEL); | |
| 1008 | − rtnl_unregister(PF_BRIDGE, RTM_NEWTUNNEL); | |
| 1009 | − rtnl_unregister(PF_BRIDGE, RTM_DELTUNNEL); | |
| 1008 | + rtnl_unregister_many(vxlan_vnifilter_rtnl_msg_handlers); | |
| 1010 | 1009 | } |
| @@ -3043,9 +3043,14 @@ ath10k_wmi_tlv_op_cleanup_mgmt_tx_send(struct ath10k *ar, · 3042 unmodified lines | ||
| 3043 | 3043 | struct sk_buff *msdu) |
| 3044 | 3044 | { |
| 3045 | 3045 | struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); |
| 3046 | + struct ath10k_mgmt_tx_pkt_addr *pkt_addr; | |
| 3046 | 3047 | struct ath10k_wmi *wmi = &ar->wmi; |
| 3047 | 3048 | |
| 3048 | − idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id); | |
| 3049 | + spin_lock_bh(&ar->data_lock); | |
| 3050 | + pkt_addr = idr_remove(&wmi->mgmt_pending_tx, cb->msdu_id); | |
| 3051 | + spin_unlock_bh(&ar->data_lock); | |
| 3052 | + | |
| 3053 | + kfree(pkt_addr); | |
| 3049 | 3054 | |
| 3050 | 3055 | return 0; |
| 3051 | 3056 | } |
| @@ -2441,6 +2441,7 @@ wmi_process_mgmt_tx_comp(struct ath10k *ar, struct mgmt_tx_compl_params *param) · 2440 unmodified lines | ||
| 2441 | 2441 | dma_unmap_single(ar->dev, pkt_addr->paddr, |
| 2442 | 2442 | msdu->len, DMA_TO_DEVICE); |
| 2443 | 2443 | info = IEEE80211_SKB_CB(msdu); |
| 2444 | + kfree(pkt_addr); | |
| 2444 | 2445 | |
| 2445 | 2446 | if (param->status) { |
| 2446 | 2447 | info->flags &= ~IEEE80211_TX_STAT_ACK; |
| @@ -9612,6 +9613,7 @@ static int ath10k_wmi_mgmt_tx_clean_up_pending(int msdu_id, void *ptr, · 7165 unmodified lines | ||
| 9612 | 9613 | dma_unmap_single(ar->dev, pkt_addr->paddr, |
| 9613 | 9614 | msdu->len, DMA_TO_DEVICE); |
| 9614 | 9615 | ieee80211_free_txskb(ar->hw, msdu); |
| 9616 | + kfree(pkt_addr); | |
| 9615 | 9617 | |
| 9616 | 9618 | return 0; |
| 9617 | 9619 | } |
| @@ -5291,8 +5291,11 @@ int ath11k_dp_rx_process_mon_status(struct ath11k_base *ab, int mac_id, · 5290 unmodified lines | ||
| 5291 | 5291 | hal_status == HAL_TLV_STATUS_PPDU_DONE) { |
| 5292 | 5292 | rx_mon_stats->status_ppdu_done++; |
| 5293 | 5293 | pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE; |
| 5294 | − ath11k_dp_rx_mon_dest_process(ar, mac_id, budget, napi); | |
| 5295 | − pmon->mon_ppdu_status = DP_PPDU_STATUS_START; | |
| 5294 | + if (!ab->hw_params.full_monitor_mode) { | |
| 5295 | + ath11k_dp_rx_mon_dest_process(ar, mac_id, | |
| 5296 | + budget, napi); | |
| 5297 | + pmon->mon_ppdu_status = DP_PPDU_STATUS_START; | |
| 5298 | + } | |
| 5296 | 5299 | } |
| 5297 | 5300 | |
| 5298 | 5301 | if (ppdu_info->peer_id == HAL_INVALID_PEERID || |
| @@ -306,7 +306,7 @@ static void wil_rx_add_radiotap_header(struct wil6210_priv *wil, · 305 unmodified lines | ||
| 306 | 306 | struct sk_buff *skb) |
| 307 | 307 | { |
| 308 | 308 | struct wil6210_rtap { |
| 309 | − struct ieee80211_radiotap_header rthdr; | |
| 309 | + struct ieee80211_radiotap_header_fixed rthdr; | |
| 310 | 310 | /* fields should be in the order of bits in rthdr.it_present */ |
| 311 | 311 | /* flags */ |
| 312 | 312 | u8 flags; |
| @@ -27,6 +27,7 @@ source "drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig" · 26 unmodified lines | ||
| 27 | 27 | config BRCM_TRACING |
| 28 | 28 | bool "Broadcom device tracing" |
| 29 | 29 | depends on BRCMSMAC || BRCMFMAC |
| 30 | + depends on TRACING | |
| 30 | 31 | help |
| 31 | 32 | If you say Y here, the Broadcom wireless drivers will register |
| 32 | 33 | with ftrace to dump event information into the trace ringbuffer. |
| @@ -2518,7 +2518,7 @@ static void isr_rx_monitor(struct ipw2100_priv *priv, int i, · 2517 unmodified lines | ||
| 2518 | 2518 | * to build this manually element by element, we can write it much |
| 2519 | 2519 | * more efficiently than we can parse it. ORDER MATTERS HERE */ |
| 2520 | 2520 | struct ipw_rt_hdr { |
| 2521 | − struct ieee80211_radiotap_header rt_hdr; | |
| 2521 | + struct ieee80211_radiotap_header_fixed rt_hdr; | |
| 2522 | 2522 | s8 rt_dbmsignal; /* signal in dbM, kluged to signed */ |
| 2523 | 2523 | } *ipw_rt; |
| 2524 | 2524 | |
| @@ -1143,7 +1143,7 @@ struct ipw_prom_priv { · 1142 unmodified lines | ||
| 1143 | 1143 | * structure is provided regardless of any bits unset. |
| 1144 | 1144 | */ |
| 1145 | 1145 | struct ipw_rt_hdr { |
| 1146 | − struct ieee80211_radiotap_header rt_hdr; | |
| 1146 | + struct ieee80211_radiotap_header_fixed rt_hdr; | |
| 1147 | 1147 | u64 rt_tsf; /* TSF */ /* XXX */ |
| 1148 | 1148 | u8 rt_flags; /* radiotap packet flags */ |
| 1149 | 1149 | u8 rt_rate; /* rate in 500kb/s */ |
| @@ -3122,6 +3122,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd) · 3121 unmodified lines | ||
| 3122 | 3122 | struct il_cmd_meta *out_meta; |
| 3123 | 3123 | dma_addr_t phys_addr; |
| 3124 | 3124 | unsigned long flags; |
| 3125 | + u8 *out_payload; | |
| 3125 | 3126 | u32 idx; |
| 3126 | 3127 | u16 fix_size; |
| 3127 | 3128 | |
| @@ -3157,6 +3158,16 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd) · 29 unmodified lines | ||
| 3157 | 3158 | out_cmd = txq->cmd[idx]; |
| 3158 | 3159 | out_meta = &txq->meta[idx]; |
| 3159 | 3160 | |
| 3161 | + /* The payload is in the same place in regular and huge | |
| 3162 | + * command buffers, but we need to let the compiler know when | |
| 3163 | + * we're using a larger payload buffer to avoid "field- | |
| 3164 | + * spanning write" warnings at run-time for huge commands. | |
| 3165 | + */ | |
| 3166 | + if (cmd->flags & CMD_SIZE_HUGE) | |
| 3167 | + out_payload = ((struct il_device_cmd_huge *)out_cmd)->cmd.payload; | |
| 3168 | + else | |
| 3169 | + out_payload = out_cmd->cmd.payload; | |
| 3170 | + | |
| 3160 | 3171 | if (WARN_ON(out_meta->flags & CMD_MAPPED)) { |
| 3161 | 3172 | spin_unlock_irqrestore(&il->hcmd_lock, flags); |
| 3162 | 3173 | return -ENOSPC; |
| @@ -3170,7 +3181,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd) · 7 unmodified lines | ||
| 3170 | 3181 | out_meta->callback = cmd->callback; |
| 3171 | 3182 | |
| 3172 | 3183 | out_cmd->hdr.cmd = cmd->id; |
| 3173 | − memcpy(&out_cmd->cmd.payload, cmd->data, cmd->len); | |
| 3184 | + memcpy(out_payload, cmd->data, cmd->len); | |
| 3174 | 3185 | |
| 3175 | 3186 | /* At this point, the out_cmd now has all of the incoming cmd |
| 3176 | 3187 | * information */ |
| @@ -4962,6 +4973,8 @@ il_pci_resume(struct device *device) · 1785 unmodified lines | ||
| 4962 | 4973 | */ |
| 4963 | 4974 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); |
| 4964 | 4975 | |
| 4976 | + _il_wr(il, CSR_INT, 0xffffffff); | |
| 4977 | + _il_wr(il, CSR_FH_INT_STATUS, 0xffffffff); | |
| 4965 | 4978 | il_enable_interrupts(il); |
| 4966 | 4979 | |
| 4967 | 4980 | if (!(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) |
| @@ -560,6 +560,18 @@ struct il_device_cmd { · 559 unmodified lines | ||
| 560 | 560 | |
| 561 | 561 | #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct il_device_cmd)) |
| 562 | 562 | |
| 563 | +/** | |
| 564 | + * struct il_device_cmd_huge | |
| 565 | + * | |
| 566 | + * For use when sending huge commands. | |
| 567 | + */ | |
| 568 | +struct il_device_cmd_huge { | |
| 569 | + struct il_cmd_header hdr; /* uCode API */ | |
| 570 | + union { | |
| 571 | + u8 payload[IL_MAX_CMD_SIZE - sizeof(struct il_cmd_header)]; | |
| 572 | + } __packed cmd; | |
| 573 | +} __packed; | |
| 574 | + | |
| 563 | 575 | struct il_host_cmd { |
| 564 | 576 | const void *data; |
| 565 | 577 | unsigned long reply_page; |
| @@ -429,38 +429,28 @@ out_free: · 428 unmodified lines | ||
| 429 | 429 | return ret; |
| 430 | 430 | } |
| 431 | 431 | |
| 432 | −static int iwl_acpi_sar_set_profile(union acpi_object *table, | |
| 433 | − struct iwl_sar_profile *profile, | |
| 434 | − bool enabled, u8 num_chains, | |
| 435 | − u8 num_sub_bands) | |
| 432 | +static int | |
| 433 | +iwl_acpi_parse_chains_table(union acpi_object *table, | |
| 434 | + struct iwl_sar_profile_chain *chains, | |
| 435 | + u8 num_chains, u8 num_sub_bands) | |
| 436 | 436 | { |
| 437 | − int i, j, idx = 0; | |
| 438 | − | |
| 439 | − /* | |
| 440 | − * The table from ACPI is flat, but we store it in a | |
| 441 | − * structured array. | |
| 442 | − */ | |
| 443 | − for (i = 0; i < BIOS_SAR_MAX_CHAINS_PER_PROFILE; i++) { | |
| 444 | − for (j = 0; j < BIOS_SAR_MAX_SUB_BANDS_NUM; j++) { | |
| 437 | + for (u8 chain = 0; chain < num_chains; chain++) { | |
| 438 | + for (u8 subband = 0; subband < BIOS_SAR_MAX_SUB_BANDS_NUM; | |
| 439 | + subband++) { | |
| 445 | 440 | /* if we don't have the values, use the default */ |
| 446 | − if (i >= num_chains || j >= num_sub_bands) { | |
| 447 | − profile->chains[i].subbands[j] = 0; | |
| 441 | + if (subband >= num_sub_bands) { | |
| 442 | + chains[chain].subbands[subband] = 0; | |
| 443 | + } else if (table->type != ACPI_TYPE_INTEGER || | |
| 444 | + table->integer.value > U8_MAX) { | |
| 445 | + return -EINVAL; | |
| 448 | 446 | } else { |
| 449 | − if (table[idx].type != ACPI_TYPE_INTEGER || | |
| 450 | − table[idx].integer.value > U8_MAX) | |
| 451 | − return -EINVAL; | |
| 452 | − | |
| 453 | − profile->chains[i].subbands[j] = | |
| 454 | − table[idx].integer.value; | |
| 455 | − | |
| 456 | − idx++; | |
| 447 | + chains[chain].subbands[subband] = | |
| 448 | + table->integer.value; | |
| 449 | + table++; | |
| 457 | 450 | } |
| 458 | 451 | } |
| 459 | 452 | } |
| 460 | 453 | |
| 461 | − /* Only if all values were valid can the profile be enabled */ | |
| 462 | − profile->enabled = enabled; | |
| 463 | − | |
| 464 | 454 | return 0; |
| 465 | 455 | } |
| 466 | 456 | |
| @@ -543,9 +533,11 @@ read_table: · 76 unmodified lines | ||
| 543 | 533 | /* The profile from WRDS is officially profile 1, but goes |
| 544 | 534 | * into sar_profiles[0] (because we don't have a profile 0). |
| 545 | 535 | */ |
| 546 | − ret = iwl_acpi_sar_set_profile(table, &fwrt->sar_profiles[0], | |
| 547 | − flags & IWL_SAR_ENABLE_MSK, | |
| 548 | − num_chains, num_sub_bands); | |
| 536 | + ret = iwl_acpi_parse_chains_table(table, fwrt->sar_profiles[0].chains, | |
| 537 | + num_chains, num_sub_bands); | |
| 538 | + if (!ret && flags & IWL_SAR_ENABLE_MSK) | |
| 539 | + fwrt->sar_profiles[0].enabled = true; | |
| 540 | + | |
| 549 | 541 | out_free: |
| 550 | 542 | kfree(data); |
| 551 | 543 | return ret; |
| @@ -557,7 +549,7 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt) · 5 unmodified lines | ||
| 557 | 549 | bool enabled; |
| 558 | 550 | int i, n_profiles, tbl_rev, pos; |
| 559 | 551 | int ret = 0; |
| 560 | − u8 num_chains, num_sub_bands; | |
| 552 | + u8 num_sub_bands; | |
| 561 | 553 | |
| 562 | 554 | data = iwl_acpi_get_object(fwrt->dev, ACPI_EWRD_METHOD); |
| 563 | 555 | if (IS_ERR(data)) |
| @@ -573,7 +565,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt) · 9 unmodified lines | ||
| 573 | 565 | goto out_free; |
| 574 | 566 | } |
| 575 | 567 | |
| 576 | − num_chains = ACPI_SAR_NUM_CHAINS_REV2; | |
| 577 | 568 | num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV2; |
| 578 | 569 | |
| 579 | 570 | goto read_table; |
| @@ -589,7 +580,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt) · 9 unmodified lines | ||
| 589 | 580 | goto out_free; |
| 590 | 581 | } |
| 591 | 582 | |
| 592 | − num_chains = ACPI_SAR_NUM_CHAINS_REV1; | |
| 593 | 583 | num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV1; |
| 594 | 584 | |
| 595 | 585 | goto read_table; |
| @@ -605,7 +595,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt) · 9 unmodified lines | ||
| 605 | 595 | goto out_free; |
| 606 | 596 | } |
| 607 | 597 | |
| 608 | − num_chains = ACPI_SAR_NUM_CHAINS_REV0; | |
| 609 | 598 | num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV0; |
| 610 | 599 | |
| 611 | 600 | goto read_table; |
| @@ -637,23 +626,54 @@ read_table: · 25 unmodified lines | ||
| 637 | 626 | /* the tables start at element 3 */ |
| 638 | 627 | pos = 3; |
| 639 | 628 | |
| 629 | + BUILD_BUG_ON(ACPI_SAR_NUM_CHAINS_REV0 != ACPI_SAR_NUM_CHAINS_REV1); | |
| 630 | + BUILD_BUG_ON(ACPI_SAR_NUM_CHAINS_REV2 != 2 * ACPI_SAR_NUM_CHAINS_REV0); | |
| 631 | + | |
| 632 | + /* parse non-cdb chains for all profiles */ | |
| 640 | 633 | for (i = 0; i < n_profiles; i++) { |
| 641 | 634 | union acpi_object *table = &wifi_pkg->package.elements[pos]; |
| 635 | + | |
| 642 | 636 | /* The EWRD profiles officially go from 2 to 4, but we |
| 643 | 637 | * save them in sar_profiles[1-3] (because we don't |
| 644 | 638 | * have profile 0). So in the array we start from 1. |
| 645 | 639 | */ |
| 646 | − ret = iwl_acpi_sar_set_profile(table, | |
| 647 | − &fwrt->sar_profiles[i + 1], | |
| 648 | − enabled, num_chains, | |
| 649 | − num_sub_bands); | |
| 640 | + ret = iwl_acpi_parse_chains_table(table, | |
| 641 | + fwrt->sar_profiles[i + 1].chains, | |
| 642 | + ACPI_SAR_NUM_CHAINS_REV0, | |
| 643 | + num_sub_bands); | |
| 650 | 644 | if (ret < 0) |
| 651 | − break; | |
| 645 | + goto out_free; | |
| 652 | 646 | |
| 653 | 647 | /* go to the next table */ |
| 654 | − pos += num_chains * num_sub_bands; | |
| 648 | + pos += ACPI_SAR_NUM_CHAINS_REV0 * num_sub_bands; | |
| 655 | 649 | } |
| 656 | 650 | |
| 651 | + /* non-cdb table revisions */ | |
| 652 | + if (tbl_rev < 2) | |
| 653 | + goto set_enabled; | |
| 654 | + | |
| 655 | + /* parse cdb chains for all profiles */ | |
| 656 | + for (i = 0; i < n_profiles; i++) { | |
| 657 | + struct iwl_sar_profile_chain *chains; | |
| 658 | + union acpi_object *table; | |
| 659 | + | |
| 660 | + table = &wifi_pkg->package.elements[pos]; | |
| 661 | + chains = &fwrt->sar_profiles[i + 1].chains[ACPI_SAR_NUM_CHAINS_REV0]; | |
| 662 | + ret = iwl_acpi_parse_chains_table(table, | |
| 663 | + chains, | |
| 664 | + ACPI_SAR_NUM_CHAINS_REV0, | |
| 665 | + num_sub_bands); | |
| 666 | + if (ret < 0) | |
| 667 | + goto out_free; | |
| 668 | + | |
| 669 | + /* go to the next table */ | |
| 670 | + pos += ACPI_SAR_NUM_CHAINS_REV0 * num_sub_bands; | |
| 671 | + } | |
| 672 | + | |
| 673 | +set_enabled: | |
| 674 | + for (i = 0; i < n_profiles; i++) | |
| 675 | + fwrt->sar_profiles[i + 1].enabled = enabled; | |
| 676 | + | |
| 657 | 677 | out_free: |
| 658 | 678 | kfree(data); |
| 659 | 679 | return ret; |
| @@ -39,10 +39,12 @@ void iwl_fw_runtime_init(struct iwl_fw_runtime *fwrt, struct iwl_trans *trans, · 38 unmodified lines | ||
| 39 | 39 | } |
| 40 | 40 | IWL_EXPORT_SYMBOL(iwl_fw_runtime_init); |
| 41 | 41 | |
| 42 | +/* Assumes the appropriate lock is held by the caller */ | |
| 42 | 43 | void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt) |
| 43 | 44 | { |
| 44 | 45 | iwl_fw_suspend_timestamp(fwrt); |
| 45 | − iwl_dbg_tlv_time_point(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_START, NULL); | |
| 46 | + iwl_dbg_tlv_time_point_sync(fwrt, IWL_FW_INI_TIME_POINT_HOST_D3_START, | |
| 47 | + NULL); | |
| 46 | 48 | } |
| 47 | 49 | IWL_EXPORT_SYMBOL(iwl_fw_runtime_suspend); |
| 48 | 50 | |
| @@ -1413,25 +1413,35 @@ _iwl_op_mode_start(struct iwl_drv *drv, struct iwlwifi_opmode_table *op) · 1412 unmodified lines | ||
| 1413 | 1413 | const struct iwl_op_mode_ops *ops = op->ops; |
| 1414 | 1414 | struct dentry *dbgfs_dir = NULL; |
| 1415 | 1415 | struct iwl_op_mode *op_mode = NULL; |
| 1416 | + int retry, max_retry = !!iwlwifi_mod_params.fw_restart * IWL_MAX_INIT_RETRY; | |
| 1416 | 1417 | |
| 1417 | 1418 | /* also protects start/stop from racing against each other */ |
| 1418 | 1419 | lockdep_assert_held(&iwlwifi_opmode_table_mtx); |
| 1419 | 1420 | |
| 1421 | + for (retry = 0; retry <= max_retry; retry++) { | |
| 1422 | + | |
| 1420 | 1423 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 1421 | − drv->dbgfs_op_mode = debugfs_create_dir(op->name, | |
| 1422 | − drv->dbgfs_drv); | |
| 1423 | − dbgfs_dir = drv->dbgfs_op_mode; | |
| 1424 | + drv->dbgfs_op_mode = debugfs_create_dir(op->name, | |
| 1425 | + drv->dbgfs_drv); | |
| 1426 | + dbgfs_dir = drv->dbgfs_op_mode; | |
| 1424 | 1427 | #endif |
| 1425 | 1428 | |
| 1426 | − op_mode = ops->start(drv->trans, drv->trans->cfg, | |
| 1427 | − &drv->fw, dbgfs_dir); | |
| 1428 | − if (op_mode) | |
| 1429 | − return op_mode; | |
| 1429 | + op_mode = ops->start(drv->trans, drv->trans->cfg, | |
| 1430 | + &drv->fw, dbgfs_dir); | |
| 1431 | + | |
| 1432 | + if (op_mode) | |
| 1433 | + return op_mode; | |
| 1434 | + | |
| 1435 | + if (test_bit(STATUS_TRANS_DEAD, &drv->trans->status)) | |
| 1436 | + break; | |
| 1437 | + | |
| 1438 | + IWL_ERR(drv, "retry init count %d\n", retry); | |
| 1430 | 1439 | |
| 1431 | 1440 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 1432 | − debugfs_remove_recursive(drv->dbgfs_op_mode); | |
| 1433 | − drv->dbgfs_op_mode = NULL; | |
| 1441 | + debugfs_remove_recursive(drv->dbgfs_op_mode); | |
| 1442 | + drv->dbgfs_op_mode = NULL; | |
| 1434 | 1443 | #endif |
| 1444 | + } | |
| 1435 | 1445 | |
| 1436 | 1446 | return NULL; |
| 1437 | 1447 | } |
| @@ -98,6 +98,9 @@ void iwl_drv_stop(struct iwl_drv *drv); · 97 unmodified lines | ||
| 98 | 98 | #define VISIBLE_IF_IWLWIFI_KUNIT static |
| 99 | 99 | #endif |
| 100 | 100 | |
| 101 | +/* max retry for init flow */ | |
| 102 | +#define IWL_MAX_INIT_RETRY 2 | |
| 103 | + | |
| 101 | 104 | #define FW_NAME_PRE_BUFSIZE 64 |
| 102 | 105 | struct iwl_trans; |
| 103 | 106 | const char *iwl_drv_get_fwname_pre(struct iwl_trans *trans, char *buf); |
| @@ -1398,7 +1398,9 @@ int iwl_mvm_suspend(struct ieee80211_hw *hw, struct cfg80211_wowlan *wowlan) · 1397 unmodified lines | ||
| 1398 | 1398 | |
| 1399 | 1399 | iwl_mvm_pause_tcm(mvm, true); |
| 1400 | 1400 | |
| 1401 | + mutex_lock(&mvm->mutex); | |
| 1401 | 1402 | iwl_fw_runtime_suspend(&mvm->fwrt); |
| 1403 | + mutex_unlock(&mvm->mutex); | |
| 1402 | 1404 | |
| 1403 | 1405 | return __iwl_mvm_suspend(hw, wowlan, false); |
| 1404 | 1406 | } |
| @@ -1307,8 +1307,8 @@ static void iwl_mvm_disconnect_iterator(void *data, u8 *mac, · 1306 unmodified lines | ||
| 1307 | 1307 | void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags) |
| 1308 | 1308 | { |
| 1309 | 1309 | u32 error_log_size = mvm->fw->ucode_capa.error_log_size; |
| 1310 | + u32 status = 0; | |
| 1310 | 1311 | int ret; |
| 1311 | − u32 resp; | |
| 1312 | 1312 | |
| 1313 | 1313 | struct iwl_fw_error_recovery_cmd recovery_cmd = { |
| 1314 | 1314 | .flags = cpu_to_le32(flags), |
| @@ -1316,7 +1316,6 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags) · 1 unmodified line | ||
| 1316 | 1316 | }; |
| 1317 | 1317 | struct iwl_host_cmd host_cmd = { |
| 1318 | 1318 | .id = WIDE_ID(SYSTEM_GROUP, FW_ERROR_RECOVERY_CMD), |
| 1319 | − .flags = CMD_WANT_SKB, | |
| 1320 | 1319 | .data = {&recovery_cmd, }, |
| 1321 | 1320 | .len = {sizeof(recovery_cmd), }, |
| 1322 | 1321 | }; |
| @@ -1336,7 +1335,7 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags) · 13 unmodified lines | ||
| 1336 | 1335 | recovery_cmd.buf_size = cpu_to_le32(error_log_size); |
| 1337 | 1336 | } |
| 1338 | 1337 | |
| 1339 | − ret = iwl_mvm_send_cmd(mvm, &host_cmd); | |
| 1338 | + ret = iwl_mvm_send_cmd_status(mvm, &host_cmd, &status); | |
| 1340 | 1339 | kfree(mvm->error_recovery_buf); |
| 1341 | 1340 | mvm->error_recovery_buf = NULL; |
| 1342 | 1341 | |
| @@ -1347,11 +1346,10 @@ void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags) · 4 unmodified lines | ||
| 1347 | 1346 | |
| 1348 | 1347 | /* skb respond is only relevant in ERROR_RECOVERY_UPDATE_DB */ |
| 1349 | 1348 | if (flags & ERROR_RECOVERY_UPDATE_DB) { |
| 1350 | − resp = le32_to_cpu(*(__le32 *)host_cmd.resp_pkt->data); | |
| 1351 | − if (resp) { | |
| 1349 | + if (status) { | |
| 1352 | 1350 | IWL_ERR(mvm, |
| 1353 | 1351 | "Failed to send recovery cmd blob was invalid %d\n", |
| 1354 | − resp); | |
| 1352 | + status); | |
| 1355 | 1353 | |
| 1356 | 1354 | ieee80211_iterate_interfaces(mvm->hw, 0, |
| 1357 | 1355 | iwl_mvm_disconnect_iterator, |
| @@ -1293,12 +1293,14 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw) · 1292 unmodified lines | ||
| 1293 | 1293 | { |
| 1294 | 1294 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); |
| 1295 | 1295 | int ret; |
| 1296 | + int retry, max_retry = 0; | |
| 1296 | 1297 | |
| 1297 | 1298 | mutex_lock(&mvm->mutex); |
| 1298 | 1299 | |
| 1299 | 1300 | /* we are starting the mac not in error flow, and restart is enabled */ |
| 1300 | 1301 | if (!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) && |
| 1301 | 1302 | iwlwifi_mod_params.fw_restart) { |
| 1303 | + max_retry = IWL_MAX_INIT_RETRY; | |
| 1302 | 1304 | /* |
| 1303 | 1305 | * This will prevent mac80211 recovery flows to trigger during |
| 1304 | 1306 | * init failures |
| @@ -1306,7 +1308,13 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw) · 1 unmodified line | ||
| 1306 | 1308 | set_bit(IWL_MVM_STATUS_STARTING, &mvm->status); |
| 1307 | 1309 | } |
| 1308 | 1310 | |
| 1309 | − ret = __iwl_mvm_mac_start(mvm); | |
| 1311 | + for (retry = 0; retry <= max_retry; retry++) { | |
| 1312 | + ret = __iwl_mvm_mac_start(mvm); | |
| 1313 | + if (!ret) | |
| 1314 | + break; | |
| 1315 | + | |
| 1316 | + IWL_ERR(mvm, "mac start retry %d\n", retry); | |
| 1317 | + } | |
| 1310 | 1318 | clear_bit(IWL_MVM_STATUS_STARTING, &mvm->status); |
| 1311 | 1319 | |
| 1312 | 1320 | mutex_unlock(&mvm->mutex); |
| @@ -1970,7 +1978,6 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, · 657 unmodified lines | ||
| 1970 | 1978 | mvm->p2p_device_vif = NULL; |
| 1971 | 1979 | } |
| 1972 | 1980 | |
| 1973 | − iwl_mvm_unset_link_mapping(mvm, vif, &vif->bss_conf); | |
| 1974 | 1981 | iwl_mvm_mac_ctxt_remove(mvm, vif); |
| 1975 | 1982 | |
| 1976 | 1983 | RCU_INIT_POINTER(mvm->vif_id_to_mac[mvmvif->id], NULL); |
| @@ -1979,6 +1986,7 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, · 2 unmodified lines | ||
| 1979 | 1986 | mvm->monitor_on = false; |
| 1980 | 1987 | |
| 1981 | 1988 | out: |
| 1989 | + iwl_mvm_unset_link_mapping(mvm, vif, &vif->bss_conf); | |
| 1982 | 1990 | if (vif->type == NL80211_IFTYPE_AP || |
| 1983 | 1991 | vif->type == NL80211_IFTYPE_ADHOC) { |
| 1984 | 1992 | iwl_mvm_dealloc_int_sta(mvm, &mvmvif->deflink.mcast_sta); |
| @@ -41,8 +41,6 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw, · 40 unmodified lines | ||
| 41 | 41 | /* reset deflink MLO parameters */ |
| 42 | 42 | mvmvif->deflink.fw_link_id = IWL_MVM_FW_LINK_ID_INVALID; |
| 43 | 43 | mvmvif->deflink.active = 0; |
| 44 | − /* the first link always points to the default one */ | |
| 45 | − mvmvif->link[0] = &mvmvif->deflink; | |
| 46 | 44 | |
| 47 | 45 | ret = iwl_mvm_mld_mac_ctxt_add(mvm, vif); |
| 48 | 46 | if (ret) |
| @@ -60,9 +58,19 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw, · 11 unmodified lines | ||
| 60 | 58 | IEEE80211_VIF_SUPPORTS_CQM_RSSI; |
| 61 | 59 | } |
| 62 | 60 | |
| 63 | − ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf); | |
| 64 | − if (ret) | |
| 65 | − goto out_free_bf; | |
| 61 | + /* We want link[0] to point to the default link, unless we have MLO and | |
| 62 | + * in this case this will be modified later by .change_vif_links() | |
| 63 | + * If we are in the restart flow with an MLD connection, we will wait | |
| 64 | + * to .change_vif_links() to setup the links. | |
| 65 | + */ | |
| 66 | + if (!test_bit(IWL_MVM_STATUS_IN_HW_RESTART, &mvm->status) || | |
| 67 | + !ieee80211_vif_is_mld(vif)) { | |
| 68 | + mvmvif->link[0] = &mvmvif->deflink; | |
| 69 | + | |
| 70 | + ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf); | |
| 71 | + if (ret) | |
| 72 | + goto out_free_bf; | |
| 73 | + } | |
| 66 | 74 | |
| 67 | 75 | /* Save a pointer to p2p device vif, so it can later be used to |
| 68 | 76 | * update the p2p device MAC when a GO is started/stopped |
| @@ -350,11 +358,6 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm, · 281 unmodified lines | ||
| 350 | 358 | rcu_read_unlock(); |
| 351 | 359 | } |
| 352 | 360 | |
| 353 | − if (vif->type == NL80211_IFTYPE_STATION) | |
| 354 | − iwl_mvm_send_ap_tx_power_constraint_cmd(mvm, vif, | |
| 355 | − link_conf, | |
| 356 | − false); | |
| 357 | − | |
| 358 | 361 | /* then activate */ |
| 359 | 362 | ret = iwl_mvm_link_changed(mvm, vif, link_conf, |
| 360 | 363 | LINK_CONTEXT_MODIFY_ACTIVE | |
| @@ -363,6 +366,11 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm, · 2 unmodified lines | ||
| 363 | 366 | if (ret) |
| 364 | 367 | goto out; |
| 365 | 368 | |
| 369 | + if (vif->type == NL80211_IFTYPE_STATION) | |
| 370 | + iwl_mvm_send_ap_tx_power_constraint_cmd(mvm, vif, | |
| 371 | + link_conf, | |
| 372 | + false); | |
| 373 | + | |
| 366 | 374 | /* |
| 367 | 375 | * Power state must be updated before quotas, |
| 368 | 376 | * otherwise fw will complain. |
| @@ -1194,7 +1202,11 @@ iwl_mvm_mld_change_vif_links(struct ieee80211_hw *hw, · 825 unmodified lines | ||
| 1194 | 1202 | |
| 1195 | 1203 | mutex_lock(&mvm->mutex); |
| 1196 | 1204 | |
| 1197 | − if (old_links == 0) { | |
| 1205 | + /* If we're in RESTART flow, the default link wasn't added in | |
| 1206 | + * drv_add_interface(), and link[0] doesn't point to it. | |
| 1207 | + */ | |
| 1208 | + if (old_links == 0 && !test_bit(IWL_MVM_STATUS_IN_HW_RESTART, | |
| 1209 | + &mvm->status)) { | |
| 1198 | 1210 | err = iwl_mvm_disable_link(mvm, vif, &vif->bss_conf); |
| 1199 | 1211 | if (err) |
| 1200 | 1212 | goto out_err; |
| @@ -1774,7 +1774,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm, · 1773 unmodified lines | ||
| 1774 | 1774 | &cp->channel_config[ch_cnt]; |
| 1775 | 1775 | |
| 1776 | 1776 | u32 s_ssid_bitmap = 0, bssid_bitmap = 0, flags = 0; |
| 1777 | − u8 j, k, n_s_ssids = 0, n_bssids = 0; | |
| 1777 | + u8 k, n_s_ssids = 0, n_bssids = 0; | |
| 1778 | 1778 | u8 max_s_ssids, max_bssids; |
| 1779 | 1779 | bool force_passive = false, found = false, allow_passive = true, |
| 1780 | 1780 | unsolicited_probe_on_chan = false, psc_no_listen = false; |
| @@ -1799,7 +1799,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm, · 18 unmodified lines | ||
| 1799 | 1799 | cfg->v5.iter_count = 1; |
| 1800 | 1800 | cfg->v5.iter_interval = 0; |
| 1801 | 1801 | |
| 1802 | − for (j = 0; j < params->n_6ghz_params; j++) { | |
| 1802 | + for (u32 j = 0; j < params->n_6ghz_params; j++) { | |
| 1803 | 1803 | s8 tmp_psd_20; |
| 1804 | 1804 | |
| 1805 | 1805 | if (!(scan_6ghz_params[j].channel_idx == i)) |
| @@ -1873,7 +1873,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm, · 67 unmodified lines | ||
| 1873 | 1873 | * SSID. |
| 1874 | 1874 | * TODO: improve this logic |
| 1875 | 1875 | */ |
| 1876 | − for (j = 0; j < params->n_6ghz_params; j++) { | |
| 1876 | + for (u32 j = 0; j < params->n_6ghz_params; j++) { | |
| 1877 | 1877 | if (!(scan_6ghz_params[j].channel_idx == i)) |
| 1878 | 1878 | continue; |
| 1879 | 1879 | |
| @@ -2,7 +2,7 @@ · 1 unmodified line | ||
| 2 | 2 | #include <net/ieee80211_radiotap.h> |
| 3 | 3 | |
| 4 | 4 | struct tx_radiotap_hdr { |
| 5 | − struct ieee80211_radiotap_header hdr; | |
| 5 | + struct ieee80211_radiotap_header_fixed hdr; | |
| 6 | 6 | u8 rate; |
| 7 | 7 | u8 txpower; |
| 8 | 8 | u8 rts_retries; |
| @@ -31,7 +31,7 @@ struct tx_radiotap_hdr { · 22 unmodified lines | ||
| 31 | 31 | #define IEEE80211_FC_DSTODS 0x0300 |
| 32 | 32 | |
| 33 | 33 | struct rx_radiotap_hdr { |
| 34 | − struct ieee80211_radiotap_header hdr; | |
| 34 | + struct ieee80211_radiotap_header_fixed hdr; | |
| 35 | 35 | u8 flags; |
| 36 | 36 | u8 rate; |
| 37 | 37 | u8 antsignal; |
| @@ -84,13 +84,16 @@ int mt76_mcu_skb_send_and_get_msg(struct mt76_dev *dev, struct sk_buff *skb, · 83 unmodified lines | ||
| 84 | 84 | mutex_lock(&dev->mcu.mutex); |
| 85 | 85 | |
| 86 | 86 | if (dev->mcu_ops->mcu_skb_prepare_msg) { |
| 87 | + orig_skb = skb; | |
| 87 | 88 | ret = dev->mcu_ops->mcu_skb_prepare_msg(dev, skb, cmd, &seq); |
| 88 | 89 | if (ret < 0) |
| 89 | 90 | goto out; |
| 90 | 91 | } |
| 91 | 92 | |
| 92 | 93 | retry: |
| 93 | − orig_skb = skb_get(skb); | |
| 94 | + /* orig skb might be needed for retry, mcu_skb_send_msg consumes it */ | |
| 95 | + if (orig_skb) | |
| 96 | + skb_get(orig_skb); | |
| 94 | 97 | ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, &seq); |
| 95 | 98 | if (ret < 0) |
| 96 | 99 | goto out; |
| @@ -105,7 +108,7 @@ retry: · 8 unmodified lines | ||
| 105 | 108 | do { |
| 106 | 109 | skb = mt76_mcu_get_response(dev, expires); |
| 107 | 110 | if (!skb && !test_bit(MT76_MCU_RESET, &dev->phy.state) && |
| 108 | − retry++ < dev->mcu_ops->max_retry) { | |
| 111 | + orig_skb && retry++ < dev->mcu_ops->max_retry) { | |
| 109 | 112 | dev_err(dev->dev, "Retry message %08x (seq %d)\n", |
| 110 | 113 | cmd, seq); |
| 111 | 114 | skb = orig_skb; |
| @@ -7,12 +7,12 @@ · 6 unmodified lines | ||
| 7 | 7 | #include "cfg80211.h" |
| 8 | 8 | |
| 9 | 9 | struct wilc_wfi_radiotap_hdr { |
| 10 | − struct ieee80211_radiotap_header hdr; | |
| 10 | + struct ieee80211_radiotap_header_fixed hdr; | |
| 11 | 11 | u8 rate; |
| 12 | 12 | } __packed; |
| 13 | 13 | |
| 14 | 14 | struct wilc_wfi_radiotap_cb_hdr { |
| 15 | − struct ieee80211_radiotap_header hdr; | |
| 15 | + struct ieee80211_radiotap_header_fixed hdr; | |
| 16 | 16 | u8 rate; |
| 17 | 17 | u8 dump; |
| 18 | 18 | u16 tx_flags; |
| @@ -352,7 +352,6 @@ static const struct usb_device_id rtl8192d_usb_ids[] = { · 351 unmodified lines | ||
| 352 | 352 | {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8194, rtl92du_hal_cfg)}, |
| 353 | 353 | {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8111, rtl92du_hal_cfg)}, |
| 354 | 354 | {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x0193, rtl92du_hal_cfg)}, |
| 355 | − {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8171, rtl92du_hal_cfg)}, | |
| 356 | 355 | {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0xe194, rtl92du_hal_cfg)}, |
| 357 | 356 | {RTL_USB_DEVICE(0x2019, 0xab2c, rtl92du_hal_cfg)}, |
| 358 | 357 | {RTL_USB_DEVICE(0x2019, 0xab2d, rtl92du_hal_cfg)}, |
| @@ -771,7 +771,6 @@ static void rtw_usb_dynamic_rx_agg_v1(struct rtw_dev *rtwdev, bool enable) · 770 unmodified lines | ||
| 771 | 771 | u8 size, timeout; |
| 772 | 772 | u16 val16; |
| 773 | 773 | |
| 774 | − rtw_write32_set(rtwdev, REG_RXDMA_AGG_PG_TH, BIT_EN_PRE_CALC); | |
| 775 | 774 | rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); |
| 776 | 775 | rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7)); |
| 777 | 776 | |
| @@ -6445,6 +6445,8 @@ static void _update_wl_info_v7(struct rtw89_dev *rtwdev, u8 rid) · 6444 unmodified lines | ||
| 6445 | 6445 | |
| 6446 | 6446 | /* todo DBCC related event */ |
| 6447 | 6447 | rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC] wl_info phy_now=%d\n", phy_now); |
| 6448 | + rtw89_debug(rtwdev, RTW89_DBG_BTC, | |
| 6449 | + "[BTC] rlink cnt_2g=%d cnt_5g=%d\n", cnt_2g, cnt_5g); | |
| 6448 | 6450 | |
| 6449 | 6451 | if (wl_rinfo->dbcc_en != rtwdev->dbcc_en) { |
| 6450 | 6452 | wl_rinfo->dbcc_chg = 1; |
| @@ -3026,24 +3026,54 @@ static void rtw89_pci_declaim_device(struct rtw89_dev *rtwdev, · 3025 unmodified lines | ||
| 3026 | 3026 | pci_disable_device(pdev); |
| 3027 | 3027 | } |
| 3028 | 3028 | |
| 3029 | −static void rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev) | |
| 3029 | +static bool rtw89_pci_chip_is_manual_dac(struct rtw89_dev *rtwdev) | |
| 3030 | 3030 | { |
| 3031 | − struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; | |
| 3032 | 3031 | const struct rtw89_chip_info *chip = rtwdev->chip; |
| 3033 | 3032 | |
| 3034 | − if (!rtwpci->enable_dac) | |
| 3035 | − return; | |
| 3036 | − | |
| 3037 | 3033 | switch (chip->chip_id) { |
| 3038 | 3034 | case RTL8852A: |
| 3039 | 3035 | case RTL8852B: |
| 3040 | 3036 | case RTL8851B: |
| 3041 | 3037 | case RTL8852BT: |
| 3042 | − break; | |
| 3038 | + return true; | |
| 3043 | 3039 | default: |
| 3044 | − return; | |
| 3040 | + return false; | |
| 3041 | + } | |
| 3042 | +} | |
| 3043 | + | |
| 3044 | +static bool rtw89_pci_is_dac_compatible_bridge(struct rtw89_dev *rtwdev) | |
| 3045 | +{ | |
| 3046 | + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; | |
| 3047 | + struct pci_dev *bridge = pci_upstream_bridge(rtwpci->pdev); | |
| 3048 | + | |
| 3049 | + if (!rtw89_pci_chip_is_manual_dac(rtwdev)) | |
| 3050 | + return true; | |
| 3051 | + | |
| 3052 | + if (!bridge) | |
| 3053 | + return false; | |
| 3054 | + | |
| 3055 | + switch (bridge->vendor) { | |
| 3056 | + case PCI_VENDOR_ID_INTEL: | |
| 3057 | + return true; | |
| 3058 | + case PCI_VENDOR_ID_ASMEDIA: | |
| 3059 | + if (bridge->device == 0x2806) | |
| 3060 | + return true; | |
| 3061 | + break; | |
| 3045 | 3062 | } |
| 3046 | 3063 | |
| 3064 | + return false; | |
| 3065 | +} | |
| 3066 | + | |
| 3067 | +static void rtw89_pci_cfg_dac(struct rtw89_dev *rtwdev) | |
| 3068 | +{ | |
| 3069 | + struct rtw89_pci *rtwpci = (struct rtw89_pci *)rtwdev->priv; | |
| 3070 | + | |
| 3071 | + if (!rtwpci->enable_dac) | |
| 3072 | + return; | |
| 3073 | + | |
| 3074 | + if (!rtw89_pci_chip_is_manual_dac(rtwdev)) | |
| 3075 | + return; | |
| 3076 | + | |
| 3047 | 3077 | rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_L1_CTRL, RTW89_PCIE_BIT_EN_64BITS); |
| 3048 | 3078 | } |
| 3049 | 3079 | |
| @@ -3061,6 +3091,9 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev, · 11 unmodified lines | ||
| 3061 | 3091 | goto err; |
| 3062 | 3092 | } |
| 3063 | 3093 | |
| 3094 | + if (!rtw89_pci_is_dac_compatible_bridge(rtwdev)) | |
| 3095 | + goto no_dac; | |
| 3096 | + | |
| 3064 | 3097 | ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36)); |
| 3065 | 3098 | if (!ret) { |
| 3066 | 3099 | rtwpci->enable_dac = true; |
| @@ -3073,6 +3106,7 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev, · 6 unmodified lines | ||
| 3073 | 3106 | goto err_release_regions; |
| 3074 | 3107 | } |
| 3075 | 3108 | } |
| 3109 | +no_dac: | |
| 3076 | 3110 | |
| 3077 | 3111 | resource_len = pci_resource_len(pdev, bar_id); |
| 3078 | 3112 | rtwpci->mmap = pci_iomap(pdev, bar_id, resource_len); |
| @@ -763,7 +763,7 @@ static const struct rhashtable_params hwsim_rht_params = { · 762 unmodified lines | ||
| 763 | 763 | }; |
| 764 | 764 | |
| 765 | 765 | struct hwsim_radiotap_hdr { |
| 766 | − struct ieee80211_radiotap_header hdr; | |
| 766 | + struct ieee80211_radiotap_header_fixed hdr; | |
| 767 | 767 | __le64 rt_tsft; |
| 768 | 768 | u8 rt_flags; |
| 769 | 769 | u8 rt_rate; |
| @@ -772,7 +772,7 @@ struct hwsim_radiotap_hdr { · 2 unmodified lines | ||
| 772 | 772 | } __packed; |
| 773 | 773 | |
| 774 | 774 | struct hwsim_radiotap_ack_hdr { |
| 775 | − struct ieee80211_radiotap_header hdr; | |
| 775 | + struct ieee80211_radiotap_header_fixed hdr; | |
| 776 | 776 | u8 rt_flags; |
| 777 | 777 | u8 pad; |
| 778 | 778 | __le16 rt_channel; |
| @@ -1038,7 +1038,7 @@ static const struct nla_policy wwan_rtnl_policy[IFLA_WWAN_MAX + 1] = { · 1037 unmodified lines | ||
| 1038 | 1038 | |
| 1039 | 1039 | static struct rtnl_link_ops wwan_rtnl_link_ops __read_mostly = { |
| 1040 | 1040 | .kind = "wwan", |
| 1041 | − .maxtype = __IFLA_WWAN_MAX, | |
| 1041 | + .maxtype = IFLA_WWAN_MAX, | |
| 1042 | 1042 | .alloc = wwan_rtnl_alloc, |
| 1043 | 1043 | .validate = wwan_rtnl_validate, |
| 1044 | 1044 | .newlink = wwan_rtnl_newlink, |
| @@ -91,6 +91,17 @@ module_param(apst_secondary_latency_tol_us, ulong, 0644); · 90 unmodified lines | ||
| 91 | 91 | MODULE_PARM_DESC(apst_secondary_latency_tol_us, |
| 92 | 92 | "secondary APST latency tolerance in us"); |
| 93 | 93 | |
| 94 | +/* | |
| 95 | + * Older kernels didn't enable protection information if it was at an offset. | |
| 96 | + * Newer kernels do, so it breaks reads on the upgrade if such formats were | |
| 97 | + * used in prior kernels since the metadata written did not contain a valid | |
| 98 | + * checksum. | |
| 99 | + */ | |
| 100 | +static bool disable_pi_offsets = false; | |
| 101 | +module_param(disable_pi_offsets, bool, 0444); | |
| 102 | +MODULE_PARM_DESC(disable_pi_offsets, | |
| 103 | + "disable protection information if it has an offset"); | |
| 104 | + | |
| 94 | 105 | /* |
| 95 | 106 | * nvme_wq - hosts nvme related works that are not reset or delete |
| 96 | 107 | * nvme_reset_wq - hosts nvme reset works |
| @@ -1292,14 +1303,12 @@ static void nvme_queue_keep_alive_work(struct nvme_ctrl *ctrl) · 1195 unmodified lines | ||
| 1292 | 1303 | queue_delayed_work(nvme_wq, &ctrl->ka_work, delay); |
| 1293 | 1304 | } |
| 1294 | 1305 | |
| 1295 | −static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq, | |
| 1296 | − blk_status_t status) | |
| 1306 | +static void nvme_keep_alive_finish(struct request *rq, | |
| 1307 | + blk_status_t status, struct nvme_ctrl *ctrl) | |
| 1297 | 1308 | { |
| 1298 | − struct nvme_ctrl *ctrl = rq->end_io_data; | |
| 1299 | − unsigned long flags; | |
| 1300 | − bool startka = false; | |
| 1301 | 1309 | unsigned long rtt = jiffies - (rq->deadline - rq->timeout); |
| 1302 | 1310 | unsigned long delay = nvme_keep_alive_work_period(ctrl); |
| 1311 | + enum nvme_ctrl_state state = nvme_ctrl_state(ctrl); | |
| 1303 | 1312 | |
| 1304 | 1313 | /* |
| 1305 | 1314 | * Subtract off the keepalive RTT so nvme_keep_alive_work runs |
| @@ -1313,25 +1322,17 @@ static enum rq_end_io_ret nvme_keep_alive_end_io(struct request *rq, · 7 unmodified lines | ||
| 1313 | 1322 | delay = 0; |
| 1314 | 1323 | } |
| 1315 | 1324 | |
| 1316 | − blk_mq_free_request(rq); | |
| 1317 | − | |
| 1318 | 1325 | if (status) { |
| 1319 | 1326 | dev_err(ctrl->device, |
| 1320 | 1327 | "failed nvme_keep_alive_end_io error=%d\n", |
| 1321 | 1328 | status); |
| 1322 | − return RQ_END_IO_NONE; | |
| 1329 | + return; | |
| 1323 | 1330 | } |
| 1324 | 1331 | |
| 1325 | 1332 | ctrl->ka_last_check_time = jiffies; |
| 1326 | 1333 | ctrl->comp_seen = false; |
| 1327 | − spin_lock_irqsave(&ctrl->lock, flags); | |
| 1328 | − if (ctrl->state == NVME_CTRL_LIVE || | |
| 1329 | − ctrl->state == NVME_CTRL_CONNECTING) | |
| 1330 | − startka = true; | |
| 1331 | − spin_unlock_irqrestore(&ctrl->lock, flags); | |
| 1332 | − if (startka) | |
| 1334 | + if (state == NVME_CTRL_LIVE || state == NVME_CTRL_CONNECTING) | |
| 1333 | 1335 | queue_delayed_work(nvme_wq, &ctrl->ka_work, delay); |
| 1334 | − return RQ_END_IO_NONE; | |
| 1335 | 1336 | } |
| 1336 | 1337 | |
| 1337 | 1338 | static void nvme_keep_alive_work(struct work_struct *work) |
| @@ -1340,6 +1341,7 @@ static void nvme_keep_alive_work(struct work_struct *work) · 2 unmodified lines | ||
| 1340 | 1341 | struct nvme_ctrl, ka_work); |
| 1341 | 1342 | bool comp_seen = ctrl->comp_seen; |
| 1342 | 1343 | struct request *rq; |
| 1344 | + blk_status_t status; | |
| 1343 | 1345 | |
| 1344 | 1346 | ctrl->ka_last_check_time = jiffies; |
| 1345 | 1347 | |
| @@ -1362,9 +1364,9 @@ static void nvme_keep_alive_work(struct work_struct *work) · 16 unmodified lines | ||
| 1362 | 1364 | nvme_init_request(rq, &ctrl->ka_cmd); |
| 1363 | 1365 | |
| 1364 | 1366 | rq->timeout = ctrl->kato * HZ; |
| 1365 | − rq->end_io = nvme_keep_alive_end_io; | |
| 1366 | − rq->end_io_data = ctrl; | |
| 1367 | − blk_execute_rq_nowait(rq, false); | |
| 1367 | + status = blk_execute_rq(rq, false); | |
| 1368 | + nvme_keep_alive_finish(rq, status, ctrl); | |
| 1369 | + blk_mq_free_request(rq); | |
| 1368 | 1370 | } |
| 1369 | 1371 | |
| 1370 | 1372 | static void nvme_start_keep_alive(struct nvme_ctrl *ctrl) |
| @@ -1399,17 +1401,30 @@ static void nvme_update_keep_alive(struct nvme_ctrl *ctrl, · 28 unmodified lines | ||
| 1399 | 1401 | nvme_start_keep_alive(ctrl); |
| 1400 | 1402 | } |
| 1401 | 1403 | |
| 1402 | −/* | |
| 1403 | − * In NVMe 1.0 the CNS field was just a binary controller or namespace | |
| 1404 | − * flag, thus sending any new CNS opcodes has a big chance of not working. | |
| 1405 | − * Qemu unfortunately had that bug after reporting a 1.1 version compliance | |
| 1406 | − * (but not for any later version). | |
| 1407 | − */ | |
| 1408 | −static bool nvme_ctrl_limited_cns(struct nvme_ctrl *ctrl) | |
| 1404 | +static bool nvme_id_cns_ok(struct nvme_ctrl *ctrl, u8 cns) | |
| 1409 | 1405 | { |
| 1410 | − if (ctrl->quirks & NVME_QUIRK_IDENTIFY_CNS) | |
| 1411 | − return ctrl->vs < NVME_VS(1, 2, 0); | |
| 1412 | − return ctrl->vs < NVME_VS(1, 1, 0); | |
| 1406 | + /* | |
| 1407 | + * The CNS field occupies a full byte starting with NVMe 1.2 | |
| 1408 | + */ | |
| 1409 | + if (ctrl->vs >= NVME_VS(1, 2, 0)) | |
| 1410 | + return true; | |
| 1411 | + | |
| 1412 | + /* | |
| 1413 | + * NVMe 1.1 expanded the CNS value to two bits, which means values | |
| 1414 | + * larger than that could get truncated and treated as an incorrect | |
| 1415 | + * value. | |
| 1416 | + * | |
| 1417 | + * Qemu implemented 1.0 behavior for controllers claiming 1.1 | |
| 1418 | + * compliance, so they need to be quirked here. | |
| 1419 | + */ | |
| 1420 | + if (ctrl->vs >= NVME_VS(1, 1, 0) && | |
| 1421 | + !(ctrl->quirks & NVME_QUIRK_IDENTIFY_CNS)) | |
| 1422 | + return cns <= 3; | |
| 1423 | + | |
| 1424 | + /* | |
| 1425 | + * NVMe 1.0 used a single bit for the CNS value. | |
| 1426 | + */ | |
| 1427 | + return cns <= 1; | |
| 1413 | 1428 | } |
| 1414 | 1429 | |
| 1415 | 1430 | static int nvme_identify_ctrl(struct nvme_ctrl *dev, struct nvme_id_ctrl **id) |
| @@ -1922,8 +1937,12 @@ static void nvme_configure_metadata(struct nvme_ctrl *ctrl, · 506 unmodified lines | ||
| 1922 | 1937 | |
| 1923 | 1938 | if (head->pi_size && head->ms >= head->pi_size) |
| 1924 | 1939 | head->pi_type = id->dps & NVME_NS_DPS_PI_MASK; |
| 1925 | − if (!(id->dps & NVME_NS_DPS_PI_FIRST)) | |
| 1926 | − info->pi_offset = head->ms - head->pi_size; | |
| 1940 | + if (!(id->dps & NVME_NS_DPS_PI_FIRST)) { | |
| 1941 | + if (disable_pi_offsets) | |
| 1942 | + head->pi_type = 0; | |
| 1943 | + else | |
| 1944 | + info->pi_offset = head->ms - head->pi_size; | |
| 1945 | + } | |
| 1927 | 1946 | |
| 1928 | 1947 | if (ctrl->ops->flags & NVME_F_FABRICS) { |
| 1929 | 1948 | /* |
| @@ -2458,8 +2477,13 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl) · 528 unmodified lines | ||
| 2458 | 2477 | else |
| 2459 | 2478 | ctrl->ctrl_config = NVME_CC_CSS_NVM; |
| 2460 | 2479 | |
| 2461 | − if (ctrl->cap & NVME_CAP_CRMS_CRWMS && ctrl->cap & NVME_CAP_CRMS_CRIMS) | |
| 2462 | − ctrl->ctrl_config |= NVME_CC_CRIME; | |
| 2480 | + /* | |
| 2481 | + * Setting CRIME results in CSTS.RDY before the media is ready. This | |
| 2482 | + * makes it possible for media related commands to return the error | |
| 2483 | + * NVME_SC_ADMIN_COMMAND_MEDIA_NOT_READY. Until the driver is | |
| 2484 | + * restructured to handle retries, disable CC.CRIME. | |
| 2485 | + */ | |
| 2486 | + ctrl->ctrl_config &= ~NVME_CC_CRIME; | |
| 2463 | 2487 | |
| 2464 | 2488 | ctrl->ctrl_config |= (NVME_CTRL_PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT; |
| 2465 | 2489 | ctrl->ctrl_config |= NVME_CC_AMS_RR | NVME_CC_SHN_NONE; |
| @@ -2489,10 +2513,7 @@ int nvme_enable_ctrl(struct nvme_ctrl *ctrl) · 23 unmodified lines | ||
| 2489 | 2513 | * devices are known to get this wrong. Use the larger of the |
| 2490 | 2514 | * two values. |
| 2491 | 2515 | */ |
| 2492 | − if (ctrl->ctrl_config & NVME_CC_CRIME) | |
| 2493 | − ready_timeout = NVME_CRTO_CRIMT(crto); | |
| 2494 | − else | |
| 2495 | − ready_timeout = NVME_CRTO_CRWMT(crto); | |
| 2516 | + ready_timeout = NVME_CRTO_CRWMT(crto); | |
| 2496 | 2517 | |
| 2497 | 2518 | if (ready_timeout < timeout) |
| 2498 | 2519 | dev_warn_once(ctrl->device, "bad crto:%x cap:%llx\n", |
| @@ -3111,7 +3132,7 @@ static int nvme_init_non_mdts_limits(struct nvme_ctrl *ctrl) · 612 unmodified lines | ||
| 3111 | 3132 | ctrl->max_zeroes_sectors = 0; |
| 3112 | 3133 | |
| 3113 | 3134 | if (ctrl->subsys->subtype != NVME_NQN_NVME || |
| 3114 | − nvme_ctrl_limited_cns(ctrl) || | |
| 3135 | + !nvme_id_cns_ok(ctrl, NVME_ID_CNS_CS_CTRL) || | |
| 3115 | 3136 | test_bit(NVME_CTRL_SKIP_ID_CNS_CS, &ctrl->flags)) |
| 3116 | 3137 | return 0; |
| 3117 | 3138 | |
| @@ -4207,7 +4228,7 @@ static void nvme_scan_work(struct work_struct *work) · 1089 unmodified lines | ||
| 4207 | 4228 | } |
| 4208 | 4229 | |
| 4209 | 4230 | mutex_lock(&ctrl->scan_lock); |
| 4210 | − if (nvme_ctrl_limited_cns(ctrl)) { | |
| 4231 | + if (!nvme_id_cns_ok(ctrl, NVME_ID_CNS_NS_ACTIVE_LIST)) { | |
| 4211 | 4232 | nvme_scan_ns_sequential(ctrl); |
| 4212 | 4233 | } else { |
| 4213 | 4234 | /* |
| @@ -421,10 +421,13 @@ static enum rq_end_io_ret nvme_uring_cmd_end_io(struct request *req, · 420 unmodified lines | ||
| 421 | 421 | struct io_uring_cmd *ioucmd = req->end_io_data; |
| 422 | 422 | struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd); |
| 423 | 423 | |
| 424 | − if (nvme_req(req)->flags & NVME_REQ_CANCELLED) | |
| 424 | + if (nvme_req(req)->flags & NVME_REQ_CANCELLED) { | |
| 425 | 425 | pdu->status = -EINTR; |
| 426 | − else | |
| 426 | + } else { | |
| 427 | 427 | pdu->status = nvme_req(req)->status; |
| 428 | + if (!pdu->status) | |
| 429 | + pdu->status = blk_status_to_errno(err); | |
| 430 | + } | |
| 428 | 431 | pdu->result = le64_to_cpu(nvme_req(req)->result.u64); |
| 429 | 432 | |
| 430 | 433 | /* |
| @@ -431,7 +431,6 @@ static bool nvme_available_path(struct nvme_ns_head *head) · 430 unmodified lines | ||
| 431 | 431 | case NVME_CTRL_LIVE: |
| 432 | 432 | case NVME_CTRL_RESETTING: |
| 433 | 433 | case NVME_CTRL_CONNECTING: |
| 434 | − /* fallthru */ | |
| 435 | 434 | return true; |
| 436 | 435 | default: |
| 437 | 436 | break; |
| @@ -580,6 +579,20 @@ static int nvme_add_ns_head_cdev(struct nvme_ns_head *head) · 142 unmodified lines | ||
| 580 | 579 | return ret; |
| 581 | 580 | } |
| 582 | 581 | |
| 582 | +static void nvme_partition_scan_work(struct work_struct *work) | |
| 583 | +{ | |
| 584 | + struct nvme_ns_head *head = | |
| 585 | + container_of(work, struct nvme_ns_head, partition_scan_work); | |
| 586 | + | |
| 587 | + if (WARN_ON_ONCE(!test_and_clear_bit(GD_SUPPRESS_PART_SCAN, | |
| 588 | + &head->disk->state))) | |
| 589 | + return; | |
| 590 | + | |
| 591 | + mutex_lock(&head->disk->open_mutex); | |
| 592 | + bdev_disk_changed(head->disk, false); | |
| 593 | + mutex_unlock(&head->disk->open_mutex); | |
| 594 | +} | |
| 595 | + | |
| 583 | 596 | static void nvme_requeue_work(struct work_struct *work) |
| 584 | 597 | { |
| 585 | 598 | struct nvme_ns_head *head = |
| @@ -606,6 +619,7 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head) · 20 unmodified lines | ||
| 606 | 619 | bio_list_init(&head->requeue_list); |
| 607 | 620 | spin_lock_init(&head->requeue_lock); |
| 608 | 621 | INIT_WORK(&head->requeue_work, nvme_requeue_work); |
| 622 | + INIT_WORK(&head->partition_scan_work, nvme_partition_scan_work); | |
| 609 | 623 | |
| 610 | 624 | /* |
| 611 | 625 | * Add a multipath node if the subsystems supports multiple controllers. |
| @@ -629,6 +643,16 @@ int nvme_mpath_alloc_disk(struct nvme_ctrl *ctrl, struct nvme_ns_head *head) · 17 unmodified lines | ||
| 629 | 643 | return PTR_ERR(head->disk); |
| 630 | 644 | head->disk->fops = &nvme_ns_head_ops; |
| 631 | 645 | head->disk->private_data = head; |
| 646 | + | |
| 647 | + /* | |
| 648 | + * We need to suppress the partition scan from occuring within the | |
| 649 | + * controller's scan_work context. If a path error occurs here, the IO | |
| 650 | + * will wait until a path becomes available or all paths are torn down, | |
| 651 | + * but that action also occurs within scan_work, so it would deadlock. | |
| 652 | + * Defer the partion scan to a different context that does not block | |
| 653 | + * scan_work. | |
| 654 | + */ | |
| 655 | + set_bit(GD_SUPPRESS_PART_SCAN, &head->disk->state); | |
| 632 | 656 | sprintf(head->disk->disk_name, "nvme%dn%d", |
| 633 | 657 | ctrl->subsys->instance, head->instance); |
| 634 | 658 | return 0; |
| @@ -655,6 +679,7 @@ static void nvme_mpath_set_live(struct nvme_ns *ns) · 20 unmodified lines | ||
| 655 | 679 | return; |
| 656 | 680 | } |
| 657 | 681 | nvme_add_ns_head_cdev(head); |
| 682 | + kblockd_schedule_work(&head->partition_scan_work); | |
| 658 | 683 | } |
| 659 | 684 | |
| 660 | 685 | mutex_lock(&head->lock); |
| @@ -974,14 +999,14 @@ void nvme_mpath_shutdown_disk(struct nvme_ns_head *head) · 313 unmodified lines | ||
| 974 | 999 | return; |
| 975 | 1000 | if (test_and_clear_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) { |
| 976 | 1001 | nvme_cdev_del(&head->cdev, &head->cdev_device); |
| 1002 | + /* | |
| 1003 | + * requeue I/O after NVME_NSHEAD_DISK_LIVE has been cleared | |
| 1004 | + * to allow multipath to fail all I/O. | |
| 1005 | + */ | |
| 1006 | + synchronize_srcu(&head->srcu); | |
| 1007 | + kblockd_schedule_work(&head->requeue_work); | |
| 977 | 1008 | del_gendisk(head->disk); |
| 978 | 1009 | } |
| 979 | − /* | |
| 980 | − * requeue I/O after NVME_NSHEAD_DISK_LIVE has been cleared | |
| 981 | − * to allow multipath to fail all I/O. | |
| 982 | − */ | |
| 983 | − synchronize_srcu(&head->srcu); | |
| 984 | − kblockd_schedule_work(&head->requeue_work); | |
| 985 | 1010 | } |
| 986 | 1011 | |
| 987 | 1012 | void nvme_mpath_remove_disk(struct nvme_ns_head *head) |
| @@ -991,6 +1016,7 @@ void nvme_mpath_remove_disk(struct nvme_ns_head *head) · 3 unmodified lines | ||
| 991 | 1016 | /* make sure all pending bios are cleaned up */ |
| 992 | 1017 | kblockd_schedule_work(&head->requeue_work); |
| 993 | 1018 | flush_work(&head->requeue_work); |
| 1019 | + flush_work(&head->partition_scan_work); | |
| 994 | 1020 | put_disk(head->disk); |
| 995 | 1021 | } |
| 996 | 1022 | |
| @@ -494,6 +494,7 @@ struct nvme_ns_head { · 493 unmodified lines | ||
| 494 | 494 | struct bio_list requeue_list; |
| 495 | 495 | spinlock_t requeue_lock; |
| 496 | 496 | struct work_struct requeue_work; |
| 497 | + struct work_struct partition_scan_work; | |
| 497 | 498 | struct mutex lock; |
| 498 | 499 | unsigned long flags; |
| 499 | 500 | #define NVME_NSHEAD_DISK_LIVE 0 |
| @@ -2506,17 +2506,29 @@ static unsigned int nvme_pci_nr_maps(struct nvme_dev *dev) · 2505 unmodified lines | ||
| 2506 | 2506 | return 1; |
| 2507 | 2507 | } |
| 2508 | 2508 | |
| 2509 | −static void nvme_pci_update_nr_queues(struct nvme_dev *dev) | |
| 2509 | +static bool nvme_pci_update_nr_queues(struct nvme_dev *dev) | |
| 2510 | 2510 | { |
| 2511 | 2511 | if (!dev->ctrl.tagset) { |
| 2512 | 2512 | nvme_alloc_io_tag_set(&dev->ctrl, &dev->tagset, &nvme_mq_ops, |
| 2513 | 2513 | nvme_pci_nr_maps(dev), sizeof(struct nvme_iod)); |
| 2514 | − return; | |
| 2514 | + return true; | |
| 2515 | + } | |
| 2516 | + | |
| 2517 | + /* Give up if we are racing with nvme_dev_disable() */ | |
| 2518 | + if (!mutex_trylock(&dev->shutdown_lock)) | |
| 2519 | + return false; | |
| 2520 | + | |
| 2521 | + /* Check if nvme_dev_disable() has been executed already */ | |
| 2522 | + if (!dev->online_queues) { | |
| 2523 | + mutex_unlock(&dev->shutdown_lock); | |
| 2524 | + return false; | |
| 2515 | 2525 | } |
| 2516 | 2526 | |
| 2517 | 2527 | blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1); |
| 2518 | 2528 | /* free previously allocated queues that are no longer usable */ |
| 2519 | 2529 | nvme_free_queues(dev, dev->online_queues); |
| 2530 | + mutex_unlock(&dev->shutdown_lock); | |
| 2531 | + return true; | |
| 2520 | 2532 | } |
| 2521 | 2533 | |
| 2522 | 2534 | static int nvme_pci_enable(struct nvme_dev *dev) |
| @@ -2797,7 +2809,8 @@ static void nvme_reset_work(struct work_struct *work) · 274 unmodified lines | ||
| 2797 | 2809 | nvme_dbbuf_set(dev); |
| 2798 | 2810 | nvme_unquiesce_io_queues(&dev->ctrl); |
| 2799 | 2811 | nvme_wait_freeze(&dev->ctrl); |
| 2800 | − nvme_pci_update_nr_queues(dev); | |
| 2812 | + if (!nvme_pci_update_nr_queues(dev)) | |
| 2813 | + goto out; | |
| 2801 | 2814 | nvme_unfreeze(&dev->ctrl); |
| 2802 | 2815 | } else { |
| 2803 | 2816 | dev_warn(dev->ctrl.device, "IO queues lost\n"); |
| @@ -2644,10 +2644,11 @@ static int nvme_tcp_get_address(struct nvme_ctrl *ctrl, char *buf, int size) · 2643 unmodified lines | ||
| 2644 | 2644 | |
| 2645 | 2645 | len = nvmf_get_address(ctrl, buf, size); |
| 2646 | 2646 | |
| 2647 | + if (!test_bit(NVME_TCP_Q_LIVE, &queue->flags)) | |
| 2648 | + return len; | |
| 2649 | + | |
| 2647 | 2650 | mutex_lock(&queue->queue_lock); |
| 2648 | 2651 | |
| 2649 | − if (!test_bit(NVME_TCP_Q_LIVE, &queue->flags)) | |
| 2650 | − goto done; | |
| 2651 | 2652 | ret = kernel_getsockname(queue->sock, (struct sockaddr *)&src_addr); |
| 2652 | 2653 | if (ret > 0) { |
| 2653 | 2654 | if (len > 0) |
| @@ -2655,7 +2656,7 @@ static int nvme_tcp_get_address(struct nvme_ctrl *ctrl, char *buf, int size) · 1 unmodified line | ||
| 2655 | 2656 | len += scnprintf(buf + len, size - len, "%ssrc_addr=%pISc\n", |
| 2656 | 2657 | (len) ? "," : "", &src_addr); |
| 2657 | 2658 | } |
| 2658 | −done: | |
| 2659 | + | |
| 2659 | 2660 | mutex_unlock(&queue->queue_lock); |
| 2660 | 2661 | |
| 2661 | 2662 | return len; |
| @@ -115,6 +115,7 @@ int nvmet_setup_dhgroup(struct nvmet_ctrl *ctrl, u8 dhgroup_id) · 114 unmodified lines | ||
| 115 | 115 | pr_debug("%s: ctrl %d failed to generate private key, err %d\n", |
| 116 | 116 | __func__, ctrl->cntlid, ret); |
| 117 | 117 | kfree_sensitive(ctrl->dh_key); |
| 118 | + ctrl->dh_key = NULL; | |
| 118 | 119 | return ret; |
| 119 | 120 | } |
| 120 | 121 | ctrl->dh_keysize = crypto_kpp_maxsize(ctrl->dh_tfm); |
| @@ -265,6 +265,13 @@ static void nvme_loop_destroy_admin_queue(struct nvme_loop_ctrl *ctrl) · 264 unmodified lines | ||
| 265 | 265 | { |
| 266 | 266 | if (!test_and_clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[0].flags)) |
| 267 | 267 | return; |
| 268 | + /* | |
| 269 | + * It's possible that some requests might have been added | |
| 270 | + * after admin queue is stopped/quiesced. So now start the | |
| 271 | + * queue to flush these requests to the completion. | |
| 272 | + */ | |
| 273 | + nvme_unquiesce_admin_queue(&ctrl->ctrl); | |
| 274 | + | |
| 268 | 275 | nvmet_sq_destroy(&ctrl->queues[0].nvme_sq); |
| 269 | 276 | nvme_remove_admin_tag_set(&ctrl->ctrl); |
| 270 | 277 | } |
| @@ -297,6 +304,12 @@ static void nvme_loop_destroy_io_queues(struct nvme_loop_ctrl *ctrl) · 26 unmodified lines | ||
| 297 | 304 | nvmet_sq_destroy(&ctrl->queues[i].nvme_sq); |
| 298 | 305 | } |
| 299 | 306 | ctrl->ctrl.queue_count = 1; |
| 307 | + /* | |
| 308 | + * It's possible that some requests might have been added | |
| 309 | + * after io queue is stopped/quiesced. So now start the | |
| 310 | + * queue to flush these requests to the completion. | |
| 311 | + */ | |
| 312 | + nvme_unquiesce_io_queues(&ctrl->ctrl); | |
| 300 | 313 | } |
| 301 | 314 | |
| 302 | 315 | static int nvme_loop_init_io_queues(struct nvme_loop_ctrl *ctrl) |
| @@ -535,10 +535,6 @@ u16 nvmet_parse_passthru_admin_cmd(struct nvmet_req *req) · 534 unmodified lines | ||
| 535 | 535 | break; |
| 536 | 536 | case nvme_admin_identify: |
| 537 | 537 | switch (req->cmd->identify.cns) { |
| 538 | − case NVME_ID_CNS_CTRL: | |
| 539 | − req->execute = nvmet_passthru_execute_cmd; | |
| 540 | − req->p.use_workqueue = true; | |
| 541 | − return NVME_SC_SUCCESS; | |
| 542 | 538 | case NVME_ID_CNS_CS_CTRL: |
| 543 | 539 | switch (req->cmd->identify.csi) { |
| 544 | 540 | case NVME_CSI_ZNS: |
| @@ -547,7 +543,9 @@ u16 nvmet_parse_passthru_admin_cmd(struct nvmet_req *req) · 2 unmodified lines | ||
| 547 | 543 | return NVME_SC_SUCCESS; |
| 548 | 544 | } |
| 549 | 545 | return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; |
| 546 | + case NVME_ID_CNS_CTRL: | |
| 550 | 547 | case NVME_ID_CNS_NS: |
| 548 | + case NVME_ID_CNS_NS_DESC_LIST: | |
| 551 | 549 | req->execute = nvmet_passthru_execute_cmd; |
| 552 | 550 | req->p.use_workqueue = true; |
| 553 | 551 | return NVME_SC_SUCCESS; |
| @@ -39,6 +39,8 @@ · 38 unmodified lines | ||
| 39 | 39 | |
| 40 | 40 | #define NVMET_RDMA_BACKLOG 128 |
| 41 | 41 | |
| 42 | +#define NVMET_RDMA_DISCRETE_RSP_TAG -1 | |
| 43 | + | |
| 42 | 44 | struct nvmet_rdma_srq; |
| 43 | 45 | |
| 44 | 46 | struct nvmet_rdma_cmd { |
| @@ -75,7 +77,7 @@ struct nvmet_rdma_rsp { · 30 unmodified lines | ||
| 75 | 77 | u32 invalidate_rkey; |
| 76 | 78 | |
| 77 | 79 | struct list_head wait_list; |
| 78 | − struct list_head free_list; | |
| 80 | + int tag; | |
| 79 | 81 | }; |
| 80 | 82 | |
| 81 | 83 | enum nvmet_rdma_queue_state { |
| @@ -98,8 +100,7 @@ struct nvmet_rdma_queue { · 16 unmodified lines | ||
| 98 | 100 | struct nvmet_sq nvme_sq; |
| 99 | 101 | |
| 100 | 102 | struct nvmet_rdma_rsp *rsps; |
| 101 | − struct list_head free_rsps; | |
| 102 | − spinlock_t rsps_lock; | |
| 103 | + struct sbitmap rsp_tags; | |
| 103 | 104 | struct nvmet_rdma_cmd *cmds; |
| 104 | 105 | |
| 105 | 106 | struct work_struct release_work; |
| @@ -172,7 +173,8 @@ static void nvmet_rdma_queue_disconnect(struct nvmet_rdma_queue *queue); · 66 unmodified lines | ||
| 172 | 173 | static void nvmet_rdma_free_rsp(struct nvmet_rdma_device *ndev, |
| 173 | 174 | struct nvmet_rdma_rsp *r); |
| 174 | 175 | static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev, |
| 175 | − struct nvmet_rdma_rsp *r); | |
| 176 | + struct nvmet_rdma_rsp *r, | |
| 177 | + int tag); | |
| 176 | 178 | |
| 177 | 179 | static const struct nvmet_fabrics_ops nvmet_rdma_ops; |
| 178 | 180 | |
| @@ -210,15 +212,12 @@ static inline bool nvmet_rdma_need_data_out(struct nvmet_rdma_rsp *rsp) · 31 unmodified lines | ||
| 210 | 212 | static inline struct nvmet_rdma_rsp * |
| 211 | 213 | nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue) |
| 212 | 214 | { |
| 213 | − struct nvmet_rdma_rsp *rsp; | |
| 214 | − unsigned long flags; | |
| 215 | + struct nvmet_rdma_rsp *rsp = NULL; | |
| 216 | + int tag; | |
| 215 | 217 | |
| 216 | − spin_lock_irqsave(&queue->rsps_lock, flags); | |
| 217 | − rsp = list_first_entry_or_null(&queue->free_rsps, | |
| 218 | − struct nvmet_rdma_rsp, free_list); | |
| 219 | − if (likely(rsp)) | |
| 220 | − list_del(&rsp->free_list); | |
| 221 | − spin_unlock_irqrestore(&queue->rsps_lock, flags); | |
| 218 | + tag = sbitmap_get(&queue->rsp_tags); | |
| 219 | + if (tag >= 0) | |
| 220 | + rsp = &queue->rsps[tag]; | |
| 222 | 221 | |
| 223 | 222 | if (unlikely(!rsp)) { |
| 224 | 223 | int ret; |
| @@ -226,13 +225,12 @@ nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue) · 1 unmodified line | ||
| 226 | 225 | rsp = kzalloc(sizeof(*rsp), GFP_KERNEL); |
| 227 | 226 | if (unlikely(!rsp)) |
| 228 | 227 | return NULL; |
| 229 | − ret = nvmet_rdma_alloc_rsp(queue->dev, rsp); | |
| 228 | + ret = nvmet_rdma_alloc_rsp(queue->dev, rsp, | |
| 229 | + NVMET_RDMA_DISCRETE_RSP_TAG); | |
| 230 | 230 | if (unlikely(ret)) { |
| 231 | 231 | kfree(rsp); |
| 232 | 232 | return NULL; |
| 233 | 233 | } |
| 234 | − | |
| 235 | − rsp->allocated = true; | |
| 236 | 234 | } |
| 237 | 235 | |
| 238 | 236 | return rsp; |
| @@ -241,17 +239,13 @@ nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue) · 2 unmodified lines | ||
| 241 | 239 | static inline void |
| 242 | 240 | nvmet_rdma_put_rsp(struct nvmet_rdma_rsp *rsp) |
| 243 | 241 | { |
| 244 | − unsigned long flags; | |
| 245 | − | |
| 246 | − if (unlikely(rsp->allocated)) { | |
| 242 | + if (unlikely(rsp->tag == NVMET_RDMA_DISCRETE_RSP_TAG)) { | |
| 247 | 243 | nvmet_rdma_free_rsp(rsp->queue->dev, rsp); |
| 248 | 244 | kfree(rsp); |
| 249 | 245 | return; |
| 250 | 246 | } |
| 251 | 247 | |
| 252 | − spin_lock_irqsave(&rsp->queue->rsps_lock, flags); | |
| 253 | − list_add_tail(&rsp->free_list, &rsp->queue->free_rsps); | |
| 254 | − spin_unlock_irqrestore(&rsp->queue->rsps_lock, flags); | |
| 248 | + sbitmap_clear_bit(&rsp->queue->rsp_tags, rsp->tag); | |
| 255 | 249 | } |
| 256 | 250 | |
| 257 | 251 | static void nvmet_rdma_free_inline_pages(struct nvmet_rdma_device *ndev, |
| @@ -404,7 +398,7 @@ static void nvmet_rdma_free_cmds(struct nvmet_rdma_device *ndev, · 146 unmodified lines | ||
| 404 | 398 | } |
| 405 | 399 | |
| 406 | 400 | static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev, |
| 407 | − struct nvmet_rdma_rsp *r) | |
| 401 | + struct nvmet_rdma_rsp *r, int tag) | |
| 408 | 402 | { |
| 409 | 403 | /* NVMe CQE / RDMA SEND */ |
| 410 | 404 | r->req.cqe = kmalloc(sizeof(*r->req.cqe), GFP_KERNEL); |
| @@ -432,6 +426,7 @@ static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev, · 21 unmodified lines | ||
| 432 | 426 | r->read_cqe.done = nvmet_rdma_read_data_done; |
| 433 | 427 | /* Data Out / RDMA WRITE */ |
| 434 | 428 | r->write_cqe.done = nvmet_rdma_write_data_done; |
| 429 | + r->tag = tag; | |
| 435 | 430 | |
| 436 | 431 | return 0; |
| 437 | 432 | |
| @@ -454,21 +449,23 @@ nvmet_rdma_alloc_rsps(struct nvmet_rdma_queue *queue) · 16 unmodified lines | ||
| 454 | 449 | { |
| 455 | 450 | struct nvmet_rdma_device *ndev = queue->dev; |
| 456 | 451 | int nr_rsps = queue->recv_queue_size * 2; |
| 457 | − int ret = -EINVAL, i; | |
| 452 | + int ret = -ENOMEM, i; | |
| 453 | + | |
| 454 | + if (sbitmap_init_node(&queue->rsp_tags, nr_rsps, -1, GFP_KERNEL, | |
| 455 | + NUMA_NO_NODE, false, true)) | |
| 456 | + goto out; | |
| 458 | 457 | |
| 459 | 458 | queue->rsps = kcalloc(nr_rsps, sizeof(struct nvmet_rdma_rsp), |
| 460 | 459 | GFP_KERNEL); |
| 461 | 460 | if (!queue->rsps) |
| 462 | − goto out; | |
| 461 | + goto out_free_sbitmap; | |
| 463 | 462 | |
| 464 | 463 | for (i = 0; i < nr_rsps; i++) { |
| 465 | 464 | struct nvmet_rdma_rsp *rsp = &queue->rsps[i]; |
| 466 | 465 | |
| 467 | − ret = nvmet_rdma_alloc_rsp(ndev, rsp); | |
| 466 | + ret = nvmet_rdma_alloc_rsp(ndev, rsp, i); | |
| 468 | 467 | if (ret) |
| 469 | 468 | goto out_free; |
| 470 | − | |
| 471 | − list_add_tail(&rsp->free_list, &queue->free_rsps); | |
| 472 | 469 | } |
| 473 | 470 | |
| 474 | 471 | return 0; |
| @@ -477,6 +474,8 @@ out_free: · 2 unmodified lines | ||
| 477 | 474 | while (--i >= 0) |
| 478 | 475 | nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); |
| 479 | 476 | kfree(queue->rsps); |
| 477 | +out_free_sbitmap: | |
| 478 | + sbitmap_free(&queue->rsp_tags); | |
| 480 | 479 | out: |
| 481 | 480 | return ret; |
| 482 | 481 | } |
| @@ -489,6 +488,7 @@ static void nvmet_rdma_free_rsps(struct nvmet_rdma_queue *queue) · 6 unmodified lines | ||
| 489 | 488 | for (i = 0; i < nr_rsps; i++) |
| 490 | 489 | nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); |
| 491 | 490 | kfree(queue->rsps); |
| 491 | + sbitmap_free(&queue->rsp_tags); | |
| 492 | 492 | } |
| 493 | 493 | |
| 494 | 494 | static int nvmet_rdma_post_recv(struct nvmet_rdma_device *ndev, |
| @@ -1447,8 +1447,6 @@ nvmet_rdma_alloc_queue(struct nvmet_rdma_device *ndev, · 952 unmodified lines | ||
| 1447 | 1447 | INIT_LIST_HEAD(&queue->rsp_wait_list); |
| 1448 | 1448 | INIT_LIST_HEAD(&queue->rsp_wr_wait_list); |
| 1449 | 1449 | spin_lock_init(&queue->rsp_wr_wait_lock); |
| 1450 | − INIT_LIST_HEAD(&queue->free_rsps); | |
| 1451 | − spin_lock_init(&queue->rsps_lock); | |
| 1452 | 1450 | INIT_LIST_HEAD(&queue->queue_list); |
| 1453 | 1451 | |
| 1454 | 1452 | queue->idx = ida_alloc(&nvmet_rdma_queue_ida, GFP_KERNEL); |
| @@ -10,6 +10,19 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <kunit/test.h> |
| 11 | 11 | #include <kunit/resource.h> |
| 12 | 12 | |
| 13 | +#include "of_private.h" | |
| 14 | + | |
| 15 | +/** | |
| 16 | + * of_root_kunit_skip() - Skip test if the root node isn't populated | |
| 17 | + * @test: test to skip if the root node isn't populated | |
| 18 | + */ | |
| 19 | +void of_root_kunit_skip(struct kunit *test) | |
| 20 | +{ | |
| 21 | + if (IS_ENABLED(CONFIG_ARM64) && IS_ENABLED(CONFIG_ACPI) && !of_root) | |
| 22 | + kunit_skip(test, "arm64+acpi doesn't populate a root node"); | |
| 23 | +} | |
| 24 | +EXPORT_SYMBOL_GPL(of_root_kunit_skip); | |
| 25 | + | |
| 13 | 26 | #if defined(CONFIG_OF_OVERLAY) && defined(CONFIG_OF_EARLY_FLATTREE) |
| 14 | 27 | |
| 15 | 28 | static void of_overlay_fdt_apply_kunit_exit(void *ovcs_id) |
| @@ -36,6 +49,8 @@ int of_overlay_fdt_apply_kunit(struct kunit *test, void *overlay_fdt, · 20 unmodified lines | ||
| 36 | 49 | int ret; |
| 37 | 50 | int *copy_id; |
| 38 | 51 | |
| 52 | + of_root_kunit_skip(test); | |
| 53 | + | |
| 39 | 54 | copy_id = kunit_kmalloc(test, sizeof(*copy_id), GFP_KERNEL); |
| 40 | 55 | if (!copy_id) |
| 41 | 56 | return -ENOMEM; |
| @@ -42,6 +42,9 @@ extern raw_spinlock_t devtree_lock; · 41 unmodified lines | ||
| 42 | 42 | extern struct list_head aliases_lookup; |
| 43 | 43 | extern struct kset *of_kset; |
| 44 | 44 | |
| 45 | +struct kunit; | |
| 46 | +extern void of_root_kunit_skip(struct kunit *test); | |
| 47 | + | |
| 45 | 48 | #if defined(CONFIG_OF_DYNAMIC) |
| 46 | 49 | extern int of_property_notify(int action, struct device_node *np, |
| 47 | 50 | struct property *prop, struct property *old_prop); |
| @@ -7,6 +7,8 @@ · 6 unmodified lines | ||
| 7 | 7 | |
| 8 | 8 | #include <kunit/test.h> |
| 9 | 9 | |
| 10 | +#include "of_private.h" | |
| 11 | + | |
| 10 | 12 | /* |
| 11 | 13 | * Test that the root node "/" can be found by path. |
| 12 | 14 | */ |
| @@ -36,6 +38,7 @@ static struct kunit_case of_dtb_test_cases[] = { · 23 unmodified lines | ||
| 36 | 38 | |
| 37 | 39 | static int of_dtb_test_init(struct kunit *test) |
| 38 | 40 | { |
| 41 | + of_root_kunit_skip(test); | |
| 39 | 42 | if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE)) |
| 40 | 43 | kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE"); |
| 41 | 44 | |
| @@ -11,6 +11,8 @@ · 10 unmodified lines | ||
| 11 | 11 | #include <kunit/of.h> |
| 12 | 12 | #include <kunit/test.h> |
| 13 | 13 | |
| 14 | +#include "of_private.h" | |
| 15 | + | |
| 14 | 16 | static const char * const kunit_node_name = "kunit-test"; |
| 15 | 17 | static const char * const kunit_compatible = "test,empty"; |
| 16 | 18 | |
| @@ -62,6 +64,7 @@ static void of_overlay_apply_kunit_cleanup(struct kunit *test) · 45 unmodified lines | ||
| 62 | 64 | struct device *dev; |
| 63 | 65 | struct device_node *np; |
| 64 | 66 | |
| 67 | + of_root_kunit_skip(test); | |
| 65 | 68 | if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE)) |
| 66 | 69 | kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE for root node"); |
| 67 | 70 | |
| @@ -73,7 +76,7 @@ static void of_overlay_apply_kunit_cleanup(struct kunit *test) · 5 unmodified lines | ||
| 73 | 76 | |
| 74 | 77 | np = of_find_node_by_name(NULL, kunit_node_name); |
| 75 | 78 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, np); |
| 76 | − of_node_put_kunit(test, np); | |
| 79 | + of_node_put_kunit(&fake, np); | |
| 77 | 80 | |
| 78 | 81 | pdev = of_find_device_by_node(np); |
| 79 | 82 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); |
| @@ -2630,8 +2630,10 @@ int dev_pm_opp_set_config(struct device *dev, struct dev_pm_opp_config *config) · 2629 unmodified lines | ||
| 2630 | 2630 | |
| 2631 | 2631 | /* Attach genpds */ |
| 2632 | 2632 | if (config->genpd_names) { |
| 2633 | − if (config->required_devs) | |
| 2633 | + if (config->required_devs) { | |
| 2634 | + ret = -EINVAL; | |
| 2634 | 2635 | goto err; |
| 2636 | + } | |
| 2635 | 2637 | |
| 2636 | 2638 | ret = _opp_attach_genpd(opp_table, dev, config->genpd_names, |
| 2637 | 2639 | config->virt_devs); |
| @@ -51,12 +51,12 @@ static int do_active_device(const struct ctl_table *table, int write, · 50 unmodified lines | ||
| 51 | 51 | |
| 52 | 52 | for (dev = port->devices; dev ; dev = dev->next) { |
| 53 | 53 | if(dev == port->cad) { |
| 54 | − len += snprintf(buffer, sizeof(buffer), "%s\n", dev->name); | |
| 54 | + len += scnprintf(buffer, sizeof(buffer), "%s\n", dev->name); | |
| 55 | 55 | } |
| 56 | 56 | } |
| 57 | 57 | |
| 58 | 58 | if(!len) { |
| 59 | − len += snprintf(buffer, sizeof(buffer), "%s\n", "none"); | |
| 59 | + len += scnprintf(buffer, sizeof(buffer), "%s\n", "none"); | |
| 60 | 60 | } |
| 61 | 61 | |
| 62 | 62 | if (len > *lenp) |
| @@ -87,19 +87,19 @@ static int do_autoprobe(const struct ctl_table *table, int write, · 24 unmodified lines | ||
| 87 | 87 | } |
| 88 | 88 | |
| 89 | 89 | if ((str = info->class_name) != NULL) |
| 90 | − len += snprintf (buffer + len, sizeof(buffer) - len, "CLASS:%s;\n", str); | |
| 90 | + len += scnprintf (buffer + len, sizeof(buffer) - len, "CLASS:%s;\n", str); | |
| 91 | 91 | |
| 92 | 92 | if ((str = info->model) != NULL) |
| 93 | − len += snprintf (buffer + len, sizeof(buffer) - len, "MODEL:%s;\n", str); | |
| 93 | + len += scnprintf (buffer + len, sizeof(buffer) - len, "MODEL:%s;\n", str); | |
| 94 | 94 | |
| 95 | 95 | if ((str = info->mfr) != NULL) |
| 96 | − len += snprintf (buffer + len, sizeof(buffer) - len, "MANUFACTURER:%s;\n", str); | |
| 96 | + len += scnprintf (buffer + len, sizeof(buffer) - len, "MANUFACTURER:%s;\n", str); | |
| 97 | 97 | |
| 98 | 98 | if ((str = info->description) != NULL) |
| 99 | − len += snprintf (buffer + len, sizeof(buffer) - len, "DESCRIPTION:%s;\n", str); | |
| 99 | + len += scnprintf (buffer + len, sizeof(buffer) - len, "DESCRIPTION:%s;\n", str); | |
| 100 | 100 | |
| 101 | 101 | if ((str = info->cmdset) != NULL) |
| 102 | − len += snprintf (buffer + len, sizeof(buffer) - len, "COMMAND SET:%s;\n", str); | |
| 102 | + len += scnprintf (buffer + len, sizeof(buffer) - len, "COMMAND SET:%s;\n", str); | |
| 103 | 103 | |
| 104 | 104 | if (len > *lenp) |
| 105 | 105 | len = *lenp; |
| @@ -128,7 +128,7 @@ static int do_hardware_base_addr(const struct ctl_table *table, int write, · 22 unmodified lines | ||
| 128 | 128 | if (write) /* permissions prevent this anyway */ |
| 129 | 129 | return -EACCES; |
| 130 | 130 | |
| 131 | − len += snprintf (buffer, sizeof(buffer), "%lu\t%lu\n", port->base, port->base_hi); | |
| 131 | + len += scnprintf (buffer, sizeof(buffer), "%lu\t%lu\n", port->base, port->base_hi); | |
| 132 | 132 | |
| 133 | 133 | if (len > *lenp) |
| 134 | 134 | len = *lenp; |
| @@ -155,7 +155,7 @@ static int do_hardware_irq(const struct ctl_table *table, int write, · 20 unmodified lines | ||
| 155 | 155 | if (write) /* permissions prevent this anyway */ |
| 156 | 156 | return -EACCES; |
| 157 | 157 | |
| 158 | − len += snprintf (buffer, sizeof(buffer), "%d\n", port->irq); | |
| 158 | + len += scnprintf (buffer, sizeof(buffer), "%d\n", port->irq); | |
| 159 | 159 | |
| 160 | 160 | if (len > *lenp) |
| 161 | 161 | len = *lenp; |
| @@ -182,7 +182,7 @@ static int do_hardware_dma(const struct ctl_table *table, int write, · 20 unmodified lines | ||
| 182 | 182 | if (write) /* permissions prevent this anyway */ |
| 183 | 183 | return -EACCES; |
| 184 | 184 | |
| 185 | − len += snprintf (buffer, sizeof(buffer), "%d\n", port->dma); | |
| 185 | + len += scnprintf (buffer, sizeof(buffer), "%d\n", port->dma); | |
| 186 | 186 | |
| 187 | 187 | if (len > *lenp) |
| 188 | 188 | len = *lenp; |
| @@ -213,7 +213,7 @@ static int do_hardware_modes(const struct ctl_table *table, int write, · 24 unmodified lines | ||
| 213 | 213 | #define printmode(x) \ |
| 214 | 214 | do { \ |
| 215 | 215 | if (port->modes & PARPORT_MODE_##x) \ |
| 216 | − len += snprintf(buffer + len, sizeof(buffer) - len, "%s%s", f++ ? "," : "", #x); \ | |
| 216 | + len += scnprintf(buffer + len, sizeof(buffer) - len, "%s%s", f++ ? "," : "", #x); \ | |
| 217 | 217 | } while (0) |
| 218 | 218 | int f = 0; |
| 219 | 219 | printmode(PCSPP); |
| @@ -1067,8 +1067,15 @@ static void pci_std_enable_acs(struct pci_dev *dev, struct pci_acs *caps) · 1066 unmodified lines | ||
| 1067 | 1067 | static void pci_enable_acs(struct pci_dev *dev) |
| 1068 | 1068 | { |
| 1069 | 1069 | struct pci_acs caps; |
| 1070 | + bool enable_acs = false; | |
| 1070 | 1071 | int pos; |
| 1071 | 1072 | |
| 1073 | + /* If an iommu is present we start with kernel default caps */ | |
| 1074 | + if (pci_acs_enable) { | |
| 1075 | + if (pci_dev_specific_enable_acs(dev)) | |
| 1076 | + enable_acs = true; | |
| 1077 | + } | |
| 1078 | + | |
| 1072 | 1079 | pos = dev->acs_cap; |
| 1073 | 1080 | if (!pos) |
| 1074 | 1081 | return; |
| @@ -1077,11 +1084,8 @@ static void pci_enable_acs(struct pci_dev *dev) · 2 unmodified lines | ||
| 1077 | 1084 | pci_read_config_word(dev, pos + PCI_ACS_CTRL, &caps.ctrl); |
| 1078 | 1085 | caps.fw_ctrl = caps.ctrl; |
| 1079 | 1086 | |
| 1080 | − /* If an iommu is present we start with kernel default caps */ | |
| 1081 | − if (pci_acs_enable) { | |
| 1082 | − if (pci_dev_specific_enable_acs(dev)) | |
| 1083 | − pci_std_enable_acs(dev, &caps); | |
| 1084 | − } | |
| 1087 | + if (enable_acs) | |
| 1088 | + pci_std_enable_acs(dev, &caps); | |
| 1085 | 1089 | |
| 1086 | 1090 | /* |
| 1087 | 1091 | * Always apply caps from the command line, even if there is no iommu. |
| @@ -3105,7 +3105,9 @@ int pci_host_probe(struct pci_host_bridge *bridge) · 3104 unmodified lines | ||
| 3105 | 3105 | list_for_each_entry(child, &bus->children, node) |
| 3106 | 3106 | pcie_bus_configure_settings(child); |
| 3107 | 3107 | |
| 3108 | + pci_lock_rescan_remove(); | |
| 3108 | 3109 | pci_bus_add_devices(bus); |
| 3110 | + pci_unlock_rescan_remove(); | |
| 3109 | 3111 | return 0; |
| 3110 | 3112 | } |
| 3111 | 3113 | EXPORT_SYMBOL_GPL(pci_host_probe); |
| @@ -6,9 +6,9 @@ · 5 unmodified lines | ||
| 6 | 6 | #include <linux/device.h> |
| 7 | 7 | #include <linux/mod_devicetable.h> |
| 8 | 8 | #include <linux/module.h> |
| 9 | −#include <linux/of.h> | |
| 10 | 9 | #include <linux/pci-pwrctl.h> |
| 11 | 10 | #include <linux/platform_device.h> |
| 11 | +#include <linux/property.h> | |
| 12 | 12 | #include <linux/pwrseq/consumer.h> |
| 13 | 13 | #include <linux/slab.h> |
| 14 | 14 | #include <linux/types.h> |
| @@ -18,6 +18,40 @@ struct pci_pwrctl_pwrseq_data { · 3 unmodified lines | ||
| 18 | 18 | struct pwrseq_desc *pwrseq; |
| 19 | 19 | }; |
| 20 | 20 | |
| 21 | +struct pci_pwrctl_pwrseq_pdata { | |
| 22 | + const char *target; | |
| 23 | + /* | |
| 24 | + * Called before doing anything else to perform device-specific | |
| 25 | + * verification between requesting the power sequencing handle. | |
| 26 | + */ | |
| 27 | + int (*validate_device)(struct device *dev); | |
| 28 | +}; | |
| 29 | + | |
| 30 | +static int pci_pwrctl_pwrseq_qcm_wcn_validate_device(struct device *dev) | |
| 31 | +{ | |
| 32 | + /* | |
| 33 | + * Old device trees for some platforms already define wifi nodes for | |
| 34 | + * the WCN family of chips since before power sequencing was added | |
| 35 | + * upstream. | |
| 36 | + * | |
| 37 | + * These nodes don't consume the regulator outputs from the PMU, and | |
| 38 | + * if we allow this driver to bind to one of such "incomplete" nodes, | |
| 39 | + * we'll see a kernel log error about the indefinite probe deferral. | |
| 40 | + * | |
| 41 | + * Check the existence of the regulator supply that exists on all | |
| 42 | + * WCN models before moving forward. | |
| 43 | + */ | |
| 44 | + if (!device_property_present(dev, "vddaon-supply")) | |
| 45 | + return -ENODEV; | |
| 46 | + | |
| 47 | + return 0; | |
| 48 | +} | |
| 49 | + | |
| 50 | +static const struct pci_pwrctl_pwrseq_pdata pci_pwrctl_pwrseq_qcom_wcn_pdata = { | |
| 51 | + .target = "wlan", | |
| 52 | + .validate_device = pci_pwrctl_pwrseq_qcm_wcn_validate_device, | |
| 53 | +}; | |
| 54 | + | |
| 21 | 55 | static void devm_pci_pwrctl_pwrseq_power_off(void *data) |
| 22 | 56 | { |
| 23 | 57 | struct pwrseq_desc *pwrseq = data; |
| @@ -27,15 +61,26 @@ static void devm_pci_pwrctl_pwrseq_power_off(void *data) · 3 unmodified lines | ||
| 27 | 61 | |
| 28 | 62 | static int pci_pwrctl_pwrseq_probe(struct platform_device *pdev) |
| 29 | 63 | { |
| 64 | + const struct pci_pwrctl_pwrseq_pdata *pdata; | |
| 30 | 65 | struct pci_pwrctl_pwrseq_data *data; |
| 31 | 66 | struct device *dev = &pdev->dev; |
| 32 | 67 | int ret; |
| 33 | 68 | |
| 69 | + pdata = device_get_match_data(dev); | |
| 70 | + if (!pdata || !pdata->target) | |
| 71 | + return -EINVAL; | |
| 72 | + | |
| 73 | + if (pdata->validate_device) { | |
| 74 | + ret = pdata->validate_device(dev); | |
| 75 | + if (ret) | |
| 76 | + return ret; | |
| 77 | + } | |
| 78 | + | |
| 34 | 79 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); |
| 35 | 80 | if (!data) |
| 36 | 81 | return -ENOMEM; |
| 37 | 82 | |
| 38 | − data->pwrseq = devm_pwrseq_get(dev, of_device_get_match_data(dev)); | |
| 83 | + data->pwrseq = devm_pwrseq_get(dev, pdata->target); | |
| 39 | 84 | if (IS_ERR(data->pwrseq)) |
| 40 | 85 | return dev_err_probe(dev, PTR_ERR(data->pwrseq), |
| 41 | 86 | "Failed to get the power sequencer\n"); |
| @@ -64,17 +109,17 @@ static const struct of_device_id pci_pwrctl_pwrseq_of_match[] = { · 22 unmodified lines | ||
| 64 | 109 | { |
| 65 | 110 | /* ATH11K in QCA6390 package. */ |
| 66 | 111 | .compatible = "pci17cb,1101", |
| 67 | − .data = "wlan", | |
| 112 | + .data = &pci_pwrctl_pwrseq_qcom_wcn_pdata, | |
| 68 | 113 | }, |
| 69 | 114 | { |
| 70 | 115 | /* ATH11K in WCN6855 package. */ |
| 71 | 116 | .compatible = "pci17cb,1103", |
| 72 | − .data = "wlan", | |
| 117 | + .data = &pci_pwrctl_pwrseq_qcom_wcn_pdata, | |
| 73 | 118 | }, |
| 74 | 119 | { |
| 75 | 120 | /* ATH12K in WCN7850 package. */ |
| 76 | 121 | .compatible = "pci17cb,1107", |
| 77 | − .data = "wlan", | |
| 122 | + .data = &pci_pwrctl_pwrseq_qcom_wcn_pdata, | |
| 78 | 123 | }, |
| 79 | 124 | { } |
| 80 | 125 | }; |
| @@ -153,7 +153,9 @@ static void xhci_soft_reset(struct brcm_usb_init_params *params, · 152 unmodified lines | ||
| 153 | 153 | } else { |
| 154 | 154 | USB_CTRL_SET(ctrl, USB_PM, XHC_SOFT_RESETB); |
| 155 | 155 | /* Required for COMMONONN to be set */ |
| 156 | − USB_XHCI_GBL_UNSET(xhci_gbl, GUSB2PHYCFG, U2_FREECLK_EXISTS); | |
| 156 | + if (params->supported_port_modes != USB_CTLR_MODE_DRD) | |
| 157 | + USB_XHCI_GBL_UNSET(xhci_gbl, GUSB2PHYCFG, | |
| 158 | + U2_FREECLK_EXISTS); | |
| 157 | 159 | } |
| 158 | 160 | } |
| 159 | 161 | |
| @@ -328,8 +330,12 @@ static void usb_init_common_7216(struct brcm_usb_init_params *params) · 168 unmodified lines | ||
| 328 | 330 | /* 1 millisecond - for USB clocks to settle down */ |
| 329 | 331 | usleep_range(1000, 2000); |
| 330 | 332 | |
| 331 | − /* Disable PHY when port is suspended */ | |
| 332 | − USB_CTRL_SET(ctrl, P0_U2PHY_CFG1, COMMONONN); | |
| 333 | + /* | |
| 334 | + * Disable PHY when port is suspended | |
| 335 | + * Does not work in DRD mode | |
| 336 | + */ | |
| 337 | + if (params->supported_port_modes != USB_CTLR_MODE_DRD) | |
| 338 | + USB_CTRL_SET(ctrl, P0_U2PHY_CFG1, COMMONONN); | |
| 333 | 339 | |
| 334 | 340 | usb_wake_enable_7216(params, false); |
| 335 | 341 | usb_init_common(params); |
| @@ -220,6 +220,8 @@ usb_reg_bits_map_table[BRCM_FAMILY_COUNT][USB_CTRL_SELECTOR_COUNT] = { · 219 unmodified lines | ||
| 220 | 220 | 0, /* USB_CTRL_SETUP_SCB2_EN_MASK */ |
| 221 | 221 | 0, /* USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK */ |
| 222 | 222 | 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */ |
| 223 | + 0, /* USB_CTRL_SETUP_OC3_DISABLE_PORT0_MASK */ | |
| 224 | + 0, /* USB_CTRL_SETUP_OC3_DISABLE_PORT1_MASK */ | |
| 223 | 225 | 0, /* USB_CTRL_SETUP_OC3_DISABLE_MASK */ |
| 224 | 226 | 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ |
| 225 | 227 | 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ |
| @@ -174,8 +174,9 @@ · 173 unmodified lines | ||
| 174 | 174 | #define SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG 0x150 |
| 175 | 175 | #define SIERRA_DEQ_TAU_CTRL2_PREG 0x151 |
| 176 | 176 | #define SIERRA_DEQ_TAU_CTRL3_PREG 0x152 |
| 177 | −#define SIERRA_DEQ_OPENEYE_CTRL_PREG 0x158 | |
| 177 | +#define SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG 0x158 | |
| 178 | 178 | #define SIERRA_DEQ_CONCUR_EPIOFFSET_MODE_PREG 0x159 |
| 179 | +#define SIERRA_DEQ_OPENEYE_CTRL_PREG 0x15C | |
| 179 | 180 | #define SIERRA_DEQ_PICTRL_PREG 0x161 |
| 180 | 181 | #define SIERRA_CPICAL_TMRVAL_MODE1_PREG 0x170 |
| 181 | 182 | #define SIERRA_CPICAL_TMRVAL_MODE0_PREG 0x171 |
| @@ -1733,7 +1734,7 @@ static const struct cdns_reg_pairs ml_pcie_100_no_ssc_ln_regs[] = { · 1551 unmodified lines | ||
| 1733 | 1734 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 1734 | 1735 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 1735 | 1736 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 1736 | − {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | |
| 1737 | + {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, | |
| 1737 | 1738 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 1738 | 1739 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 1739 | 1740 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, |
| @@ -1797,7 +1798,7 @@ static const struct cdns_reg_pairs ti_ml_pcie_100_no_ssc_ln_regs[] = { · 57 unmodified lines | ||
| 1797 | 1798 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 1798 | 1799 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 1799 | 1800 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 1800 | − {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | |
| 1801 | + {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, | |
| 1801 | 1802 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 1802 | 1803 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 1803 | 1804 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, |
| @@ -1874,7 +1875,7 @@ static const struct cdns_reg_pairs ml_pcie_100_int_ssc_ln_regs[] = { · 70 unmodified lines | ||
| 1874 | 1875 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 1875 | 1876 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 1876 | 1877 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 1877 | − {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | |
| 1878 | + {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, | |
| 1878 | 1879 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 1879 | 1880 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 1880 | 1881 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, |
| @@ -1941,7 +1942,7 @@ static const struct cdns_reg_pairs ti_ml_pcie_100_int_ssc_ln_regs[] = { · 60 unmodified lines | ||
| 1941 | 1942 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 1942 | 1943 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 1943 | 1944 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 1944 | − {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | |
| 1945 | + {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, | |
| 1945 | 1946 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 1946 | 1947 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 1947 | 1948 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, |
| @@ -2012,7 +2013,7 @@ static const struct cdns_reg_pairs ml_pcie_100_ext_ssc_ln_regs[] = { · 64 unmodified lines | ||
| 2012 | 2013 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 2013 | 2014 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 2014 | 2015 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 2015 | − {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | |
| 2016 | + {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, | |
| 2016 | 2017 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 2017 | 2018 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 2018 | 2019 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, |
| @@ -2079,7 +2080,7 @@ static const struct cdns_reg_pairs ti_ml_pcie_100_ext_ssc_ln_regs[] = { · 60 unmodified lines | ||
| 2079 | 2080 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 2080 | 2081 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 2081 | 2082 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 2082 | − {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | |
| 2083 | + {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, | |
| 2083 | 2084 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 2084 | 2085 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 2085 | 2086 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, |
| @@ -2140,7 +2141,7 @@ static const struct cdns_reg_pairs cdns_pcie_ln_regs_no_ssc[] = { · 54 unmodified lines | ||
| 2140 | 2141 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 2141 | 2142 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 2142 | 2143 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 2143 | − {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | |
| 2144 | + {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, | |
| 2144 | 2145 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 2145 | 2146 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 2146 | 2147 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, |
| @@ -2215,7 +2216,7 @@ static const struct cdns_reg_pairs cdns_pcie_ln_regs_int_ssc[] = { · 68 unmodified lines | ||
| 2215 | 2216 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 2216 | 2217 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 2217 | 2218 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 2218 | − {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | |
| 2219 | + {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, | |
| 2219 | 2220 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 2220 | 2221 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 2221 | 2222 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, |
| @@ -2284,7 +2285,7 @@ static const struct cdns_reg_pairs cdns_pcie_ln_regs_ext_ssc[] = { · 62 unmodified lines | ||
| 2284 | 2285 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 2285 | 2286 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 2286 | 2287 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 2287 | − {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | |
| 2288 | + {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, | |
| 2288 | 2289 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 2289 | 2290 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 2290 | 2291 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, |
| @@ -141,11 +141,6 @@ static int imx8_pcie_phy_power_on(struct phy *phy) · 140 unmodified lines | ||
| 141 | 141 | IMX8MM_GPR_PCIE_REF_CLK_PLL); |
| 142 | 142 | usleep_range(100, 200); |
| 143 | 143 | |
| 144 | − /* Do the PHY common block reset */ | |
| 145 | − regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14, | |
| 146 | − IMX8MM_GPR_PCIE_CMN_RST, | |
| 147 | − IMX8MM_GPR_PCIE_CMN_RST); | |
| 148 | − | |
| 149 | 144 | switch (imx8_phy->drvdata->variant) { |
| 150 | 145 | case IMX8MP: |
| 151 | 146 | reset_control_deassert(imx8_phy->perst); |
| @@ -156,6 +151,11 @@ static int imx8_pcie_phy_power_on(struct phy *phy) · 4 unmodified lines | ||
| 156 | 151 | break; |
| 157 | 152 | } |
| 158 | 153 | |
| 154 | + /* Do the PHY common block reset */ | |
| 155 | + regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14, | |
| 156 | + IMX8MM_GPR_PCIE_CMN_RST, | |
| 157 | + IMX8MM_GPR_PCIE_CMN_RST); | |
| 158 | + | |
| 159 | 159 | /* Polling to check the phy is ready or not. */ |
| 160 | 160 | ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG075, |
| 161 | 161 | val, val == ANA_PLL_DONE, 10, 20000); |
| @@ -3673,6 +3673,7 @@ static int qmp_combo_probe(struct platform_device *pdev) · 3672 unmodified lines | ||
| 3673 | 3673 | return -ENOMEM; |
| 3674 | 3674 | |
| 3675 | 3675 | qmp->dev = dev; |
| 3676 | + dev_set_drvdata(dev, qmp); | |
| 3676 | 3677 | |
| 3677 | 3678 | qmp->orientation = TYPEC_ORIENTATION_NORMAL; |
| 3678 | 3679 | |
| @@ -3749,8 +3750,6 @@ static int qmp_combo_probe(struct platform_device *pdev) · 70 unmodified lines | ||
| 3749 | 3750 | |
| 3750 | 3751 | phy_set_drvdata(qmp->dp_phy, qmp); |
| 3751 | 3752 | |
| 3752 | − dev_set_drvdata(dev, qmp); | |
| 3753 | − | |
| 3754 | 3753 | if (usb_np == dev->of_node) |
| 3755 | 3754 | phy_provider = devm_of_phy_provider_register(dev, qmp_combo_phy_xlate); |
| 3756 | 3755 | else |
| @@ -3661,8 +3661,8 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x2_pciephy_cfg = { · 3660 unmodified lines | ||
| 3661 | 3661 | |
| 3662 | 3662 | .reset_list = sdm845_pciephy_reset_l, |
| 3663 | 3663 | .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), |
| 3664 | − .vreg_list = sm8550_qmp_phy_vreg_l, | |
| 3665 | − .num_vregs = ARRAY_SIZE(sm8550_qmp_phy_vreg_l), | |
| 3664 | + .vreg_list = qmp_phy_vreg_l, | |
| 3665 | + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), | |
| 3666 | 3666 | .regs = pciephy_v6_regs_layout, |
| 3667 | 3667 | |
| 3668 | 3668 | .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, |
| @@ -3695,8 +3695,8 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x4_pciephy_cfg = { · 26 unmodified lines | ||
| 3695 | 3695 | |
| 3696 | 3696 | .reset_list = sdm845_pciephy_reset_l, |
| 3697 | 3697 | .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), |
| 3698 | − .vreg_list = sm8550_qmp_phy_vreg_l, | |
| 3699 | − .num_vregs = ARRAY_SIZE(sm8550_qmp_phy_vreg_l), | |
| 3698 | + .vreg_list = qmp_phy_vreg_l, | |
| 3699 | + .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), | |
| 3700 | 3700 | .regs = pciephy_v6_regs_layout, |
| 3701 | 3701 | |
| 3702 | 3702 | .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, |
| @@ -1248,6 +1248,7 @@ static int qmp_usb_legacy_probe(struct platform_device *pdev) · 1247 unmodified lines | ||
| 1248 | 1248 | return -ENOMEM; |
| 1249 | 1249 | |
| 1250 | 1250 | qmp->dev = dev; |
| 1251 | + dev_set_drvdata(dev, qmp); | |
| 1251 | 1252 | |
| 1252 | 1253 | qmp->cfg = of_device_get_match_data(dev); |
| 1253 | 1254 | if (!qmp->cfg) |
| @@ -2179,6 +2179,7 @@ static int qmp_usb_probe(struct platform_device *pdev) · 2178 unmodified lines | ||
| 2179 | 2179 | return -ENOMEM; |
| 2180 | 2180 | |
| 2181 | 2181 | qmp->dev = dev; |
| 2182 | + dev_set_drvdata(dev, qmp); | |
| 2182 | 2183 | |
| 2183 | 2184 | qmp->cfg = of_device_get_match_data(dev); |
| 2184 | 2185 | if (!qmp->cfg) |
| @@ -1050,6 +1050,7 @@ static int qmp_usbc_probe(struct platform_device *pdev) · 1049 unmodified lines | ||
| 1050 | 1050 | return -ENOMEM; |
| 1051 | 1051 | |
| 1052 | 1052 | qmp->dev = dev; |
| 1053 | + dev_set_drvdata(dev, qmp); | |
| 1053 | 1054 | |
| 1054 | 1055 | qmp->orientation = TYPEC_ORIENTATION_NORMAL; |
| 1055 | 1056 | |
| @@ -86,6 +86,7 @@ config PHY_ROCKCHIP_PCIE · 85 unmodified lines | ||
| 86 | 86 | config PHY_ROCKCHIP_SAMSUNG_HDPTX |
| 87 | 87 | tristate "Rockchip Samsung HDMI/eDP Combo PHY driver" |
| 88 | 88 | depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF |
| 89 | + depends on COMMON_CLK | |
| 89 | 90 | depends on HAS_IOMEM |
| 90 | 91 | select GENERIC_PHY |
| 91 | 92 | select MFD_SYSCON |
| @@ -10,18 +10,24 @@ · 9 unmodified lines | ||
| 10 | 10 | #include <linux/clk.h> |
| 11 | 11 | #include <linux/err.h> |
| 12 | 12 | #include <linux/io.h> |
| 13 | +#include <linux/mfd/syscon.h> | |
| 13 | 14 | #include <linux/module.h> |
| 14 | 15 | #include <linux/phy/phy.h> |
| 15 | 16 | #include <linux/platform_device.h> |
| 17 | +#include <linux/regmap.h> | |
| 16 | 18 | #include <linux/usb/of.h> |
| 17 | 19 | |
| 18 | 20 | #define USB_125M_CLK_RATE 125000000 |
| 19 | 21 | #define USB_LS_KEEPALIVE_OFF 0x4 |
| 20 | 22 | #define USB_LS_KEEPALIVE_ENABLE BIT(4) |
| 21 | 23 | |
| 24 | +#define USB_PDRSTN_SPLIT BIT(17) | |
| 25 | +#define SYSCON_USB_SPLIT_OFFSET 0x18 | |
| 26 | + | |
| 22 | 27 | struct jh7110_usb2_phy { |
| 23 | 28 | struct phy *phy; |
| 24 | 29 | void __iomem *regs; |
| 30 | + struct regmap *sys_syscon; | |
| 25 | 31 | struct clk *usb_125m_clk; |
| 26 | 32 | struct clk *app_125m; |
| 27 | 33 | enum phy_mode mode; |
| @@ -61,6 +67,10 @@ static int usb2_phy_set_mode(struct phy *_phy, · 33 unmodified lines | ||
| 61 | 67 | usb2_set_ls_keepalive(phy, (mode != PHY_MODE_USB_DEVICE)); |
| 62 | 68 | } |
| 63 | 69 | |
| 70 | + /* Connect usb 2.0 phy mode */ | |
| 71 | + regmap_update_bits(phy->sys_syscon, SYSCON_USB_SPLIT_OFFSET, | |
| 72 | + USB_PDRSTN_SPLIT, USB_PDRSTN_SPLIT); | |
| 73 | + | |
| 64 | 74 | return 0; |
| 65 | 75 | } |
| 66 | 76 | |
| @@ -129,6 +139,12 @@ static int jh7110_usb_phy_probe(struct platform_device *pdev) · 62 unmodified lines | ||
| 129 | 139 | phy_set_drvdata(phy->phy, phy); |
| 130 | 140 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); |
| 131 | 141 | |
| 142 | + phy->sys_syscon = | |
| 143 | + syscon_regmap_lookup_by_compatible("starfive,jh7110-sys-syscon"); | |
| 144 | + if (IS_ERR(phy->sys_syscon)) | |
| 145 | + return dev_err_probe(dev, PTR_ERR(phy->sys_syscon), | |
| 146 | + "Failed to get sys-syscon\n"); | |
| 147 | + | |
| 132 | 148 | return PTR_ERR_OR_ZERO(phy_provider); |
| 133 | 149 | } |
| 134 | 150 | |
| @@ -699,6 +699,8 @@ static int tegra_xusb_setup_usb_role_switch(struct tegra_xusb_port *port) · 698 unmodified lines | ||
| 699 | 699 | return -ENOMEM; |
| 700 | 700 | |
| 701 | 701 | lane = tegra_xusb_find_lane(port->padctl, "usb2", port->index); |
| 702 | + if (IS_ERR(lane)) | |
| 703 | + return PTR_ERR(lane); | |
| 702 | 704 | |
| 703 | 705 | /* |
| 704 | 706 | * Assign phy dev to usb-phy dev. Host/device drivers can use phy |
| @@ -450,8 +450,8 @@ static int wiz_mode_select(struct wiz *wiz) · 449 unmodified lines | ||
| 450 | 450 | } else if (wiz->lane_phy_type[i] == PHY_TYPE_USXGMII) { |
| 451 | 451 | ret = regmap_field_write(wiz->p0_mac_src_sel[i], 0x3); |
| 452 | 452 | ret = regmap_field_write(wiz->p0_rxfclk_sel[i], 0x3); |
| 453 | − ret = regmap_field_write(wiz->p0_refclk_sel[i], 0x3); | |
| 454 | − mode = LANE_MODE_GEN1; | |
| 453 | + ret = regmap_field_write(wiz->p0_refclk_sel[i], 0x2); | |
| 454 | + mode = LANE_MODE_GEN2; | |
| 455 | 455 | } else { |
| 456 | 456 | continue; |
| 457 | 457 | } |
| @@ -46,6 +46,7 @@ config PINCTRL_INTEL_PLATFORM · 45 unmodified lines | ||
| 46 | 46 | of Intel PCH pins and using them as GPIOs. Currently the following |
| 47 | 47 | Intel SoCs / platforms require this to be functional: |
| 48 | 48 | - Lunar Lake |
| 49 | + - Panther Lake | |
| 49 | 50 | |
| 50 | 51 | config PINCTRL_ALDERLAKE |
| 51 | 52 | tristate "Intel Alder Lake pinctrl and GPIO driver" |
| @@ -90,7 +90,6 @@ static int intel_platform_pinctrl_prepare_community(struct device *dev, · 89 unmodified lines | ||
| 90 | 90 | struct intel_community *community, |
| 91 | 91 | struct intel_platform_pins *pins) |
| 92 | 92 | { |
| 93 | − struct fwnode_handle *child; | |
| 94 | 93 | struct intel_padgroup *gpps; |
| 95 | 94 | unsigned int group; |
| 96 | 95 | size_t ngpps; |
| @@ -131,7 +130,7 @@ static int intel_platform_pinctrl_prepare_community(struct device *dev, · 34 unmodified lines | ||
| 131 | 130 | return -ENOMEM; |
| 132 | 131 | |
| 133 | 132 | group = 0; |
| 134 | − device_for_each_child_node(dev, child) { | |
| 133 | + device_for_each_child_node_scoped(dev, child) { | |
| 135 | 134 | struct intel_padgroup *gpp = &gpps[group]; |
| 136 | 135 | |
| 137 | 136 | gpp->reg_num = group; |
| @@ -159,7 +158,7 @@ static int intel_platform_pinctrl_prepare_soc_data(struct device *dev, · 21 unmodified lines | ||
| 159 | 158 | int ret; |
| 160 | 159 | |
| 161 | 160 | /* Version 1.0 of the specification assumes only a single community per device node */ |
| 162 | − ncommunities = 1, | |
| 161 | + ncommunities = 1; | |
| 163 | 162 | communities = devm_kcalloc(dev, ncommunities, sizeof(*communities), GFP_KERNEL); |
| 164 | 163 | if (!communities) |
| 165 | 164 | return -ENOMEM; |
| @@ -218,7 +218,7 @@ static int ma35_pinctrl_dt_node_to_map_func(struct pinctrl_dev *pctldev, · 217 unmodified lines | ||
| 218 | 218 | } |
| 219 | 219 | |
| 220 | 220 | map_num += grp->npins; |
| 221 | − new_map = devm_kcalloc(pctldev->dev, map_num, sizeof(*new_map), GFP_KERNEL); | |
| 221 | + new_map = kcalloc(map_num, sizeof(*new_map), GFP_KERNEL); | |
| 222 | 222 | if (!new_map) |
| 223 | 223 | return -ENOMEM; |
| 224 | 224 | |
| @@ -474,6 +474,9 @@ static int apple_gpio_pinctrl_probe(struct platform_device *pdev) · 473 unmodified lines | ||
| 474 | 474 | for (i = 0; i < npins; i++) { |
| 475 | 475 | pins[i].number = i; |
| 476 | 476 | pins[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "PIN%u", i); |
| 477 | + if (!pins[i].name) | |
| 478 | + return -ENOMEM; | |
| 479 | + | |
| 477 | 480 | pins[i].drv_data = pctl; |
| 478 | 481 | pin_names[i] = pins[i].name; |
| 479 | 482 | pin_nums[i] = i; |
| @@ -987,8 +987,10 @@ static int aw9523_probe(struct i2c_client *client) · 986 unmodified lines | ||
| 987 | 987 | lockdep_set_subclass(&awi->i2c_lock, i2c_adapter_depth(client->adapter)); |
| 988 | 988 | |
| 989 | 989 | pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL); |
| 990 | − if (!pdesc) | |
| 991 | − return -ENOMEM; | |
| 990 | + if (!pdesc) { | |
| 991 | + ret = -ENOMEM; | |
| 992 | + goto err_disable_vregs; | |
| 993 | + } | |
| 992 | 994 | |
| 993 | 995 | ret = aw9523_hw_init(awi); |
| 994 | 996 | if (ret) |
| @@ -1955,21 +1955,21 @@ static void ocelot_irq_handler(struct irq_desc *desc) · 1954 unmodified lines | ||
| 1955 | 1955 | unsigned int reg = 0, irq, i; |
| 1956 | 1956 | unsigned long irqs; |
| 1957 | 1957 | |
| 1958 | + chained_irq_enter(parent_chip, desc); | |
| 1959 | + | |
| 1958 | 1960 | for (i = 0; i < info->stride; i++) { |
| 1959 | 1961 | regmap_read(info->map, id_reg + 4 * i, ®); |
| 1960 | 1962 | if (!reg) |
| 1961 | 1963 | continue; |
| 1962 | 1964 | |
| 1963 | − chained_irq_enter(parent_chip, desc); | |
| 1964 | − | |
| 1965 | 1965 | irqs = reg; |
| 1966 | 1966 | |
| 1967 | 1967 | for_each_set_bit(irq, &irqs, |
| 1968 | 1968 | min(32U, info->desc->npins - 32 * i)) |
| 1969 | 1969 | generic_handle_domain_irq(chip->irq.domain, irq + 32 * i); |
| 1970 | − | |
| 1971 | − chained_irq_exit(parent_chip, desc); | |
| 1972 | 1970 | } |
| 1971 | + | |
| 1972 | + chained_irq_exit(parent_chip, desc); | |
| 1973 | 1973 | } |
| 1974 | 1974 | |
| 1975 | 1975 | static int ocelot_gpiochip_register(struct platform_device *pdev, |
| @@ -221,7 +221,7 @@ static int cv1800_pctrl_dt_node_to_map(struct pinctrl_dev *pctldev, · 220 unmodified lines | ||
| 221 | 221 | if (!grpnames) |
| 222 | 222 | return -ENOMEM; |
| 223 | 223 | |
| 224 | − map = devm_kcalloc(dev, ngroups * 2, sizeof(*map), GFP_KERNEL); | |
| 224 | + map = kcalloc(ngroups * 2, sizeof(*map), GFP_KERNEL); | |
| 225 | 225 | if (!map) |
| 226 | 226 | return -ENOMEM; |
| 227 | 227 | |
| @@ -1374,10 +1374,15 @@ static int stm32_gpiolib_register_bank(struct stm32_pinctrl *pctl, struct fwnode · 1373 unmodified lines | ||
| 1374 | 1374 | |
| 1375 | 1375 | for (i = 0; i < npins; i++) { |
| 1376 | 1376 | stm32_pin = stm32_pctrl_get_desc_pin_from_gpio(pctl, bank, i); |
| 1377 | − if (stm32_pin && stm32_pin->pin.name) | |
| 1377 | + if (stm32_pin && stm32_pin->pin.name) { | |
| 1378 | 1378 | names[i] = devm_kasprintf(dev, GFP_KERNEL, "%s", stm32_pin->pin.name); |
| 1379 | − else | |
| 1379 | + if (!names[i]) { | |
| 1380 | + err = -ENOMEM; | |
| 1381 | + goto err_clk; | |
| 1382 | + } | |
| 1383 | + } else { | |
| 1380 | 1384 | names[i] = NULL; |
| 1385 | + } | |
| 1381 | 1386 | } |
| 1382 | 1387 | |
| 1383 | 1388 | bank->gpio_chip.names = (const char * const *)names; |
| @@ -3908,6 +3908,16 @@ static int platform_profile_setup(struct asus_wmi *asus) · 3907 unmodified lines | ||
| 3908 | 3908 | if (!asus->throttle_thermal_policy_dev) |
| 3909 | 3909 | return 0; |
| 3910 | 3910 | |
| 3911 | + /* | |
| 3912 | + * We need to set the default thermal profile during probe or otherwise | |
| 3913 | + * the system will often remain in silent mode, causing low performance. | |
| 3914 | + */ | |
| 3915 | + err = throttle_thermal_policy_set_default(asus); | |
| 3916 | + if (err < 0) { | |
| 3917 | + pr_warn("Failed to set default thermal profile\n"); | |
| 3918 | + return err; | |
| 3919 | + } | |
| 3920 | + | |
| 3911 | 3921 | dev_info(dev, "Using throttle_thermal_policy for platform_profile support\n"); |
| 3912 | 3922 | |
| 3913 | 3923 | asus->platform_profile_handler.profile_get = asus_wmi_platform_profile_get; |
| @@ -264,6 +264,15 @@ static const struct key_entry dell_wmi_keymap_type_0010[] = { · 263 unmodified lines | ||
| 264 | 264 | /*Speaker Mute*/ |
| 265 | 265 | { KE_KEY, 0x109, { KEY_MUTE} }, |
| 266 | 266 | |
| 267 | + /* S2Idle screen off */ | |
| 268 | + { KE_IGNORE, 0x120, { KEY_RESERVED }}, | |
| 269 | + | |
| 270 | + /* Leaving S4 or S2Idle suspend */ | |
| 271 | + { KE_IGNORE, 0x130, { KEY_RESERVED }}, | |
| 272 | + | |
| 273 | + /* Entering S2Idle suspend */ | |
| 274 | + { KE_IGNORE, 0x140, { KEY_RESERVED }}, | |
| 275 | + | |
| 267 | 276 | /* Mic mute */ |
| 268 | 277 | { KE_KEY, 0x150, { KEY_MICMUTE } }, |
| 269 | 278 | |
| @@ -295,8 +295,6 @@ const struct pmc_reg_map adl_reg_map = { · 294 unmodified lines | ||
| 295 | 295 | .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES, |
| 296 | 296 | .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, |
| 297 | 297 | .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, |
| 298 | − .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET, | |
| 299 | − .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE, | |
| 300 | 298 | .ltr_ignore_max = ADL_NUM_IP_IGN_ALLOWED, |
| 301 | 299 | .lpm_num_modes = ADL_LPM_NUM_MODES, |
| 302 | 300 | .lpm_num_maps = ADL_LPM_NUM_MAPS, |
| @@ -200,8 +200,6 @@ const struct pmc_reg_map cnp_reg_map = { · 199 unmodified lines | ||
| 200 | 200 | .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES, |
| 201 | 201 | .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, |
| 202 | 202 | .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, |
| 203 | − .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET, | |
| 204 | − .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE, | |
| 205 | 203 | .ltr_ignore_max = CNP_NUM_IP_IGN_ALLOWED, |
| 206 | 204 | .etr3_offset = ETR3_OFFSET, |
| 207 | 205 | }; |
| @@ -11,7 +11,6 @@ · 10 unmodified lines | ||
| 11 | 11 | |
| 12 | 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 13 | 13 | |
| 14 | −#include <linux/acpi_pmtmr.h> | |
| 15 | 14 | #include <linux/bitfield.h> |
| 16 | 15 | #include <linux/debugfs.h> |
| 17 | 16 | #include <linux/delay.h> |
| @@ -1258,39 +1257,6 @@ static bool pmc_core_is_pson_residency_enabled(struct pmc_dev *pmcdev) · 1240 unmodified lines | ||
| 1258 | 1257 | return val == 1; |
| 1259 | 1258 | } |
| 1260 | 1259 | |
| 1261 | −/* | |
| 1262 | − * Enable or disable ACPI PM Timer | |
| 1263 | − * | |
| 1264 | − * This function is intended to be a callback for ACPI PM suspend/resume event. | |
| 1265 | − * The ACPI PM Timer is enabled on resume only if it was enabled during suspend. | |
| 1266 | − */ | |
| 1267 | −static void pmc_core_acpi_pm_timer_suspend_resume(void *data, bool suspend) | |
| 1268 | −{ | |
| 1269 | − struct pmc_dev *pmcdev = data; | |
| 1270 | − struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; | |
| 1271 | − const struct pmc_reg_map *map = pmc->map; | |
| 1272 | − bool enabled; | |
| 1273 | − u32 reg; | |
| 1274 | − | |
| 1275 | − if (!map->acpi_pm_tmr_ctl_offset) | |
| 1276 | − return; | |
| 1277 | − | |
| 1278 | − guard(mutex)(&pmcdev->lock); | |
| 1279 | − | |
| 1280 | − if (!suspend && !pmcdev->enable_acpi_pm_timer_on_resume) | |
| 1281 | − return; | |
| 1282 | − | |
| 1283 | − reg = pmc_core_reg_read(pmc, map->acpi_pm_tmr_ctl_offset); | |
| 1284 | − enabled = !(reg & map->acpi_pm_tmr_disable_bit); | |
| 1285 | − if (suspend) | |
| 1286 | − reg |= map->acpi_pm_tmr_disable_bit; | |
| 1287 | − else | |
| 1288 | − reg &= ~map->acpi_pm_tmr_disable_bit; | |
| 1289 | − pmc_core_reg_write(pmc, map->acpi_pm_tmr_ctl_offset, reg); | |
| 1290 | − | |
| 1291 | − pmcdev->enable_acpi_pm_timer_on_resume = suspend && enabled; | |
| 1292 | −} | |
| 1293 | − | |
| 1294 | 1260 | static void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev) |
| 1295 | 1261 | { |
| 1296 | 1262 | debugfs_remove_recursive(pmcdev->dbgfs_dir); |
| @@ -1486,7 +1452,6 @@ static int pmc_core_probe(struct platform_device *pdev) · 189 unmodified lines | ||
| 1486 | 1452 | struct pmc_dev *pmcdev; |
| 1487 | 1453 | const struct x86_cpu_id *cpu_id; |
| 1488 | 1454 | int (*core_init)(struct pmc_dev *pmcdev); |
| 1489 | − const struct pmc_reg_map *map; | |
| 1490 | 1455 | struct pmc *primary_pmc; |
| 1491 | 1456 | int ret; |
| 1492 | 1457 | |
| @@ -1545,11 +1510,6 @@ static int pmc_core_probe(struct platform_device *pdev) · 52 unmodified lines | ||
| 1545 | 1510 | pm_report_max_hw_sleep(FIELD_MAX(SLP_S0_RES_COUNTER_MASK) * |
| 1546 | 1511 | pmc_core_adjust_slp_s0_step(primary_pmc, 1)); |
| 1547 | 1512 | |
| 1548 | − map = primary_pmc->map; | |
| 1549 | − if (map->acpi_pm_tmr_ctl_offset) | |
| 1550 | − acpi_pmtmr_register_suspend_resume_callback(pmc_core_acpi_pm_timer_suspend_resume, | |
| 1551 | − pmcdev); | |
| 1552 | − | |
| 1553 | 1513 | device_initialized = true; |
| 1554 | 1514 | dev_info(&pdev->dev, " initialized\n"); |
| 1555 | 1515 | |
| @@ -1559,12 +1519,6 @@ static int pmc_core_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 1559 | 1519 | static void pmc_core_remove(struct platform_device *pdev) |
| 1560 | 1520 | { |
| 1561 | 1521 | struct pmc_dev *pmcdev = platform_get_drvdata(pdev); |
| 1562 | − const struct pmc *pmc = pmcdev->pmcs[PMC_IDX_MAIN]; | |
| 1563 | − const struct pmc_reg_map *map = pmc->map; | |
| 1564 | − | |
| 1565 | − if (map->acpi_pm_tmr_ctl_offset) | |
| 1566 | − acpi_pmtmr_unregister_suspend_resume_callback(); | |
| 1567 | − | |
| 1568 | 1522 | pmc_core_dbgfs_unregister(pmcdev); |
| 1569 | 1523 | pmc_core_clean_structure(pdev); |
| 1570 | 1524 | } |
| @@ -68,8 +68,6 @@ struct telem_endpoint; · 67 unmodified lines | ||
| 68 | 68 | #define SPT_PMC_LTR_SCC 0x3A0 |
| 69 | 69 | #define SPT_PMC_LTR_ISH 0x3A4 |
| 70 | 70 | |
| 71 | −#define SPT_PMC_ACPI_PM_TMR_CTL_OFFSET 0x18FC | |
| 72 | − | |
| 73 | 71 | /* Sunrise Point: PGD PFET Enable Ack Status Registers */ |
| 74 | 72 | enum ppfear_regs { |
| 75 | 73 | SPT_PMC_XRAM_PPFEAR0A = 0x590, |
| @@ -150,8 +148,6 @@ enum ppfear_regs { · 74 unmodified lines | ||
| 150 | 148 | #define SPT_PMC_VRIC1_SLPS0LVEN BIT(13) |
| 151 | 149 | #define SPT_PMC_VRIC1_XTALSDQDIS BIT(22) |
| 152 | 150 | |
| 153 | −#define SPT_PMC_BIT_ACPI_PM_TMR_DISABLE BIT(1) | |
| 154 | − | |
| 155 | 151 | /* Cannonlake Power Management Controller register offsets */ |
| 156 | 152 | #define CNP_PMC_SLPS0_DBG_OFFSET 0x10B4 |
| 157 | 153 | #define CNP_PMC_PM_CFG_OFFSET 0x1818 |
| @@ -355,8 +351,6 @@ struct pmc_reg_map { · 197 unmodified lines | ||
| 355 | 351 | const u8 *lpm_reg_index; |
| 356 | 352 | const u32 pson_residency_offset; |
| 357 | 353 | const u32 pson_residency_counter_step; |
| 358 | − const u32 acpi_pm_tmr_ctl_offset; | |
| 359 | − const u32 acpi_pm_tmr_disable_bit; | |
| 360 | 354 | }; |
| 361 | 355 | |
| 362 | 356 | /** |
| @@ -432,8 +426,6 @@ struct pmc_dev { · 69 unmodified lines | ||
| 432 | 426 | u32 die_c6_offset; |
| 433 | 427 | struct telem_endpoint *punit_ep; |
| 434 | 428 | struct pmc_info *regmap_list; |
| 435 | − | |
| 436 | − bool enable_acpi_pm_timer_on_resume; | |
| 437 | 429 | }; |
| 438 | 430 | |
| 439 | 431 | enum pmc_index { |
| @@ -29,7 +29,7 @@ · 28 unmodified lines | ||
| 29 | 29 | #define LPM_REG_COUNT 28 |
| 30 | 30 | #define LPM_MODE_OFFSET 1 |
| 31 | 31 | |
| 32 | −DEFINE_FREE(pmc_core_iounmap, void __iomem *, iounmap(_T)); | |
| 32 | +DEFINE_FREE(pmc_core_iounmap, void __iomem *, if (_T) iounmap(_T)) | |
| 33 | 33 | |
| 34 | 34 | static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *map) |
| 35 | 35 | { |
| @@ -262,6 +262,8 @@ pmc_core_ssram_get_pmc(struct pmc_dev *pmcdev, int pmc_idx, u32 offset) · 226 unmodified lines | ||
| 262 | 262 | |
| 263 | 263 | ssram_base = ssram_pcidev->resource[0].start; |
| 264 | 264 | tmp_ssram = ioremap(ssram_base, SSRAM_HDR_SIZE); |
| 265 | + if (!tmp_ssram) | |
| 266 | + return -ENOMEM; | |
| 265 | 267 | |
| 266 | 268 | if (pmc_idx != PMC_IDX_MAIN) { |
| 267 | 269 | /* |
| @@ -46,8 +46,6 @@ const struct pmc_reg_map icl_reg_map = { · 45 unmodified lines | ||
| 46 | 46 | .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES, |
| 47 | 47 | .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, |
| 48 | 48 | .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, |
| 49 | − .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET, | |
| 50 | − .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE, | |
| 51 | 49 | .ltr_ignore_max = ICL_NUM_IP_IGN_ALLOWED, |
| 52 | 50 | .etr3_offset = ETR3_OFFSET, |
| 53 | 51 | }; |
| @@ -462,8 +462,6 @@ const struct pmc_reg_map mtl_socm_reg_map = { · 461 unmodified lines | ||
| 462 | 462 | .ppfear_buckets = MTL_SOCM_PPFEAR_NUM_ENTRIES, |
| 463 | 463 | .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, |
| 464 | 464 | .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, |
| 465 | − .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET, | |
| 466 | − .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE, | |
| 467 | 465 | .lpm_num_maps = ADL_LPM_NUM_MAPS, |
| 468 | 466 | .ltr_ignore_max = MTL_SOCM_NUM_IP_IGN_ALLOWED, |
| 469 | 467 | .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2, |
| @@ -197,8 +197,6 @@ const struct pmc_reg_map tgl_reg_map = { · 196 unmodified lines | ||
| 197 | 197 | .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES, |
| 198 | 198 | .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, |
| 199 | 199 | .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, |
| 200 | − .acpi_pm_tmr_ctl_offset = SPT_PMC_ACPI_PM_TMR_CTL_OFFSET, | |
| 201 | − .acpi_pm_tmr_disable_bit = SPT_PMC_BIT_ACPI_PM_TMR_DISABLE, | |
| 202 | 200 | .ltr_ignore_max = TGL_NUM_IP_IGN_ALLOWED, |
| 203 | 201 | .lpm_num_maps = TGL_LPM_NUM_MAPS, |
| 204 | 202 | .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2, |
| @@ -1052,7 +1052,7 @@ static unsigned long cpr_get_opp_hz_for_req(struct dev_pm_opp *ref, · 1051 unmodified lines | ||
| 1052 | 1052 | of_parse_phandle(child_np, "required-opps", 0); |
| 1053 | 1053 | |
| 1054 | 1054 | if (child_req_np == ref_np) { |
| 1055 | − u64 rate; | |
| 1055 | + u64 rate = 0; | |
| 1056 | 1056 | |
| 1057 | 1057 | of_property_read_u64(child_np, "opp-hz", &rate); |
| 1058 | 1058 | return (unsigned long) rate; |
| @@ -178,7 +178,7 @@ static int __dtpm_devfreq_setup(struct devfreq *devfreq, struct dtpm *parent) · 177 unmodified lines | ||
| 178 | 178 | ret = dev_pm_qos_add_request(dev, &dtpm_devfreq->qos_req, |
| 179 | 179 | DEV_PM_QOS_MAX_FREQUENCY, |
| 180 | 180 | PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE); |
| 181 | − if (ret) { | |
| 181 | + if (ret < 0) { | |
| 182 | 182 | pr_err("Failed to add QoS request: %d\n", ret); |
| 183 | 183 | goto out_dtpm_unregister; |
| 184 | 184 | } |
| @@ -147,6 +147,8 @@ static const struct x86_cpu_id pl4_support_ids[] = { · 146 unmodified lines | ||
| 147 | 147 | X86_MATCH_VFM(INTEL_RAPTORLAKE_P, NULL), |
| 148 | 148 | X86_MATCH_VFM(INTEL_METEORLAKE, NULL), |
| 149 | 149 | X86_MATCH_VFM(INTEL_METEORLAKE_L, NULL), |
| 150 | + X86_MATCH_VFM(INTEL_ARROWLAKE_U, NULL), | |
| 151 | + X86_MATCH_VFM(INTEL_ARROWLAKE_H, NULL), | |
| 150 | 152 | {} |
| 151 | 153 | }; |
| 152 | 154 | |
| @@ -15,7 +15,8 @@ · 14 unmodified lines | ||
| 15 | 15 | #include <linux/module.h> |
| 16 | 16 | #include <linux/slab.h> |
| 17 | 17 | |
| 18 | −#define TPMI_RAPL_VERSION 1 | |
| 18 | +#define TPMI_RAPL_MAJOR_VERSION 0 | |
| 19 | +#define TPMI_RAPL_MINOR_VERSION 1 | |
| 19 | 20 | |
| 20 | 21 | /* 1 header + 10 registers + 5 reserved. 8 bytes for each. */ |
| 21 | 22 | #define TPMI_RAPL_DOMAIN_SIZE 128 |
| @@ -154,11 +155,21 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset) · 132 unmodified lines | ||
| 154 | 155 | tpmi_domain_size = tpmi_domain_header >> 16 & 0xff; |
| 155 | 156 | tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff; |
| 156 | 157 | |
| 157 | − if (tpmi_domain_version != TPMI_RAPL_VERSION) { | |
| 158 | − pr_warn(FW_BUG "Unsupported version:%d\n", tpmi_domain_version); | |
| 158 | + if (tpmi_domain_version == TPMI_VERSION_INVALID) { | |
| 159 | + pr_warn(FW_BUG "Invalid version\n"); | |
| 159 | 160 | return -ENODEV; |
| 160 | 161 | } |
| 161 | 162 | |
| 163 | + if (TPMI_MAJOR_VERSION(tpmi_domain_version) != TPMI_RAPL_MAJOR_VERSION) { | |
| 164 | + pr_warn(FW_BUG "Unsupported major version:%ld\n", | |
| 165 | + TPMI_MAJOR_VERSION(tpmi_domain_version)); | |
| 166 | + return -ENODEV; | |
| 167 | + } | |
| 168 | + | |
| 169 | + if (TPMI_MINOR_VERSION(tpmi_domain_version) > TPMI_RAPL_MINOR_VERSION) | |
| 170 | + pr_info("Ignore: Unsupported minor version:%ld\n", | |
| 171 | + TPMI_MINOR_VERSION(tpmi_domain_version)); | |
| 172 | + | |
| 162 | 173 | /* Domain size: in unit of 128 Bytes */ |
| 163 | 174 | if (tpmi_domain_size != 1) { |
| 164 | 175 | pr_warn(FW_BUG "Invalid Domain size %d\n", tpmi_domain_size); |
| @@ -181,7 +192,7 @@ static int parse_one_domain(struct tpmi_rapl_package *trp, u32 offset) · 16 unmodified lines | ||
| 181 | 192 | pr_warn(FW_BUG "System domain must support Domain Info register\n"); |
| 182 | 193 | return -ENODEV; |
| 183 | 194 | } |
| 184 | − tpmi_domain_info = readq(trp->base + offset + TPMI_RAPL_REG_DOMAIN_INFO); | |
| 195 | + tpmi_domain_info = readq(trp->base + offset + TPMI_RAPL_REG_DOMAIN_INFO * 8); | |
| 185 | 196 | if (!(tpmi_domain_info & TPMI_RAPL_DOMAIN_ROOT)) |
| 186 | 197 | return 0; |
| 187 | 198 | domain_type = RAPL_DOMAIN_PLATFORM; |
| @@ -405,8 +405,8 @@ static int npcm_rc_probe(struct platform_device *pdev) · 404 unmodified lines | ||
| 405 | 405 | if (!of_property_read_u32(pdev->dev.of_node, "nuvoton,sw-reset-number", |
| 406 | 406 | &rc->sw_reset_number)) { |
| 407 | 407 | if (rc->sw_reset_number && rc->sw_reset_number < 5) { |
| 408 | − rc->restart_nb.priority = 192, | |
| 409 | − rc->restart_nb.notifier_call = npcm_rc_restart, | |
| 408 | + rc->restart_nb.priority = 192; | |
| 409 | + rc->restart_nb.notifier_call = npcm_rc_restart; | |
| 410 | 410 | ret = register_restart_handler(&rc->restart_nb); |
| 411 | 411 | if (ret) |
| 412 | 412 | dev_warn(&pdev->dev, "failed to register restart handler\n"); |
| @@ -94,6 +94,9 @@ static int jh71x0_reset_status(struct reset_controller_dev *rcdev, · 93 unmodified lines | ||
| 94 | 94 | void __iomem *reg_status = data->status + offset * sizeof(u32); |
| 95 | 95 | u32 value = readl(reg_status); |
| 96 | 96 | |
| 97 | + if (!data->asserted) | |
| 98 | + return !(value & mask); | |
| 99 | + | |
| 97 | 100 | return !((value ^ data->asserted[offset]) & mask); |
| 98 | 101 | } |
| 99 | 102 | |
| @@ -1195,7 +1195,8 @@ sclp_reboot_event(struct notifier_block *this, unsigned long event, void *ptr) · 1194 unmodified lines | ||
| 1195 | 1195 | } |
| 1196 | 1196 | |
| 1197 | 1197 | static struct notifier_block sclp_reboot_notifier = { |
| 1198 | − .notifier_call = sclp_reboot_event | |
| 1198 | + .notifier_call = sclp_reboot_event, | |
| 1199 | + .priority = INT_MIN, | |
| 1199 | 1200 | }; |
| 1200 | 1201 | |
| 1201 | 1202 | static ssize_t con_pages_show(struct device_driver *dev, char *buf) |
| @@ -319,7 +319,7 @@ sclp_vt220_add_msg(struct sclp_vt220_request *request, · 318 unmodified lines | ||
| 319 | 319 | buffer = (void *) ((addr_t) sccb + sccb->header.length); |
| 320 | 320 | |
| 321 | 321 | if (convertlf) { |
| 322 | − /* Perform Linefeed conversion (0x0a -> 0x0a 0x0d)*/ | |
| 322 | + /* Perform Linefeed conversion (0x0a -> 0x0d 0x0a)*/ | |
| 323 | 323 | for (from=0, to=0; |
| 324 | 324 | (from < count) && (to < sclp_vt220_space_left(request)); |
| 325 | 325 | from++) { |
| @@ -328,8 +328,8 @@ sclp_vt220_add_msg(struct sclp_vt220_request *request, · 2 unmodified lines | ||
| 328 | 328 | /* Perform conversion */ |
| 329 | 329 | if (c == 0x0a) { |
| 330 | 330 | if (to + 1 < sclp_vt220_space_left(request)) { |
| 331 | − ((unsigned char *) buffer)[to++] = c; | |
| 332 | 331 | ((unsigned char *) buffer)[to++] = 0x0d; |
| 332 | + ((unsigned char *) buffer)[to++] = c; | |
| 333 | 333 | } else |
| 334 | 334 | break; |
| 335 | 335 | |
| @@ -1864,13 +1864,12 @@ static inline void ap_scan_domains(struct ap_card *ac) · 1863 unmodified lines | ||
| 1864 | 1864 | } |
| 1865 | 1865 | /* if no queue device exists, create a new one */ |
| 1866 | 1866 | if (!aq) { |
| 1867 | − aq = ap_queue_create(qid, ac->ap_dev.device_type); | |
| 1867 | + aq = ap_queue_create(qid, ac); | |
| 1868 | 1868 | if (!aq) { |
| 1869 | 1869 | AP_DBF_WARN("%s(%d,%d) ap_queue_create() failed\n", |
| 1870 | 1870 | __func__, ac->id, dom); |
| 1871 | 1871 | continue; |
| 1872 | 1872 | } |
| 1873 | − aq->card = ac; | |
| 1874 | 1873 | aq->config = !decfg; |
| 1875 | 1874 | aq->chkstop = chkstop; |
| 1876 | 1875 | aq->se_bstate = hwinfo.bs; |
| @@ -272,7 +272,7 @@ int ap_test_config_usage_domain(unsigned int domain); · 271 unmodified lines | ||
| 272 | 272 | int ap_test_config_ctrl_domain(unsigned int domain); |
| 273 | 273 | |
| 274 | 274 | void ap_queue_init_reply(struct ap_queue *aq, struct ap_message *ap_msg); |
| 275 | −struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type); | |
| 275 | +struct ap_queue *ap_queue_create(ap_qid_t qid, struct ap_card *ac); | |
| 276 | 276 | void ap_queue_prepare_remove(struct ap_queue *aq); |
| 277 | 277 | void ap_queue_remove(struct ap_queue *aq); |
| 278 | 278 | void ap_queue_init_state(struct ap_queue *aq); |
| @@ -22,6 +22,11 @@ static void __ap_flush_queue(struct ap_queue *aq); · 21 unmodified lines | ||
| 22 | 22 | * some AP queue helper functions |
| 23 | 23 | */ |
| 24 | 24 | |
| 25 | +static inline bool ap_q_supported_in_se(struct ap_queue *aq) | |
| 26 | +{ | |
| 27 | + return aq->card->hwinfo.ep11 || aq->card->hwinfo.accel; | |
| 28 | +} | |
| 29 | + | |
| 25 | 30 | static inline bool ap_q_supports_bind(struct ap_queue *aq) |
| 26 | 31 | { |
| 27 | 32 | return aq->card->hwinfo.ep11 || aq->card->hwinfo.accel; |
| @@ -1104,18 +1109,19 @@ static void ap_queue_device_release(struct device *dev) · 1076 unmodified lines | ||
| 1104 | 1109 | kfree(aq); |
| 1105 | 1110 | } |
| 1106 | 1111 | |
| 1107 | −struct ap_queue *ap_queue_create(ap_qid_t qid, int device_type) | |
| 1112 | +struct ap_queue *ap_queue_create(ap_qid_t qid, struct ap_card *ac) | |
| 1108 | 1113 | { |
| 1109 | 1114 | struct ap_queue *aq; |
| 1110 | 1115 | |
| 1111 | 1116 | aq = kzalloc(sizeof(*aq), GFP_KERNEL); |
| 1112 | 1117 | if (!aq) |
| 1113 | 1118 | return NULL; |
| 1119 | + aq->card = ac; | |
| 1114 | 1120 | aq->ap_dev.device.release = ap_queue_device_release; |
| 1115 | 1121 | aq->ap_dev.device.type = &ap_queue_type; |
| 1116 | − aq->ap_dev.device_type = device_type; | |
| 1117 | − // add optional SE secure binding attributes group | |
| 1118 | − if (ap_sb_available() && is_prot_virt_guest()) | |
| 1122 | + aq->ap_dev.device_type = ac->ap_dev.device_type; | |
| 1123 | + /* in SE environment add bind/associate attributes group */ | |
| 1124 | + if (ap_is_se_guest() && ap_q_supported_in_se(aq)) | |
| 1119 | 1125 | aq->ap_dev.device.groups = ap_queue_dev_sb_attr_groups; |
| 1120 | 1126 | aq->qid = qid; |
| 1121 | 1127 | spin_lock_init(&aq->lock); |
| @@ -1196,10 +1202,16 @@ bool ap_queue_usable(struct ap_queue *aq) · 74 unmodified lines | ||
| 1196 | 1202 | } |
| 1197 | 1203 | |
| 1198 | 1204 | /* SE guest's queues additionally need to be bound */ |
| 1199 | − if (ap_q_needs_bind(aq) && | |
| 1200 | − !(aq->se_bstate == AP_BS_Q_USABLE || | |
| 1201 | − aq->se_bstate == AP_BS_Q_USABLE_NO_SECURE_KEY)) | |
| 1202 | − rc = false; | |
| 1205 | + if (ap_is_se_guest()) { | |
| 1206 | + if (!ap_q_supported_in_se(aq)) { | |
| 1207 | + rc = false; | |
| 1208 | + goto unlock_and_out; | |
| 1209 | + } | |
| 1210 | + if (ap_q_needs_bind(aq) && | |
| 1211 | + !(aq->se_bstate == AP_BS_Q_USABLE || | |
| 1212 | + aq->se_bstate == AP_BS_Q_USABLE_NO_SECURE_KEY)) | |
| 1213 | + rc = false; | |
| 1214 | + } | |
| 1203 | 1215 | |
| 1204 | 1216 | unlock_and_out: |
| 1205 | 1217 | spin_unlock_bh(&aq->lock); |
| @@ -324,6 +324,7 @@ static int pckmo_key2protkey(const u8 *key, u32 keylen, · 323 unmodified lines | ||
| 324 | 324 | memcpy(protkey, t->protkey, t->len); |
| 325 | 325 | *protkeylen = t->len; |
| 326 | 326 | *protkeytype = t->keytype; |
| 327 | + rc = 0; | |
| 327 | 328 | break; |
| 328 | 329 | } |
| 329 | 330 | case TOKVER_CLEAR_KEY: { |
| @@ -830,7 +830,6 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 829 unmodified lines | ||
| 830 | 830 | spin_lock_init(&fnic->vlans_lock); |
| 831 | 831 | INIT_WORK(&fnic->fip_frame_work, fnic_handle_fip_frame); |
| 832 | 832 | INIT_WORK(&fnic->event_work, fnic_handle_event); |
| 833 | − INIT_WORK(&fnic->flush_work, fnic_flush_tx); | |
| 834 | 833 | skb_queue_head_init(&fnic->fip_frame_queue); |
| 835 | 834 | INIT_LIST_HEAD(&fnic->evlist); |
| 836 | 835 | INIT_LIST_HEAD(&fnic->vlans); |
| @@ -948,6 +947,7 @@ static int fnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent) · 111 unmodified lines | ||
| 948 | 947 | |
| 949 | 948 | INIT_WORK(&fnic->link_work, fnic_handle_link); |
| 950 | 949 | INIT_WORK(&fnic->frame_work, fnic_handle_frame); |
| 950 | + INIT_WORK(&fnic->flush_work, fnic_flush_tx); | |
| 951 | 951 | skb_queue_head_init(&fnic->frame_queue); |
| 952 | 952 | skb_queue_head_init(&fnic->tx_queue); |
| 953 | 953 | |
| @@ -542,8 +542,8 @@ struct mpi3mr_hba_port { · 541 unmodified lines | ||
| 542 | 542 | * @port_list: List of ports belonging to a SAS node |
| 543 | 543 | * @num_phys: Number of phys associated with port |
| 544 | 544 | * @marked_responding: used while refresing the sas ports |
| 545 | − * @lowest_phy: lowest phy ID of current sas port | |
| 546 | − * @phy_mask: phy_mask of current sas port | |
| 545 | + * @lowest_phy: lowest phy ID of current sas port, valid for controller port | |
| 546 | + * @phy_mask: phy_mask of current sas port, valid for controller port | |
| 547 | 547 | * @hba_port: HBA port entry |
| 548 | 548 | * @remote_identify: Attached device identification |
| 549 | 549 | * @rphy: SAS transport layer rphy object |
| @@ -590,12 +590,13 @@ static enum sas_linkrate mpi3mr_convert_phy_link_rate(u8 link_rate) · 589 unmodified lines | ||
| 590 | 590 | * @mrioc: Adapter instance reference |
| 591 | 591 | * @mr_sas_port: Internal Port object |
| 592 | 592 | * @mr_sas_phy: Internal Phy object |
| 593 | + * @host_node: Flag to indicate this is a host_node | |
| 593 | 594 | * |
| 594 | 595 | * Return: None. |
| 595 | 596 | */ |
| 596 | 597 | static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc, |
| 597 | 598 | struct mpi3mr_sas_port *mr_sas_port, |
| 598 | − struct mpi3mr_sas_phy *mr_sas_phy) | |
| 599 | + struct mpi3mr_sas_phy *mr_sas_phy, u8 host_node) | |
| 599 | 600 | { |
| 600 | 601 | u64 sas_address = mr_sas_port->remote_identify.sas_address; |
| 601 | 602 | |
| @@ -605,9 +606,13 @@ static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc, · 3 unmodified lines | ||
| 605 | 606 | |
| 606 | 607 | list_del(&mr_sas_phy->port_siblings); |
| 607 | 608 | mr_sas_port->num_phys--; |
| 608 | − mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id); | |
| 609 | − if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id) | |
| 610 | − mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | |
| 609 | + | |
| 610 | + if (host_node) { | |
| 611 | + mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id); | |
| 612 | + | |
| 613 | + if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id) | |
| 614 | + mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | |
| 615 | + } | |
| 611 | 616 | sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy); |
| 612 | 617 | mr_sas_phy->phy_belongs_to_port = 0; |
| 613 | 618 | } |
| @@ -617,12 +622,13 @@ static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc, · 3 unmodified lines | ||
| 617 | 622 | * @mrioc: Adapter instance reference |
| 618 | 623 | * @mr_sas_port: Internal Port object |
| 619 | 624 | * @mr_sas_phy: Internal Phy object |
| 625 | + * @host_node: Flag to indicate this is a host_node | |
| 620 | 626 | * |
| 621 | 627 | * Return: None. |
| 622 | 628 | */ |
| 623 | 629 | static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc, |
| 624 | 630 | struct mpi3mr_sas_port *mr_sas_port, |
| 625 | − struct mpi3mr_sas_phy *mr_sas_phy) | |
| 631 | + struct mpi3mr_sas_phy *mr_sas_phy, u8 host_node) | |
| 626 | 632 | { |
| 627 | 633 | u64 sas_address = mr_sas_port->remote_identify.sas_address; |
| 628 | 634 | |
| @@ -632,9 +638,12 @@ static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc, · 3 unmodified lines | ||
| 632 | 638 | |
| 633 | 639 | list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list); |
| 634 | 640 | mr_sas_port->num_phys++; |
| 635 | − mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id); | |
| 636 | − if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy) | |
| 637 | − mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | |
| 641 | + if (host_node) { | |
| 642 | + mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id); | |
| 643 | + | |
| 644 | + if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy) | |
| 645 | + mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | |
| 646 | + } | |
| 638 | 647 | sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy); |
| 639 | 648 | mr_sas_phy->phy_belongs_to_port = 1; |
| 640 | 649 | } |
| @@ -675,7 +684,7 @@ static void mpi3mr_add_phy_to_an_existing_port(struct mpi3mr_ioc *mrioc, · 34 unmodified lines | ||
| 675 | 684 | if (srch_phy == mr_sas_phy) |
| 676 | 685 | return; |
| 677 | 686 | } |
| 678 | − mpi3mr_add_sas_phy(mrioc, mr_sas_port, mr_sas_phy); | |
| 687 | + mpi3mr_add_sas_phy(mrioc, mr_sas_port, mr_sas_phy, mr_sas_node->host_node); | |
| 679 | 688 | return; |
| 680 | 689 | } |
| 681 | 690 | } |
| @@ -736,7 +745,7 @@ static void mpi3mr_del_phy_from_an_existing_port(struct mpi3mr_ioc *mrioc, · 54 unmodified lines | ||
| 736 | 745 | mpi3mr_delete_sas_port(mrioc, mr_sas_port); |
| 737 | 746 | else |
| 738 | 747 | mpi3mr_delete_sas_phy(mrioc, mr_sas_port, |
| 739 | − mr_sas_phy); | |
| 748 | + mr_sas_phy, mr_sas_node->host_node); | |
| 740 | 749 | return; |
| 741 | 750 | } |
| 742 | 751 | } |
| @@ -1028,7 +1037,7 @@ mpi3mr_alloc_hba_port(struct mpi3mr_ioc *mrioc, u16 port_id) · 285 unmodified lines | ||
| 1028 | 1037 | /** |
| 1029 | 1038 | * mpi3mr_get_hba_port_by_id - find hba port by id |
| 1030 | 1039 | * @mrioc: Adapter instance reference |
| 1031 | − * @port_id - Port ID to search | |
| 1040 | + * @port_id: Port ID to search | |
| 1032 | 1041 | * |
| 1033 | 1042 | * Return: mpi3mr_hba_port reference for the matched port |
| 1034 | 1043 | */ |
| @@ -1367,7 +1376,8 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, · 332 unmodified lines | ||
| 1367 | 1376 | mpi3mr_sas_port_sanity_check(mrioc, mr_sas_node, |
| 1368 | 1377 | mr_sas_port->remote_identify.sas_address, hba_port); |
| 1369 | 1378 | |
| 1370 | − if (mr_sas_node->num_phys >= sizeof(mr_sas_port->phy_mask) * 8) | |
| 1379 | + if (mr_sas_node->host_node && mr_sas_node->num_phys >= | |
| 1380 | + sizeof(mr_sas_port->phy_mask) * 8) | |
| 1371 | 1381 | ioc_info(mrioc, "max port count %u could be too high\n", |
| 1372 | 1382 | mr_sas_node->num_phys); |
| 1373 | 1383 | |
| @@ -1377,7 +1387,7 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, · 3 unmodified lines | ||
| 1377 | 1387 | (mr_sas_node->phy[i].hba_port != hba_port)) |
| 1378 | 1388 | continue; |
| 1379 | 1389 | |
| 1380 | − if (i >= sizeof(mr_sas_port->phy_mask) * 8) { | |
| 1390 | + if (mr_sas_node->host_node && (i >= sizeof(mr_sas_port->phy_mask) * 8)) { | |
| 1381 | 1391 | ioc_warn(mrioc, "skipping port %u, max allowed value is %zu\n", |
| 1382 | 1392 | i, sizeof(mr_sas_port->phy_mask) * 8); |
| 1383 | 1393 | goto out_fail; |
| @@ -1385,7 +1395,8 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, · 1 unmodified line | ||
| 1385 | 1395 | list_add_tail(&mr_sas_node->phy[i].port_siblings, |
| 1386 | 1396 | &mr_sas_port->phy_list); |
| 1387 | 1397 | mr_sas_port->num_phys++; |
| 1388 | − mr_sas_port->phy_mask |= (1 << i); | |
| 1398 | + if (mr_sas_node->host_node) | |
| 1399 | + mr_sas_port->phy_mask |= (1 << i); | |
| 1389 | 1400 | } |
| 1390 | 1401 | |
| 1391 | 1402 | if (!mr_sas_port->num_phys) { |
| @@ -1394,7 +1405,8 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc, · 2 unmodified lines | ||
| 1394 | 1405 | goto out_fail; |
| 1395 | 1406 | } |
| 1396 | 1407 | |
| 1397 | − mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | |
| 1408 | + if (mr_sas_node->host_node) | |
| 1409 | + mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | |
| 1398 | 1410 | |
| 1399 | 1411 | if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { |
| 1400 | 1412 | tgtdev = mpi3mr_get_tgtdev_by_addr(mrioc, |
| @@ -3651,7 +3651,7 @@ static int do_device_access(struct sdeb_store_info *sip, struct scsi_cmnd *scp, · 3650 unmodified lines | ||
| 3651 | 3651 | enum dma_data_direction dir; |
| 3652 | 3652 | struct scsi_data_buffer *sdb = &scp->sdb; |
| 3653 | 3653 | u8 *fsp; |
| 3654 | − int i; | |
| 3654 | + int i, total = 0; | |
| 3655 | 3655 | |
| 3656 | 3656 | /* |
| 3657 | 3657 | * Even though reads are inherently atomic (in this driver), we expect |
| @@ -3688,18 +3688,16 @@ static int do_device_access(struct sdeb_store_info *sip, struct scsi_cmnd *scp, · 30 unmodified lines | ||
| 3688 | 3688 | fsp + (block * sdebug_sector_size), |
| 3689 | 3689 | sdebug_sector_size, sg_skip, do_write); |
| 3690 | 3690 | sdeb_data_sector_unlock(sip, do_write); |
| 3691 | − if (ret != sdebug_sector_size) { | |
| 3692 | − ret += (i * sdebug_sector_size); | |
| 3691 | + total += ret; | |
| 3692 | + if (ret != sdebug_sector_size) | |
| 3693 | 3693 | break; |
| 3694 | − } | |
| 3695 | 3694 | sg_skip += sdebug_sector_size; |
| 3696 | 3695 | if (++block >= sdebug_store_sectors) |
| 3697 | 3696 | block = 0; |
| 3698 | 3697 | } |
| 3699 | − ret = num * sdebug_sector_size; | |
| 3700 | 3698 | sdeb_data_unlock(sip, atomic); |
| 3701 | 3699 | |
| 3702 | − return ret; | |
| 3700 | + return total; | |
| 3703 | 3701 | } |
| 3704 | 3702 | |
| 3705 | 3703 | /* Returns number of bytes copied or -1 if error. */ |
| @@ -1250,7 +1250,7 @@ static ssize_t fc_rport_set_marginal_state(struct device *dev, · 1249 unmodified lines | ||
| 1250 | 1250 | */ |
| 1251 | 1251 | if (rport->port_state == FC_PORTSTATE_ONLINE) |
| 1252 | 1252 | rport->port_state = port_state; |
| 1253 | − else | |
| 1253 | + else if (port_state != rport->port_state) | |
| 1254 | 1254 | return -EINVAL; |
| 1255 | 1255 | } else if (port_state == FC_PORTSTATE_ONLINE) { |
| 1256 | 1256 | /* |
| @@ -1260,7 +1260,7 @@ static ssize_t fc_rport_set_marginal_state(struct device *dev, · 3 unmodified lines | ||
| 1260 | 1260 | */ |
| 1261 | 1261 | if (rport->port_state == FC_PORTSTATE_MARGINAL) |
| 1262 | 1262 | rport->port_state = port_state; |
| 1263 | − else | |
| 1263 | + else if (port_state != rport->port_state) | |
| 1264 | 1264 | return -EINVAL; |
| 1265 | 1265 | } else |
| 1266 | 1266 | return -EINVAL; |
| @@ -831,7 +831,7 @@ wd33c93_intr(struct Scsi_Host *instance) · 830 unmodified lines | ||
| 831 | 831 | /* construct an IDENTIFY message with correct disconnect bit */ |
| 832 | 832 | |
| 833 | 833 | hostdata->outgoing_msg[0] = IDENTIFY(0, cmd->device->lun); |
| 834 | − if (scsi_pointer->phase) | |
| 834 | + if (WD33C93_scsi_pointer(cmd)->phase) | |
| 835 | 835 | hostdata->outgoing_msg[0] |= 0x40; |
| 836 | 836 | |
| 837 | 837 | if (hostdata->sync_stat[cmd->device->id] == SS_FIRST) { |
| @@ -1761,10 +1761,9 @@ static int qmc_qe_init_resources(struct qmc *qmc, struct platform_device *pdev) · 1760 unmodified lines | ||
| 1761 | 1761 | */ |
| 1762 | 1762 | info = devm_qe_muram_alloc(qmc->dev, UCC_SLOW_PRAM_SIZE + 2 * 64, |
| 1763 | 1763 | ALIGNMENT_OF_UCC_SLOW_PRAM); |
| 1764 | − if (IS_ERR_VALUE(info)) { | |
| 1765 | − dev_err(qmc->dev, "cannot allocate MURAM for PRAM"); | |
| 1766 | − return -ENOMEM; | |
| 1767 | − } | |
| 1764 | + if (info < 0) | |
| 1765 | + return info; | |
| 1766 | + | |
| 1768 | 1767 | if (!qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, qmc->qe_subblock, |
| 1769 | 1768 | QE_CR_PROTOCOL_UNSPECIFIED, info)) { |
| 1770 | 1769 | dev_err(qmc->dev, "QE_ASSIGN_PAGE_TO_DEVICE cmd failed"); |
| @@ -2056,7 +2055,7 @@ static void qmc_remove(struct platform_device *pdev) · 285 unmodified lines | ||
| 2056 | 2055 | qmc_exit_xcc(qmc); |
| 2057 | 2056 | } |
| 2058 | 2057 | |
| 2059 | −static const struct qmc_data qmc_data_cpm1 = { | |
| 2058 | +static const struct qmc_data qmc_data_cpm1 __maybe_unused = { | |
| 2060 | 2059 | .version = QMC_CPM1, |
| 2061 | 2060 | .tstate = 0x30000000, |
| 2062 | 2061 | .rstate = 0x31000000, |
| @@ -2066,7 +2065,7 @@ static const struct qmc_data qmc_data_cpm1 = { · 3 unmodified lines | ||
| 2066 | 2065 | .rpack = 0x00000000, |
| 2067 | 2066 | }; |
| 2068 | 2067 | |
| 2069 | −static const struct qmc_data qmc_data_qe = { | |
| 2068 | +static const struct qmc_data qmc_data_qe __maybe_unused = { | |
| 2070 | 2069 | .version = QMC_QE, |
| 2071 | 2070 | .tstate = 0x30000000, |
| 2072 | 2071 | .rstate = 0x30000000, |
| @@ -376,11 +376,12 @@ static int intel_hw_params(struct snd_pcm_substream *substream, · 375 unmodified lines | ||
| 376 | 376 | static int intel_prepare(struct snd_pcm_substream *substream, |
| 377 | 377 | struct snd_soc_dai *dai) |
| 378 | 378 | { |
| 379 | + struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); | |
| 379 | 380 | struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); |
| 380 | 381 | struct sdw_intel *sdw = cdns_to_intel(cdns); |
| 381 | 382 | struct sdw_cdns_dai_runtime *dai_runtime; |
| 383 | + struct snd_pcm_hw_params *hw_params; | |
| 382 | 384 | int ch, dir; |
| 383 | − int ret = 0; | |
| 384 | 385 | |
| 385 | 386 | dai_runtime = cdns->dai_runtime_array[dai->id]; |
| 386 | 387 | if (!dai_runtime) { |
| @@ -389,12 +390,8 @@ static int intel_prepare(struct snd_pcm_substream *substream, · 2 unmodified lines | ||
| 389 | 390 | return -EIO; |
| 390 | 391 | } |
| 391 | 392 | |
| 393 | + hw_params = &rtd->dpcm[substream->stream].hw_params; | |
| 392 | 394 | if (dai_runtime->suspended) { |
| 393 | − struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); | |
| 394 | − struct snd_pcm_hw_params *hw_params; | |
| 395 | − | |
| 396 | − hw_params = &rtd->dpcm[substream->stream].hw_params; | |
| 397 | − | |
| 398 | 395 | dai_runtime->suspended = false; |
| 399 | 396 | |
| 400 | 397 | /* |
| @@ -415,15 +412,11 @@ static int intel_prepare(struct snd_pcm_substream *substream, · 14 unmodified lines | ||
| 415 | 412 | /* the SHIM will be configured in the callback functions */ |
| 416 | 413 | |
| 417 | 414 | sdw_cdns_config_stream(cdns, ch, dir, dai_runtime->pdi); |
| 418 | − | |
| 419 | − /* Inform DSP about PDI stream number */ | |
| 420 | − ret = intel_params_stream(sdw, substream, dai, | |
| 421 | − hw_params, | |
| 422 | − sdw->instance, | |
| 423 | − dai_runtime->pdi->intel_alh_id); | |
| 424 | 415 | } |
| 425 | 416 | |
| 426 | − return ret; | |
| 417 | + /* Inform DSP about PDI stream number */ | |
| 418 | + return intel_params_stream(sdw, substream, dai, hw_params, sdw->instance, | |
| 419 | + dai_runtime->pdi->intel_alh_id); | |
| 427 | 420 | } |
| 428 | 421 | |
| 429 | 422 | static int |
| @@ -1003,6 +1003,7 @@ static int dspi_setup(struct spi_device *spi) · 1002 unmodified lines | ||
| 1003 | 1003 | u32 cs_sck_delay = 0, sck_cs_delay = 0; |
| 1004 | 1004 | struct fsl_dspi_platform_data *pdata; |
| 1005 | 1005 | unsigned char pasc = 0, asc = 0; |
| 1006 | + struct gpio_desc *gpio_cs; | |
| 1006 | 1007 | struct chip_data *chip; |
| 1007 | 1008 | unsigned long clkrate; |
| 1008 | 1009 | bool cs = true; |
| @@ -1077,7 +1078,10 @@ static int dspi_setup(struct spi_device *spi) · 68 unmodified lines | ||
| 1077 | 1078 | chip->ctar_val |= SPI_CTAR_LSBFE; |
| 1078 | 1079 | } |
| 1079 | 1080 | |
| 1080 | − gpiod_direction_output(spi_get_csgpiod(spi, 0), false); | |
| 1081 | + gpio_cs = spi_get_csgpiod(spi, 0); | |
| 1082 | + if (gpio_cs) | |
| 1083 | + gpiod_direction_output(gpio_cs, false); | |
| 1084 | + | |
| 1081 | 1085 | dspi_deassert_cs(spi, &cs); |
| 1082 | 1086 | |
| 1083 | 1087 | spi_set_ctldata(spi, chip); |
| @@ -1116,6 +1116,11 @@ static int spi_geni_probe(struct platform_device *pdev) · 1115 unmodified lines | ||
| 1116 | 1116 | init_completion(&mas->tx_reset_done); |
| 1117 | 1117 | init_completion(&mas->rx_reset_done); |
| 1118 | 1118 | spin_lock_init(&mas->lock); |
| 1119 | + | |
| 1120 | + ret = geni_icc_get(&mas->se, NULL); | |
| 1121 | + if (ret) | |
| 1122 | + return ret; | |
| 1123 | + | |
| 1119 | 1124 | pm_runtime_use_autosuspend(&pdev->dev); |
| 1120 | 1125 | pm_runtime_set_autosuspend_delay(&pdev->dev, 250); |
| 1121 | 1126 | ret = devm_pm_runtime_enable(dev); |
| @@ -1125,9 +1130,6 @@ static int spi_geni_probe(struct platform_device *pdev) · 3 unmodified lines | ||
| 1125 | 1130 | if (device_property_read_bool(&pdev->dev, "spi-slave")) |
| 1126 | 1131 | spi->target = true; |
| 1127 | 1132 | |
| 1128 | − ret = geni_icc_get(&mas->se, NULL); | |
| 1129 | − if (ret) | |
| 1130 | − return ret; | |
| 1131 | 1133 | /* Set the bus quota to a reasonable value for register access */ |
| 1132 | 1134 | mas->se.icc_paths[GENI_TO_CORE].avg_bw = Bps_to_icc(CORE_2X_50_MHZ); |
| 1133 | 1135 | mas->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW; |
| @@ -1187,7 +1187,7 @@ cleanup: · 1186 unmodified lines | ||
| 1187 | 1187 | |
| 1188 | 1188 | /** |
| 1189 | 1189 | * mtk_snand_is_page_ops() - check if the op is a controller supported page op. |
| 1190 | − * @op spi-mem op to check | |
| 1190 | + * @op: spi-mem op to check | |
| 1191 | 1191 | * |
| 1192 | 1192 | * Check whether op can be executed with read_from_cache or program_load |
| 1193 | 1193 | * mode in the controller. |
| @@ -2044,6 +2044,7 @@ static const struct stm32_spi_cfg stm32mp25_spi_cfg = { · 2043 unmodified lines | ||
| 2044 | 2044 | .baud_rate_div_max = STM32H7_SPI_MBR_DIV_MAX, |
| 2045 | 2045 | .has_fifo = true, |
| 2046 | 2046 | .prevent_dma_burst = true, |
| 2047 | + .has_device_mode = true, | |
| 2047 | 2048 | }; |
| 2048 | 2049 | |
| 2049 | 2050 | static const struct of_device_id stm32_spi_of_match[] = { |
| @@ -129,12 +129,15 @@ static unsigned long ad9832_calc_freqreg(unsigned long mclk, unsigned long fout) · 128 unmodified lines | ||
| 129 | 129 | static int ad9832_write_frequency(struct ad9832_state *st, |
| 130 | 130 | unsigned int addr, unsigned long fout) |
| 131 | 131 | { |
| 132 | + unsigned long clk_freq; | |
| 132 | 133 | unsigned long regval; |
| 133 | 134 | |
| 134 | − if (fout > (clk_get_rate(st->mclk) / 2)) | |
| 135 | + clk_freq = clk_get_rate(st->mclk); | |
| 136 | + | |
| 137 | + if (!clk_freq || fout > (clk_freq / 2)) | |
| 135 | 138 | return -EINVAL; |
| 136 | 139 | |
| 137 | − regval = ad9832_calc_freqreg(clk_get_rate(st->mclk), fout); | |
| 140 | + regval = ad9832_calc_freqreg(clk_freq, fout); | |
| 138 | 141 | |
| 139 | 142 | st->freq_data[0] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | |
| 140 | 143 | (addr << ADD_SHIFT) | |
| @@ -691,7 +691,7 @@ struct se_device *target_alloc_device(struct se_hba *hba, const char *name) · 690 unmodified lines | ||
| 691 | 691 | |
| 692 | 692 | dev->queues = kcalloc(nr_cpu_ids, sizeof(*dev->queues), GFP_KERNEL); |
| 693 | 693 | if (!dev->queues) { |
| 694 | − dev->transport->free_device(dev); | |
| 694 | + hba->backend->ops->free_device(dev); | |
| 695 | 695 | return NULL; |
| 696 | 696 | } |
| 697 | 697 | |
| @@ -2130,7 +2130,7 @@ static int tcmu_netlink_event_send(struct tcmu_dev *udev, · 2129 unmodified lines | ||
| 2130 | 2130 | } |
| 2131 | 2131 | |
| 2132 | 2132 | ret = genlmsg_multicast_allns(&tcmu_genl_family, skb, 0, |
| 2133 | − TCMU_MCGRP_CONFIG, GFP_KERNEL); | |
| 2133 | + TCMU_MCGRP_CONFIG); | |
| 2134 | 2134 | |
| 2135 | 2135 | /* Wait during an add as the listener may not be up yet */ |
| 2136 | 2136 | if (ret == 0 || |
| @@ -416,7 +416,6 @@ err_del_legacy: · 415 unmodified lines | ||
| 416 | 416 | if (!pci_info->no_legacy) |
| 417 | 417 | proc_thermal_remove(proc_priv); |
| 418 | 418 | proc_thermal_mmio_remove(pdev, proc_priv); |
| 419 | − pci_disable_device(pdev); | |
| 420 | 419 | |
| 421 | 420 | return ret; |
| 422 | 421 | } |
| @@ -438,7 +437,6 @@ static void proc_thermal_pci_remove(struct pci_dev *pdev) · 15 unmodified lines | ||
| 438 | 437 | proc_thermal_mmio_remove(pdev, pci_info->proc_priv); |
| 439 | 438 | if (!pci_info->no_legacy) |
| 440 | 439 | proc_thermal_remove(proc_priv); |
| 441 | − pci_disable_device(pdev); | |
| 442 | 440 | } |
| 443 | 441 | |
| 444 | 442 | #ifdef CONFIG_PM_SLEEP |
| @@ -13,48 +13,12 @@ static struct rapl_if_priv rapl_mmio_priv; · 12 unmodified lines | ||
| 13 | 13 | |
| 14 | 14 | static const struct rapl_mmio_regs rapl_mmio_default = { |
| 15 | 15 | .reg_unit = 0x5938, |
| 16 | − .regs[RAPL_DOMAIN_PACKAGE] = { 0x59a0, 0x593c, 0x58f0, 0, 0x5930}, | |
| 16 | + .regs[RAPL_DOMAIN_PACKAGE] = { 0x59a0, 0x593c, 0x58f0, 0, 0x5930, 0x59b0}, | |
| 17 | 17 | .regs[RAPL_DOMAIN_DRAM] = { 0x58e0, 0x58e8, 0x58ec, 0, 0}, |
| 18 | − .limits[RAPL_DOMAIN_PACKAGE] = BIT(POWER_LIMIT2), | |
| 18 | + .limits[RAPL_DOMAIN_PACKAGE] = BIT(POWER_LIMIT2) | BIT(POWER_LIMIT4), | |
| 19 | 19 | .limits[RAPL_DOMAIN_DRAM] = BIT(POWER_LIMIT2), |
| 20 | 20 | }; |
| 21 | 21 | |
| 22 | −static int rapl_mmio_cpu_online(unsigned int cpu) | |
| 23 | −{ | |
| 24 | − struct rapl_package *rp; | |
| 25 | − | |
| 26 | − /* mmio rapl supports package 0 only for now */ | |
| 27 | − if (topology_physical_package_id(cpu)) | |
| 28 | − return 0; | |
| 29 | − | |
| 30 | − rp = rapl_find_package_domain_cpuslocked(cpu, &rapl_mmio_priv, true); | |
| 31 | − if (!rp) { | |
| 32 | − rp = rapl_add_package_cpuslocked(cpu, &rapl_mmio_priv, true); | |
| 33 | − if (IS_ERR(rp)) | |
| 34 | − return PTR_ERR(rp); | |
| 35 | − } | |
| 36 | − cpumask_set_cpu(cpu, &rp->cpumask); | |
| 37 | − return 0; | |
| 38 | −} | |
| 39 | − | |
| 40 | −static int rapl_mmio_cpu_down_prep(unsigned int cpu) | |
| 41 | −{ | |
| 42 | − struct rapl_package *rp; | |
| 43 | − int lead_cpu; | |
| 44 | − | |
| 45 | − rp = rapl_find_package_domain_cpuslocked(cpu, &rapl_mmio_priv, true); | |
| 46 | − if (!rp) | |
| 47 | − return 0; | |
| 48 | − | |
| 49 | − cpumask_clear_cpu(cpu, &rp->cpumask); | |
| 50 | − lead_cpu = cpumask_first(&rp->cpumask); | |
| 51 | − if (lead_cpu >= nr_cpu_ids) | |
| 52 | − rapl_remove_package_cpuslocked(rp); | |
| 53 | − else if (rp->lead_cpu == cpu) | |
| 54 | − rp->lead_cpu = lead_cpu; | |
| 55 | − return 0; | |
| 56 | −} | |
| 57 | − | |
| 58 | 22 | static int rapl_mmio_read_raw(int cpu, struct reg_action *ra) |
| 59 | 23 | { |
| 60 | 24 | if (!ra->reg.mmio) |
| @@ -82,6 +46,7 @@ static int rapl_mmio_write_raw(int cpu, struct reg_action *ra) · 21 unmodified lines | ||
| 82 | 46 | int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv) |
| 83 | 47 | { |
| 84 | 48 | const struct rapl_mmio_regs *rapl_regs = &rapl_mmio_default; |
| 49 | + struct rapl_package *rp; | |
| 85 | 50 | enum rapl_domain_reg_id reg; |
| 86 | 51 | enum rapl_domain_type domain; |
| 87 | 52 | int ret; |
| @@ -109,25 +74,38 @@ int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc · 21 unmodified lines | ||
| 109 | 74 | return PTR_ERR(rapl_mmio_priv.control_type); |
| 110 | 75 | } |
| 111 | 76 | |
| 112 | − ret = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powercap/rapl:online", | |
| 113 | − rapl_mmio_cpu_online, rapl_mmio_cpu_down_prep); | |
| 114 | − if (ret < 0) { | |
| 115 | − powercap_unregister_control_type(rapl_mmio_priv.control_type); | |
| 116 | − rapl_mmio_priv.control_type = NULL; | |
| 117 | − return ret; | |
| 77 | + /* Register a RAPL package device for package 0 which is always online */ | |
| 78 | + rp = rapl_find_package_domain(0, &rapl_mmio_priv, false); | |
| 79 | + if (rp) { | |
| 80 | + ret = -EEXIST; | |
| 81 | + goto err; | |
| 82 | + } | |
| 83 | + | |
| 84 | + rp = rapl_add_package(0, &rapl_mmio_priv, false); | |
| 85 | + if (IS_ERR(rp)) { | |
| 86 | + ret = PTR_ERR(rp); | |
| 87 | + goto err; | |
| 118 | 88 | } |
| 119 | − rapl_mmio_priv.pcap_rapl_online = ret; | |
| 120 | 89 | |
| 121 | 90 | return 0; |
| 91 | + | |
| 92 | +err: | |
| 93 | + powercap_unregister_control_type(rapl_mmio_priv.control_type); | |
| 94 | + rapl_mmio_priv.control_type = NULL; | |
| 95 | + return ret; | |
| 122 | 96 | } |
| 123 | 97 | EXPORT_SYMBOL_GPL(proc_thermal_rapl_add); |
| 124 | 98 | |
| 125 | 99 | void proc_thermal_rapl_remove(void) |
| 126 | 100 | { |
| 101 | + struct rapl_package *rp; | |
| 102 | + | |
| 127 | 103 | if (IS_ERR_OR_NULL(rapl_mmio_priv.control_type)) |
| 128 | 104 | return; |
| 129 | 105 | |
| 130 | − cpuhp_remove_state(rapl_mmio_priv.pcap_rapl_online); | |
| 106 | + rp = rapl_find_package_domain(0, &rapl_mmio_priv, false); | |
| 107 | + if (rp) | |
| 108 | + rapl_remove_package(rp); | |
| 131 | 109 | powercap_unregister_control_type(rapl_mmio_priv.control_type); |
| 132 | 110 | } |
| 133 | 111 | EXPORT_SYMBOL_GPL(proc_thermal_rapl_remove); |
| @@ -728,6 +728,7 @@ struct thermal_zone_device *thermal_zone_get_by_id(int id) · 727 unmodified lines | ||
| 728 | 728 | mutex_lock(&thermal_list_lock); |
| 729 | 729 | list_for_each_entry(tz, &thermal_tz_list, node) { |
| 730 | 730 | if (tz->id == id) { |
| 731 | + get_device(&tz->device); | |
| 731 | 732 | match = tz; |
| 732 | 733 | break; |
| 733 | 734 | } |
| @@ -1605,14 +1606,12 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) · 871 unmodified lines | ||
| 1605 | 1606 | ida_destroy(&tz->ida); |
| 1606 | 1607 | |
| 1607 | 1608 | device_del(&tz->device); |
| 1608 | − | |
| 1609 | − kfree(tz->tzp); | |
| 1610 | − | |
| 1611 | 1609 | put_device(&tz->device); |
| 1612 | 1610 | |
| 1613 | 1611 | thermal_notify_tz_delete(tz); |
| 1614 | 1612 | |
| 1615 | 1613 | wait_for_completion(&tz->removal); |
| 1614 | + kfree(tz->tzp); | |
| 1616 | 1615 | kfree(tz); |
| 1617 | 1616 | } |
| 1618 | 1617 | EXPORT_SYMBOL_GPL(thermal_zone_device_unregister); |
| @@ -194,6 +194,9 @@ int for_each_thermal_governor(int (*cb)(struct thermal_governor *, void *), · 193 unmodified lines | ||
| 194 | 194 | |
| 195 | 195 | struct thermal_zone_device *thermal_zone_get_by_id(int id); |
| 196 | 196 | |
| 197 | +DEFINE_CLASS(thermal_zone_get_by_id, struct thermal_zone_device *, | |
| 198 | + if (_T) put_device(&_T->device), thermal_zone_get_by_id(id), int id) | |
| 199 | + | |
| 197 | 200 | static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) |
| 198 | 201 | { |
| 199 | 202 | return cdev->ops->get_requested_power && cdev->ops->state2power && |
| @@ -443,7 +443,6 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p) · 442 unmodified lines | ||
| 443 | 443 | { |
| 444 | 444 | struct sk_buff *msg = p->msg; |
| 445 | 445 | const struct thermal_trip_desc *td; |
| 446 | − struct thermal_zone_device *tz; | |
| 447 | 446 | struct nlattr *start_trip; |
| 448 | 447 | int id; |
| 449 | 448 | |
| @@ -452,7 +451,7 @@ static int thermal_genl_cmd_tz_get_trip(struct param *p) · 2 unmodified lines | ||
| 452 | 451 | |
| 453 | 452 | id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]); |
| 454 | 453 | |
| 455 | − tz = thermal_zone_get_by_id(id); | |
| 454 | + CLASS(thermal_zone_get_by_id, tz)(id); | |
| 456 | 455 | if (!tz) |
| 457 | 456 | return -EINVAL; |
| 458 | 457 | |
| @@ -488,7 +487,6 @@ out_cancel_nest: · 29 unmodified lines | ||
| 488 | 487 | static int thermal_genl_cmd_tz_get_temp(struct param *p) |
| 489 | 488 | { |
| 490 | 489 | struct sk_buff *msg = p->msg; |
| 491 | − struct thermal_zone_device *tz; | |
| 492 | 490 | int temp, ret, id; |
| 493 | 491 | |
| 494 | 492 | if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID]) |
| @@ -496,7 +494,7 @@ static int thermal_genl_cmd_tz_get_temp(struct param *p) · 1 unmodified line | ||
| 496 | 494 | |
| 497 | 495 | id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]); |
| 498 | 496 | |
| 499 | − tz = thermal_zone_get_by_id(id); | |
| 497 | + CLASS(thermal_zone_get_by_id, tz)(id); | |
| 500 | 498 | if (!tz) |
| 501 | 499 | return -EINVAL; |
| 502 | 500 | |
| @@ -514,7 +512,6 @@ static int thermal_genl_cmd_tz_get_temp(struct param *p) · 11 unmodified lines | ||
| 514 | 512 | static int thermal_genl_cmd_tz_get_gov(struct param *p) |
| 515 | 513 | { |
| 516 | 514 | struct sk_buff *msg = p->msg; |
| 517 | − struct thermal_zone_device *tz; | |
| 518 | 515 | int id, ret = 0; |
| 519 | 516 | |
| 520 | 517 | if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID]) |
| @@ -522,7 +519,7 @@ static int thermal_genl_cmd_tz_get_gov(struct param *p) · 1 unmodified line | ||
| 522 | 519 | |
| 523 | 520 | id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]); |
| 524 | 521 | |
| 525 | − tz = thermal_zone_get_by_id(id); | |
| 522 | + CLASS(thermal_zone_get_by_id, tz)(id); | |
| 526 | 523 | if (!tz) |
| 527 | 524 | return -EINVAL; |
| 528 | 525 | |
| @@ -516,7 +516,7 @@ int tb_retimer_scan(struct tb_port *port, bool add) · 515 unmodified lines | ||
| 516 | 516 | */ |
| 517 | 517 | tb_retimer_set_inbound_sbtx(port); |
| 518 | 518 | |
| 519 | − for (i = 1; i <= TB_MAX_RETIMER_INDEX; i++) { | |
| 519 | + for (max = 1, i = 1; i <= TB_MAX_RETIMER_INDEX; i++) { | |
| 520 | 520 | /* |
| 521 | 521 | * Last retimer is true only for the last on-board |
| 522 | 522 | * retimer (the one connected directly to the Type-C |
| @@ -527,9 +527,10 @@ int tb_retimer_scan(struct tb_port *port, bool add) · 4 unmodified lines | ||
| 527 | 527 | last_idx = i; |
| 528 | 528 | else if (ret < 0) |
| 529 | 529 | break; |
| 530 | + | |
| 531 | + max = i; | |
| 530 | 532 | } |
| 531 | 533 | |
| 532 | − max = i; | |
| 533 | 534 | ret = 0; |
| 534 | 535 | |
| 535 | 536 | /* Add retimers if they do not exist already */ |
| @@ -288,6 +288,24 @@ static void tb_increase_tmu_accuracy(struct tb_tunnel *tunnel) · 287 unmodified lines | ||
| 288 | 288 | device_for_each_child(&sw->dev, NULL, tb_increase_switch_tmu_accuracy); |
| 289 | 289 | } |
| 290 | 290 | |
| 291 | +static int tb_switch_tmu_hifi_uni_required(struct device *dev, void *not_used) | |
| 292 | +{ | |
| 293 | + struct tb_switch *sw = tb_to_switch(dev); | |
| 294 | + | |
| 295 | + if (sw && tb_switch_tmu_is_enabled(sw) && | |
| 296 | + tb_switch_tmu_is_configured(sw, TB_SWITCH_TMU_MODE_HIFI_UNI)) | |
| 297 | + return 1; | |
| 298 | + | |
| 299 | + return device_for_each_child(dev, NULL, | |
| 300 | + tb_switch_tmu_hifi_uni_required); | |
| 301 | +} | |
| 302 | + | |
| 303 | +static bool tb_tmu_hifi_uni_required(struct tb *tb) | |
| 304 | +{ | |
| 305 | + return device_for_each_child(&tb->dev, NULL, | |
| 306 | + tb_switch_tmu_hifi_uni_required) == 1; | |
| 307 | +} | |
| 308 | + | |
| 291 | 309 | static int tb_enable_tmu(struct tb_switch *sw) |
| 292 | 310 | { |
| 293 | 311 | int ret; |
| @@ -302,12 +320,30 @@ static int tb_enable_tmu(struct tb_switch *sw) · 8 unmodified lines | ||
| 302 | 320 | ret = tb_switch_tmu_configure(sw, |
| 303 | 321 | TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI); |
| 304 | 322 | if (ret == -EOPNOTSUPP) { |
| 305 | − if (tb_switch_clx_is_enabled(sw, TB_CL1)) | |
| 306 | − ret = tb_switch_tmu_configure(sw, | |
| 307 | − TB_SWITCH_TMU_MODE_LOWRES); | |
| 308 | − else | |
| 309 | − ret = tb_switch_tmu_configure(sw, | |
| 310 | − TB_SWITCH_TMU_MODE_HIFI_BI); | |
| 323 | + if (tb_switch_clx_is_enabled(sw, TB_CL1)) { | |
| 324 | + /* | |
| 325 | + * Figure out uni-directional HiFi TMU requirements | |
| 326 | + * currently in the domain. If there are no | |
| 327 | + * uni-directional HiFi requirements we can put the TMU | |
| 328 | + * into LowRes mode. | |
| 329 | + * | |
| 330 | + * Deliberately skip bi-directional HiFi links | |
| 331 | + * as these work independently of other links | |
| 332 | + * (and they do not allow any CL states anyway). | |
| 333 | + */ | |
| 334 | + if (tb_tmu_hifi_uni_required(sw->tb)) | |
| 335 | + ret = tb_switch_tmu_configure(sw, | |
| 336 | + TB_SWITCH_TMU_MODE_HIFI_UNI); | |
| 337 | + else | |
| 338 | + ret = tb_switch_tmu_configure(sw, | |
| 339 | + TB_SWITCH_TMU_MODE_LOWRES); | |
| 340 | + } else { | |
| 341 | + ret = tb_switch_tmu_configure(sw, TB_SWITCH_TMU_MODE_HIFI_BI); | |
| 342 | + } | |
| 343 | + | |
| 344 | + /* If not supported, fallback to bi-directional HiFi */ | |
| 345 | + if (ret == -EOPNOTSUPP) | |
| 346 | + ret = tb_switch_tmu_configure(sw, TB_SWITCH_TMU_MODE_HIFI_BI); | |
| 311 | 347 | } |
| 312 | 348 | if (ret) |
| 313 | 349 | return ret; |
| @@ -3157,6 +3157,8 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) · 3156 unmodified lines | ||
| 3157 | 3157 | mutex_unlock(&gsm->mutex); |
| 3158 | 3158 | /* Now wipe the queues */ |
| 3159 | 3159 | tty_ldisc_flush(gsm->tty); |
| 3160 | + | |
| 3161 | + guard(spinlock_irqsave)(&gsm->tx_lock); | |
| 3160 | 3162 | list_for_each_entry_safe(txq, ntxq, &gsm->tx_ctrl_list, list) |
| 3161 | 3163 | kfree(txq); |
| 3162 | 3164 | INIT_LIST_HEAD(&gsm->tx_ctrl_list); |
| @@ -762,6 +762,21 @@ static irqreturn_t __imx_uart_rtsint(int irq, void *dev_id) · 761 unmodified lines | ||
| 762 | 762 | |
| 763 | 763 | imx_uart_writel(sport, USR1_RTSD, USR1); |
| 764 | 764 | usr1 = imx_uart_readl(sport, USR1) & USR1_RTSS; |
| 765 | + /* | |
| 766 | + * Update sport->old_status here, so any follow-up calls to | |
| 767 | + * imx_uart_mctrl_check() will be able to recognize that RTS | |
| 768 | + * state changed since last imx_uart_mctrl_check() call. | |
| 769 | + * | |
| 770 | + * In case RTS has been detected as asserted here and later on | |
| 771 | + * deasserted by the time imx_uart_mctrl_check() was called, | |
| 772 | + * imx_uart_mctrl_check() can detect the RTS state change and | |
| 773 | + * trigger uart_handle_cts_change() to unblock the port for | |
| 774 | + * further TX transfers. | |
| 775 | + */ | |
| 776 | + if (usr1 & USR1_RTSS) | |
| 777 | + sport->old_status |= TIOCM_CTS; | |
| 778 | + else | |
| 779 | + sport->old_status &= ~TIOCM_CTS; | |
| 765 | 780 | uart_handle_cts_change(&sport->port, usr1); |
| 766 | 781 | wake_up_interruptible(&sport->port.state->port.delta_msr_wait); |
| 767 | 782 | |
| @@ -147,6 +147,7 @@ static struct uart_driver qcom_geni_uart_driver; · 146 unmodified lines | ||
| 147 | 147 | |
| 148 | 148 | static void __qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport); |
| 149 | 149 | static void qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport); |
| 150 | +static int qcom_geni_serial_port_setup(struct uart_port *uport); | |
| 150 | 151 | |
| 151 | 152 | static inline struct qcom_geni_serial_port *to_dev_port(struct uart_port *uport) |
| 152 | 153 | { |
| @@ -395,6 +396,23 @@ static void qcom_geni_serial_poll_put_char(struct uart_port *uport, · 242 unmodified lines | ||
| 395 | 396 | writel(c, uport->membase + SE_GENI_TX_FIFOn); |
| 396 | 397 | qcom_geni_serial_poll_tx_done(uport); |
| 397 | 398 | } |
| 399 | + | |
| 400 | +static int qcom_geni_serial_poll_init(struct uart_port *uport) | |
| 401 | +{ | |
| 402 | + struct qcom_geni_serial_port *port = to_dev_port(uport); | |
| 403 | + int ret; | |
| 404 | + | |
| 405 | + if (!port->setup) { | |
| 406 | + ret = qcom_geni_serial_port_setup(uport); | |
| 407 | + if (ret) | |
| 408 | + return ret; | |
| 409 | + } | |
| 410 | + | |
| 411 | + if (!qcom_geni_serial_secondary_active(uport)) | |
| 412 | + geni_se_setup_s_cmd(&port->se, UART_START_READ, 0); | |
| 413 | + | |
| 414 | + return 0; | |
| 415 | +} | |
| 398 | 416 | #endif |
| 399 | 417 | |
| 400 | 418 | #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE |
| @@ -562,7 +580,7 @@ static void handle_rx_console(struct uart_port *uport, u32 bytes, bool drop) · 161 unmodified lines | ||
| 562 | 580 | } |
| 563 | 581 | #endif /* CONFIG_SERIAL_QCOM_GENI_CONSOLE */ |
| 564 | 582 | |
| 565 | −static void handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop) | |
| 583 | +static void handle_rx_uart(struct uart_port *uport, u32 bytes) | |
| 566 | 584 | { |
| 567 | 585 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
| 568 | 586 | struct tty_port *tport = &uport->state->port; |
| @@ -570,9 +588,8 @@ static void handle_rx_uart(struct uart_port *uport, u32 bytes, bool drop) · 1 unmodified line | ||
| 570 | 588 | |
| 571 | 589 | ret = tty_insert_flip_string(tport, port->rx_buf, bytes); |
| 572 | 590 | if (ret != bytes) { |
| 573 | − dev_err(uport->dev, "%s:Unable to push data ret %d_bytes %d\n", | |
| 574 | − __func__, ret, bytes); | |
| 575 | − WARN_ON_ONCE(1); | |
| 591 | + dev_err_ratelimited(uport->dev, "failed to push data (%d < %u)\n", | |
| 592 | + ret, bytes); | |
| 576 | 593 | } |
| 577 | 594 | uport->icount.rx += ret; |
| 578 | 595 | tty_flip_buffer_push(tport); |
| @@ -787,17 +804,27 @@ static void qcom_geni_serial_start_rx_fifo(struct uart_port *uport) · 208 unmodified lines | ||
| 787 | 804 | static void qcom_geni_serial_stop_rx_dma(struct uart_port *uport) |
| 788 | 805 | { |
| 789 | 806 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
| 807 | + bool done; | |
| 790 | 808 | |
| 791 | 809 | if (!qcom_geni_serial_secondary_active(uport)) |
| 792 | 810 | return; |
| 793 | 811 | |
| 794 | 812 | geni_se_cancel_s_cmd(&port->se); |
| 795 | − qcom_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS, | |
| 796 | − S_CMD_CANCEL_EN, true); | |
| 797 | − | |
| 798 | − if (qcom_geni_serial_secondary_active(uport)) | |
| 813 | + done = qcom_geni_serial_poll_bit(uport, SE_DMA_RX_IRQ_STAT, | |
| 814 | + RX_EOT, true); | |
| 815 | + if (done) { | |
| 816 | + writel(RX_EOT | RX_DMA_DONE, | |
| 817 | + uport->membase + SE_DMA_RX_IRQ_CLR); | |
| 818 | + } else { | |
| 799 | 819 | qcom_geni_serial_abort_rx(uport); |
| 800 | 820 | |
| 821 | + writel(1, uport->membase + SE_DMA_RX_FSM_RST); | |
| 822 | + qcom_geni_serial_poll_bit(uport, SE_DMA_RX_IRQ_STAT, | |
| 823 | + RX_RESET_DONE, true); | |
| 824 | + writel(RX_RESET_DONE | RX_DMA_DONE, | |
| 825 | + uport->membase + SE_DMA_RX_IRQ_CLR); | |
| 826 | + } | |
| 827 | + | |
| 801 | 828 | if (port->rx_dma_addr) { |
| 802 | 829 | geni_se_rx_dma_unprep(&port->se, port->rx_dma_addr, |
| 803 | 830 | DMA_RX_BUF_SIZE); |
| @@ -846,7 +873,7 @@ static void qcom_geni_serial_handle_rx_dma(struct uart_port *uport, bool drop) · 42 unmodified lines | ||
| 846 | 873 | } |
| 847 | 874 | |
| 848 | 875 | if (!drop) |
| 849 | − handle_rx_uart(uport, rx_in, drop); | |
| 876 | + handle_rx_uart(uport, rx_in); | |
| 850 | 877 | |
| 851 | 878 | ret = geni_se_rx_dma_prep(&port->se, port->rx_buf, |
| 852 | 879 | DMA_RX_BUF_SIZE, |
| @@ -1096,10 +1123,12 @@ static void qcom_geni_serial_shutdown(struct uart_port *uport) · 243 unmodified lines | ||
| 1096 | 1123 | { |
| 1097 | 1124 | disable_irq(uport->irq); |
| 1098 | 1125 | |
| 1126 | + uart_port_lock_irq(uport); | |
| 1099 | 1127 | qcom_geni_serial_stop_tx(uport); |
| 1100 | 1128 | qcom_geni_serial_stop_rx(uport); |
| 1101 | 1129 | |
| 1102 | 1130 | qcom_geni_serial_cancel_tx_cmd(uport); |
| 1131 | + uart_port_unlock_irq(uport); | |
| 1103 | 1132 | } |
| 1104 | 1133 | |
| 1105 | 1134 | static void qcom_geni_serial_flush_buffer(struct uart_port *uport) |
| @@ -1152,7 +1181,6 @@ static int qcom_geni_serial_port_setup(struct uart_port *uport) · 46 unmodified lines | ||
| 1152 | 1181 | false, true, true); |
| 1153 | 1182 | geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2); |
| 1154 | 1183 | geni_se_select_mode(&port->se, port->dev_data->mode); |
| 1155 | − qcom_geni_serial_start_rx(uport); | |
| 1156 | 1184 | port->setup = true; |
| 1157 | 1185 | |
| 1158 | 1186 | return 0; |
| @@ -1168,6 +1196,11 @@ static int qcom_geni_serial_startup(struct uart_port *uport) · 9 unmodified lines | ||
| 1168 | 1196 | if (ret) |
| 1169 | 1197 | return ret; |
| 1170 | 1198 | } |
| 1199 | + | |
| 1200 | + uart_port_lock_irq(uport); | |
| 1201 | + qcom_geni_serial_start_rx(uport); | |
| 1202 | + uart_port_unlock_irq(uport); | |
| 1203 | + | |
| 1171 | 1204 | enable_irq(uport->irq); |
| 1172 | 1205 | |
| 1173 | 1206 | return 0; |
| @@ -1253,7 +1286,6 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport, · 79 unmodified lines | ||
| 1253 | 1286 | unsigned int avg_bw_core; |
| 1254 | 1287 | unsigned long timeout; |
| 1255 | 1288 | |
| 1256 | − qcom_geni_serial_stop_rx(uport); | |
| 1257 | 1289 | /* baud rate */ |
| 1258 | 1290 | baud = uart_get_baud_rate(uport, termios, old, 300, 4000000); |
| 1259 | 1291 | |
| @@ -1269,7 +1301,7 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport, · 9 unmodified lines | ||
| 1269 | 1301 | dev_err(port->se.dev, |
| 1270 | 1302 | "Couldn't find suitable clock rate for %u\n", |
| 1271 | 1303 | baud * sampling_rate); |
| 1272 | − goto out_restart_rx; | |
| 1304 | + return; | |
| 1273 | 1305 | } |
| 1274 | 1306 | |
| 1275 | 1307 | dev_dbg(port->se.dev, "desired_rate = %u, clk_rate = %lu, clk_div = %u\n", |
| @@ -1360,8 +1392,6 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport, · 84 unmodified lines | ||
| 1360 | 1392 | writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN); |
| 1361 | 1393 | writel(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG); |
| 1362 | 1394 | writel(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG); |
| 1363 | −out_restart_rx: | |
| 1364 | − qcom_geni_serial_start_rx(uport); | |
| 1365 | 1395 | } |
| 1366 | 1396 | |
| 1367 | 1397 | #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE |
| @@ -1582,7 +1612,7 @@ static const struct uart_ops qcom_geni_console_pops = { · 214 unmodified lines | ||
| 1582 | 1612 | #ifdef CONFIG_CONSOLE_POLL |
| 1583 | 1613 | .poll_get_char = qcom_geni_serial_get_char, |
| 1584 | 1614 | .poll_put_char = qcom_geni_serial_poll_put_char, |
| 1585 | − .poll_init = qcom_geni_serial_port_setup, | |
| 1615 | + .poll_init = qcom_geni_serial_poll_init, | |
| 1586 | 1616 | #endif |
| 1587 | 1617 | .pm = qcom_geni_serial_pm, |
| 1588 | 1618 | }; |
| @@ -1749,7 +1779,7 @@ static void qcom_geni_serial_remove(struct platform_device *pdev) · 160 unmodified lines | ||
| 1749 | 1779 | uart_remove_one_port(drv, &port->uport); |
| 1750 | 1780 | } |
| 1751 | 1781 | |
| 1752 | −static int qcom_geni_serial_sys_suspend(struct device *dev) | |
| 1782 | +static int qcom_geni_serial_suspend(struct device *dev) | |
| 1753 | 1783 | { |
| 1754 | 1784 | struct qcom_geni_serial_port *port = dev_get_drvdata(dev); |
| 1755 | 1785 | struct uart_port *uport = &port->uport; |
| @@ -1766,7 +1796,7 @@ static int qcom_geni_serial_sys_suspend(struct device *dev) · 10 unmodified lines | ||
| 1766 | 1796 | return uart_suspend_port(private_data->drv, uport); |
| 1767 | 1797 | } |
| 1768 | 1798 | |
| 1769 | −static int qcom_geni_serial_sys_resume(struct device *dev) | |
| 1799 | +static int qcom_geni_serial_resume(struct device *dev) | |
| 1770 | 1800 | { |
| 1771 | 1801 | int ret; |
| 1772 | 1802 | struct qcom_geni_serial_port *port = dev_get_drvdata(dev); |
| @@ -1781,38 +1811,6 @@ static int qcom_geni_serial_sys_resume(struct device *dev) · 8 unmodified lines | ||
| 1781 | 1811 | return ret; |
| 1782 | 1812 | } |
| 1783 | 1813 | |
| 1784 | −static int qcom_geni_serial_sys_hib_resume(struct device *dev) | |
| 1785 | −{ | |
| 1786 | − int ret = 0; | |
| 1787 | − struct uart_port *uport; | |
| 1788 | − struct qcom_geni_private_data *private_data; | |
| 1789 | − struct qcom_geni_serial_port *port = dev_get_drvdata(dev); | |
| 1790 | − | |
| 1791 | − uport = &port->uport; | |
| 1792 | − private_data = uport->private_data; | |
| 1793 | − | |
| 1794 | − if (uart_console(uport)) { | |
| 1795 | − geni_icc_set_tag(&port->se, QCOM_ICC_TAG_ALWAYS); | |
| 1796 | − geni_icc_set_bw(&port->se); | |
| 1797 | − ret = uart_resume_port(private_data->drv, uport); | |
| 1798 | − /* | |
| 1799 | − * For hibernation usecase clients for | |
| 1800 | − * console UART won't call port setup during restore, | |
| 1801 | − * hence call port setup for console uart. | |
| 1802 | − */ | |
| 1803 | − qcom_geni_serial_port_setup(uport); | |
| 1804 | − } else { | |
| 1805 | − /* | |
| 1806 | − * Peripheral register settings are lost during hibernation. | |
| 1807 | − * Update setup flag such that port setup happens again | |
| 1808 | − * during next session. Clients of HS-UART will close and | |
| 1809 | − * open the port during hibernation. | |
| 1810 | − */ | |
| 1811 | − port->setup = false; | |
| 1812 | − } | |
| 1813 | − return ret; | |
| 1814 | −} | |
| 1815 | − | |
| 1816 | 1814 | static const struct qcom_geni_device_data qcom_geni_console_data = { |
| 1817 | 1815 | .console = true, |
| 1818 | 1816 | .mode = GENI_SE_FIFO, |
| @@ -1824,12 +1822,7 @@ static const struct qcom_geni_device_data qcom_geni_uart_data = { · 5 unmodified lines | ||
| 1824 | 1822 | }; |
| 1825 | 1823 | |
| 1826 | 1824 | static const struct dev_pm_ops qcom_geni_serial_pm_ops = { |
| 1827 | − .suspend = pm_sleep_ptr(qcom_geni_serial_sys_suspend), | |
| 1828 | − .resume = pm_sleep_ptr(qcom_geni_serial_sys_resume), | |
| 1829 | − .freeze = pm_sleep_ptr(qcom_geni_serial_sys_suspend), | |
| 1830 | − .poweroff = pm_sleep_ptr(qcom_geni_serial_sys_suspend), | |
| 1831 | − .restore = pm_sleep_ptr(qcom_geni_serial_sys_hib_resume), | |
| 1832 | − .thaw = pm_sleep_ptr(qcom_geni_serial_sys_hib_resume), | |
| 1825 | + SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_suspend, qcom_geni_serial_resume) | |
| 1833 | 1826 | }; |
| 1834 | 1827 | |
| 1835 | 1828 | static const struct of_device_id qcom_geni_serial_match_table[] = { |
| @@ -4726,7 +4726,7 @@ static int con_font_get(struct vc_data *vc, struct console_font_op *op) · 4725 unmodified lines | ||
| 4726 | 4726 | return -EINVAL; |
| 4727 | 4727 | |
| 4728 | 4728 | if (op->data) { |
| 4729 | − font.data = kvmalloc(max_font_size, GFP_KERNEL); | |
| 4729 | + font.data = kvzalloc(max_font_size, GFP_KERNEL); | |
| 4730 | 4730 | if (!font.data) |
| 4731 | 4731 | return -ENOMEM; |
| 4732 | 4732 | } else |
| @@ -539,7 +539,7 @@ int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag) · 538 unmodified lines | ||
| 539 | 539 | struct scsi_cmnd *cmd = lrbp->cmd; |
| 540 | 540 | struct ufs_hw_queue *hwq; |
| 541 | 541 | void __iomem *reg, *opr_sqd_base; |
| 542 | − u32 nexus, id, val; | |
| 542 | + u32 nexus, id, val, rtc; | |
| 543 | 543 | int err; |
| 544 | 544 | |
| 545 | 545 | if (hba->quirks & UFSHCD_QUIRK_MCQ_BROKEN_RTC) |
| @@ -569,17 +569,18 @@ int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag) · 23 unmodified lines | ||
| 569 | 569 | opr_sqd_base = mcq_opr_base(hba, OPR_SQD, id); |
| 570 | 570 | writel(nexus, opr_sqd_base + REG_SQCTI); |
| 571 | 571 | |
| 572 | − /* SQRTCy.ICU = 1 */ | |
| 573 | − writel(SQ_ICU, opr_sqd_base + REG_SQRTC); | |
| 572 | + /* Initiate Cleanup */ | |
| 573 | + writel(readl(opr_sqd_base + REG_SQRTC) | SQ_ICU, | |
| 574 | + opr_sqd_base + REG_SQRTC); | |
| 574 | 575 | |
| 575 | 576 | /* Poll SQRTSy.CUS = 1. Return result from SQRTSy.RTC */ |
| 576 | 577 | reg = opr_sqd_base + REG_SQRTS; |
| 577 | 578 | err = read_poll_timeout(readl, val, val & SQ_CUS, 20, |
| 578 | 579 | MCQ_POLL_US, false, reg); |
| 579 | − if (err) | |
| 580 | − dev_err(hba->dev, "%s: failed. hwq=%d, tag=%d err=%ld\n", | |
| 581 | − __func__, id, task_tag, | |
| 582 | − FIELD_GET(SQ_ICU_ERR_CODE_MASK, readl(reg))); | |
| 580 | + rtc = FIELD_GET(SQ_ICU_ERR_CODE_MASK, readl(reg)); | |
| 581 | + if (err || rtc) | |
| 582 | + dev_err(hba->dev, "%s: failed. hwq=%d, tag=%d err=%d RTC=%d\n", | |
| 583 | + __func__, id, task_tag, err, rtc); | |
| 583 | 584 | |
| 584 | 585 | if (ufshcd_mcq_sq_start(hba, hwq)) |
| 585 | 586 | err = -ETIMEDOUT; |
| @@ -2933,9 +2933,8 @@ static void ufshcd_init_lrb(struct ufs_hba *hba, struct ufshcd_lrb *lrb, int i) · 2932 unmodified lines | ||
| 2933 | 2933 | struct utp_transfer_req_desc *utrdlp = hba->utrdl_base_addr; |
| 2934 | 2934 | dma_addr_t cmd_desc_element_addr = hba->ucdl_dma_addr + |
| 2935 | 2935 | i * ufshcd_get_ucd_size(hba); |
| 2936 | − u16 response_offset = offsetof(struct utp_transfer_cmd_desc, | |
| 2937 | − response_upiu); | |
| 2938 | − u16 prdt_offset = offsetof(struct utp_transfer_cmd_desc, prd_table); | |
| 2936 | + u16 response_offset = le16_to_cpu(utrdlp[i].response_upiu_offset); | |
| 2937 | + u16 prdt_offset = le16_to_cpu(utrdlp[i].prd_table_offset); | |
| 2939 | 2938 | |
| 2940 | 2939 | lrb->utr_descriptor_ptr = utrdlp + i; |
| 2941 | 2940 | lrb->utrd_dma_addr = hba->utrdl_dma_addr + |
| @@ -5417,10 +5416,12 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp, · 2475 unmodified lines | ||
| 5417 | 5416 | } |
| 5418 | 5417 | break; |
| 5419 | 5418 | case OCS_ABORTED: |
| 5420 | − result |= DID_ABORT << 16; | |
| 5421 | − break; | |
| 5422 | 5419 | case OCS_INVALID_COMMAND_STATUS: |
| 5423 | 5420 | result |= DID_REQUEUE << 16; |
| 5421 | + dev_warn(hba->dev, | |
| 5422 | + "OCS %s from controller for tag %d\n", | |
| 5423 | + (ocs == OCS_ABORTED ? "aborted" : "invalid"), | |
| 5424 | + lrbp->task_tag); | |
| 5424 | 5425 | break; |
| 5425 | 5426 | case OCS_INVALID_CMD_TABLE_ATTR: |
| 5426 | 5427 | case OCS_INVALID_PRDT_ATTR: |
| @@ -6466,26 +6467,12 @@ static bool ufshcd_abort_one(struct request *rq, void *priv) · 1039 unmodified lines | ||
| 6466 | 6467 | struct scsi_device *sdev = cmd->device; |
| 6467 | 6468 | struct Scsi_Host *shost = sdev->host; |
| 6468 | 6469 | struct ufs_hba *hba = shost_priv(shost); |
| 6469 | − struct ufshcd_lrb *lrbp = &hba->lrb[tag]; | |
| 6470 | − struct ufs_hw_queue *hwq; | |
| 6471 | − unsigned long flags; | |
| 6472 | 6470 | |
| 6473 | 6471 | *ret = ufshcd_try_to_abort_task(hba, tag); |
| 6474 | 6472 | dev_err(hba->dev, "Aborting tag %d / CDB %#02x %s\n", tag, |
| 6475 | 6473 | hba->lrb[tag].cmd ? hba->lrb[tag].cmd->cmnd[0] : -1, |
| 6476 | 6474 | *ret ? "failed" : "succeeded"); |
| 6477 | 6475 | |
| 6478 | − /* Release cmd in MCQ mode if abort succeeds */ | |
| 6479 | − if (hba->mcq_enabled && (*ret == 0)) { | |
| 6480 | − hwq = ufshcd_mcq_req_to_hwq(hba, scsi_cmd_to_rq(lrbp->cmd)); | |
| 6481 | − if (!hwq) | |
| 6482 | − return 0; | |
| 6483 | − spin_lock_irqsave(&hwq->cq_lock, flags); | |
| 6484 | − if (ufshcd_cmd_inflight(lrbp->cmd)) | |
| 6485 | − ufshcd_release_scsi_cmd(hba, lrbp); | |
| 6486 | − spin_unlock_irqrestore(&hwq->cq_lock, flags); | |
| 6487 | − } | |
| 6488 | − | |
| 6489 | 6476 | return *ret == 0; |
| 6490 | 6477 | } |
| 6491 | 6478 | |
| @@ -8232,7 +8219,7 @@ static void ufshcd_update_rtc(struct ufs_hba *hba) · 1740 unmodified lines | ||
| 8232 | 8219 | |
| 8233 | 8220 | err = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, QUERY_ATTR_IDN_SECONDS_PASSED, |
| 8234 | 8221 | 0, 0, &val); |
| 8235 | − ufshcd_rpm_put_sync(hba); | |
| 8222 | + ufshcd_rpm_put(hba); | |
| 8236 | 8223 | |
| 8237 | 8224 | if (err) |
| 8238 | 8225 | dev_err(hba->dev, "%s: Failed to update rtc %d\n", __func__, err); |
| @@ -10210,7 +10197,9 @@ static void ufshcd_wl_shutdown(struct device *dev) · 1971 unmodified lines | ||
| 10210 | 10197 | shost_for_each_device(sdev, hba->host) { |
| 10211 | 10198 | if (sdev == hba->ufs_device_wlun) |
| 10212 | 10199 | continue; |
| 10213 | − scsi_device_quiesce(sdev); | |
| 10200 | + mutex_lock(&sdev->state_mutex); | |
| 10201 | + scsi_device_set_state(sdev, SDEV_OFFLINE); | |
| 10202 | + mutex_unlock(&sdev->state_mutex); | |
| 10214 | 10203 | } |
| 10215 | 10204 | __ufshcd_wl_suspend(hba, UFS_SHUTDOWN_PM); |
| 10216 | 10205 | |
| @@ -170,11 +170,11 @@ static int usb_acpi_add_usb4_devlink(struct usb_device *udev) · 169 unmodified lines | ||
| 170 | 170 | struct fwnode_handle *nhi_fwnode __free(fwnode_handle) = |
| 171 | 171 | fwnode_find_reference(dev_fwnode(&port_dev->dev), "usb4-host-interface", 0); |
| 172 | 172 | |
| 173 | − if (IS_ERR(nhi_fwnode)) | |
| 173 | + if (IS_ERR(nhi_fwnode) || !nhi_fwnode->dev) | |
| 174 | 174 | return 0; |
| 175 | 175 | |
| 176 | 176 | link = device_link_add(&port_dev->child->dev, nhi_fwnode->dev, |
| 177 | − DL_FLAG_AUTOREMOVE_CONSUMER | | |
| 177 | + DL_FLAG_STATELESS | | |
| 178 | 178 | DL_FLAG_RPM_ACTIVE | |
| 179 | 179 | DL_FLAG_PM_RUNTIME); |
| 180 | 180 | if (!link) { |
| @@ -23,7 +23,6 @@ static void dwc2_set_bcm_params(struct dwc2_hsotg *hsotg) · 22 unmodified lines | ||
| 23 | 23 | p->max_transfer_size = 65535; |
| 24 | 24 | p->max_packet_count = 511; |
| 25 | 25 | p->ahbcfg = 0x10; |
| 26 | − p->no_clock_gating = true; | |
| 27 | 26 | } |
| 28 | 27 | |
| 29 | 28 | static void dwc2_set_his_params(struct dwc2_hsotg *hsotg) |
| @@ -544,6 +544,7 @@ static int dwc3_alloc_event_buffers(struct dwc3 *dwc, unsigned int length) · 543 unmodified lines | ||
| 544 | 544 | int dwc3_event_buffers_setup(struct dwc3 *dwc) |
| 545 | 545 | { |
| 546 | 546 | struct dwc3_event_buffer *evt; |
| 547 | + u32 reg; | |
| 547 | 548 | |
| 548 | 549 | if (!dwc->ev_buf) |
| 549 | 550 | return 0; |
| @@ -556,8 +557,10 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc) · 6 unmodified lines | ||
| 556 | 557 | upper_32_bits(evt->dma)); |
| 557 | 558 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), |
| 558 | 559 | DWC3_GEVNTSIZ_SIZE(evt->length)); |
| 559 | − dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0); | |
| 560 | 560 | |
| 561 | + /* Clear any stale event */ | |
| 562 | + reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)); | |
| 563 | + dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg); | |
| 561 | 564 | return 0; |
| 562 | 565 | } |
| 563 | 566 | |
| @@ -584,7 +587,10 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc) · 20 unmodified lines | ||
| 584 | 587 | dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0); |
| 585 | 588 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK |
| 586 | 589 | | DWC3_GEVNTSIZ_SIZE(0)); |
| 587 | − dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), 0); | |
| 590 | + | |
| 591 | + /* Clear any stale event */ | |
| 592 | + reg = dwc3_readl(dwc->regs, DWC3_GEVNTCOUNT(0)); | |
| 593 | + dwc3_writel(dwc->regs, DWC3_GEVNTCOUNT(0), reg); | |
| 588 | 594 | } |
| 589 | 595 | |
| 590 | 596 | static void dwc3_core_num_eps(struct dwc3 *dwc) |
| @@ -2336,6 +2342,11 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) · 1745 unmodified lines | ||
| 2336 | 2342 | u32 reg; |
| 2337 | 2343 | int i; |
| 2338 | 2344 | |
| 2345 | + dwc->susphy_state = (dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)) & | |
| 2346 | + DWC3_GUSB2PHYCFG_SUSPHY) || | |
| 2347 | + (dwc3_readl(dwc->regs, DWC3_GUSB3PIPECTL(0)) & | |
| 2348 | + DWC3_GUSB3PIPECTL_SUSPHY); | |
| 2349 | + | |
| 2339 | 2350 | switch (dwc->current_dr_role) { |
| 2340 | 2351 | case DWC3_GCTL_PRTCAP_DEVICE: |
| 2341 | 2352 | if (pm_runtime_suspended(dwc->dev)) |
| @@ -2387,6 +2398,15 @@ static int dwc3_suspend_common(struct dwc3 *dwc, pm_message_t msg) · 45 unmodified lines | ||
| 2387 | 2398 | break; |
| 2388 | 2399 | } |
| 2389 | 2400 | |
| 2401 | + if (!PMSG_IS_AUTO(msg)) { | |
| 2402 | + /* | |
| 2403 | + * TI AM62 platform requires SUSPHY to be | |
| 2404 | + * enabled for system suspend to work. | |
| 2405 | + */ | |
| 2406 | + if (!dwc->susphy_state) | |
| 2407 | + dwc3_enable_susphy(dwc, true); | |
| 2408 | + } | |
| 2409 | + | |
| 2390 | 2410 | return 0; |
| 2391 | 2411 | } |
| 2392 | 2412 | |
| @@ -2454,6 +2474,11 @@ static int dwc3_resume_common(struct dwc3 *dwc, pm_message_t msg) · 61 unmodified lines | ||
| 2454 | 2474 | break; |
| 2455 | 2475 | } |
| 2456 | 2476 | |
| 2477 | + if (!PMSG_IS_AUTO(msg)) { | |
| 2478 | + /* restore SUSPHY state to that before system suspend. */ | |
| 2479 | + dwc3_enable_susphy(dwc, dwc->susphy_state); | |
| 2480 | + } | |
| 2481 | + | |
| 2457 | 2482 | return 0; |
| 2458 | 2483 | } |
| 2459 | 2484 | |
| @@ -2499,7 +2524,11 @@ static int dwc3_runtime_resume(struct device *dev) · 39 unmodified lines | ||
| 2499 | 2524 | |
| 2500 | 2525 | switch (dwc->current_dr_role) { |
| 2501 | 2526 | case DWC3_GCTL_PRTCAP_DEVICE: |
| 2502 | − dwc3_gadget_process_pending_events(dwc); | |
| 2527 | + if (dwc->pending_events) { | |
| 2528 | + pm_runtime_put(dwc->dev); | |
| 2529 | + dwc->pending_events = false; | |
| 2530 | + enable_irq(dwc->irq_gadget); | |
| 2531 | + } | |
| 2503 | 2532 | break; |
| 2504 | 2533 | case DWC3_GCTL_PRTCAP_HOST: |
| 2505 | 2534 | default: |
| @@ -2552,7 +2581,7 @@ static int dwc3_suspend(struct device *dev) · 46 unmodified lines | ||
| 2552 | 2581 | static int dwc3_resume(struct device *dev) |
| 2553 | 2582 | { |
| 2554 | 2583 | struct dwc3 *dwc = dev_get_drvdata(dev); |
| 2555 | − int ret; | |
| 2584 | + int ret = 0; | |
| 2556 | 2585 | |
| 2557 | 2586 | pinctrl_pm_select_default_state(dev); |
| 2558 | 2587 | |
| @@ -2560,14 +2589,12 @@ static int dwc3_resume(struct device *dev) · 1 unmodified line | ||
| 2560 | 2589 | pm_runtime_set_active(dev); |
| 2561 | 2590 | |
| 2562 | 2591 | ret = dwc3_resume_common(dwc, PMSG_RESUME); |
| 2563 | − if (ret) { | |
| 2592 | + if (ret) | |
| 2564 | 2593 | pm_runtime_set_suspended(dev); |
| 2565 | − return ret; | |
| 2566 | − } | |
| 2567 | 2594 | |
| 2568 | 2595 | pm_runtime_enable(dev); |
| 2569 | 2596 | |
| 2570 | − return 0; | |
| 2597 | + return ret; | |
| 2571 | 2598 | } |
| 2572 | 2599 | |
| 2573 | 2600 | static void dwc3_complete(struct device *dev) |
| @@ -2589,6 +2616,12 @@ static void dwc3_complete(struct device *dev) · 15 unmodified lines | ||
| 2589 | 2616 | static const struct dev_pm_ops dwc3_dev_pm_ops = { |
| 2590 | 2617 | SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume) |
| 2591 | 2618 | .complete = dwc3_complete, |
| 2619 | + | |
| 2620 | + /* | |
| 2621 | + * Runtime suspend halts the controller on disconnection. It relies on | |
| 2622 | + * platforms with custom connection notification to start the controller | |
| 2623 | + * again. | |
| 2624 | + */ | |
| 2592 | 2625 | SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume, |
| 2593 | 2626 | dwc3_runtime_idle) |
| 2594 | 2627 | }; |
| @@ -1150,6 +1150,8 @@ struct dwc3_scratchpad_array { · 1149 unmodified lines | ||
| 1150 | 1150 | * @sys_wakeup: set if the device may do system wakeup. |
| 1151 | 1151 | * @wakeup_configured: set if the device is configured for remote wakeup. |
| 1152 | 1152 | * @suspended: set to track suspend event due to U3/L2. |
| 1153 | + * @susphy_state: state of DWC3_GUSB2PHYCFG_SUSPHY + DWC3_GUSB3PIPECTL_SUSPHY | |
| 1154 | + * before PM suspend. | |
| 1153 | 1155 | * @imod_interval: set the interrupt moderation interval in 250ns |
| 1154 | 1156 | * increments or 0 to disable. |
| 1155 | 1157 | * @max_cfg_eps: current max number of IN eps used across all USB configs. |
| @@ -1382,6 +1384,7 @@ struct dwc3 { · 226 unmodified lines | ||
| 1382 | 1384 | unsigned sys_wakeup:1; |
| 1383 | 1385 | unsigned wakeup_configured:1; |
| 1384 | 1386 | unsigned suspended:1; |
| 1387 | + unsigned susphy_state:1; | |
| 1385 | 1388 | |
| 1386 | 1389 | u16 imod_interval; |
| 1387 | 1390 | |
| @@ -1675,7 +1678,6 @@ static inline void dwc3_otg_host_init(struct dwc3 *dwc) · 287 unmodified lines | ||
| 1675 | 1678 | #if !IS_ENABLED(CONFIG_USB_DWC3_HOST) |
| 1676 | 1679 | int dwc3_gadget_suspend(struct dwc3 *dwc); |
| 1677 | 1680 | int dwc3_gadget_resume(struct dwc3 *dwc); |
| 1678 | −void dwc3_gadget_process_pending_events(struct dwc3 *dwc); | |
| 1679 | 1681 | #else |
| 1680 | 1682 | static inline int dwc3_gadget_suspend(struct dwc3 *dwc) |
| 1681 | 1683 | { |
| @@ -1687,9 +1689,6 @@ static inline int dwc3_gadget_resume(struct dwc3 *dwc) · 5 unmodified lines | ||
| 1687 | 1689 | return 0; |
| 1688 | 1690 | } |
| 1689 | 1691 | |
| 1690 | −static inline void dwc3_gadget_process_pending_events(struct dwc3 *dwc) | |
| 1691 | −{ | |
| 1692 | −} | |
| 1693 | 1692 | #endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */ |
| 1694 | 1693 | |
| 1695 | 1694 | #if IS_ENABLED(CONFIG_USB_DWC3_ULPI) |
| @@ -438,6 +438,10 @@ skip_status: · 437 unmodified lines | ||
| 438 | 438 | dwc3_gadget_ep_get_transfer_index(dep); |
| 439 | 439 | } |
| 440 | 440 | |
| 441 | + if (DWC3_DEPCMD_CMD(cmd) == DWC3_DEPCMD_ENDTRANSFER && | |
| 442 | + !(cmd & DWC3_DEPCMD_CMDIOC)) | |
| 443 | + mdelay(1); | |
| 444 | + | |
| 441 | 445 | if (saved_config) { |
| 442 | 446 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); |
| 443 | 447 | reg |= saved_config; |
| @@ -1715,12 +1719,10 @@ static int __dwc3_stop_active_transfer(struct dwc3_ep *dep, bool force, bool int · 1271 unmodified lines | ||
| 1715 | 1719 | WARN_ON_ONCE(ret); |
| 1716 | 1720 | dep->resource_index = 0; |
| 1717 | 1721 | |
| 1718 | − if (!interrupt) { | |
| 1719 | − mdelay(1); | |
| 1722 | + if (!interrupt) | |
| 1720 | 1723 | dep->flags &= ~DWC3_EP_TRANSFER_STARTED; |
| 1721 | − } else if (!ret) { | |
| 1724 | + else if (!ret) | |
| 1722 | 1725 | dep->flags |= DWC3_EP_END_TRANSFER_PENDING; |
| 1723 | − } | |
| 1724 | 1726 | |
| 1725 | 1727 | dep->flags &= ~DWC3_EP_DELAY_STOP; |
| 1726 | 1728 | return ret; |
| @@ -4728,14 +4730,3 @@ int dwc3_gadget_resume(struct dwc3 *dwc) · 3001 unmodified lines | ||
| 4728 | 4730 | |
| 4729 | 4731 | return dwc3_gadget_soft_connect(dwc); |
| 4730 | 4732 | } |
| 4731 | − | |
| 4732 | −void dwc3_gadget_process_pending_events(struct dwc3 *dwc) | |
| 4733 | −{ | |
| 4734 | − if (dwc->pending_events) { | |
| 4735 | − dwc3_interrupt(dwc->irq_gadget, dwc->ev_buf); | |
| 4736 | − dwc3_thread_interrupt(dwc->irq_gadget, dwc->ev_buf); | |
| 4737 | − pm_runtime_put(dwc->dev); | |
| 4738 | − dwc->pending_events = false; | |
| 4739 | − enable_irq(dwc->irq_gadget); | |
| 4740 | − } | |
| 4741 | −} | |
| @@ -2061,7 +2061,7 @@ static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \ · 2060 unmodified lines | ||
| 2061 | 2061 | const char *page, size_t len) \ |
| 2062 | 2062 | { \ |
| 2063 | 2063 | struct f_uac2_opts *opts = to_f_uac2_opts(item); \ |
| 2064 | − int ret = 0; \ | |
| 2064 | + int ret = len; \ | |
| 2065 | 2065 | \ |
| 2066 | 2066 | mutex_lock(&opts->lock); \ |
| 2067 | 2067 | if (opts->refcnt) { \ |
| @@ -2072,8 +2072,8 @@ static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \ · 4 unmodified lines | ||
| 2072 | 2072 | if (len && page[len - 1] == '\n') \ |
| 2073 | 2073 | len--; \ |
| 2074 | 2074 | \ |
| 2075 | − ret = scnprintf(opts->name, min(sizeof(opts->name), len + 1), \ | |
| 2076 | − "%s", page); \ | |
| 2075 | + scnprintf(opts->name, min(sizeof(opts->name), len + 1), \ | |
| 2076 | + "%s", page); \ | |
| 2077 | 2077 | \ |
| 2078 | 2078 | end: \ |
| 2079 | 2079 | mutex_unlock(&opts->lock); \ |
| @@ -1696,6 +1696,7 @@ int usb_gadget_register_driver_owner(struct usb_gadget_driver *driver, · 1695 unmodified lines | ||
| 1696 | 1696 | driver->driver.bus = &gadget_bus_type; |
| 1697 | 1697 | driver->driver.owner = owner; |
| 1698 | 1698 | driver->driver.mod_name = mod_name; |
| 1699 | + driver->driver.probe_type = PROBE_FORCE_SYNCHRONOUS; | |
| 1699 | 1700 | ret = driver_register(&driver->driver); |
| 1700 | 1701 | if (ret) { |
| 1701 | 1702 | pr_warn("%s: driver registration failed: %d\n", |
| @@ -254,6 +254,7 @@ struct dummy_hcd { · 253 unmodified lines | ||
| 254 | 254 | u32 stream_en_ep; |
| 255 | 255 | u8 num_stream[30 / 2]; |
| 256 | 256 | |
| 257 | + unsigned timer_pending:1; | |
| 257 | 258 | unsigned active:1; |
| 258 | 259 | unsigned old_active:1; |
| 259 | 260 | unsigned resuming:1; |
| @@ -1303,9 +1304,11 @@ static int dummy_urb_enqueue( · 1043 unmodified lines | ||
| 1303 | 1304 | urb->error_count = 1; /* mark as a new urb */ |
| 1304 | 1305 | |
| 1305 | 1306 | /* kick the scheduler, it'll do the rest */ |
| 1306 | − if (!hrtimer_active(&dum_hcd->timer)) | |
| 1307 | + if (!dum_hcd->timer_pending) { | |
| 1308 | + dum_hcd->timer_pending = 1; | |
| 1307 | 1309 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), |
| 1308 | 1310 | HRTIMER_MODE_REL_SOFT); |
| 1311 | + } | |
| 1309 | 1312 | |
| 1310 | 1313 | done: |
| 1311 | 1314 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); |
| @@ -1324,9 +1327,10 @@ static int dummy_urb_dequeue(struct usb_hcd *hcd, struct urb *urb, int status) · 12 unmodified lines | ||
| 1324 | 1327 | spin_lock_irqsave(&dum_hcd->dum->lock, flags); |
| 1325 | 1328 | |
| 1326 | 1329 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); |
| 1327 | − if (!rc && dum_hcd->rh_state != DUMMY_RH_RUNNING && | |
| 1328 | − !list_empty(&dum_hcd->urbp_list)) | |
| 1330 | + if (rc == 0 && !dum_hcd->timer_pending) { | |
| 1331 | + dum_hcd->timer_pending = 1; | |
| 1329 | 1332 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); |
| 1333 | + } | |
| 1330 | 1334 | |
| 1331 | 1335 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); |
| 1332 | 1336 | return rc; |
| @@ -1813,6 +1817,7 @@ static enum hrtimer_restart dummy_timer(struct hrtimer *t) · 480 unmodified lines | ||
| 1813 | 1817 | |
| 1814 | 1818 | /* look at each urb queued by the host side driver */ |
| 1815 | 1819 | spin_lock_irqsave(&dum->lock, flags); |
| 1820 | + dum_hcd->timer_pending = 0; | |
| 1816 | 1821 | |
| 1817 | 1822 | if (!dum_hcd->udev) { |
| 1818 | 1823 | dev_err(dummy_dev(dum_hcd), |
| @@ -1994,8 +1999,10 @@ return_urb: · 175 unmodified lines | ||
| 1994 | 1999 | if (list_empty(&dum_hcd->urbp_list)) { |
| 1995 | 2000 | usb_put_dev(dum_hcd->udev); |
| 1996 | 2001 | dum_hcd->udev = NULL; |
| 1997 | − } else if (dum_hcd->rh_state == DUMMY_RH_RUNNING) { | |
| 2002 | + } else if (!dum_hcd->timer_pending && | |
| 2003 | + dum_hcd->rh_state == DUMMY_RH_RUNNING) { | |
| 1998 | 2004 | /* want a 1 msec delay here */ |
| 2005 | + dum_hcd->timer_pending = 1; | |
| 1999 | 2006 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), |
| 2000 | 2007 | HRTIMER_MODE_REL_SOFT); |
| 2001 | 2008 | } |
| @@ -2390,8 +2397,10 @@ static int dummy_bus_resume(struct usb_hcd *hcd) · 388 unmodified lines | ||
| 2390 | 2397 | } else { |
| 2391 | 2398 | dum_hcd->rh_state = DUMMY_RH_RUNNING; |
| 2392 | 2399 | set_link_state(dum_hcd); |
| 2393 | − if (!list_empty(&dum_hcd->urbp_list)) | |
| 2400 | + if (!list_empty(&dum_hcd->urbp_list)) { | |
| 2401 | + dum_hcd->timer_pending = 1; | |
| 2394 | 2402 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); |
| 2403 | + } | |
| 2395 | 2404 | hcd->state = HC_STATE_RUNNING; |
| 2396 | 2405 | } |
| 2397 | 2406 | spin_unlock_irq(&dum_hcd->dum->lock); |
| @@ -2522,6 +2531,7 @@ static void dummy_stop(struct usb_hcd *hcd) · 124 unmodified lines | ||
| 2522 | 2531 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); |
| 2523 | 2532 | |
| 2524 | 2533 | hrtimer_cancel(&dum_hcd->timer); |
| 2534 | + dum_hcd->timer_pending = 0; | |
| 2525 | 2535 | device_remove_file(dummy_dev(dum_hcd), &dev_attr_urbs); |
| 2526 | 2536 | dev_info(dummy_dev(dum_hcd), "stopped\n"); |
| 2527 | 2537 | } |
| @@ -110,6 +110,7 @@ struct dbc_port { · 109 unmodified lines | ||
| 110 | 110 | struct tasklet_struct push; |
| 111 | 111 | |
| 112 | 112 | struct list_head write_pool; |
| 113 | + unsigned int tx_boundary; | |
| 113 | 114 | |
| 114 | 115 | bool registered; |
| 115 | 116 | }; |
| @@ -24,6 +24,29 @@ static inline struct dbc_port *dbc_to_port(struct xhci_dbc *dbc) · 23 unmodified lines | ||
| 24 | 24 | return dbc->priv; |
| 25 | 25 | } |
| 26 | 26 | |
| 27 | +static unsigned int | |
| 28 | +dbc_kfifo_to_req(struct dbc_port *port, char *packet) | |
| 29 | +{ | |
| 30 | + unsigned int len; | |
| 31 | + | |
| 32 | + len = kfifo_len(&port->port.xmit_fifo); | |
| 33 | + | |
| 34 | + if (len == 0) | |
| 35 | + return 0; | |
| 36 | + | |
| 37 | + len = min(len, DBC_MAX_PACKET); | |
| 38 | + | |
| 39 | + if (port->tx_boundary) | |
| 40 | + len = min(port->tx_boundary, len); | |
| 41 | + | |
| 42 | + len = kfifo_out(&port->port.xmit_fifo, packet, len); | |
| 43 | + | |
| 44 | + if (port->tx_boundary) | |
| 45 | + port->tx_boundary -= len; | |
| 46 | + | |
| 47 | + return len; | |
| 48 | +} | |
| 49 | + | |
| 27 | 50 | static int dbc_start_tx(struct dbc_port *port) |
| 28 | 51 | __releases(&port->port_lock) |
| 29 | 52 | __acquires(&port->port_lock) |
| @@ -36,7 +59,7 @@ static int dbc_start_tx(struct dbc_port *port) · 6 unmodified lines | ||
| 36 | 59 | |
| 37 | 60 | while (!list_empty(pool)) { |
| 38 | 61 | req = list_entry(pool->next, struct dbc_request, list_pool); |
| 39 | − len = kfifo_out(&port->port.xmit_fifo, req->buf, DBC_MAX_PACKET); | |
| 62 | + len = dbc_kfifo_to_req(port, req->buf); | |
| 40 | 63 | if (len == 0) |
| 41 | 64 | break; |
| 42 | 65 | do_tty_wake = true; |
| @@ -200,14 +223,32 @@ static ssize_t dbc_tty_write(struct tty_struct *tty, const u8 *buf, · 157 unmodified lines | ||
| 200 | 223 | { |
| 201 | 224 | struct dbc_port *port = tty->driver_data; |
| 202 | 225 | unsigned long flags; |
| 226 | + unsigned int written = 0; | |
| 203 | 227 | |
| 204 | 228 | spin_lock_irqsave(&port->port_lock, flags); |
| 205 | − if (count) | |
| 206 | − count = kfifo_in(&port->port.xmit_fifo, buf, count); | |
| 207 | − dbc_start_tx(port); | |
| 229 | + | |
| 230 | + /* | |
| 231 | + * Treat tty write as one usb transfer. Make sure the writes are turned | |
| 232 | + * into TRB request having the same size boundaries as the tty writes. | |
| 233 | + * Don't add data to kfifo before previous write is turned into TRBs | |
| 234 | + */ | |
| 235 | + if (port->tx_boundary) { | |
| 236 | + spin_unlock_irqrestore(&port->port_lock, flags); | |
| 237 | + return 0; | |
| 238 | + } | |
| 239 | + | |
| 240 | + if (count) { | |
| 241 | + written = kfifo_in(&port->port.xmit_fifo, buf, count); | |
| 242 | + | |
| 243 | + if (written == count) | |
| 244 | + port->tx_boundary = kfifo_len(&port->port.xmit_fifo); | |
| 245 | + | |
| 246 | + dbc_start_tx(port); | |
| 247 | + } | |
| 248 | + | |
| 208 | 249 | spin_unlock_irqrestore(&port->port_lock, flags); |
| 209 | 250 | |
| 210 | − return count; | |
| 251 | + return written; | |
| 211 | 252 | } |
| 212 | 253 | |
| 213 | 254 | static int dbc_tty_put_char(struct tty_struct *tty, u8 ch) |
| @@ -241,6 +282,10 @@ static unsigned int dbc_tty_write_room(struct tty_struct *tty) · 27 unmodified lines | ||
| 241 | 282 | |
| 242 | 283 | spin_lock_irqsave(&port->port_lock, flags); |
| 243 | 284 | room = kfifo_avail(&port->port.xmit_fifo); |
| 285 | + | |
| 286 | + if (port->tx_boundary) | |
| 287 | + room = 0; | |
| 288 | + | |
| 244 | 289 | spin_unlock_irqrestore(&port->port_lock, flags); |
| 245 | 290 | |
| 246 | 291 | return room; |
| @@ -79,6 +79,7 @@ · 78 unmodified lines | ||
| 79 | 79 | #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 |
| 80 | 80 | #define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242 |
| 81 | 81 | #define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142 |
| 82 | +#define PCI_DEVICE_ID_ASMEDIA_3042_XHCI 0x3042 | |
| 82 | 83 | #define PCI_DEVICE_ID_ASMEDIA_3242_XHCI 0x3242 |
| 83 | 84 | |
| 84 | 85 | #define PCI_DEVICE_ID_CADENCE 0x17CD |
| @@ -451,6 +452,10 @@ static void xhci_pci_quirks(struct device *dev, struct xhci_hcd *xhci) · 366 unmodified lines | ||
| 451 | 452 | pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) |
| 452 | 453 | xhci->quirks |= XHCI_ASMEDIA_MODIFY_FLOWCONTROL; |
| 453 | 454 | |
| 455 | + if (pdev->vendor == PCI_VENDOR_ID_ASMEDIA && | |
| 456 | + pdev->device == PCI_DEVICE_ID_ASMEDIA_3042_XHCI) | |
| 457 | + xhci->quirks |= XHCI_RESET_ON_RESUME; | |
| 458 | + | |
| 454 | 459 | if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241) |
| 455 | 460 | xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7; |
| 456 | 461 | |
| @@ -635,7 +640,7 @@ int xhci_pci_common_probe(struct pci_dev *dev, const struct pci_device_id *id) · 178 unmodified lines | ||
| 635 | 640 | pm_runtime_put_noidle(&dev->dev); |
| 636 | 641 | |
| 637 | 642 | if (pci_choose_state(dev, PMSG_SUSPEND) == PCI_D0) |
| 638 | − pm_runtime_forbid(&dev->dev); | |
| 643 | + pm_runtime_get(&dev->dev); | |
| 639 | 644 | else if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW) |
| 640 | 645 | pm_runtime_allow(&dev->dev); |
| 641 | 646 | |
| @@ -678,7 +683,9 @@ void xhci_pci_remove(struct pci_dev *dev) · 36 unmodified lines | ||
| 678 | 683 | |
| 679 | 684 | xhci->xhc_state |= XHCI_STATE_REMOVING; |
| 680 | 685 | |
| 681 | − if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW) | |
| 686 | + if (pci_choose_state(dev, PMSG_SUSPEND) == PCI_D0) | |
| 687 | + pm_runtime_put(&dev->dev); | |
| 688 | + else if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW) | |
| 682 | 689 | pm_runtime_forbid(&dev->dev); |
| 683 | 690 | |
| 684 | 691 | if (xhci->shared_hcd) { |
| @@ -1023,7 +1023,7 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep) · 1022 unmodified lines | ||
| 1023 | 1023 | td_to_noop(xhci, ring, cached_td, false); |
| 1024 | 1024 | cached_td->cancel_status = TD_CLEARED; |
| 1025 | 1025 | } |
| 1026 | − | |
| 1026 | + td_to_noop(xhci, ring, td, false); | |
| 1027 | 1027 | td->cancel_status = TD_CLEARING_CACHE; |
| 1028 | 1028 | cached_td = td; |
| 1029 | 1029 | break; |
| @@ -1718,6 +1718,14 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, · 688 unmodified lines | ||
| 1718 | 1718 | |
| 1719 | 1719 | trace_xhci_handle_command(xhci->cmd_ring, &cmd_trb->generic); |
| 1720 | 1720 | |
| 1721 | + cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event->status)); | |
| 1722 | + | |
| 1723 | + /* If CMD ring stopped we own the trbs between enqueue and dequeue */ | |
| 1724 | + if (cmd_comp_code == COMP_COMMAND_RING_STOPPED) { | |
| 1725 | + complete_all(&xhci->cmd_ring_stop_completion); | |
| 1726 | + return; | |
| 1727 | + } | |
| 1728 | + | |
| 1721 | 1729 | cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, |
| 1722 | 1730 | cmd_trb); |
| 1723 | 1731 | /* |
| @@ -1734,14 +1742,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, · 10 unmodified lines | ||
| 1734 | 1742 | |
| 1735 | 1743 | cancel_delayed_work(&xhci->cmd_timer); |
| 1736 | 1744 | |
| 1737 | − cmd_comp_code = GET_COMP_CODE(le32_to_cpu(event->status)); | |
| 1738 | − | |
| 1739 | − /* If CMD ring stopped we own the trbs between enqueue and dequeue */ | |
| 1740 | − if (cmd_comp_code == COMP_COMMAND_RING_STOPPED) { | |
| 1741 | − complete_all(&xhci->cmd_ring_stop_completion); | |
| 1742 | − return; | |
| 1743 | − } | |
| 1744 | − | |
| 1745 | 1745 | if (cmd->command_trb != xhci->cmd_ring->dequeue) { |
| 1746 | 1746 | xhci_err(xhci, |
| 1747 | 1747 | "Command completion event does not match command\n"); |
| @@ -2775,6 +2775,29 @@ static int handle_tx_event(struct xhci_hcd *xhci, · 1027 unmodified lines | ||
| 2775 | 2775 | return 0; |
| 2776 | 2776 | } |
| 2777 | 2777 | |
| 2778 | + /* | |
| 2779 | + * xhci 4.10.2 states isoc endpoints should continue | |
| 2780 | + * processing the next TD if there was an error mid TD. | |
| 2781 | + * So host like NEC don't generate an event for the last | |
| 2782 | + * isoc TRB even if the IOC flag is set. | |
| 2783 | + * xhci 4.9.1 states that if there are errors in mult-TRB | |
| 2784 | + * TDs xHC should generate an error for that TRB, and if xHC | |
| 2785 | + * proceeds to the next TD it should genete an event for | |
| 2786 | + * any TRB with IOC flag on the way. Other host follow this. | |
| 2787 | + * | |
| 2788 | + * We wait for the final IOC event, but if we get an event | |
| 2789 | + * anywhere outside this TD, just give it back already. | |
| 2790 | + */ | |
| 2791 | + td = list_first_entry_or_null(&ep_ring->td_list, struct xhci_td, td_list); | |
| 2792 | + | |
| 2793 | + if (td && td->error_mid_td && !trb_in_td(xhci, td, ep_trb_dma, false)) { | |
| 2794 | + xhci_dbg(xhci, "Missing TD completion event after mid TD error\n"); | |
| 2795 | + ep_ring->dequeue = td->last_trb; | |
| 2796 | + ep_ring->deq_seg = td->last_trb_seg; | |
| 2797 | + inc_deq(xhci, ep_ring); | |
| 2798 | + xhci_td_cleanup(xhci, td, ep_ring, td->status); | |
| 2799 | + } | |
| 2800 | + | |
| 2778 | 2801 | if (list_empty(&ep_ring->td_list)) { |
| 2779 | 2802 | /* |
| 2780 | 2803 | * Don't print wanings if ring is empty due to a stopped endpoint generating an |
| @@ -2836,44 +2859,13 @@ static int handle_tx_event(struct xhci_hcd *xhci, · 55 unmodified lines | ||
| 2836 | 2859 | return 0; |
| 2837 | 2860 | } |
| 2838 | 2861 | |
| 2839 | − /* | |
| 2840 | − * xhci 4.10.2 states isoc endpoints should continue | |
| 2841 | − * processing the next TD if there was an error mid TD. | |
| 2842 | − * So host like NEC don't generate an event for the last | |
| 2843 | − * isoc TRB even if the IOC flag is set. | |
| 2844 | − * xhci 4.9.1 states that if there are errors in mult-TRB | |
| 2845 | − * TDs xHC should generate an error for that TRB, and if xHC | |
| 2846 | − * proceeds to the next TD it should genete an event for | |
| 2847 | − * any TRB with IOC flag on the way. Other host follow this. | |
| 2848 | − * So this event might be for the next TD. | |
| 2849 | − */ | |
| 2850 | − if (td->error_mid_td && | |
| 2851 | − !list_is_last(&td->td_list, &ep_ring->td_list)) { | |
| 2852 | − struct xhci_td *td_next = list_next_entry(td, td_list); | |
| 2853 | − | |
| 2854 | − ep_seg = trb_in_td(xhci, td_next, ep_trb_dma, false); | |
| 2855 | − if (ep_seg) { | |
30 more lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 1666 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 37 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 198 lines aren’t shown here.
This diff is large: its 196 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 93 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 204 lines aren’t shown here.
This diff is large: its 187 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 109 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 253 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 871 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 437 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 154 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 117 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 183 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 104 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 83 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 312 lines aren’t shown here.
This diff is large: its 167 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 140 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 70 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 213 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 6765 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 132 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 274 lines aren’t shown here.
This diff is large: its 138 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 185 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 91 lines aren’t shown here.
This diff is large: its 186 lines aren’t shown here.
This diff is large: its 141 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 134 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 95 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 154 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 125 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 347 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 240 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 573 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 111 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 79 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 94 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 60 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 223 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 147 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 283 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 42 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 50 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 48 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 82 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 25 lines aren’t shown here.
This diff is large: its 115 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 26 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 43 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 68 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 380 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 61 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 38 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 174 lines aren’t shown here.
This diff is large: its 92 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 17 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 66 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 22 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 73 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 55 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 33 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 58 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 105 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 45 lines aren’t shown here.
This diff is large: its 18 lines aren’t shown here.
This diff is large: its 69 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 29 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 307 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 134 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 57 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 40 lines aren’t shown here.
This diff is large: its 110 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 56 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 49 lines aren’t shown here.
This diff is large: its 182 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 108 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 86 lines aren’t shown here.
This diff is large: its 62 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 47 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 35 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 5 lines aren’t shown here.
This diff is large: its 32 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 44 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 7 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 180 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 16 lines aren’t shown here.
This diff is large: its 27 lines aren’t shown here.
This diff is large: its 71 lines aren’t shown here.
This diff is large: its 96 lines aren’t shown here.
This diff is large: its 122 lines aren’t shown here.
This diff is large: its 2 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 13 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 169 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 161 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 15 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 24 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 21 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 10 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 12 lines aren’t shown here.
This diff is large: its 9 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 11 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 23 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 183 lines aren’t shown here.
This diff is large: its 19 lines aren’t shown here.
This diff is large: its 14 lines aren’t shown here.
This diff is large: its 54 lines aren’t shown here.
This diff is large: its 8 lines aren’t shown here.
This diff is large: its 34 lines aren’t shown here.