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 | Andrzej Hajda <andrzej.hajda@intel.com> <a.hajda@samsung.com> | 73 | Andrzej Hajda <andrzej.hajda@intel.com> <a.hajda@samsung.com> |
| 74 | André Almeida <andrealmeid@igalia.com> <andrealmeid@collabora.com> | 74 | André Almeida <andrealmeid@igalia.com> <andrealmeid@collabora.com> |
| 75 | Andy Adamson <andros@citi.umich.edu> | 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 | Andy Shevchenko <andy@kernel.org> <andy@smile.org.ua> | 78 | Andy Shevchenko <andy@kernel.org> <andy@smile.org.ua> |
| 77 | Andy Shevchenko <andy@kernel.org> <ext-andriy.shevchenko@nokia.com> | 79 | Andy Shevchenko <andy@kernel.org> <ext-andriy.shevchenko@nokia.com> |
| 78 | Anilkumar Kolli <quic_akolli@quicinc.com> <akolli@codeaurora.org> | 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 | Enric Balletbo i Serra <eballetbo@kernel.org> <enric.balletbo@collabora.com> | 199 | Enric Balletbo i Serra <eballetbo@kernel.org> <enric.balletbo@collabora.com> |
| 198 | Enric Balletbo i Serra <eballetbo@kernel.org> <eballetbo@iseebcn.com> | 200 | Enric Balletbo i Serra <eballetbo@kernel.org> <eballetbo@iseebcn.com> |
| 199 | Erik Kaneda <erik.kaneda@intel.com> <erik.schmauss@intel.com> | 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 | Evgeniy Polyakov <johnpol@2ka.mipt.ru> | 204 | Evgeniy Polyakov <johnpol@2ka.mipt.ru> |
| 202 | Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> <ezequiel@collabora.com> | 205 | Ezequiel Garcia <ezequiel@vanguardiasur.com.ar> <ezequiel@collabora.com> |
| 203 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason@jlekstrand.net> | 206 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason@jlekstrand.net> |
| 204 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@intel.com> | 207 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@intel.com> |
| 205 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@collabora.com> | 208 | Faith Ekstrand <faith.ekstrand@collabora.com> <jason.ekstrand@collabora.com> |
| 209 | Fangrui Song <i@maskray.me> <maskray@google.com> | ||
| 206 | Felipe W Damasio <felipewd@terra.com.br> | 210 | Felipe W Damasio <felipewd@terra.com.br> |
| 207 | Felix Kuhling <fxkuehl@gmx.de> | 211 | Felix Kuhling <fxkuehl@gmx.de> |
| 208 | Felix Moeller <felix@derklecks.de> | 212 | Felix Moeller <felix@derklecks.de> |
| 209 | Fenglin Wu <quic_fenglinw@quicinc.com> <fenglinw@codeaurora.org> | 213 | Fenglin Wu <quic_fenglinw@quicinc.com> <fenglinw@codeaurora.org> |
| 210 | Filipe Lautert <filipe@icewall.org> | 214 | Filipe Lautert <filipe@icewall.org> |
| 211 | Finn Thain <fthain@linux-m68k.org> <fthain@telegraphics.com.au> | 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 | Franck Bui-Huu <vagabon.xyz@gmail.com> | 219 | Franck Bui-Huu <vagabon.xyz@gmail.com> |
| 213 | Frank Rowand <frowand.list@gmail.com> <frank.rowand@am.sony.com> | 220 | Frank Rowand <frowand.list@gmail.com> <frank.rowand@am.sony.com> |
| 214 | Frank Rowand <frowand.list@gmail.com> <frank.rowand@sony.com> | 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 | Jan Kuliga <jtkuliga.kdev@gmail.com> <jankul@alatek.krakow.pl> | 283 | Jan Kuliga <jtkuliga.kdev@gmail.com> <jankul@alatek.krakow.pl> |
| 277 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@linux.intel.com> | 284 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko.sakkinen@linux.intel.com> |
| 278 | Jarkko Sakkinen <jarkko@kernel.org> <jarkko@profian.com> | 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 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com> | 287 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@mellanox.com> |
| 281 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com> | 288 | Jason Gunthorpe <jgg@ziepe.ca> <jgg@nvidia.com> |
| 282 | Jason Gunthorpe <jgg@ziepe.ca> <jgunthorpe@obsidianresearch.com> | 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 | Jens Axboe <axboe@kernel.dk> <axboe@meta.com> | 307 | Jens Axboe <axboe@kernel.dk> <axboe@meta.com> |
| 301 | Jens Osterkamp <Jens.Osterkamp@de.ibm.com> | 308 | Jens Osterkamp <Jens.Osterkamp@de.ibm.com> |
| 302 | Jernej Skrabec <jernej.skrabec@gmail.com> <jernej.skrabec@siol.net> | 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 | Jessica Zhang <quic_jesszhan@quicinc.com> <jesszhan@codeaurora.org> | 315 | Jessica Zhang <quic_jesszhan@quicinc.com> <jesszhan@codeaurora.org> |
| 304 | Jilai Wang <quic_jilaiw@quicinc.com> <jilaiw@codeaurora.org> | 316 | Jilai Wang <quic_jilaiw@quicinc.com> <jilaiw@codeaurora.org> |
| 305 | Jiri Kosina <jikos@kernel.org> <jikos@jikos.cz> | 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 | D: ISDN Maintainer | 1358 | D: ISDN Maintainer |
| 1359 | S: USA | 1359 | S: USA |
| 1360 | 1360 | ||
| 1361 | N: Gerrit Renker | ||
| 1362 | E: gerrit@erg.abdn.ac.uk | ||
| 1363 | D: DCCP protocol support. | ||
| 1364 | |||
| 1365 | N: Philip Gladstone | 1361 | N: Philip Gladstone |
| 1366 | E: philip@gladstonefamily.net | 1362 | E: philip@gladstonefamily.net |
| 1367 | D: Kernel / timekeeping stuff | 1363 | D: Kernel / timekeeping stuff |
| @@ -1677,11 +1673,6 @@ W: http://www.carumba.com/ · 309 unmodified lines | |||
| 1677 | D: bug toaster (A1 sauce makes all the difference) | 1673 | D: bug toaster (A1 sauce makes all the difference) |
| 1678 | D: Random linux hacker | 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 | N: Tim Hockin | 1676 | N: Tim Hockin |
| 1686 | E: thockin@hockin.org | 1677 | E: thockin@hockin.org |
| 1687 | W: http://www.hockin.org/~thockin | 1678 | W: http://www.hockin.org/~thockin |
| @@ -1697,6 +1688,11 @@ D: hwmon subsystem maintainer · 9 unmodified lines | |||
| 1697 | D: i2c-sis96x and i2c-stub SMBus drivers | 1688 | D: i2c-sis96x and i2c-stub SMBus drivers |
| 1698 | S: USA | 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 | N: Dirk Hohndel | 1696 | N: Dirk Hohndel |
| 1701 | E: hohndel@suse.de | 1697 | E: hohndel@suse.de |
| 1702 | D: The XFree86[tm] Project | 1698 | D: The XFree86[tm] Project |
| @@ -1872,6 +1868,10 @@ S: K osmidomkum 723 · 169 unmodified lines | |||
| 1872 | S: 160 00 Praha 6 | 1868 | S: 160 00 Praha 6 |
| 1873 | S: Czech Republic | 1869 | S: Czech Republic |
| 1874 | 1870 | ||
| 1871 | N: Seth Jennings | ||
| 1872 | E: sjenning@redhat.com | ||
| 1873 | D: Creation and maintenance of zswap | ||
| 1874 | |||
| 1875 | N: Jeremy Kerr | 1875 | N: Jeremy Kerr |
| 1876 | D: Maintainer of SPU File System | 1876 | D: Maintainer of SPU File System |
| 1877 | 1877 | ||
| @@ -2188,19 +2188,6 @@ N: Mike Kravetz · 310 unmodified lines | |||
| 2188 | E: mike.kravetz@oracle.com | 2188 | E: mike.kravetz@oracle.com |
| 2189 | D: Maintenance and development of the hugetlb subsystem | 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 | N: Andreas S. Krebs | 2191 | N: Andreas S. Krebs |
| 2205 | E: akrebs@altavista.net | 2192 | E: akrebs@altavista.net |
| 2206 | D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards | 2193 | D: CYPRESS CY82C693 chipset IDE, Digital's PC-Alpha 164SX boards |
| @@ -3191,6 +3178,11 @@ N: Ken Pizzini · 984 unmodified lines | |||
| 3191 | E: ken@halcyon.com | 3178 | E: ken@halcyon.com |
| 3192 | D: CDROM driver "sonycd535" (Sony CDU-535/531) | 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 | N: Stelian Pop | 3186 | N: Stelian Pop |
| 3195 | E: stelian@popies.net | 3187 | E: stelian@popies.net |
| 3196 | P: 1024D/EDBB6147 7B36 0E07 04BC 11DC A7A0 D3F7 7185 9E7A EDBB 6147 | 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 | S: 79098 Freiburg | 3292 | S: 79098 Freiburg |
| 3301 | S: Germany | 3293 | S: Germany |
| 3302 | 3294 | ||
| 3295 | N: Gerrit Renker | ||
| 3296 | E: gerrit@erg.abdn.ac.uk | ||
| 3297 | D: DCCP protocol support. | ||
| 3298 | |||
| 3303 | N: Thomas Renninger | 3299 | N: Thomas Renninger |
| 3304 | E: trenn@suse.de | 3300 | E: trenn@suse.de |
| 3305 | D: cpupowerutils | 3301 | D: cpupowerutils |
| @@ -3576,11 +3572,6 @@ D: several improvements to system programs · 270 unmodified lines | |||
| 3576 | S: Oldenburg | 3572 | S: Oldenburg |
| 3577 | S: Germany | 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 | N: Robert Schwebel | 3575 | N: Robert Schwebel |
| 3585 | E: robert@schwebel.de | 3576 | E: robert@schwebel.de |
| 3586 | W: https://www.schwebel.de | 3577 | W: https://www.schwebel.de |
| @@ -3771,6 +3762,11 @@ S: Chr. Winthersvej 1 B, st.th. · 184 unmodified lines | |||
| 3771 | S: DK-1860 Frederiksberg C | 3762 | S: DK-1860 Frederiksberg C |
| 3772 | S: Denmark | 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 | N: Drew Sullivan | 3770 | N: Drew Sullivan |
| 3775 | E: drew@ss.org | 3771 | E: drew@ss.org |
| 3776 | W: http://www.ss.org/ | 3772 | W: http://www.ss.org/ |
| @@ -4286,6 +4282,10 @@ S: Pipers Way · 509 unmodified lines | |||
| 4286 | S: Swindon. SN3 1RJ | 4282 | S: Swindon. SN3 1RJ |
| 4287 | S: England | 4283 | S: England |
| 4288 | 4284 | ||
| 4285 | N: Vitaly Wool | ||
| 4286 | E: vitaly.wool@konsulko.com | ||
| 4287 | D: Maintenance and development of zswap | ||
| 4288 | |||
| 4289 | N: Chris Wright | 4289 | N: Chris Wright |
| 4290 | E: chrisw@sous-sol.org | 4290 | E: chrisw@sous-sol.org |
| 4291 | D: hacking on LSM framework and security modules. | 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 | authorization of the policies (prohibiting an attacker from gaining | 223 | authorization of the policies (prohibiting an attacker from gaining |
| 224 | unconstrained root, and deploying an "allow all" policy). These | 224 | unconstrained root, and deploying an "allow all" policy). These |
| 225 | policies must be signed by a certificate that chains to the | 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 | openssl smime -sign \ | 231 | openssl smime -sign \ |
| 229 | -in "$MY_POLICY" \ | 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 | policy. Two checks will always be performed on this policy: First, the | 269 | policy. Two checks will always be performed on this policy: First, the |
| 267 | ``policy_names`` must match with the updated version and the existing | 270 | ``policy_names`` must match with the updated version and the existing |
| 268 | version. Second the updated policy must have a policy version greater than | 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 | The ``delete`` file is used to remove a policy that is no longer needed. | 274 | The ``delete`` file is used to remove a policy that is no longer needed. |
| 272 | This file is write-only and accepts a value of ``1`` to delete the policy. | 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 | ``rate_limit_us`` | 426 | ``rate_limit_us`` |
| 427 | Minimum time (in microseconds) that has to pass between two consecutive | 427 | Minimum time (in microseconds) that has to pass between two consecutive |
| 428 | runs of governor computations (default: 1000 times the scaling driver's | 428 | runs of governor computations (default: 1.5 times the scaling driver's |
| 429 | transition latency). | 429 | transition latency or the maximum 2ms). |
| 430 | 430 | ||
| 431 | The purpose of this tunable is to reduce the scheduler context overhead | 431 | The purpose of this tunable is to reduce the scheduler context overhead |
| 432 | of the governor which might be excessive without it. | 432 | of the governor which might be excessive without it. |
| @@ -474,17 +474,17 @@ This governor exposes the following tunables: · 41 unmodified lines | |||
| 474 | This is how often the governor's worker routine should run, in | 474 | This is how often the governor's worker routine should run, in |
| 475 | microseconds. | 475 | microseconds. |
| 476 | 476 | ||
| 477 | Typically, it is set to values of the order of 10000 (10 ms). Its | 477 | Typically, it is set to values of the order of 2000 (2 ms). Its |
| 478 | default value is equal to the value of ``cpuinfo_transition_latency`` | 478 | default value is to add a 50% breathing room |
| 479 | for each policy this governor is attached to (but since the unit here | 479 | to ``cpuinfo_transition_latency`` on each policy this governor is |
| 480 | is greater by 1000, this means that the time represented by | 480 | attached to. The minimum is typically the length of two scheduler |
| 481 | ``sampling_rate`` is 1000 times greater than the transition latency by | 481 | ticks. |
| 482 | default). | ||
| 483 | 482 | ||
| 484 | If this tunable is per-policy, the following shell command sets the time | 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 | ``up_threshold`` | 489 | ``up_threshold`` |
| 490 | If the estimated CPU load is above this value (in percent), the governor | 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 | * Intel server CPUs, Skylake and later | 12 | * Intel server CPUs, Skylake and later |
| 13 | * Intel client CPUs, Tiger Lake (11th Gen Core) and later | 13 | * Intel client CPUs, Tiger Lake (11th Gen Core) and later |
| 14 | * Future AMD CPUs | 14 | * Future AMD CPUs |
| 15 | * arm64 CPUs implementing the Permission Overlay Extension (FEAT_S1POE) | ||
| 15 | 16 | ||
| 17 | x86_64 | ||
| 18 | ====== | ||
| 16 | Pkeys work by dedicating 4 previously Reserved bits in each page table entry to | 19 | Pkeys work by dedicating 4 previously Reserved bits in each page table entry to |
| 17 | a "protection key", giving 16 possible keys. | 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 | theoretically space in the PAE PTEs. These permissions are enforced on data | 31 | theoretically space in the PAE PTEs. These permissions are enforced on data |
| 29 | access only and have no effect on instruction fetches. | 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 | Syscalls | 50 | Syscalls |
| 32 | ======== | 51 | ======== |
| 33 | 52 | ||
| @@ -38,11 +57,10 @@ There are 3 system calls which directly interact with pkeys:: · 4 unmodified lines | |||
| 38 | int pkey_mprotect(unsigned long start, size_t len, | 57 | int pkey_mprotect(unsigned long start, size_t len, |
| 39 | unsigned long prot, int pkey); | 58 | unsigned long prot, int pkey); |
| 40 | 59 | ||
| 41 | Before a pkey can be used, it must first be allocated with | 60 | Before a pkey can be used, it must first be allocated with pkey_alloc(). An |
| 42 | pkey_alloc(). An application calls the WRPKRU instruction | 61 | application writes to the architecture specific CPU register directly in order |
| 43 | directly in order to change access permissions to memory covered | 62 | to change access permissions to memory covered with a key. In this example |
| 44 | with a key. In this example WRPKRU is wrapped by a C function | 63 | this is wrapped by a C function called pkey_set(). |
| 45 | called pkey_set(). | ||
| 46 | :: | 64 | :: |
| 47 | 65 | ||
| 48 | int real_prot = PROT_READ|PROT_WRITE; | 66 | int real_prot = PROT_READ|PROT_WRITE; |
| @@ -64,9 +82,9 @@ is no longer in use:: · 15 unmodified lines | |||
| 64 | munmap(ptr, PAGE_SIZE); | 82 | munmap(ptr, PAGE_SIZE); |
| 65 | pkey_free(pkey); | 83 | pkey_free(pkey); |
| 66 | 84 | ||
| 67 | .. note:: pkey_set() is a wrapper for the RDPKRU and WRPKRU instructions. | 85 | .. note:: pkey_set() is a wrapper around writing to the CPU register. |
| 68 | An example implementation can be found in | 86 | Example implementations can be found in |
| 69 | tools/testing/selftests/x86/protection_keys.c. | 87 | tools/testing/selftests/mm/pkey-{arm64,powerpc,x86}.h |
| 70 | 88 | ||
| 71 | Behavior | 89 | Behavior |
| 72 | ======== | 90 | ======== |
| @@ -96,3 +114,7 @@ with a read():: · 23 unmodified lines | |||
| 96 | The kernel will send a SIGSEGV in both cases, but si_code will be set | 114 | The kernel will send a SIGSEGV in both cases, but si_code will be set |
| 97 | to SEGV_PKERR when violating protection keys versus SEGV_ACCERR when | 115 | to SEGV_PKERR when violating protection keys versus SEGV_ACCERR when |
| 98 | the plain mprotect() permissions are violated. | 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 | - const: sleep | 63 | - const: sleep |
| 64 | 64 | ||
| 65 | power-domains: | 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 | maxItems: 1 | 76 | maxItems: 1 |
| 67 | 77 | ||
| 68 | port: | 78 | port: |
| @@ -79,20 +89,6 @@ required: · 10 unmodified lines | |||
| 79 | - clock-names | 89 | - clock-names |
| 80 | - port | 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 | additionalProperties: false | 92 | additionalProperties: false |
| 97 | 93 | ||
| 98 | examples: | 94 | examples: |
| @@ -38,6 +38,7 @@ properties: · 37 unmodified lines | |||
| 38 | description: A phandle and PM domain specifier as defined by bindings of | 38 | description: A phandle and PM domain specifier as defined by bindings of |
| 39 | the power controller specified by phandle. See | 39 | the power controller specified by phandle. See |
| 40 | Documentation/devicetree/bindings/power/power-domain.yaml for details. | 40 | Documentation/devicetree/bindings/power/power-domain.yaml for details. |
| 41 | maxItems: 1 | ||
| 41 | 42 | ||
| 42 | mediatek,gce-client-reg: | 43 | mediatek,gce-client-reg: |
| 43 | description: | 44 | description: |
| @@ -57,6 +58,9 @@ properties: · 13 unmodified lines | |||
| 57 | clocks: | 58 | clocks: |
| 58 | items: | 59 | items: |
| 59 | - description: SPLIT Clock | 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 | required: | 65 | required: |
| 62 | - compatible | 66 | - compatible |
| @@ -72,9 +76,24 @@ allOf: · 9 unmodified lines | |||
| 72 | const: mediatek,mt8195-mdp3-split | 76 | const: mediatek,mt8195-mdp3-split |
| 73 | 77 | ||
| 74 | then: | 78 | then: |
| 79 | properties: | ||
| 80 | clocks: | ||
| 81 | minItems: 3 | ||
| 82 | |||
| 75 | required: | 83 | required: |
| 76 | - mediatek,gce-client-reg | 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 | additionalProperties: false | 97 | additionalProperties: false |
| 79 | 98 | ||
| 80 | examples: | 99 | examples: |
| @@ -67,6 +67,10 @@ properties: · 66 unmodified lines | |||
| 67 | A 2.5V to 3.3V supply for the external reference voltage. When omitted, | 67 | A 2.5V to 3.3V supply for the external reference voltage. When omitted, |
| 68 | the internal 2.5V reference is used. | 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 | aina-supply: | 74 | aina-supply: |
| 71 | description: | 75 | description: |
| 72 | The common mode voltage supply for the AINA- pin on pseudo-differential | 76 | The common mode voltage supply for the AINA- pin on pseudo-differential |
| @@ -135,6 +139,23 @@ allOf: · 62 unmodified lines | |||
| 135 | ainc-supply: false | 139 | ainc-supply: false |
| 136 | aind-supply: false | 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 | examples: | 159 | examples: |
| 139 | - | | 160 | - | |
| 140 | #include <dt-bindings/interrupt-controller/irq.h> | 161 | #include <dt-bindings/interrupt-controller/irq.h> |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | |||
| 4 | $id: http://devicetree.org/schemas/iio/dac/adi,ad5686.yaml# | 4 | $id: http://devicetree.org/schemas/iio/dac/adi,ad5686.yaml# |
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | 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 | maintainers: | 9 | maintainers: |
| 10 | - Michael Hennerich <michael.hennerich@analog.com> | 10 | - Michael Hennerich <michael.hennerich@analog.com> |
| @@ -12,41 +12,22 @@ maintainers: · 1 unmodified line | |||
| 12 | 12 | ||
| 13 | properties: | 13 | properties: |
| 14 | compatible: | 14 | compatible: |
| 15 | oneOf: | 15 | enum: |
| 16 | - description: SPI devices | 16 | - adi,ad5310r |
| 17 | enum: | 17 | - adi,ad5672r |
| 18 | - adi,ad5310r | 18 | - adi,ad5674r |
| 19 | - adi,ad5672r | 19 | - adi,ad5676 |
| 20 | - adi,ad5674r | 20 | - adi,ad5676r |
| 21 | - adi,ad5676 | 21 | - adi,ad5679r |
| 22 | - adi,ad5676r | 22 | - adi,ad5681r |
| 23 | - adi,ad5679r | 23 | - adi,ad5682r |
| 24 | - adi,ad5681r | 24 | - adi,ad5683 |
| 25 | - adi,ad5682r | 25 | - adi,ad5683r |
| 26 | - adi,ad5683 | 26 | - adi,ad5684 |
| 27 | - adi,ad5683r | 27 | - adi,ad5684r |
| 28 | - adi,ad5684 | 28 | - adi,ad5685r |
| 29 | - adi,ad5684r | 29 | - adi,ad5686 |
| 30 | - adi,ad5685r | 30 | - adi,ad5686r |
| 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 | |||
| 50 | 31 | ||
| 51 | reg: | 32 | reg: |
| 52 | maxItems: 1 | 33 | maxItems: 1 |
| @@ -4,7 +4,7 @@ · 3 unmodified lines | |||
| 4 | $id: http://devicetree.org/schemas/iio/dac/adi,ad5696.yaml# | 4 | $id: http://devicetree.org/schemas/iio/dac/adi,ad5696.yaml# |
| 5 | $schema: http://devicetree.org/meta-schemas/core.yaml# | 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 | maintainers: | 9 | maintainers: |
| 10 | - Michael Auchter <michael.auchter@ni.com> | 10 | - Michael Auchter <michael.auchter@ni.com> |
| @@ -16,6 +16,7 @@ properties: · 5 unmodified lines | |||
| 16 | compatible: | 16 | compatible: |
| 17 | enum: | 17 | enum: |
| 18 | - adi,ad5311r | 18 | - adi,ad5311r |
| 19 | - adi,ad5337r | ||
| 19 | - adi,ad5338r | 20 | - adi,ad5338r |
| 20 | - adi,ad5671r | 21 | - adi,ad5671r |
| 21 | - adi,ad5675r | 22 | - adi,ad5675r |
| @@ -82,9 +82,6 @@ allOf: · 81 unmodified lines | |||
| 82 | enum: | 82 | enum: |
| 83 | - fsl,ls1043a-extirq | 83 | - fsl,ls1043a-extirq |
| 84 | - fsl,ls1046a-extirq | 84 | - fsl,ls1046a-extirq |
| 85 | - fsl,ls1088a-extirq | ||
| 86 | - fsl,ls2080a-extirq | ||
| 87 | - fsl,lx2160a-extirq | ||
| 88 | then: | 85 | then: |
| 89 | properties: | 86 | properties: |
| 90 | interrupt-map: | 87 | interrupt-map: |
| @@ -95,6 +92,29 @@ allOf: · 4 unmodified lines | |||
| 95 | - const: 0xf | 92 | - const: 0xf |
| 96 | - const: 0 | 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 | additionalProperties: false | 118 | additionalProperties: false |
| 99 | 119 | ||
| 100 | examples: | 120 | examples: |
| @@ -113,7 +113,7 @@ properties: · 112 unmodified lines | |||
| 113 | 113 | ||
| 114 | msi-parent: | 114 | msi-parent: |
| 115 | deprecated: true | 115 | deprecated: true |
| 116 | $ref: /schemas/types.yaml#/definitions/phandle | 116 | maxItems: 1 |
| 117 | description: | 117 | description: |
| 118 | Describes the MSI controller node handling message | 118 | Describes the MSI controller node handling message |
| 119 | interrupts for the MC. When there is no translation | 119 | interrupts for the MC. When there is no translation |
| @@ -26,6 +26,7 @@ properties: · 25 unmodified lines | |||
| 26 | - brcm,asp-v2.1-mdio | 26 | - brcm,asp-v2.1-mdio |
| 27 | - brcm,asp-v2.2-mdio | 27 | - brcm,asp-v2.2-mdio |
| 28 | - brcm,unimac-mdio | 28 | - brcm,unimac-mdio |
| 29 | - brcm,bcm6846-mdio | ||
| 29 | 30 | ||
| 30 | reg: | 31 | reg: |
| 31 | minItems: 1 | 32 | minItems: 1 |
| @@ -154,8 +154,6 @@ allOf: · 153 unmodified lines | |||
| 154 | - qcom,sm8550-qmp-gen4x2-pcie-phy | 154 | - qcom,sm8550-qmp-gen4x2-pcie-phy |
| 155 | - qcom,sm8650-qmp-gen3x2-pcie-phy | 155 | - qcom,sm8650-qmp-gen3x2-pcie-phy |
| 156 | - qcom,sm8650-qmp-gen4x2-pcie-phy | 156 | - qcom,sm8650-qmp-gen4x2-pcie-phy |
| 157 | - qcom,x1e80100-qmp-gen3x2-pcie-phy | ||
| 158 | - qcom,x1e80100-qmp-gen4x2-pcie-phy | ||
| 159 | then: | 157 | then: |
| 160 | properties: | 158 | properties: |
| 161 | clocks: | 159 | clocks: |
| @@ -171,6 +169,8 @@ allOf: · 9 unmodified lines | |||
| 171 | - qcom,sc8280xp-qmp-gen3x1-pcie-phy | 169 | - qcom,sc8280xp-qmp-gen3x1-pcie-phy |
| 172 | - qcom,sc8280xp-qmp-gen3x2-pcie-phy | 170 | - qcom,sc8280xp-qmp-gen3x2-pcie-phy |
| 173 | - qcom,sc8280xp-qmp-gen3x4-pcie-phy | 171 | - qcom,sc8280xp-qmp-gen3x4-pcie-phy |
| 172 | - qcom,x1e80100-qmp-gen3x2-pcie-phy | ||
| 173 | - qcom,x1e80100-qmp-gen4x2-pcie-phy | ||
| 174 | - qcom,x1e80100-qmp-gen4x4-pcie-phy | 174 | - qcom,x1e80100-qmp-gen4x4-pcie-phy |
| 175 | then: | 175 | then: |
| 176 | properties: | 176 | properties: |
| @@ -201,6 +201,7 @@ allOf: · 24 unmodified lines | |||
| 201 | - qcom,sm8550-qmp-gen4x2-pcie-phy | 201 | - qcom,sm8550-qmp-gen4x2-pcie-phy |
| 202 | - qcom,sm8650-qmp-gen4x2-pcie-phy | 202 | - qcom,sm8650-qmp-gen4x2-pcie-phy |
| 203 | - qcom,x1e80100-qmp-gen4x2-pcie-phy | 203 | - qcom,x1e80100-qmp-gen4x2-pcie-phy |
| 204 | - qcom,x1e80100-qmp-gen4x4-pcie-phy | ||
| 204 | then: | 205 | then: |
| 205 | properties: | 206 | properties: |
| 206 | resets: | 207 | resets: |
| @@ -102,21 +102,21 @@ properties: · 101 unmodified lines | |||
| 102 | default: 2 | 102 | default: 2 |
| 103 | 103 | ||
| 104 | interrupts: | 104 | interrupts: |
| 105 | oneOf: | 105 | minItems: 1 |
| 106 | - minItems: 1 | 106 | maxItems: 2 |
| 107 | items: | ||
| 108 | - description: TX interrupt | ||
| 109 | - description: RX interrupt | ||
| 110 | - items: | ||
| 111 | - description: common/combined interrupt | ||
| 112 | 107 | ||
| 113 | interrupt-names: | 108 | interrupt-names: |
| 114 | oneOf: | 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 | items: | 115 | items: |
| 117 | - const: tx | 116 | - const: tx |
| 118 | - const: rx | 117 | - const: rx |
| 119 | - const: common | 118 | - description: Common/combined interrupt |
| 119 | const: common | ||
| 120 | 120 | ||
| 121 | fck_parent: | 121 | fck_parent: |
| 122 | $ref: /schemas/types.yaml#/definitions/string | 122 | $ref: /schemas/types.yaml#/definitions/string |
| @@ -48,6 +48,10 @@ properties: · 47 unmodified lines | |||
| 48 | - const: mclk_rx | 48 | - const: mclk_rx |
| 49 | - const: hclk | 49 | - const: hclk |
| 50 | 50 | ||
| 51 | port: | ||
| 52 | $ref: audio-graph-port.yaml# | ||
| 53 | unevaluatedProperties: false | ||
| 54 | |||
| 51 | resets: | 55 | resets: |
| 52 | maxItems: 1 | 56 | maxItems: 1 |
| 53 | 57 | ||
| @@ -101,8 +101,6 @@ properties: · 100 unmodified lines | |||
| 101 | - domintech,dmard09 | 101 | - domintech,dmard09 |
| 102 | # DMARD10: 3-axis Accelerometer | 102 | # DMARD10: 3-axis Accelerometer |
| 103 | - domintech,dmard10 | 103 | - domintech,dmard10 |
| 104 | # Elgin SPI-controlled LCD | ||
| 105 | - elgin,jg10309-01 | ||
| 106 | # MMA7660FC: 3-Axis Orientation/Motion Detection Sensor | 104 | # MMA7660FC: 3-Axis Orientation/Motion Detection Sensor |
| 107 | - fsl,mma7660 | 105 | - fsl,mma7660 |
| 108 | # MMA8450Q: Xtrinsic Low-power, 3-axis Xtrinsic Accelerometer | 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 | This mask can also be set through sysfs, eg:: | 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 | Starting the Cache | 121 | Starting the Cache |
| @@ -208,7 +208,7 @@ The filesystem must arrange to `cancel · 207 unmodified lines | |||
| 208 | such `reservations | 208 | such `reservations |
| 209 | <https://lore.kernel.org/linux-xfs/20220817093627.GZ3600936@dread.disaster.area/>`_ | 209 | <https://lore.kernel.org/linux-xfs/20220817093627.GZ3600936@dread.disaster.area/>`_ |
| 210 | because writeback will not consume the reservation. | 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 | ``->iomap_end`` function to find all the clean areas of the folios | 212 | ``->iomap_end`` function to find all the clean areas of the folios |
| 213 | caching a fresh (``IOMAP_F_NEW``) delalloc mapping. | 213 | caching a fresh (``IOMAP_F_NEW``) delalloc mapping. |
| 214 | It takes the ``invalidate_lock``. | 214 | It takes the ``invalidate_lock``. |
| @@ -592,4 +592,3 @@ API Function Reference · 591 unmodified lines | |||
| 592 | 592 | ||
| 593 | .. kernel-doc:: include/linux/netfs.h | 593 | .. kernel-doc:: include/linux/netfs.h |
| 594 | .. kernel-doc:: fs/netfs/buffered_read.c | 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 | Reference voltage | 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 | - Internal reference (2.5V) | 55 | - Internal reference (2.5V) |
| 47 | - External reference (2.5V to 3.3V) | 56 | - External reference (2.5V to 3.3V) |
| 48 | 57 | ||
| 49 | The source is determined by the device tree. If ``refio-supply`` is present, | 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 | Oversampling and resolution boost | 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 | section of 'MAINTAINERS' file. | 7 | section of 'MAINTAINERS' file. |
| 8 | 8 | ||
| 9 | The mailing lists for the subsystem are damon@lists.linux.dev and | 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 | 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 | 11 | <https://git.kernel.org/akpm/mm/h/mm-unstable>`_ whenever possible and posted |
| 12 | the mailing lists. | 12 | to the mailing lists. |
| 13 | 13 | ||
| 14 | SCM Trees | 14 | SCM Trees |
| 15 | --------- | 15 | --------- |
| 16 | 16 | ||
| 17 | There are multiple Linux trees for DAMON development. Patches under | 17 | There are multiple Linux trees for DAMON development. Patches under |
| 18 | development or testing are queued in `damon/next | 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 | Sufficiently reviewed patches will be queued in `mm-unstable | 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 | subsystem maintainer. After more sufficient tests, the patches will be queued | 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 | pull-requested to the mainline by the memory management subsystem maintainer. | 24 | pull-requested to the mainline by the memory management subsystem maintainer. |
| 25 | 25 | ||
| 26 | Note again the patches for mm-unstable `tree | 26 | Note again the patches for `mm-unstable tree |
| 27 | <https://git.kernel.org/akpm/mm/h/mm-unstable>` are queued by the memory | 27 | <https://git.kernel.org/akpm/mm/h/mm-unstable>`_ are queued by the memory |
| 28 | management subsystem maintainer. If the patches requires some patches in | 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 | in mm-unstable, please make sure the requirement is clearly specified. | 30 | in mm-unstable, please make sure the requirement is clearly specified. |
| 31 | 31 | ||
| 32 | Submit checklist addendum | 32 | Submit checklist addendum |
| @@ -37,25 +37,25 @@ When making DAMON changes, you should do below. · 4 unmodified lines | |||
| 37 | - Build changes related outputs including kernel and documents. | 37 | - Build changes related outputs including kernel and documents. |
| 38 | - Ensure the builds introduce no new errors or warnings. | 38 | - Ensure the builds introduce no new errors or warnings. |
| 39 | - Run and ensure no new failures for DAMON `selftests | 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 | `kunittests | 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 | Further doing below and putting the results will be helpful. | 44 | Further doing below and putting the results will be helpful. |
| 45 | 45 | ||
| 46 | - Run `damon-tests/corr | 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 | changes. | 48 | changes. |
| 49 | - Run `damon-tests/perf | 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 | changes. | 51 | changes. |
| 52 | 52 | ||
| 53 | Key cycle dates | 53 | Key cycle dates |
| 54 | --------------- | 54 | --------------- |
| 55 | 55 | ||
| 56 | Patches can be sent anytime. Key cycle dates of the `mm-unstable | 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 | 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 | 58 | <https://git.kernel.org/akpm/mm/h/mm-stable>`_ trees depend on the memory |
| 59 | management subsystem maintainer. | 59 | management subsystem maintainer. |
| 60 | 60 | ||
| 61 | Review cadence | 61 | Review cadence |
| @@ -72,13 +72,13 @@ Mailing tool · 10 unmodified lines | |||
| 72 | Like many other Linux kernel subsystems, DAMON uses the mailing lists | 72 | Like many other Linux kernel subsystems, DAMON uses the mailing lists |
| 73 | (damon@lists.linux.dev and linux-mm@kvack.org) as the major communication | 73 | (damon@lists.linux.dev and linux-mm@kvack.org) as the major communication |
| 74 | channel. There is a simple tool called `HacKerMaiL | 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 | are not very familiar with the mailing lists based communication. The tool | 76 | are not very familiar with the mailing lists based communication. The tool |
| 77 | could be particularly helpful for DAMON community members since it is developed | 77 | could be particularly helpful for DAMON community members since it is developed |
| 78 | and maintained by DAMON maintainer. The tool is also officially announced to | 78 | and maintained by DAMON maintainer. The tool is also officially announced to |
| 79 | support DAMON and general Linux kernel development workflow. | 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 | tool for DAMON community, which DAMON maintainer is committed to support. | 82 | tool for DAMON community, which DAMON maintainer is committed to support. |
| 83 | Please feel free to try and report issues or feature requests for the tool to | 83 | Please feel free to try and report issues or feature requests for the tool to |
| 84 | the maintainer. | 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 | time slot, by reaching out to the maintainer. | 98 | time slot, by reaching out to the maintainer. |
| 99 | 99 | ||
| 100 | Schedules and available reservation time slots are available at the Google `doc | 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 | There is also a public Google `calendar | 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 | that has the events. Anyone can subscribe it. DAMON maintainer will also | 104 | that has the events. Anyone can subscribe it. DAMON maintainer will also |
| 105 | provide periodic reminder to the mailing list (damon@lists.linux.dev). | 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 | Howto can be found at: | 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 | Please send your comments to | 21 | Please send your comments to |
| 22 | - Ulisses Alonso Camaró <uaca@i.hate.spam.alumni.uv.es> | 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 | /* bind socket to eth0 */ | 166 | /* bind socket to eth0 */ |
| 167 | bind(this->socket, (struct sockaddr *)&my_addr, sizeof(struct sockaddr_ll)); | 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 | By default, the user should put data at:: | 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 | a Message Authentication Code (MAC). MACs are produced from the content | 9 | a Message Authentication Code (MAC). MACs are produced from the content |
| 10 | of a TCP segment using a hashing function with a password known to both peers. | 10 | of a TCP segment using a hashing function with a password known to both peers. |
| 11 | The intent of TCP-AO is to deprecate TCP-MD5 providing better security, | 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 | 1. Introduction | 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 | is not available, no action is required (RNextKeyID of a received | 164 | is not available, no action is required (RNextKeyID of a received |
| 165 | segment needs to match the MKT’s SendID). | 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 | 167 | Q: How is current_key set, and when does it change? Is it a user-triggered |
| 168 | change, or is it by a request from the remote peer? Is it set by the user | 168 | change, or is it triggered by a request from the remote peer? Is it set by the |
| 169 | explicitly, or by a matching rule? | 169 | user explicitly, or by a matching rule? |
| 170 | 170 | ||
| 171 | A: current_key is set by RNextKeyID [6.1]:: | 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 | Q: Can a non-TCP-AO connection become a TCP-AO-enabled one? | 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 | 236 | A: No: for an already established non-TCP-AO connection it would be impossible |
| 237 | to switch using TCP-AO as the traffic key generation requires the initial | 237 | to switch to using TCP-AO, as the traffic key generation requires the initial |
| 238 | sequence numbers. Paraphrasing, starting using TCP-AO would require | 238 | sequence numbers. Paraphrasing, starting using TCP-AO would require |
| 239 | re-establishing the TCP connection. | 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 | Linux provides a set of ``setsockopt()s`` and ``getsockopt()s`` that let | 293 | Linux provides a set of ``setsockopt()s`` and ``getsockopt()s`` that let |
| 294 | userspace manage TCP-AO on a per-socket basis. In order to add/delete MKTs | 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 | It is not allowed to add a key on an established non-TCP-AO connection | 296 | It is not allowed to add a key on an established non-TCP-AO connection |
| 297 | as well as to remove the last key from TCP-AO connection. | 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 | 4. ``setsockopt()`` vs ``accept()`` race | 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 | TCP-AO connections may have many keys, which means that accepted connections | 365 | TCP-AO connections may have many keys, which means that accepted connections |
| 366 | on a listen socket may have any amount of keys as well. As copying all those | 366 | on a listen socket may have any amount of keys as well. As copying all those |
| 367 | keys on a first properly signed SYN would make the request socket bigger, that | 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 | hanging in the accept queue. | 374 | hanging in the accept queue. |
| 375 | 375 | ||
| 376 | The reverse is valid as well: if userspace adds a new key for a peer on | 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 | have the new keys. | 378 | have the new keys. |
| 379 | 379 | ||
| 380 | At this moment, the resolution for the two races: | 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 | and ``setsockopt(TCP_AO_DEL_KEY)`` vs ``accept()`` is delegated to userspace. | 382 | and ``setsockopt(TCP_AO_DEL_KEY)`` vs ``accept()`` is delegated to userspace. |
| 383 | This means that it's expected that userspace would check the MKTs on the socket | 383 | This means that it's expected that userspace would check the MKTs on the socket |
| 384 | that was returned by ``accept()`` to verify that any key rotation that | 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 | This is a similar "do-nothing" approach to TCP-MD5 from the kernel side and | 387 | This is a similar "do-nothing" approach to TCP-MD5 from the kernel side and |
| 388 | may be changed later by introducing new flags to ``tcp_ao_add`` | 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 | with better review coverage. Re-posting large series also increases the mailing | 355 | with better review coverage. Re-posting large series also increases the mailing |
| 356 | list traffic. | 356 | list traffic. |
| 357 | 357 | ||
| 358 | .. _rcs: | ||
| 359 | |||
| 358 | Local variable ordering ("reverse xmas tree", "RCS") | 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 | ``__free()`` within networking core and drivers is discouraged. | 393 | ``__free()`` within networking core and drivers is discouraged. |
| 392 | Similar guidance applies to declaring variables mid-function. | 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 | Resending after review | 411 | Resending after review |
| 395 | ~~~~~~~~~~~~~~~~~~~~~~ | 412 | ~~~~~~~~~~~~~~~~~~~~~~ |
| 396 | 413 | ||
| @@ -30,10 +30,13 @@ tree as a dedicated branch covering multiple subsystems. · 29 unmodified lines | |||
| 30 | The main SoC tree is housed on git.kernel.org: | 30 | The main SoC tree is housed on git.kernel.org: |
| 31 | https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/ | 31 | https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git/ |
| 32 | 32 | ||
| 33 | Maintainers | ||
| 34 | ----------- | ||
| 35 | |||
| 33 | Clearly this is quite a wide range of topics, which no one person, or even | 36 | Clearly this is quite a wide range of topics, which no one person, or even |
| 34 | small group of people are capable of maintaining. Instead, the SoC subsystem | 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 | 38 | is comprised of many submaintainers (platform maintainers), each taking care of |
| 36 | and driver subdirectories. | 39 | individual platforms and driver subdirectories. |
| 37 | In this regard, "platform" usually refers to a series of SoCs from a given | 40 | In this regard, "platform" usually refers to a series of SoCs from a given |
| 38 | vendor, for example, Nvidia's series of Tegra SoCs. Many submaintainers operate | 41 | vendor, for example, Nvidia's series of Tegra SoCs. Many submaintainers operate |
| 39 | on a vendor level, responsible for multiple product lines. For several reasons, | 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 | Most of these submaintainers have their own trees where they stage patches, | 47 | Most of these submaintainers have their own trees where they stage patches, |
| 45 | sending pull requests to the main SoC tree. These trees are usually, but not | 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 | 49 | always, listed in MAINTAINERS. |
| 47 | alias soc@kernel.org if there is no platform-specific maintainer, or if they | ||
| 48 | are unresponsive. | ||
| 49 | 50 | ||
| 50 | What the SoC tree is not, however, is a location for architecture-specific code | 51 | What the SoC tree is not, however, is a location for architecture-specific code |
| 51 | changes. Each architecture has its own maintainers that are responsible for | 52 | changes. Each architecture has its own maintainers that are responsible for |
| 52 | architectural details, CPU errata and the like. | 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 | Information for (new) Submaintainers | 86 | Information for (new) Submaintainers |
| 55 | ------------------------------------ | 87 | ------------------------------------ |
| 56 | 88 | ||
| @@ -17,7 +17,7 @@ Architecture Level of support Constraints · 16 unmodified lines | |||
| 17 | ============= ================ ============================================== | 17 | ============= ================ ============================================== |
| 18 | ``arm64`` Maintained Little Endian only. | 18 | ``arm64`` Maintained Little Endian only. |
| 19 | ``loongarch`` Maintained \- | 19 | ``loongarch`` Maintained \- |
| 20 | ``riscv`` Maintained ``riscv64`` only. | 20 | ``riscv`` Maintained ``riscv64`` and LLVM/Clang only. |
| 21 | ``um`` Maintained \- | 21 | ``um`` Maintained \- |
| 22 | ``x86`` Maintained ``x86_64`` only. | 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 | .. code-block:: none | 66 | .. code-block:: none |
| 67 | 67 | ||
| 68 | # make -j16 -C tools/sched_ext | 68 | # make -j16 -C tools/sched_ext |
| 69 | # tools/sched_ext/scx_simple | 69 | # tools/sched_ext/build/bin/scx_simple |
| 70 | local=0 global=3 | 70 | local=0 global=3 |
| 71 | local=5 global=24 | 71 | local=5 global=24 |
| 72 | local=9 global=44 | 72 | local=9 global=44 |
| @@ -23,177 +23,166 @@ applications can additionally seal security critical data at runtime. · 22 unmodified lines | |||
| 23 | A similar feature already exists in the XNU kernel with the | 23 | A similar feature already exists in the XNU kernel with the |
| 24 | VM_FLAGS_PERMANENT flag [1] and on OpenBSD with the mimmutable syscall [2]. | 24 | VM_FLAGS_PERMANENT flag [1] and on OpenBSD with the mimmutable syscall [2]. |
| 25 | 25 | ||
| 26 | User API | 26 | SYSCALL |
| 27 | ======== | 27 | ======= |
| 28 | mseal() | 28 | mseal syscall signature |
| 29 | ----------- | 29 | ----------------------- |
| 30 | The mseal() syscall has the following signature: | 30 | ``int mseal(void \* addr, size_t len, unsigned long flags)`` |
| 31 | 31 | ||
| 32 | ``int mseal(void addr, size_t len, unsigned long flags)`` | 32 | **addr**/**len**: virtual memory address range. |
| 33 | 33 | The address range set by **addr**/**len** must meet: | |
| 34 | **addr/len**: virtual memory address range. | 34 | - The start address must be in an allocated VMA. |
| 35 | 35 | - The start address must be page aligned. | |
| 36 | The address range set by ``addr``/``len`` must meet: | 36 | - The end address (**addr** + **len**) must be in an allocated VMA. |
| 37 | - The start address must be in an allocated VMA. | 37 | - no gap (unallocated memory) between start and end address. |
| 38 | - The start address must be page aligned. | 38 | |
| 39 | - The end address (``addr`` + ``len``) must be in an allocated VMA. | 39 | The ``len`` will be paged aligned implicitly by the kernel. |
| 40 | - no gap (unallocated memory) between start and end address. | 40 | |
| 41 | 41 | **flags**: reserved for future use. | |
| 42 | The ``len`` will be paged aligned implicitly by the kernel. | 42 | |
| 43 | 43 | **Return values**: | |
| 44 | **flags**: reserved for future use. | 44 | - **0**: Success. |
| 45 | 45 | - **-EINVAL**: | |
| 46 | **return values**: | 46 | * Invalid input ``flags``. |
| 47 | 47 | * The start address (``addr``) is not page aligned. | |
| 48 | - ``0``: Success. | 48 | * Address range (``addr`` + ``len``) overflow. |
| 49 | 49 | - **-ENOMEM**: | |
| 50 | - ``-EINVAL``: | 50 | * The start address (``addr``) is not allocated. |
| 51 | - Invalid input ``flags``. | 51 | * The end address (``addr`` + ``len``) is not allocated. |
| 52 | - The start address (``addr``) is not page aligned. | 52 | * A gap (unallocated memory) between start and end address. |
| 53 | - Address range (``addr`` + ``len``) overflow. | 53 | - **-EPERM**: |
| 54 | 54 | * sealing is supported only on 64-bit CPUs, 32-bit is not supported. | |
| 55 | - ``-ENOMEM``: | 55 | |
| 56 | - The start address (``addr``) is not allocated. | 56 | **Note about error return**: |
| 57 | - The end address (``addr`` + ``len``) is not allocated. | 57 | - For above error cases, users can expect the given memory range is |
| 58 | - A gap (unallocated memory) between start and end address. | 58 | unmodified, i.e. no partial update. |
| 59 | 59 | - There might be other internal errors/cases not listed here, e.g. | |
| 60 | - ``-EPERM``: | 60 | error during merging/splitting VMAs, or the process reaching the maximum |
| 61 | - sealing is supported only on 64-bit CPUs, 32-bit is not supported. | 61 | number of supported VMAs. In those cases, partial updates to the given |
| 62 | 62 | memory range could happen. However, those cases should be rare. | |
| 63 | - For above error cases, users can expect the given memory range is | 63 | |
| 64 | unmodified, i.e. no partial update. | 64 | **Architecture support**: |
| 65 | 65 | mseal only works on 64-bit CPUs, not 32-bit CPUs. | |
| 66 | - There might be other internal errors/cases not listed here, e.g. | 66 | |
| 67 | error during merging/splitting VMAs, or the process reaching the max | 67 | **Idempotent**: |
| 68 | number of supported VMAs. In those cases, partial updates to the given | 68 | users can call mseal multiple times. mseal on an already sealed memory |
| 69 | memory range could happen. However, those cases should be rare. | 69 | is a no-action (not error). |
| 70 | 70 | ||
| 71 | **Blocked operations after sealing**: | 71 | **no munseal** |
| 72 | Unmapping, moving to another location, and shrinking the size, | 72 | Once mapping is sealed, it can't be unsealed. The kernel should never |
| 73 | via munmap() and mremap(), can leave an empty space, therefore | 73 | have munseal, this is consistent with other sealing feature, e.g. |
| 74 | can be replaced with a VMA with a new set of attributes. | 74 | F_SEAL_SEAL for file. |
| 75 | 75 | ||
| 76 | Moving or expanding a different VMA into the current location, | 76 | Blocked mm syscall for sealed mapping |
| 77 | via mremap(). | 77 | ------------------------------------- |
| 78 | 78 | It might be important to note: **once the mapping is sealed, it will | |
| 79 | Modifying a VMA via mmap(MAP_FIXED). | 79 | stay in the process's memory until the process terminates**. |
| 80 | 80 | ||
| 81 | Size expansion, via mremap(), does not appear to pose any | 81 | Example:: |
| 82 | specific risks to sealed VMAs. It is included anyway because | 82 | |
| 83 | the use case is unclear. In any case, users can rely on | 83 | *ptr = mmap(0, 4096, PROT_READ, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0); |
| 84 | merging to expand a sealed VMA. | 84 | rc = mseal(ptr, 4096, 0); |
| 85 | 85 | /* munmap will fail */ | |
| 86 | mprotect() and pkey_mprotect(). | 86 | rc = munmap(ptr, 4096); |
| 87 | 87 | assert(rc < 0); | |
| 88 | Some destructive madvice() behaviors (e.g. MADV_DONTNEED) | 88 | |
| 89 | for anonymous memory, when users don't have write permission to the | 89 | Blocked mm syscall: |
| 90 | memory. Those behaviors can alter region contents by discarding pages, | 90 | - munmap |
| 91 | effectively a memset(0) for anonymous memory. | 91 | - mmap |
| 92 | 92 | - mremap | |
| 93 | Kernel will return -EPERM for blocked operations. | 93 | - mprotect and pkey_mprotect |
| 94 | 94 | - some destructive madvise behaviors: MADV_DONTNEED, MADV_FREE, | |
| 95 | For blocked operations, one can expect the given address is unmodified, | 95 | MADV_DONTNEED_LOCKED, MADV_FREE, MADV_DONTFORK, MADV_WIPEONFORK |
| 96 | i.e. no partial update. Note, this is different from existing mm | 96 | |
| 97 | system call behaviors, where partial updates are made till an error is | 97 | The first set of syscalls to block is munmap, mremap, mmap. They can |
| 98 | found and returned to userspace. To give an example: | 98 | either leave an empty space in the address space, therefore allowing |
| 99 | 99 | replacement with a new mapping with new set of attributes, or can | |
| 100 | Assume following code sequence: | 100 | overwrite the existing mapping with another mapping. |
| 101 | 101 | ||
| 102 | - ptr = mmap(null, 8192, PROT_NONE); | 102 | mprotect and pkey_mprotect are blocked because they changes the |
| 103 | - munmap(ptr + 4096, 4096); | 103 | protection bits (RWX) of the mapping. |
| 104 | - ret1 = mprotect(ptr, 8192, PROT_READ); | 104 | |
| 105 | - mseal(ptr, 4096); | 105 | Certain destructive madvise behaviors, specifically MADV_DONTNEED, |
| 106 | - ret2 = mprotect(ptr, 8192, PROT_NONE); | 106 | MADV_FREE, MADV_DONTNEED_LOCKED, and MADV_WIPEONFORK, can introduce |
| 107 | 107 | risks when applied to anonymous memory by threads lacking write | |
| 108 | ret1 will be -ENOMEM, the page from ptr is updated to PROT_READ. | 108 | permissions. Consequently, these operations are prohibited under such |
| 109 | 109 | conditions. The aforementioned behaviors have the potential to modify | |
| 110 | ret2 will be -EPERM, the page remains to be PROT_READ. | 110 | region contents by discarding pages, effectively performing a memset(0) |
| 111 | 111 | operation on the anonymous memory. | |
| 112 | **Note**: | 112 | |
| 113 | 113 | Kernel will return -EPERM for blocked syscalls. | |
| 114 | - mseal() only works on 64-bit CPUs, not 32-bit CPU. | 114 | |
| 115 | 115 | When blocked syscall return -EPERM due to sealing, the memory regions may | |
| 116 | - users can call mseal() multiple times, mseal() on an already sealed memory | 116 | or may not be changed, depends on the syscall being blocked: |
| 117 | is a no-action (not error). | 117 | |
| 118 | 118 | - munmap: munmap is atomic. If one of VMAs in the given range is | |
| 119 | - munseal() is not supported. | 119 | sealed, none of VMAs are updated. |
| 120 | 120 | - mprotect, pkey_mprotect, madvise: partial update might happen, e.g. | |
| 121 | Use cases: | 121 | when mprotect over multiple VMAs, mprotect might update the beginning |
| 122 | ========== | 122 | VMAs before reaching the sealed VMA and return -EPERM. |
| 123 | - mmap and mremap: undefined behavior. | ||
| 124 | |||
| 125 | Use cases | ||
| 126 | ========= | ||
| 123 | - glibc: | 127 | - glibc: |
| 124 | The dynamic linker, during loading ELF executables, can apply sealing to | 128 | The dynamic linker, during loading ELF executables, can apply sealing to |
| 125 | non-writable memory segments. | 129 | mapping segments. |
| 126 | |||
| 127 | - Chrome browser: protect some security sensitive data-structures. | ||
| 128 | 130 | ||
| 129 | Notes on which memory to seal: | 131 | - Chrome browser: protect some security sensitive data structures. |
| 130 | ============================== | ||
| 131 | 132 | ||
| 132 | It might be important to note that sealing changes the lifetime of a mapping, | 133 | When not to use mseal |
| 133 | i.e. the sealed mapping won’t be unmapped till the process terminates or the | 134 | ===================== |
| 134 | exec system call is invoked. Applications can apply sealing to any virtual | 135 | Applications can apply sealing to any virtual memory region from userspace, |
| 135 | memory region from userspace, but it is crucial to thoroughly analyze the | 136 | but it is *crucial to thoroughly analyze the mapping's lifetime* prior to |
| 136 | mapping's lifetime prior to apply the sealing. | 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 | For example: | 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 | As Jann Horn pointed out in [3], there are still a few ways to write | 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 | 171 | to RO memory, which is, in a way, by design. And those could be blocked |
| 179 | by mseal(). If applications want to block such cases, sandbox tools (such as | 172 | by different security measures. |
| 180 | seccomp, LSM, etc) might be considered. | ||
| 181 | 173 | ||
| 182 | Those cases are: | 174 | Those cases are: |
| 183 | 175 | ||
| 184 | - Write to read-only memory through /proc/self/mem interface. | 176 | - Write to read-only memory through /proc/self/mem interface (FOLL_FORCE). |
| 185 | - Write to read-only memory through ptrace (such as PTRACE_POKETEXT). | 177 | - Write to read-only memory through ptrace (such as PTRACE_POKETEXT). |
| 186 | - userfaultfd. | 178 | - userfaultfd. |
| 187 | 179 | ||
| 188 | The idea that inspired this patch comes from Stephen Röttger’s work in V8 | 180 | The idea that inspired this patch comes from Stephen Röttger’s work in V8 |
| 189 | CFI [4]. Chrome browser in ChromeOS will be the first user of this API. | 181 | CFI [4]. Chrome browser in ChromeOS will be the first user of this API. |
| 190 | 182 | ||
| 191 | Reference: | 183 | Reference |
| 192 | ========== | 184 | ========= |
| 193 | [1] https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/osfmk/mach/vm_statistics.h#L274 | 185 | - [1] https://github.com/apple-oss-distributions/xnu/blob/1031c584a5e37aff177559b9f69dbd3c8c3fd30a/osfmk/mach/vm_statistics.h#L274 |
| 194 | 186 | - [2] https://man.openbsd.org/mimmutable.2 | |
| 195 | [2] https://man.openbsd.org/mimmutable.2 | 187 | - [3] https://lore.kernel.org/lkml/CAG48ez3ShUYey+ZAFsU2i1RpQn0a5eOs2hzQ426FkcgnfUGLvA@mail.gmail.com |
| 196 | 188 | - [4] https://docs.google.com/document/d/1O2jwK4dxI3nRcOJuPYkonhTkNQfbmwdvxQMyXgeaRHo/edit#heading=h.bvaojj9fu6hc | |
| 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 | ||
| @@ -8098,13 +8098,15 @@ KVM_X86_QUIRK_MWAIT_NEVER_UD_FAULTS By default, KVM emulates MONITOR/MWAIT (if · 8097 unmodified lines | |||
| 8098 | KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT is | 8098 | KVM_X86_QUIRK_MISC_ENABLE_NO_MWAIT is |
| 8099 | disabled. | 8099 | disabled. |
| 8100 | 8100 | ||
| 8101 | KVM_X86_QUIRK_SLOT_ZAP_ALL By default, KVM invalidates all SPTEs in | 8101 | KVM_X86_QUIRK_SLOT_ZAP_ALL By default, for KVM_X86_DEFAULT_VM VMs, KVM |
| 8102 | fast way for memslot deletion when VM type | 8102 | invalidates all SPTEs in all memslots and |
| 8103 | is KVM_X86_DEFAULT_VM. | 8103 | address spaces when a memslot is deleted or |
| 8104 | When this quirk is disabled or when VM type | 8104 | moved. When this quirk is disabled (or the |
| 8105 | is other than KVM_X86_DEFAULT_VM, KVM zaps | 8105 | VM type isn't KVM_X86_DEFAULT_VM), KVM only |
| 8106 | only leaf SPTEs that are within the range of | 8106 | ensures the backing memory of the deleted |
| 8107 | the memslot being 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 | 7.32 KVM_CAP_MAX_VCPU_ID | 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 | to gfn. For indirect sp, we disabled fast page fault for simplicity. | 136 | to gfn. For indirect sp, we disabled fast page fault for simplicity. |
| 137 | 137 | ||
| 138 | A solution for indirect sp could be to pin the gfn, for example via | 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 | - We have held the refcount of pfn; that means the pfn can not be freed and | 141 | - We have held the refcount of pfn; that means the pfn can not be freed and |
| 142 | be reused for another gfn. | 142 | be reused for another gfn. |
| @@ -258,12 +258,6 @@ L: linux-acenic@sunsite.dk · 257 unmodified lines | |||
| 258 | S: Maintained | 258 | S: Maintained |
| 259 | F: drivers/net/ethernet/alteon/acenic* | 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 | ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER | 261 | ACER ASPIRE ONE TEMPERATURE AND FAN DRIVER |
| 268 | M: Peter Kaestle <peter@piie.net> | 262 | M: Peter Kaestle <peter@piie.net> |
| 269 | L: platform-driver-x86@vger.kernel.org | 263 | L: platform-driver-x86@vger.kernel.org |
| @@ -888,7 +882,6 @@ F: drivers/staging/media/sunxi/cedrus/ · 618 unmodified lines | |||
| 888 | 882 | ||
| 889 | ALPHA PORT | 883 | ALPHA PORT |
| 890 | M: Richard Henderson <richard.henderson@linaro.org> | 884 | M: Richard Henderson <richard.henderson@linaro.org> |
| 891 | M: Ivan Kokshaysky <ink@jurassic.park.msu.ru> | ||
| 892 | M: Matt Turner <mattst88@gmail.com> | 885 | M: Matt Turner <mattst88@gmail.com> |
| 893 | L: linux-alpha@vger.kernel.org | 886 | L: linux-alpha@vger.kernel.org |
| 894 | S: Odd Fixes | 887 | S: Odd Fixes |
| @@ -1761,8 +1754,8 @@ F: include/uapi/linux/if_arcnet.h · 866 unmodified lines | |||
| 1761 | ARM AND ARM64 SoC SUB-ARCHITECTURES (COMMON PARTS) | 1754 | ARM AND ARM64 SoC SUB-ARCHITECTURES (COMMON PARTS) |
| 1762 | M: Arnd Bergmann <arnd@arndb.de> | 1755 | M: Arnd Bergmann <arnd@arndb.de> |
| 1763 | M: Olof Johansson <olof@lixom.net> | 1756 | M: Olof Johansson <olof@lixom.net> |
| 1764 | M: soc@kernel.org | ||
| 1765 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 1757 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 1758 | L: soc@lists.linux.dev | ||
| 1766 | S: Maintained | 1759 | S: Maintained |
| 1767 | P: Documentation/process/maintainer-soc.rst | 1760 | P: Documentation/process/maintainer-soc.rst |
| 1768 | C: irc://irc.libera.chat/armlinux | 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 | S: Maintained | 2256 | S: Maintained |
| 2264 | F: arch/arm/mach-ep93xx/ts72xx.c | 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 | ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE | 2259 | ARM/CIRRUS LOGIC EP93XX ARM ARCHITECTURE |
| 2273 | M: Hartley Sweeten <hsweeten@visionengravers.com> | 2260 | M: Hartley Sweeten <hsweeten@visionengravers.com> |
| 2274 | M: Alexander Sverdlin <alexander.sverdlin@gmail.com> | 2261 | M: Alexander Sverdlin <alexander.sverdlin@gmail.com> |
| @@ -3815,14 +3802,6 @@ F: drivers/video/backlight/ · 1540 unmodified lines | |||
| 3815 | F: include/linux/backlight.h | 3802 | F: include/linux/backlight.h |
| 3816 | F: include/linux/pwm_backlight.h | 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 | BARCO P50 GPIO DRIVER | 3805 | BARCO P50 GPIO DRIVER |
| 3827 | M: Santosh Kumar Yadav <santoshkumar.yadav@barco.com> | 3806 | M: Santosh Kumar Yadav <santoshkumar.yadav@barco.com> |
| 3828 | M: Peter Korsgaard <peter.korsgaard@barco.com> | 3807 | M: Peter Korsgaard <peter.korsgaard@barco.com> |
| @@ -6476,7 +6455,6 @@ F: drivers/mtd/nand/raw/denali* · 2647 unmodified lines | |||
| 6476 | 6455 | ||
| 6477 | DESIGNWARE EDMA CORE IP DRIVER | 6456 | DESIGNWARE EDMA CORE IP DRIVER |
| 6478 | M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> | 6457 | M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org> |
| 6479 | R: Serge Semin <fancer.lancer@gmail.com> | ||
| 6480 | L: dmaengine@vger.kernel.org | 6458 | L: dmaengine@vger.kernel.org |
| 6481 | S: Maintained | 6459 | S: Maintained |
| 6482 | F: drivers/dma/dw-edma/ | 6460 | F: drivers/dma/dw-edma/ |
| @@ -9757,6 +9735,7 @@ F: include/dt-bindings/gpio/ · 3274 unmodified lines | |||
| 9757 | F: include/linux/gpio.h | 9735 | F: include/linux/gpio.h |
| 9758 | F: include/linux/gpio/ | 9736 | F: include/linux/gpio/ |
| 9759 | F: include/linux/of_gpio.h | 9737 | F: include/linux/of_gpio.h |
| 9738 | K: (devm_)?gpio_(request|free|direction|get|set) | ||
| 9760 | 9739 | ||
| 9761 | GPIO UAPI | 9740 | GPIO UAPI |
| 9762 | M: Bartosz Golaszewski <brgl@bgdev.pl> | 9741 | M: Bartosz Golaszewski <brgl@bgdev.pl> |
| @@ -9771,14 +9750,6 @@ F: drivers/gpio/gpiolib-cdev.c · 8 unmodified lines | |||
| 9771 | F: include/uapi/linux/gpio.h | 9750 | F: include/uapi/linux/gpio.h |
| 9772 | F: tools/gpio/ | 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 | GRETH 10/100/1G Ethernet MAC device driver | 9753 | GRETH 10/100/1G Ethernet MAC device driver |
| 9783 | M: Andreas Larsson <andreas@gaisler.com> | 9754 | M: Andreas Larsson <andreas@gaisler.com> |
| 9784 | L: netdev@vger.kernel.org | 9755 | L: netdev@vger.kernel.org |
| @@ -10282,7 +10253,7 @@ F: Documentation/devicetree/bindings/arm/hisilicon/low-pin-count.yaml · 497 unmodified lines | |||
| 10282 | F: drivers/bus/hisi_lpc.c | 10253 | F: drivers/bus/hisi_lpc.c |
| 10283 | 10254 | ||
| 10284 | HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3) | 10255 | HISILICON NETWORK SUBSYSTEM 3 DRIVER (HNS3) |
| 10285 | M: Yisen Zhuang <yisen.zhuang@huawei.com> | 10256 | M: Jian Shen <shenjian15@huawei.com> |
| 10286 | M: Salil Mehta <salil.mehta@huawei.com> | 10257 | M: Salil Mehta <salil.mehta@huawei.com> |
| 10287 | M: Jijie Shao <shaojijie@huawei.com> | 10258 | M: Jijie Shao <shaojijie@huawei.com> |
| 10288 | L: netdev@vger.kernel.org | 10259 | L: netdev@vger.kernel.org |
| @@ -10291,7 +10262,7 @@ W: http://www.hisilicon.com · 2 unmodified lines | |||
| 10291 | F: drivers/net/ethernet/hisilicon/hns3/ | 10262 | F: drivers/net/ethernet/hisilicon/hns3/ |
| 10292 | 10263 | ||
| 10293 | HISILICON NETWORK SUBSYSTEM DRIVER | 10264 | HISILICON NETWORK SUBSYSTEM DRIVER |
| 10294 | M: Yisen Zhuang <yisen.zhuang@huawei.com> | 10265 | M: Jian Shen <shenjian15@huawei.com> |
| 10295 | M: Salil Mehta <salil.mehta@huawei.com> | 10266 | M: Salil Mehta <salil.mehta@huawei.com> |
| 10296 | L: netdev@vger.kernel.org | 10267 | L: netdev@vger.kernel.org |
| 10297 | S: Maintained | 10268 | S: Maintained |
| @@ -11295,10 +11266,10 @@ F: security/integrity/ · 997 unmodified lines | |||
| 11295 | F: security/integrity/ima/ | 11266 | F: security/integrity/ima/ |
| 11296 | 11267 | ||
| 11297 | INTEGRITY POLICY ENFORCEMENT (IPE) | 11268 | INTEGRITY POLICY ENFORCEMENT (IPE) |
| 11298 | M: Fan Wu <wufan@linux.microsoft.com> | 11269 | M: Fan Wu <wufan@kernel.org> |
| 11299 | L: linux-security-module@vger.kernel.org | 11270 | L: linux-security-module@vger.kernel.org |
| 11300 | S: Supported | 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 | F: Documentation/admin-guide/LSM/ipe.rst | 11273 | F: Documentation/admin-guide/LSM/ipe.rst |
| 11303 | F: Documentation/security/ipe.rst | 11274 | F: Documentation/security/ipe.rst |
| 11304 | F: scripts/ipe/ | 11275 | F: scripts/ipe/ |
| @@ -11616,6 +11587,16 @@ F: drivers/crypto/intel/keembay/keembay-ocs-hcu-core.c · 311 unmodified lines | |||
| 11616 | F: drivers/crypto/intel/keembay/ocs-hcu.c | 11587 | F: drivers/crypto/intel/keembay/ocs-hcu.c |
| 11617 | F: drivers/crypto/intel/keembay/ocs-hcu.h | 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 | INTEL MANAGEMENT ENGINE (mei) | 11600 | INTEL MANAGEMENT ENGINE (mei) |
| 11620 | M: Tomas Winkler <tomas.winkler@intel.com> | 11601 | M: Tomas Winkler <tomas.winkler@intel.com> |
| 11621 | L: linux-kernel@vger.kernel.org | 11602 | L: linux-kernel@vger.kernel.org |
| @@ -12254,6 +12235,7 @@ R: Dmitry Vyukov <dvyukov@google.com> · 632 unmodified lines | |||
| 12254 | R: Vincenzo Frascino <vincenzo.frascino@arm.com> | 12235 | R: Vincenzo Frascino <vincenzo.frascino@arm.com> |
| 12255 | L: kasan-dev@googlegroups.com | 12236 | L: kasan-dev@googlegroups.com |
| 12256 | S: Maintained | 12237 | S: Maintained |
| 12238 | B: https://bugzilla.kernel.org/buglist.cgi?component=Sanitizers&product=Memory%20Management | ||
| 12257 | F: Documentation/dev-tools/kasan.rst | 12239 | F: Documentation/dev-tools/kasan.rst |
| 12258 | F: arch/*/include/asm/*kasan.h | 12240 | F: arch/*/include/asm/*kasan.h |
| 12259 | F: arch/*/mm/kasan_init* | 12241 | F: arch/*/mm/kasan_init* |
| @@ -12277,6 +12259,7 @@ R: Dmitry Vyukov <dvyukov@google.com> · 17 unmodified lines | |||
| 12277 | R: Andrey Konovalov <andreyknvl@gmail.com> | 12259 | R: Andrey Konovalov <andreyknvl@gmail.com> |
| 12278 | L: kasan-dev@googlegroups.com | 12260 | L: kasan-dev@googlegroups.com |
| 12279 | S: Maintained | 12261 | S: Maintained |
| 12262 | B: https://bugzilla.kernel.org/buglist.cgi?component=Sanitizers&product=Memory%20Management | ||
| 12280 | F: Documentation/dev-tools/kcov.rst | 12263 | F: Documentation/dev-tools/kcov.rst |
| 12281 | F: include/linux/kcov.h | 12264 | F: include/linux/kcov.h |
| 12282 | F: include/uapi/linux/kcov.h | 12265 | F: include/uapi/linux/kcov.h |
| @@ -12956,49 +12939,29 @@ LIBATA PATA ARASAN COMPACT FLASH CONTROLLER · 673 unmodified lines | |||
| 12956 | M: Viresh Kumar <vireshk@kernel.org> | 12939 | M: Viresh Kumar <vireshk@kernel.org> |
| 12957 | L: linux-ide@vger.kernel.org | 12940 | L: linux-ide@vger.kernel.org |
| 12958 | S: Maintained | 12941 | S: Maintained |
| 12959 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | ||
| 12960 | F: drivers/ata/pata_arasan_cf.c | 12942 | F: drivers/ata/pata_arasan_cf.c |
| 12961 | F: include/linux/pata_arasan_cf_data.h | 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 | LIBATA PATA FARADAY FTIDE010 AND GEMINI SATA BRIDGE DRIVERS | 12945 | LIBATA PATA FARADAY FTIDE010 AND GEMINI SATA BRIDGE DRIVERS |
| 12970 | M: Linus Walleij <linus.walleij@linaro.org> | 12946 | M: Linus Walleij <linus.walleij@linaro.org> |
| 12971 | L: linux-ide@vger.kernel.org | 12947 | L: linux-ide@vger.kernel.org |
| 12972 | S: Maintained | 12948 | S: Maintained |
| 12973 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | ||
| 12974 | F: drivers/ata/pata_ftide010.c | 12949 | F: drivers/ata/pata_ftide010.c |
| 12975 | F: drivers/ata/sata_gemini.c | 12950 | F: drivers/ata/sata_gemini.c |
| 12976 | F: drivers/ata/sata_gemini.h | 12951 | F: drivers/ata/sata_gemini.h |
| 12977 | 12952 | ||
| 12978 | LIBATA SATA AHCI PLATFORM devices support | 12953 | LIBATA SATA AHCI PLATFORM devices support |
| 12979 | M: Hans de Goede <hdegoede@redhat.com> | 12954 | M: Hans de Goede <hdegoede@redhat.com> |
| 12980 | M: Jens Axboe <axboe@kernel.dk> | ||
| 12981 | L: linux-ide@vger.kernel.org | 12955 | L: linux-ide@vger.kernel.org |
| 12982 | S: Maintained | 12956 | S: Maintained |
| 12983 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | ||
| 12984 | F: drivers/ata/ahci_platform.c | 12957 | F: drivers/ata/ahci_platform.c |
| 12985 | F: drivers/ata/libahci_platform.c | 12958 | F: drivers/ata/libahci_platform.c |
| 12986 | F: include/linux/ahci_platform.h | 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 | LIBATA SATA PROMISE TX2/TX4 CONTROLLER DRIVER | 12961 | LIBATA SATA PROMISE TX2/TX4 CONTROLLER DRIVER |
| 12998 | M: Mikael Pettersson <mikpelinux@gmail.com> | 12962 | M: Mikael Pettersson <mikpelinux@gmail.com> |
| 12999 | L: linux-ide@vger.kernel.org | 12963 | L: linux-ide@vger.kernel.org |
| 13000 | S: Maintained | 12964 | S: Maintained |
| 13001 | T: git git://git.kernel.org/pub/scm/linux/kernel/git/axboe/linux-block.git | ||
| 13002 | F: drivers/ata/sata_promise.* | 12965 | F: drivers/ata/sata_promise.* |
| 13003 | 12966 | ||
| 13004 | LIBATA SUBSYSTEM (Serial and Parallel ATA drivers) | 12967 | LIBATA SUBSYSTEM (Serial and Parallel ATA drivers) |
| @@ -14191,8 +14154,7 @@ T: git git://linuxtv.org/media_tree.git · 1186 unmodified lines | |||
| 14191 | F: drivers/media/platform/nxp/imx-pxp.[ch] | 14154 | F: drivers/media/platform/nxp/imx-pxp.[ch] |
| 14192 | 14155 | ||
| 14193 | MEDIA DRIVERS FOR ASCOT2E | 14156 | MEDIA DRIVERS FOR ASCOT2E |
| 14194 | M: Sergey Kozlov <serjk@netup.ru> | 14157 | M: Abylay Ospan <aospan@amazon.com> |
| 14195 | M: Abylay Ospan <aospan@netup.ru> | ||
| 14196 | L: linux-media@vger.kernel.org | 14158 | L: linux-media@vger.kernel.org |
| 14197 | S: Supported | 14159 | S: Supported |
| 14198 | W: https://linuxtv.org | 14160 | W: https://linuxtv.org |
| @@ -14209,8 +14171,7 @@ T: git git://linuxtv.org/media_tree.git · 10 unmodified lines | |||
| 14209 | F: drivers/media/dvb-frontends/cxd2099* | 14171 | F: drivers/media/dvb-frontends/cxd2099* |
| 14210 | 14172 | ||
| 14211 | MEDIA DRIVERS FOR CXD2841ER | 14173 | MEDIA DRIVERS FOR CXD2841ER |
| 14212 | M: Sergey Kozlov <serjk@netup.ru> | 14174 | M: Abylay Ospan <aospan@amazon.com> |
| 14213 | M: Abylay Ospan <aospan@netup.ru> | ||
| 14214 | L: linux-media@vger.kernel.org | 14175 | L: linux-media@vger.kernel.org |
| 14215 | S: Supported | 14176 | S: Supported |
| 14216 | W: https://linuxtv.org | 14177 | W: https://linuxtv.org |
| @@ -14263,7 +14224,7 @@ F: drivers/media/platform/nxp/imx7-media-csi.c · 46 unmodified lines | |||
| 14263 | F: drivers/media/platform/nxp/imx8mq-mipi-csi2.c | 14224 | F: drivers/media/platform/nxp/imx8mq-mipi-csi2.c |
| 14264 | 14225 | ||
| 14265 | MEDIA DRIVERS FOR HELENE | 14226 | MEDIA DRIVERS FOR HELENE |
| 14266 | M: Abylay Ospan <aospan@netup.ru> | 14227 | M: Abylay Ospan <aospan@amazon.com> |
| 14267 | L: linux-media@vger.kernel.org | 14228 | L: linux-media@vger.kernel.org |
| 14268 | S: Supported | 14229 | S: Supported |
| 14269 | W: https://linuxtv.org | 14230 | W: https://linuxtv.org |
| @@ -14272,8 +14233,7 @@ T: git git://linuxtv.org/media_tree.git · 2 unmodified lines | |||
| 14272 | F: drivers/media/dvb-frontends/helene* | 14233 | F: drivers/media/dvb-frontends/helene* |
| 14273 | 14234 | ||
| 14274 | MEDIA DRIVERS FOR HORUS3A | 14235 | MEDIA DRIVERS FOR HORUS3A |
| 14275 | M: Sergey Kozlov <serjk@netup.ru> | 14236 | M: Abylay Ospan <aospan@amazon.com> |
| 14276 | M: Abylay Ospan <aospan@netup.ru> | ||
| 14277 | L: linux-media@vger.kernel.org | 14237 | L: linux-media@vger.kernel.org |
| 14278 | S: Supported | 14238 | S: Supported |
| 14279 | W: https://linuxtv.org | 14239 | W: https://linuxtv.org |
| @@ -14282,8 +14242,7 @@ T: git git://linuxtv.org/media_tree.git · 2 unmodified lines | |||
| 14282 | F: drivers/media/dvb-frontends/horus3a* | 14242 | F: drivers/media/dvb-frontends/horus3a* |
| 14283 | 14243 | ||
| 14284 | MEDIA DRIVERS FOR LNBH25 | 14244 | MEDIA DRIVERS FOR LNBH25 |
| 14285 | M: Sergey Kozlov <serjk@netup.ru> | 14245 | M: Abylay Ospan <aospan@amazon.com> |
| 14286 | M: Abylay Ospan <aospan@netup.ru> | ||
| 14287 | L: linux-media@vger.kernel.org | 14246 | L: linux-media@vger.kernel.org |
| 14288 | S: Supported | 14247 | S: Supported |
| 14289 | W: https://linuxtv.org | 14248 | W: https://linuxtv.org |
| @@ -14299,8 +14258,7 @@ T: git git://linuxtv.org/media_tree.git · 9 unmodified lines | |||
| 14299 | F: drivers/media/dvb-frontends/mxl5xx* | 14258 | F: drivers/media/dvb-frontends/mxl5xx* |
| 14300 | 14259 | ||
| 14301 | MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices | 14260 | MEDIA DRIVERS FOR NETUP PCI UNIVERSAL DVB devices |
| 14302 | M: Sergey Kozlov <serjk@netup.ru> | 14261 | M: Abylay Ospan <aospan@amazon.com> |
| 14303 | M: Abylay Ospan <aospan@netup.ru> | ||
| 14304 | L: linux-media@vger.kernel.org | 14262 | L: linux-media@vger.kernel.org |
| 14305 | S: Supported | 14263 | S: Supported |
| 14306 | W: https://linuxtv.org | 14264 | W: https://linuxtv.org |
| @@ -14925,9 +14883,10 @@ N: include/linux/page[-_]* · 618 unmodified lines | |||
| 14925 | 14883 | ||
| 14926 | MEMORY MAPPING | 14884 | MEMORY MAPPING |
| 14927 | M: Andrew Morton <akpm@linux-foundation.org> | 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 | R: Vlastimil Babka <vbabka@suse.cz> | 14888 | R: Vlastimil Babka <vbabka@suse.cz> |
| 14930 | R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | 14889 | R: Jann Horn <jannh@google.com> |
| 14931 | L: linux-mm@kvack.org | 14890 | L: linux-mm@kvack.org |
| 14932 | S: Maintained | 14891 | S: Maintained |
| 14933 | W: http://www.linux-mm.org | 14892 | W: http://www.linux-mm.org |
| @@ -14950,13 +14909,6 @@ F: drivers/mtd/ · 16 unmodified lines | |||
| 14950 | F: include/linux/mtd/ | 14909 | F: include/linux/mtd/ |
| 14951 | F: include/uapi/mtd/ | 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 | MEN A21 WATCHDOG DRIVER | 14912 | MEN A21 WATCHDOG DRIVER |
| 14961 | M: Johannes Thumshirn <morbidrsa@gmail.com> | 14913 | M: Johannes Thumshirn <morbidrsa@gmail.com> |
| 14962 | L: linux-watchdog@vger.kernel.org | 14914 | L: linux-watchdog@vger.kernel.org |
| @@ -15101,6 +15053,7 @@ F: drivers/spi/spi-at91-usart.c · 138 unmodified lines | |||
| 15101 | 15053 | ||
| 15102 | MICROCHIP AUDIO ASOC DRIVERS | 15054 | MICROCHIP AUDIO ASOC DRIVERS |
| 15103 | M: Claudiu Beznea <claudiu.beznea@tuxon.dev> | 15055 | M: Claudiu Beznea <claudiu.beznea@tuxon.dev> |
| 15056 | M: Andrei Simion <andrei.simion@microchip.com> | ||
| 15104 | L: linux-sound@vger.kernel.org | 15057 | L: linux-sound@vger.kernel.org |
| 15105 | S: Supported | 15058 | S: Supported |
| 15106 | F: Documentation/devicetree/bindings/sound/atmel* | 15059 | F: Documentation/devicetree/bindings/sound/atmel* |
| @@ -15209,6 +15162,7 @@ F: include/video/atmel_lcdc.h · 102 unmodified lines | |||
| 15209 | 15162 | ||
| 15210 | MICROCHIP MCP16502 PMIC DRIVER | 15163 | MICROCHIP MCP16502 PMIC DRIVER |
| 15211 | M: Claudiu Beznea <claudiu.beznea@tuxon.dev> | 15164 | M: Claudiu Beznea <claudiu.beznea@tuxon.dev> |
| 15165 | M: Andrei Simion <andrei.simion@microchip.com> | ||
| 15212 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 15166 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 15213 | S: Supported | 15167 | S: Supported |
| 15214 | F: Documentation/devicetree/bindings/regulator/microchip,mcp16502.yaml | 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 | MICROCHIP POLARFIRE FPGA DRIVERS | 15245 | MICROCHIP POLARFIRE FPGA DRIVERS |
| 15292 | M: Conor Dooley <conor.dooley@microchip.com> | 15246 | M: Conor Dooley <conor.dooley@microchip.com> |
| 15293 | R: Vladimir Georgiev <v.georgiev@metrotek.ru> | ||
| 15294 | L: linux-fpga@vger.kernel.org | 15247 | L: linux-fpga@vger.kernel.org |
| 15295 | S: Supported | 15248 | S: Supported |
| 15296 | F: Documentation/devicetree/bindings/fpga/microchip,mpf-spi-fpga-mgr.yaml | 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 | MICROCHIP SSC DRIVER | 15294 | MICROCHIP SSC DRIVER |
| 15342 | M: Claudiu Beznea <claudiu.beznea@tuxon.dev> | 15295 | M: Claudiu Beznea <claudiu.beznea@tuxon.dev> |
| 15296 | M: Andrei Simion <andrei.simion@microchip.com> | ||
| 15343 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 15297 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 15344 | S: Supported | 15298 | S: Supported |
| 15345 | F: Documentation/devicetree/bindings/misc/atmel-ssc.txt | 15299 | F: Documentation/devicetree/bindings/misc/atmel-ssc.txt |
| @@ -15545,17 +15499,6 @@ F: arch/mips/ · 199 unmodified lines | |||
| 15545 | F: drivers/platform/mips/ | 15499 | F: drivers/platform/mips/ |
| 15546 | F: include/dt-bindings/mips/ | 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 | MIPS BOSTON DEVELOPMENT BOARD | 15502 | MIPS BOSTON DEVELOPMENT BOARD |
| 15560 | M: Paul Burton <paulburton@kernel.org> | 15503 | M: Paul Burton <paulburton@kernel.org> |
| 15561 | L: linux-mips@vger.kernel.org | 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 | MIPS CORE DRIVERS | 15512 | MIPS CORE DRIVERS |
| 15570 | M: Thomas Bogendoerfer <tsbogend@alpha.franken.de> | 15513 | M: Thomas Bogendoerfer <tsbogend@alpha.franken.de> |
| 15571 | M: Serge Semin <fancer.lancer@gmail.com> | ||
| 15572 | L: linux-mips@vger.kernel.org | 15514 | L: linux-mips@vger.kernel.org |
| 15573 | S: Supported | 15515 | S: Supported |
| 15574 | F: drivers/bus/mips_cdmm.c | 15516 | F: drivers/bus/mips_cdmm.c |
| @@ -16104,6 +16046,7 @@ F: include/uapi/linux/net_dropmon.h · 529 unmodified lines | |||
| 16104 | F: net/core/drop_monitor.c | 16046 | F: net/core/drop_monitor.c |
| 16105 | 16047 | ||
| 16106 | NETWORKING DRIVERS | 16048 | NETWORKING DRIVERS |
| 16049 | M: Andrew Lunn <andrew+netdev@lunn.ch> | ||
| 16107 | M: "David S. Miller" <davem@davemloft.net> | 16050 | M: "David S. Miller" <davem@davemloft.net> |
| 16108 | M: Eric Dumazet <edumazet@google.com> | 16051 | M: Eric Dumazet <edumazet@google.com> |
| 16109 | M: Jakub Kicinski <kuba@kernel.org> | 16052 | M: Jakub Kicinski <kuba@kernel.org> |
| @@ -16169,6 +16112,7 @@ M: "David S. Miller" <davem@davemloft.net> · 59 unmodified lines | |||
| 16169 | M: Eric Dumazet <edumazet@google.com> | 16112 | M: Eric Dumazet <edumazet@google.com> |
| 16170 | M: Jakub Kicinski <kuba@kernel.org> | 16113 | M: Jakub Kicinski <kuba@kernel.org> |
| 16171 | M: Paolo Abeni <pabeni@redhat.com> | 16114 | M: Paolo Abeni <pabeni@redhat.com> |
| 16115 | R: Simon Horman <horms@kernel.org> | ||
| 16172 | L: netdev@vger.kernel.org | 16116 | L: netdev@vger.kernel.org |
| 16173 | S: Maintained | 16117 | S: Maintained |
| 16174 | P: Documentation/process/maintainer-netdev.rst | 16118 | P: Documentation/process/maintainer-netdev.rst |
| @@ -16211,10 +16155,22 @@ F: include/uapi/linux/rtnetlink.h · 36 unmodified lines | |||
| 16211 | F: lib/net_utils.c | 16155 | F: lib/net_utils.c |
| 16212 | F: lib/random32.c | 16156 | F: lib/random32.c |
| 16213 | F: net/ | 16157 | F: net/ |
| 16158 | F: samples/pktgen/ | ||
| 16214 | F: tools/net/ | 16159 | F: tools/net/ |
| 16215 | F: tools/testing/selftests/net/ | 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 | X: net/9p/ | 16169 | X: net/9p/ |
| 16217 | X: net/bluetooth/ | 16170 | X: net/bluetooth/ |
| 16171 | X: net/mac80211/ | ||
| 16172 | X: net/rfkill/ | ||
| 16173 | X: net/wireless/ | ||
| 16218 | 16174 | ||
| 16219 | NETWORKING [IPSEC] | 16175 | NETWORKING [IPSEC] |
| 16220 | M: Steffen Klassert <steffen.klassert@secunet.com> | 16176 | M: Steffen Klassert <steffen.klassert@secunet.com> |
| @@ -16524,12 +16480,6 @@ F: include/linux/ntb.h · 303 unmodified lines | |||
| 16524 | F: include/linux/ntb_transport.h | 16480 | F: include/linux/ntb_transport.h |
| 16525 | F: tools/testing/selftests/ntb/ | 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 | NTB INTEL DRIVER | 16483 | NTB INTEL DRIVER |
| 16534 | M: Dave Jiang <dave.jiang@intel.com> | 16484 | M: Dave Jiang <dave.jiang@intel.com> |
| 16535 | L: ntb@lists.linux.dev | 16485 | L: ntb@lists.linux.dev |
| @@ -18550,13 +18500,6 @@ F: drivers/pps/ · 2014 unmodified lines | |||
| 18550 | F: include/linux/pps*.h | 18500 | F: include/linux/pps*.h |
| 18551 | F: include/uapi/linux/pps.h | 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 | PRESSURE STALL INFORMATION (PSI) | 18503 | PRESSURE STALL INFORMATION (PSI) |
| 18561 | M: Johannes Weiner <hannes@cmpxchg.org> | 18504 | M: Johannes Weiner <hannes@cmpxchg.org> |
| 18562 | M: Suren Baghdasaryan <surenb@google.com> | 18505 | M: Suren Baghdasaryan <surenb@google.com> |
| @@ -19530,6 +19473,14 @@ S: Maintained · 967 unmodified lines | |||
| 19530 | F: Documentation/tools/rtla/ | 19473 | F: Documentation/tools/rtla/ |
| 19531 | F: tools/tracing/rtla/ | 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 | REALTEK AUDIO CODECS | 19484 | REALTEK AUDIO CODECS |
| 19534 | M: Oder Chiou <oder_chiou@realtek.com> | 19485 | M: Oder Chiou <oder_chiou@realtek.com> |
| 19535 | S: Maintained | 19486 | S: Maintained |
| @@ -19639,15 +19590,6 @@ S: Supported · 103 unmodified lines | |||
| 19639 | F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml | 19590 | F: Documentation/devicetree/bindings/i2c/renesas,iic-emev2.yaml |
| 19640 | F: drivers/i2c/busses/i2c-emev2.c | 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 | RENESAS ETHERNET SWITCH DRIVER | 19593 | RENESAS ETHERNET SWITCH DRIVER |
| 19652 | R: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> | 19594 | R: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
| 19653 | L: netdev@vger.kernel.org | 19595 | L: netdev@vger.kernel.org |
| @@ -19697,14 +19639,6 @@ F: Documentation/devicetree/bindings/i2c/renesas,rmobile-iic.yaml · 43 unmodified lines | |||
| 19697 | F: drivers/i2c/busses/i2c-rcar.c | 19639 | F: drivers/i2c/busses/i2c-rcar.c |
| 19698 | F: drivers/i2c/busses/i2c-sh_mobile.c | 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 | RENESAS R-CAR THERMAL DRIVERS | 19642 | RENESAS R-CAR THERMAL DRIVERS |
| 19709 | M: Niklas Söderlund <niklas.soderlund@ragnatech.se> | 19643 | M: Niklas Söderlund <niklas.soderlund@ragnatech.se> |
| 19710 | L: linux-renesas-soc@vger.kernel.org | 19644 | L: linux-renesas-soc@vger.kernel.org |
| @@ -19780,16 +19714,6 @@ S: Supported · 69 unmodified lines | |||
| 19780 | F: Documentation/devicetree/bindings/i2c/renesas,rzv2m.yaml | 19714 | F: Documentation/devicetree/bindings/i2c/renesas,rzv2m.yaml |
| 19781 | F: drivers/i2c/busses/i2c-rzv2m.c | 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 | RENESAS USB PHY DRIVER | 19717 | RENESAS USB PHY DRIVER |
| 19794 | M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> | 19718 | M: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> |
| 19795 | L: linux-renesas-soc@vger.kernel.org | 19719 | L: linux-renesas-soc@vger.kernel.org |
| @@ -21784,8 +21708,8 @@ F: drivers/accessibility/speakup/ · 1988 unmodified lines | |||
| 21784 | SPEAR PLATFORM/CLOCK/PINCTRL SUPPORT | 21708 | SPEAR PLATFORM/CLOCK/PINCTRL SUPPORT |
| 21785 | M: Viresh Kumar <vireshk@kernel.org> | 21709 | M: Viresh Kumar <vireshk@kernel.org> |
| 21786 | M: Shiraz Hashim <shiraz.linux.kernel@gmail.com> | 21710 | M: Shiraz Hashim <shiraz.linux.kernel@gmail.com> |
| 21787 | M: soc@kernel.org | ||
| 21788 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) | 21711 | L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) |
| 21712 | L: soc@lists.linux.dev | ||
| 21789 | S: Maintained | 21713 | S: Maintained |
| 21790 | W: http://www.st.com/spear | 21714 | W: http://www.st.com/spear |
| 21791 | F: arch/arm/boot/dts/st/spear* | 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 | SYNOPSYS DESIGNWARE APB GPIO DRIVER | 22368 | SYNOPSYS DESIGNWARE APB GPIO DRIVER |
| 22445 | M: Hoan Tran <hoan@os.amperecomputing.com> | 22369 | M: Hoan Tran <hoan@os.amperecomputing.com> |
| 22446 | M: Serge Semin <fancer.lancer@gmail.com> | ||
| 22447 | L: linux-gpio@vger.kernel.org | 22370 | L: linux-gpio@vger.kernel.org |
| 22448 | S: Maintained | 22371 | S: Maintained |
| 22449 | F: Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml | 22372 | F: Documentation/devicetree/bindings/gpio/snps,dw-apb-gpio.yaml |
| 22450 | F: drivers/gpio/gpio-dwapb.c | 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 | SYNOPSYS DESIGNWARE AXI DMAC DRIVER | 22375 | SYNOPSYS DESIGNWARE AXI DMAC DRIVER |
| 22460 | M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> | 22376 | M: Eugeniy Paltsev <Eugeniy.Paltsev@synopsys.com> |
| 22461 | S: Maintained | 22377 | S: Maintained |
| @@ -23299,7 +23215,7 @@ F: Documentation/devicetree/bindings/iio/adc/ti,lmp92064.yaml · 837 unmodified lines | |||
| 23299 | F: drivers/iio/adc/ti-lmp92064.c | 23215 | F: drivers/iio/adc/ti-lmp92064.c |
| 23300 | 23216 | ||
| 23301 | TI PCM3060 ASoC CODEC DRIVER | 23217 | TI PCM3060 ASoC CODEC DRIVER |
| 23302 | M: Kirill Marinushkin <kmarinushkin@birdec.com> | 23218 | M: Kirill Marinushkin <k.marinushkin@gmail.com> |
| 23303 | L: linux-sound@vger.kernel.org | 23219 | L: linux-sound@vger.kernel.org |
| 23304 | S: Maintained | 23220 | S: Maintained |
| 23305 | F: Documentation/devicetree/bindings/sound/pcm3060.txt | 23221 | F: Documentation/devicetree/bindings/sound/pcm3060.txt |
| @@ -23765,12 +23681,6 @@ L: linux-input@vger.kernel.org · 459 unmodified lines | |||
| 23765 | S: Maintained | 23681 | S: Maintained |
| 23766 | F: drivers/hid/hid-udraw-ps3.c | 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 | UHID USERSPACE HID IO DRIVER | 23684 | UHID USERSPACE HID IO DRIVER |
| 23775 | M: David Rheinsberg <david@readahead.eu> | 23685 | M: David Rheinsberg <david@readahead.eu> |
| 23776 | L: linux-input@vger.kernel.org | 23686 | L: linux-input@vger.kernel.org |
| @@ -24073,6 +23983,7 @@ USB RAW GADGET DRIVER · 296 unmodified lines | |||
| 24073 | R: Andrey Konovalov <andreyknvl@gmail.com> | 23983 | R: Andrey Konovalov <andreyknvl@gmail.com> |
| 24074 | L: linux-usb@vger.kernel.org | 23984 | L: linux-usb@vger.kernel.org |
| 24075 | S: Maintained | 23985 | S: Maintained |
| 23986 | B: https://github.com/xairy/raw-gadget/issues | ||
| 24076 | F: Documentation/usb/raw-gadget.rst | 23987 | F: Documentation/usb/raw-gadget.rst |
| 24077 | F: drivers/usb/gadget/legacy/raw_gadget.c | 23988 | F: drivers/usb/gadget/legacy/raw_gadget.c |
| 24078 | F: include/uapi/linux/usb/raw_gadget.h | 23989 | F: include/uapi/linux/usb/raw_gadget.h |
| @@ -24189,8 +24100,12 @@ F: drivers/usb/host/xhci* · 110 unmodified lines | |||
| 24189 | 24100 | ||
| 24190 | USER DATAGRAM PROTOCOL (UDP) | 24101 | USER DATAGRAM PROTOCOL (UDP) |
| 24191 | M: Willem de Bruijn <willemdebruijn.kernel@gmail.com> | 24102 | M: Willem de Bruijn <willemdebruijn.kernel@gmail.com> |
| 24103 | L: netdev@vger.kernel.org | ||
| 24192 | S: Maintained | 24104 | S: Maintained |
| 24193 | F: include/linux/udp.h | 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 | F: net/ipv4/udp.c | 24109 | F: net/ipv4/udp.c |
| 24195 | F: net/ipv6/udp.c | 24110 | F: net/ipv6/udp.c |
| 24196 | 24111 | ||
| @@ -24741,9 +24656,10 @@ F: tools/testing/vsock/ · 544 unmodified lines | |||
| 24741 | 24656 | ||
| 24742 | VMA | 24657 | VMA |
| 24743 | M: Andrew Morton <akpm@linux-foundation.org> | 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 | R: Vlastimil Babka <vbabka@suse.cz> | 24661 | R: Vlastimil Babka <vbabka@suse.cz> |
| 24746 | R: Lorenzo Stoakes <lorenzo.stoakes@oracle.com> | 24662 | R: Jann Horn <jannh@google.com> |
| 24747 | L: linux-mm@kvack.org | 24663 | L: linux-mm@kvack.org |
| 24748 | S: Maintained | 24664 | S: Maintained |
| 24749 | W: https://www.linux-mm.org | 24665 | W: https://www.linux-mm.org |
| @@ -25417,7 +25333,7 @@ F: include/xen/arm/swiotlb-xen.h · 667 unmodified lines | |||
| 25417 | F: include/xen/swiotlb-xen.h | 25333 | F: include/xen/swiotlb-xen.h |
| 25418 | 25334 | ||
| 25419 | XFS FILESYSTEM | 25335 | XFS FILESYSTEM |
| 25420 | M: Chandan Babu R <chandan.babu@oracle.com> | 25336 | M: Carlos Maiolino <cem@kernel.org> |
| 25421 | R: Darrick J. Wong <djwong@kernel.org> | 25337 | R: Darrick J. Wong <djwong@kernel.org> |
| 25422 | L: linux-xfs@vger.kernel.org | 25338 | L: linux-xfs@vger.kernel.org |
| 25423 | S: Supported | 25339 | S: Supported |
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | VERSION = 6 | 2 | VERSION = 6 |
| 3 | PATCHLEVEL = 12 | 3 | PATCHLEVEL = 12 |
| 4 | SUBLEVEL = 0 | 4 | SUBLEVEL = 0 |
| 5 | EXTRAVERSION = -rc2 | 5 | EXTRAVERSION = -rc6 |
| 6 | NAME = Baby Opossum Posse | 6 | NAME = Baby Opossum Posse |
| 7 | 7 | ||
| 8 | # *DOCUMENTATION* | 8 | # *DOCUMENTATION* |
| @@ -838,7 +838,7 @@ config CFI_CLANG · 837 unmodified lines | |||
| 838 | config CFI_ICALL_NORMALIZE_INTEGERS | 838 | config CFI_ICALL_NORMALIZE_INTEGERS |
| 839 | bool "Normalize CFI tags for integers" | 839 | bool "Normalize CFI tags for integers" |
| 840 | depends on CFI_CLANG | 840 | depends on CFI_CLANG |
| 841 | depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS | 841 | depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG |
| 842 | help | 842 | help |
| 843 | This option normalizes the CFI tags for integer types so that all | 843 | This option normalizes the CFI tags for integer types so that all |
| 844 | integer types of the same size and signedness receive the same CFI | 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 | This option is necessary for using CFI with Rust. If unsure, say N. | 852 | This option is necessary for using CFI with Rust. If unsure, say N. |
| 853 | 853 | ||
| 854 | config HAVE_CFI_ICALL_NORMALIZE_INTEGERS | 854 | config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG |
| 855 | def_bool !GCOV_KERNEL && !KASAN | 855 | def_bool y |
| 856 | depends on CFI_CLANG | ||
| 857 | depends on $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers) | 856 | depends on $(cc-option,-fsanitize=kcfi -fsanitize-cfi-icall-experimental-normalize-integers) |
| 858 | help | 857 | # With GCOV/KASAN we need this fix: https://github.com/llvm/llvm-project/pull/104826 |
| 859 | Is CFI_ICALL_NORMALIZE_INTEGERS supported with the set of compilers | 858 | depends on CLANG_VERSION >= 190103 || (!GCOV_KERNEL && !KASAN_GENERIC && !KASAN_SW_TAGS) |
| 860 | currently in use? | ||
| 861 | 859 | ||
| 862 | This option defaults to false if GCOV or KASAN is enabled, as there is | 860 | config HAVE_CFI_ICALL_NORMALIZE_INTEGERS_RUSTC |
| 863 | an LLVM bug that makes normalized integers tags incompatible with | 861 | def_bool y |
| 864 | KASAN and GCOV. Kconfig currently does not have the infrastructure to | 862 | depends on HAVE_CFI_ICALL_NORMALIZE_INTEGERS_CLANG |
| 865 | detect whether your rustc compiler contains the fix for this bug, so | 863 | depends on RUSTC_VERSION >= 107900 |
| 866 | it is assumed that it doesn't. If your compiler has the fix, you can | 864 | # With GCOV/KASAN we need this fix: https://github.com/rust-lang/rust/pull/129373 |
| 867 | explicitly enable this option in your config file. The Kconfig logic | 865 | depends on (RUSTC_LLVM_VERSION >= 190103 && RUSTC_VERSION >= 108200) || \ |
| 868 | needed to detect this will be added in a future kernel release. | 866 | (!GCOV_KERNEL && !KASAN_GENERIC && !KASAN_SW_TAGS) |
| 869 | 867 | ||
| 870 | config CFI_PERMISSIVE | 868 | config CFI_PERMISSIVE |
| 871 | bool "Use CFI in permissive mode" | 869 | bool "Use CFI in permissive mode" |
| @@ -77,7 +77,7 @@ · 76 unmodified lines | |||
| 77 | }; | 77 | }; |
| 78 | 78 | ||
| 79 | &hdmi { | 79 | &hdmi { |
| 80 | hpd-gpios = <&expgpio 1 GPIO_ACTIVE_LOW>; | 80 | hpd-gpios = <&expgpio 0 GPIO_ACTIVE_LOW>; |
| 81 | power-domains = <&power RPI_POWER_DOMAIN_HDMI>; | 81 | power-domains = <&power RPI_POWER_DOMAIN_HDMI>; |
| 82 | status = "okay"; | 82 | status = "okay"; |
| 83 | }; | 83 | }; |
| @@ -136,7 +136,7 @@ · 135 unmodified lines | |||
| 136 | }; | 136 | }; |
| 137 | 137 | ||
| 138 | cp0_mdio_pins: cp0-mdio-pins { | 138 | cp0_mdio_pins: cp0-mdio-pins { |
| 139 | marvell,pins = "mpp40", "mpp41"; | 139 | marvell,pins = "mpp0", "mpp1"; |
| 140 | marvell,function = "ge"; | 140 | marvell,function = "ge"; |
| 141 | }; | 141 | }; |
| 142 | 142 | ||
| @@ -178,6 +178,7 @@ struct kvm_nvhe_init_params { · 177 unmodified lines | |||
| 178 | unsigned long hcr_el2; | 178 | unsigned long hcr_el2; |
| 179 | unsigned long vttbr; | 179 | unsigned long vttbr; |
| 180 | unsigned long vtcr; | 180 | unsigned long vtcr; |
| 181 | unsigned long tmp; | ||
| 181 | }; | 182 | }; |
| 182 | 183 | ||
| 183 | /* | 184 | /* |
| @@ -51,6 +51,7 @@ · 50 unmodified lines | |||
| 51 | #define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5) | 51 | #define KVM_REQ_RELOAD_PMU KVM_ARCH_REQ(5) |
| 52 | #define KVM_REQ_SUSPEND KVM_ARCH_REQ(6) | 52 | #define KVM_REQ_SUSPEND KVM_ARCH_REQ(6) |
| 53 | #define KVM_REQ_RESYNC_PMU_EL0 KVM_ARCH_REQ(7) | 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 | #define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ | 56 | #define KVM_DIRTY_LOG_MANUAL_CAPS (KVM_DIRTY_LOG_MANUAL_PROTECT_ENABLE | \ |
| 56 | KVM_DIRTY_LOG_INITIALLY_SET) | 57 | KVM_DIRTY_LOG_INITIALLY_SET) |
| @@ -211,6 +212,12 @@ struct kvm_s2_mmu { · 154 unmodified lines | |||
| 211 | */ | 212 | */ |
| 212 | bool nested_stage2_enabled; | 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 | * 0: Nobody is currently using this, check vttbr for validity | 222 | * 0: Nobody is currently using this, check vttbr for validity |
| 216 | * >0: Somebody is actively using this. | 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 | int create_hyp_stack(phys_addr_t phys_addr, unsigned long *haddr); | 166 | int create_hyp_stack(phys_addr_t phys_addr, unsigned long *haddr); |
| 167 | void __init free_hyp_pgds(void); | 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 | void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end); | 171 | void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end); |
| 171 | void kvm_stage2_wp_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end); | 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 | extern void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu); | 78 | extern void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu); |
| 79 | extern void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu); | 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 | struct kvm_s2_trans { | 83 | struct kvm_s2_trans { |
| 82 | phys_addr_t output; | 84 | phys_addr_t output; |
| 83 | unsigned long block_size; | 85 | unsigned long block_size; |
| @@ -124,7 +126,7 @@ extern int kvm_s2_handle_perm_fault(struct kvm_vcpu *vcpu, · 40 unmodified lines | |||
| 124 | struct kvm_s2_trans *trans); | 126 | struct kvm_s2_trans *trans); |
| 125 | extern int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2); | 127 | extern int kvm_inject_s2_fault(struct kvm_vcpu *vcpu, u64 esr_el2); |
| 126 | extern void kvm_nested_s2_wp(struct kvm *kvm); | 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 | extern void kvm_nested_s2_flush(struct kvm *kvm); | 130 | extern void kvm_nested_s2_flush(struct kvm *kvm); |
| 129 | 131 | ||
| 130 | unsigned long compute_tlb_inval_range(struct kvm_s2_mmu *mmu, u64 val); | 132 | unsigned long compute_tlb_inval_range(struct kvm_s2_mmu *mmu, u64 val); |
| @@ -10,11 +10,9 @@ · 9 unmodified lines | |||
| 10 | #include <asm/insn.h> | 10 | #include <asm/insn.h> |
| 11 | #include <asm/probes.h> | 11 | #include <asm/probes.h> |
| 12 | 12 | ||
| 13 | #define MAX_UINSN_BYTES AARCH64_INSN_SIZE | ||
| 14 | |||
| 15 | #define UPROBE_SWBP_INSN cpu_to_le32(BRK64_OPCODE_UPROBES) | 13 | #define UPROBE_SWBP_INSN cpu_to_le32(BRK64_OPCODE_UPROBES) |
| 16 | #define UPROBE_SWBP_INSN_SIZE AARCH64_INSN_SIZE | 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 | typedef __le32 uprobe_opcode_t; | 17 | typedef __le32 uprobe_opcode_t; |
| 20 | 18 | ||
| @@ -23,8 +21,8 @@ struct arch_uprobe_task { · 2 unmodified lines | |||
| 23 | 21 | ||
| 24 | struct arch_uprobe { | 22 | struct arch_uprobe { |
| 25 | union { | 23 | union { |
| 26 | u8 insn[MAX_UINSN_BYTES]; | 24 | __le32 insn; |
| 27 | u8 ixol[MAX_UINSN_BYTES]; | 25 | __le32 ixol; |
| 28 | }; | 26 | }; |
| 29 | struct arch_probe_insn api; | 27 | struct arch_probe_insn api; |
| 30 | bool simulate; | 28 | bool simulate; |
| @@ -146,6 +146,7 @@ int main(void) · 145 unmodified lines | |||
| 146 | DEFINE(NVHE_INIT_HCR_EL2, offsetof(struct kvm_nvhe_init_params, hcr_el2)); | 146 | DEFINE(NVHE_INIT_HCR_EL2, offsetof(struct kvm_nvhe_init_params, hcr_el2)); |
| 147 | DEFINE(NVHE_INIT_VTTBR, offsetof(struct kvm_nvhe_init_params, vttbr)); | 147 | DEFINE(NVHE_INIT_VTTBR, offsetof(struct kvm_nvhe_init_params, vttbr)); |
| 148 | DEFINE(NVHE_INIT_VTCR, offsetof(struct kvm_nvhe_init_params, vtcr)); | 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 | #endif | 150 | #endif |
| 150 | #ifdef CONFIG_CPU_PM | 151 | #ifdef CONFIG_CPU_PM |
| 151 | DEFINE(CPU_CTX_SP, offsetof(struct cpu_suspend_ctx, sp)); | 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 | aarch64_insn_is_blr(insn) || | 99 | aarch64_insn_is_blr(insn) || |
| 100 | aarch64_insn_is_ret(insn)) { | 100 | aarch64_insn_is_ret(insn)) { |
| 101 | api->handler = simulate_br_blr_ret; | 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 | } else { | 102 | } else { |
| 107 | /* | 103 | /* |
| 108 | * Instruction cannot be stepped out-of-line and we don't | 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 | probe_opcode_t insn = le32_to_cpu(*addr); | 136 | probe_opcode_t insn = le32_to_cpu(*addr); |
| 141 | probe_opcode_t *scan_end = NULL; | 137 | probe_opcode_t *scan_end = NULL; |
| 142 | unsigned long size = 0, offset = 0; | 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 | * If there's a symbol defined in front of and near enough to | 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 | else | 164 | else |
| 158 | scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE; | 165 | scan_end = addr - MAX_ATOMIC_CONTEXT_SIZE; |
| 159 | } | 166 | } |
| 160 | decoded = arm_probe_decode_insn(insn, &asi->api); | ||
| 161 | 167 | ||
| 162 | if (decoded != INSN_REJECTED && scan_end) | 168 | if (decoded != INSN_REJECTED && scan_end) |
| 163 | if (is_probed_address_atomic(addr - 1, scan_end)) | 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 | void __kprobes | 171 | void __kprobes |
| 172 | simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs) | 172 | simulate_ldr_literal(u32 opcode, long addr, struct pt_regs *regs) |
| 173 | { | 173 | { |
| 174 | u64 *load_addr; | 174 | unsigned long load_addr; |
| 175 | int xn = opcode & 0x1f; | 175 | int xn = opcode & 0x1f; |
| 176 | int disp; | ||
| 177 | 176 | ||
| 178 | disp = ldr_displacement(opcode); | 177 | load_addr = addr + ldr_displacement(opcode); |
| 179 | load_addr = (u64 *) (addr + disp); | ||
| 180 | 178 | ||
| 181 | if (opcode & (1 << 30)) /* x0-x30 */ | 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 | else /* w0-w30 */ | 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 | instruction_pointer_set(regs, instruction_pointer(regs) + 4); | 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 | void __kprobes | 187 | void __kprobes |
| 190 | simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs) | 188 | simulate_ldrsw_literal(u32 opcode, long addr, struct pt_regs *regs) |
| 191 | { | 189 | { |
| 192 | s32 *load_addr; | 190 | unsigned long load_addr; |
| 193 | int xn = opcode & 0x1f; | 191 | int xn = opcode & 0x1f; |
| 194 | int disp; | ||
| 195 | 192 | ||
| 196 | disp = ldr_displacement(opcode); | 193 | load_addr = addr + ldr_displacement(opcode); |
| 197 | load_addr = (s32 *) (addr + disp); | ||
| 198 | 194 | ||
| 199 | set_x_reg(regs, xn, *load_addr); | 195 | set_x_reg(regs, xn, READ_ONCE(*(s32 *)load_addr)); |
| 200 | 196 | ||
| 201 | instruction_pointer_set(regs, instruction_pointer(regs) + 4); | 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 | else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE)) | 42 | else if (!IS_ALIGNED(addr, AARCH64_INSN_SIZE)) |
| 43 | return -EINVAL; | 43 | return -EINVAL; |
| 44 | 44 | ||
| 45 | insn = *(probe_opcode_t *)(&auprobe->insn[0]); | 45 | insn = le32_to_cpu(auprobe->insn); |
| 46 | 46 | ||
| 47 | switch (arm_probe_decode_insn(insn, &auprobe->api)) { | 47 | switch (arm_probe_decode_insn(insn, &auprobe->api)) { |
| 48 | case INSN_REJECTED: | 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 | if (!auprobe->simulate) | 108 | if (!auprobe->simulate) |
| 109 | return false; | 109 | return false; |
| 110 | 110 | ||
| 111 | insn = *(probe_opcode_t *)(&auprobe->insn[0]); | 111 | insn = le32_to_cpu(auprobe->insn); |
| 112 | addr = instruction_pointer(regs); | 112 | addr = instruction_pointer(regs); |
| 113 | 113 | ||
| 114 | if (auprobe->api.handler) | 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 | p->thread.cpu_context.x19 = (unsigned long)args->fn; | 413 | p->thread.cpu_context.x19 = (unsigned long)args->fn; |
| 414 | p->thread.cpu_context.x20 = (unsigned long)args->fn_arg; | 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 | p->thread.cpu_context.pc = (unsigned long)ret_from_fork; | 419 | p->thread.cpu_context.pc = (unsigned long)ret_from_fork; |
| 417 | p->thread.cpu_context.sp = (unsigned long)childregs; | 420 | p->thread.cpu_context.sp = (unsigned long)childregs; |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/ratelimit.h> | 19 | #include <linux/ratelimit.h> |
| 20 | #include <linux/rseq.h> | 20 | #include <linux/rseq.h> |
| 21 | #include <linux/syscalls.h> | 21 | #include <linux/syscalls.h> |
| 22 | #include <linux/pkeys.h> | ||
| 22 | 23 | ||
| 23 | #include <asm/daifflags.h> | 24 | #include <asm/daifflags.h> |
| 24 | #include <asm/debug-monitors.h> | 25 | #include <asm/debug-monitors.h> |
| @@ -66,10 +67,63 @@ struct rt_sigframe_user_layout { · 41 unmodified lines | |||
| 66 | unsigned long end_offset; | 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 | #define BASE_SIGFRAME_SIZE round_up(sizeof(struct rt_sigframe), 16) | 82 | #define BASE_SIGFRAME_SIZE round_up(sizeof(struct rt_sigframe), 16) |
| 70 | #define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16) | 83 | #define TERMINATOR_SIZE round_up(sizeof(struct _aarch64_ctx), 16) |
| 71 | #define EXTRA_CONTEXT_SIZE round_up(sizeof(struct extra_context), 16) | 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 | static void init_user_layout(struct rt_sigframe_user_layout *user) | 127 | static void init_user_layout(struct rt_sigframe_user_layout *user) |
| 74 | { | 128 | { |
| 75 | const size_t reserved_size = | 129 | const size_t reserved_size = |
| @@ -261,18 +315,20 @@ static int restore_fpmr_context(struct user_ctxs *user) · 185 unmodified lines | |||
| 261 | return err; | 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 | int err = 0; | 321 | int err = 0; |
| 267 | 322 | ||
| 268 | __put_user_error(POE_MAGIC, &ctx->head.magic, err); | 323 | __put_user_error(POE_MAGIC, &ctx->head.magic, err); |
| 269 | __put_user_error(sizeof(*ctx), &ctx->head.size, err); | 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 | return err; | 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 | u64 por_el0; | 333 | u64 por_el0; |
| 278 | int err = 0; | 334 | int err = 0; |
| @@ -282,7 +338,7 @@ static int restore_poe_context(struct user_ctxs *user) · 3 unmodified lines | |||
| 282 | 338 | ||
| 283 | __get_user_error(por_el0, &(user->poe->por_el0), err); | 339 | __get_user_error(por_el0, &(user->poe->por_el0), err); |
| 284 | if (!err) | 340 | if (!err) |
| 285 | write_sysreg_s(por_el0, SYS_POR_EL0); | 341 | ua_state->por_el0 = por_el0; |
| 286 | 342 | ||
| 287 | return err; | 343 | return err; |
| 288 | } | 344 | } |
| @@ -850,7 +906,8 @@ invalid: · 561 unmodified lines | |||
| 850 | } | 906 | } |
| 851 | 907 | ||
| 852 | static int restore_sigframe(struct pt_regs *regs, | 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 | sigset_t set; | 912 | sigset_t set; |
| 856 | int i, err; | 913 | int i, err; |
| @@ -899,7 +956,7 @@ static int restore_sigframe(struct pt_regs *regs, · 42 unmodified lines | |||
| 899 | err = restore_zt_context(&user); | 956 | err = restore_zt_context(&user); |
| 900 | 957 | ||
| 901 | if (err == 0 && system_supports_poe() && user.poe) | 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 | return err; | 961 | return err; |
| 905 | } | 962 | } |
| @@ -908,6 +965,7 @@ SYSCALL_DEFINE0(rt_sigreturn) · 2 unmodified lines | |||
| 908 | { | 965 | { |
| 909 | struct pt_regs *regs = current_pt_regs(); | 966 | struct pt_regs *regs = current_pt_regs(); |
| 910 | struct rt_sigframe __user *frame; | 967 | struct rt_sigframe __user *frame; |
| 968 | struct user_access_state ua_state; | ||
| 911 | 969 | ||
| 912 | /* Always make any pending restarted system calls return -EINTR */ | 970 | /* Always make any pending restarted system calls return -EINTR */ |
| 913 | current->restart_block.fn = do_no_restart_syscall; | 971 | current->restart_block.fn = do_no_restart_syscall; |
| @@ -924,12 +982,14 @@ SYSCALL_DEFINE0(rt_sigreturn) · 10 unmodified lines | |||
| 924 | if (!access_ok(frame, sizeof (*frame))) | 982 | if (!access_ok(frame, sizeof (*frame))) |
| 925 | goto badframe; | 983 | goto badframe; |
| 926 | 984 | ||
| 927 | if (restore_sigframe(regs, frame)) | 985 | if (restore_sigframe(regs, frame, &ua_state)) |
| 928 | goto badframe; | 986 | goto badframe; |
| 929 | 987 | ||
| 930 | if (restore_altstack(&frame->uc.uc_stack)) | 988 | if (restore_altstack(&frame->uc.uc_stack)) |
| 931 | goto badframe; | 989 | goto badframe; |
| 932 | 990 | ||
| 991 | restore_user_access_state(&ua_state); | ||
| 992 | |||
| 933 | return regs->regs[0]; | 993 | return regs->regs[0]; |
| 934 | 994 | ||
| 935 | badframe: | 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 | static int setup_sigframe(struct rt_sigframe_user_layout *user, | 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 | int i, err = 0; | 1101 | int i, err = 0; |
| 1041 | struct rt_sigframe __user *sf = user->sigframe; | 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 | struct poe_context __user *poe_ctx = | 1158 | struct poe_context __user *poe_ctx = |
| 1098 | apply_user_offset(user, user->poe_offset); | 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 | /* ZA state if present */ | 1164 | /* ZA state if present */ |
| 1105 | if (system_supports_sme() && err == 0 && user->za_offset) { | 1165 | if (system_supports_sme() && err == 0 && user->za_offset) { |
| 1106 | struct za_context __user *za_ctx = | 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 | sme_smstop(); | 1297 | sme_smstop(); |
| 1238 | } | 1298 | } |
| 1239 | 1299 | ||
| 1240 | if (system_supports_poe()) | ||
| 1241 | write_sysreg_s(POR_EL0_INIT, SYS_POR_EL0); | ||
| 1242 | |||
| 1243 | if (ka->sa.sa_flags & SA_RESTORER) | 1300 | if (ka->sa.sa_flags & SA_RESTORER) |
| 1244 | sigtramp = ka->sa.sa_restorer; | 1301 | sigtramp = ka->sa.sa_restorer; |
| 1245 | else | 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 | struct rt_sigframe_user_layout user; | 1311 | struct rt_sigframe_user_layout user; |
| 1255 | struct rt_sigframe __user *frame; | 1312 | struct rt_sigframe __user *frame; |
| 1313 | struct user_access_state ua_state; | ||
| 1256 | int err = 0; | 1314 | int err = 0; |
| 1257 | 1315 | ||
| 1258 | fpsimd_signal_preserve_current_state(); | 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 | if (get_sigframe(&user, ksig, regs)) | 1318 | if (get_sigframe(&user, ksig, regs)) |
| 1261 | return 1; | 1319 | return 1; |
| 1262 | 1320 | ||
| 1321 | save_reset_user_access_state(&ua_state); | ||
| 1263 | frame = user.sigframe; | 1322 | frame = user.sigframe; |
| 1264 | 1323 | ||
| 1265 | __put_user_error(0, &frame->uc.uc_flags, err); | 1324 | __put_user_error(0, &frame->uc.uc_flags, err); |
| 1266 | __put_user_error(NULL, &frame->uc.uc_link, err); | 1325 | __put_user_error(NULL, &frame->uc.uc_link, err); |
| 1267 | 1326 | ||
| 1268 | err |= __save_altstack(&frame->uc.uc_stack, regs->sp); | 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 | if (err == 0) { | 1329 | if (err == 0) { |
| 1271 | setup_return(regs, &ksig->ka, &user, usig); | 1330 | setup_return(regs, &ksig->ka, &user, usig); |
| 1272 | if (ksig->ka.sa.sa_flags & SA_SIGINFO) { | 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 | return err; | 1343 | return err; |
| 1280 | } | 1344 | } |
| 1281 | 1345 | ||
| @@ -997,6 +997,9 @@ static int kvm_vcpu_suspend(struct kvm_vcpu *vcpu) · 996 unmodified lines | |||
| 997 | static int check_vcpu_requests(struct kvm_vcpu *vcpu) | 997 | static int check_vcpu_requests(struct kvm_vcpu *vcpu) |
| 998 | { | 998 | { |
| 999 | if (kvm_request_pending(vcpu)) { | 999 | if (kvm_request_pending(vcpu)) { |
| 1000 | if (kvm_check_request(KVM_REQ_VM_DEAD, vcpu)) | ||
| 1001 | return -EIO; | ||
| 1002 | |||
| 1000 | if (kvm_check_request(KVM_REQ_SLEEP, vcpu)) | 1003 | if (kvm_check_request(KVM_REQ_SLEEP, vcpu)) |
| 1001 | kvm_vcpu_sleep(vcpu); | 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 | if (kvm_dirty_ring_check_request(vcpu)) | 1035 | if (kvm_dirty_ring_check_request(vcpu)) |
| 1033 | return 0; | 1036 | return 0; |
| 1037 | |||
| 1038 | check_nested_vcpu_requests(vcpu); | ||
| 1034 | } | 1039 | } |
| 1035 | 1040 | ||
| 1036 | return 1; | 1041 | return 1; |
| @@ -24,28 +24,25 @@ · 23 unmodified lines | |||
| 24 | .align 11 | 24 | .align 11 |
| 25 | 25 | ||
| 26 | SYM_CODE_START(__kvm_hyp_init) | 26 | SYM_CODE_START(__kvm_hyp_init) |
| 27 | ventry __invalid // Synchronous EL2t | 27 | ventry . // Synchronous EL2t |
| 28 | ventry __invalid // IRQ EL2t | 28 | ventry . // IRQ EL2t |
| 29 | ventry __invalid // FIQ EL2t | 29 | ventry . // FIQ EL2t |
| 30 | ventry __invalid // Error EL2t | 30 | ventry . // Error EL2t |
| 31 | 31 | ||
| 32 | ventry __invalid // Synchronous EL2h | 32 | ventry . // Synchronous EL2h |
| 33 | ventry __invalid // IRQ EL2h | 33 | ventry . // IRQ EL2h |
| 34 | ventry __invalid // FIQ EL2h | 34 | ventry . // FIQ EL2h |
| 35 | ventry __invalid // Error EL2h | 35 | ventry . // Error EL2h |
| 36 | 36 | ||
| 37 | ventry __do_hyp_init // Synchronous 64-bit EL1 | 37 | ventry __do_hyp_init // Synchronous 64-bit EL1 |
| 38 | ventry __invalid // IRQ 64-bit EL1 | 38 | ventry . // IRQ 64-bit EL1 |
| 39 | ventry __invalid // FIQ 64-bit EL1 | 39 | ventry . // FIQ 64-bit EL1 |
| 40 | ventry __invalid // Error 64-bit EL1 | 40 | ventry . // Error 64-bit EL1 |
| 41 | 41 | ||
| 42 | ventry __invalid // Synchronous 32-bit EL1 | 42 | ventry . // Synchronous 32-bit EL1 |
| 43 | ventry __invalid // IRQ 32-bit EL1 | 43 | ventry . // IRQ 32-bit EL1 |
| 44 | ventry __invalid // FIQ 32-bit EL1 | 44 | ventry . // FIQ 32-bit EL1 |
| 45 | ventry __invalid // Error 32-bit EL1 | 45 | ventry . // Error 32-bit EL1 |
| 46 | |||
| 47 | __invalid: | ||
| 48 | b . | ||
| 49 | 46 | ||
| 50 | /* | 47 | /* |
| 51 | * Only uses x0..x3 so as to not clobber callee-saved SMCCC registers. | 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 | eret | 73 | eret |
| 77 | SYM_CODE_END(__kvm_hyp_init) | 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 | * Initialize the hypervisor in EL2. | 84 | * Initialize the hypervisor in EL2. |
| 81 | * | 85 | * |
| @@ -102,9 +106,12 @@ SYM_CODE_START_LOCAL(___kvm_hyp_init) · 20 unmodified lines | |||
| 102 | // TPIDR_EL2 is used to preserve x0 across the macro maze... | 106 | // TPIDR_EL2 is used to preserve x0 across the macro maze... |
| 103 | isb | 107 | isb |
| 104 | msr tpidr_el2, x0 | 108 | msr tpidr_el2, x0 |
| 105 | init_el2_state | 109 | str lr, [x0, #NVHE_INIT_TMP] |
| 106 | finalise_el2_state | 110 | |
| 111 | bl __kvm_init_el2_state | ||
| 112 | |||
| 107 | mrs x0, tpidr_el2 | 113 | mrs x0, tpidr_el2 |
| 114 | ldr lr, [x0, #NVHE_INIT_TMP] | ||
| 108 | 115 | ||
| 109 | 1: | 116 | 1: |
| 110 | ldr x1, [x0, #NVHE_INIT_TPIDR_EL2] | 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 | 2: msr SPsel, #1 // We want to use SP_EL{1,2} | 207 | 2: msr SPsel, #1 // We want to use SP_EL{1,2} |
| 201 | 208 | ||
| 202 | /* Initialize EL2 CPU state to sane values. */ | 209 | bl __kvm_init_el2_state |
| 203 | init_el2_state // Clobbers x0..x2 | 210 | |
| 204 | finalise_el2_state | ||
| 205 | __init_el2_nvhe_prepare_eret | 211 | __init_el2_nvhe_prepare_eret |
| 206 | 212 | ||
| 207 | /* Enable MMU, set vectors and stack. */ | 213 | /* Enable MMU, set vectors and stack. */ |
| @@ -317,7 +317,7 @@ int kvm_smccc_call_handler(struct kvm_vcpu *vcpu) · 316 unmodified lines | |||
| 317 | * to the guest, and hide SSBS so that the | 317 | * to the guest, and hide SSBS so that the |
| 318 | * guest stays protected. | 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 | break; | 321 | break; |
| 322 | fallthrough; | 322 | fallthrough; |
| 323 | case SPECTRE_UNAFFECTED: | 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 | * Convert the workaround level into an easy-to-compare number, where higher | 428 | * Convert the workaround level into an easy-to-compare number, where higher |
| 429 | * values mean better protection. | 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 | switch (regid) { | 433 | switch (regid) { |
| 434 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: | 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 | * don't have any FW mitigation if SSBS is there at | 449 | * don't have any FW mitigation if SSBS is there at |
| 450 | * all times. | 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 | return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL; | 453 | return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL; |
| 454 | fallthrough; | 454 | fallthrough; |
| 455 | case SPECTRE_UNAFFECTED: | 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 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: | 486 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: |
| 487 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: | 487 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: |
| 488 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_3: | 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 | break; | 490 | break; |
| 491 | case KVM_REG_ARM_STD_BMAP: | 491 | case KVM_REG_ARM_STD_BMAP: |
| 492 | val = READ_ONCE(smccc_feat->std_bmap); | 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 | if (val & ~KVM_REG_FEATURE_LEVEL_MASK) | 588 | if (val & ~KVM_REG_FEATURE_LEVEL_MASK) |
| 589 | return -EINVAL; | 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 | return -EINVAL; | 592 | return -EINVAL; |
| 593 | 593 | ||
| 594 | return 0; | 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 | * We can deal with NOT_AVAIL on NOT_REQUIRED, but not the | 624 | * We can deal with NOT_AVAIL on NOT_REQUIRED, but not the |
| 625 | * other way around. | 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 | return -EINVAL; | 628 | return -EINVAL; |
| 629 | 629 | ||
| 630 | return 0; | 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 | may_block)); | 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 | void kvm_stage2_flush_range(struct kvm_s2_mmu *mmu, phys_addr_t addr, phys_addr_t end) | 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 | if (!(vma->vm_flags & VM_PFNMAP)) { | 1017 | if (!(vma->vm_flags & VM_PFNMAP)) { |
| 1017 | gpa_t gpa = addr + (vm_start - memslot->userspace_addr); | 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 | hva = vm_end; | 1021 | hva = vm_end; |
| 1021 | } while (hva < reg_end); | 1022 | } while (hva < reg_end); |
| @@ -1042,7 +1043,7 @@ void stage2_unmap_vm(struct kvm *kvm) · 20 unmodified lines | |||
| 1042 | kvm_for_each_memslot(memslot, bkt, slots) | 1043 | kvm_for_each_memslot(memslot, bkt, slots) |
| 1043 | stage2_unmap_memslot(kvm, memslot); | 1044 | stage2_unmap_memslot(kvm, memslot); |
| 1044 | 1045 | ||
| 1045 | kvm_nested_s2_unmap(kvm); | 1046 | kvm_nested_s2_unmap(kvm, true); |
| 1046 | 1047 | ||
| 1047 | write_unlock(&kvm->mmu_lock); | 1048 | write_unlock(&kvm->mmu_lock); |
| 1048 | mmap_read_unlock(current->mm); | 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 | (range->end - range->start) << PAGE_SHIFT, | 1913 | (range->end - range->start) << PAGE_SHIFT, |
| 1913 | range->may_block); | 1914 | range->may_block); |
| 1914 | 1915 | ||
| 1915 | kvm_nested_s2_unmap(kvm); | 1916 | kvm_nested_s2_unmap(kvm, range->may_block); |
| 1916 | return false; | 1917 | return false; |
| 1917 | } | 1918 | } |
| 1918 | 1919 | ||
| @@ -2179,8 +2180,8 @@ void kvm_arch_flush_shadow_memslot(struct kvm *kvm, · 260 unmodified lines | |||
| 2179 | phys_addr_t size = slot->npages << PAGE_SHIFT; | 2180 | phys_addr_t size = slot->npages << PAGE_SHIFT; |
| 2180 | 2181 | ||
| 2181 | write_lock(&kvm->mmu_lock); | 2182 | write_lock(&kvm->mmu_lock); |
| 2182 | kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, size); | 2183 | kvm_stage2_unmap_range(&kvm->arch.mmu, gpa, size, true); |
| 2183 | kvm_nested_s2_unmap(kvm); | 2184 | kvm_nested_s2_unmap(kvm, true); |
| 2184 | write_unlock(&kvm->mmu_lock); | 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 | /* Set the scene for the next search */ | 632 | /* Set the scene for the next search */ |
| 633 | kvm->arch.nested_mmus_next = (i + 1) % kvm->arch.nested_mmus_size; | 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 | if (kvm_s2_mmu_valid(s2_mmu)) | 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 | * The virtual VMID (modulo CnP) will be used as a key when matching | 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 | out: | 651 | out: |
| 652 | atomic_inc(&s2_mmu->refcnt); | 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 | return s2_mmu; | 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 | void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu) | 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 | if (is_hyp_ctxt(vcpu)) { | 683 | if (is_hyp_ctxt(vcpu)) { |
| 667 | vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu; | 684 | vcpu->arch.hw_mmu = &vcpu->kvm->arch.mmu; |
| 668 | } else { | 685 | } else { |
| @@ -674,10 +691,18 @@ void kvm_vcpu_load_hw_mmu(struct kvm_vcpu *vcpu) · 5 unmodified lines | |||
| 674 | 691 | ||
| 675 | void kvm_vcpu_put_hw_mmu(struct kvm_vcpu *vcpu) | 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 | atomic_dec(&vcpu->arch.hw_mmu->refcnt); | 703 | atomic_dec(&vcpu->arch.hw_mmu->refcnt); |
| 679 | vcpu->arch.hw_mmu = NULL; | 704 | |
| 680 | } | 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 | int i; | 760 | int i; |
| 736 | 761 | ||
| @@ -740,7 +765,7 @@ void kvm_nested_s2_unmap(struct kvm *kvm) · 3 unmodified lines | |||
| 740 | struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i]; | 765 | struct kvm_s2_mmu *mmu = &kvm->arch.nested_mmus[i]; |
| 741 | 766 | ||
| 742 | if (kvm_s2_mmu_valid(mmu)) | 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 | return 0; | 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 | val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE); | 1527 | val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_MTE); |
| 1528 | 1528 | ||
| 1529 | val &= ~ARM64_FEATURE_MASK(ID_AA64PFR1_EL1_SME); | 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 | break; | 1538 | break; |
| 1531 | case SYS_ID_AA64PFR2_EL1: | 1539 | case SYS_ID_AA64PFR2_EL1: |
| 1532 | /* We only expose FPMR */ | 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 | val &= ~ID_AA64MMFR2_EL1_CCIDX_MASK; | 1558 | val &= ~ID_AA64MMFR2_EL1_CCIDX_MASK; |
| 1551 | break; | 1559 | break; |
| 1552 | case SYS_ID_AA64MMFR3_EL1: | 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 | break; | 1563 | break; |
| 1555 | case SYS_ID_MMFR4_EL1: | 1564 | case SYS_ID_MMFR4_EL1: |
| 1556 | val &= ~ARM64_FEATURE_MASK(ID_MMFR4_EL1_CCIDX); | 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 | * one cache line. | 1994 | * one cache line. |
| 1986 | */ | 1995 | */ |
| 1987 | if (kvm_has_mte(vcpu->kvm)) | 1996 | if (kvm_has_mte(vcpu->kvm)) |
| 1988 | clidr |= 2 << CLIDR_TTYPE_SHIFT(loc); | 1997 | clidr |= 2ULL << CLIDR_TTYPE_SHIFT(loc); |
| 1989 | 1998 | ||
| 1990 | __vcpu_sys_reg(vcpu, r->reg) = clidr; | 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 | ID_AA64PFR0_EL1_RAS | | 2385 | ID_AA64PFR0_EL1_RAS | |
| 2377 | ID_AA64PFR0_EL1_AdvSIMD | | 2386 | ID_AA64PFR0_EL1_AdvSIMD | |
| 2378 | ID_AA64PFR0_EL1_FP), }, | 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 | ID_WRITABLE(ID_AA64PFR2_EL1, ID_AA64PFR2_EL1_FPMR), | 2401 | ID_WRITABLE(ID_AA64PFR2_EL1, ID_AA64PFR2_EL1_FPMR), |
| 2381 | ID_UNALLOCATED(4,3), | 2402 | ID_UNALLOCATED(4,3), |
| 2382 | ID_WRITABLE(ID_AA64ZFR0_EL1, ~ID_AA64ZFR0_EL1_RES0), | 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 | .get_user = get_id_reg, | 2411 | .get_user = get_id_reg, |
| 2391 | .set_user = set_id_aa64dfr0_el1, | 2412 | .set_user = set_id_aa64dfr0_el1, |
| 2392 | .reset = read_sanitised_id_aa64dfr0_el1, | 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 | ID_AA64DFR0_EL1_DebugVer_MASK, }, | 2429 | ID_AA64DFR0_EL1_DebugVer_MASK, }, |
| 2395 | ID_SANITISED(ID_AA64DFR1_EL1), | 2430 | ID_SANITISED(ID_AA64DFR1_EL1), |
| 2396 | ID_UNALLOCATED(5,2), | 2431 | ID_UNALLOCATED(5,2), |
| @@ -2433,6 +2468,7 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 36 unmodified lines | |||
| 2433 | ID_AA64MMFR2_EL1_NV | | 2468 | ID_AA64MMFR2_EL1_NV | |
| 2434 | ID_AA64MMFR2_EL1_CCIDX)), | 2469 | ID_AA64MMFR2_EL1_CCIDX)), |
| 2435 | ID_WRITABLE(ID_AA64MMFR3_EL1, (ID_AA64MMFR3_EL1_TCRX | | 2470 | ID_WRITABLE(ID_AA64MMFR3_EL1, (ID_AA64MMFR3_EL1_TCRX | |
| 2471 | ID_AA64MMFR3_EL1_S1PIE | | ||
| 2436 | ID_AA64MMFR3_EL1_S1POE)), | 2472 | ID_AA64MMFR3_EL1_S1POE)), |
| 2437 | ID_SANITISED(ID_AA64MMFR4_EL1), | 2473 | ID_SANITISED(ID_AA64MMFR4_EL1), |
| 2438 | ID_UNALLOCATED(7,5), | 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 | * Drop all shadow S2s, resulting in S1/S2 TLBIs for each of the | 2939 | * Drop all shadow S2s, resulting in S1/S2 TLBIs for each of the |
| 2904 | * corresponding VMIDs. | 2940 | * corresponding VMIDs. |
| 2905 | */ | 2941 | */ |
| 2906 | kvm_nested_s2_unmap(vcpu->kvm); | 2942 | kvm_nested_s2_unmap(vcpu->kvm, true); |
| 2907 | 2943 | ||
| 2908 | write_unlock(&vcpu->kvm->mmu_lock); | 2944 | write_unlock(&vcpu->kvm->mmu_lock); |
| 2909 | 2945 | ||
| @@ -2955,7 +2991,30 @@ union tlbi_info { · 45 unmodified lines | |||
| 2955 | static void s2_mmu_unmap_range(struct kvm_s2_mmu *mmu, | 2991 | static void s2_mmu_unmap_range(struct kvm_s2_mmu *mmu, |
| 2956 | const union tlbi_info *info) | 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 | static bool handle_vmalls12e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p, | 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 | max_size = compute_tlb_inval_range(mmu, info->ipa.addr); | 3109 | max_size = compute_tlb_inval_range(mmu, info->ipa.addr); |
| 3051 | base_addr &= ~(max_size - 1); | 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 | static bool handle_ipas2e1is(struct kvm_vcpu *vcpu, struct sys_reg_params *p, | 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 | kfree(vgic_cpu->private_irqs); | 417 | kfree(vgic_cpu->private_irqs); |
| 418 | vgic_cpu->private_irqs = NULL; | 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 | vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF; | 440 | vgic_cpu->rd_iodev.base_addr = VGIC_ADDR_UNDEF; |
| 441 | } | ||
| 422 | } | 442 | } |
| 423 | 443 | ||
| 424 | void kvm_vgic_vcpu_destroy(struct kvm_vcpu *vcpu) | 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 | if (ret) | 544 | if (ret) |
| 525 | goto out; | 545 | goto out; |
| 526 | 546 | ||
| 527 | dist->ready = true; | ||
| 528 | dist_base = dist->vgic_dist_base; | 547 | dist_base = dist->vgic_dist_base; |
| 529 | mutex_unlock(&kvm->arch.config_lock); | 548 | mutex_unlock(&kvm->arch.config_lock); |
| 530 | 549 | ||
| 531 | ret = vgic_register_dist_iodev(kvm, dist_base, type); | 550 | ret = vgic_register_dist_iodev(kvm, dist_base, type); |
| 532 | if (ret) | 551 | if (ret) { |
| 533 | kvm_err("Unable to register VGIC dist MMIO regions\n"); | 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 | goto out_slots; | 564 | goto out_slots; |
| 536 | out: | 565 | out: |
| 537 | mutex_unlock(&kvm->arch.config_lock); | 566 | mutex_unlock(&kvm->arch.config_lock); |
| 538 | out_slots: | 567 | out_slots: |
| 539 | mutex_unlock(&kvm->slots_lock); | ||
| 540 | |||
| 541 | if (ret) | 568 | if (ret) |
| 542 | kvm_vgic_destroy(kvm); | 569 | kvm_vm_dead(kvm); |
| 570 | |||
| 571 | mutex_unlock(&kvm->slots_lock); | ||
| 543 | 572 | ||
| 544 | return ret; | 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 | mutex_lock(&dev->kvm->arch.config_lock); | 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 | ret = -EBUSY; | 245 | ret = -EBUSY; |
| 241 | else | 246 | else |
| 242 | dev->kvm->arch.vgic.nr_spis = | 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 | emit(A64_STR64I(A64_R(20), A64_SP, regs_off + 8), ctx); | 2220 | emit(A64_STR64I(A64_R(20), A64_SP, regs_off + 8), ctx); |
| 2221 | 2221 | ||
| 2222 | if (flags & BPF_TRAMP_F_CALL_ORIG) { | 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 | emit_call((const u64)__bpf_tramp_enter, ctx); | 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 | if (flags & BPF_TRAMP_F_CALL_ORIG) { | 2269 | if (flags & BPF_TRAMP_F_CALL_ORIG) { |
| 2266 | im->ip_epilogue = ctx->ro_image + ctx->idx; | 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 | emit_call((const u64)__bpf_tramp_exit, ctx); | 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 | #define NR_WORDS DIV_ROUND_UP(NR_CPUS, BITS_PER_LONG) | 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 | struct loongson_system_configuration { | 33 | struct loongson_system_configuration { |
| 30 | int nr_cpus; | 34 | int nr_cpus; |
| 31 | int nr_nodes; | 35 | int nr_nodes; |
| @@ -16,7 +16,7 @@ · 15 unmodified lines | |||
| 16 | #define XRANGE_SHIFT (48) | 16 | #define XRANGE_SHIFT (48) |
| 17 | 17 | ||
| 18 | /* Valid address length */ | 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 | /* Used for taking out the valid address */ | 20 | /* Used for taking out the valid address */ |
| 21 | #define XRANGE_SHADOW_MASK GENMASK_ULL(XRANGE_SHADOW_SHIFT - 1, 0) | 21 | #define XRANGE_SHADOW_MASK GENMASK_ULL(XRANGE_SHADOW_SHIFT - 1, 0) |
| 22 | /* One segment whole address space size */ | 22 | /* One segment whole address space size */ |
| @@ -250,7 +250,7 @@ · 249 unmodified lines | |||
| 250 | #define CSR_ESTAT_IS_WIDTH 15 | 250 | #define CSR_ESTAT_IS_WIDTH 15 |
| 251 | #define CSR_ESTAT_IS (_ULCAST_(0x7fff) << CSR_ESTAT_IS_SHIFT) | 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 | #define LOONGARCH_CSR_BADV 0x7 /* Bad virtual address */ | 255 | #define LOONGARCH_CSR_BADV 0x7 /* Bad virtual address */ |
| 256 | 256 | ||
| @@ -10,6 +10,7 @@ · 9 unmodified lines | |||
| 10 | 10 | ||
| 11 | #define __HAVE_ARCH_PMD_ALLOC_ONE | 11 | #define __HAVE_ARCH_PMD_ALLOC_ONE |
| 12 | #define __HAVE_ARCH_PUD_ALLOC_ONE | 12 | #define __HAVE_ARCH_PUD_ALLOC_ONE |
| 13 | #define __HAVE_ARCH_PTE_ALLOC_ONE_KERNEL | ||
| 13 | #include <asm-generic/pgalloc.h> | 14 | #include <asm-generic/pgalloc.h> |
| 14 | 15 | ||
| 15 | static inline void pmd_populate_kernel(struct mm_struct *mm, | 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 | extern pgd_t *pgd_alloc(struct mm_struct *mm); | 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 | #define __pte_free_tlb(tlb, pte, address) \ | 58 | #define __pte_free_tlb(tlb, pte, address) \ |
| 48 | do { \ | 59 | do { \ |
| 49 | pagetable_pte_dtor(page_ptdesc(pte)); \ | 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 | extern void pgd_init(void *addr); | 269 | extern void pgd_init(void *addr); |
| 270 | extern void pud_init(void *addr); | 270 | extern void pud_init(void *addr); |
| 271 | extern void pmd_init(void *addr); | 271 | extern void pmd_init(void *addr); |
| 272 | extern void kernel_pte_init(void *addr); | ||
| 272 | 273 | ||
| 273 | /* | 274 | /* |
| 274 | * Encode/decode swap entries and swap PTEs. Swap PTEs are all PTEs that | 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 | WRITE_ONCE(*ptep, pteval); | 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 | #ifdef CONFIG_SMP | 329 | #ifdef CONFIG_SMP |
| 336 | /* | 330 | if (pte_val(pteval) & _PAGE_GLOBAL) |
| 337 | * For SMP, multiple CPUs can race, so we need | 331 | DBAR(0b11000); /* o_wrw = 0b11000 */ |
| 338 | * to do this atomically. | 332 | #endif |
| 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 | } | ||
| 352 | } | 333 | } |
| 353 | 334 | ||
| 354 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | 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 */ | 337 | pte_t pte = ptep_get(ptep); |
| 357 | if (pte_val(ptep_get(ptep_buddy(ptep))) & _PAGE_GLOBAL) | 338 | pte_val(pte) &= _PAGE_GLOBAL; |
| 358 | set_pte(ptep, __pte(_PAGE_GLOBAL)); | 339 | set_pte(ptep, pte); |
| 359 | else | ||
| 360 | set_pte(ptep, __pte(0)); | ||
| 361 | } | 340 | } |
| 362 | 341 | ||
| 363 | #define PGD_T_LOG2 (__builtin_ffs(sizeof(pgd_t)) - 1) | 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 | unsigned long top = TASK_SIZE & PAGE_MASK; | 294 | unsigned long top = TASK_SIZE & PAGE_MASK; |
| 295 | 295 | ||
| 296 | /* Space for the VDSO & data page */ | 296 | if (current->thread.vdso) { |
| 297 | top -= PAGE_ALIGN(current->thread.vdso->size); | 297 | /* Space for the VDSO & data page */ |
| 298 | top -= VVAR_SIZE; | 298 | top -= PAGE_ALIGN(current->thread.vdso->size); |
| 299 | 299 | top -= VVAR_SIZE; | |
| 300 | /* Space to randomize the VDSO base */ | 300 | |
| 301 | if (current->flags & PF_RANDOMIZE) | 301 | /* Space to randomize the VDSO base */ |
| 302 | top -= VDSO_RANDOMIZE_SIZE; | 302 | if (current->flags & PF_RANDOMIZE) |
| 303 | top -= VDSO_RANDOMIZE_SIZE; | ||
| 304 | } | ||
| 303 | 305 | ||
| 304 | return top; | 306 | return top; |
| 305 | } | 307 | } |
| @@ -55,6 +55,7 @@ · 54 unmodified lines | |||
| 55 | #define SMBIOS_FREQHIGH_OFFSET 0x17 | 55 | #define SMBIOS_FREQHIGH_OFFSET 0x17 |
| 56 | #define SMBIOS_FREQLOW_MASK 0xFF | 56 | #define SMBIOS_FREQLOW_MASK 0xFF |
| 57 | #define SMBIOS_CORE_PACKAGE_OFFSET 0x23 | 57 | #define SMBIOS_CORE_PACKAGE_OFFSET 0x23 |
| 58 | #define SMBIOS_THREAD_PACKAGE_OFFSET 0x25 | ||
| 58 | #define LOONGSON_EFI_ENABLE (1 << 3) | 59 | #define LOONGSON_EFI_ENABLE (1 << 3) |
| 59 | 60 | ||
| 60 | unsigned long fw_arg0, fw_arg1, fw_arg2; | 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 | cpu_clock_freq = freq_temp * 1000000; | 126 | cpu_clock_freq = freq_temp * 1000000; |
| 126 | 127 | ||
| 127 | loongson_sysconf.cpuname = (void *)dmi_string_parse(dm, dmi_data[16]); | 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 | pr_info("CpuClock = %llu\n", cpu_clock_freq); | 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 | #else | 555 | #else |
| 556 | unsigned int *pc; | 556 | unsigned int *pc; |
| 557 | 557 | ||
| 558 | if (regs->csr_prmd & CSR_PRMD_PIE) | ||
| 559 | local_irq_enable(); | ||
| 560 | |||
| 558 | perf_sw_event(PERF_COUNT_SW_ALIGNMENT_FAULTS, 1, regs, regs->csr_badvaddr); | 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 | die_if_kernel("Kernel ale access", regs); | 582 | die_if_kernel("Kernel ale access", regs); |
| 580 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr); | 583 | force_sig_fault(SIGBUS, BUS_ADRALN, (void __user *)regs->csr_badvaddr); |
| 581 | out: | 584 | out: |
| 585 | if (regs->csr_prmd & CSR_PRMD_PIE) | ||
| 586 | local_irq_disable(); | ||
| 582 | #endif | 587 | #endif |
| 583 | irqentry_exit(regs, state); | 588 | irqentry_exit(regs, state); |
| 584 | } | 589 | } |
| @@ -34,7 +34,6 @@ static union { · 33 unmodified lines | |||
| 34 | struct loongarch_vdso_data vdata; | 34 | struct loongarch_vdso_data vdata; |
| 35 | } loongarch_vdso_data __page_aligned_data; | 35 | } loongarch_vdso_data __page_aligned_data; |
| 36 | 36 | ||
| 37 | static struct page *vdso_pages[] = { NULL }; | ||
| 38 | struct vdso_data *vdso_data = generic_vdso_data.data; | 37 | struct vdso_data *vdso_data = generic_vdso_data.data; |
| 39 | struct vdso_pcpu_data *vdso_pdata = loongarch_vdso_data.vdata.pdata; | 38 | struct vdso_pcpu_data *vdso_pdata = loongarch_vdso_data.vdata.pdata; |
| 40 | struct vdso_rng_data *vdso_rng_data = &loongarch_vdso_data.vdata.rng_data; | 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 | struct loongarch_vdso_info vdso_info = { | 85 | struct loongarch_vdso_info vdso_info = { |
| 87 | .vdso = vdso_start, | 86 | .vdso = vdso_start, |
| 88 | .size = PAGE_SIZE, | ||
| 89 | .code_mapping = { | 87 | .code_mapping = { |
| 90 | .name = "[vdso]", | 88 | .name = "[vdso]", |
| 91 | .pages = vdso_pages, | ||
| 92 | .mremap = vdso_mremap, | 89 | .mremap = vdso_mremap, |
| 93 | }, | 90 | }, |
| 94 | .data_mapping = { | 91 | .data_mapping = { |
| @@ -103,11 +100,14 @@ static int __init init_vdso(void) · 8 unmodified lines | |||
| 103 | unsigned long i, cpu, pfn; | 100 | unsigned long i, cpu, pfn; |
| 104 | 101 | ||
| 105 | BUG_ON(!PAGE_ALIGNED(vdso_info.vdso)); | 102 | BUG_ON(!PAGE_ALIGNED(vdso_info.vdso)); |
| 106 | BUG_ON(!PAGE_ALIGNED(vdso_info.size)); | ||
| 107 | 103 | ||
| 108 | for_each_possible_cpu(cpu) | 104 | for_each_possible_cpu(cpu) |
| 109 | vdso_pdata[cpu].node = cpu_to_node(cpu); | 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 | pfn = __phys_to_pfn(__pa_symbol(vdso_info.vdso)); | 111 | pfn = __phys_to_pfn(__pa_symbol(vdso_info.vdso)); |
| 112 | for (i = 0; i < vdso_info.size / PAGE_SIZE; i++) | 112 | for (i = 0; i < vdso_info.size / PAGE_SIZE; i++) |
| 113 | vdso_info.code_mapping.pages[i] = pfn_to_page(pfn + i); | 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 | if (kvm_vcpu_is_blocking(vcpu)) { | 161 | if (kvm_vcpu_is_blocking(vcpu)) { |
| 162 | 162 | ||
| 163 | /* | 163 | /* |
| 164 | * HRTIMER_MODE_PINNED is suggested since vcpu may run in | 164 | * HRTIMER_MODE_PINNED_HARD is suggested since vcpu may run in |
| 165 | * the same physical cpu in next time | 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 | vcpu->arch.vpid = 0; | 1457 | vcpu->arch.vpid = 0; |
| 1458 | vcpu->arch.flush_gpa = INVALID_GPA; | 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 | vcpu->arch.swtimer.function = kvm_swtimer_wakeup; | 1461 | vcpu->arch.swtimer.function = kvm_swtimer_wakeup; |
| 1462 | 1462 | ||
| 1463 | vcpu->arch.handle_exit = kvm_handle_exit; | 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 | pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE); | 201 | pte = memblock_alloc(PAGE_SIZE, PAGE_SIZE); |
| 202 | if (!pte) | 202 | if (!pte) |
| 203 | panic("%s: Failed to allocate memory\n", __func__); | 203 | panic("%s: Failed to allocate memory\n", __func__); |
| 204 | |||
| 204 | pmd_populate_kernel(&init_mm, pmd, pte); | 205 | pmd_populate_kernel(&init_mm, pmd, pte); |
| 206 | kernel_pte_init(pte); | ||
| 205 | } | 207 | } |
| 206 | 208 | ||
| 207 | return pte_offset_kernel(pmd, addr); | 209 | return pte_offset_kernel(pmd, addr); |
| @@ -116,6 +116,26 @@ void pud_init(void *addr) · 115 unmodified lines | |||
| 116 | EXPORT_SYMBOL_GPL(pud_init); | 116 | EXPORT_SYMBOL_GPL(pud_init); |
| 117 | #endif | 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 | pmd_t mk_pmd(struct page *page, pgprot_t prot) | 139 | pmd_t mk_pmd(struct page *page, pgprot_t prot) |
| 120 | { | 140 | { |
| 121 | pmd_t pmd; | 141 | pmd_t pmd; |
| @@ -102,3 +102,4 @@ unsigned long __cmpxchg_small(volatile void *ptr, unsigned long old, · 101 unmodified lines | |||
| 102 | return old; | 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 | bctr /* jump into table */ | 494 | bctr /* jump into table */ |
| 495 | 152: | 495 | 152: |
| 496 | mfdar r11 | 496 | mfdar r11 |
| 497 | mtdar r10 | ||
| 497 | mtctr r11 /* restore ctr reg from DAR */ | 498 | mtctr r11 /* restore ctr reg from DAR */ |
| 498 | mfspr r11, SPRN_SPRG_THREAD | 499 | mfspr r11, SPRN_SPRG_THREAD |
| 499 | stw r10, DAR(r11) | 500 | stw r10, DAR(r11) |
| @@ -282,6 +282,7 @@ int __init opal_event_init(void) · 281 unmodified lines | |||
| 282 | name, NULL); | 282 | name, NULL); |
| 283 | if (rc) { | 283 | if (rc) { |
| 284 | pr_warn("Error %d requesting OPAL irq %d\n", rc, (int)r->start); | 284 | pr_warn("Error %d requesting OPAL irq %d\n", rc, (int)r->start); |
| 285 | kfree(name); | ||
| 285 | continue; | 286 | continue; |
| 286 | } | 287 | } |
| 287 | } | 288 | } |
| @@ -177,7 +177,7 @@ config RISCV · 176 unmodified lines | |||
| 177 | select HAVE_REGS_AND_STACK_ACCESS_API | 177 | select HAVE_REGS_AND_STACK_ACCESS_API |
| 178 | select HAVE_RETHOOK if !XIP_KERNEL | 178 | select HAVE_RETHOOK if !XIP_KERNEL |
| 179 | select HAVE_RSEQ | 179 | select HAVE_RSEQ |
| 180 | select HAVE_RUST if RUSTC_SUPPORTS_RISCV | 180 | select HAVE_RUST if RUSTC_SUPPORTS_RISCV && CC_IS_CLANG |
| 181 | select HAVE_SAMPLE_FTRACE_DIRECT | 181 | select HAVE_SAMPLE_FTRACE_DIRECT |
| 182 | select HAVE_SAMPLE_FTRACE_DIRECT_MULTI | 182 | select HAVE_SAMPLE_FTRACE_DIRECT_MULTI |
| 183 | select HAVE_STACKPROTECTOR | 183 | select HAVE_STACKPROTECTOR |
| @@ -2,6 +2,12 @@ ifdef CONFIG_RELOCATABLE · 1 unmodified line | |||
| 2 | KBUILD_CFLAGS += -fno-pie | 2 | KBUILD_CFLAGS += -fno-pie |
| 3 | endif | 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 | obj-$(CONFIG_ERRATA_ANDES) += andes/ | 11 | obj-$(CONFIG_ERRATA_ANDES) += andes/ |
| 6 | obj-$(CONFIG_ERRATA_SIFIVE) += sifive/ | 12 | obj-$(CONFIG_ERRATA_SIFIVE) += sifive/ |
| 7 | obj-$(CONFIG_ERRATA_THEAD) += thead/ | 13 | obj-$(CONFIG_ERRATA_THEAD) += thead/ |
| @@ -36,6 +36,11 @@ KASAN_SANITIZE_alternative.o := n · 35 unmodified lines | |||
| 36 | KASAN_SANITIZE_cpufeature.o := n | 36 | KASAN_SANITIZE_cpufeature.o := n |
| 37 | KASAN_SANITIZE_sbi_ecall.o := n | 37 | KASAN_SANITIZE_sbi_ecall.o := n |
| 38 | endif | 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 | endif | 44 | endif |
| 40 | 45 | ||
| 41 | extra-y += vmlinux.lds | 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 | if (!size) | 210 | if (!size) |
| 211 | return NULL; | 211 | return NULL; |
| 212 | 212 | ||
| 213 | return early_ioremap(phys, size); | 213 | return early_memremap(phys, size); |
| 214 | } | 214 | } |
| 215 | 215 | ||
| 216 | void __init __acpi_unmap_table(void __iomem *map, unsigned long size) | 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 | if (!map || !size) | 218 | if (!map || !size) |
| 219 | return; | 219 | return; |
| 220 | 220 | ||
| 221 | early_iounmap(map, size); | 221 | early_memunmap(map, size); |
| 222 | } | 222 | } |
| 223 | 223 | ||
| 224 | void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size) | 224 | void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size) |
| @@ -4,8 +4,6 @@ · 3 unmodified lines | |||
| 4 | * Copyright (C) 2017 SiFive | 4 | * Copyright (C) 2017 SiFive |
| 5 | */ | 5 | */ |
| 6 | 6 | ||
| 7 | #define GENERATING_ASM_OFFSETS | ||
| 8 | |||
| 9 | #include <linux/kbuild.h> | 7 | #include <linux/kbuild.h> |
| 10 | #include <linux/mm.h> | 8 | #include <linux/mm.h> |
| 11 | #include <linux/sched.h> | 9 | #include <linux/sched.h> |
| @@ -80,8 +80,7 @@ int populate_cache_leaves(unsigned int cpu) · 79 unmodified lines | |||
| 80 | { | 80 | { |
| 81 | struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); | 81 | struct cpu_cacheinfo *this_cpu_ci = get_cpu_cacheinfo(cpu); |
| 82 | struct cacheinfo *this_leaf = this_cpu_ci->info_list; | 82 | struct cacheinfo *this_leaf = this_cpu_ci->info_list; |
| 83 | struct device_node *np = of_cpu_device_node_get(cpu); | 83 | struct device_node *np, *prev; |
| 84 | struct device_node *prev = NULL; | ||
| 85 | int levels = 1, level = 1; | 84 | int levels = 1, level = 1; |
| 86 | 85 | ||
| 87 | if (!acpi_disabled) { | 86 | if (!acpi_disabled) { |
| @@ -105,6 +104,10 @@ int populate_cache_leaves(unsigned int cpu) · 17 unmodified lines | |||
| 105 | return 0; | 104 | return 0; |
| 106 | } | 105 | } |
| 107 | 106 | ||
| 107 | np = of_cpu_device_node_get(cpu); | ||
| 108 | if (!np) | ||
| 109 | return -ENOENT; | ||
| 110 | |||
| 108 | if (of_property_read_bool(np, "cache-size")) | 111 | if (of_property_read_bool(np, "cache-size")) |
| 109 | ci_leaf_init(this_leaf++, CACHE_TYPE_UNIFIED, level); | 112 | ci_leaf_init(this_leaf++, CACHE_TYPE_UNIFIED, level); |
| 110 | if (of_property_read_bool(np, "i-cache-size")) | 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 | if (cpu_ops->cpu_is_stopped) | 58 | if (cpu_ops->cpu_is_stopped) |
| 59 | ret = cpu_ops->cpu_is_stopped(cpu); | 59 | ret = cpu_ops->cpu_is_stopped(cpu); |
| 60 | if (ret) | 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 | .long efi_header_end - _start // SizeOfHeaders | 64 | .long efi_header_end - _start // SizeOfHeaders |
| 65 | .long 0 // CheckSum | 65 | .long 0 // CheckSum |
| 66 | .short IMAGE_SUBSYSTEM_EFI_APPLICATION // Subsystem | 66 | .short IMAGE_SUBSYSTEM_EFI_APPLICATION // Subsystem |
| 67 | .short 0 // DllCharacteristics | 67 | .short IMAGE_DLL_CHARACTERISTICS_NX_COMPAT // DllCharacteristics |
| 68 | .quad 0 // SizeOfStackReserve | 68 | .quad 0 // SizeOfStackReserve |
| 69 | .quad 0 // SizeOfStackCommit | 69 | .quad 0 // SizeOfStackCommit |
| 70 | .quad 0 // SizeOfHeapReserve | 70 | .quad 0 // SizeOfHeapReserve |
| @@ -16,8 +16,12 @@ KBUILD_CFLAGS := $(filter-out $(CC_FLAGS_LTO), $(KBUILD_CFLAGS)) · 15 unmodified lines | |||
| 16 | KBUILD_CFLAGS += -mcmodel=medany | 16 | KBUILD_CFLAGS += -mcmodel=medany |
| 17 | 17 | ||
| 18 | CFLAGS_cmdline_early.o += -D__NO_FORTIFY | 18 | CFLAGS_cmdline_early.o += -D__NO_FORTIFY |
| 19 | CFLAGS_lib-fdt_ro.o += -D__NO_FORTIFY | ||
| 20 | CFLAGS_fdt_early.o += -D__NO_FORTIFY | 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 | $(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \ | 26 | $(obj)/%.pi.o: OBJCOPYFLAGS := --prefix-symbols=__pi_ \ |
| 23 | --remove-section=.note.gnu.property \ | 27 | --remove-section=.note.gnu.property \ |
| @@ -136,8 +136,6 @@ · 135 unmodified lines | |||
| 136 | #define REG_PTR(insn, pos, regs) \ | 136 | #define REG_PTR(insn, pos, regs) \ |
| 137 | (ulong *)((ulong)(regs) + REG_OFFSET(insn, pos)) | 137 | (ulong *)((ulong)(regs) + REG_OFFSET(insn, pos)) |
| 138 | 138 | ||
| 139 | #define GET_RM(insn) (((insn) >> 12) & 7) | ||
| 140 | |||
| 141 | #define GET_RS1(insn, regs) (*REG_PTR(insn, SH_RS1, regs)) | 139 | #define GET_RS1(insn, regs) (*REG_PTR(insn, SH_RS1, regs)) |
| 142 | #define GET_RS2(insn, regs) (*REG_PTR(insn, SH_RS2, regs)) | 140 | #define GET_RS2(insn, regs) (*REG_PTR(insn, SH_RS2, regs)) |
| 143 | #define GET_RS1S(insn, regs) (*REG_PTR(RVC_RS1S(insn), 0, regs)) | 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 | ccflags-y := -fno-stack-protector | 19 | ccflags-y := -fno-stack-protector |
| 20 | ccflags-y += -DDISABLE_BRANCH_PROFILING | 20 | ccflags-y += -DDISABLE_BRANCH_PROFILING |
| 21 | ccflags-y += -fno-builtin | ||
| 21 | 22 | ||
| 22 | ifneq ($(c-gettimeofday-y),) | 23 | ifneq ($(c-gettimeofday-y),) |
| 23 | CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y) | 24 | CFLAGS_vgettimeofday.o += -fPIC -include $(c-gettimeofday-y) |
| @@ -55,7 +55,7 @@ struct imsic { · 54 unmodified lines | |||
| 55 | /* IMSIC SW-file */ | 55 | /* IMSIC SW-file */ |
| 56 | struct imsic_mrif *swfile; | 56 | struct imsic_mrif *swfile; |
| 57 | phys_addr_t swfile_pa; | 57 | phys_addr_t swfile_pa; |
| 58 | spinlock_t swfile_extirq_lock; | 58 | raw_spinlock_t swfile_extirq_lock; |
| 59 | }; | 59 | }; |
| 60 | 60 | ||
| 61 | #define imsic_vs_csr_read(__c) \ | 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 | * interruptions between reading topei and updating pending status. | 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 | if (imsic_mrif_atomic_read(mrif, &mrif->eidelivery) && | 627 | if (imsic_mrif_atomic_read(mrif, &mrif->eidelivery) && |
| 628 | imsic_mrif_topei(mrif, imsic->nr_eix, imsic->nr_msis)) | 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 | else | 630 | else |
| 631 | kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_EXT); | 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 | static void imsic_swfile_read(struct kvm_vcpu *vcpu, bool clear, | 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 | imsic->swfile = page_to_virt(swfile_page); | 1052 | imsic->swfile = page_to_virt(swfile_page); |
| 1053 | imsic->swfile_pa = page_to_phys(swfile_page); | 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 | /* Setup IO device */ | 1056 | /* Setup IO device */ |
| 1057 | kvm_iodevice_init(&imsic->iodev, &imsic_iodoev_ops); | 1057 | kvm_iodevice_init(&imsic->iodev, &imsic_iodoev_ops); |
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | #define RV_MAX_REG_ARGS 8 | 18 | #define RV_MAX_REG_ARGS 8 |
| 19 | #define RV_FENTRY_NINSNS 2 | 19 | #define RV_FENTRY_NINSNS 2 |
| 20 | #define RV_FENTRY_NBYTES (RV_FENTRY_NINSNS * 4) | 20 | #define RV_FENTRY_NBYTES (RV_FENTRY_NINSNS * 4) |
| 21 | #define RV_KCFI_NINSNS (IS_ENABLED(CONFIG_CFI_CLANG) ? 1 : 0) | ||
| 21 | /* imm that allows emit_imm to emit max count insns */ | 22 | /* imm that allows emit_imm to emit max count insns */ |
| 22 | #define RV_MAX_COUNT_IMM 0x7FFF7FF7FF7FF7FF | 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 | if (!is_tail_call) | 272 | if (!is_tail_call) |
| 272 | emit_addiw(RV_REG_A0, RV_REG_A5, 0, ctx); | 273 | emit_addiw(RV_REG_A0, RV_REG_A5, 0, ctx); |
| 273 | emit_jalr(RV_REG_ZERO, is_tail_call ? RV_REG_T3 : RV_REG_RA, | 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 | ctx); | 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 | rv_lr_w(r0, 0, rd, 0, 0), ctx); | 550 | rv_lr_w(r0, 0, rd, 0, 0), ctx); |
| 549 | jmp_offset = ninsns_rvoff(8); | 551 | jmp_offset = ninsns_rvoff(8); |
| 550 | emit(rv_bne(RV_REG_T2, r0, jmp_offset >> 1), ctx); | 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) : | 553 | emit(is64 ? rv_sc_d(RV_REG_T3, rs, rd, 0, 1) : |
| 552 | rv_sc_w(RV_REG_T3, rs, rd, 0, 0), ctx); | 554 | rv_sc_w(RV_REG_T3, rs, rd, 0, 1), ctx); |
| 553 | jmp_offset = ninsns_rvoff(-6); | 555 | jmp_offset = ninsns_rvoff(-6); |
| 554 | emit(rv_bne(RV_REG_T3, 0, jmp_offset >> 1), ctx); | 556 | emit(rv_bne(RV_REG_T3, 0, jmp_offset >> 1), ctx); |
| 555 | emit(rv_fence(0x3, 0x3), ctx); | 557 | emit(rv_fence(0x3, 0x3), ctx); |
| @@ -50,7 +50,6 @@ CONFIG_NUMA=y · 49 unmodified lines | |||
| 50 | CONFIG_HZ_100=y | 50 | CONFIG_HZ_100=y |
| 51 | CONFIG_CERT_STORE=y | 51 | CONFIG_CERT_STORE=y |
| 52 | CONFIG_EXPOLINE=y | 52 | CONFIG_EXPOLINE=y |
| 53 | # CONFIG_EXPOLINE_EXTERN is not set | ||
| 54 | CONFIG_EXPOLINE_AUTO=y | 53 | CONFIG_EXPOLINE_AUTO=y |
| 55 | CONFIG_CHSC_SCH=y | 54 | CONFIG_CHSC_SCH=y |
| 56 | CONFIG_VFIO_CCW=m | 55 | CONFIG_VFIO_CCW=m |
| @@ -95,6 +94,7 @@ CONFIG_BINFMT_MISC=m · 38 unmodified lines | |||
| 95 | CONFIG_ZSWAP=y | 94 | CONFIG_ZSWAP=y |
| 96 | CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y | 95 | CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y |
| 97 | CONFIG_ZSMALLOC_STAT=y | 96 | CONFIG_ZSMALLOC_STAT=y |
| 97 | CONFIG_SLAB_BUCKETS=y | ||
| 98 | CONFIG_SLUB_STATS=y | 98 | CONFIG_SLUB_STATS=y |
| 99 | # CONFIG_COMPAT_BRK is not set | 99 | # CONFIG_COMPAT_BRK is not set |
| 100 | CONFIG_MEMORY_HOTPLUG=y | 100 | CONFIG_MEMORY_HOTPLUG=y |
| @@ -426,6 +426,13 @@ CONFIG_DEVTMPFS_SAFE=y · 325 unmodified lines | |||
| 426 | # CONFIG_FW_LOADER is not set | 426 | # CONFIG_FW_LOADER is not set |
| 427 | CONFIG_CONNECTOR=y | 427 | CONFIG_CONNECTOR=y |
| 428 | CONFIG_ZRAM=y | 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 | CONFIG_BLK_DEV_LOOP=m | 436 | CONFIG_BLK_DEV_LOOP=m |
| 430 | CONFIG_BLK_DEV_DRBD=m | 437 | CONFIG_BLK_DEV_DRBD=m |
| 431 | CONFIG_BLK_DEV_NBD=m | 438 | CONFIG_BLK_DEV_NBD=m |
| @@ -486,6 +493,7 @@ CONFIG_DM_UEVENT=y · 54 unmodified lines | |||
| 486 | CONFIG_DM_FLAKEY=m | 493 | CONFIG_DM_FLAKEY=m |
| 487 | CONFIG_DM_VERITY=m | 494 | CONFIG_DM_VERITY=m |
| 488 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y | 495 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y |
| 496 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING=y | ||
| 489 | CONFIG_DM_SWITCH=m | 497 | CONFIG_DM_SWITCH=m |
| 490 | CONFIG_DM_INTEGRITY=m | 498 | CONFIG_DM_INTEGRITY=m |
| 491 | CONFIG_DM_VDO=m | 499 | CONFIG_DM_VDO=m |
| @@ -535,6 +543,7 @@ CONFIG_NLMON=m · 43 unmodified lines | |||
| 535 | CONFIG_MLX4_EN=m | 543 | CONFIG_MLX4_EN=m |
| 536 | CONFIG_MLX5_CORE=m | 544 | CONFIG_MLX5_CORE=m |
| 537 | CONFIG_MLX5_CORE_EN=y | 545 | CONFIG_MLX5_CORE_EN=y |
| 546 | # CONFIG_NET_VENDOR_META is not set | ||
| 538 | # CONFIG_NET_VENDOR_MICREL is not set | 547 | # CONFIG_NET_VENDOR_MICREL is not set |
| 539 | # CONFIG_NET_VENDOR_MICROCHIP is not set | 548 | # CONFIG_NET_VENDOR_MICROCHIP is not set |
| 540 | # CONFIG_NET_VENDOR_MICROSEMI is not set | 549 | # CONFIG_NET_VENDOR_MICROSEMI is not set |
| @@ -695,6 +704,7 @@ CONFIG_NFSD=m · 154 unmodified lines | |||
| 695 | CONFIG_NFSD_V3_ACL=y | 704 | CONFIG_NFSD_V3_ACL=y |
| 696 | CONFIG_NFSD_V4=y | 705 | CONFIG_NFSD_V4=y |
| 697 | CONFIG_NFSD_V4_SECURITY_LABEL=y | 706 | CONFIG_NFSD_V4_SECURITY_LABEL=y |
| 707 | # CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set | ||
| 698 | CONFIG_CIFS=m | 708 | CONFIG_CIFS=m |
| 699 | CONFIG_CIFS_UPCALL=y | 709 | CONFIG_CIFS_UPCALL=y |
| 700 | CONFIG_CIFS_XATTR=y | 710 | CONFIG_CIFS_XATTR=y |
| @@ -740,7 +750,6 @@ CONFIG_CRYPTO_DH=m · 39 unmodified lines | |||
| 740 | CONFIG_CRYPTO_ECDH=m | 750 | CONFIG_CRYPTO_ECDH=m |
| 741 | CONFIG_CRYPTO_ECDSA=m | 751 | CONFIG_CRYPTO_ECDSA=m |
| 742 | CONFIG_CRYPTO_ECRDSA=m | 752 | CONFIG_CRYPTO_ECRDSA=m |
| 743 | CONFIG_CRYPTO_SM2=m | ||
| 744 | CONFIG_CRYPTO_CURVE25519=m | 753 | CONFIG_CRYPTO_CURVE25519=m |
| 745 | CONFIG_CRYPTO_AES_TI=m | 754 | CONFIG_CRYPTO_AES_TI=m |
| 746 | CONFIG_CRYPTO_ANUBIS=m | 755 | CONFIG_CRYPTO_ANUBIS=m |
| @@ -48,7 +48,6 @@ CONFIG_NUMA=y · 47 unmodified lines | |||
| 48 | CONFIG_HZ_100=y | 48 | CONFIG_HZ_100=y |
| 49 | CONFIG_CERT_STORE=y | 49 | CONFIG_CERT_STORE=y |
| 50 | CONFIG_EXPOLINE=y | 50 | CONFIG_EXPOLINE=y |
| 51 | # CONFIG_EXPOLINE_EXTERN is not set | ||
| 52 | CONFIG_EXPOLINE_AUTO=y | 51 | CONFIG_EXPOLINE_AUTO=y |
| 53 | CONFIG_CHSC_SCH=y | 52 | CONFIG_CHSC_SCH=y |
| 54 | CONFIG_VFIO_CCW=m | 53 | CONFIG_VFIO_CCW=m |
| @@ -89,6 +88,7 @@ CONFIG_BINFMT_MISC=m · 34 unmodified lines | |||
| 89 | CONFIG_ZSWAP=y | 88 | CONFIG_ZSWAP=y |
| 90 | CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y | 89 | CONFIG_ZSWAP_ZPOOL_DEFAULT_ZBUD=y |
| 91 | CONFIG_ZSMALLOC_STAT=y | 90 | CONFIG_ZSMALLOC_STAT=y |
| 91 | CONFIG_SLAB_BUCKETS=y | ||
| 92 | # CONFIG_COMPAT_BRK is not set | 92 | # CONFIG_COMPAT_BRK is not set |
| 93 | CONFIG_MEMORY_HOTPLUG=y | 93 | CONFIG_MEMORY_HOTPLUG=y |
| 94 | CONFIG_MEMORY_HOTREMOVE=y | 94 | CONFIG_MEMORY_HOTREMOVE=y |
| @@ -416,6 +416,13 @@ CONFIG_DEVTMPFS_SAFE=y · 321 unmodified lines | |||
| 416 | # CONFIG_FW_LOADER is not set | 416 | # CONFIG_FW_LOADER is not set |
| 417 | CONFIG_CONNECTOR=y | 417 | CONFIG_CONNECTOR=y |
| 418 | CONFIG_ZRAM=y | 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 | CONFIG_BLK_DEV_LOOP=m | 426 | CONFIG_BLK_DEV_LOOP=m |
| 420 | CONFIG_BLK_DEV_DRBD=m | 427 | CONFIG_BLK_DEV_DRBD=m |
| 421 | CONFIG_BLK_DEV_NBD=m | 428 | CONFIG_BLK_DEV_NBD=m |
| @@ -476,6 +483,7 @@ CONFIG_DM_UEVENT=y · 54 unmodified lines | |||
| 476 | CONFIG_DM_FLAKEY=m | 483 | CONFIG_DM_FLAKEY=m |
| 477 | CONFIG_DM_VERITY=m | 484 | CONFIG_DM_VERITY=m |
| 478 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y | 485 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG=y |
| 486 | CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG_PLATFORM_KEYRING=y | ||
| 479 | CONFIG_DM_SWITCH=m | 487 | CONFIG_DM_SWITCH=m |
| 480 | CONFIG_DM_INTEGRITY=m | 488 | CONFIG_DM_INTEGRITY=m |
| 481 | CONFIG_DM_VDO=m | 489 | CONFIG_DM_VDO=m |
| @@ -525,6 +533,7 @@ CONFIG_NLMON=m · 43 unmodified lines | |||
| 525 | CONFIG_MLX4_EN=m | 533 | CONFIG_MLX4_EN=m |
| 526 | CONFIG_MLX5_CORE=m | 534 | CONFIG_MLX5_CORE=m |
| 527 | CONFIG_MLX5_CORE_EN=y | 535 | CONFIG_MLX5_CORE_EN=y |
| 536 | # CONFIG_NET_VENDOR_META is not set | ||
| 528 | # CONFIG_NET_VENDOR_MICREL is not set | 537 | # CONFIG_NET_VENDOR_MICREL is not set |
| 529 | # CONFIG_NET_VENDOR_MICROCHIP is not set | 538 | # CONFIG_NET_VENDOR_MICROCHIP is not set |
| 530 | # CONFIG_NET_VENDOR_MICROSEMI is not set | 539 | # CONFIG_NET_VENDOR_MICROSEMI is not set |
| @@ -682,6 +691,7 @@ CONFIG_NFSD=m · 151 unmodified lines | |||
| 682 | CONFIG_NFSD_V3_ACL=y | 691 | CONFIG_NFSD_V3_ACL=y |
| 683 | CONFIG_NFSD_V4=y | 692 | CONFIG_NFSD_V4=y |
| 684 | CONFIG_NFSD_V4_SECURITY_LABEL=y | 693 | CONFIG_NFSD_V4_SECURITY_LABEL=y |
| 694 | # CONFIG_NFSD_LEGACY_CLIENT_TRACKING is not set | ||
| 685 | CONFIG_CIFS=m | 695 | CONFIG_CIFS=m |
| 686 | CONFIG_CIFS_UPCALL=y | 696 | CONFIG_CIFS_UPCALL=y |
| 687 | CONFIG_CIFS_XATTR=y | 697 | CONFIG_CIFS_XATTR=y |
| @@ -726,7 +736,6 @@ CONFIG_CRYPTO_DH=m · 38 unmodified lines | |||
| 726 | CONFIG_CRYPTO_ECDH=m | 736 | CONFIG_CRYPTO_ECDH=m |
| 727 | CONFIG_CRYPTO_ECDSA=m | 737 | CONFIG_CRYPTO_ECDSA=m |
| 728 | CONFIG_CRYPTO_ECRDSA=m | 738 | CONFIG_CRYPTO_ECRDSA=m |
| 729 | CONFIG_CRYPTO_SM2=m | ||
| 730 | CONFIG_CRYPTO_CURVE25519=m | 739 | CONFIG_CRYPTO_CURVE25519=m |
| 731 | CONFIG_CRYPTO_AES_TI=m | 740 | CONFIG_CRYPTO_AES_TI=m |
| 732 | CONFIG_CRYPTO_ANUBIS=m | 741 | CONFIG_CRYPTO_ANUBIS=m |
| @@ -767,6 +776,7 @@ CONFIG_CRYPTO_LZ4=m · 34 unmodified lines | |||
| 767 | CONFIG_CRYPTO_LZ4HC=m | 776 | CONFIG_CRYPTO_LZ4HC=m |
| 768 | CONFIG_CRYPTO_ZSTD=m | 777 | CONFIG_CRYPTO_ZSTD=m |
| 769 | CONFIG_CRYPTO_ANSI_CPRNG=m | 778 | CONFIG_CRYPTO_ANSI_CPRNG=m |
| 779 | CONFIG_CRYPTO_JITTERENTROPY_OSR=1 | ||
| 770 | CONFIG_CRYPTO_USER_API_HASH=m | 780 | CONFIG_CRYPTO_USER_API_HASH=m |
| 771 | CONFIG_CRYPTO_USER_API_SKCIPHER=m | 781 | CONFIG_CRYPTO_USER_API_SKCIPHER=m |
| 772 | CONFIG_CRYPTO_USER_API_RNG=m | 782 | CONFIG_CRYPTO_USER_API_RNG=m |
| @@ -49,6 +49,7 @@ CONFIG_ZFCP=y · 48 unmodified lines | |||
| 49 | # CONFIG_HVC_IUCV is not set | 49 | # CONFIG_HVC_IUCV is not set |
| 50 | # CONFIG_HW_RANDOM_S390 is not set | 50 | # CONFIG_HW_RANDOM_S390 is not set |
| 51 | # CONFIG_HMC_DRV is not set | 51 | # CONFIG_HMC_DRV is not set |
| 52 | # CONFIG_S390_UV_UAPI is not set | ||
| 52 | # CONFIG_S390_TAPE is not set | 53 | # CONFIG_S390_TAPE is not set |
| 53 | # CONFIG_VMCP is not set | 54 | # CONFIG_VMCP is not set |
| 54 | # CONFIG_MONWRITER is not set | 55 | # CONFIG_MONWRITER is not set |
| @@ -16,8 +16,10 @@ · 15 unmodified lines | |||
| 16 | #include <asm/pci_io.h> | 16 | #include <asm/pci_io.h> |
| 17 | 17 | ||
| 18 | #define xlate_dev_mem_ptr xlate_dev_mem_ptr | 18 | #define xlate_dev_mem_ptr xlate_dev_mem_ptr |
| 19 | #define kc_xlate_dev_mem_ptr xlate_dev_mem_ptr | ||
| 19 | void *xlate_dev_mem_ptr(phys_addr_t phys); | 20 | void *xlate_dev_mem_ptr(phys_addr_t phys); |
| 20 | #define unxlate_dev_mem_ptr unxlate_dev_mem_ptr | 21 | #define unxlate_dev_mem_ptr unxlate_dev_mem_ptr |
| 22 | #define kc_unxlate_dev_mem_ptr unxlate_dev_mem_ptr | ||
| 21 | void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr); | 23 | void unxlate_dev_mem_ptr(phys_addr_t phys, void *addr); |
| 22 | 24 | ||
| 23 | #define IO_SPACE_LIMIT 0 | 25 | #define IO_SPACE_LIMIT 0 |
| @@ -49,6 +49,7 @@ struct perf_sf_sde_regs { · 48 unmodified lines | |||
| 49 | }; | 49 | }; |
| 50 | 50 | ||
| 51 | #define perf_arch_fetch_caller_regs(regs, __ip) do { \ | 51 | #define perf_arch_fetch_caller_regs(regs, __ip) do { \ |
| 52 | (regs)->psw.mask = 0; \ | ||
| 52 | (regs)->psw.addr = (__ip); \ | 53 | (regs)->psw.addr = (__ip); \ |
| 53 | (regs)->gprs[15] = (unsigned long)__builtin_frame_address(0) - \ | 54 | (regs)->gprs[15] = (unsigned long)__builtin_frame_address(0) - \ |
| 54 | offsetof(struct stack_frame, back_chain); \ | 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 | vcpu->stat.instruction_diagnose_258++; | 77 | vcpu->stat.instruction_diagnose_258++; |
| 78 | if (vcpu->run->s.regs.gprs[rx] & 7) | 78 | if (vcpu->run->s.regs.gprs[rx] & 7) |
| 79 | return kvm_s390_inject_program_int(vcpu, PGM_SPECIFICATION); | 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 | if (rc) | 81 | if (rc) |
| 82 | return kvm_s390_inject_prog_cond(vcpu, rc); | 82 | return kvm_s390_inject_prog_cond(vcpu, rc); |
| 83 | if (parm.parm_version != 2 || parm.parm_len < 5 || parm.code != 0x258) | 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 | const gfn_t gfn = gpa_to_gfn(gpa); | 828 | const gfn_t gfn = gpa_to_gfn(gpa); |
| 829 | int rc; | 829 | int rc; |
| 830 | 830 | ||
| 831 | if (!gfn_to_memslot(kvm, gfn)) | ||
| 832 | return PGM_ADDRESSING; | ||
| 831 | if (mode == GACC_STORE) | 833 | if (mode == GACC_STORE) |
| 832 | rc = kvm_write_guest_page(kvm, gfn, data, offset, len); | 834 | rc = kvm_write_guest_page(kvm, gfn, data, offset, len); |
| 833 | else | 835 | else |
| @@ -985,6 +987,8 @@ int access_guest_real(struct kvm_vcpu *vcpu, unsigned long gra, · 151 unmodified lines | |||
| 985 | gra += fragment_len; | 987 | gra += fragment_len; |
| 986 | data += fragment_len; | 988 | data += fragment_len; |
| 987 | } | 989 | } |
| 990 | if (rc > 0) | ||
| 991 | vcpu->arch.pgm.code = rc; | ||
| 988 | return rc; | 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 | * @len: number of bytes to copy | 405 | * @len: number of bytes to copy |
| 406 | * | 406 | * |
| 407 | * Copy @len bytes from @data (kernel space) to @gra (guest real address). | 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 | * Guest low address and key protection are not checked. | 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 | * If an error occurs data may have been copied partially to guest memory. | 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 | * @len: number of bytes to copy | 429 | * @len: number of bytes to copy |
| 429 | * | 430 | * |
| 430 | * Copy @len bytes from @gra (guest real address) to @data (kernel space). | 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 | * Guest key protection is not checked. | 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 | * If an error occurs data may have been copied partially to kernel space. | 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 | goto no_pdev; | 280 | goto no_pdev; |
| 281 | 281 | ||
| 282 | switch (ccdf->pec) { | 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 | ers_res = zpci_event_attempt_error_recovery(pdev); | 292 | ers_res = zpci_event_attempt_error_recovery(pdev); |
| 285 | if (ers_res != PCI_ERS_RESULT_RECOVERED) | 293 | if (ers_res != PCI_ERS_RESULT_RECOVERED) |
| 286 | zpci_event_io_failure(pdev, pci_channel_io_perm_failure); | 294 | zpci_event_io_failure(pdev, pci_channel_io_perm_failure); |
| 287 | break; | 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 | pci_dev_put(pdev); | 297 | pci_dev_put(pdev); |
| 297 | no_pdev: | 298 | no_pdev: |
| @@ -2257,6 +2257,7 @@ config RANDOMIZE_MEMORY_PHYSICAL_PADDING · 2256 unmodified lines | |||
| 2257 | config ADDRESS_MASKING | 2257 | config ADDRESS_MASKING |
| 2258 | bool "Linear Address Masking support" | 2258 | bool "Linear Address Masking support" |
| 2259 | depends on X86_64 | 2259 | depends on X86_64 |
| 2260 | depends on COMPILE_TEST || !CPU_MITIGATIONS # wait for LASS | ||
| 2260 | help | 2261 | help |
| 2261 | Linear Address Masking (LAM) modifies the checking that is applied | 2262 | Linear Address Masking (LAM) modifies the checking that is applied |
| 2262 | to 64-bit linear addresses, allowing software to use of the | 2263 | to 64-bit linear addresses, allowing software to use of the |
| @@ -9,6 +9,8 @@ · 8 unmodified lines | |||
| 9 | #include <asm/unwind_hints.h> | 9 | #include <asm/unwind_hints.h> |
| 10 | #include <asm/segment.h> | 10 | #include <asm/segment.h> |
| 11 | #include <asm/cache.h> | 11 | #include <asm/cache.h> |
| 12 | #include <asm/cpufeatures.h> | ||
| 13 | #include <asm/nospec-branch.h> | ||
| 12 | 14 | ||
| 13 | #include "calling.h" | 15 | #include "calling.h" |
| 14 | 16 | ||
| @@ -19,6 +21,9 @@ SYM_FUNC_START(entry_ibpb) · 4 unmodified lines | |||
| 19 | movl $PRED_CMD_IBPB, %eax | 21 | movl $PRED_CMD_IBPB, %eax |
| 20 | xorl %edx, %edx | 22 | xorl %edx, %edx |
| 21 | wrmsr | 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 | RET | 27 | RET |
| 23 | SYM_FUNC_END(entry_ibpb) | 28 | SYM_FUNC_END(entry_ibpb) |
| 24 | /* For KVM */ | 29 | /* For KVM */ |
| @@ -871,6 +871,8 @@ SYM_FUNC_START(entry_SYSENTER_32) · 870 unmodified lines | |||
| 871 | 871 | ||
| 872 | /* Now ready to switch the cr3 */ | 872 | /* Now ready to switch the cr3 */ |
| 873 | SWITCH_TO_USER_CR3 scratch_reg=%eax | 873 | SWITCH_TO_USER_CR3 scratch_reg=%eax |
| 874 | /* Clobbers ZF */ | ||
| 875 | CLEAR_CPU_BUFFERS | ||
| 874 | 876 | ||
| 875 | /* | 877 | /* |
| 876 | * Restore all flags except IF. (We restore IF separately because | 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 | BUG_IF_WRONG_CR3 no_user_check=1 | 883 | BUG_IF_WRONG_CR3 no_user_check=1 |
| 882 | popfl | 884 | popfl |
| 883 | popl %eax | 885 | popl %eax |
| 884 | CLEAR_CPU_BUFFERS | ||
| 885 | 886 | ||
| 886 | /* | 887 | /* |
| 887 | * Return back to the vDSO, which will pop ecx and edx. | 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 | /* Not on SYSENTER stack. */ | 1146 | /* Not on SYSENTER stack. */ |
| 1146 | call exc_nmi | 1147 | call exc_nmi |
| 1147 | CLEAR_CPU_BUFFERS | ||
| 1148 | jmp .Lnmi_return | 1148 | jmp .Lnmi_return |
| 1149 | 1149 | ||
| 1150 | .Lnmi_from_sysenter_stack: | 1150 | .Lnmi_from_sysenter_stack: |
| @@ -1165,6 +1165,7 @@ SYM_CODE_START(asm_exc_nmi) · 14 unmodified lines | |||
| 1165 | 1165 | ||
| 1166 | CHECK_AND_APPLY_ESPFIX | 1166 | CHECK_AND_APPLY_ESPFIX |
| 1167 | RESTORE_ALL_NMI cr3_reg=%edi pop=4 | 1167 | RESTORE_ALL_NMI cr3_reg=%edi pop=4 |
| 1168 | CLEAR_CPU_BUFFERS | ||
| 1168 | jmp .Lirq_return | 1169 | jmp .Lirq_return |
| 1169 | 1170 | ||
| 1170 | #ifdef CONFIG_X86_ESPFIX32 | 1171 | #ifdef CONFIG_X86_ESPFIX32 |
| @@ -1206,6 +1207,7 @@ SYM_CODE_START(asm_exc_nmi) · 35 unmodified lines | |||
| 1206 | * 1 - orig_ax | 1207 | * 1 - orig_ax |
| 1207 | */ | 1208 | */ |
| 1208 | lss (1+5+6)*4(%esp), %esp # back to espfix stack | 1209 | lss (1+5+6)*4(%esp), %esp # back to espfix stack |
| 1210 | CLEAR_CPU_BUFFERS | ||
| 1209 | jmp .Lirq_return | 1211 | jmp .Lirq_return |
| 1210 | #endif | 1212 | #endif |
| 1211 | SYM_CODE_END(asm_exc_nmi) | 1213 | SYM_CODE_END(asm_exc_nmi) |
| @@ -116,7 +116,10 @@ static inline bool amd_gart_present(void) · 115 unmodified lines | |||
| 116 | 116 | ||
| 117 | #define amd_nb_num(x) 0 | 117 | #define amd_nb_num(x) 0 |
| 118 | #define amd_nb_has_feature(x) false | 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 | #define amd_gart_present(x) false | 123 | #define amd_gart_present(x) false |
| 121 | 124 | ||
| 122 | #endif | 125 | #endif |
| @@ -215,7 +215,7 @@ · 214 unmodified lines | |||
| 215 | #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* Disable Speculative Store Bypass. */ | 215 | #define X86_FEATURE_SPEC_STORE_BYPASS_DISABLE ( 7*32+23) /* Disable Speculative Store Bypass. */ |
| 216 | #define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* AMD SSBD implementation via LS_CFG MSR */ | 216 | #define X86_FEATURE_LS_CFG_SSBD ( 7*32+24) /* AMD SSBD implementation via LS_CFG MSR */ |
| 217 | #define X86_FEATURE_IBRS ( 7*32+25) /* "ibrs" Indirect Branch Restricted Speculation */ | 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 | #define X86_FEATURE_STIBP ( 7*32+27) /* "stibp" Single Thread Indirect Branch Predictors */ | 219 | #define X86_FEATURE_STIBP ( 7*32+27) /* "stibp" Single Thread Indirect Branch Predictors */ |
| 220 | #define X86_FEATURE_ZEN ( 7*32+28) /* Generic flag for all Zen and newer */ | 220 | #define X86_FEATURE_ZEN ( 7*32+28) /* Generic flag for all Zen and newer */ |
| 221 | #define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* L1TF workaround PTE inversion */ | 221 | #define X86_FEATURE_L1TF_PTEINV ( 7*32+29) /* L1TF workaround PTE inversion */ |
| @@ -348,6 +348,7 @@ · 126 unmodified lines | |||
| 348 | #define X86_FEATURE_CPPC (13*32+27) /* "cppc" Collaborative Processor Performance Control */ | 348 | #define X86_FEATURE_CPPC (13*32+27) /* "cppc" Collaborative Processor Performance Control */ |
| 349 | #define X86_FEATURE_AMD_PSFD (13*32+28) /* Predictive Store Forwarding Disable */ | 349 | #define X86_FEATURE_AMD_PSFD (13*32+28) /* Predictive Store Forwarding Disable */ |
| 350 | #define X86_FEATURE_BTC_NO (13*32+29) /* Not vulnerable to Branch Type Confusion */ | 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 | #define X86_FEATURE_BRS (13*32+31) /* "brs" Branch Sampling available */ | 352 | #define X86_FEATURE_BRS (13*32+31) /* "brs" Branch Sampling available */ |
| 352 | 353 | ||
| 353 | /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ | 354 | /* Thermal and Power Management Leaf, CPUID level 0x00000006 (EAX), word 14 */ |
| @@ -523,4 +524,5 @@ · 169 unmodified lines | |||
| 523 | #define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* "div0" AMD DIV0 speculation bug */ | 524 | #define X86_BUG_DIV0 X86_BUG(1*32 + 1) /* "div0" AMD DIV0 speculation bug */ |
| 524 | #define X86_BUG_RFDS X86_BUG(1*32 + 2) /* "rfds" CPU is vulnerable to Register File Data Sampling */ | 525 | #define X86_BUG_RFDS X86_BUG(1*32 + 2) /* "rfds" CPU is vulnerable to Register File Data Sampling */ |
| 525 | #define X86_BUG_BHI X86_BUG(1*32 + 3) /* "bhi" CPU is affected by Branch History Injection */ | 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 | #endif /* _ASM_X86_CPUFEATURES_H */ | 528 | #endif /* _ASM_X86_CPUFEATURES_H */ |
| @@ -323,7 +323,16 @@ · 322 unmodified lines | |||
| 323 | * Note: Only the memory operand variant of VERW clears the CPU buffers. | 323 | * Note: Only the memory operand variant of VERW clears the CPU buffers. |
| 324 | */ | 324 | */ |
| 325 | .macro CLEAR_CPU_BUFFERS | 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 | .endm | 336 | .endm |
| 328 | 337 | ||
| 329 | #ifdef CONFIG_X86_64 | 338 | #ifdef CONFIG_X86_64 |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | |||
| 6 | typeof(sym) __ret; \ | 6 | typeof(sym) __ret; \ |
| 7 | asm_inline("mov %1,%0\n1:\n" \ | 7 | asm_inline("mov %1,%0\n1:\n" \ |
| 8 | ".pushsection runtime_ptr_" #sym ",\"a\"\n\t" \ | 8 | ".pushsection runtime_ptr_" #sym ",\"a\"\n\t" \ |
| 9 | ".long 1b - %c2 - .\n\t" \ | 9 | ".long 1b - %c2 - .\n" \ |
| 10 | ".popsection" \ | 10 | ".popsection" \ |
| 11 | :"=r" (__ret) \ | 11 | :"=r" (__ret) \ |
| 12 | :"i" ((unsigned long)0x0123456789abcdefull), \ | 12 | :"i" ((unsigned long)0x0123456789abcdefull), \ |
| @@ -20,7 +20,7 @@ · 7 unmodified lines | |||
| 20 | typeof(0u+(val)) __ret = (val); \ | 20 | typeof(0u+(val)) __ret = (val); \ |
| 21 | asm_inline("shrl $12,%k0\n1:\n" \ | 21 | asm_inline("shrl $12,%k0\n1:\n" \ |
| 22 | ".pushsection runtime_shift_" #sym ",\"a\"\n\t" \ | 22 | ".pushsection runtime_shift_" #sym ",\"a\"\n\t" \ |
| 23 | ".long 1b - 1 - .\n\t" \ | 23 | ".long 1b - 1 - .\n" \ |
| 24 | ".popsection" \ | 24 | ".popsection" \ |
| 25 | :"+r" (__ret)); \ | 25 | :"+r" (__ret)); \ |
| 26 | __ret; }) | 26 | __ret; }) |
| @@ -12,6 +12,13 @@ · 11 unmodified lines | |||
| 12 | #include <asm/cpufeatures.h> | 12 | #include <asm/cpufeatures.h> |
| 13 | #include <asm/page.h> | 13 | #include <asm/page.h> |
| 14 | #include <asm/percpu.h> | 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 | #ifdef CONFIG_ADDRESS_MASKING | 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 | #endif | 54 | #endif |
| 48 | 55 | ||
| 49 | /* | 56 | #define valid_user_address(x) \ |
| 50 | * The virtual address space space is logically divided into a kernel | 57 | ((__force unsigned long)(x) <= runtime_const_ptr(USER_PTR_MAX)) |
| 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) | ||
| 55 | 58 | ||
| 56 | /* | 59 | /* |
| 57 | * Masking the user address is an alternative to a conditional | 60 | * Masking the user address is an alternative to a conditional |
| 58 | * user_access_begin that can avoid the fencing. This only works | 61 | * user_access_begin that can avoid the fencing. This only works |
| 59 | * for dense accesses starting at the address. | 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 | #define masked_user_access_begin(x) ({ \ | 74 | #define masked_user_access_begin(x) ({ \ |
| 63 | __auto_type __masked_ptr = (x); \ | 75 | __auto_type __masked_ptr = (x); \ |
| 64 | __masked_ptr = mask_user_address(__masked_ptr); \ | 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 | * arbitrary values in those bits rather then masking them off. | 81 | * arbitrary values in those bits rather then masking them off. |
| 70 | * | 82 | * |
| 71 | * Enforce two rules: | 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 | * 2. 'ptr+size' must not overflow into kernel addresses | 85 | * 2. 'ptr+size' must not overflow into kernel addresses |
| 74 | * | 86 | * |
| 75 | * Note that addresses around the sign change are not valid addresses, | 87 | * Note that we always have at least one guard page between the |
| 76 | * and will GP-fault even with LAM enabled if the sign bit is set (see | 88 | * max user address and the non-canonical gap, allowing us to |
| 77 | * "CR3.LAM_SUP" that can narrow the canonicality check if we ever | 89 | * ignore small sizes entirely. |
| 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. | ||
| 83 | * | 90 | * |
| 84 | * In fact, we could probably remove the size check entirely, since | 91 | * In fact, we could probably remove the size check entirely, since |
| 85 | * any kernel accesses will be in increasing address order starting | 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 | 93 | * at 'ptr'. |
| 87 | * hit the GP faults for non-canonical accesses before we ever get | ||
| 88 | * there. | ||
| 89 | * | 94 | * |
| 90 | * That's a separate optimization, for now just handle the small | 95 | * That's a separate optimization, for now just handle the small |
| 91 | * constant case. | 96 | * constant case. |
| @@ -44,6 +44,7 @@ · 43 unmodified lines | |||
| 44 | #define PCI_DEVICE_ID_AMD_19H_M70H_DF_F4 0x14f4 | 44 | #define PCI_DEVICE_ID_AMD_19H_M70H_DF_F4 0x14f4 |
| 45 | #define PCI_DEVICE_ID_AMD_19H_M78H_DF_F4 0x12fc | 45 | #define PCI_DEVICE_ID_AMD_19H_M78H_DF_F4 0x12fc |
| 46 | #define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4 0x12c4 | 46 | #define PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4 0x12c4 |
| 47 | #define PCI_DEVICE_ID_AMD_1AH_M20H_DF_F4 0x16fc | ||
| 47 | #define PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4 0x124c | 48 | #define PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4 0x124c |
| 48 | #define PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4 0x12bc | 49 | #define PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4 0x12bc |
| 49 | #define PCI_DEVICE_ID_AMD_MI200_DF_F4 0x14d4 | 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 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F4) }, | 128 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_19H_M78H_DF_F4) }, |
| 128 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) }, | 129 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CNB17H_F4) }, |
| 129 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M00H_DF_F4) }, | 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 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4) }, | 132 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M60H_DF_F4) }, |
| 131 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4) }, | 133 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_1AH_M70H_DF_F4) }, |
| 132 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_MI200_DF_F4) }, | 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 | v = apic_read(APIC_LVTT); | 440 | v = apic_read(APIC_LVTT); |
| 441 | v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); | 441 | v |= (APIC_LVT_MASKED | LOCAL_TIMER_VECTOR); |
| 442 | apic_write(APIC_LVTT, v); | 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 | return 0; | 456 | return 0; |
| 445 | } | 457 | } |
| 446 | 458 | ||
| @@ -1202,5 +1202,6 @@ void amd_check_microcode(void) · 1201 unmodified lines | |||
| 1202 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) | 1202 | if (boot_cpu_data.x86_vendor != X86_VENDOR_AMD) |
| 1203 | return; | 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 | case RETBLEED_MITIGATION_IBPB: | 1116 | case RETBLEED_MITIGATION_IBPB: |
| 1117 | setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); | 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 | setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); | 1127 | setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); |
| 1119 | mitigate_smt = true; | 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 | break; | 1137 | break; |
| 1121 | 1138 | ||
| 1122 | case RETBLEED_MITIGATION_STUFF: | 1139 | case RETBLEED_MITIGATION_STUFF: |
| @@ -2627,6 +2644,14 @@ static void __init srso_select_mitigation(void) · 1504 unmodified lines | |||
| 2627 | if (has_microcode) { | 2644 | if (has_microcode) { |
| 2628 | setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); | 2645 | setup_force_cpu_cap(X86_FEATURE_ENTRY_IBPB); |
| 2629 | srso_mitigation = SRSO_MITIGATION_IBPB; | 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 | } else { | 2656 | } else { |
| 2632 | pr_err("WARNING: kernel not compiled with MITIGATION_IBPB_ENTRY.\n"); | 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 | if (!boot_cpu_has(X86_FEATURE_ENTRY_IBPB) && has_microcode) { | 2663 | if (!boot_cpu_has(X86_FEATURE_ENTRY_IBPB) && has_microcode) { |
| 2639 | setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); | 2664 | setup_force_cpu_cap(X86_FEATURE_IBPB_ON_VMEXIT); |
| 2640 | srso_mitigation = SRSO_MITIGATION_IBPB_ON_VMEXIT; | 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 | } else { | 2674 | } else { |
| 2643 | pr_err("WARNING: kernel not compiled with MITIGATION_SRSO.\n"); | 2675 | pr_err("WARNING: kernel not compiled with MITIGATION_SRSO.\n"); |
| @@ -69,6 +69,7 @@ · 68 unmodified lines | |||
| 69 | #include <asm/sev.h> | 69 | #include <asm/sev.h> |
| 70 | #include <asm/tdx.h> | 70 | #include <asm/tdx.h> |
| 71 | #include <asm/posted_intr.h> | 71 | #include <asm/posted_intr.h> |
| 72 | #include <asm/runtime-const.h> | ||
| 72 | 73 | ||
| 73 | #include "cpu.h" | 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 | boot_cpu_has(X86_FEATURE_HYPERVISOR))) | 1444 | boot_cpu_has(X86_FEATURE_HYPERVISOR))) |
| 1444 | setup_force_cpu_bug(X86_BUG_BHI); | 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 | if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) | 1450 | if (cpu_matches(cpu_vuln_whitelist, NO_MELTDOWN)) |
| 1447 | return; | 1451 | return; |
| 1448 | 1452 | ||
| @@ -2386,6 +2390,15 @@ void __init arch_cpu_finalize_init(void) · 937 unmodified lines | |||
| 2386 | alternative_instructions(); | 2390 | alternative_instructions(); |
| 2387 | 2391 | ||
| 2388 | if (IS_ENABLED(CONFIG_X86_64)) { | 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 | * Make sure the first 2MB area is not mapped by huge pages | 2403 | * Make sure the first 2MB area is not mapped by huge pages |
| 2391 | * There are typically fixed size MTRRs in there and overlapping | 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 | native_rdmsr(MSR_AMD64_PATCH_LEVEL, ed->new_rev, dummy); | 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 | static int __init save_microcode_in_initrd(void) | 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 | if (!desc.mc) | 605 | if (!desc.mc) |
| 606 | return -EINVAL; | 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 | if (ret > UCODE_UPDATED) | 609 | if (ret > UCODE_UPDATED) |
| 610 | return -EINVAL; | 610 | return -EINVAL; |
| 611 | 611 | ||
| @@ -613,16 +613,19 @@ static int __init save_microcode_in_initrd(void) · 1 unmodified line | |||
| 613 | } | 613 | } |
| 614 | early_initcall(save_microcode_in_initrd); | 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 | /* Zen and newer hardcode the f/m/s in the patch ID */ | 620 | /* Zen and newer hardcode the f/m/s in the patch ID */ |
| 619 | if (x86_family(bsp_cpuid_1_eax) >= 0x17) { | 621 | if (x86_family(bsp_cpuid_1_eax) >= 0x17) { |
| 620 | union cpuid_1_eax p_cid = ucode_rev_to_cpuid(p->patch_id); | 622 | union cpuid_1_eax p_cid = ucode_rev_to_cpuid(p->patch_id); |
| 621 | union cpuid_1_eax n_cid = ucode_rev_to_cpuid(n->patch_id); | 623 | union cpuid_1_eax n_cid = ucode_rev_to_cpuid(n->patch_id); |
| 622 | 624 | ||
| 623 | /* Zap stepping */ | 625 | if (ignore_stepping) { |
| 624 | p_cid.stepping = 0; | 626 | p_cid.stepping = 0; |
| 625 | n_cid.stepping = 0; | 627 | n_cid.stepping = 0; |
| 628 | } | ||
| 626 | 629 | ||
| 627 | return p_cid.full == n_cid.full; | 630 | return p_cid.full == n_cid.full; |
| 628 | } else { | 631 | } else { |
| @@ -644,13 +647,13 @@ static struct ucode_patch *cache_find_patch(struct ucode_cpu_info *uci, u16 equi · 15 unmodified lines | |||
| 644 | WARN_ON_ONCE(!n.patch_id); | 647 | WARN_ON_ONCE(!n.patch_id); |
| 645 | 648 | ||
| 646 | list_for_each_entry(p, µcode_cache, plist) | 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 | return p; | 651 | return p; |
| 649 | 652 | ||
| 650 | return NULL; | 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 | /* Zen and newer hardcode the f/m/s in the patch ID */ | 658 | /* Zen and newer hardcode the f/m/s in the patch ID */ |
| 656 | if (x86_family(bsp_cpuid_1_eax) >= 0x17) { | 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 | zp.ucode_rev = p->patch_id; | 662 | zp.ucode_rev = p->patch_id; |
| 660 | zn.ucode_rev = n->patch_id; | 663 | zn.ucode_rev = n->patch_id; |
| 661 | 664 | ||
| 665 | if (zn.stepping != zp.stepping) | ||
| 666 | return -1; | ||
| 667 | |||
| 662 | return zn.rev > zp.rev; | 668 | return zn.rev > zp.rev; |
| 663 | } else { | 669 | } else { |
| 664 | return n->patch_id > p->patch_id; | 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 | static void update_cache(struct ucode_patch *new_patch) | 674 | static void update_cache(struct ucode_patch *new_patch) |
| 669 | { | 675 | { |
| 670 | struct ucode_patch *p; | 676 | struct ucode_patch *p; |
| 677 | int ret; | ||
| 671 | 678 | ||
| 672 | list_for_each_entry(p, µcode_cache, plist) { | 679 | list_for_each_entry(p, µcode_cache, plist) { |
| 673 | if (patch_cpus_equivalent(p, new_patch)) { | 680 | if (patch_cpus_equivalent(p, new_patch, true)) { |
| 674 | if (!patch_newer(p, new_patch)) { | 681 | ret = patch_newer(p, new_patch); |
| 682 | if (ret < 0) | ||
| 683 | continue; | ||
| 684 | else if (!ret) { | ||
| 675 | /* we already have the latest patch */ | 685 | /* we already have the latest patch */ |
| 676 | kfree(new_patch->data); | 686 | kfree(new_patch->data); |
| 677 | kfree(new_patch); | 687 | kfree(new_patch); |
| @@ -944,21 +954,30 @@ static enum ucode_state __load_microcode_amd(u8 family, const u8 *data, · 266 unmodified lines | |||
| 944 | return UCODE_OK; | 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 | enum ucode_state ret; | 959 | enum ucode_state ret; |
| 953 | 960 | ||
| 954 | /* free old equiv table */ | 961 | /* free old equiv table */ |
| 955 | free_equiv_cpu_table(); | 962 | free_equiv_cpu_table(); |
| 956 | 963 | ||
| 957 | ret = __load_microcode_amd(family, data, size); | 964 | ret = __load_microcode_amd(family, data, size); |
| 958 | if (ret != UCODE_OK) { | 965 | if (ret != UCODE_OK) |
| 959 | cleanup(); | 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 | return ret; | 980 | return ret; |
| 961 | } | ||
| 962 | 981 | ||
| 963 | for_each_node(nid) { | 982 | for_each_node(nid) { |
| 964 | cpu = cpumask_first(cpumask_of_node(nid)); | 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 | return false; | 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 | struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); | 212 | struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); |
| 213 | union cpuid_0x10_3_eax eax; | 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 | return true; | 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 | struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); | 246 | struct rdt_hw_resource *hw_res = resctrl_to_arch_res(r); |
| 247 | u32 eax, ebx, ecx, edx, subleaf; | 247 | u32 eax, ebx, ecx, edx, subleaf; |
| @@ -29,10 +29,10 @@ · 28 unmodified lines | |||
| 29 | * hardware. The allocated bandwidth percentage is rounded to the next | 29 | * hardware. The allocated bandwidth percentage is rounded to the next |
| 30 | * control step available on the hardware. | 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 | int ret; | 34 | int ret; |
| 35 | u32 bw; | ||
| 36 | 36 | ||
| 37 | /* | 37 | /* |
| 38 | * Only linear delay values is supported for current Intel SKUs. | 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 | return false; | 42 | return false; |
| 43 | } | 43 | } |
| 44 | 44 | ||
| 45 | ret = kstrtoul(buf, 10, &bw); | 45 | ret = kstrtou32(buf, 10, &bw); |
| 46 | if (ret) { | 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 | return false; | 48 | return false; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | if ((bw < r->membw.min_bw || bw > r->default_ctrl) && | 51 | /* Nothing else to do if software controller is enabled. */ |
| 52 | !is_mba_sc(r)) { | 52 | if (is_mba_sc(r)) { |
| 53 | rdt_last_cmd_printf("MB value %ld out of range [%d,%d]\n", bw, | 53 | *data = bw; |
| 54 | r->membw.min_bw, r->default_ctrl); | 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 | return false; | 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 | struct resctrl_staged_config *cfg; | 70 | struct resctrl_staged_config *cfg; |
| 66 | u32 closid = data->rdtgrp->closid; | 71 | u32 closid = data->rdtgrp->closid; |
| 67 | struct rdt_resource *r = s->res; | 72 | struct rdt_resource *r = s->res; |
| 68 | unsigned long bw_val; | 73 | u32 bw_val; |
| 69 | 74 | ||
| 70 | cfg = &d->staged_config[s->conf_type]; | 75 | cfg = &d->staged_config[s->conf_type]; |
| 71 | if (cfg->have_new_ctrl) { | 76 | if (cfg->have_new_ctrl) { |
| @@ -37,6 +37,7 @@ · 36 unmodified lines | |||
| 37 | #include <asm/apic.h> | 37 | #include <asm/apic.h> |
| 38 | #include <asm/apicdef.h> | 38 | #include <asm/apicdef.h> |
| 39 | #include <asm/hypervisor.h> | 39 | #include <asm/hypervisor.h> |
| 40 | #include <asm/mtrr.h> | ||
| 40 | #include <asm/tlb.h> | 41 | #include <asm/tlb.h> |
| 41 | #include <asm/cpuidle_haltpoll.h> | 42 | #include <asm/cpuidle_haltpoll.h> |
| 42 | #include <asm/ptrace.h> | 43 | #include <asm/ptrace.h> |
| @@ -980,6 +981,9 @@ static void __init kvm_init_platform(void) · 937 unmodified lines | |||
| 980 | } | 981 | } |
| 981 | kvmclock_init(); | 982 | kvmclock_init(); |
| 982 | x86_platform.apic_post_init = kvm_apic_init; | 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 | #if defined(CONFIG_AMD_MEM_ENCRYPT) | 989 | #if defined(CONFIG_AMD_MEM_ENCRYPT) |
| @@ -261,12 +261,6 @@ static noinstr bool handle_bug(struct pt_regs *regs) · 260 unmodified lines | |||
| 261 | int ud_type; | 261 | int ud_type; |
| 262 | u32 imm; | 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 | ud_type = decode_bug(regs->ip, &imm); | 264 | ud_type = decode_bug(regs->ip, &imm); |
| 271 | if (ud_type == BUG_NONE) | 265 | if (ud_type == BUG_NONE) |
| 272 | return handled; | 266 | return handled; |
| @@ -275,6 +269,12 @@ static noinstr bool handle_bug(struct pt_regs *regs) · 2 unmodified lines | |||
| 275 | * All lies, just get the WARN/BUG out. | 269 | * All lies, just get the WARN/BUG out. |
| 276 | */ | 270 | */ |
| 277 | instrumentation_begin(); | 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 | * Since we're emulating a CALL with exceptions, restore the interrupt | 279 | * Since we're emulating a CALL with exceptions, restore the interrupt |
| 280 | * state to what it was at the exception site. | 280 | * state to what it was at the exception site. |
| @@ -358,6 +358,7 @@ SECTIONS · 357 unmodified lines | |||
| 358 | #endif | 358 | #endif |
| 359 | 359 | ||
| 360 | RUNTIME_CONST_VARIABLES | 360 | RUNTIME_CONST_VARIABLES |
| 361 | RUNTIME_CONST(ptr, USER_PTR_MAX) | ||
| 361 | 362 | ||
| 362 | . = ALIGN(PAGE_SIZE); | 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 | bool flush = false; | 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 | if (kvm_memslots_have_rmaps(kvm)) | 1570 | if (kvm_memslots_have_rmaps(kvm)) |
| 1560 | flush = __kvm_rmap_zap_gfn_range(kvm, range->slot, | 1571 | flush = __kvm_rmap_zap_gfn_range(kvm, range->slot, |
| 1561 | range->start, range->end, | 1572 | range->start, range->end, |
| @@ -1884,14 +1895,10 @@ static bool sp_has_gptes(struct kvm_mmu_page *sp) · 322 unmodified lines | |||
| 1884 | if (is_obsolete_sp((_kvm), (_sp))) { \ | 1895 | if (is_obsolete_sp((_kvm), (_sp))) { \ |
| 1885 | } else | 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 | for_each_valid_sp(_kvm, _sp, \ | 1899 | for_each_valid_sp(_kvm, _sp, \ |
| 1889 | &(_kvm)->arch.mmu_page_hash[kvm_page_table_hashfn(_gfn)]) \ | 1900 | &(_kvm)->arch.mmu_page_hash[kvm_page_table_hashfn(_gfn)]) \ |
| 1890 | if ((_sp)->gfn != (_gfn)) {} else | 1901 | if ((_sp)->gfn != (_gfn) || !sp_has_gptes(_sp)) {} 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 | ||
| 1895 | 1902 | ||
| 1896 | static bool kvm_sync_page_check(struct kvm_vcpu *vcpu, struct kvm_mmu_page *sp) | 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 | * Since accounting information is stored in struct kvm_arch_memory_slot, | 7072 | * Since accounting information is stored in struct kvm_arch_memory_slot, |
| 7066 | * shadow pages deletion (e.g. unaccount_shadowed()) requires that all | 7073 | * all MMU pages that are shadowing guest PTEs must be zapped before the |
| 7067 | * gfns with a shadow page have a corresponding memslot. Do so before | 7074 | * memslot is deleted, as freeing such pages after the memslot is freed |
| 7068 | * the memslot goes away. | 7075 | * will result in use-after-free, e.g. in unaccount_shadowed(). |
| 7069 | */ | 7076 | */ |
| 7070 | for (i = 0; i < slot->npages; i++) { | 7077 | for (i = 0; i < slot->npages; i++) { |
| 7071 | struct kvm_mmu_page *sp; | 7078 | struct kvm_mmu_page *sp; |
| 7072 | gfn_t gfn = slot->base_gfn + i; | 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 | kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list); | 7082 | kvm_mmu_prepare_zap_page(kvm, sp, &invalid_list); |
| 7076 | 7083 | ||
| 7077 | if (need_resched() || rwlock_needbreak(&kvm->mmu_lock)) { | 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 | u64 pdpte; | 63 | u64 pdpte; |
| 64 | int ret; | 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 | ret = kvm_vcpu_read_guest_page(vcpu, gpa_to_gfn(cr3), &pdpte, | 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 | if (ret) | 72 | if (ret) |
| 69 | return 0; | 73 | return 0; |
| 70 | return pdpte; | 74 | return pdpte; |
| @@ -4888,9 +4888,6 @@ void vmx_vcpu_reset(struct kvm_vcpu *vcpu, bool init_event) · 4887 unmodified lines | |||
| 4888 | vmx->hv_deadline_tsc = -1; | 4888 | vmx->hv_deadline_tsc = -1; |
| 4889 | kvm_set_cr8(vcpu, 0); | 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 | seg_setup(VCPU_SREG_CS); | 4891 | seg_setup(VCPU_SREG_CS); |
| 4895 | vmcs_write16(GUEST_CS_SELECTOR, 0xf000); | 4892 | vmcs_write16(GUEST_CS_SELECTOR, 0xf000); |
| 4896 | vmcs_writel(GUEST_CS_BASE, 0xffff0000ul); | 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 | vmcs_writel(GUEST_IDTR_BASE, 0); | 4914 | vmcs_writel(GUEST_IDTR_BASE, 0); |
| 4918 | vmcs_write32(GUEST_IDTR_LIMIT, 0xffff); | 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 | vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE); | 4920 | vmcs_write32(GUEST_ACTIVITY_STATE, GUEST_ACTIVITY_ACTIVE); |
| 4921 | vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0); | 4921 | vmcs_write32(GUEST_INTERRUPTIBILITY_INFO, 0); |
| 4922 | vmcs_writel(GUEST_PENDING_DBG_EXCEPTIONS, 0); | 4922 | vmcs_writel(GUEST_PENDING_DBG_EXCEPTIONS, 0); |
| @@ -39,8 +39,13 @@ · 38 unmodified lines | |||
| 39 | 39 | ||
| 40 | .macro check_range size:req | 40 | .macro check_range size:req |
| 41 | .if IS_ENABLED(CONFIG_X86_64) | 41 | .if IS_ENABLED(CONFIG_X86_64) |
| 42 | mov %rax, %rdx | 42 | movq $0x0123456789abcdef,%rdx |
| 43 | sar $63, %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 | or %rdx, %rax | 49 | or %rdx, %rax |
| 45 | .else | 50 | .else |
| 46 | cmp $TASK_SIZE_MAX-\size+1, %eax | 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 | e820__range_update(pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED); | 173 | e820__range_update(pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED); |
| 174 | e820__range_update_table(e820_table_kexec, pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED); | 174 | e820__range_update_table(e820_table_kexec, pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED); |
| 175 | e820__range_update_table(e820_table_firmware, pa, PMD_SIZE, E820_TYPE_RAM, E820_TYPE_RESERVED); | 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 | switch (msr) { | 1032 | switch (msr) { |
| 1033 | case MSR_IA32_APICBASE: | 1033 | case MSR_IA32_APICBASE: |
| 1034 | val &= ~X2APIC_ENABLE; | 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 | break; | 1039 | break; |
| 1036 | } | 1040 | } |
| 1037 | return val; | 1041 | return val; |
| @@ -561,57 +561,33 @@ EXPORT_SYMBOL(blk_rq_append_bio); · 560 unmodified lines | |||
| 561 | /* Prepare bio for passthrough IO given ITER_BVEC iter */ | 561 | /* Prepare bio for passthrough IO given ITER_BVEC iter */ |
| 562 | static int blk_rq_map_user_bvec(struct request *rq, const struct iov_iter *iter) | 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; | 564 | const struct queue_limits *lim = &rq->q->limits; |
| 565 | size_t nr_iter = iov_iter_count(iter); | 565 | unsigned int max_bytes = lim->max_hw_sectors << SECTOR_SHIFT; |
| 566 | size_t nr_segs = iter->nr_segs; | 566 | unsigned int nsegs; |
| 567 | struct bio_vec *bvecs, *bvprvp = NULL; | ||
| 568 | const struct queue_limits *lim = &q->limits; | ||
| 569 | unsigned int nsegs = 0, bytes = 0; | ||
| 570 | struct bio *bio; | 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)) | 570 | if (!iov_iter_count(iter) || iov_iter_count(iter) > max_bytes) |
| 574 | return -EINVAL; | ||
| 575 | if (nr_segs > queue_max_segments(q)) | ||
| 576 | return -EINVAL; | 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 | bio = blk_rq_map_bio_alloc(rq, 0, GFP_KERNEL); | 574 | bio = blk_rq_map_bio_alloc(rq, 0, GFP_KERNEL); |
| 580 | if (bio == NULL) | 575 | if (!bio) |
| 581 | return -ENOMEM; | 576 | return -ENOMEM; |
| 582 | |||
| 583 | bio_iov_bvec_set(bio, (struct iov_iter *)iter); | 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 | /* | 579 | /* check that the data layout matches the hardware restrictions */ |
| 592 | * If the queue doesn't support SG gaps and adding this | 580 | ret = bio_split_rw_at(bio, lim, &nsegs, max_bytes); |
| 593 | * offset would create a gap, fallback to copy. | 581 | if (ret) { |
| 594 | */ | 582 | /* if we would have to split the bio, copy instead */ |
| 595 | if (bvprvp && bvec_gap_to_prev(lim, bvprvp, bv->bv_offset)) { | 583 | if (ret > 0) |
| 596 | blk_mq_map_bio_put(bio); | 584 | ret = -EREMOTEIO; |
| 597 | return -EREMOTEIO; | 585 | blk_mq_map_bio_put(bio); |
| 598 | } | 586 | return ret; |
| 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; | ||
| 610 | } | 587 | } |
| 588 | |||
| 589 | blk_rq_bio_prep(rq, bio, nsegs); | ||
| 611 | return 0; | 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 | /* mark the queue as mq asap */ | 4310 | /* mark the queue as mq asap */ |
| 4311 | q->mq_ops = set->ops; | 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 | if (blk_mq_alloc_ctxs(q)) | 4319 | if (blk_mq_alloc_ctxs(q)) |
| 4314 | goto err_exit; | 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 | INIT_WORK(&q->timeout_work, blk_mq_timeout_work); | 4334 | INIT_WORK(&q->timeout_work, blk_mq_timeout_work); |
| 4329 | blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ); | 4335 | blk_queue_rq_timeout(q, set->timeout ? set->timeout : 30 * HZ); |
| 4330 | 4336 | ||
| 4331 | q->tag_set = set; | ||
| 4332 | |||
| 4333 | q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT; | 4337 | q->queue_flags |= QUEUE_FLAG_MQ_DEFAULT; |
| 4334 | 4338 | ||
| 4335 | INIT_DELAYED_WORK(&q->requeue_work, blk_mq_requeue_work); | 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 | data->got_token = true; | 220 | data->got_token = true; |
| 221 | smp_wmb(); | 221 | smp_wmb(); |
| 222 | list_del_init(&curr->entry); | ||
| 223 | wake_up_process(data->task); | 222 | wake_up_process(data->task); |
| 223 | list_del_init_careful(&curr->entry); | ||
| 224 | return 1; | 224 | return 1; |
| 225 | } | 225 | } |
| 226 | 226 | ||
| @@ -106,8 +106,7 @@ static struct elevator_type *__elevator_find(const char *name) · 105 unmodified lines | |||
| 106 | return NULL; | 106 | return NULL; |
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | static struct elevator_type *elevator_find_get(struct request_queue *q, | 109 | static struct elevator_type *elevator_find_get(const char *name) |
| 110 | const char *name) | ||
| 111 | { | 110 | { |
| 112 | struct elevator_type *e; | 111 | struct elevator_type *e; |
| 113 | 112 | ||
| @@ -551,7 +550,7 @@ EXPORT_SYMBOL_GPL(elv_unregister); · 437 unmodified lines | |||
| 551 | static inline bool elv_support_iosched(struct request_queue *q) | 550 | static inline bool elv_support_iosched(struct request_queue *q) |
| 552 | { | 551 | { |
| 553 | if (!queue_is_mq(q) || | 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 | return false; | 554 | return false; |
| 556 | return true; | 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 | static struct elevator_type *elevator_get_default(struct request_queue *q) | 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 | return NULL; | 565 | return NULL; |
| 567 | 566 | ||
| 568 | if (q->nr_hw_queues != 1 && | 567 | if (q->nr_hw_queues != 1 && |
| 569 | !blk_mq_is_shared_tags(q->tag_set->flags)) | 568 | !blk_mq_is_shared_tags(q->tag_set->flags)) |
| 570 | return NULL; | 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 | if (q->elevator && elevator_match(q->elevator->type, elevator_name)) | 696 | if (q->elevator && elevator_match(q->elevator->type, elevator_name)) |
| 698 | return 0; | 697 | return 0; |
| 699 | 698 | ||
| 700 | e = elevator_find_get(q, elevator_name); | 699 | e = elevator_find_get(elevator_name); |
| 701 | if (!e) | 700 | if (!e) |
| 702 | return -EINVAL; | 701 | return -EINVAL; |
| 703 | ret = elevator_switch(q, e); | 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 | size_t count) | 708 | size_t count) |
| 710 | { | 709 | { |
| 711 | char elevator_name[ELV_NAME_MAX]; | 710 | char elevator_name[ELV_NAME_MAX]; |
| 711 | struct elevator_type *found; | ||
| 712 | const char *name; | ||
| 712 | 713 | ||
| 713 | if (!elv_support_iosched(disk->queue)) | 714 | if (!elv_support_iosched(disk->queue)) |
| 714 | return -EOPNOTSUPP; | 715 | return -EOPNOTSUPP; |
| 715 | 716 | ||
| 716 | strscpy(elevator_name, buf, sizeof(elevator_name)); | 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 | return 0; | 727 | return 0; |
| 721 | } | 728 | } |
| @@ -373,7 +373,7 @@ found: · 372 unmodified lines | |||
| 373 | q->cra_flags |= CRYPTO_ALG_DEAD; | 373 | q->cra_flags |= CRYPTO_ALG_DEAD; |
| 374 | alg = test->adult; | 374 | alg = test->adult; |
| 375 | 375 | ||
| 376 | if (list_empty(&alg->cra_list)) | 376 | if (crypto_is_dead(alg)) |
| 377 | goto complete; | 377 | goto complete; |
| 378 | 378 | ||
| 379 | if (err == -ECANCELED) | 379 | if (err == -ECANCELED) |
| @@ -1940,7 +1940,7 @@ static int __alg_test_hash(const struct hash_testvec *vecs, · 1939 unmodified lines | |||
| 1940 | atfm = crypto_alloc_ahash(driver, type, mask); | 1940 | atfm = crypto_alloc_ahash(driver, type, mask); |
| 1941 | if (IS_ERR(atfm)) { | 1941 | if (IS_ERR(atfm)) { |
| 1942 | if (PTR_ERR(atfm) == -ENOENT) | 1942 | if (PTR_ERR(atfm) == -ENOENT) |
| 1943 | return -ENOENT; | 1943 | return 0; |
| 1944 | pr_err("alg: hash: failed to allocate transform for %s: %ld\n", | 1944 | pr_err("alg: hash: failed to allocate transform for %s: %ld\n", |
| 1945 | driver, PTR_ERR(atfm)); | 1945 | driver, PTR_ERR(atfm)); |
| 1946 | return PTR_ERR(atfm); | 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 | tfm = crypto_alloc_aead(driver, type, mask); | 2706 | tfm = crypto_alloc_aead(driver, type, mask); |
| 2707 | if (IS_ERR(tfm)) { | 2707 | if (IS_ERR(tfm)) { |
| 2708 | if (PTR_ERR(tfm) == -ENOENT) | 2708 | if (PTR_ERR(tfm) == -ENOENT) |
| 2709 | return -ENOENT; | 2709 | return 0; |
| 2710 | pr_err("alg: aead: failed to allocate transform for %s: %ld\n", | 2710 | pr_err("alg: aead: failed to allocate transform for %s: %ld\n", |
| 2711 | driver, PTR_ERR(tfm)); | 2711 | driver, PTR_ERR(tfm)); |
| 2712 | return PTR_ERR(tfm); | 2712 | return PTR_ERR(tfm); |
| @@ -3285,7 +3285,7 @@ static int alg_test_skcipher(const struct alg_test_desc *desc, · 572 unmodified lines | |||
| 3285 | tfm = crypto_alloc_skcipher(driver, type, mask); | 3285 | tfm = crypto_alloc_skcipher(driver, type, mask); |
| 3286 | if (IS_ERR(tfm)) { | 3286 | if (IS_ERR(tfm)) { |
| 3287 | if (PTR_ERR(tfm) == -ENOENT) | 3287 | if (PTR_ERR(tfm) == -ENOENT) |
| 3288 | return -ENOENT; | 3288 | return 0; |
| 3289 | pr_err("alg: skcipher: failed to allocate transform for %s: %ld\n", | 3289 | pr_err("alg: skcipher: failed to allocate transform for %s: %ld\n", |
| 3290 | driver, PTR_ERR(tfm)); | 3290 | driver, PTR_ERR(tfm)); |
| 3291 | return PTR_ERR(tfm); | 3291 | return PTR_ERR(tfm); |
| @@ -3700,7 +3700,7 @@ static int alg_test_cipher(const struct alg_test_desc *desc, · 408 unmodified lines | |||
| 3700 | tfm = crypto_alloc_cipher(driver, type, mask); | 3700 | tfm = crypto_alloc_cipher(driver, type, mask); |
| 3701 | if (IS_ERR(tfm)) { | 3701 | if (IS_ERR(tfm)) { |
| 3702 | if (PTR_ERR(tfm) == -ENOENT) | 3702 | if (PTR_ERR(tfm) == -ENOENT) |
| 3703 | return -ENOENT; | 3703 | return 0; |
| 3704 | printk(KERN_ERR "alg: cipher: Failed to load transform for " | 3704 | printk(KERN_ERR "alg: cipher: Failed to load transform for " |
| 3705 | "%s: %ld\n", driver, PTR_ERR(tfm)); | 3705 | "%s: %ld\n", driver, PTR_ERR(tfm)); |
| 3706 | return PTR_ERR(tfm); | 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 | acomp = crypto_alloc_acomp(driver, type, mask); | 3726 | acomp = crypto_alloc_acomp(driver, type, mask); |
| 3727 | if (IS_ERR(acomp)) { | 3727 | if (IS_ERR(acomp)) { |
| 3728 | if (PTR_ERR(acomp) == -ENOENT) | 3728 | if (PTR_ERR(acomp) == -ENOENT) |
| 3729 | return -ENOENT; | 3729 | return 0; |
| 3730 | pr_err("alg: acomp: Failed to load transform for %s: %ld\n", | 3730 | pr_err("alg: acomp: Failed to load transform for %s: %ld\n", |
| 3731 | driver, PTR_ERR(acomp)); | 3731 | driver, PTR_ERR(acomp)); |
| 3732 | return PTR_ERR(acomp); | 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 | comp = crypto_alloc_comp(driver, type, mask); | 3740 | comp = crypto_alloc_comp(driver, type, mask); |
| 3741 | if (IS_ERR(comp)) { | 3741 | if (IS_ERR(comp)) { |
| 3742 | if (PTR_ERR(comp) == -ENOENT) | 3742 | if (PTR_ERR(comp) == -ENOENT) |
| 3743 | return -ENOENT; | 3743 | return 0; |
| 3744 | pr_err("alg: comp: Failed to load transform for %s: %ld\n", | 3744 | pr_err("alg: comp: Failed to load transform for %s: %ld\n", |
| 3745 | driver, PTR_ERR(comp)); | 3745 | driver, PTR_ERR(comp)); |
| 3746 | return PTR_ERR(comp); | 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 | rng = crypto_alloc_rng(driver, type, mask); | 3818 | rng = crypto_alloc_rng(driver, type, mask); |
| 3819 | if (IS_ERR(rng)) { | 3819 | if (IS_ERR(rng)) { |
| 3820 | if (PTR_ERR(rng) == -ENOENT) | 3820 | if (PTR_ERR(rng) == -ENOENT) |
| 3821 | return -ENOENT; | 3821 | return 0; |
| 3822 | printk(KERN_ERR "alg: cprng: Failed to load transform for %s: " | 3822 | printk(KERN_ERR "alg: cprng: Failed to load transform for %s: " |
| 3823 | "%ld\n", driver, PTR_ERR(rng)); | 3823 | "%ld\n", driver, PTR_ERR(rng)); |
| 3824 | return PTR_ERR(rng); | 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 | drng = crypto_alloc_rng(driver, type, mask); | 3847 | drng = crypto_alloc_rng(driver, type, mask); |
| 3848 | if (IS_ERR(drng)) { | 3848 | if (IS_ERR(drng)) { |
| 3849 | kfree_sensitive(buf); | ||
| 3849 | if (PTR_ERR(drng) == -ENOENT) | 3850 | if (PTR_ERR(drng) == -ENOENT) |
| 3850 | goto out_no_rng; | 3851 | return 0; |
| 3851 | printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for " | 3852 | printk(KERN_ERR "alg: drbg: could not allocate DRNG handle for " |
| 3852 | "%s\n", driver); | 3853 | "%s\n", driver); |
| 3853 | out_no_rng: | ||
| 3854 | kfree_sensitive(buf); | ||
| 3855 | return PTR_ERR(drng); | 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 | tfm = crypto_alloc_kpp(driver, type, mask); | 4094 | tfm = crypto_alloc_kpp(driver, type, mask); |
| 4096 | if (IS_ERR(tfm)) { | 4095 | if (IS_ERR(tfm)) { |
| 4097 | if (PTR_ERR(tfm) == -ENOENT) | 4096 | if (PTR_ERR(tfm) == -ENOENT) |
| 4098 | return -ENOENT; | 4097 | return 0; |
| 4099 | pr_err("alg: kpp: Failed to load tfm for %s: %ld\n", | 4098 | pr_err("alg: kpp: Failed to load tfm for %s: %ld\n", |
| 4100 | driver, PTR_ERR(tfm)); | 4099 | driver, PTR_ERR(tfm)); |
| 4101 | return PTR_ERR(tfm); | 4100 | return PTR_ERR(tfm); |
| @@ -4325,7 +4324,7 @@ static int alg_test_akcipher(const struct alg_test_desc *desc, · 223 unmodified lines | |||
| 4325 | tfm = crypto_alloc_akcipher(driver, type, mask); | 4324 | tfm = crypto_alloc_akcipher(driver, type, mask); |
| 4326 | if (IS_ERR(tfm)) { | 4325 | if (IS_ERR(tfm)) { |
| 4327 | if (PTR_ERR(tfm) == -ENOENT) | 4326 | if (PTR_ERR(tfm) == -ENOENT) |
| 4328 | return -ENOENT; | 4327 | return 0; |
| 4329 | pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n", | 4328 | pr_err("alg: akcipher: Failed to load tfm for %s: %ld\n", |
| 4330 | driver, PTR_ERR(tfm)); | 4329 | driver, PTR_ERR(tfm)); |
| 4331 | return PTR_ERR(tfm); | 4330 | return PTR_ERR(tfm); |
| @@ -116,6 +116,14 @@ static int reset_pending_show(struct seq_file *s, void *v) · 115 unmodified lines | |||
| 116 | return 0; | 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 | static const struct drm_debugfs_info vdev_debugfs_list[] = { | 127 | static const struct drm_debugfs_info vdev_debugfs_list[] = { |
| 120 | {"bo_list", bo_list_show, 0}, | 128 | {"bo_list", bo_list_show, 0}, |
| 121 | {"fw_name", fw_name_show, 0}, | 129 | {"fw_name", fw_name_show, 0}, |
| @@ -125,6 +133,7 @@ static const struct drm_debugfs_info vdev_debugfs_list[] = { · 3 unmodified lines | |||
| 125 | {"last_bootmode", last_bootmode_show, 0}, | 133 | {"last_bootmode", last_bootmode_show, 0}, |
| 126 | {"reset_counter", reset_counter_show, 0}, | 134 | {"reset_counter", reset_counter_show, 0}, |
| 127 | {"reset_pending", reset_pending_show, 0}, | 135 | {"reset_pending", reset_pending_show, 0}, |
| 136 | {"firewall_irq_counter", firewall_irq_counter_show, 0}, | ||
| 128 | }; | 137 | }; |
| 129 | 138 | ||
| 130 | static int dvfs_mode_get(void *data, u64 *dvfs_mode) | 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 | platform_init(vdev); | 252 | platform_init(vdev); |
| 253 | wa_init(vdev); | 253 | wa_init(vdev); |
| 254 | timeouts_init(vdev); | 254 | timeouts_init(vdev); |
| 255 | atomic_set(&vdev->hw->firewall_irq_counter, 0); | ||
| 255 | 256 | ||
| 256 | return 0; | 257 | return 0; |
| 257 | } | 258 | } |
| @@ -51,6 +51,7 @@ struct ivpu_hw_info { · 50 unmodified lines | |||
| 51 | int dma_bits; | 51 | int dma_bits; |
| 52 | ktime_t d0i3_entry_host_ts; | 52 | ktime_t d0i3_entry_host_ts; |
| 53 | u64 d0i3_entry_vpu_ts; | 53 | u64 d0i3_entry_vpu_ts; |
| 54 | atomic_t firewall_irq_counter; | ||
| 54 | }; | 55 | }; |
| 55 | 56 | ||
| 56 | int ivpu_hw_init(struct ivpu_device *vdev); | 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 | static void irq_noc_firewall_handler(struct ivpu_device *vdev) | 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 | /* Handler for IRQs from NPU core */ | 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 | nents = sgt->nents; | 496 | nents = sgt->nents; |
| 497 | nents_dma = nents; | 497 | nents_dma = nents; |
| 498 | *size = QAIC_MANAGE_EXT_MSG_LENGTH - msg_hdr_len - sizeof(**out_trans); | 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 | *size -= sizeof(*asp); | 500 | *size -= sizeof(*asp); |
| 501 | /* Save 1K for possible follow-up transactions. */ | 501 | /* Save 1K for possible follow-up transactions. */ |
| 502 | if (*size < SZ_1K) { | 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 | nents = 0; | 184 | nents = 0; |
| 185 | 185 | ||
| 186 | size = size ? size : PAGE_SIZE; | 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 | len = sg_dma_len(sg); | 188 | len = sg_dma_len(sg); |
| 189 | 189 | ||
| 190 | if (!len) | 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 | /* copy relevant sg node and fix page and length */ | 222 | /* copy relevant sg node and fix page and length */ |
| 223 | sgn = sgf; | 223 | sgn = sgf; |
| 224 | for_each_sgtable_sg(sgt, sg, j) { | 224 | for_each_sgtable_dma_sg(sgt, sg, j) { |
| 225 | memcpy(sg, sgn, sizeof(*sg)); | 225 | memcpy(sg, sgn, sizeof(*sg)); |
| 226 | if (sgn == sgf) { | 226 | if (sgn == sgf) { |
| 227 | sg_dma_address(sg) += offf; | 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 | * fence. | 301 | * fence. |
| 302 | */ | 302 | */ |
| 303 | dev_addr = req->dev_addr; | 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 | slice->reqs[i].cmd = cmd; | 305 | slice->reqs[i].cmd = cmd; |
| 306 | slice->reqs[i].src_addr = cpu_to_le64(slice->dir == DMA_TO_DEVICE ? | 306 | slice->reqs[i].src_addr = cpu_to_le64(slice->dir == DMA_TO_DEVICE ? |
| 307 | sg_dma_address(sg) : dev_addr); | 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 | .driver_data = (void *)(long)ACPI_BUTTON_LID_INIT_OPEN, | 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 | /* Store CPU Logical ID */ | 868 | /* Store CPU Logical ID */ |
| 869 | cpc_ptr->cpu_id = pr->id; | 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 | /* Parse PSD data for this CPU */ | 872 | /* Parse PSD data for this CPU */ |
| 873 | ret = acpi_get_psd(cpc_ptr, handle); | 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 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); | 1087 | int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu); |
| 1088 | struct cpc_reg *reg = ®_res->cpc_entry.reg; | 1088 | struct cpc_reg *reg = ®_res->cpc_entry.reg; |
| 1089 | struct cpc_desc *cpc_desc; | 1089 | struct cpc_desc *cpc_desc; |
| 1090 | unsigned long flags; | ||
| 1090 | 1091 | ||
| 1091 | size = GET_BIT_WIDTH(reg); | 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 | return -ENODEV; | 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 | switch (size) { | 1131 | switch (size) { |
| 1131 | case 8: | 1132 | case 8: |
| 1132 | prev_val = readb_relaxed(vaddr); | 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 | prev_val = readq_relaxed(vaddr); | 1142 | prev_val = readq_relaxed(vaddr); |
| 1142 | break; | 1143 | break; |
| 1143 | default: | 1144 | default: |
| 1144 | spin_unlock(&cpc_desc->rmw_lock); | 1145 | raw_spin_unlock_irqrestore(&cpc_desc->rmw_lock, flags); |
| 1145 | return -EFAULT; | 1146 | return -EFAULT; |
| 1146 | } | 1147 | } |
| 1147 | val = MASK_VAL_WRITE(reg, prev_val, val); | 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 | if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) | 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 | return ret_val; | 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 | u64 mul, div; | 1917 | u64 mul, div; |
| 1917 | 1918 | ||
| 1918 | if (caps->lowest_freq && caps->nominal_freq) { | 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 | mul *= KHZ_PER_MHZ; | 1928 | mul *= KHZ_PER_MHZ; |
| 1921 | div = caps->nominal_perf - caps->lowest_perf; | ||
| 1922 | offset = caps->nominal_freq * KHZ_PER_MHZ - | 1929 | offset = caps->nominal_freq * KHZ_PER_MHZ - |
| 1923 | div64_u64(caps->nominal_perf * mul, div); | 1930 | div64_u64(caps->nominal_perf * mul, div); |
| 1924 | } else { | 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 | s64 retval, offset = 0; | 1947 | s64 retval, offset = 0; |
| 1941 | static u64 max_khz; | 1948 | static u64 max_khz; |
| 1942 | u64 mul, div; | 1949 | u64 mul, div; |
| 1943 | 1950 | ||
| 1944 | if (caps->lowest_freq && caps->nominal_freq) { | 1951 | if (caps->lowest_freq && caps->nominal_freq) { |
| 1945 | mul = caps->nominal_perf - caps->lowest_perf; | 1952 | /* Avoid special case when nominal_freq is equal to lowest_freq */ |
| 1946 | div = caps->nominal_freq - caps->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 | * We don't need to convert to kHz for computing offset and can | 1961 | * We don't need to convert to kHz for computing offset and can |
| 1949 | * directly use nominal_freq and lowest_freq as the div64_u64 | 1962 | * directly use nominal_freq and lowest_freq as the div64_u64 |
| @@ -52,7 +52,7 @@ struct prm_context_buffer { · 51 unmodified lines | |||
| 52 | static LIST_HEAD(prm_module_list); | 52 | static LIST_HEAD(prm_module_list); |
| 53 | 53 | ||
| 54 | struct prm_handler_info { | 54 | struct prm_handler_info { |
| 55 | guid_t guid; | 55 | efi_guid_t guid; |
| 56 | efi_status_t (__efiapi *handler_addr)(u64, void *); | 56 | efi_status_t (__efiapi *handler_addr)(u64, void *); |
| 57 | u64 static_data_buffer_addr; | 57 | u64 static_data_buffer_addr; |
| 58 | u64 acpi_param_buffer_addr; | 58 | u64 acpi_param_buffer_addr; |
| @@ -72,17 +72,21 @@ struct prm_module_info { · 13 unmodified lines | |||
| 72 | struct prm_handler_info handlers[] __counted_by(handler_count); | 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 | efi_memory_desc_t *md; | 77 | efi_memory_desc_t *md; |
| 78 | u64 pa_offset = pa & ~PAGE_MASK; | 78 | u64 pa_offset = pa & ~PAGE_MASK; |
| 79 | u64 page = pa & PAGE_MASK; | 79 | u64 page = pa & PAGE_MASK; |
| 80 | 80 | ||
| 81 | for_each_efi_memory_desc(md) { | 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 | return pa_offset + md->virt_addr + page - md->phys_addr; | 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 | return 0; | 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 | th = &tm->handlers[cur_handler]; | 152 | th = &tm->handlers[cur_handler]; |
| 149 | 153 | ||
| 150 | guid_copy(&th->guid, (guid_t *)handler_info->handler_guid); | 154 | guid_copy(&th->guid, (guid_t *)handler_info->handler_guid); |
| 151 | th->handler_addr = (void *)efi_pa_va_lookup(handler_info->handler_address); | 155 | th->handler_addr = |
| 152 | th->static_data_buffer_addr = efi_pa_va_lookup(handler_info->static_data_buffer_address); | 156 | (void *)efi_pa_va_lookup(&th->guid, handler_info->handler_address); |
| 153 | th->acpi_param_buffer_addr = efi_pa_va_lookup(handler_info->acpi_param_buffer_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 | } while (++cur_handler < tm->handler_count && (handler_info = get_next_handler(handler_info))); | 164 | } while (++cur_handler < tm->handler_count && (handler_info = get_next_handler(handler_info))); |
| 155 | 165 | ||
| 156 | return 0; | 166 | return 0; |
| @@ -277,6 +287,13 @@ static acpi_status acpi_platformrt_space_handler(u32 function, · 120 unmodified lines | |||
| 277 | if (!handler || !module) | 287 | if (!handler || !module) |
| 278 | goto invalid_guid; | 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 | ACPI_COPY_NAMESEG(context.signature, "PRMC"); | 297 | ACPI_COPY_NAMESEG(context.signature, "PRMC"); |
| 281 | context.revision = 0x0; | 298 | context.revision = 0x0; |
| 282 | context.reserved = 0x0; | 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 | .matches = { | 452 | .matches = { |
| 453 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 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 | .matches = { | 459 | .matches = { |
| 460 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 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 | .matches = { | 466 | .matches = { |
| 467 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 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 | .matches = { | 473 | .matches = { |
| 474 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 474 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), |
| 475 | DMI_MATCH(DMI_BOARD_NAME, "B1502CGA"), | 475 | DMI_MATCH(DMI_BOARD_NAME, "B2502"), |
| 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"), | ||
| 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 */ | 493 | /* Asus Vivobook Pro N6506M* */ |
| 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 */ | ||
| 543 | .matches = { | 494 | .matches = { |
| 544 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 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 | .matches = { | 501 | .matches = { |
| 551 | DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."), | 502 | DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"), |
| 552 | DMI_MATCH(DMI_BOARD_NAME, "N6506MJ"), | 503 | DMI_MATCH(DMI_BOARD_NAME, "17U70P"), |
| 553 | }, | 504 | }, |
| 554 | }, | 505 | }, |
| 555 | { | 506 | { |
| 556 | /* LG Electronics 17U70P */ | 507 | /* LG Electronics 16T90SP */ |
| 557 | .matches = { | 508 | .matches = { |
| 558 | DMI_MATCH(DMI_SYS_VENDOR, "LG Electronics"), | 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 | /* the scmd has an associated qc */ | 651 | /* the scmd has an associated qc */ |
| 652 | if (!(qc->flags & ATA_QCFLAG_EH)) { | 652 | if (!(qc->flags & ATA_QCFLAG_EH)) { |
| 653 | /* which hasn't failed yet, timeout */ | 653 | /* which hasn't failed yet, timeout */ |
| 654 | set_host_byte(scmd, DID_TIME_OUT); | ||
| 654 | qc->err_mask |= AC_ERR_TIMEOUT; | 655 | qc->err_mask |= AC_ERR_TIMEOUT; |
| 655 | qc->flags |= ATA_QCFLAG_EH; | 656 | qc->flags |= ATA_QCFLAG_EH; |
| 656 | nr_timedout++; | 657 | nr_timedout++; |
| @@ -4099,10 +4100,20 @@ static void ata_eh_handle_port_suspend(struct ata_port *ap) · 3442 unmodified lines | |||
| 4099 | 4100 | ||
| 4100 | WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); | 4101 | WARN_ON(ap->pflags & ATA_PFLAG_SUSPENDED); |
| 4101 | 4102 | ||
| 4102 | /* Set all devices attached to the port in standby mode */ | 4103 | /* |
| 4103 | ata_for_each_link(link, ap, HOST_FIRST) { | 4104 | * We will reach this point for all of the PM events: |
| 4104 | ata_for_each_dev(dev, link, ENABLED) | 4105 | * PM_EVENT_SUSPEND (if runtime pm, PM_EVENT_AUTO will also be set) |
| 4105 | ata_dev_power_set_standby(dev); | 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 | #include <linux/of.h> | 26 | #include <linux/of.h> |
| 27 | #include <linux/of_device.h> | 27 | #include <linux/of_device.h> |
| 28 | #include <linux/pm_runtime.h> | 28 | #include <linux/pm_runtime.h> |
| 29 | #include <linux/rcupdate.h> | ||
| 30 | #include <linux/sched/mm.h> | 29 | #include <linux/sched/mm.h> |
| 31 | #include <linux/sched/signal.h> | 30 | #include <linux/sched/signal.h> |
| 32 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
| @@ -2634,7 +2633,6 @@ static const char *dev_uevent_name(const struct kobject *kobj) · 2601 unmodified lines | |||
| 2634 | static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) | 2633 | static int dev_uevent(const struct kobject *kobj, struct kobj_uevent_env *env) |
| 2635 | { | 2634 | { |
| 2636 | const struct device *dev = kobj_to_dev(kobj); | 2635 | const struct device *dev = kobj_to_dev(kobj); |
| 2637 | struct device_driver *driver; | ||
| 2638 | int retval = 0; | 2636 | int retval = 0; |
| 2639 | 2637 | ||
| 2640 | /* add device node properties if present */ | 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 | if (dev->type && dev->type->name) | 2661 | if (dev->type && dev->type->name) |
| 2664 | add_uevent_var(env, "DEVTYPE=%s", dev->type->name); | 2662 | add_uevent_var(env, "DEVTYPE=%s", dev->type->name); |
| 2665 | 2663 | ||
| 2666 | /* Synchronize with module_remove_driver() */ | 2664 | if (dev->driver) |
| 2667 | rcu_read_lock(); | 2665 | add_uevent_var(env, "DRIVER=%s", dev->driver->name); |
| 2668 | driver = READ_ONCE(dev->driver); | ||
| 2669 | if (driver) | ||
| 2670 | add_uevent_var(env, "DRIVER=%s", driver->name); | ||
| 2671 | rcu_read_unlock(); | ||
| 2672 | 2666 | ||
| 2673 | /* Add common DT information about the device */ | 2667 | /* Add common DT information about the device */ |
| 2674 | of_device_uevent(dev, env); | 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 | if (!env) | 2732 | if (!env) |
| 2739 | return -ENOMEM; | 2733 | return -ENOMEM; |
| 2740 | 2734 | ||
| 2735 | /* Synchronize with really_probe() */ | ||
| 2736 | device_lock(dev); | ||
| 2741 | /* let the kset specific function add its keys */ | 2737 | /* let the kset specific function add its keys */ |
| 2742 | retval = kset->uevent_ops->uevent(&dev->kobj, env); | 2738 | retval = kset->uevent_ops->uevent(&dev->kobj, env); |
| 2739 | device_unlock(dev); | ||
| 2743 | if (retval) | 2740 | if (retval) |
| 2744 | goto out; | 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 | EXPORT_SYMBOL_GPL(device_for_each_child_reverse); | 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 | * device_find_child - device iterator for locating a particular device. | 4073 | * device_find_child - device iterator for locating a particular device. |
| 4042 | * @parent: parent struct device | 4074 | * @parent: parent struct device |
| @@ -7,7 +7,6 @@ · 6 unmodified lines | |||
| 7 | #include <linux/errno.h> | 7 | #include <linux/errno.h> |
| 8 | #include <linux/slab.h> | 8 | #include <linux/slab.h> |
| 9 | #include <linux/string.h> | 9 | #include <linux/string.h> |
| 10 | #include <linux/rcupdate.h> | ||
| 11 | #include "base.h" | 10 | #include "base.h" |
| 12 | 11 | ||
| 13 | static char *make_driver_name(const struct device_driver *drv) | 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 | if (!drv) | 101 | if (!drv) |
| 103 | return; | 102 | return; |
| 104 | 103 | ||
| 105 | /* Synchronize with dev_uevent() */ | ||
| 106 | synchronize_rcu(); | ||
| 107 | |||
| 108 | sysfs_remove_link(&drv->p->kobj, "module"); | 104 | sysfs_remove_link(&drv->p->kobj, "module"); |
| 109 | 105 | ||
| 110 | if (drv->owner) | 106 | if (drv->owner) |
| @@ -195,6 +195,7 @@ int dev_pm_domain_attach_list(struct device *dev, · 194 unmodified lines | |||
| 195 | struct device *pd_dev = NULL; | 195 | struct device *pd_dev = NULL; |
| 196 | int ret, i, num_pds = 0; | 196 | int ret, i, num_pds = 0; |
| 197 | bool by_id = true; | 197 | bool by_id = true; |
| 198 | size_t size; | ||
| 198 | u32 pd_flags = data ? data->pd_flags : 0; | 199 | u32 pd_flags = data ? data->pd_flags : 0; |
| 199 | u32 link_flags = pd_flags & PD_FLAG_NO_DEV_LINK ? 0 : | 200 | u32 link_flags = pd_flags & PD_FLAG_NO_DEV_LINK ? 0 : |
| 200 | DL_FLAG_STATELESS | DL_FLAG_PM_RUNTIME; | 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 | if (num_pds <= 0) | 218 | if (num_pds <= 0) |
| 218 | return 0; | 219 | return 0; |
| 219 | 220 | ||
| 220 | pds = devm_kzalloc(dev, sizeof(*pds), GFP_KERNEL); | 221 | pds = kzalloc(sizeof(*pds), GFP_KERNEL); |
| 221 | if (!pds) | 222 | if (!pds) |
| 222 | return -ENOMEM; | 223 | return -ENOMEM; |
| 223 | 224 | ||
| 224 | pds->pd_devs = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_devs), | 225 | size = sizeof(*pds->pd_devs) + sizeof(*pds->pd_links); |
| 225 | GFP_KERNEL); | 226 | pds->pd_devs = kcalloc(num_pds, size, GFP_KERNEL); |
| 226 | if (!pds->pd_devs) | 227 | if (!pds->pd_devs) { |
| 227 | return -ENOMEM; | 228 | ret = -ENOMEM; |
| 228 | 229 | goto free_pds; | |
| 229 | pds->pd_links = devm_kcalloc(dev, num_pds, sizeof(*pds->pd_links), | 230 | } |
| 230 | GFP_KERNEL); | 231 | pds->pd_links = (void *)(pds->pd_devs + num_pds); |
| 231 | if (!pds->pd_links) | ||
| 232 | return -ENOMEM; | ||
| 233 | 232 | ||
| 234 | if (link_flags && pd_flags & PD_FLAG_DEV_LINK_ON) | 233 | if (link_flags && pd_flags & PD_FLAG_DEV_LINK_ON) |
| 235 | link_flags |= DL_FLAG_RPM_ACTIVE; | 234 | link_flags |= DL_FLAG_RPM_ACTIVE; |
| @@ -272,6 +271,9 @@ err_attach: · 36 unmodified lines | |||
| 272 | device_link_del(pds->pd_links[i]); | 271 | device_link_del(pds->pd_links[i]); |
| 273 | dev_pm_domain_detach(pds->pd_devs[i], true); | 272 | dev_pm_domain_detach(pds->pd_devs[i], true); |
| 274 | } | 273 | } |
| 274 | kfree(pds->pd_devs); | ||
| 275 | free_pds: | ||
| 276 | kfree(pds); | ||
| 275 | return ret; | 277 | return ret; |
| 276 | } | 278 | } |
| 277 | EXPORT_SYMBOL_GPL(dev_pm_domain_attach_list); | 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 | device_link_del(list->pd_links[i]); | 365 | device_link_del(list->pd_links[i]); |
| 364 | dev_pm_domain_detach(list->pd_devs[i], true); | 366 | dev_pm_domain_detach(list->pd_devs[i], true); |
| 365 | } | 367 | } |
| 368 | |||
| 369 | kfree(list->pd_devs); | ||
| 370 | kfree(list); | ||
| 366 | } | 371 | } |
| 367 | EXPORT_SYMBOL_GPL(dev_pm_domain_detach_list); | 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 | extern struct mutex resources_mutex; | 1365 | extern struct mutex resources_mutex; |
| 1366 | 1366 | ||
| 1367 | extern int conn_lowest_minor(struct drbd_connection *connection); | ||
| 1368 | extern enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor); | 1367 | extern enum drbd_ret_code drbd_create_device(struct drbd_config_context *adm_ctx, unsigned int minor); |
| 1369 | extern void drbd_destroy_device(struct kref *kref); | 1368 | extern void drbd_destroy_device(struct kref *kref); |
| 1370 | extern void drbd_delete_device(struct drbd_device *device); | 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 | wait_for_completion(&thi->stop); | 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 | #ifdef CONFIG_SMP | 474 | #ifdef CONFIG_SMP |
| 489 | /* | 475 | /* |
| 490 | * drbd_calc_cpu_mask() - Generate CPU masks, spread over all CPUs | 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 | * TODO: provide forward progress for RECOVERY handler, so that | 2380 | * TODO: provide forward progress for RECOVERY handler, so that |
| 2381 | * unprivileged device can benefit from it | 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 | info.flags &= ~(UBLK_F_USER_RECOVERY_REISSUE | | 2384 | info.flags &= ~(UBLK_F_USER_RECOVERY_REISSUE | |
| 2385 | UBLK_F_USER_RECOVERY); | 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 | /* the created device is always owned by current user */ | 2396 | /* the created device is always owned by current user */ |
| 2388 | ublk_store_owner_uid_gid(&info.owner_uid, &info.owner_gid); | 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 | if (!urb) | 1345 | if (!urb) |
| 1346 | return -ENOMEM; | 1346 | return -ENOMEM; |
| 1347 | 1347 | ||
| 1348 | /* Use maximum HCI Event size so the USB stack handles | 1348 | if (le16_to_cpu(data->udev->descriptor.idVendor) == 0x0a12 && |
| 1349 | * ZPL/short-transfer automatically. | 1349 | le16_to_cpu(data->udev->descriptor.idProduct) == 0x0001) |
| 1350 | */ | 1350 | /* Fake CSR devices don't seem to support sort-transter */ |
| 1351 | size = HCI_MAX_EVENT_SIZE; | 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 | buf = kmalloc(size, mem_flags); | 1358 | buf = kmalloc(size, mem_flags); |
| 1354 | if (!buf) { | 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 | BT_DBG("intf %p", intf); | 4047 | BT_DBG("intf %p", intf); |
| 4043 | 4048 | ||
| 4044 | /* Don't suspend if there are connections */ | 4049 | /* Don't auto-suspend if there are connections; external suspend calls |
| 4045 | if (hci_conn_count(data->hdev)) | 4050 | * shall never fail. |
| 4051 | */ | ||
| 4052 | if (PMSG_IS_AUTO(message) && hci_conn_count(data->hdev)) | ||
| 4046 | return -EBUSY; | 4053 | return -EBUSY; |
| 4047 | 4054 | ||
| 4048 | if (data->suspend_count++) | 4055 | if (data->suspend_count++) |
| @@ -2313,7 +2313,7 @@ static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi, · 2312 unmodified lines | |||
| 2313 | return -EINVAL; | 2313 | return -EINVAL; |
| 2314 | 2314 | ||
| 2315 | /* Prevent arg from speculatively bypassing the length check */ | 2315 | /* Prevent arg from speculatively bypassing the length check */ |
| 2316 | barrier_nospec(); | 2316 | arg = array_index_nospec(arg, cdi->capacity); |
| 2317 | 2317 | ||
| 2318 | info = kmalloc(sizeof(*info), GFP_KERNEL); | 2318 | info = kmalloc(sizeof(*info), GFP_KERNEL); |
| 2319 | if (!info) | 2319 | if (!info) |
| @@ -674,6 +674,16 @@ EXPORT_SYMBOL_GPL(tpm_chip_register); · 673 unmodified lines | |||
| 674 | */ | 674 | */ |
| 675 | void tpm_chip_unregister(struct tpm_chip *chip) | 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 | tpm_del_legacy_sysfs(chip); | 687 | tpm_del_legacy_sysfs(chip); |
| 678 | if (tpm_is_hwrng_enabled(chip)) | 688 | if (tpm_is_hwrng_enabled(chip)) |
| 679 | hwrng_unregister(&chip->hwrng); | 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 | struct tpm_header *header = (void *)buf; | 27 | struct tpm_header *header = (void *)buf; |
| 28 | ssize_t ret, len; | 28 | ssize_t ret, len; |
| 29 | 29 | ||
| 30 | if (chip->flags & TPM_CHIP_FLAG_TPM2) | ||
| 31 | tpm2_end_auth_session(chip); | ||
| 32 | |||
| 30 | ret = tpm2_prepare_space(chip, space, buf, bufsiz); | 33 | ret = tpm2_prepare_space(chip, space, buf, bufsiz); |
| 31 | /* If the command is not implemented by the TPM, synthesize a | 34 | /* If the command is not implemented by the TPM, synthesize a |
| 32 | * response with a TPM2_RC_COMMAND_CODE return for user-space. | 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 | rc = tpm_try_get_ops(chip); | 380 | rc = tpm_try_get_ops(chip); |
| 381 | if (!rc) { | 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 | tpm2_shutdown(chip, TPM2_SU_STATE); | 384 | tpm2_shutdown(chip, TPM2_SU_STATE); |
| 384 | else | 385 | } else { |
| 385 | rc = tpm1_pm_suspend(chip, tpm_suspend_pcr); | 386 | rc = tpm1_pm_suspend(chip, tpm_suspend_pcr); |
| 387 | } | ||
| 386 | 388 | ||
| 387 | tpm_put_ops(chip); | 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 | #ifdef CONFIG_TCG_TPM2_HMAC | 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 | * The Architecture Guide requires us to strip trailing zeros | 340 | * The Architecture Guide requires us to strip trailing zeros |
| 338 | * before computing the HMAC | 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 | sha256_final(&sctx, out); | 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 | struct crypto_kpp *kpp; | 493 | struct crypto_kpp *kpp; |
| 490 | struct kpp_request *req; | 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 | sg_set_buf(&s[0], chip->null_ec_key_x, EC_PT_SZ); | 547 | sg_set_buf(&s[0], chip->null_ec_key_x, EC_PT_SZ); |
| 544 | sg_set_buf(&s[1], chip->null_ec_key_y, EC_PT_SZ); | 548 | sg_set_buf(&s[1], chip->null_ec_key_y, EC_PT_SZ); |
| 545 | kpp_request_set_input(req, s, EC_PT_SZ*2); | 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 | kpp_request_set_output(req, d, EC_PT_SZ); | 551 | kpp_request_set_output(req, d, EC_PT_SZ); |
| 548 | crypto_kpp_compute_shared_secret(req); | 552 | crypto_kpp_compute_shared_secret(req); |
| 549 | kpp_request_free(req); | 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 | * This works because KDFe fully consumes the secret before it | 558 | * This works because KDFe fully consumes the secret before it |
| 555 | * writes the salt | 559 | * writes the salt |
| 556 | */ | 560 | */ |
| 557 | tpm2_KDFe(chip->auth->salt, "SECRET", x, chip->null_ec_key_x, | 561 | tpm2_KDFe(auth->salt, "SECRET", x, chip->null_ec_key_x, auth->salt); |
| 558 | chip->auth->salt); | ||
| 559 | 562 | ||
| 560 | out: | 563 | out: |
| 561 | crypto_free_kpp(kpp); | 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 | if (rc) | 856 | if (rc) |
| 854 | /* manually close the session if it wasn't consumed */ | 857 | /* manually close the session if it wasn't consumed */ |
| 855 | tpm2_flush_context(chip, auth->handle); | 858 | tpm2_flush_context(chip, auth->handle); |
| 856 | memzero_explicit(auth, sizeof(*auth)); | 859 | |
| 860 | kfree_sensitive(auth); | ||
| 861 | chip->auth = NULL; | ||
| 857 | } else { | 862 | } else { |
| 858 | /* reset for next use */ | 863 | /* reset for next use */ |
| 859 | auth->session = TPM_HEADER_SIZE; | 864 | auth->session = TPM_HEADER_SIZE; |
| @@ -881,7 +886,8 @@ void tpm2_end_auth_session(struct tpm_chip *chip) · 21 unmodified lines | |||
| 881 | return; | 886 | return; |
| 882 | 887 | ||
| 883 | tpm2_flush_context(chip, auth->handle); | 888 | tpm2_flush_context(chip, auth->handle); |
| 884 | memzero_explicit(auth, sizeof(*auth)); | 889 | kfree_sensitive(auth); |
| 890 | chip->auth = NULL; | ||
| 885 | } | 891 | } |
| 886 | EXPORT_SYMBOL(tpm2_end_auth_session); | 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 | static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key) | 922 | static int tpm2_load_null(struct tpm_chip *chip, u32 *null_key) |
| 917 | { | 923 | { |
| 918 | int rc; | ||
| 919 | unsigned int offset = 0; /* dummy offset for null seed context */ | 924 | unsigned int offset = 0; /* dummy offset for null seed context */ |
| 920 | u8 name[SHA256_DIGEST_SIZE + 2]; | 925 | u8 name[SHA256_DIGEST_SIZE + 2]; |
| 926 | u32 tmp_null_key; | ||
| 927 | int rc; | ||
| 921 | 928 | ||
| 922 | rc = tpm2_load_context(chip, chip->null_key_context, &offset, | 929 | rc = tpm2_load_context(chip, chip->null_key_context, &offset, |
| 923 | null_key); | 930 | &tmp_null_key); |
| 924 | if (rc != -EINVAL) | 931 | if (rc != -EINVAL) { |
| 925 | return rc; | 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 */ | 937 | /* Try to re-create null key, given the integrity failure: */ |
| 928 | dev_err(&chip->dev, "NULL key integrity failure!\n"); | 938 | rc = tpm2_create_primary(chip, TPM2_RH_NULL, &tmp_null_key, name); |
| 929 | /* check the null name against what we know */ | 939 | if (rc) |
| 930 | tpm2_create_primary(chip, TPM2_RH_NULL, NULL, name); | 940 | goto err; |
| 931 | if (memcmp(name, chip->null_key_name, sizeof(name)) == 0) | 941 | |
| 932 | /* name unchanged, assume transient integrity failure */ | 942 | /* Return null key if the name has not been changed: */ |
| 933 | return rc; | 943 | if (!memcmp(name, chip->null_key_name, sizeof(name))) { |
| 934 | /* | 944 | *null_key = tmp_null_key; |
| 935 | * Fatal TPM failure: the NULL seed has actually changed, so | 945 | return 0; |
| 936 | * the TPM must have been illegally reset. All in-kernel TPM | 946 | } |
| 937 | * operations will fail because the NULL primary can't be | 947 | |
| 938 | * loaded to salt the sessions, but disable the TPM anyway so | 948 | /* Deduce from the name change TPM interference: */ |
| 939 | * userspace programmes can't be compromised by it. | 949 | dev_err(&chip->dev, "null key integrity check failed\n"); |
| 940 | */ | 950 | tpm2_flush_context(chip, tmp_null_key); |
| 941 | dev_err(&chip->dev, "NULL name has changed, disabling TPM due to interference\n"); | ||
| 942 | chip->flags |= TPM_CHIP_FLAG_DISABLE; | 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 | int tpm2_start_auth_session(struct tpm_chip *chip) | 969 | int tpm2_start_auth_session(struct tpm_chip *chip) |
| 960 | { | 970 | { |
| 971 | struct tpm2_auth *auth; | ||
| 961 | struct tpm_buf buf; | 972 | struct tpm_buf buf; |
| 962 | struct tpm2_auth *auth = chip->auth; | ||
| 963 | int rc; | ||
| 964 | u32 null_key; | 973 | u32 null_key; |
| 974 | int rc; | ||
| 965 | 975 | ||
| 966 | if (!auth) { | 976 | if (chip->auth) { |
| 967 | dev_warn_once(&chip->dev, "auth session is not active\n"); | 977 | dev_warn_once(&chip->dev, "auth session is active\n"); |
| 968 | return 0; | 978 | return 0; |
| 969 | } | 979 | } |
| 970 | 980 | ||
| 981 | auth = kzalloc(sizeof(*auth), GFP_KERNEL); | ||
| 982 | if (!auth) | ||
| 983 | return -ENOMEM; | ||
| 984 | |||
| 971 | rc = tpm2_load_null(chip, &null_key); | 985 | rc = tpm2_load_null(chip, &null_key); |
| 972 | if (rc) | 986 | if (rc) |
| 973 | goto out; | 987 | goto out; |
| @@ -988,7 +1002,7 @@ int tpm2_start_auth_session(struct tpm_chip *chip) · 14 unmodified lines | |||
| 988 | tpm_buf_append(&buf, auth->our_nonce, sizeof(auth->our_nonce)); | 1002 | tpm_buf_append(&buf, auth->our_nonce, sizeof(auth->our_nonce)); |
| 989 | 1003 | ||
| 990 | /* append encrypted salt and squirrel away unencrypted in auth */ | 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 | /* session type (HMAC, audit or policy) */ | 1006 | /* session type (HMAC, audit or policy) */ |
| 993 | tpm_buf_append_u8(&buf, TPM2_SE_HMAC); | 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 | tpm_buf_destroy(&buf); | 1025 | tpm_buf_destroy(&buf); |
| 1012 | 1026 | ||
| 1013 | if (rc) | 1027 | if (rc == TPM2_RC_SUCCESS) { |
| 1014 | goto out; | 1028 | chip->auth = auth; |
| 1029 | return 0; | ||
| 1030 | } | ||
| 1015 | 1031 | ||
| 1016 | out: | 1032 | out: |
| 1033 | kfree_sensitive(auth); | ||
| 1017 | return rc; | 1034 | return rc; |
| 1018 | } | 1035 | } |
| 1019 | EXPORT_SYMBOL(tpm2_start_auth_session); | 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 | * Derive and context save the null primary and allocate memory in the | 1365 | * Derive and context save the null primary and allocate memory in the |
| 1349 | * struct tpm_chip for the authorizations. | 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 | int tpm2_sessions_init(struct tpm_chip *chip) | 1373 | int tpm2_sessions_init(struct tpm_chip *chip) |
| 1352 | { | 1374 | { |
| 1353 | int rc; | 1375 | int rc; |
| 1354 | 1376 | ||
| 1355 | rc = tpm2_create_null_primary(chip); | 1377 | rc = tpm2_create_null_primary(chip); |
| 1356 | if (rc) | 1378 | if (rc) { |
| 1357 | dev_err(&chip->dev, "TPM: security failed (NULL seed derivation): %d\n", rc); | 1379 | dev_err(&chip->dev, "null key creation failed with %d\n", rc); |
| 1358 | 1380 | return rc; | |
| 1359 | chip->auth = kmalloc(sizeof(*chip->auth), GFP_KERNEL); | 1381 | } |
| 1360 | if (!chip->auth) | ||
| 1361 | return -ENOMEM; | ||
| 1362 | 1382 | ||
| 1363 | return rc; | 1383 | return rc; |
| 1364 | } | 1384 | } |
| @@ -2006,25 +2006,27 @@ static int virtcons_probe(struct virtio_device *vdev) · 2005 unmodified lines | |||
| 2006 | multiport = true; | 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 | spin_lock_init(&portdev->ports_lock); | 2009 | spin_lock_init(&portdev->ports_lock); |
| 2016 | INIT_LIST_HEAD(&portdev->ports); | 2010 | INIT_LIST_HEAD(&portdev->ports); |
| 2017 | INIT_LIST_HEAD(&portdev->list); | 2011 | INIT_LIST_HEAD(&portdev->list); |
| 2018 | 2012 | ||
| 2019 | virtio_device_ready(portdev->vdev); | ||
| 2020 | |||
| 2021 | INIT_WORK(&portdev->config_work, &config_work_handler); | 2013 | INIT_WORK(&portdev->config_work, &config_work_handler); |
| 2022 | INIT_WORK(&portdev->control_work, &control_work_handler); | 2014 | INIT_WORK(&portdev->control_work, &control_work_handler); |
| 2023 | 2015 | ||
| 2024 | if (multiport) { | 2016 | if (multiport) { |
| 2025 | spin_lock_init(&portdev->c_ivq_lock); | 2017 | spin_lock_init(&portdev->c_ivq_lock); |
| 2026 | spin_lock_init(&portdev->c_ovq_lock); | 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 | err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); | 2030 | err = fill_queue(portdev->c_ivq, &portdev->c_ivq_lock); |
| 2029 | if (err < 0) { | 2031 | if (err < 0) { |
| 2030 | dev_err(&vdev->dev, | 2032 | dev_err(&vdev->dev, |
| @@ -473,7 +473,7 @@ clk_multiple_parents_mux_test_init(struct kunit *test) · 472 unmodified lines | |||
| 473 | &clk_dummy_rate_ops, | 473 | &clk_dummy_rate_ops, |
| 474 | 0); | 474 | 0); |
| 475 | ctx->parents_ctx[0].rate = DUMMY_CLOCK_RATE_1; | 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 | if (ret) | 477 | if (ret) |
| 478 | return ret; | 478 | return ret; |
| 479 | 479 | ||
| @@ -481,7 +481,7 @@ clk_multiple_parents_mux_test_init(struct kunit *test) · 1 unmodified line | |||
| 481 | &clk_dummy_rate_ops, | 481 | &clk_dummy_rate_ops, |
| 482 | 0); | 482 | 0); |
| 483 | ctx->parents_ctx[1].rate = DUMMY_CLOCK_RATE_2; | 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 | if (ret) | 485 | if (ret) |
| 486 | return ret; | 486 | return ret; |
| 487 | 487 | ||
| @@ -489,23 +489,13 @@ clk_multiple_parents_mux_test_init(struct kunit *test) · 1 unmodified line | |||
| 489 | ctx->hw.init = CLK_HW_INIT_PARENTS("test-mux", parents, | 489 | ctx->hw.init = CLK_HW_INIT_PARENTS("test-mux", parents, |
| 490 | &clk_multiple_parents_mux_ops, | 490 | &clk_multiple_parents_mux_ops, |
| 491 | CLK_SET_RATE_PARENT); | 491 | CLK_SET_RATE_PARENT); |
| 492 | ret = clk_hw_register(NULL, &ctx->hw); | 492 | ret = clk_hw_register_kunit(test, NULL, &ctx->hw); |
| 493 | if (ret) | 493 | if (ret) |
| 494 | return ret; | 494 | return ret; |
| 495 | 495 | ||
| 496 | return 0; | 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 | * Test that for a clock with multiple parents, clk_get_parent() | 500 | * Test that for a clock with multiple parents, clk_get_parent() |
| 511 | * actually returns the current one. | 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 | struct clk_multiple_parent_ctx *ctx = test->priv; | 552 | struct clk_multiple_parent_ctx *ctx = test->priv; |
| 563 | struct clk_hw *hw = &ctx->hw; | 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 | struct clk *parent1, *parent2; | 555 | struct clk *parent1, *parent2; |
| 566 | unsigned long rate; | 556 | unsigned long rate; |
| 567 | int ret; | 557 | int ret; |
| 568 | 558 | ||
| 569 | kunit_skip(test, "This needs to be fixed in the core."); | 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 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent1); | 562 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent1); |
| 573 | KUNIT_ASSERT_TRUE(test, clk_is_match(clk_get_parent(clk), parent1)); | 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 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent2); | 566 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent2); |
| 577 | 567 | ||
| 578 | ret = clk_set_rate(parent1, DUMMY_CLOCK_RATE_1); | 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 | KUNIT_ASSERT_GT(test, rate, 0); | 583 | KUNIT_ASSERT_GT(test, rate, 0); |
| 594 | KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1 - 1000); | 584 | KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1 - 1000); |
| 595 | KUNIT_EXPECT_LE(test, rate, DUMMY_CLOCK_RATE_1 + 1000); | 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 | static struct kunit_case clk_multiple_parents_mux_test_cases[] = { | 588 | static struct kunit_case clk_multiple_parents_mux_test_cases[] = { |
| @@ -617,7 +603,6 @@ static struct kunit_suite · 14 unmodified lines | |||
| 617 | clk_multiple_parents_mux_test_suite = { | 603 | clk_multiple_parents_mux_test_suite = { |
| 618 | .name = "clk-multiple-parents-mux-test", | 604 | .name = "clk-multiple-parents-mux-test", |
| 619 | .init = clk_multiple_parents_mux_test_init, | 605 | .init = clk_multiple_parents_mux_test_init, |
| 620 | .exit = clk_multiple_parents_mux_test_exit, | ||
| 621 | .test_cases = clk_multiple_parents_mux_test_cases, | 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 | &clk_dummy_rate_ops, | 622 | &clk_dummy_rate_ops, |
| 638 | 0); | 623 | 0); |
| 639 | ctx->parents_ctx[1].rate = DUMMY_CLOCK_INIT_RATE; | 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 | if (ret) | 626 | if (ret) |
| 642 | return ret; | 627 | return ret; |
| 643 | 628 | ||
| 644 | ctx->hw.init = CLK_HW_INIT_PARENTS("test-orphan-mux", parents, | 629 | ctx->hw.init = CLK_HW_INIT_PARENTS("test-orphan-mux", parents, |
| 645 | &clk_multiple_parents_mux_ops, | 630 | &clk_multiple_parents_mux_ops, |
| 646 | CLK_SET_RATE_PARENT); | 631 | CLK_SET_RATE_PARENT); |
| 647 | ret = clk_hw_register(NULL, &ctx->hw); | 632 | ret = clk_hw_register_kunit(test, NULL, &ctx->hw); |
| 648 | if (ret) | 633 | if (ret) |
| 649 | return ret; | 634 | return ret; |
| 650 | 635 | ||
| 651 | return 0; | 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 | * Test that, for a mux whose current parent hasn't been registered yet and is | 640 | * Test that, for a mux whose current parent hasn't been registered yet and is |
| 665 | * thus orphan, clk_get_parent() will return NULL. | 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 | struct clk_multiple_parent_ctx *ctx = test->priv; | 889 | struct clk_multiple_parent_ctx *ctx = test->priv; |
| 914 | struct clk_hw *hw = &ctx->hw; | 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 | struct clk *parent; | 892 | struct clk *parent; |
| 917 | unsigned long rate; | 893 | unsigned long rate; |
| 918 | int ret; | 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 | clk_hw_set_rate_range(hw, DUMMY_CLOCK_RATE_1, DUMMY_CLOCK_RATE_2); | 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 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent); | 901 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent); |
| 926 | 902 | ||
| 927 | ret = clk_set_parent(clk, parent); | 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 | KUNIT_ASSERT_GT(test, rate, 0); | 907 | KUNIT_ASSERT_GT(test, rate, 0); |
| 932 | KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1); | 908 | KUNIT_EXPECT_GE(test, rate, DUMMY_CLOCK_RATE_1); |
| 933 | KUNIT_EXPECT_LE(test, rate, DUMMY_CLOCK_RATE_2); | 909 | KUNIT_EXPECT_LE(test, rate, DUMMY_CLOCK_RATE_2); |
| 934 | |||
| 935 | clk_put(parent); | ||
| 936 | clk_put(clk); | ||
| 937 | } | 910 | } |
| 938 | 911 | ||
| 939 | static struct kunit_case clk_orphan_transparent_multiple_parent_mux_test_cases[] = { | 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 | static struct kunit_suite clk_orphan_transparent_multiple_parent_mux_test_suite = { | 934 | static struct kunit_suite clk_orphan_transparent_multiple_parent_mux_test_suite = { |
| 962 | .name = "clk-orphan-transparent-multiple-parent-mux-test", | 935 | .name = "clk-orphan-transparent-multiple-parent-mux-test", |
| 963 | .init = clk_orphan_transparent_multiple_parent_mux_test_init, | 936 | .init = clk_orphan_transparent_multiple_parent_mux_test_init, |
| 964 | .exit = clk_orphan_transparent_multiple_parent_mux_test_exit, | ||
| 965 | .test_cases = clk_orphan_transparent_multiple_parent_mux_test_cases, | 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 | &clk_dummy_rate_ops, | 958 | &clk_dummy_rate_ops, |
| 987 | 0); | 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 | if (ret) | 962 | if (ret) |
| 991 | return ret; | 963 | return ret; |
| 992 | 964 | ||
| @@ -994,7 +966,7 @@ static int clk_single_parent_mux_test_init(struct kunit *test) · 1 unmodified line | |||
| 994 | &clk_dummy_single_parent_ops, | 966 | &clk_dummy_single_parent_ops, |
| 995 | CLK_SET_RATE_PARENT); | 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 | if (ret) | 970 | if (ret) |
| 999 | return ret; | 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 | struct clk_single_parent_ctx *ctx = test->priv; | 1033 | struct clk_single_parent_ctx *ctx = test->priv; |
| 1062 | struct clk_hw *hw = &ctx->hw; | 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 | struct clk *parent; | 1036 | struct clk *parent; |
| 1065 | int ret; | 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 | ret = clk_set_rate_range(clk, 3000, 4000); | 1047 | ret = clk_set_rate_range(clk, 3000, 4000); |
| 1076 | KUNIT_EXPECT_LT(test, ret, 0); | 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 | struct clk_single_parent_ctx *ctx = test->priv; | 1063 | struct clk_single_parent_ctx *ctx = test->priv; |
| 1094 | struct clk_hw *hw = &ctx->hw; | 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 | struct clk *parent; | 1066 | struct clk *parent; |
| 1097 | int ret; | 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 | ret = clk_set_rate_range(parent, 3000, 4000); | 1077 | ret = clk_set_rate_range(parent, 3000, 4000); |
| 1108 | KUNIT_EXPECT_LT(test, ret, 0); | 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 | clk_single_parent_mux_test_suite = { | 1206 | clk_single_parent_mux_test_suite = { |
| 1239 | .name = "clk-single-parent-mux-test", | 1207 | .name = "clk-single-parent-mux-test", |
| 1240 | .init = clk_single_parent_mux_test_init, | 1208 | .init = clk_single_parent_mux_test_init, |
| 1241 | .exit = clk_single_parent_mux_test_exit, | ||
| 1242 | .test_cases = clk_single_parent_mux_test_cases, | 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 | if (list->id > max) | 439 | if (list->id > max) |
| 440 | max = list->id; | 440 | max = list->id; |
| 441 | if (list->child && list->child->id > max) | 441 | if (list->child && list->child->id > max) |
| 442 | max = list->id; | 442 | max = list->child->id; |
| 443 | } | 443 | } |
| 444 | 444 | ||
| 445 | return max; | 445 | return max; |
| @@ -1155,6 +1155,7 @@ static const struct of_device_id exynosautov920_cmu_of_match[] = { · 1154 unmodified lines | |||
| 1155 | .compatible = "samsung,exynosautov920-cmu-peric0", | 1155 | .compatible = "samsung,exynosautov920-cmu-peric0", |
| 1156 | .data = &peric0_cmu_info, | 1156 | .data = &peric0_cmu_info, |
| 1157 | }, | 1157 | }, |
| 1158 | { } | ||
| 1158 | }; | 1159 | }; |
| 1159 | 1160 | ||
| 1160 | static struct platform_driver exynosautov920_cmu_driver __refdata = { | 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 | static int amd_pstate_update_min_max_limit(struct cpufreq_policy *policy) | 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 | struct amd_cpudata *cpudata = policy->driver_data; | 540 | struct amd_cpudata *cpudata = policy->driver_data; |
| 541 | 541 | ||
| 542 | max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq); | 542 | if (cpudata->boost_supported && !policy->boost_enabled) |
| 543 | min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq); | 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 | lowest_perf = READ_ONCE(cpudata->lowest_perf); | 550 | lowest_perf = READ_ONCE(cpudata->lowest_perf); |
| 546 | if (min_limit_perf < lowest_perf) | 551 | if (min_limit_perf < lowest_perf) |
| @@ -1201,11 +1206,21 @@ static int amd_pstate_register_driver(int mode) · 654 unmodified lines | |||
| 1201 | return -EINVAL; | 1206 | return -EINVAL; |
| 1202 | 1207 | ||
| 1203 | cppc_state = mode; | 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 | ret = cpufreq_register_driver(current_pstate_driver); | 1218 | ret = cpufreq_register_driver(current_pstate_driver); |
| 1205 | if (ret) { | 1219 | if (ret) { |
| 1206 | amd_pstate_driver_cleanup(); | 1220 | amd_pstate_driver_cleanup(); |
| 1207 | return ret; | 1221 | return ret; |
| 1208 | } | 1222 | } |
| 1223 | |||
| 1209 | return 0; | 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 | u64 value; | 1511 | u64 value; |
| 1497 | s16 epp; | 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 | min_perf = READ_ONCE(cpudata->lowest_perf); | 1518 | min_perf = READ_ONCE(cpudata->lowest_perf); |
| 1501 | max_limit_perf = div_u64(policy->max * cpudata->highest_perf, cpudata->max_freq); | 1519 | max_limit_perf = div_u64(policy->max * max_perf, policy->cpuinfo.max_freq); |
| 1502 | min_limit_perf = div_u64(policy->min * cpudata->highest_perf, cpudata->max_freq); | 1520 | min_limit_perf = div_u64(policy->min * max_perf, policy->cpuinfo.max_freq); |
| 1503 | 1521 | ||
| 1504 | if (min_limit_perf < min_perf) | 1522 | if (min_limit_perf < min_perf) |
| 1505 | min_limit_perf = min_perf; | 1523 | min_limit_perf = min_perf; |
| @@ -947,7 +947,7 @@ struct ahash_alg mv_md5_alg = { · 946 unmodified lines | |||
| 947 | .base = { | 947 | .base = { |
| 948 | .cra_name = "md5", | 948 | .cra_name = "md5", |
| 949 | .cra_driver_name = "mv-md5", | 949 | .cra_driver_name = "mv-md5", |
| 950 | .cra_priority = 300, | 950 | .cra_priority = 0, |
| 951 | .cra_flags = CRYPTO_ALG_ASYNC | | 951 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 952 | CRYPTO_ALG_ALLOCATES_MEMORY | | 952 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 953 | CRYPTO_ALG_KERN_DRIVER_ONLY, | 953 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1018,7 +1018,7 @@ struct ahash_alg mv_sha1_alg = { · 64 unmodified lines | |||
| 1018 | .base = { | 1018 | .base = { |
| 1019 | .cra_name = "sha1", | 1019 | .cra_name = "sha1", |
| 1020 | .cra_driver_name = "mv-sha1", | 1020 | .cra_driver_name = "mv-sha1", |
| 1021 | .cra_priority = 300, | 1021 | .cra_priority = 0, |
| 1022 | .cra_flags = CRYPTO_ALG_ASYNC | | 1022 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1023 | CRYPTO_ALG_ALLOCATES_MEMORY | | 1023 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1024 | CRYPTO_ALG_KERN_DRIVER_ONLY, | 1024 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1092,7 +1092,7 @@ struct ahash_alg mv_sha256_alg = { · 67 unmodified lines | |||
| 1092 | .base = { | 1092 | .base = { |
| 1093 | .cra_name = "sha256", | 1093 | .cra_name = "sha256", |
| 1094 | .cra_driver_name = "mv-sha256", | 1094 | .cra_driver_name = "mv-sha256", |
| 1095 | .cra_priority = 300, | 1095 | .cra_priority = 0, |
| 1096 | .cra_flags = CRYPTO_ALG_ASYNC | | 1096 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1097 | CRYPTO_ALG_ALLOCATES_MEMORY | | 1097 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1098 | CRYPTO_ALG_KERN_DRIVER_ONLY, | 1098 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1302,7 +1302,7 @@ struct ahash_alg mv_ahmac_md5_alg = { · 203 unmodified lines | |||
| 1302 | .base = { | 1302 | .base = { |
| 1303 | .cra_name = "hmac(md5)", | 1303 | .cra_name = "hmac(md5)", |
| 1304 | .cra_driver_name = "mv-hmac-md5", | 1304 | .cra_driver_name = "mv-hmac-md5", |
| 1305 | .cra_priority = 300, | 1305 | .cra_priority = 0, |
| 1306 | .cra_flags = CRYPTO_ALG_ASYNC | | 1306 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1307 | CRYPTO_ALG_ALLOCATES_MEMORY | | 1307 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1308 | CRYPTO_ALG_KERN_DRIVER_ONLY, | 1308 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1373,7 +1373,7 @@ struct ahash_alg mv_ahmac_sha1_alg = { · 64 unmodified lines | |||
| 1373 | .base = { | 1373 | .base = { |
| 1374 | .cra_name = "hmac(sha1)", | 1374 | .cra_name = "hmac(sha1)", |
| 1375 | .cra_driver_name = "mv-hmac-sha1", | 1375 | .cra_driver_name = "mv-hmac-sha1", |
| 1376 | .cra_priority = 300, | 1376 | .cra_priority = 0, |
| 1377 | .cra_flags = CRYPTO_ALG_ASYNC | | 1377 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1378 | CRYPTO_ALG_ALLOCATES_MEMORY | | 1378 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1379 | CRYPTO_ALG_KERN_DRIVER_ONLY, | 1379 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -1444,7 +1444,7 @@ struct ahash_alg mv_ahmac_sha256_alg = { · 64 unmodified lines | |||
| 1444 | .base = { | 1444 | .base = { |
| 1445 | .cra_name = "hmac(sha256)", | 1445 | .cra_name = "hmac(sha256)", |
| 1446 | .cra_driver_name = "mv-hmac-sha256", | 1446 | .cra_driver_name = "mv-hmac-sha256", |
| 1447 | .cra_priority = 300, | 1447 | .cra_priority = 0, |
| 1448 | .cra_flags = CRYPTO_ALG_ASYNC | | 1448 | .cra_flags = CRYPTO_ALG_ASYNC | |
| 1449 | CRYPTO_ALG_ALLOCATES_MEMORY | | 1449 | CRYPTO_ALG_ALLOCATES_MEMORY | |
| 1450 | CRYPTO_ALG_KERN_DRIVER_ONLY, | 1450 | CRYPTO_ALG_KERN_DRIVER_ONLY, |
| @@ -60,6 +60,7 @@ config CXL_ACPI · 59 unmodified lines | |||
| 60 | default CXL_BUS | 60 | default CXL_BUS |
| 61 | select ACPI_TABLE_LIB | 61 | select ACPI_TABLE_LIB |
| 62 | select ACPI_HMAT | 62 | select ACPI_HMAT |
| 63 | select CXL_PORT | ||
| 63 | help | 64 | help |
| 64 | Enable support for host managed device memory (HDM) resources | 65 | Enable support for host managed device memory (HDM) resources |
| 65 | published by a platform's ACPI CXL memory layout description. See | 66 | published by a platform's ACPI CXL memory layout description. See |
| @@ -1,13 +1,21 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0 | 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 | obj-y += core/ | 10 | obj-y += core/ |
| 3 | obj-$(CONFIG_CXL_PCI) += cxl_pci.o | 11 | obj-$(CONFIG_CXL_PORT) += cxl_port.o |
| 4 | obj-$(CONFIG_CXL_MEM) += cxl_mem.o | ||
| 5 | obj-$(CONFIG_CXL_ACPI) += cxl_acpi.o | 12 | obj-$(CONFIG_CXL_ACPI) += cxl_acpi.o |
| 6 | obj-$(CONFIG_CXL_PMEM) += cxl_pmem.o | 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 | 17 | cxl_port-y := port.o |
| 10 | cxl_pci-y := pci.o | ||
| 11 | cxl_acpi-y := acpi.o | 18 | cxl_acpi-y := acpi.o |
| 12 | cxl_pmem-y := pmem.o security.o | 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 | /* load before dax_hmem sees 'Soft Reserved' CXL ranges */ | 925 | /* load before dax_hmem sees 'Soft Reserved' CXL ranges */ |
| 926 | subsys_initcall(cxl_acpi_init); | 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 | module_exit(cxl_acpi_exit); | 934 | module_exit(cxl_acpi_exit); |
| 928 | MODULE_DESCRIPTION("CXL ACPI: Platform Support"); | 935 | MODULE_DESCRIPTION("CXL ACPI: Platform Support"); |
| 929 | MODULE_LICENSE("GPL v2"); | 936 | MODULE_LICENSE("GPL v2"); |
| @@ -641,6 +641,9 @@ static int cxl_endpoint_gather_bandwidth(struct cxl_region *cxlr, · 640 unmodified lines | |||
| 641 | void *ptr; | 641 | void *ptr; |
| 642 | int rc; | 642 | int rc; |
| 643 | 643 | ||
| 644 | if (!dev_is_pci(cxlds->dev)) | ||
| 645 | return -ENODEV; | ||
| 646 | |||
| 644 | if (cxlds->rcd) | 647 | if (cxlds->rcd) |
| 645 | return -ENODEV; | 648 | return -ENODEV; |
| 646 | 649 | ||
| @@ -712,7 +712,44 @@ static int cxl_decoder_commit(struct cxl_decoder *cxld) · 711 unmodified lines | |||
| 712 | return 0; | 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 | struct cxl_port *port = to_cxl_port(cxld->dev.parent); | 754 | struct cxl_port *port = to_cxl_port(cxld->dev.parent); |
| 718 | struct cxl_hdm *cxlhdm = dev_get_drvdata(&port->dev); | 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 | u32 ctrl; | 758 | u32 ctrl; |
| 722 | 759 | ||
| 723 | if ((cxld->flags & CXL_DECODER_F_ENABLE) == 0) | 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 | dev_dbg(&port->dev, | 766 | dev_dbg(&port->dev, |
| 728 | "%s: out of order reset, expected decoder%d.%d\n", | 767 | "%s: out of order reset, expected decoder%d.%d\n", |
| 729 | dev_name(&cxld->dev), port->id, port->commit_end); | 768 | dev_name(&cxld->dev), port->id, port->commit_end); |
| 730 | return -EBUSY; | ||
| 731 | } | ||
| 732 | 769 | ||
| 733 | down_read(&cxl_dpa_rwsem); | 770 | down_read(&cxl_dpa_rwsem); |
| 734 | ctrl = readl(hdm + CXL_HDM_DECODER0_CTRL_OFFSET(id)); | 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 | writel(0, hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(id)); | 778 | writel(0, hdm + CXL_HDM_DECODER0_BASE_LOW_OFFSET(id)); |
| 742 | up_read(&cxl_dpa_rwsem); | 779 | up_read(&cxl_dpa_rwsem); |
| 743 | 780 | ||
| 744 | port->commit_end--; | ||
| 745 | cxld->flags &= ~CXL_DECODER_F_ENABLE; | 781 | cxld->flags &= ~CXL_DECODER_F_ENABLE; |
| 746 | 782 | ||
| 747 | /* Userspace is now responsible for reconfiguring this decoder */ | 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 | cxled = to_cxl_endpoint_decoder(&cxld->dev); | 787 | cxled = to_cxl_endpoint_decoder(&cxld->dev); |
| 752 | cxled->state = CXL_DECODER_STATE_MANUAL; | 788 | cxled->state = CXL_DECODER_STATE_MANUAL; |
| 753 | } | 789 | } |
| 754 | |||
| 755 | return 0; | ||
| 756 | } | 790 | } |
| 757 | 791 | ||
| 758 | static int cxl_setup_hdm_decoder_from_dvsec( | 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 | static struct workqueue_struct *cxl_bus_wq; | 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 | void cxl_bus_rescan(void) | 2101 | void cxl_bus_rescan(void) |
| @@ -232,8 +232,8 @@ static int cxl_region_invalidate_memregion(struct cxl_region *cxlr) · 231 unmodified lines | |||
| 232 | "Bypassing cpu_cache_invalidate_memregion() for testing!\n"); | 232 | "Bypassing cpu_cache_invalidate_memregion() for testing!\n"); |
| 233 | return 0; | 233 | return 0; |
| 234 | } else { | 234 | } else { |
| 235 | dev_err(&cxlr->dev, | 235 | dev_WARN(&cxlr->dev, |
| 236 | "Failed to synchronize CPU cache state\n"); | 236 | "Failed to synchronize CPU cache state\n"); |
| 237 | return -ENXIO; | 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 | return 0; | 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 | struct cxl_region_params *p = &cxlr->params; | 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 | 251 | * Before region teardown attempt to flush, evict any data cached for |
| 252 | * fails cancel the region teardown for data consistency | 252 | * this region, or scream loudly about missing arch / platform support |
| 253 | * concerns | 253 | * for CXL teardown. |
| 254 | */ | 254 | */ |
| 255 | rc = cxl_region_invalidate_memregion(cxlr); | 255 | cxl_region_invalidate_memregion(cxlr); |
| 256 | if (rc) | ||
| 257 | return rc; | ||
| 258 | 256 | ||
| 259 | for (i = count - 1; i >= 0; i--) { | 257 | for (i = count - 1; i >= 0; i--) { |
| 260 | struct cxl_endpoint_decoder *cxled = p->targets[i]; | 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 | cxl_rr = cxl_rr_load(iter, cxlr); | 275 | cxl_rr = cxl_rr_load(iter, cxlr); |
| 278 | cxld = cxl_rr->decoder; | 276 | cxld = cxl_rr->decoder; |
| 279 | if (cxld->reset) | 277 | if (cxld->reset) |
| 280 | rc = cxld->reset(cxld); | 278 | cxld->reset(cxld); |
| 281 | if (rc) | ||
| 282 | return rc; | ||
| 283 | set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags); | 279 | set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags); |
| 284 | } | 280 | } |
| 285 | 281 | ||
| 286 | endpoint_reset: | 282 | endpoint_reset: |
| 287 | rc = cxled->cxld.reset(&cxled->cxld); | 283 | cxled->cxld.reset(&cxled->cxld); |
| 288 | if (rc) | ||
| 289 | return rc; | ||
| 290 | set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags); | 284 | set_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags); |
| 291 | } | 285 | } |
| 292 | 286 | ||
| 293 | /* all decoders associated with this region have been torn down */ | 287 | /* all decoders associated with this region have been torn down */ |
| 294 | clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags); | 288 | clear_bit(CXL_REGION_F_NEEDS_RESET, &cxlr->flags); |
| 295 | |||
| 296 | return 0; | ||
| 297 | } | 289 | } |
| 298 | 290 | ||
| 299 | static int commit_decoder(struct cxl_decoder *cxld) | 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 | * still pending. | 401 | * still pending. |
| 410 | */ | 402 | */ |
| 411 | if (p->state == CXL_CONFIG_RESET_PENDING) { | 403 | if (p->state == CXL_CONFIG_RESET_PENDING) { |
| 412 | rc = cxl_region_decode_reset(cxlr, p->interleave_ways); | 404 | cxl_region_decode_reset(cxlr, p->interleave_ways); |
| 413 | /* | 405 | p->state = CXL_CONFIG_ACTIVE; |
| 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; | ||
| 422 | } | 406 | } |
| 423 | } | 407 | } |
| 424 | 408 | ||
| @@ -794,26 +778,50 @@ out: · 369 unmodified lines | |||
| 794 | return rc; | 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 | static int match_free_decoder(struct device *dev, void *data) | 795 | static int match_free_decoder(struct device *dev, void *data) |
| 798 | { | 796 | { |
| 797 | struct cxl_port *port = to_cxl_port(dev->parent); | ||
| 799 | struct cxl_decoder *cxld; | 798 | struct cxl_decoder *cxld; |
| 800 | int *id = data; | 799 | int rc; |
| 801 | 800 | ||
| 802 | if (!is_switch_decoder(dev)) | 801 | if (!is_switch_decoder(dev)) |
| 803 | return 0; | 802 | return 0; |
| 804 | 803 | ||
| 805 | cxld = to_cxl_decoder(dev); | 804 | cxld = to_cxl_decoder(dev); |
| 806 | 805 | ||
| 807 | /* enforce ordered allocation */ | 806 | if (cxld->id != port->commit_end + 1) |
| 808 | if (cxld->id != *id) | ||
| 809 | return 0; | 807 | return 0; |
| 810 | 808 | ||
| 811 | if (!cxld->region) | 809 | if (cxld->region) { |
| 812 | return 1; | 810 | dev_dbg(dev->parent, |
| 813 | 811 | "next decoder to commit (%s) is already reserved (%s)\n", | |
| 814 | (*id)++; | 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 | static int match_auto_decoder(struct device *dev, void *data) | 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 | struct cxl_region *cxlr) | 848 | struct cxl_region *cxlr) |
| 841 | { | 849 | { |
| 842 | struct device *dev; | 850 | struct device *dev; |
| 843 | int id = 0; | ||
| 844 | 851 | ||
| 845 | if (port == cxled_to_port(cxled)) | 852 | if (port == cxled_to_port(cxled)) |
| 846 | return &cxled->cxld; | 853 | return &cxled->cxld; |
| @@ -849,7 +856,7 @@ cxl_region_find_decoder(struct cxl_port *port, · 2 unmodified lines | |||
| 849 | dev = device_find_child(&port->dev, &cxlr->params, | 856 | dev = device_find_child(&port->dev, &cxlr->params, |
| 850 | match_auto_decoder); | 857 | match_auto_decoder); |
| 851 | else | 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 | if (!dev) | 860 | if (!dev) |
| 854 | return NULL; | 861 | return NULL; |
| 855 | /* | 862 | /* |
| @@ -2054,13 +2061,7 @@ static int cxl_region_detach(struct cxl_endpoint_decoder *cxled) · 1198 unmodified lines | |||
| 2054 | get_device(&cxlr->dev); | 2061 | get_device(&cxlr->dev); |
| 2055 | 2062 | ||
| 2056 | if (p->state > CXL_CONFIG_ACTIVE) { | 2063 | if (p->state > CXL_CONFIG_ACTIVE) { |
| 2057 | /* | 2064 | cxl_region_decode_reset(cxlr, p->interleave_ways); |
| 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 | p->state = CXL_CONFIG_ACTIVE; | 2065 | p->state = CXL_CONFIG_ACTIVE; |
| 2065 | } | 2066 | } |
| 2066 | 2067 | ||
| @@ -279,7 +279,7 @@ TRACE_EVENT(cxl_generic_event, · 278 unmodified lines | |||
| 279 | #define CXL_GMER_MEM_EVT_TYPE_ECC_ERROR 0x00 | 279 | #define CXL_GMER_MEM_EVT_TYPE_ECC_ERROR 0x00 |
| 280 | #define CXL_GMER_MEM_EVT_TYPE_INV_ADDR 0x01 | 280 | #define CXL_GMER_MEM_EVT_TYPE_INV_ADDR 0x01 |
| 281 | #define CXL_GMER_MEM_EVT_TYPE_DATA_PATH_ERROR 0x02 | 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 | { CXL_GMER_MEM_EVT_TYPE_ECC_ERROR, "ECC Error" }, \ | 283 | { CXL_GMER_MEM_EVT_TYPE_ECC_ERROR, "ECC Error" }, \ |
| 284 | { CXL_GMER_MEM_EVT_TYPE_INV_ADDR, "Invalid Address" }, \ | 284 | { CXL_GMER_MEM_EVT_TYPE_INV_ADDR, "Invalid Address" }, \ |
| 285 | { CXL_GMER_MEM_EVT_TYPE_DATA_PATH_ERROR, "Data Path Error" } \ | 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 | "hpa=%llx region=%s region_uuid=%pUb", | 373 | "hpa=%llx region=%s region_uuid=%pUb", |
| 374 | __entry->dpa, show_dpa_flags(__entry->dpa_flags), | 374 | __entry->dpa, show_dpa_flags(__entry->dpa_flags), |
| 375 | show_event_desc_flags(__entry->descriptor), | 375 | show_event_desc_flags(__entry->descriptor), |
| 376 | show_mem_event_type(__entry->type), | 376 | show_gmer_mem_event_type(__entry->type), |
| 377 | show_trans_type(__entry->transaction_type), | 377 | show_trans_type(__entry->transaction_type), |
| 378 | __entry->channel, __entry->rank, __entry->device, | 378 | __entry->channel, __entry->rank, __entry->device, |
| 379 | __print_hex(__entry->comp_id, CXL_EVENT_GEN_MED_COMP_ID_SIZE), | 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 | * DRAM Event Record defines many fields the same as the General Media Event | 391 | * DRAM Event Record defines many fields the same as the General Media Event |
| 392 | * Record. Reuse those definitions as appropriate. | 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 | #define CXL_DER_VALID_CHANNEL BIT(0) | 405 | #define CXL_DER_VALID_CHANNEL BIT(0) |
| 395 | #define CXL_DER_VALID_RANK BIT(1) | 406 | #define CXL_DER_VALID_RANK BIT(1) |
| 396 | #define CXL_DER_VALID_NIBBLE BIT(2) | 407 | #define CXL_DER_VALID_NIBBLE BIT(2) |
| @@ -477,7 +488,7 @@ TRACE_EVENT(cxl_dram, · 80 unmodified lines | |||
| 477 | "hpa=%llx region=%s region_uuid=%pUb", | 488 | "hpa=%llx region=%s region_uuid=%pUb", |
| 478 | __entry->dpa, show_dpa_flags(__entry->dpa_flags), | 489 | __entry->dpa, show_dpa_flags(__entry->dpa_flags), |
| 479 | show_event_desc_flags(__entry->descriptor), | 490 | show_event_desc_flags(__entry->descriptor), |
| 480 | show_mem_event_type(__entry->type), | 491 | show_dram_mem_event_type(__entry->type), |
| 481 | show_trans_type(__entry->transaction_type), | 492 | show_trans_type(__entry->transaction_type), |
| 482 | __entry->channel, __entry->rank, __entry->nibble_mask, | 493 | __entry->channel, __entry->rank, __entry->nibble_mask, |
| 483 | __entry->bank_group, __entry->bank, | 494 | __entry->bank_group, __entry->bank, |
| @@ -359,7 +359,7 @@ struct cxl_decoder { · 358 unmodified lines | |||
| 359 | struct cxl_region *region; | 359 | struct cxl_region *region; |
| 360 | unsigned long flags; | 360 | unsigned long flags; |
| 361 | int (*commit)(struct cxl_decoder *cxld); | 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 | int cxl_num_decoders_committed(struct cxl_port *port); | 730 | int cxl_num_decoders_committed(struct cxl_port *port); |
| 731 | bool is_cxl_port(const struct device *dev); | 731 | bool is_cxl_port(const struct device *dev); |
| 732 | struct cxl_port *to_cxl_port(const struct device *dev); | 732 | struct cxl_port *to_cxl_port(const struct device *dev); |
| 733 | void cxl_port_commit_reap(struct cxl_decoder *cxld); | ||
| 733 | struct pci_bus; | 734 | struct pci_bus; |
| 734 | int devm_cxl_register_pci_bus(struct device *host, struct device *uport_dev, | 735 | int devm_cxl_register_pci_bus(struct device *host, struct device *uport_dev, |
| 735 | struct pci_bus *bus); | 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 | MODULE_DESCRIPTION("CXL: Port enumeration and services"); | 227 | MODULE_DESCRIPTION("CXL: Port enumeration and services"); |
| 213 | MODULE_LICENSE("GPL v2"); | 228 | MODULE_LICENSE("GPL v2"); |
| 214 | MODULE_IMPORT_NS(CXL); | 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 | nr_pages = 1; | 86 | nr_pages = 1; |
| 87 | 87 | ||
| 88 | pgoff = linear_page_index(vmf->vma, | 88 | pgoff = linear_page_index(vmf->vma, |
| 89 | ALIGN(vmf->address, fault_size)); | 89 | ALIGN_DOWN(vmf->address, fault_size)); |
| 90 | 90 | ||
| 91 | for (i = 0; i < nr_pages; i++) { | 91 | for (i = 0; i < nr_pages; i++) { |
| 92 | struct page *page = pfn_to_page(pfn_t_to_pfn(pfn) + i); | 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 | INIT_LIST_HEAD(&dma_dev->channels); | 1391 | INIT_LIST_HEAD(&dma_dev->channels); |
| 1392 | for (i = 0; i < edma->num_channels; i++) { | 1392 | for (i = 0; i < edma->num_channels; i++) { |
| 1393 | struct ep93xx_dma_chan *edmac = &edma->channels[i]; | 1393 | struct ep93xx_dma_chan *edmac = &edma->channels[i]; |
| 1394 | int len; | ||
| 1394 | 1395 | ||
| 1395 | edmac->chan.device = dma_dev; | 1396 | edmac->chan.device = dma_dev; |
| 1396 | edmac->regs = devm_platform_ioremap_resource(pdev, i); | 1397 | edmac->regs = devm_platform_ioremap_resource(pdev, i); |
| 1397 | if (IS_ERR(edmac->regs)) | 1398 | if (IS_ERR(edmac->regs)) |
| 1398 | return edmac->regs; | 1399 | return ERR_CAST(edmac->regs); |
| 1399 | 1400 | ||
| 1400 | edmac->irq = fwnode_irq_get(dev_fwnode(dev), i); | 1401 | edmac->irq = fwnode_irq_get(dev_fwnode(dev), i); |
| 1401 | if (edmac->irq < 0) | 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 | edmac->edma = edma; | 1405 | edmac->edma = edma; |
| 1405 | 1406 | ||
| 1406 | if (edma->m2m) | 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 | else | 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 | edmac->clk = devm_clk_get(dev, dma_clk_name); | 1414 | edmac->clk = devm_clk_get(dev, dma_clk_name); |
| 1412 | if (IS_ERR(edmac->clk)) { | 1415 | if (IS_ERR(edmac->clk)) { |
| @@ -601,22 +601,25 @@ static int rz_dmac_config(struct dma_chan *chan, · 600 unmodified lines | |||
| 601 | struct rz_dmac_chan *channel = to_rz_dmac_chan(chan); | 601 | struct rz_dmac_chan *channel = to_rz_dmac_chan(chan); |
| 602 | u32 val; | 602 | u32 val; |
| 603 | 603 | ||
| 604 | channel->src_per_address = config->src_addr; | ||
| 605 | channel->dst_per_address = config->dst_addr; | 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 | channel->chcfg &= ~CHCFG_FILL_DDS_MASK; | 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); | 611 | channel->chcfg |= FIELD_PREP(CHCFG_FILL_DDS_MASK, val); |
| 615 | if (val == CHCFG_DS_INVALID) | 612 | } |
| 616 | return -EINVAL; | ||
| 617 | 613 | ||
| 614 | channel->src_per_address = config->src_addr; | ||
| 618 | channel->chcfg &= ~CHCFG_FILL_SDS_MASK; | 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 | return 0; | 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 | d->static_tr.elcnt = elcnt; | 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 | if (uc->config.pkt_mode || !uc->cyclic) { | 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 | unsigned int div = dev_width * elcnt; | 3195 | unsigned int div = dev_width * elcnt; |
| 3196 | 3196 | ||
| 3197 | if (uc->cyclic) | 3197 | if (uc->cyclic) |
| 3198 | d->static_tr.bstcnt = d->residue / d->sglen / div; | 3198 | d->static_tr.bstcnt = d->residue / d->sglen / div; |
| 3199 | else | 3199 | else |
| 3200 | d->static_tr.bstcnt = d->residue / div; | 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 && | 3212 | d->static_tr.bstcnt = |
| 3203 | d->static_tr.bstcnt > uc->ud->match_data->statictr_z_mask) | 3213 | (tr_req->icnt0 * tr_req->icnt1) / dev_width; |
| 3204 | return -EINVAL; | ||
| 3205 | } else { | 3214 | } else { |
| 3206 | d->static_tr.bstcnt = 0; | 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 | return 0; | 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 | /* static TR for remote PDMA */ | 3463 | /* static TR for remote PDMA */ |
| 3451 | if (udma_configure_statictr(uc, d, dev_width, burst)) { | 3464 | if (udma_configure_statictr(uc, d, dev_width, burst)) { |
| 3452 | dev_err(uc->ud->dev, | 3465 | dev_err(uc->ud->dev, |
| 3453 | "%s: StaticTR Z is limited to maximum 4095 (%u)\n", | 3466 | "%s: StaticTR Z is limited to maximum %u (%u)\n", |
| 3454 | __func__, d->static_tr.bstcnt); | 3467 | __func__, uc->ud->match_data->statictr_z_mask, |
| 3468 | d->static_tr.bstcnt); | ||
| 3455 | 3469 | ||
| 3456 | udma_free_hwdesc(uc, d); | 3470 | udma_free_hwdesc(uc, d); |
| 3457 | kfree(d); | 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 | u16 tr0_cnt0, tr0_cnt1, tr1_cnt0; | 3490 | u16 tr0_cnt0, tr0_cnt1, tr1_cnt0; |
| 3477 | unsigned int i; | 3491 | unsigned int i; |
| 3478 | int num_tr; | 3492 | int num_tr; |
| 3493 | u32 period_csf = 0; | ||
| 3479 | 3494 | ||
| 3480 | num_tr = udma_get_tr_counters(period_len, __ffs(buf_addr), &tr0_cnt0, | 3495 | num_tr = udma_get_tr_counters(period_len, __ffs(buf_addr), &tr0_cnt0, |
| 3481 | &tr0_cnt1, &tr1_cnt0); | 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 | period_addr = buf_addr | | 3513 | period_addr = buf_addr | |
| 3499 | ((u64)uc->config.asel << K3_ADDRESS_ASEL_SHIFT); | 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 | for (i = 0; i < periods; i++) { | 3530 | for (i = 0; i < periods; i++) { |
| 3502 | int tr_idx = i * num_tr; | 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 | if (!(flags & DMA_PREP_INTERRUPT)) | 3556 | if (!(flags & DMA_PREP_INTERRUPT)) |
| 3528 | cppi5_tr_csf_set(&tr_req[tr_idx].flags, | 3557 | period_csf |= CPPI5_TR_CSF_SUPR_EVT; |
| 3529 | 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 | period_addr += period_len; | 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 | /* static TR for remote PDMA */ | 3686 | /* static TR for remote PDMA */ |
| 3656 | if (udma_configure_statictr(uc, d, dev_width, burst)) { | 3687 | if (udma_configure_statictr(uc, d, dev_width, burst)) { |
| 3657 | dev_err(uc->ud->dev, | 3688 | dev_err(uc->ud->dev, |
| 3658 | "%s: StaticTR Z is limited to maximum 4095 (%u)\n", | 3689 | "%s: StaticTR Z is limited to maximum %u (%u)\n", |
| 3659 | __func__, d->static_tr.bstcnt); | 3690 | __func__, uc->ud->match_data->statictr_z_mask, |
| 3691 | d->static_tr.bstcnt); | ||
| 3660 | 3692 | ||
| 3661 | udma_free_hwdesc(uc, d); | 3693 | udma_free_hwdesc(uc, d); |
| 3662 | kfree(d); | 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 | // the node->ports array where the parent node should be. Later, | 204 | // the node->ports array where the parent node should be. Later, |
| 205 | // when we handle the parent node, we fix up the reference. | 205 | // when we handle the parent node, we fix up the reference. |
| 206 | ++parent_count; | 206 | ++parent_count; |
| 207 | node->color = i; | 207 | node->color = port_index; |
| 208 | break; | 208 | break; |
| 209 | 209 | ||
| 210 | case PHY_PACKET_SELF_ID_PORT_STATUS_CHILD: | 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 | struct ffa_send_direct_data2 *data) | 481 | struct ffa_send_direct_data2 *data) |
| 482 | { | 482 | { |
| 483 | u32 src_dst_ids = PACK_TARGET_INFO(src_id, dst_id); | 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 | ffa_value_t ret, args = { | 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 | memcpy((void *)&args + offsetof(ffa_value_t, a4), data, sizeof(*data)); | 494 | memcpy((void *)&args + offsetof(ffa_value_t, a4), data, sizeof(*data)); |
| 490 | 495 | ||
| 491 | invoke_ffa_fn(args, &ret); | 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 | return ffa_to_linux_errno((int)ret.a2); | 501 | return ffa_to_linux_errno((int)ret.a2); |
| 497 | 502 | ||
| 498 | if (ret.a0 == FFA_MSG_SEND_DIRECT_RESP2) { | 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 | return 0; | 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 | dbg->top_dentry = top_dentry; | 2976 | dbg->top_dentry = top_dentry; |
| 2977 | 2977 | ||
| 2978 | if (devm_add_action_or_reset(info->dev, | 2978 | if (devm_add_action_or_reset(info->dev, |
| 2979 | scmi_debugfs_common_cleanup, dbg)) { | 2979 | scmi_debugfs_common_cleanup, dbg)) |
| 2980 | scmi_debugfs_common_cleanup(dbg); | ||
| 2981 | return NULL; | 2980 | return NULL; |
| 2982 | } | ||
| 2983 | 2981 | ||
| 2984 | return dbg; | 2982 | return dbg; |
| 2985 | } | 2983 | } |
| @@ -1,8 +1,10 @@ | |||
| 1 | # SPDX-License-Identifier: GPL-2.0-only | 1 | # SPDX-License-Identifier: GPL-2.0-only |
| 2 | scmi_transport_mailbox-objs := mailbox.o | 2 | # Keep before scmi_transport_mailbox.o to allow precedence |
| 3 | obj-$(CONFIG_ARM_SCMI_TRANSPORT_MAILBOX) += scmi_transport_mailbox.o | 3 | # while matching the compatible. |
| 4 | scmi_transport_smc-objs := smc.o | 4 | scmi_transport_smc-objs := smc.o |
| 5 | obj-$(CONFIG_ARM_SCMI_TRANSPORT_SMC) += scmi_transport_smc.o | 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 | scmi_transport_optee-objs := optee.o | 8 | scmi_transport_optee-objs := optee.o |
| 7 | obj-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += scmi_transport_optee.o | 9 | obj-$(CONFIG_ARM_SCMI_TRANSPORT_OPTEE) += scmi_transport_optee.o |
| 8 | scmi_transport_virtio-objs := virtio.o | 10 | scmi_transport_virtio-objs := virtio.o |
| @@ -25,6 +25,7 @@ · 24 unmodified lines | |||
| 25 | * @chan_platform_receiver: Optional Platform Receiver mailbox unidirectional channel | 25 | * @chan_platform_receiver: Optional Platform Receiver mailbox unidirectional channel |
| 26 | * @cinfo: SCMI channel info | 26 | * @cinfo: SCMI channel info |
| 27 | * @shmem: Transmit/Receive shared memory area | 27 | * @shmem: Transmit/Receive shared memory area |
| 28 | * @chan_lock: Lock that prevents multiple xfers from being queued | ||
| 28 | */ | 29 | */ |
| 29 | struct scmi_mailbox { | 30 | struct scmi_mailbox { |
| 30 | struct mbox_client cl; | 31 | struct mbox_client cl; |
| @@ -33,6 +34,7 @@ struct scmi_mailbox { · 2 unmodified lines | |||
| 33 | struct mbox_chan *chan_platform_receiver; | 34 | struct mbox_chan *chan_platform_receiver; |
| 34 | struct scmi_chan_info *cinfo; | 35 | struct scmi_chan_info *cinfo; |
| 35 | struct scmi_shared_mem __iomem *shmem; | 36 | struct scmi_shared_mem __iomem *shmem; |
| 37 | struct mutex chan_lock; | ||
| 36 | }; | 38 | }; |
| 37 | 39 | ||
| 38 | #define client_to_scmi_mailbox(c) container_of(c, struct scmi_mailbox, cl) | 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 | cinfo->transport_info = smbox; | 241 | cinfo->transport_info = smbox; |
| 240 | smbox->cinfo = cinfo; | 242 | smbox->cinfo = cinfo; |
| 243 | mutex_init(&smbox->chan_lock); | ||
| 241 | 244 | ||
| 242 | return 0; | 245 | return 0; |
| 243 | } | 246 | } |
| @@ -267,13 +270,23 @@ static int mailbox_send_message(struct scmi_chan_info *cinfo, · 23 unmodified lines | |||
| 267 | struct scmi_mailbox *smbox = cinfo->transport_info; | 270 | struct scmi_mailbox *smbox = cinfo->transport_info; |
| 268 | int ret; | 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 */ | 282 | ret = mbox_send_message(smbox->chan, xfer); |
| 273 | if (ret > 0) | 283 | /* mbox_send_message returns non-negative value on success */ |
| 274 | ret = 0; | 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 | static void mailbox_mark_txdone(struct scmi_chan_info *cinfo, int ret, | 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 | struct scmi_mailbox *smbox = cinfo->transport_info; | 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 | mbox_client_txdone(smbox->chan, ret); | 297 | mbox_client_txdone(smbox->chan, ret); |
| 298 | |||
| 299 | /* Release channel */ | ||
| 300 | mutex_unlock(&smbox->chan_lock); | ||
| 291 | } | 301 | } |
| 292 | 302 | ||
| 293 | static void mailbox_fetch_response(struct scmi_chan_info *cinfo, | 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 | int err; | 763 | int err; |
| 764 | 764 | ||
| 765 | /* unregister private events */ | 765 | /* unregister private events */ |
| 766 | cpuhp_remove_state(sdei_entry_point); | 766 | cpuhp_remove_state(sdei_hp_state); |
| 767 | 767 | ||
| 768 | err = sdei_unregister_shared(); | 768 | err = sdei_unregister_shared(); |
| 769 | if (err) | 769 | if (err) |
| @@ -406,6 +406,8 @@ static void __aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, · 405 unmodified lines | |||
| 406 | gpio->dcache[GPIO_BANK(offset)] = reg; | 406 | gpio->dcache[GPIO_BANK(offset)] = reg; |
| 407 | 407 | ||
| 408 | iowrite32(reg, addr); | 408 | iowrite32(reg, addr); |
| 409 | /* Flush write */ | ||
| 410 | ioread32(addr); | ||
| 409 | } | 411 | } |
| 410 | 412 | ||
| 411 | static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, | 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 | if (!gpio_id) | 1193 | if (!gpio_id) |
| 1192 | return -EINVAL; | 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 | if (IS_ERR(gpio->clk)) { | 1197 | if (IS_ERR(gpio->clk)) { |
| 1196 | dev_warn(&pdev->dev, | 1198 | dev_warn(&pdev->dev, |
| 1197 | "Failed to get clock from devicetree, debouncing disabled\n"); | 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 | if (!priv) | 234 | if (!priv) |
| 235 | return -ENOMEM; | 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 | fops_buf_size_set(priv, GPIO_LA_DEFAULT_BUF_SIZE); | 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 | struct fwnode_reference_args args; | 64 | struct fwnode_reference_args args; |
| 65 | struct gpio_desc *desc; | 65 | struct gpio_desc *desc; |
| 66 | char propname[32]; /* 32 is max size of property name */ | 66 | char propname[32]; /* 32 is max size of property name */ |
| 67 | int ret; | 67 | int ret = 0; |
| 68 | 68 | ||
| 69 | swnode = to_software_node(fwnode); | 69 | swnode = to_software_node(fwnode); |
| 70 | if (!swnode) | 70 | if (!swnode) |
| @@ -4926,6 +4926,8 @@ static void *gpiolib_seq_start(struct seq_file *s, loff_t *pos) · 4925 unmodified lines | |||
| 4926 | return NULL; | 4926 | return NULL; |
| 4927 | 4927 | ||
| 4928 | s->private = priv; | 4928 | s->private = priv; |
| 4929 | if (*pos > 0) | ||
| 4930 | priv->newline = true; | ||
| 4929 | priv->idx = srcu_read_lock(&gpio_devices_srcu); | 4931 | priv->idx = srcu_read_lock(&gpio_devices_srcu); |
| 4930 | 4932 | ||
| 4931 | list_for_each_entry_srcu(gdev, &gpio_devices, list, | 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 | gc = srcu_dereference(gdev->chip, &gdev->srcu); | 4972 | gc = srcu_dereference(gdev->chip, &gdev->srcu); |
| 4971 | if (!gc) { | 4973 | if (!gc) { |
| 4972 | seq_printf(s, "%s%s: (dangling chip)", | 4974 | seq_printf(s, "%s%s: (dangling chip)\n", |
| 4973 | priv->newline ? "\n" : "", | 4975 | priv->newline ? "\n" : "", |
| 4974 | dev_name(&gdev->dev)); | 4976 | dev_name(&gdev->dev)); |
| 4975 | return 0; | 4977 | return 0; |
| @@ -303,6 +303,7 @@ void build_unoptimized_policy_settings(enum dml_project_id project, struct dml_m · 302 unmodified lines | |||
| 303 | if (project == dml_project_dcn35 || | 303 | if (project == dml_project_dcn35 || |
| 304 | project == dml_project_dcn351) { | 304 | project == dml_project_dcn351) { |
| 305 | policy->DCCProgrammingAssumesScanDirectionUnknownFinal = false; | 305 | policy->DCCProgrammingAssumesScanDirectionUnknownFinal = false; |
| 306 | policy->EnhancedPrefetchScheduleAccelerationFinal = 0; | ||
| 306 | policy->AllowForPStateChangeOrStutterInVBlankFinal = dml_prefetch_support_uclk_fclk_and_stutter_if_possible; /*new*/ | 307 | policy->AllowForPStateChangeOrStutterInVBlankFinal = dml_prefetch_support_uclk_fclk_and_stutter_if_possible; /*new*/ |
| 307 | policy->UseOnlyMaxPrefetchModes = 1; | 308 | policy->UseOnlyMaxPrefetchModes = 1; |
| 308 | } | 309 | } |
| @@ -242,7 +242,9 @@ static int vangogh_tables_init(struct smu_context *smu) · 241 unmodified lines | |||
| 242 | goto err0_out; | 242 | goto err0_out; |
| 243 | smu_table->metrics_time = 0; | 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 | smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL); | 248 | smu_table->gpu_metrics_table = kzalloc(smu_table->gpu_metrics_table_size, GFP_KERNEL); |
| 247 | if (!smu_table->gpu_metrics_table) | 249 | if (!smu_table->gpu_metrics_table) |
| 248 | goto err1_out; | 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 | DpmActivityMonitorCoeffInt_t *activity_monitor = | 2473 | DpmActivityMonitorCoeffInt_t *activity_monitor = |
| 2474 | &(activity_monitor_external.DpmActivityMonitorCoeffInt); | 2474 | &(activity_monitor_external.DpmActivityMonitorCoeffInt); |
| 2475 | int workload_type, ret = 0; | 2475 | int workload_type, ret = 0; |
| 2476 | u32 workload_mask; | 2476 | u32 workload_mask, selected_workload_mask; |
| 2477 | 2477 | ||
| 2478 | smu->power_profile_mode = input[size]; | 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 | if (workload_type < 0) | 2540 | if (workload_type < 0) |
| 2541 | return -EINVAL; | 2541 | return -EINVAL; |
| 2542 | 2542 | ||
| 2543 | workload_mask = 1 << workload_type; | 2543 | selected_workload_mask = workload_mask = 1 << workload_type; |
| 2544 | 2544 | ||
| 2545 | /* Add optimizations for SMU13.0.0/10. Reuse the power saving profile */ | 2545 | /* Add optimizations for SMU13.0.0/10. Reuse the power saving profile */ |
| 2546 | if ((amdgpu_ip_version(smu->adev, MP1_HWIP, 0) == IP_VERSION(13, 0, 0) && | 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 | workload_mask, | 2560 | workload_mask, |
| 2561 | NULL); | 2561 | NULL); |
| 2562 | if (!ret) | 2562 | if (!ret) |
| 2563 | smu->workload_mask = workload_mask; | 2563 | smu->workload_mask = selected_workload_mask; |
| 2564 | 2564 | ||
| 2565 | return ret; | 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 | if (ast_connector->physical_status == connector_status_connected) { | 29 | if (ast_connector->physical_status == connector_status_connected) { |
| 30 | count = drm_connector_helper_get_modes(connector); | 30 | count = drm_connector_helper_get_modes(connector); |
| 31 | } else { | 31 | } else { |
| 32 | drm_edid_connector_update(connector, NULL); | ||
| 33 | |||
| 32 | /* | 34 | /* |
| 33 | * There's no EDID data without a connected monitor. Set BMC- | 35 | * There's no EDID data without a connected monitor. Set BMC- |
| 34 | * compatible modes in this case. The XGA default resolution | 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 | if (ast_connector->physical_status == connector_status_connected) { | 29 | if (ast_connector->physical_status == connector_status_connected) { |
| 30 | count = drm_connector_helper_get_modes(connector); | 30 | count = drm_connector_helper_get_modes(connector); |
| 31 | } else { | 31 | } else { |
| 32 | drm_edid_connector_update(connector, NULL); | ||
| 33 | |||
| 32 | /* | 34 | /* |
| 33 | * There's no EDID data without a connected monitor. Set BMC- | 35 | * There's no EDID data without a connected monitor. Set BMC- |
| 34 | * compatible modes in this case. The XGA default resolution | 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 | adev->id = ret; | 58 | adev->id = ret; |
| 59 | adev->name = "aux_bridge"; | 59 | adev->name = "aux_bridge"; |
| 60 | adev->dev.parent = parent; | 60 | adev->dev.parent = parent; |
| 61 | adev->dev.of_node = of_node_get(parent->of_node); | ||
| 62 | adev->dev.release = drm_aux_bridge_release; | 61 | adev->dev.release = drm_aux_bridge_release; |
| 63 | 62 | ||
| 63 | device_set_of_node_from_dev(&adev->dev, parent); | ||
| 64 | |||
| 64 | ret = auxiliary_device_init(adev); | 65 | ret = auxiliary_device_init(adev); |
| 65 | if (ret) { | 66 | if (ret) { |
| 66 | ida_free(&drm_aux_bridge_ida, adev->id); | 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 | if (tc->pre_emphasis[0] < 0 || tc->pre_emphasis[0] > 2 || | 2412 | if (tc->pre_emphasis[0] < 0 || tc->pre_emphasis[0] > 2 || |
| 2413 | tc->pre_emphasis[1] < 0 || tc->pre_emphasis[1] > 2) { | 2413 | tc->pre_emphasis[1] < 0 || tc->pre_emphasis[1] > 2) { |
| 2414 | dev_err(dev, "Incorrect Pre-Emphasis setting, use either 0=0dB 1=3.5dB 2=6dB\n"); | 2414 | dev_err(dev, "Incorrect Pre-Emphasis setting, use either 0=0dB 1=3.5dB 2=6dB\n"); |
| 2415 | of_node_put(node); | ||
| 2415 | return -EINVAL; | 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 | if (!fb_helper->dev) | 48 | if (!fb_helper->dev) |
| 49 | return; | 49 | return; |
| 50 | 50 | ||
| 51 | fb_deferred_io_cleanup(info); | 51 | if (info->fbdefio) |
| 52 | fb_deferred_io_cleanup(info); | ||
| 52 | drm_fb_helper_fini(fb_helper); | 53 | drm_fb_helper_fini(fb_helper); |
| 53 | 54 | ||
| 54 | drm_client_buffer_vunmap(fb_helper->buffer); | 55 | drm_client_buffer_vunmap(fb_helper->buffer); |
| @@ -125,9 +125,8 @@ config DRM_I915_USERPTR · 124 unmodified lines | |||
| 125 | config DRM_I915_GVT_KVMGT | 125 | config DRM_I915_GVT_KVMGT |
| 126 | tristate "Enable KVM host support Intel GVT-g graphics virtualization" | 126 | tristate "Enable KVM host support Intel GVT-g graphics virtualization" |
| 127 | depends on DRM_I915 | 127 | depends on DRM_I915 |
| 128 | depends on X86 | 128 | depends on KVM_X86 |
| 129 | depends on 64BIT | 129 | depends on 64BIT |
| 130 | depends on KVM | ||
| 131 | depends on VFIO | 130 | depends on VFIO |
| 132 | select DRM_I915_GVT | 131 | select DRM_I915_GVT |
| 133 | select KVM_EXTERNAL_WRITE_TRACKING | 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 | static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state, | 91 | static int intel_dp_mst_bw_overhead(const struct intel_crtc_state *crtc_state, |
| 92 | const struct intel_connector *connector, | 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 | const struct drm_display_mode *adjusted_mode = | 95 | const struct drm_display_mode *adjusted_mode = |
| 96 | &crtc_state->hw.adjusted_mode; | 96 | &crtc_state->hw.adjusted_mode; |
| 97 | unsigned long flags = DRM_DP_BW_OVERHEAD_MST; | 97 | unsigned long flags = DRM_DP_BW_OVERHEAD_MST; |
| 98 | int dsc_slice_count = 0; | ||
| 99 | int overhead; | 98 | int overhead; |
| 100 | 99 | ||
| 101 | flags |= intel_dp_is_uhbr(crtc_state) ? DRM_DP_BW_OVERHEAD_UHBR : 0; | 100 | flags |= intel_dp_is_uhbr(crtc_state) ? DRM_DP_BW_OVERHEAD_UHBR : 0; |
| 102 | flags |= ssc ? DRM_DP_BW_OVERHEAD_SSC_REF_CLK : 0; | 101 | flags |= ssc ? DRM_DP_BW_OVERHEAD_SSC_REF_CLK : 0; |
| 103 | flags |= crtc_state->fec_enable ? DRM_DP_BW_OVERHEAD_FEC : 0; | 102 | flags |= crtc_state->fec_enable ? DRM_DP_BW_OVERHEAD_FEC : 0; |
| 104 | 103 | ||
| 105 | if (dsc) { | 104 | if (dsc_slice_count) |
| 106 | int num_joined_pipes = intel_crtc_num_joined_pipes(crtc_state); | ||
| 107 | |||
| 108 | flags |= DRM_DP_BW_OVERHEAD_DSC; | 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 | overhead = drm_dp_bw_overhead(crtc_state->lane_count, | 107 | overhead = drm_dp_bw_overhead(crtc_state->lane_count, |
| 116 | adjusted_mode->hdisplay, | 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 | return DIV_ROUND_UP(effective_data_rate * 64, 54 * 1000); | 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 | static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, | 164 | static int intel_dp_mst_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, |
| 160 | struct intel_crtc_state *crtc_state, | 165 | struct intel_crtc_state *crtc_state, |
| 161 | int max_bpp, | 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 | const struct drm_display_mode *adjusted_mode = | 180 | const struct drm_display_mode *adjusted_mode = |
| 176 | &crtc_state->hw.adjusted_mode; | 181 | &crtc_state->hw.adjusted_mode; |
| 177 | int bpp, slots = -EINVAL; | 182 | int bpp, slots = -EINVAL; |
| 183 | int dsc_slice_count = 0; | ||
| 178 | int max_dpt_bpp; | 184 | int max_dpt_bpp; |
| 179 | int ret = 0; | 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 | drm_dbg_kms(&i915->drm, "Looking for slots in range min bpp %d max bpp %d\n", | 212 | drm_dbg_kms(&i915->drm, "Looking for slots in range min bpp %d max bpp %d\n", |
| 207 | min_bpp, max_bpp); | 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 | for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) { | 224 | for (bpp = max_bpp; bpp >= min_bpp; bpp -= step) { |
| 210 | int local_bw_overhead; | 225 | int local_bw_overhead; |
| 211 | int remote_bw_overhead; | 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 | intel_dp_output_bpp(crtc_state->output_format, bpp)); | 234 | intel_dp_output_bpp(crtc_state->output_format, bpp)); |
| 220 | 235 | ||
| 221 | local_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector, | 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 | remote_bw_overhead = intel_dp_mst_bw_overhead(crtc_state, connector, | 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 | intel_dp_mst_compute_m_n(crtc_state, connector, | 241 | intel_dp_mst_compute_m_n(crtc_state, connector, |
| 227 | local_bw_overhead, | 242 | local_bw_overhead, |
| @@ -452,6 +467,9 @@ hblank_expansion_quirk_needs_dsc(const struct intel_connector *connector, · 224 unmodified lines | |||
| 452 | if (mode_hblank_period_ns(adjusted_mode) > hblank_limit) | 467 | if (mode_hblank_period_ns(adjusted_mode) > hblank_limit) |
| 453 | return false; | 468 | return false; |
| 454 | 469 | ||
| 470 | if (!intel_dp_mst_dsc_get_slice_count(connector, crtc_state)) | ||
| 471 | return false; | ||
| 472 | |||
| 455 | return true; | 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 | mtk_mutex_put(mtk_crtc->mutex); | 128 | mtk_mutex_put(mtk_crtc->mutex); |
| 129 | #if IS_REACHABLE(CONFIG_MTK_CMDQ) | 129 | #if IS_REACHABLE(CONFIG_MTK_CMDQ) |
| 130 | cmdq_pkt_destroy(&mtk_crtc->cmdq_client, &mtk_crtc->cmdq_handle); | ||
| 131 | |||
| 132 | if (mtk_crtc->cmdq_client.chan) { | 130 | if (mtk_crtc->cmdq_client.chan) { |
| 131 | cmdq_pkt_destroy(&mtk_crtc->cmdq_client, &mtk_crtc->cmdq_handle); | ||
| 133 | mbox_free_channel(mtk_crtc->cmdq_client.chan); | 132 | mbox_free_channel(mtk_crtc->cmdq_client.chan); |
| 134 | mtk_crtc->cmdq_client.chan = NULL; | 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 | BIT(pipe), | 912 | BIT(pipe), |
| 914 | mtk_crtc_plane_type(mtk_crtc->layer_nr, num_planes), | 913 | mtk_crtc_plane_type(mtk_crtc->layer_nr, num_planes), |
| 915 | mtk_ddp_comp_supported_rotations(comp), | 914 | mtk_ddp_comp_supported_rotations(comp), |
| 915 | mtk_ddp_comp_get_blend_modes(comp), | ||
| 916 | mtk_ddp_comp_get_formats(comp), | 916 | mtk_ddp_comp_get_formats(comp), |
| 917 | mtk_ddp_comp_get_num_formats(comp), i); | 917 | mtk_ddp_comp_get_num_formats(comp), i); |
| 918 | if (ret) | 918 | if (ret) |
| @@ -363,6 +363,7 @@ static const struct mtk_ddp_comp_funcs ddp_ovl = { · 362 unmodified lines | |||
| 363 | .layer_config = mtk_ovl_layer_config, | 363 | .layer_config = mtk_ovl_layer_config, |
| 364 | .bgclr_in_on = mtk_ovl_bgclr_in_on, | 364 | .bgclr_in_on = mtk_ovl_bgclr_in_on, |
| 365 | .bgclr_in_off = mtk_ovl_bgclr_in_off, | 365 | .bgclr_in_off = mtk_ovl_bgclr_in_off, |
| 366 | .get_blend_modes = mtk_ovl_get_blend_modes, | ||
| 366 | .get_formats = mtk_ovl_get_formats, | 367 | .get_formats = mtk_ovl_get_formats, |
| 367 | .get_num_formats = mtk_ovl_get_num_formats, | 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 | .disconnect = mtk_ovl_adaptor_disconnect, | 417 | .disconnect = mtk_ovl_adaptor_disconnect, |
| 417 | .add = mtk_ovl_adaptor_add_comp, | 418 | .add = mtk_ovl_adaptor_add_comp, |
| 418 | .remove = mtk_ovl_adaptor_remove_comp, | 419 | .remove = mtk_ovl_adaptor_remove_comp, |
| 420 | .get_blend_modes = mtk_ovl_adaptor_get_blend_modes, | ||
| 419 | .get_formats = mtk_ovl_adaptor_get_formats, | 421 | .get_formats = mtk_ovl_adaptor_get_formats, |
| 420 | .get_num_formats = mtk_ovl_adaptor_get_num_formats, | 422 | .get_num_formats = mtk_ovl_adaptor_get_num_formats, |
| 421 | .mode_valid = mtk_ovl_adaptor_mode_valid, | 423 | .mode_valid = mtk_ovl_adaptor_mode_valid, |
| @@ -80,6 +80,7 @@ struct mtk_ddp_comp_funcs { · 79 unmodified lines | |||
| 80 | void (*ctm_set)(struct device *dev, | 80 | void (*ctm_set)(struct device *dev, |
| 81 | struct drm_crtc_state *state); | 81 | struct drm_crtc_state *state); |
| 82 | struct device * (*dma_dev_get)(struct device *dev); | 82 | struct device * (*dma_dev_get)(struct device *dev); |
| 83 | u32 (*get_blend_modes)(struct device *dev); | ||
| 83 | const u32 *(*get_formats)(struct device *dev); | 84 | const u32 *(*get_formats)(struct device *dev); |
| 84 | size_t (*get_num_formats)(struct device *dev); | 85 | size_t (*get_num_formats)(struct device *dev); |
| 85 | void (*connect)(struct device *dev, struct device *mmsys_dev, unsigned int next); | 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 | return comp->dev; | 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 | static inline | 279 | static inline |
| 270 | const u32 *mtk_ddp_comp_get_formats(struct mtk_ddp_comp *comp) | 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 | void mtk_ovl_unregister_vblank_cb(struct device *dev); | 103 | void mtk_ovl_unregister_vblank_cb(struct device *dev); |
| 104 | void mtk_ovl_enable_vblank(struct device *dev); | 104 | void mtk_ovl_enable_vblank(struct device *dev); |
| 105 | void mtk_ovl_disable_vblank(struct device *dev); | 105 | void mtk_ovl_disable_vblank(struct device *dev); |
| 106 | u32 mtk_ovl_get_blend_modes(struct device *dev); | ||
| 106 | const u32 *mtk_ovl_get_formats(struct device *dev); | 107 | const u32 *mtk_ovl_get_formats(struct device *dev); |
| 107 | size_t mtk_ovl_get_num_formats(struct device *dev); | 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 | void mtk_ovl_adaptor_stop(struct device *dev); | 132 | void mtk_ovl_adaptor_stop(struct device *dev); |
| 132 | unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev); | 133 | unsigned int mtk_ovl_adaptor_layer_nr(struct device *dev); |
| 133 | struct device *mtk_ovl_adaptor_dma_dev_get(struct device *dev); | 134 | struct device *mtk_ovl_adaptor_dma_dev_get(struct device *dev); |
| 135 | u32 mtk_ovl_adaptor_get_blend_modes(struct device *dev); | ||
| 134 | const u32 *mtk_ovl_adaptor_get_formats(struct device *dev); | 136 | const u32 *mtk_ovl_adaptor_get_formats(struct device *dev); |
| 135 | size_t mtk_ovl_adaptor_get_num_formats(struct device *dev); | 137 | size_t mtk_ovl_adaptor_get_num_formats(struct device *dev); |
| 136 | enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev, | 138 | enum drm_mode_status mtk_ovl_adaptor_mode_valid(struct device *dev, |
| @@ -65,8 +65,8 @@ · 64 unmodified lines | |||
| 65 | #define OVL_CON_CLRFMT_RGB (1 << 12) | 65 | #define OVL_CON_CLRFMT_RGB (1 << 12) |
| 66 | #define OVL_CON_CLRFMT_ARGB8888 (2 << 12) | 66 | #define OVL_CON_CLRFMT_ARGB8888 (2 << 12) |
| 67 | #define OVL_CON_CLRFMT_RGBA8888 (3 << 12) | 67 | #define OVL_CON_CLRFMT_RGBA8888 (3 << 12) |
| 68 | #define OVL_CON_CLRFMT_ABGR8888 (OVL_CON_CLRFMT_RGBA8888 | 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_ARGB8888 | OVL_CON_BYTE_SWAP) | 69 | #define OVL_CON_CLRFMT_BGRA8888 (OVL_CON_CLRFMT_RGBA8888 | OVL_CON_BYTE_SWAP) |
| 70 | #define OVL_CON_CLRFMT_UYVY (4 << 12) | 70 | #define OVL_CON_CLRFMT_UYVY (4 << 12) |
| 71 | #define OVL_CON_CLRFMT_YUYV (5 << 12) | 71 | #define OVL_CON_CLRFMT_YUYV (5 << 12) |
| 72 | #define OVL_CON_MTX_YUV_TO_RGB (6 << 16) | 72 | #define OVL_CON_MTX_YUV_TO_RGB (6 << 16) |
| @@ -146,6 +146,7 @@ struct mtk_disp_ovl_data { · 73 unmodified lines | |||
| 146 | bool fmt_rgb565_is_0; | 146 | bool fmt_rgb565_is_0; |
| 147 | bool smi_id_en; | 147 | bool smi_id_en; |
| 148 | bool supports_afbc; | 148 | bool supports_afbc; |
| 149 | const u32 blend_modes; | ||
| 149 | const u32 *formats; | 150 | const u32 *formats; |
| 150 | size_t num_formats; | 151 | size_t num_formats; |
| 151 | bool supports_clrfmt_ext; | 152 | bool supports_clrfmt_ext; |
| @@ -214,6 +215,13 @@ void mtk_ovl_disable_vblank(struct device *dev) · 62 unmodified lines | |||
| 214 | writel_relaxed(0x0, ovl->regs + DISP_REG_OVL_INTEN); | 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 | const u32 *mtk_ovl_get_formats(struct device *dev) | 225 | const u32 *mtk_ovl_get_formats(struct device *dev) |
| 218 | { | 226 | { |
| 219 | struct mtk_disp_ovl *ovl = dev_get_drvdata(dev); | 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 | DISP_REG_OVL_RDMA_CTRL(idx)); | 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, | 397 | static unsigned int mtk_ovl_fmt_convert(struct mtk_disp_ovl *ovl, |
| 390 | unsigned int blend_mode) | 398 | struct mtk_plane_state *state) |
| 391 | { | 399 | { |
| 392 | /* The return value in switch "MEM_MODE_INPUT_FORMAT_XXX" | 400 | unsigned int fmt = state->pending.format; |
| 393 | * is defined in mediatek HW data sheet. | 401 | unsigned int blend_mode = DRM_MODE_BLEND_COVERAGE; |
| 394 | * The alphabet order in XXX is no relation to data | 402 | |
| 395 | * arrangement in memory. | 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 | switch (fmt) { | 418 | switch (fmt) { |
| 398 | default: | 419 | default: |
| 399 | case DRM_FORMAT_RGB565: | 420 | case DRM_FORMAT_RGB565: |
| @@ -471,20 +492,26 @@ void mtk_ovl_layer_config(struct device *dev, unsigned int idx, · 71 unmodified lines | |||
| 471 | return; | 492 | return; |
| 472 | } | 493 | } |
| 473 | 494 | ||
| 474 | con = ovl_fmt_convert(ovl, fmt, blend_mode); | 495 | con = mtk_ovl_fmt_convert(ovl, state); |
| 475 | if (state->base.fb) { | 496 | if (state->base.fb) { |
| 476 | con |= OVL_CON_AEN; | ||
| 477 | con |= state->base.alpha & OVL_CON_ALPHA; | 497 | con |= state->base.alpha & OVL_CON_ALPHA; |
| 478 | } | ||
| 479 | 498 | ||
| 480 | /* CONST_BLD must be enabled for XRGB formats although the alpha channel | 499 | /* |
| 481 | * can be ignored, or OVL will still read the value from memory. | 500 | * For blend_modes supported SoCs, always enable alpha blending. |
| 482 | * For RGB888 related formats, whether CONST_BLD is enabled or not won't | 501 | * For blend_modes unsupported SoCs, enable alpha blending when has_alpha is set. |
| 483 | * affect the result. Therefore we use !has_alpha as the condition. | 502 | */ |
| 484 | */ | 503 | if (blend_mode || state->base.fb->format->has_alpha) |
| 485 | if ((state->base.fb && !state->base.fb->format->has_alpha) || | 504 | con |= OVL_CON_AEN; |
| 486 | blend_mode == DRM_MODE_BLEND_PIXEL_NONE) | 505 | |
| 487 | ignore_pixel_alpha = OVL_CONST_BLEND; | 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 | if (pending->rotation & DRM_MODE_REFLECT_Y) { | 516 | if (pending->rotation & DRM_MODE_REFLECT_Y) { |
| 490 | con |= OVL_CON_VIRT_FLIP; | 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 | .layer_nr = 4, | 690 | .layer_nr = 4, |
| 664 | .fmt_rgb565_is_0 = true, | 691 | .fmt_rgb565_is_0 = true, |
| 665 | .smi_id_en = true, | 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 | .formats = mt8173_formats, | 696 | .formats = mt8173_formats, |
| 667 | .num_formats = ARRAY_SIZE(mt8173_formats), | 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 | .layer_nr = 2, | 703 | .layer_nr = 2, |
| 674 | .fmt_rgb565_is_0 = true, | 704 | .fmt_rgb565_is_0 = true, |
| 675 | .smi_id_en = true, | 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 | .formats = mt8173_formats, | 709 | .formats = mt8173_formats, |
| 677 | .num_formats = ARRAY_SIZE(mt8173_formats), | 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 | .fmt_rgb565_is_0 = true, | 717 | .fmt_rgb565_is_0 = true, |
| 685 | .smi_id_en = true, | 718 | .smi_id_en = true, |
| 686 | .supports_afbc = true, | 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 | .formats = mt8195_formats, | 723 | .formats = mt8195_formats, |
| 688 | .num_formats = ARRAY_SIZE(mt8195_formats), | 724 | .num_formats = ARRAY_SIZE(mt8195_formats), |
| 689 | .supports_clrfmt_ext = true, | 725 | .supports_clrfmt_ext = true, |
| @@ -400,6 +400,13 @@ void mtk_ovl_adaptor_disable_vblank(struct device *dev) · 399 unmodified lines | |||
| 400 | mtk_ethdr_disable_vblank(ovl_adaptor->ovl_adaptor_comp[OVL_ADAPTOR_ETHDR0]); | 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 | const u32 *mtk_ovl_adaptor_get_formats(struct device *dev) | 410 | const u32 *mtk_ovl_adaptor_get_formats(struct device *dev) |
| 404 | { | 411 | { |
| 405 | struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev); | 412 | struct mtk_disp_ovl_adaptor *ovl_adaptor = dev_get_drvdata(dev); |
| @@ -145,6 +145,89 @@ struct mtk_dp_data { · 144 unmodified lines | |||
| 145 | u16 audio_m_div2_bit; | 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 | static const struct mtk_dp_efuse_fmt mt8195_edp_efuse_fmt[MTK_DP_CAL_MAX] = { | 231 | static const struct mtk_dp_efuse_fmt mt8195_edp_efuse_fmt[MTK_DP_CAL_MAX] = { |
| 149 | [MTK_DP_CAL_GLB_BIAS_TRIM] = { | 232 | [MTK_DP_CAL_GLB_BIAS_TRIM] = { |
| 150 | .idx = 3, | 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 | static const struct mtk_dp_data mt8188_dp_data = { | 2854 | static const struct mtk_dp_data mt8188_dp_data = { |
| 2772 | .bridge_type = DRM_MODE_CONNECTOR_DisplayPort, | 2855 | .bridge_type = DRM_MODE_CONNECTOR_DisplayPort, |
| 2773 | .smc_cmd = MTK_DP_SIP_ATF_VIDEO_UNMUTE, | 2856 | .smc_cmd = MTK_DP_SIP_ATF_VIDEO_UNMUTE, |
| 2774 | .efuse_fmt = mt8195_dp_efuse_fmt, | 2857 | .efuse_fmt = mt8188_dp_efuse_fmt, |
| 2775 | .audio_supported = true, | 2858 | .audio_supported = true, |
| 2776 | .audio_pkt_in_hblank_area = true, | 2859 | .audio_pkt_in_hblank_area = true, |
| 2777 | .audio_m_div2_bit = MT8188_AUDIO_M_CODE_MULT_DIV_SEL_DP_ENC0_P0_DIV_2, | 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 | return IRQ_HANDLED; | 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 | void mtk_ethdr_layer_config(struct device *dev, unsigned int idx, | 155 | void mtk_ethdr_layer_config(struct device *dev, unsigned int idx, |
| 149 | struct mtk_plane_state *state, | 156 | struct mtk_plane_state *state, |
| 150 | struct cmdq_pkt *cmdq_pkt) | 157 | struct cmdq_pkt *cmdq_pkt) |
| @@ -13,6 +13,7 @@ void mtk_ethdr_clk_disable(struct device *dev); · 12 unmodified lines | |||
| 13 | void mtk_ethdr_config(struct device *dev, unsigned int w, | 13 | void mtk_ethdr_config(struct device *dev, unsigned int w, |
| 14 | unsigned int h, unsigned int vrefresh, | 14 | unsigned int h, unsigned int vrefresh, |
| 15 | unsigned int bpc, struct cmdq_pkt *cmdq_pkt); | 15 | unsigned int bpc, struct cmdq_pkt *cmdq_pkt); |
| 16 | u32 mtk_ethdr_get_blend_modes(struct device *dev); | ||
| 16 | void mtk_ethdr_layer_config(struct device *dev, unsigned int idx, | 17 | void mtk_ethdr_layer_config(struct device *dev, unsigned int idx, |
| 17 | struct mtk_plane_state *state, | 18 | struct mtk_plane_state *state, |
| 18 | struct cmdq_pkt *cmdq_pkt); | 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 | int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, | 321 | int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, |
| 322 | unsigned long possible_crtcs, enum drm_plane_type type, | 322 | unsigned long possible_crtcs, enum drm_plane_type type, |
| 323 | unsigned int supported_rotations, const u32 *formats, | 323 | unsigned int supported_rotations, const u32 blend_modes, |
| 324 | size_t num_formats, unsigned int plane_idx) | 324 | const u32 *formats, size_t num_formats, unsigned int plane_idx) |
| 325 | { | 325 | { |
| 326 | int err; | 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 | if (err) | 366 | if (err) |
| 367 | DRM_ERROR("failed to create property: alpha\n"); | 367 | DRM_ERROR("failed to create property: alpha\n"); |
| 368 | 368 | ||
| 369 | err = drm_plane_create_blend_mode_property(plane, | 369 | if (blend_modes) { |
| 370 | BIT(DRM_MODE_BLEND_PREMULTI) | | 370 | err = drm_plane_create_blend_mode_property(plane, blend_modes); |
| 371 | BIT(DRM_MODE_BLEND_COVERAGE) | | 371 | if (err) |
| 372 | BIT(DRM_MODE_BLEND_PIXEL_NONE)); | 372 | DRM_ERROR("failed to create property: blend_mode\n"); |
| 373 | if (err) | 373 | } |
| 374 | DRM_ERROR("failed to create property: blend_mode\n"); | ||
| 375 | 374 | ||
| 376 | drm_plane_helper_add(plane, &mtk_plane_helper_funcs); | 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 | int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, | 49 | int mtk_plane_init(struct drm_device *dev, struct drm_plane *plane, |
| 50 | unsigned long possible_crtcs, enum drm_plane_type type, | 50 | unsigned long possible_crtcs, enum drm_plane_type type, |
| 51 | unsigned int supported_rotations, const u32 *formats, | 51 | unsigned int supported_rotations, const u32 blend_modes, |
| 52 | size_t num_formats, unsigned int plane_idx); | 52 | const u32 *formats, size_t num_formats, unsigned int plane_idx); |
| 53 | #endif | 53 | #endif |
| @@ -20,7 +20,6 @@ · 19 unmodified lines | |||
| 20 | #include <drm/drm_managed.h> | 20 | #include <drm/drm_managed.h> |
| 21 | #include <drm/drm_module.h> | 21 | #include <drm/drm_module.h> |
| 22 | #include <drm/drm_pciids.h> | 22 | #include <drm/drm_pciids.h> |
| 23 | #include <drm/drm_vblank.h> | ||
| 24 | 23 | ||
| 25 | #include "mgag200_drv.h" | 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 | return offset - 65536; | 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 | * DRM driver | 90 | * DRM driver |
| 120 | */ | 91 | */ |
| @@ -199,7 +170,6 @@ int mgag200_device_init(struct mga_device *mdev, · 78 unmodified lines | |||
| 199 | const struct mgag200_device_funcs *funcs) | 170 | const struct mgag200_device_funcs *funcs) |
| 200 | { | 171 | { |
| 201 | struct drm_device *dev = &mdev->base; | 172 | struct drm_device *dev = &mdev->base; |
| 202 | struct pci_dev *pdev = to_pci_dev(dev->dev); | ||
| 203 | u8 crtcext3, misc; | 173 | u8 crtcext3, misc; |
| 204 | int ret; | 174 | int ret; |
| 205 | 175 | ||
| @@ -226,14 +196,6 @@ int mgag200_device_init(struct mga_device *mdev, · 20 unmodified lines | |||
| 226 | mutex_unlock(&mdev->rmmio_lock); | 196 | mutex_unlock(&mdev->rmmio_lock); |
| 227 | 197 | ||
| 228 | WREG32(MGAREG_IEN, 0); | 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 | return 0; | 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 | void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *old_state); | 391 | void mgag200_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_atomic_state *old_state); |
| 392 | void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *old_state); | 392 | void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *old_state); |
| 393 | void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *old_state); | 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 | #define MGAG200_CRTC_HELPER_FUNCS \ | 395 | #define MGAG200_CRTC_HELPER_FUNCS \ |
| 400 | .mode_valid = mgag200_crtc_helper_mode_valid, \ | 396 | .mode_valid = mgag200_crtc_helper_mode_valid, \ |
| 401 | .atomic_check = mgag200_crtc_helper_atomic_check, \ | 397 | .atomic_check = mgag200_crtc_helper_atomic_check, \ |
| 402 | .atomic_flush = mgag200_crtc_helper_atomic_flush, \ | 398 | .atomic_flush = mgag200_crtc_helper_atomic_flush, \ |
| 403 | .atomic_enable = mgag200_crtc_helper_atomic_enable, \ | 399 | .atomic_enable = mgag200_crtc_helper_atomic_enable, \ |
| 404 | .atomic_disable = mgag200_crtc_helper_atomic_disable, \ | 400 | .atomic_disable = mgag200_crtc_helper_atomic_disable |
| 405 | .get_scanout_position = mgag200_crtc_helper_get_scanout_position | ||
| 406 | 401 | ||
| 407 | void mgag200_crtc_reset(struct drm_crtc *crtc); | 402 | void mgag200_crtc_reset(struct drm_crtc *crtc); |
| 408 | struct drm_crtc_state *mgag200_crtc_atomic_duplicate_state(struct drm_crtc *crtc); | 403 | struct drm_crtc_state *mgag200_crtc_atomic_duplicate_state(struct drm_crtc *crtc); |
| 409 | void mgag200_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state); | 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 | #define MGAG200_CRTC_FUNCS \ | 406 | #define MGAG200_CRTC_FUNCS \ |
| 414 | .reset = mgag200_crtc_reset, \ | 407 | .reset = mgag200_crtc_reset, \ |
| @@ -416,10 +409,7 @@ void mgag200_crtc_disable_vblank(struct drm_crtc *crtc); · 1 unmodified line | |||
| 416 | .set_config = drm_atomic_helper_set_config, \ | 409 | .set_config = drm_atomic_helper_set_config, \ |
| 417 | .page_flip = drm_atomic_helper_page_flip, \ | 410 | .page_flip = drm_atomic_helper_page_flip, \ |
| 418 | .atomic_duplicate_state = mgag200_crtc_atomic_duplicate_state, \ | 411 | .atomic_duplicate_state = mgag200_crtc_atomic_duplicate_state, \ |
| 419 | .atomic_destroy_state = mgag200_crtc_atomic_destroy_state, \ | 412 | .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 | ||
| 423 | 413 | ||
| 424 | void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mode *mode, | 414 | void mgag200_set_mode_regs(struct mga_device *mdev, const struct drm_display_mode *mode, |
| 425 | bool set_vidrst); | 415 | bool set_vidrst); |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | #include <drm/drm_drv.h> | 8 | #include <drm/drm_drv.h> |
| 9 | #include <drm/drm_gem_atomic_helper.h> | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | #include <drm/drm_probe_helper.h> | 10 | #include <drm/drm_probe_helper.h> |
| 11 | #include <drm/drm_vblank.h> | ||
| 12 | 11 | ||
| 13 | #include "mgag200_drv.h" | 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 | drm_mode_config_reset(dev); | 403 | drm_mode_config_reset(dev); |
| 405 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 406 | return mdev; |
| 412 | } | 407 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | #include <drm/drm_drv.h> | 8 | #include <drm/drm_drv.h> |
| 9 | #include <drm/drm_gem_atomic_helper.h> | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | #include <drm/drm_probe_helper.h> | 10 | #include <drm/drm_probe_helper.h> |
| 11 | #include <drm/drm_vblank.h> | ||
| 12 | 11 | ||
| 13 | #include "mgag200_drv.h" | 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 | drm_mode_config_reset(dev); | 275 | drm_mode_config_reset(dev); |
| 277 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 278 | return mdev; |
| 284 | } | 279 | } |
| @@ -7,7 +7,6 @@ · 6 unmodified lines | |||
| 7 | #include <drm/drm_drv.h> | 7 | #include <drm/drm_drv.h> |
| 8 | #include <drm/drm_gem_atomic_helper.h> | 8 | #include <drm/drm_gem_atomic_helper.h> |
| 9 | #include <drm/drm_probe_helper.h> | 9 | #include <drm/drm_probe_helper.h> |
| 10 | #include <drm/drm_vblank.h> | ||
| 11 | 10 | ||
| 12 | #include "mgag200_drv.h" | 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 | drm_mode_config_reset(dev); | 180 | drm_mode_config_reset(dev); |
| 182 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 183 | return mdev; |
| 189 | } | 184 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | #include <drm/drm_drv.h> | 8 | #include <drm/drm_drv.h> |
| 9 | #include <drm/drm_gem_atomic_helper.h> | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | #include <drm/drm_probe_helper.h> | 10 | #include <drm/drm_probe_helper.h> |
| 11 | #include <drm/drm_vblank.h> | ||
| 12 | 11 | ||
| 13 | #include "mgag200_drv.h" | 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 | mgag200_crtc_set_gamma_linear(mdev, format); | 205 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 207 | 206 | ||
| 208 | mgag200_enable_display(mdev); | 207 | mgag200_enable_display(mdev); |
| 209 | |||
| 210 | drm_crtc_vblank_on(crtc); | ||
| 211 | } | 208 | } |
| 212 | 209 | ||
| 213 | static const struct drm_crtc_helper_funcs mgag200_g200er_crtc_helper_funcs = { | 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 | .atomic_check = mgag200_crtc_helper_atomic_check, | 212 | .atomic_check = mgag200_crtc_helper_atomic_check, |
| 216 | .atomic_flush = mgag200_crtc_helper_atomic_flush, | 213 | .atomic_flush = mgag200_crtc_helper_atomic_flush, |
| 217 | .atomic_enable = mgag200_g200er_crtc_helper_atomic_enable, | 214 | .atomic_enable = mgag200_g200er_crtc_helper_atomic_enable, |
| 218 | .atomic_disable = mgag200_crtc_helper_atomic_disable, | 215 | .atomic_disable = mgag200_crtc_helper_atomic_disable |
| 219 | .get_scanout_position = mgag200_crtc_helper_get_scanout_position, | ||
| 220 | }; | 216 | }; |
| 221 | 217 | ||
| 222 | static const struct drm_crtc_funcs mgag200_g200er_crtc_funcs = { | 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 | drm_mode_config_reset(dev); | 308 | drm_mode_config_reset(dev); |
| 313 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 311 | return mdev; |
| 320 | } | 312 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | #include <drm/drm_drv.h> | 8 | #include <drm/drm_drv.h> |
| 9 | #include <drm/drm_gem_atomic_helper.h> | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | #include <drm/drm_probe_helper.h> | 10 | #include <drm/drm_probe_helper.h> |
| 11 | #include <drm/drm_vblank.h> | ||
| 12 | 11 | ||
| 13 | #include "mgag200_drv.h" | 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 | mgag200_crtc_set_gamma_linear(mdev, format); | 206 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 208 | 207 | ||
| 209 | mgag200_enable_display(mdev); | 208 | mgag200_enable_display(mdev); |
| 210 | |||
| 211 | drm_crtc_vblank_on(crtc); | ||
| 212 | } | 209 | } |
| 213 | 210 | ||
| 214 | static const struct drm_crtc_helper_funcs mgag200_g200ev_crtc_helper_funcs = { | 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 | .atomic_check = mgag200_crtc_helper_atomic_check, | 213 | .atomic_check = mgag200_crtc_helper_atomic_check, |
| 217 | .atomic_flush = mgag200_crtc_helper_atomic_flush, | 214 | .atomic_flush = mgag200_crtc_helper_atomic_flush, |
| 218 | .atomic_enable = mgag200_g200ev_crtc_helper_atomic_enable, | 215 | .atomic_enable = mgag200_g200ev_crtc_helper_atomic_enable, |
| 219 | .atomic_disable = mgag200_crtc_helper_atomic_disable, | 216 | .atomic_disable = mgag200_crtc_helper_atomic_disable |
| 220 | .get_scanout_position = mgag200_crtc_helper_get_scanout_position, | ||
| 221 | }; | 217 | }; |
| 222 | 218 | ||
| 223 | static const struct drm_crtc_funcs mgag200_g200ev_crtc_funcs = { | 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 | drm_mode_config_reset(dev); | 313 | drm_mode_config_reset(dev); |
| 318 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 316 | return mdev; |
| 325 | } | 317 | } |
| @@ -7,7 +7,6 @@ · 6 unmodified lines | |||
| 7 | #include <drm/drm_drv.h> | 7 | #include <drm/drm_drv.h> |
| 8 | #include <drm/drm_gem_atomic_helper.h> | 8 | #include <drm/drm_gem_atomic_helper.h> |
| 9 | #include <drm/drm_probe_helper.h> | 9 | #include <drm/drm_probe_helper.h> |
| 10 | #include <drm/drm_vblank.h> | ||
| 11 | 10 | ||
| 12 | #include "mgag200_drv.h" | 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 | drm_mode_config_reset(dev); | 198 | drm_mode_config_reset(dev); |
| 200 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 201 | return mdev; |
| 207 | } | 202 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | #include <drm/drm_drv.h> | 8 | #include <drm/drm_drv.h> |
| 9 | #include <drm/drm_gem_atomic_helper.h> | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | #include <drm/drm_probe_helper.h> | 10 | #include <drm/drm_probe_helper.h> |
| 11 | #include <drm/drm_vblank.h> | ||
| 12 | 11 | ||
| 13 | #include "mgag200_drv.h" | 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 | mgag200_crtc_set_gamma_linear(mdev, format); | 337 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 339 | 338 | ||
| 340 | mgag200_enable_display(mdev); | 339 | mgag200_enable_display(mdev); |
| 341 | |||
| 342 | drm_crtc_vblank_on(crtc); | ||
| 343 | } | 340 | } |
| 344 | 341 | ||
| 345 | static const struct drm_crtc_helper_funcs mgag200_g200se_crtc_helper_funcs = { | 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 | .atomic_check = mgag200_crtc_helper_atomic_check, | 344 | .atomic_check = mgag200_crtc_helper_atomic_check, |
| 348 | .atomic_flush = mgag200_crtc_helper_atomic_flush, | 345 | .atomic_flush = mgag200_crtc_helper_atomic_flush, |
| 349 | .atomic_enable = mgag200_g200se_crtc_helper_atomic_enable, | 346 | .atomic_enable = mgag200_g200se_crtc_helper_atomic_enable, |
| 350 | .atomic_disable = mgag200_crtc_helper_atomic_disable, | 347 | .atomic_disable = mgag200_crtc_helper_atomic_disable |
| 351 | .get_scanout_position = mgag200_crtc_helper_get_scanout_position, | ||
| 352 | }; | 348 | }; |
| 353 | 349 | ||
| 354 | static const struct drm_crtc_funcs mgag200_g200se_crtc_funcs = { | 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 | drm_mode_config_reset(dev); | 513 | drm_mode_config_reset(dev); |
| 518 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 516 | return mdev; |
| 525 | } | 517 | } |
| @@ -8,7 +8,6 @@ · 7 unmodified lines | |||
| 8 | #include <drm/drm_drv.h> | 8 | #include <drm/drm_drv.h> |
| 9 | #include <drm/drm_gem_atomic_helper.h> | 9 | #include <drm/drm_gem_atomic_helper.h> |
| 10 | #include <drm/drm_probe_helper.h> | 10 | #include <drm/drm_probe_helper.h> |
| 11 | #include <drm/drm_vblank.h> | ||
| 12 | 11 | ||
| 13 | #include "mgag200_drv.h" | 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 | drm_mode_config_reset(dev); | 322 | drm_mode_config_reset(dev); |
| 324 | drm_kms_helper_poll_init(dev); | 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 | return mdev; | 325 | return mdev; |
| 331 | } | 326 | } |
| @@ -22,7 +22,6 @@ · 21 unmodified lines | |||
| 22 | #include <drm/drm_gem_framebuffer_helper.h> | 22 | #include <drm/drm_gem_framebuffer_helper.h> |
| 23 | #include <drm/drm_panic.h> | 23 | #include <drm/drm_panic.h> |
| 24 | #include <drm/drm_print.h> | 24 | #include <drm/drm_print.h> |
| 25 | #include <drm/drm_vblank.h> | ||
| 26 | 25 | ||
| 27 | #include "mgag200_ddc.h" | 26 | #include "mgag200_ddc.h" |
| 28 | #include "mgag200_drv.h" | 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 | vblkstr = mode->crtc_vblank_start; | 226 | vblkstr = mode->crtc_vblank_start; |
| 228 | vblkend = vtotal + 1; | 227 | vblkend = vtotal + 1; |
| 229 | 228 | ||
| 230 | /* | 229 | linecomp = vdispend; |
| 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; | ||
| 238 | 230 | ||
| 239 | misc = RREG8(MGA_MISC_IN); | 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 | struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state); | 637 | struct mgag200_crtc_state *mgag200_crtc_state = to_mgag200_crtc_state(crtc_state); |
| 646 | struct drm_device *dev = crtc->dev; | 638 | struct drm_device *dev = crtc->dev; |
| 647 | struct mga_device *mdev = to_mga_device(dev); | 639 | struct mga_device *mdev = to_mga_device(dev); |
| 648 | struct drm_pending_vblank_event *event; | ||
| 649 | unsigned long flags; | ||
| 650 | 640 | ||
| 651 | if (crtc_state->enable && crtc_state->color_mgmt_changed) { | 641 | if (crtc_state->enable && crtc_state->color_mgmt_changed) { |
| 652 | const struct drm_format_info *format = mgag200_crtc_state->format; | 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 | else | 646 | else |
| 657 | mgag200_crtc_set_gamma_linear(mdev, format); | 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 | void mgag200_crtc_helper_atomic_enable(struct drm_crtc *crtc, struct drm_atomic_state *old_state) | 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 | mgag200_crtc_set_gamma_linear(mdev, format); | 670 | mgag200_crtc_set_gamma_linear(mdev, format); |
| 693 | 671 | ||
| 694 | mgag200_enable_display(mdev); | 672 | mgag200_enable_display(mdev); |
| 695 | |||
| 696 | drm_crtc_vblank_on(crtc); | ||
| 697 | } | 673 | } |
| 698 | 674 | ||
| 699 | void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *old_state) | 675 | void mgag200_crtc_helper_atomic_disable(struct drm_crtc *crtc, struct drm_atomic_state *old_state) |
| 700 | { | 676 | { |
| 701 | struct mga_device *mdev = to_mga_device(crtc->dev); | 677 | struct mga_device *mdev = to_mga_device(crtc->dev); |
| 702 | 678 | ||
| 703 | drm_crtc_vblank_off(crtc); | ||
| 704 | |||
| 705 | mgag200_disable_display(mdev); | 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 | void mgag200_crtc_reset(struct drm_crtc *crtc) | 682 | void mgag200_crtc_reset(struct drm_crtc *crtc) |
| 734 | { | 683 | { |
| 735 | struct mgag200_crtc_state *mgag200_crtc_state; | 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 | kfree(mgag200_crtc_state); | 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 | * Mode config | 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 | static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, | 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 | bool sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1; | 106 | bool sysprof = refcount_read(&a6xx_gpu->base.base.sysprof_active) > 1; |
| 107 | struct msm_file_private *ctx = submit->queue->ctx; | ||
| 107 | struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; | 108 | struct adreno_gpu *adreno_gpu = &a6xx_gpu->base; |
| 108 | phys_addr_t ttbr; | 109 | phys_addr_t ttbr; |
| 109 | u32 asid; | 110 | u32 asid; |
| @@ -115,6 +116,15 @@ static void a6xx_set_pagetable(struct a6xx_gpu *a6xx_gpu, · 5 unmodified lines | |||
| 115 | if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid)) | 116 | if (msm_iommu_pagetable_params(ctx->aspace->mmu, &ttbr, &asid)) |
| 116 | return; | 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 | if (!sysprof) { | 128 | if (!sysprof) { |
| 119 | if (!adreno_is_a7xx(adreno_gpu)) { | 129 | if (!adreno_is_a7xx(adreno_gpu)) { |
| 120 | /* Turn off protected mode to write to special registers */ | 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 | struct msm_ringbuffer *ring = submit->ring; | 203 | struct msm_ringbuffer *ring = submit->ring; |
| 194 | unsigned int i, ibs = 0; | 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 | get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0), | 208 | get_stats_counter(ring, REG_A6XX_RBBM_PERFCTR_CP(0), |
| 199 | rbmemptr_stats(ring, index, cpcycles_start)); | 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 | OUT_PKT7(ring, CP_THREAD_CONTROL, 1); | 293 | OUT_PKT7(ring, CP_THREAD_CONTROL, 1); |
| 284 | OUT_RING(ring, CP_THREAD_CONTROL_0_SYNC_THREADS | CP_SET_THREAD_BR); | 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 | get_stats_counter(ring, REG_A7XX_RBBM_PERFCTR_CP(0), | 298 | get_stats_counter(ring, REG_A7XX_RBBM_PERFCTR_CP(0), |
| 289 | rbmemptr_stats(ring, index, cpcycles_start)); | 299 | rbmemptr_stats(ring, index, cpcycles_start)); |
| @@ -711,12 +711,13 @@ void dpu_crtc_complete_commit(struct drm_crtc *crtc) · 710 unmodified lines | |||
| 711 | _dpu_crtc_complete_flip(crtc); | 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 | struct drm_crtc_state *state) | 715 | struct drm_crtc_state *state) |
| 716 | { | 716 | { |
| 717 | struct dpu_crtc_state *cstate = to_dpu_crtc_state(state); | 717 | struct dpu_crtc_state *cstate = to_dpu_crtc_state(state); |
| 718 | struct drm_display_mode *adj_mode = &state->adjusted_mode; | 718 | struct drm_display_mode *adj_mode = &state->adjusted_mode; |
| 719 | u32 crtc_split_width = adj_mode->hdisplay / cstate->num_mixers; | 719 | u32 crtc_split_width = adj_mode->hdisplay / cstate->num_mixers; |
| 720 | struct dpu_kms *dpu_kms = _dpu_crtc_get_kms(crtc); | ||
| 720 | int i; | 721 | int i; |
| 721 | 722 | ||
| 722 | for (i = 0; i < cstate->num_mixers; i++) { | 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 | r->y2 = adj_mode->vdisplay; | 728 | r->y2 = adj_mode->vdisplay; |
| 728 | 729 | ||
| 729 | trace_dpu_crtc_setup_lm_bounds(DRMID(crtc), i, r); | 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 | static void _dpu_crtc_get_pcc_coeff(struct drm_crtc_state *state, | 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 | DRM_DEBUG_ATOMIC("crtc%d\n", crtc->base.id); | 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 | /* encoder will trigger pending mask now */ | 814 | /* encoder will trigger pending mask now */ |
| 809 | drm_for_each_encoder_mask(encoder, crtc->dev, crtc->state->encoder_mask) | 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 | dpu_core_perf_crtc_update(crtc, 0); | 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 | /* disable clk & bw control until clk & bw properties are set */ | 1100 | /* disable clk & bw control until clk & bw properties are set */ |
| 1098 | cstate->bw_control = false; | 1101 | cstate->bw_control = false; |
| 1099 | cstate->bw_split_vote = false; | 1102 | cstate->bw_split_vote = false; |
| @@ -1192,8 +1195,11 @@ static int dpu_crtc_atomic_check(struct drm_crtc *crtc, · 92 unmodified lines | |||
| 1192 | if (crtc_state->active_changed) | 1195 | if (crtc_state->active_changed) |
| 1193 | crtc_state->mode_changed = true; | 1196 | crtc_state->mode_changed = true; |
| 1194 | 1197 | ||
| 1195 | if (cstate->num_mixers) | 1198 | if (cstate->num_mixers) { |
| 1196 | _dpu_crtc_setup_lm_bounds(crtc, crtc_state); | 1199 | rc = _dpu_crtc_check_and_setup_lm_bounds(crtc, crtc_state); |
| 1200 | if (rc) | ||
| 1201 | return rc; | ||
| 1202 | } | ||
| 1197 | 1203 | ||
| 1198 | /* FIXME: move this to dpu_plane_atomic_check? */ | 1204 | /* FIXME: move this to dpu_plane_atomic_check? */ |
| 1199 | drm_atomic_crtc_state_for_each_plane_state(plane, pstate, crtc_state) { | 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 | return topology; | 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 | static int dpu_encoder_virt_atomic_check( | 661 | static int dpu_encoder_virt_atomic_check( |
| 628 | struct drm_encoder *drm_enc, | 662 | struct drm_encoder *drm_enc, |
| 629 | struct drm_crtc_state *crtc_state, | 663 | struct drm_crtc_state *crtc_state, |
| @@ -692,6 +726,9 @@ static int dpu_encoder_virt_atomic_check( · 62 unmodified lines | |||
| 692 | if (!crtc_state->active_changed || crtc_state->enable) | 726 | if (!crtc_state->active_changed || crtc_state->enable) |
| 693 | ret = dpu_rm_reserve(&dpu_kms->rm, global_state, | 727 | ret = dpu_rm_reserve(&dpu_kms->rm, global_state, |
| 694 | drm_enc, crtc_state, topology); | 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 | trace_dpu_enc_atomic_check_flags(DRMID(drm_enc), adj_mode->flags); | 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 | struct dpu_encoder_virt *dpu_enc; | 1130 | struct dpu_encoder_virt *dpu_enc; |
| 1094 | struct msm_drm_private *priv; | 1131 | struct msm_drm_private *priv; |
| 1095 | struct dpu_kms *dpu_kms; | 1132 | struct dpu_kms *dpu_kms; |
| 1096 | struct dpu_crtc_state *cstate; | ||
| 1097 | struct dpu_global_state *global_state; | 1133 | struct dpu_global_state *global_state; |
| 1098 | struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC]; | 1134 | struct dpu_hw_blk *hw_pp[MAX_CHANNELS_PER_ENC]; |
| 1099 | struct dpu_hw_blk *hw_ctl[MAX_CHANNELS_PER_ENC]; | 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 | struct dpu_hw_blk *hw_dsc[MAX_CHANNELS_PER_ENC]; | 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 | unsigned int dsc_mask = 0; | 1138 | unsigned int dsc_mask = 0; |
| 1105 | int i; | 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 | ARRAY_SIZE(hw_pp)); | 1163 | ARRAY_SIZE(hw_pp)); |
| 1130 | num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, | 1164 | num_ctl = dpu_rm_get_assigned_resources(&dpu_kms->rm, global_state, |
| 1131 | drm_enc->base.id, DPU_HW_BLK_CTL, hw_ctl, ARRAY_SIZE(hw_ctl)); | 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 | for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) | 1167 | for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) |
| 1139 | dpu_enc->hw_pp[i] = i < num_pp ? to_dpu_hw_pingpong(hw_pp[i]) | 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 | dpu_enc->cur_master->hw_cdm = hw_cdm ? to_dpu_hw_cdm(hw_cdm) : NULL; | 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 | for (i = 0; i < dpu_enc->num_phys_encs; i++) { | 1191 | for (i = 0; i < dpu_enc->num_phys_encs; i++) { |
| 1175 | struct dpu_encoder_phys *phys = dpu_enc->phys_encs[i]; | 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 | DPU_ERROR_ENC(dpu_enc, | 1196 | DPU_ERROR_ENC(dpu_enc, |
| 1179 | "no pp block assigned at idx: %d\n", i); | 1197 | "no pp block assigned at idx: %d\n", i); |
| 1180 | return; | 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 | DPU_ERROR_ENC(dpu_enc, | 1203 | DPU_ERROR_ENC(dpu_enc, |
| 1185 | "no ctl block assigned at idx: %d\n", i); | 1204 | "no ctl block assigned at idx: %d\n", i); |
| 1186 | return; | 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 | phys->cached_mode = crtc_state->adjusted_mode; | 1208 | phys->cached_mode = crtc_state->adjusted_mode; |
| 1193 | if (phys->ops.atomic_mode_set) | 1209 | if (phys->ops.atomic_mode_set) |
| 1194 | phys->ops.atomic_mode_set(phys, crtc_state, conn_state); | 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 | intf_cfg.stream_sel = 0; /* Don't care value for video mode */ | 302 | intf_cfg.stream_sel = 0; /* Don't care value for video mode */ |
| 303 | intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); | 303 | intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); |
| 304 | intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc); | 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 | intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; | 306 | intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; |
| 307 | 307 | ||
| 308 | spin_lock_irqsave(phys_enc->enc_spinlock, lock_flags); | 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 | struct dpu_hw_ctl *ctl; | 440 | struct dpu_hw_ctl *ctl; |
| 441 | const struct msm_format *fmt; | 441 | const struct msm_format *fmt; |
| 442 | u32 fmt_fourcc; | 442 | u32 fmt_fourcc; |
| 443 | u32 mode_3d; | ||
| 443 | 444 | ||
| 444 | ctl = phys_enc->hw_ctl; | 445 | ctl = phys_enc->hw_ctl; |
| 445 | fmt_fourcc = dpu_encoder_get_drm_fmt(phys_enc); | 446 | fmt_fourcc = dpu_encoder_get_drm_fmt(phys_enc); |
| 446 | fmt = mdp_get_format(&phys_enc->dpu_kms->base, fmt_fourcc, 0); | 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 | DPU_DEBUG_VIDENC(phys_enc, "\n"); | 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 | goto skip_flush; | 468 | goto skip_flush; |
| 467 | 469 | ||
| 468 | ctl->ops.update_pending_flush_intf(ctl, phys_enc->hw_intf->idx); | 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 | ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx); | 473 | ctl->ops.update_pending_flush_merge_3d(ctl, phys_enc->hw_pp->merge_3d->idx); |
| 471 | 474 | ||
| 472 | if (ctl->ops.update_pending_flush_cdm && phys_enc->hw_cdm) | 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 | struct dpu_hw_pingpong *hw_pp; | 275 | struct dpu_hw_pingpong *hw_pp; |
| 276 | struct dpu_hw_cdm *hw_cdm; | 276 | struct dpu_hw_cdm *hw_cdm; |
| 277 | u32 pending_flush = 0; | 277 | u32 pending_flush = 0; |
| 278 | u32 mode_3d; | ||
| 278 | 279 | ||
| 279 | if (!phys_enc) | 280 | if (!phys_enc) |
| 280 | return; | 281 | return; |
| @@ -283,6 +284,7 @@ static void _dpu_encoder_phys_wb_update_flush(struct dpu_encoder_phys *phys_enc) · 2 unmodified lines | |||
| 283 | hw_pp = phys_enc->hw_pp; | 284 | hw_pp = phys_enc->hw_pp; |
| 284 | hw_ctl = phys_enc->hw_ctl; | 285 | hw_ctl = phys_enc->hw_ctl; |
| 285 | hw_cdm = phys_enc->hw_cdm; | 286 | hw_cdm = phys_enc->hw_cdm; |
| 287 | mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); | ||
| 286 | 288 | ||
| 287 | DPU_DEBUG("[wb:%d]\n", hw_wb->idx - WB_0); | 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 | if (hw_ctl->ops.update_pending_flush_wb) | 296 | if (hw_ctl->ops.update_pending_flush_wb) |
| 295 | hw_ctl->ops.update_pending_flush_wb(hw_ctl, hw_wb->idx); | 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 | hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl, | 301 | hw_ctl->ops.update_pending_flush_merge_3d(hw_ctl, |
| 299 | hw_pp->merge_3d->idx); | 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 | end_addr = base_addr + aligned_len; | 26 | end_addr = base_addr + aligned_len; |
| 27 | 27 | ||
| 28 | if (!(*reg)) | 28 | if (!(*reg)) |
| 29 | *reg = kzalloc(len_padded, GFP_KERNEL); | 29 | *reg = kvzalloc(len_padded, GFP_KERNEL); |
| 30 | 30 | ||
| 31 | if (*reg) | 31 | if (*reg) |
| 32 | dump_addr = *reg; | 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, | 51 | static void msm_disp_state_print_regs(const u32 *dump_addr, u32 len, |
| 52 | struct drm_printer *p) | 52 | void __iomem *base_addr, struct drm_printer *p) |
| 53 | { | 53 | { |
| 54 | int i; | 54 | int i; |
| 55 | u32 *dump_addr = NULL; | ||
| 56 | void __iomem *addr; | 55 | void __iomem *addr; |
| 57 | u32 num_rows; | 56 | u32 num_rows; |
| 58 | 57 | ||
| 58 | if (!dump_addr) { | ||
| 59 | drm_printf(p, "Registers not stored\n"); | ||
| 60 | return; | ||
| 61 | } | ||
| 62 | |||
| 59 | addr = base_addr; | 63 | addr = base_addr; |
| 60 | num_rows = len / REG_DUMP_ALIGN; | 64 | num_rows = len / REG_DUMP_ALIGN; |
| 61 | 65 | ||
| 62 | if (*reg) | ||
| 63 | dump_addr = *reg; | ||
| 64 | |||
| 65 | for (i = 0; i < num_rows; i++) { | 66 | for (i = 0; i < num_rows; i++) { |
| 66 | drm_printf(p, "0x%lx : %08x %08x %08x %08x\n", | 67 | drm_printf(p, "0x%lx : %08x %08x %08x %08x\n", |
| 67 | (unsigned long)(addr - base_addr), | 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 | list_for_each_entry_safe(block, tmp, &state->blocks, node) { | 91 | list_for_each_entry_safe(block, tmp, &state->blocks, node) { |
| 91 | drm_printf(p, "====================%s================\n", block->name); | 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 | drm_printf(p, "===================dpu drm state================\n"); | 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 | list_for_each_entry_safe(block, tmp, &disp_state->blocks, node) { | 163 | list_for_each_entry_safe(block, tmp, &disp_state->blocks, node) { |
| 163 | list_del(&block->node); | 164 | list_del(&block->node); |
| 164 | kfree(block->state); | 165 | kvfree(block->state); |
| 165 | kfree(block); | 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 | int new_htotal = mode->htotal - mode->hdisplay + new_hdisplay; | 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 | static unsigned long dsi_get_pclk_rate(const struct drm_display_mode *mode, | 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 | unsigned long pclk_rate; | 551 | unsigned long pclk_rate; |
| 552 | 552 | ||
| 553 | pclk_rate = mode->clock * 1000; | 553 | pclk_rate = mode->clock * 1000u; |
| 554 | 554 | ||
| 555 | if (dsc) | 555 | if (dsc) |
| 556 | pclk_rate = dsi_adjust_pclk_for_compression(mode, dsc); | 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 | return dividend - 1; | 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 | #define HDMI_REF_CLOCK_HZ ((u64)19200000) | 156 | #define HDMI_REF_CLOCK_HZ ((u64)19200000) |
| 166 | #define HDMI_MHZ_TO_HZ ((u64)1000000) | 157 | #define HDMI_MHZ_TO_HZ ((u64)1000000) |
| 167 | static int pll_get_post_div(struct hdmi_8998_post_divider *pd, u64 bclk) | 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 | } *rm; | 210 | } *rm; |
| 211 | 211 | ||
| 212 | struct { | 212 | struct { |
| 213 | struct mutex mutex;; | 213 | struct mutex mutex; |
| 214 | struct idr idr; | 214 | struct idr idr; |
| 215 | } client_id; | 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 | if (!spage || !(src & MIGRATE_PFN_MIGRATE)) | 193 | if (!spage || !(src & MIGRATE_PFN_MIGRATE)) |
| 194 | goto done; | 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 | if (!dpage) | 197 | if (!dpage) |
| 198 | goto done; | 198 | goto done; |
| 199 | 199 | ||
| @@ -332,7 +332,7 @@ nouveau_accel_ce_init(struct nouveau_drm *drm) · 331 unmodified lines | |||
| 332 | return; | 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 | if (ret) | 336 | if (ret) |
| 337 | NV_ERROR(drm, "failed to create ce channel, %d\n", ret); | 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 | msleep(60); | 298 | msleep(60); |
| 299 | 299 | ||
| 300 | hx83102_enable_extended_cmds(&dsi_ctx, true); | 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 | 0xf5, 0x39, 0x36, 0x36, 0x36, 0x36, 0x32, 0x8b, 0x11, 0x65, 0x00, 0x88, | 302 | 0xf5, 0x39, 0x36, 0x36, 0x36, 0x36, 0x32, 0x8b, 0x11, 0x65, 0x00, 0x88, |
| 303 | 0xfa, 0xff, 0xff, 0x8f, 0xff, 0x08, 0xd6, 0x33); | 303 | 0xfa, 0xff, 0xff, 0x8f, 0xff, 0x08, 0xd6, 0x33); |
| 304 | mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETDISP, 0x00, 0x47, 0xb0, 0x80, 0x00, 0x12, | 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 | 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 343 | 0xaa, 0xaa, 0xaa, 0xaa, 0xaa, 0xa0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 344 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 344 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, |
| 345 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); | 345 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00); |
| 346 | mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGMA, 0x04, 0x04, 0x06, 0x0a, 0x0a, 0x05, | 346 | mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETGMA, 0x00, 0x07, 0x10, 0x17, 0x1c, 0x33, |
| 347 | 0x12, 0x14, 0x17, 0x13, 0x2c, 0x33, 0x39, 0x4b, 0x4c, 0x56, 0x61, 0x78, | 347 | 0x48, 0x50, 0x57, 0x50, 0x68, 0x6e, 0x71, 0x7f, 0x81, 0x8a, 0x8e, 0x9b, |
| 348 | 0x7a, 0x41, 0x50, 0x68, 0x73, 0x04, 0x04, 0x06, 0x0a, 0x0a, 0x05, 0x12, | 348 | 0x9c, 0x4d, 0x56, 0x5d, 0x73, 0x00, 0x07, 0x10, 0x17, 0x1c, 0x33, 0x48, |
| 349 | 0x14, 0x17, 0x13, 0x2c, 0x33, 0x39, 0x4b, 0x4c, 0x56, 0x61, 0x78, 0x7a, | 349 | 0x50, 0x57, 0x50, 0x68, 0x6e, 0x71, 0x7f, 0x81, 0x8a, 0x8e, 0x9b, 0x9c, |
| 350 | 0x41, 0x50, 0x68, 0x73); | 350 | 0x4d, 0x56, 0x5d, 0x73); |
| 351 | mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0x07, 0x10, 0x10, 0x1a, 0x26, 0x9e, | 351 | mipi_dsi_dcs_write_seq_multi(&dsi_ctx, HX83102_SETTP1, 0x07, 0x10, 0x10, 0x1a, 0x26, 0x9e, |
| 352 | 0x00, 0x4f, 0xa0, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x12, 0x0a, 0x02, | 352 | 0x00, 0x4f, 0xa0, 0x14, 0x14, 0x00, 0x00, 0x00, 0x00, 0x12, 0x0a, 0x02, |
| 353 | 0x02, 0x00, 0x33, 0x02, 0x04, 0x18, 0x01); | 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 | struct panthor_fw_binary_iter *iter, | 500 | struct panthor_fw_binary_iter *iter, |
| 501 | u32 ehdr) | 501 | u32 ehdr) |
| 502 | { | 502 | { |
| 503 | ssize_t vm_pgsz = panthor_vm_page_size(ptdev->fw->vm); | ||
| 503 | struct panthor_fw_binary_section_entry_hdr hdr; | 504 | struct panthor_fw_binary_section_entry_hdr hdr; |
| 504 | struct panthor_fw_section *section; | 505 | struct panthor_fw_section *section; |
| 505 | u32 section_size; | 506 | u32 section_size; |
| @@ -528,8 +529,7 @@ static int panthor_fw_load_section_entry(struct panthor_device *ptdev, · 22 unmodified lines | |||
| 528 | return -EINVAL; | 529 | return -EINVAL; |
| 529 | } | 530 | } |
| 530 | 531 | ||
| 531 | if ((hdr.va.start & ~PAGE_MASK) != 0 || | 532 | if (!IS_ALIGNED(hdr.va.start, vm_pgsz) || !IS_ALIGNED(hdr.va.end, vm_pgsz)) { |
| 532 | (hdr.va.end & ~PAGE_MASK) != 0) { | ||
| 533 | drm_err(&ptdev->base, "Firmware corrupted, virtual addresses not page aligned: 0x%x-0x%x\n", | 533 | drm_err(&ptdev->base, "Firmware corrupted, virtual addresses not page aligned: 0x%x-0x%x\n", |
| 534 | hdr.va.start, hdr.va.end); | 534 | hdr.va.start, hdr.va.end); |
| 535 | return -EINVAL; | 535 | return -EINVAL; |
| @@ -44,8 +44,7 @@ void panthor_kernel_bo_destroy(struct panthor_kernel_bo *bo) · 43 unmodified lines | |||
| 44 | to_panthor_bo(bo->obj)->exclusive_vm_root_gem != panthor_vm_root_gem(vm))) | 44 | to_panthor_bo(bo->obj)->exclusive_vm_root_gem != panthor_vm_root_gem(vm))) |
| 45 | goto out_free_bo; | 45 | goto out_free_bo; |
| 46 | 46 | ||
| 47 | ret = panthor_vm_unmap_range(vm, bo->va_node.start, | 47 | ret = panthor_vm_unmap_range(vm, bo->va_node.start, bo->va_node.size); |
| 48 | panthor_kernel_bo_size(bo)); | ||
| 49 | if (ret) | 48 | if (ret) |
| 50 | goto out_free_bo; | 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 | bo = to_panthor_bo(&obj->base); | 96 | bo = to_panthor_bo(&obj->base); |
| 98 | size = obj->base.size; | ||
| 99 | kbo->obj = &obj->base; | 97 | kbo->obj = &obj->base; |
| 100 | bo->flags = bo_flags; | 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 | ret = panthor_vm_alloc_va(vm, gpu_va, size, &kbo->va_node); | 107 | ret = panthor_vm_alloc_va(vm, gpu_va, size, &kbo->va_node); |
| 103 | if (ret) | 108 | if (ret) |
| 104 | goto err_put_obj; | 109 | goto err_put_obj; |
| @@ -826,6 +826,14 @@ void panthor_vm_idle(struct panthor_vm *vm) · 825 unmodified lines | |||
| 826 | mutex_unlock(&ptdev->mmu->as.slots_lock); | 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 | static void panthor_vm_stop(struct panthor_vm *vm) | 837 | static void panthor_vm_stop(struct panthor_vm *vm) |
| 830 | { | 838 | { |
| 831 | drm_sched_stop(&vm->sched, NULL); | 839 | drm_sched_stop(&vm->sched, NULL); |
| @@ -1025,12 +1033,13 @@ int · 193 unmodified lines | |||
| 1025 | panthor_vm_alloc_va(struct panthor_vm *vm, u64 va, u64 size, | 1033 | panthor_vm_alloc_va(struct panthor_vm *vm, u64 va, u64 size, |
| 1026 | struct drm_mm_node *va_node) | 1034 | struct drm_mm_node *va_node) |
| 1027 | { | 1035 | { |
| 1036 | ssize_t vm_pgsz = panthor_vm_page_size(vm); | ||
| 1028 | int ret; | 1037 | int ret; |
| 1029 | 1038 | ||
| 1030 | if (!size || (size & ~PAGE_MASK)) | 1039 | if (!size || !IS_ALIGNED(size, vm_pgsz)) |
| 1031 | return -EINVAL; | 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 | return -EINVAL; | 1043 | return -EINVAL; |
| 1035 | 1044 | ||
| 1036 | mutex_lock(&vm->mm_lock); | 1045 | mutex_lock(&vm->mm_lock); |
| @@ -2366,11 +2375,12 @@ panthor_vm_bind_prepare_op_ctx(struct drm_file *file, · 1329 unmodified lines | |||
| 2366 | const struct drm_panthor_vm_bind_op *op, | 2375 | const struct drm_panthor_vm_bind_op *op, |
| 2367 | struct panthor_vm_op_ctx *op_ctx) | 2376 | struct panthor_vm_op_ctx *op_ctx) |
| 2368 | { | 2377 | { |
| 2378 | ssize_t vm_pgsz = panthor_vm_page_size(vm); | ||
| 2369 | struct drm_gem_object *gem; | 2379 | struct drm_gem_object *gem; |
| 2370 | int ret; | 2380 | int ret; |
| 2371 | 2381 | ||
| 2372 | /* Aligned on page size. */ | 2382 | /* Aligned on page size. */ |
| 2373 | if ((op->va | op->size) & ~PAGE_MASK) | 2383 | if (!IS_ALIGNED(op->va | op->size, vm_pgsz)) |
| 2374 | return -EINVAL; | 2384 | return -EINVAL; |
| 2375 | 2385 | ||
| 2376 | switch (op->flags & DRM_PANTHOR_VM_BIND_OP_TYPE_MASK) { | 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 | int panthor_vm_active(struct panthor_vm *vm); | 31 | int panthor_vm_active(struct panthor_vm *vm); |
| 32 | void panthor_vm_idle(struct panthor_vm *vm); | 32 | void panthor_vm_idle(struct panthor_vm *vm); |
| 33 | u32 panthor_vm_page_size(struct panthor_vm *vm); | ||
| 33 | int panthor_vm_as(struct panthor_vm *vm); | 34 | int panthor_vm_as(struct panthor_vm *vm); |
| 34 | int panthor_vm_flush_all(struct panthor_vm *vm); | 35 | int panthor_vm_flush_all(struct panthor_vm *vm); |
| 35 | 36 | ||
| @@ -602,10 +602,11 @@ struct panthor_group { · 601 unmodified lines | |||
| 602 | * @timedout: True when a timeout occurred on any of the queues owned by | 602 | * @timedout: True when a timeout occurred on any of the queues owned by |
| 603 | * this group. | 603 | * this group. |
| 604 | * | 604 | * |
| 605 | * Timeouts can be reported by drm_sched or by the FW. In any case, any | 605 | * Timeouts can be reported by drm_sched or by the FW. If a reset is required, |
| 606 | * timeout situation is unrecoverable, and the group becomes useless. | 606 | * and the group can't be suspended, this also leads to a timeout. In any case, |
| 607 | * We simply wait for all references to be dropped so we can release the | 607 | * any timeout situation is unrecoverable, and the group becomes useless. We |
| 608 | * group object. | 608 | * simply wait for all references to be dropped so we can release the group |
| 609 | * object. | ||
| 609 | */ | 610 | */ |
| 610 | bool timedout; | 611 | bool timedout; |
| 611 | 612 | ||
| @@ -2687,6 +2688,12 @@ void panthor_sched_suspend(struct panthor_device *ptdev) · 2075 unmodified lines | |||
| 2687 | csgs_upd_ctx_init(&upd_ctx); | 2688 | csgs_upd_ctx_init(&upd_ctx); |
| 2688 | while (slot_mask) { | 2689 | while (slot_mask) { |
| 2689 | u32 csg_id = ffs(slot_mask) - 1; | 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 | csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id, | 2698 | csgs_upd_ctx_queue_reqs(ptdev, &upd_ctx, csg_id, |
| 2692 | CSG_STATE_TERMINATE, | 2699 | CSG_STATE_TERMINATE, |
| @@ -3688,6 +3695,11 @@ panthor_job_create(struct panthor_file *pfile, · 995 unmodified lines | |||
| 3688 | goto err_put_job; | 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 | if (job->queue_idx >= job->group->queue_count || | 3703 | if (job->queue_idx >= job->group->queue_count || |
| 3692 | !job->group->queues[job->queue_idx]) { | 3704 | !job->group->queues[job->queue_idx]) { |
| 3693 | ret = -EINVAL; | 3705 | ret = -EINVAL; |
| @@ -87,6 +87,12 @@ · 86 unmodified lines | |||
| 87 | #define CREATE_TRACE_POINTS | 87 | #define CREATE_TRACE_POINTS |
| 88 | #include "gpu_scheduler_trace.h" | 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 | #define to_drm_sched_job(sched_job) \ | 96 | #define to_drm_sched_job(sched_job) \ |
| 91 | container_of((sched_job), struct drm_sched_job, queue_node) | 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 | sched->submit_wq = submit_wq; | 1292 | sched->submit_wq = submit_wq; |
| 1287 | sched->own_submit_wq = false; | 1293 | sched->own_submit_wq = false; |
| 1288 | } else { | 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 | if (!sched->submit_wq) | 1302 | if (!sched->submit_wq) |
| 1291 | return -ENOMEM; | 1303 | return -ENOMEM; |
| 1292 | 1304 | ||
| @@ -1156,8 +1156,8 @@ static int host1x_drm_probe(struct host1x_device *dev) · 1155 unmodified lines | |||
| 1156 | 1156 | ||
| 1157 | if (host1x_drm_wants_iommu(dev) && device_iommu_mapped(dma_dev)) { | 1157 | if (host1x_drm_wants_iommu(dev) && device_iommu_mapped(dma_dev)) { |
| 1158 | tegra->domain = iommu_paging_domain_alloc(dma_dev); | 1158 | tegra->domain = iommu_paging_domain_alloc(dma_dev); |
| 1159 | if (!tegra->domain) { | 1159 | if (IS_ERR(tegra->domain)) { |
| 1160 | err = -ENOMEM; | 1160 | err = PTR_ERR(tegra->domain); |
| 1161 | goto free; | 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 | unsigned long long rate; | 996 | unsigned long long rate; |
| 997 | struct drm_device *drm = &priv->drm; | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 1000 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1001 | 1001 | ||
| 1002 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); | 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 | unsigned long long rate; | 1017 | unsigned long long rate; |
| 1018 | struct drm_device *drm = &priv->drm; | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 1021 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1022 | 1022 | ||
| 1023 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); | 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 | unsigned long long rate; | 1038 | unsigned long long rate; |
| 1039 | struct drm_device *drm = &priv->drm; | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 1042 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1043 | 1043 | ||
| 1044 | rate = drm_hdmi_compute_mode_clock(mode, 10, HDMI_COLORSPACE_RGB); | 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 | unsigned long long rate; | 1056 | unsigned long long rate; |
| 1057 | struct drm_device *drm = &priv->drm; | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 1060 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1061 | 1061 | ||
| 1062 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); | 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 | unsigned long long rate; | 1077 | unsigned long long rate; |
| 1078 | struct drm_device *drm = &priv->drm; | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 1081 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1082 | 1082 | ||
| 1083 | rate = drm_hdmi_compute_mode_clock(mode, 12, HDMI_COLORSPACE_RGB); | 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 | unsigned long long rate; | 1095 | unsigned long long rate; |
| 1096 | struct drm_device *drm = &priv->drm; | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 1099 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1100 | 1100 | ||
| 1101 | KUNIT_ASSERT_TRUE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); | 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 | unsigned long long rate; | 1118 | unsigned long long rate; |
| 1119 | unsigned int vic = *(unsigned int *)test->param_value; | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 1122 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1123 | 1123 | ||
| 1124 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); | 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 | drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; | 1155 | drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; |
| 1156 | unsigned long long rate; | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 1159 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1160 | 1160 | ||
| 1161 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); | 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 | drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; | 1180 | drm_hdmi_compute_mode_clock_yuv420_vic_valid_tests[0]; |
| 1181 | unsigned long long rate; | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 1184 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1185 | 1185 | ||
| 1186 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); | 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 | struct drm_device *drm = &priv->drm; | 1203 | struct drm_device *drm = &priv->drm; |
| 1204 | unsigned long long rate; | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 1207 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1208 | 1208 | ||
| 1209 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); | 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 | struct drm_device *drm = &priv->drm; | 1225 | struct drm_device *drm = &priv->drm; |
| 1226 | unsigned long long rate; | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 1229 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1230 | 1230 | ||
| 1231 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); | 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 | struct drm_device *drm = &priv->drm; | 1247 | struct drm_device *drm = &priv->drm; |
| 1248 | unsigned long long rate; | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 1251 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1252 | 1252 | ||
| 1253 | KUNIT_ASSERT_FALSE(test, mode->flags & DRM_MODE_FLAG_DBLCLK); | 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 | ctx = drm_kunit_helper_acquire_ctx_alloc(test); | 441 | ctx = drm_kunit_helper_acquire_ctx_alloc(test); |
| 442 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 445 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 446 | 446 | ||
| 447 | drm = &priv->drm; | 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 | ctx = drm_kunit_helper_acquire_ctx_alloc(test); | 555 | ctx = drm_kunit_helper_acquire_ctx_alloc(test); |
| 556 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 559 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 560 | 560 | ||
| 561 | drm = &priv->drm; | 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 | ctx = drm_kunit_helper_acquire_ctx_alloc(test); | 671 | ctx = drm_kunit_helper_acquire_ctx_alloc(test); |
| 672 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 675 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 676 | 676 | ||
| 677 | drm = &priv->drm; | 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 | ctx = drm_kunit_helper_acquire_ctx_alloc(test); | 1263 | ctx = drm_kunit_helper_acquire_ctx_alloc(test); |
| 1264 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, ctx); | 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 | KUNIT_ASSERT_NOT_NULL(test, mode); | 1267 | KUNIT_ASSERT_NOT_NULL(test, mode); |
| 1268 | 1268 | ||
| 1269 | /* | 1269 | /* |
| @@ -3,6 +3,7 @@ · 2 unmodified lines | |||
| 3 | #include <drm/drm_atomic.h> | 3 | #include <drm/drm_atomic.h> |
| 4 | #include <drm/drm_atomic_helper.h> | 4 | #include <drm/drm_atomic_helper.h> |
| 5 | #include <drm/drm_drv.h> | 5 | #include <drm/drm_drv.h> |
| 6 | #include <drm/drm_edid.h> | ||
| 6 | #include <drm/drm_fourcc.h> | 7 | #include <drm/drm_fourcc.h> |
| 7 | #include <drm/drm_kunit_helpers.h> | 8 | #include <drm/drm_kunit_helpers.h> |
| 8 | #include <drm/drm_managed.h> | 9 | #include <drm/drm_managed.h> |
| @@ -311,6 +312,47 @@ drm_kunit_helper_create_crtc(struct kunit *test, · 302 unmodified lines | |||
| 311 | } | 312 | } |
| 312 | EXPORT_SYMBOL_GPL(drm_kunit_helper_create_crtc); | 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 | MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>"); | 356 | MODULE_AUTHOR("Maxime Ripard <maxime@cerno.tech>"); |
| 315 | MODULE_DESCRIPTION("KUnit test suite helper functions"); | 357 | MODULE_DESCRIPTION("KUnit test suite helper functions"); |
| 316 | MODULE_LICENSE("GPL"); | 358 | MODULE_LICENSE("GPL"); |
| @@ -306,6 +306,11 @@ void v3d_perfmon_open_file(struct v3d_file_priv *v3d_priv) · 305 unmodified lines | |||
| 306 | static int v3d_perfmon_idr_del(int id, void *elem, void *data) | 306 | static int v3d_perfmon_idr_del(int id, void *elem, void *data) |
| 307 | { | 307 | { |
| 308 | struct v3d_perfmon *perfmon = elem; | 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 | v3d_perfmon_put(perfmon); | 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 | void v3d_perfmon_close_file(struct v3d_file_priv *v3d_priv) | 320 | void v3d_perfmon_close_file(struct v3d_file_priv *v3d_priv) |
| 316 | { | 321 | { |
| 322 | struct v3d_dev *v3d = v3d_priv->v3d; | ||
| 323 | |||
| 317 | mutex_lock(&v3d_priv->perfmon.lock); | 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 | idr_destroy(&v3d_priv->perfmon.idr); | 326 | idr_destroy(&v3d_priv->perfmon.idr); |
| 320 | mutex_unlock(&v3d_priv->perfmon.lock); | 327 | mutex_unlock(&v3d_priv->perfmon.lock); |
| 321 | mutex_destroy(&v3d_priv->perfmon.lock); | 328 | mutex_destroy(&v3d_priv->perfmon.lock); |
| @@ -116,6 +116,11 @@ void vc4_perfmon_open_file(struct vc4_file *vc4file) · 115 unmodified lines | |||
| 116 | static int vc4_perfmon_idr_del(int id, void *elem, void *data) | 116 | static int vc4_perfmon_idr_del(int id, void *elem, void *data) |
| 117 | { | 117 | { |
| 118 | struct vc4_perfmon *perfmon = elem; | 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 | vc4_perfmon_put(perfmon); | 125 | vc4_perfmon_put(perfmon); |
| 121 | 126 | ||
| @@ -130,7 +135,7 @@ void vc4_perfmon_close_file(struct vc4_file *vc4file) · 8 unmodified lines | |||
| 130 | return; | 135 | return; |
| 131 | 136 | ||
| 132 | mutex_lock(&vc4file->perfmon.lock); | 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 | idr_destroy(&vc4file->perfmon.idr); | 139 | idr_destroy(&vc4file->perfmon.idr); |
| 135 | mutex_unlock(&vc4file->perfmon.lock); | 140 | mutex_unlock(&vc4file->perfmon.lock); |
| 136 | mutex_destroy(&vc4file->perfmon.lock); | 141 | mutex_destroy(&vc4file->perfmon.lock); |
| @@ -635,10 +635,8 @@ out: · 634 unmodified lines | |||
| 635 | kunmap_atomic(d.src_addr); | 635 | kunmap_atomic(d.src_addr); |
| 636 | if (d.dst_addr) | 636 | if (d.dst_addr) |
| 637 | kunmap_atomic(d.dst_addr); | 637 | kunmap_atomic(d.dst_addr); |
| 638 | if (src_pages) | 638 | kvfree(src_pages); |
| 639 | kvfree(src_pages); | 639 | kvfree(dst_pages); |
| 640 | if (dst_pages) | ||
| 641 | kvfree(dst_pages); | ||
| 642 | 640 | ||
| 643 | return ret; | 641 | return ret; |
| 644 | } | 642 | } |
| @@ -62,7 +62,7 @@ · 61 unmodified lines | |||
| 62 | #define VMWGFX_DRIVER_MINOR 20 | 62 | #define VMWGFX_DRIVER_MINOR 20 |
| 63 | #define VMWGFX_DRIVER_PATCHLEVEL 0 | 63 | #define VMWGFX_DRIVER_PATCHLEVEL 0 |
| 64 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) | 64 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) |
| 65 | #define VMWGFX_MAX_DISPLAYS 16 | 65 | #define VMWGFX_NUM_DISPLAY_UNITS 8 |
| 66 | #define VMWGFX_CMD_BOUNCE_INIT_SIZE 32768 | 66 | #define VMWGFX_CMD_BOUNCE_INIT_SIZE 32768 |
| 67 | 67 | ||
| 68 | #define VMWGFX_MIN_INITIAL_WIDTH 1280 | 68 | #define VMWGFX_MIN_INITIAL_WIDTH 1280 |
| @@ -82,7 +82,7 @@ · 13 unmodified lines | |||
| 82 | #define VMWGFX_NUM_GB_CONTEXT 256 | 82 | #define VMWGFX_NUM_GB_CONTEXT 256 |
| 83 | #define VMWGFX_NUM_GB_SHADER 20000 | 83 | #define VMWGFX_NUM_GB_SHADER 20000 |
| 84 | #define VMWGFX_NUM_GB_SURFACE 32768 | 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 | #define VMWGFX_NUM_DXCONTEXT 256 | 86 | #define VMWGFX_NUM_DXCONTEXT 256 |
| 87 | #define VMWGFX_NUM_DXQUERY 512 | 87 | #define VMWGFX_NUM_DXQUERY 512 |
| 88 | #define VMWGFX_NUM_MOB (VMWGFX_NUM_GB_CONTEXT +\ | 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 | struct drm_device *dev = &dev_priv->drm; | 1284 | struct drm_device *dev = &dev_priv->drm; |
| 1285 | struct vmw_framebuffer_surface *vfbs; | 1285 | struct vmw_framebuffer_surface *vfbs; |
| 1286 | enum SVGA3dSurfaceFormat format; | ||
| 1287 | struct vmw_surface *surface; | 1286 | struct vmw_surface *surface; |
| 1288 | int ret; | 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 | return -EINVAL; | 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 | vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL); | 1322 | vfbs = kzalloc(sizeof(*vfbs), GFP_KERNEL); |
| 1352 | if (!vfbs) { | 1323 | if (!vfbs) { |
| 1353 | ret = -ENOMEM; | 1324 | ret = -ENOMEM; |
| @@ -1539,6 +1510,7 @@ static struct drm_framebuffer *vmw_kms_fb_create(struct drm_device *dev, · 185 unmodified lines | |||
| 1539 | DRM_ERROR("Surface size cannot exceed %dx%d\n", | 1510 | DRM_ERROR("Surface size cannot exceed %dx%d\n", |
| 1540 | dev_priv->texture_max_width, | 1511 | dev_priv->texture_max_width, |
| 1541 | dev_priv->texture_max_height); | 1512 | dev_priv->texture_max_height); |
| 1513 | ret = -EINVAL; | ||
| 1542 | goto err_out; | 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 | struct drm_mode_config *mode_config = &dev->mode_config; | 2197 | struct drm_mode_config *mode_config = &dev->mode_config; |
| 2226 | struct drm_vmw_update_layout_arg *arg = | 2198 | struct drm_vmw_update_layout_arg *arg = |
| 2227 | (struct drm_vmw_update_layout_arg *)data; | 2199 | (struct drm_vmw_update_layout_arg *)data; |
| 2228 | void __user *user_rects; | 2200 | const void __user *user_rects; |
| 2229 | struct drm_vmw_rect *rects; | 2201 | struct drm_vmw_rect *rects; |
| 2230 | struct drm_rect *drm_rects; | 2202 | struct drm_rect *drm_rects; |
| 2231 | unsigned rects_size; | 2203 | unsigned rects_size; |
| @@ -2237,6 +2209,8 @@ int vmw_kms_update_layout_ioctl(struct drm_device *dev, void *data, · 5 unmodified lines | |||
| 2237 | VMWGFX_MIN_INITIAL_HEIGHT}; | 2209 | VMWGFX_MIN_INITIAL_HEIGHT}; |
| 2238 | vmw_du_update_layout(dev_priv, 1, &def_rect); | 2210 | vmw_du_update_layout(dev_priv, 1, &def_rect); |
| 2239 | return 0; | 2211 | return 0; |
| 2212 | } else if (arg->num_outputs > VMWGFX_NUM_DISPLAY_UNITS) { | ||
| 2213 | return -E2BIG; | ||
| 2240 | } | 2214 | } |
| 2241 | 2215 | ||
| 2242 | rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect); | 2216 | rects_size = arg->num_outputs * sizeof(struct drm_vmw_rect); |
| @@ -199,9 +199,6 @@ struct vmw_kms_dirty { · 198 unmodified lines | |||
| 199 | s32 unit_y2; | 199 | s32 unit_y2; |
| 200 | }; | 200 | }; |
| 201 | 201 | ||
| 202 | #define VMWGFX_NUM_DISPLAY_UNITS 8 | ||
| 203 | |||
| 204 | |||
| 205 | #define vmw_framebuffer_to_vfb(x) \ | 202 | #define vmw_framebuffer_to_vfb(x) \ |
| 206 | container_of(x, struct vmw_framebuffer, base) | 203 | container_of(x, struct vmw_framebuffer, base) |
| 207 | #define vmw_framebuffer_to_vfbs(x) \ | 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 | struct drm_crtc_state *new_crtc_state; | 886 | struct drm_crtc_state *new_crtc_state; |
| 887 | 887 | ||
| 888 | conn_state = drm_atomic_get_connector_state(state, conn); | 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 | du = vmw_connector_to_stdu(conn); | 893 | du = vmw_connector_to_stdu(conn); |
| 890 | 894 | ||
| 891 | if (!conn_state->crtc) | 895 | if (!conn_state->crtc) |
| @@ -2276,9 +2276,12 @@ int vmw_dumb_create(struct drm_file *file_priv, · 2275 unmodified lines | |||
| 2276 | const struct SVGA3dSurfaceDesc *desc = vmw_surface_get_desc(format); | 2276 | const struct SVGA3dSurfaceDesc *desc = vmw_surface_get_desc(format); |
| 2277 | SVGA3dSurfaceAllFlags flags = SVGA3D_SURFACE_HINT_TEXTURE | | 2277 | SVGA3dSurfaceAllFlags flags = SVGA3D_SURFACE_HINT_TEXTURE | |
| 2278 | SVGA3D_SURFACE_HINT_RENDERTARGET | | 2278 | SVGA3D_SURFACE_HINT_RENDERTARGET | |
| 2279 | SVGA3D_SURFACE_SCREENTARGET | | 2279 | SVGA3D_SURFACE_SCREENTARGET; |
| 2280 | SVGA3D_SURFACE_BIND_SHADER_RESOURCE | | 2280 | |
| 2281 | SVGA3D_SURFACE_BIND_RENDER_TARGET; | 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 | * Without mob support we're just going to use raw memory buffer | 2287 | * Without mob support we're just going to use raw memory buffer |
| @@ -410,12 +410,6 @@ · 409 unmodified lines | |||
| 410 | 410 | ||
| 411 | #define XE2LPM_SCRATCH3_LBCF XE_REG_MCR(0xb654) | 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 | #define XE2LPM_L3SQCREG5 XE_REG_MCR(0xb658) | 413 | #define XE2LPM_L3SQCREG5 XE_REG_MCR(0xb658) |
| 420 | 414 | ||
| 421 | #define XE2_TDF_CTRL XE_REG(0xb418) | 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 | XE_FORCE_WAKE_ACK_TIMEOUT_MS * USEC_PER_MSEC, | 115 | XE_FORCE_WAKE_ACK_TIMEOUT_MS * USEC_PER_MSEC, |
| 116 | &value, true); | 116 | &value, true); |
| 117 | if (ret) | 117 | if (ret) |
| 118 | xe_gt_notice(gt, "Force wake domain %d failed to ack %s (%pe) reg[%#x] = %#x\n", | 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), | 119 | domain->id, str_wake_sleep(wake), ERR_PTR(ret), |
| 120 | domain->reg_ack.addr, value); | 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 | return ret; | 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 | static void xe_ggtt_invalidate(struct xe_ggtt *ggtt) | 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 | /* Each GT in a tile has its own TLB to cache GGTT lookups */ | 414 | /* Each GT in a tile has its own TLB to cache GGTT lookups */ |
| 405 | ggtt_invalidate_gt_tlb(ggtt->tile->primary_gt); | 415 | ggtt_invalidate_gt_tlb(ggtt->tile->primary_gt); |
| 406 | ggtt_invalidate_gt_tlb(ggtt->tile->media_gt); | 416 | ggtt_invalidate_gt_tlb(ggtt->tile->media_gt); |
| @@ -1018,6 +1018,24 @@ retry_same_fence: · 1017 unmodified lines | |||
| 1018 | 1018 | ||
| 1019 | ret = wait_event_timeout(ct->g2h_fence_wq, g2h_fence.done, HZ); | 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 | * Ensure we serialize with completion side to prevent UAF with fence going out of scope on | 1040 | * Ensure we serialize with completion side to prevent UAF with fence going out of scope on |
| 1023 | * the stack, since we have no clue if it will fire after the timeout before we can erase | 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 | EXEC_QUEUE_STATE_BANNED)); | 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 | static void guc_submit_fini(struct drm_device *drm, void *arg) | 228 | static void guc_submit_fini(struct drm_device *drm, void *arg) |
| 296 | { | 229 | { |
| 297 | struct xe_guc *guc = arg; | 230 | struct xe_guc *guc = arg; |
| 298 | 231 | ||
| 299 | xe_guc_submit_fini(guc); | ||
| 300 | xa_destroy(&guc->submission_state.exec_queue_lookup); | 232 | xa_destroy(&guc->submission_state.exec_queue_lookup); |
| 301 | free_submit_wq(guc); | ||
| 302 | } | 233 | } |
| 303 | 234 | ||
| 304 | static void guc_submit_wedged_fini(void *arg) | 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 | if (err) | 291 | if (err) |
| 361 | return err; | 292 | return err; |
| 362 | 293 | ||
| 363 | err = alloc_submit_wq(guc); | ||
| 364 | if (err) | ||
| 365 | return err; | ||
| 366 | |||
| 367 | gt->exec_queue_ops = &guc_exec_queue_ops; | 294 | gt->exec_queue_ops = &guc_exec_queue_ops; |
| 368 | 295 | ||
| 369 | xa_init(&guc->submission_state.exec_queue_lookup); | 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 | static bool check_timeout(struct xe_exec_queue *q, struct xe_sched_job *job) | 917 | static bool check_timeout(struct xe_exec_queue *q, struct xe_sched_job *job) |
| 991 | { | 918 | { |
| 992 | struct xe_gt *gt = guc_to_gt(exec_queue_to_guc(q)); | 919 | struct xe_gt *gt = guc_to_gt(exec_queue_to_guc(q)); |
| 993 | u32 ctx_timestamp = xe_lrc_ctx_timestamp(q->lrc[0]); | 920 | u32 ctx_timestamp, ctx_job_timestamp; |
| 994 | u32 ctx_job_timestamp = xe_lrc_ctx_job_timestamp(q->lrc[0]); | ||
| 995 | u32 timeout_ms = q->sched_props.job_timeout_ms; | 921 | u32 timeout_ms = q->sched_props.job_timeout_ms; |
| 996 | u32 diff; | 922 | u32 diff; |
| 997 | u64 running_time_ms; | 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 | * Counter wraps at ~223s at the usual 19.2MHz, be paranoid catch | 937 | * Counter wraps at ~223s at the usual 19.2MHz, be paranoid catch |
| 1001 | * possible overflows with a high timeout. | 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 | exec_queue_killed_or_banned_or_wedged(q) || | 1061 | exec_queue_killed_or_banned_or_wedged(q) || |
| 1125 | exec_queue_destroyed(q); | 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 | * If devcoredump not captured and GuC capture for the job is not ready | 1065 | * If devcoredump not captured and GuC capture for the job is not ready |
| 1133 | * do manual capture first and decide later if we need to use it | 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 | timeout = (q->vm && xe_vm_in_lr_mode(q->vm)) ? MAX_SCHEDULE_TIMEOUT : | 1432 | timeout = (q->vm && xe_vm_in_lr_mode(q->vm)) ? MAX_SCHEDULE_TIMEOUT : |
| 1500 | msecs_to_jiffies(q->sched_props.job_timeout_ms); | 1433 | msecs_to_jiffies(q->sched_props.job_timeout_ms); |
| 1501 | err = xe_sched_init(&ge->sched, &drm_sched_ops, &xe_sched_ops, | 1434 | err = xe_sched_init(&ge->sched, &drm_sched_ops, &xe_sched_ops, |
| 1502 | get_submit_wq(guc), | 1435 | NULL, q->lrc[0]->ring.size / MAX_JOB_SIZE_BYTES, 64, |
| 1503 | q->lrc[0]->ring.size / MAX_JOB_SIZE_BYTES, 64, | ||
| 1504 | timeout, guc_to_gt(guc)->ordered_wq, NULL, | 1436 | timeout, guc_to_gt(guc)->ordered_wq, NULL, |
| 1505 | q->name, gt_to_xe(q->gt)->drm.dev); | 1437 | q->name, gt_to_xe(q->gt)->drm.dev); |
| 1506 | if (err) | 1438 | if (err) |
| @@ -1817,8 +1749,13 @@ void xe_guc_submit_stop(struct xe_guc *guc) · 310 unmodified lines | |||
| 1817 | 1749 | ||
| 1818 | mutex_lock(&guc->submission_state.lock); | 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 | guc_exec_queue_stop(guc, q); | 1757 | guc_exec_queue_stop(guc, q); |
| 1758 | } | ||
| 1822 | 1759 | ||
| 1823 | mutex_unlock(&guc->submission_state.lock); | 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 | mutex_lock(&guc->submission_state.lock); | 1794 | mutex_lock(&guc->submission_state.lock); |
| 1858 | atomic_dec(&guc->submission_state.stopped); | 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 | guc_exec_queue_start(q); | 1801 | guc_exec_queue_start(q); |
| 1802 | } | ||
| 1861 | mutex_unlock(&guc->submission_state.lock); | 1803 | mutex_unlock(&guc->submission_state.lock); |
| 1862 | 1804 | ||
| 1863 | wake_up_all(&guc->ct.wq); | 1805 | wake_up_all(&guc->ct.wq); |
| @@ -74,13 +74,6 @@ struct xe_guc { · 73 unmodified lines | |||
| 74 | atomic_t stopped; | 74 | atomic_t stopped; |
| 75 | /** @submission_state.lock: protects submission state */ | 75 | /** @submission_state.lock: protects submission state */ |
| 76 | struct mutex lock; | 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 | /** @submission_state.enabled: submission is enabled */ | 77 | /** @submission_state.enabled: submission is enabled */ |
| 85 | bool enabled; | 78 | bool enabled; |
| 86 | /** @submission_state.fini_wq: submit fini wait queue */ | 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 | struct xe_user_fence *ufence; | 55 | struct xe_user_fence *ufence; |
| 56 | u64 __user *ptr = u64_to_user_ptr(addr); | 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 | return ERR_PTR(-EFAULT); | 60 | return ERR_PTR(-EFAULT); |
| 60 | 61 | ||
| 61 | ufence = kzalloc(sizeof(*ufence), GFP_KERNEL); | 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 | cl_data->in_data = in_data; | 236 | cl_data->in_data = in_data; |
| 237 | 237 | ||
| 238 | for (i = 0; i < cl_data->num_hid_devices; i++) { | 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, | 239 | in_data->sensor_virt_addr[i] = dmam_alloc_coherent(dev, sizeof(int) * 8, |
| 240 | &cl_data->sensor_dma_addr[i], | 240 | &cl_data->sensor_dma_addr[i], |
| 241 | GFP_KERNEL); | 241 | GFP_KERNEL); |
| 242 | if (!in_data->sensor_virt_addr[i]) { | 242 | if (!in_data->sensor_virt_addr[i]) { |
| 243 | rc = -ENOMEM; | 243 | rc = -ENOMEM; |
| 244 | goto cleanup; | 244 | goto cleanup; |
| @@ -331,7 +331,6 @@ cleanup: · 86 unmodified lines | |||
| 331 | int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) | 331 | int amd_sfh_hid_client_deinit(struct amd_mp2_dev *privdata) |
| 332 | { | 332 | { |
| 333 | struct amdtp_cl_data *cl_data = privdata->cl_data; | 333 | struct amdtp_cl_data *cl_data = privdata->cl_data; |
| 334 | struct amd_input_data *in_data = cl_data->in_data; | ||
| 335 | int i, status; | 334 | int i, status; |
| 336 | 335 | ||
| 337 | for (i = 0; i < cl_data->num_hid_devices; i++) { | 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 | cancel_delayed_work_sync(&cl_data->work_buffer); | 350 | cancel_delayed_work_sync(&cl_data->work_buffer); |
| 352 | amdtp_hid_remove(cl_data); | 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 | return 0; | 353 | return 0; |
| 362 | } | 354 | } |
| @@ -509,6 +509,7 @@ · 508 unmodified lines | |||
| 509 | #define I2C_DEVICE_ID_GOODIX_01E8 0x01e8 | 509 | #define I2C_DEVICE_ID_GOODIX_01E8 0x01e8 |
| 510 | #define I2C_DEVICE_ID_GOODIX_01E9 0x01e9 | 510 | #define I2C_DEVICE_ID_GOODIX_01E9 0x01e9 |
| 511 | #define I2C_DEVICE_ID_GOODIX_01F0 0x01f0 | 511 | #define I2C_DEVICE_ID_GOODIX_01F0 0x01f0 |
| 512 | #define I2C_DEVICE_ID_GOODIX_0D42 0x0d42 | ||
| 512 | 513 | ||
| 513 | #define USB_VENDOR_ID_GOODTOUCH 0x1aad | 514 | #define USB_VENDOR_ID_GOODTOUCH 0x1aad |
| 514 | #define USB_DEVICE_ID_GOODTOUCH_000f 0x000f | 515 | #define USB_DEVICE_ID_GOODTOUCH_000f 0x000f |
| @@ -868,6 +869,7 @@ · 353 unmodified lines | |||
| 868 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539 | 869 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1 0xc539 |
| 869 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f | 870 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_LIGHTSPEED_1_1 0xc53f |
| 870 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a | 871 | #define USB_DEVICE_ID_LOGITECH_NANO_RECEIVER_POWERPLAY 0xc53a |
| 872 | #define USB_DEVICE_ID_LOGITECH_BOLT_RECEIVER 0xc548 | ||
| 871 | #define USB_DEVICE_ID_SPACETRAVELLER 0xc623 | 873 | #define USB_DEVICE_ID_SPACETRAVELLER 0xc623 |
| 872 | #define USB_DEVICE_ID_SPACENAVIGATOR 0xc626 | 874 | #define USB_DEVICE_ID_SPACENAVIGATOR 0xc626 |
| 873 | #define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 | 875 | #define USB_DEVICE_ID_DINOVO_DESKTOP 0xc704 |
| @@ -1036,6 +1038,8 @@ · 162 unmodified lines | |||
| 1036 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056 | 1038 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3220_SERIES 0xc056 |
| 1037 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057 | 1039 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3215_SERIES 0xc057 |
| 1038 | #define USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES 0xc058 | 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 | #define USB_VENDOR_ID_PANASONIC 0x04da | 1044 | #define USB_VENDOR_ID_PANASONIC 0x04da |
| 1041 | #define USB_DEVICE_ID_PANABOARD_UBT780 0x1044 | 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 | return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field, | 473 | return lenovo_input_mapping_tp10_ultrabook_kbd(hdev, hi, field, |
| 474 | usage, bit, max); | 474 | usage, bit, max); |
| 475 | case USB_DEVICE_ID_LENOVO_X1_TAB: | 475 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 476 | case USB_DEVICE_ID_LENOVO_X1_TAB3: | ||
| 476 | return lenovo_input_mapping_x1_tab_kbd(hdev, hi, field, usage, bit, max); | 477 | return lenovo_input_mapping_x1_tab_kbd(hdev, hi, field, usage, bit, max); |
| 477 | default: | 478 | default: |
| 478 | return 0; | 479 | return 0; |
| @@ -583,6 +584,7 @@ static ssize_t attr_fn_lock_store(struct device *dev, · 104 unmodified lines | |||
| 583 | break; | 584 | break; |
| 584 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: | 585 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 585 | case USB_DEVICE_ID_LENOVO_X1_TAB: | 586 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 587 | case USB_DEVICE_ID_LENOVO_X1_TAB3: | ||
| 586 | ret = lenovo_led_set_tp10ubkbd(hdev, TP10UBKBD_FN_LOCK_LED, value); | 588 | ret = lenovo_led_set_tp10ubkbd(hdev, TP10UBKBD_FN_LOCK_LED, value); |
| 587 | if (ret) | 589 | if (ret) |
| 588 | return ret; | 590 | return ret; |
| @@ -776,6 +778,7 @@ static int lenovo_event(struct hid_device *hdev, struct hid_field *field, · 187 unmodified lines | |||
| 776 | return lenovo_event_cptkbd(hdev, field, usage, value); | 778 | return lenovo_event_cptkbd(hdev, field, usage, value); |
| 777 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: | 779 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 778 | case USB_DEVICE_ID_LENOVO_X1_TAB: | 780 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 781 | case USB_DEVICE_ID_LENOVO_X1_TAB3: | ||
| 779 | return lenovo_event_tp10ubkbd(hdev, field, usage, value); | 782 | return lenovo_event_tp10ubkbd(hdev, field, usage, value); |
| 780 | default: | 783 | default: |
| 781 | return 0; | 784 | return 0; |
| @@ -1056,6 +1059,7 @@ static int lenovo_led_brightness_set(struct led_classdev *led_cdev, · 274 unmodified lines | |||
| 1056 | break; | 1059 | break; |
| 1057 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: | 1060 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 1058 | case USB_DEVICE_ID_LENOVO_X1_TAB: | 1061 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 1062 | case USB_DEVICE_ID_LENOVO_X1_TAB3: | ||
| 1059 | ret = lenovo_led_set_tp10ubkbd(hdev, tp10ubkbd_led[led_nr], value); | 1063 | ret = lenovo_led_set_tp10ubkbd(hdev, tp10ubkbd_led[led_nr], value); |
| 1060 | break; | 1064 | break; |
| 1061 | } | 1065 | } |
| @@ -1286,6 +1290,7 @@ static int lenovo_probe(struct hid_device *hdev, · 224 unmodified lines | |||
| 1286 | break; | 1290 | break; |
| 1287 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: | 1291 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 1288 | case USB_DEVICE_ID_LENOVO_X1_TAB: | 1292 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 1293 | case USB_DEVICE_ID_LENOVO_X1_TAB3: | ||
| 1289 | ret = lenovo_probe_tp10ubkbd(hdev); | 1294 | ret = lenovo_probe_tp10ubkbd(hdev); |
| 1290 | break; | 1295 | break; |
| 1291 | default: | 1296 | default: |
| @@ -1372,6 +1377,7 @@ static void lenovo_remove(struct hid_device *hdev) · 80 unmodified lines | |||
| 1372 | break; | 1377 | break; |
| 1373 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: | 1378 | case USB_DEVICE_ID_LENOVO_TP10UBKBD: |
| 1374 | case USB_DEVICE_ID_LENOVO_X1_TAB: | 1379 | case USB_DEVICE_ID_LENOVO_X1_TAB: |
| 1380 | case USB_DEVICE_ID_LENOVO_X1_TAB3: | ||
| 1375 | lenovo_remove_tp10ubkbd(hdev); | 1381 | lenovo_remove_tp10ubkbd(hdev); |
| 1376 | break; | 1382 | break; |
| 1377 | } | 1383 | } |
| @@ -1421,6 +1427,8 @@ static const struct hid_device_id lenovo_devices[] = { · 43 unmodified lines | |||
| 1421 | */ | 1427 | */ |
| 1422 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, | 1428 | { HID_DEVICE(BUS_USB, HID_GROUP_GENERIC, |
| 1423 | USB_VENDOR_ID_LENOVO, USB_DEVICE_ID_LENOVO_X1_TAB) }, | 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 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, | 2026 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, |
| 2027 | USB_VENDOR_ID_ELAN, 0x3148) }, | 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 | /* Elitegroup panel */ | 2033 | /* Elitegroup panel */ |
| 2030 | { .driver_data = MT_CLS_SERIAL, | 2034 | { .driver_data = MT_CLS_SERIAL, |
| 2031 | MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP, | 2035 | MT_USB_DEVICE(USB_VENDOR_ID_ELITEGROUP, |
| @@ -2095,6 +2099,11 @@ static const struct hid_device_id mt_devices[] = { · 63 unmodified lines | |||
| 2095 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, | 2099 | HID_DEVICE(BUS_I2C, HID_GROUP_MULTITOUCH_WIN_8, |
| 2096 | 0x347d, 0x7853) }, | 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 | /* Ilitek dual touch panel */ | 2107 | /* Ilitek dual touch panel */ |
| 2099 | { .driver_data = MT_CLS_NSMU, | 2108 | { .driver_data = MT_CLS_NSMU, |
| 2100 | MT_USB_DEVICE(USB_VENDOR_ID_ILITEK, | 2109 | MT_USB_DEVICE(USB_VENDOR_ID_ILITEK, |
| @@ -2137,6 +2146,10 @@ static const struct hid_device_id mt_devices[] = { · 36 unmodified lines | |||
| 2137 | HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH_WIN_8, | 2146 | HID_DEVICE(BUS_BLUETOOTH, HID_GROUP_MULTITOUCH_WIN_8, |
| 2138 | USB_VENDOR_ID_LOGITECH, | 2147 | USB_VENDOR_ID_LOGITECH, |
| 2139 | USB_DEVICE_ID_LOGITECH_CASA_TOUCHPAD) }, | 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 | /* MosArt panels */ | 2154 | /* MosArt panels */ |
| 2142 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, | 2155 | { .driver_data = MT_CLS_CONFIDENCE_MINUS_ONE, |
| @@ -38,8 +38,10 @@ · 37 unmodified lines | |||
| 38 | (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) | 38 | (usage->hid & HID_USAGE_PAGE) == HID_UP_CONSUMER) |
| 39 | 39 | ||
| 40 | #define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0) | 40 | #define PLT_QUIRK_DOUBLE_VOLUME_KEYS BIT(0) |
| 41 | #define PLT_QUIRK_FOLLOWED_OPPOSITE_VOLUME_KEYS BIT(1) | ||
| 41 | 42 | ||
| 42 | #define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */ | 43 | #define PLT_DOUBLE_KEY_TIMEOUT 5 /* ms */ |
| 44 | #define PLT_FOLLOWED_OPPOSITE_KEY_TIMEOUT 220 /* ms */ | ||
| 43 | 45 | ||
| 44 | struct plt_drv_data { | 46 | struct plt_drv_data { |
| 45 | unsigned long device_type; | 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 | drv_data->last_volume_key_ts = cur_ts; | 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 | return 0; | 158 | return 0; |
| 142 | } | 159 | } |
| @@ -210,6 +227,12 @@ static const struct hid_device_id plantronics_devices[] = { · 67 unmodified lines | |||
| 210 | { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, | 227 | { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, |
| 211 | USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES), | 228 | USB_DEVICE_ID_PLANTRONICS_BLACKWIRE_3225_SERIES), |
| 212 | .driver_data = PLT_QUIRK_DOUBLE_VOLUME_KEYS }, | 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 | { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, | 236 | { HID_USB_DEVICE(USB_VENDOR_ID_PLANTRONICS, HID_ANY_ID) }, |
| 214 | { } | 237 | { } |
| 215 | }; | 238 | }; |
| @@ -50,6 +50,7 @@ · 49 unmodified lines | |||
| 50 | #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(3) | 50 | #define I2C_HID_QUIRK_BAD_INPUT_SIZE BIT(3) |
| 51 | #define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(4) | 51 | #define I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET BIT(4) |
| 52 | #define I2C_HID_QUIRK_NO_SLEEP_ON_SUSPEND BIT(5) | 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 | /* Command opcodes */ | 55 | /* Command opcodes */ |
| 55 | #define I2C_HID_OPCODE_RESET 0x01 | 56 | #define I2C_HID_OPCODE_RESET 0x01 |
| @@ -140,6 +141,8 @@ static const struct i2c_hid_quirks { · 84 unmodified lines | |||
| 140 | { USB_VENDOR_ID_ELAN, HID_ANY_ID, | 141 | { USB_VENDOR_ID_ELAN, HID_ANY_ID, |
| 141 | I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET | | 142 | I2C_HID_QUIRK_NO_WAKEUP_AFTER_RESET | |
| 142 | I2C_HID_QUIRK_BOGUS_IRQ }, | 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 | { 0, 0 } | 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 | return -ENXIO; | 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 | /* Instead of resetting device, simply powers the device on. This | 994 | /* Instead of resetting device, simply powers the device on. This |
| 985 | * solves "incomplete reports" on Raydium devices 2386:3118 and | 995 | * solves "incomplete reports" on Raydium devices 2386:3118 and |
| 986 | * 2386:4B33 and fixes various SIS touchscreens no longer sending | 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 | const struct firmware *fw, | 635 | const struct firmware *fw, |
| 636 | const struct shim_fw_info fw_info) | 636 | const struct shim_fw_info fw_info) |
| 637 | { | 637 | { |
| 638 | int rv; | 638 | int rv = 0; |
| 639 | void *dma_buf; | 639 | void *dma_buf; |
| 640 | dma_addr_t dma_buf_phy; | 640 | dma_addr_t dma_buf_phy; |
| 641 | u32 fragment_offset, fragment_size, payload_max_size; | 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 | /* Going into range select tool */ | 2567 | /* Going into range select tool */ |
| 2568 | if (wacom_wac->hid_data.invert_state) | 2568 | if (wacom_wac->hid_data.invert_state) |
| 2569 | wacom_wac->tool[0] = BTN_TOOL_RUBBER; | 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 | else if (wacom_wac->id[0]) | 2572 | else if (wacom_wac->id[0]) |
| 2571 | wacom_wac->tool[0] = wacom_intuos_get_tool_type(wacom_wac->id[0]); | 2573 | wacom_wac->tool[0] = wacom_intuos_get_tool_type(wacom_wac->id[0]); |
| 2572 | else | 2574 | else |
| @@ -162,6 +162,7 @@ config SENSORS_ADM9240 · 161 unmodified lines | |||
| 162 | tristate "Analog Devices ADM9240 and compatibles" | 162 | tristate "Analog Devices ADM9240 and compatibles" |
| 163 | depends on I2C | 163 | depends on I2C |
| 164 | select HWMON_VID | 164 | select HWMON_VID |
| 165 | select REGMAP_I2C | ||
| 165 | help | 166 | help |
| 166 | If you say yes here you get support for Analog Devices ADM9240, | 167 | If you say yes here you get support for Analog Devices ADM9240, |
| 167 | Dallas DS1780, National Semiconductor LM81 sensor chips. | 168 | Dallas DS1780, National Semiconductor LM81 sensor chips. |
| @@ -223,6 +224,7 @@ config SENSORS_ADT7462 · 55 unmodified lines | |||
| 223 | config SENSORS_ADT7470 | 224 | config SENSORS_ADT7470 |
| 224 | tristate "Analog Devices ADT7470" | 225 | tristate "Analog Devices ADT7470" |
| 225 | depends on I2C | 226 | depends on I2C |
| 227 | select REGMAP_I2C | ||
| 226 | help | 228 | help |
| 227 | If you say yes here you get support for the Analog Devices | 229 | If you say yes here you get support for the Analog Devices |
| 228 | ADT7470 temperature monitoring chips. | 230 | ADT7470 temperature monitoring chips. |
| @@ -999,6 +1001,7 @@ config SENSORS_LTC2990 · 770 unmodified lines | |||
| 999 | config SENSORS_LTC2991 | 1001 | config SENSORS_LTC2991 |
| 1000 | tristate "Analog Devices LTC2991" | 1002 | tristate "Analog Devices LTC2991" |
| 1001 | depends on I2C | 1003 | depends on I2C |
| 1004 | select REGMAP_I2C | ||
| 1002 | help | 1005 | help |
| 1003 | If you say yes here you get support for Analog Devices LTC2991 | 1006 | If you say yes here you get support for Analog Devices LTC2991 |
| 1004 | Octal I2C Voltage, Current, and Temperature Monitor. The LTC2991 | 1007 | Octal I2C Voltage, Current, and Temperature Monitor. The LTC2991 |
| @@ -1146,6 +1149,7 @@ config SENSORS_MAX1619 · 141 unmodified lines | |||
| 1146 | config SENSORS_MAX1668 | 1149 | config SENSORS_MAX1668 |
| 1147 | tristate "Maxim MAX1668 and compatibles" | 1150 | tristate "Maxim MAX1668 and compatibles" |
| 1148 | depends on I2C | 1151 | depends on I2C |
| 1152 | select REGMAP_I2C | ||
| 1149 | help | 1153 | help |
| 1150 | If you say yes here you get support for MAX1668, MAX1989 and | 1154 | If you say yes here you get support for MAX1668, MAX1989 and |
| 1151 | MAX1805 chips. | 1155 | MAX1805 chips. |
| @@ -1275,6 +1279,7 @@ config SENSORS_MAX31790 · 123 unmodified lines | |||
| 1275 | config SENSORS_MC34VR500 | 1279 | config SENSORS_MC34VR500 |
| 1276 | tristate "NXP MC34VR500 hardware monitoring driver" | 1280 | tristate "NXP MC34VR500 hardware monitoring driver" |
| 1277 | depends on I2C | 1281 | depends on I2C |
| 1282 | select REGMAP_I2C | ||
| 1278 | help | 1283 | help |
| 1279 | If you say yes here you get support for the temperature and input | 1284 | If you say yes here you get support for the temperature and input |
| 1280 | voltage sensors of the NXP MC34VR500. | 1285 | voltage sensors of the NXP MC34VR500. |
| @@ -2312,6 +2317,7 @@ config SENSORS_TMP464 · 1031 unmodified lines | |||
| 2312 | config SENSORS_TMP513 | 2317 | config SENSORS_TMP513 |
| 2313 | tristate "Texas Instruments TMP513 and compatibles" | 2318 | tristate "Texas Instruments TMP513 and compatibles" |
| 2314 | depends on I2C | 2319 | depends on I2C |
| 2320 | select REGMAP_I2C | ||
| 2315 | help | 2321 | help |
| 2316 | If you say yes here you get support for Texas Instruments TMP512, | 2322 | If you say yes here you get support for Texas Instruments TMP512, |
| 2317 | and TMP513 temperature and power supply sensor chips. | 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 | static int adt7475_fan_pwm_config(struct i2c_client *client) | 1735 | static int adt7475_fan_pwm_config(struct i2c_client *client) |
| 1736 | { | 1736 | { |
| 1737 | struct adt7475_data *data = i2c_get_clientdata(client); | 1737 | struct adt7475_data *data = i2c_get_clientdata(client); |
| 1738 | struct fwnode_handle *child; | ||
| 1739 | struct adt7475_pwm_config cfg = {}; | 1738 | struct adt7475_pwm_config cfg = {}; |
| 1740 | int ret; | 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 | if (!fwnode_property_present(child, "pwms")) | 1742 | if (!fwnode_property_present(child, "pwms")) |
| 1744 | continue; | 1743 | continue; |
| 1745 | 1744 | ||
| @@ -358,7 +358,7 @@ static const struct m10bmc_sdata n6000bmc_temp_tbl[] = { · 357 unmodified lines | |||
| 358 | { 0x4f0, 0x4f4, 0x4f8, 0x52c, 0x0, 500, "Board Top Near FPGA Temperature" }, | 358 | { 0x4f0, 0x4f4, 0x4f8, 0x52c, 0x0, 500, "Board Top Near FPGA Temperature" }, |
| 359 | { 0x4fc, 0x500, 0x504, 0x52c, 0x0, 500, "Board Bottom Near CVL Temperature" }, | 359 | { 0x4fc, 0x500, 0x504, 0x52c, 0x0, 500, "Board Bottom Near CVL Temperature" }, |
| 360 | { 0x508, 0x50c, 0x510, 0x52c, 0x0, 500, "Board Top East Near VRs Temperature" }, | 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 | { 0x520, 0x524, 0x528, 0x52c, 0x0, 500, "Board Rear Side Temperature" }, | 362 | { 0x520, 0x524, 0x528, 0x52c, 0x0, 500, "Board Rear Side Temperature" }, |
| 363 | { 0x530, 0x534, 0x538, 0x52c, 0x0, 500, "Board Front Side Temperature" }, | 363 | { 0x530, 0x534, 0x538, 0x52c, 0x0, 500, "Board Front Side Temperature" }, |
| 364 | { 0x53c, 0x540, 0x544, 0x0, 0x0, 500, "QSFP1 Case Temperature" }, | 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 | return -ENODEV; | 417 | return -ENODEV; |
| 418 | 418 | ||
| 419 | if ((devid & TSE2004_DEVID_MASK) == TSE2004_DEVID && | 419 | if ((devid & TSE2004_DEVID_MASK) == TSE2004_DEVID && |
| 420 | (cap & 0x00e7) != 0x00e7) | 420 | (cap & 0x0062) != 0x0062) |
| 421 | return -ENODEV; | 421 | return -ENODEV; |
| 422 | 422 | ||
| 423 | for (i = 0; i < ARRAY_SIZE(jc42_chips); i++) { | 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 | config IIO_KX022A | 448 | config IIO_KX022A |
| 449 | tristate | 449 | tristate |
| 450 | select IIO_BUFFER | ||
| 451 | select IIO_TRIGGERED_BUFFER | ||
| 450 | 452 | ||
| 451 | config IIO_KX022A_SPI | 453 | config IIO_KX022A_SPI |
| 452 | tristate "Kionix KX022A tri-axis digital accelerometer SPI interface" | 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 | static int bma400_tap_event_en(struct bma400_data *data, | 1218 | static int bma400_tap_event_en(struct bma400_data *data, |
| 1219 | enum iio_event_direction dir, int state) | 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 | int ret; | 1223 | int ret; |
| 1223 | 1224 | ||
| 1224 | /* | 1225 | /* |
| @@ -52,6 +52,8 @@ config AD4695 · 51 unmodified lines | |||
| 52 | tristate "Analog Device AD4695 ADC Driver" | 52 | tristate "Analog Device AD4695 ADC Driver" |
| 53 | depends on SPI | 53 | depends on SPI |
| 54 | select REGMAP_SPI | 54 | select REGMAP_SPI |
| 55 | select IIO_BUFFER | ||
| 56 | select IIO_TRIGGERED_BUFFER | ||
| 55 | help | 57 | help |
| 56 | Say yes here to build support for Analog Devices AD4695 and similar | 58 | Say yes here to build support for Analog Devices AD4695 and similar |
| 57 | analog to digital converters (ADC). | 59 | analog to digital converters (ADC). |
| @@ -328,6 +330,8 @@ config AD7923 · 270 unmodified lines | |||
| 328 | config AD7944 | 330 | config AD7944 |
| 329 | tristate "Analog Devices AD7944 and similar ADCs driver" | 331 | tristate "Analog Devices AD7944 and similar ADCs driver" |
| 330 | depends on SPI | 332 | depends on SPI |
| 333 | select IIO_BUFFER | ||
| 334 | select IIO_TRIGGERED_BUFFER | ||
| 331 | help | 335 | help |
| 332 | Say yes here to build support for Analog Devices | 336 | Say yes here to build support for Analog Devices |
| 333 | AD7944, AD7985, AD7986 ADCs. | 337 | AD7944, AD7985, AD7986 ADCs. |
| @@ -1481,6 +1485,8 @@ config TI_ADS8344 · 1147 unmodified lines | |||
| 1481 | config TI_ADS8688 | 1485 | config TI_ADS8688 |
| 1482 | tristate "Texas Instruments ADS8688" | 1486 | tristate "Texas Instruments ADS8688" |
| 1483 | depends on SPI | 1487 | depends on SPI |
| 1488 | select IIO_BUFFER | ||
| 1489 | select IIO_TRIGGERED_BUFFER | ||
| 1484 | help | 1490 | help |
| 1485 | If you say yes here you get support for Texas Instruments ADS8684 and | 1491 | If you say yes here you get support for Texas Instruments ADS8684 and |
| 1486 | and ADS8688 ADC chips | 1492 | and ADS8688 ADC chips |
| @@ -1491,6 +1497,8 @@ config TI_ADS8688 · 4 unmodified lines | |||
| 1491 | config TI_ADS124S08 | 1497 | config TI_ADS124S08 |
| 1492 | tristate "Texas Instruments ADS124S08" | 1498 | tristate "Texas Instruments ADS124S08" |
| 1493 | depends on SPI | 1499 | depends on SPI |
| 1500 | select IIO_BUFFER | ||
| 1501 | select IIO_TRIGGERED_BUFFER | ||
| 1494 | help | 1502 | help |
| 1495 | If you say yes here you get support for Texas Instruments ADS124S08 | 1503 | If you say yes here you get support for Texas Instruments ADS124S08 |
| 1496 | and ADS124S06 ADC chips | 1504 | and ADS124S06 ADC chips |
| @@ -1525,6 +1533,9 @@ config TI_AM335X_ADC · 28 unmodified lines | |||
| 1525 | config TI_LMP92064 | 1533 | config TI_LMP92064 |
| 1526 | tristate "Texas Instruments LMP92064 ADC driver" | 1534 | tristate "Texas Instruments LMP92064 ADC driver" |
| 1527 | depends on SPI | 1535 | depends on SPI |
| 1536 | select REGMAP_SPI | ||
| 1537 | select IIO_BUFFER | ||
| 1538 | select IIO_TRIGGERED_BUFFER | ||
| 1528 | help | 1539 | help |
| 1529 | Say yes here to build support for the LMP92064 Precision Current and Voltage | 1540 | Say yes here to build support for the LMP92064 Precision Current and Voltage |
| 1530 | sensor. | 1541 | sensor. |
| @@ -637,7 +637,7 @@ static int ad7124_write_raw(struct iio_dev *indio_dev, · 636 unmodified lines | |||
| 637 | 637 | ||
| 638 | switch (info) { | 638 | switch (info) { |
| 639 | case IIO_CHAN_INFO_SAMP_FREQ: | 639 | case IIO_CHAN_INFO_SAMP_FREQ: |
| 640 | if (val2 != 0) { | 640 | if (val2 != 0 || val == 0) { |
| 641 | ret = -EINVAL; | 641 | ret = -EINVAL; |
| 642 | break; | 642 | break; |
| 643 | } | 643 | } |
| @@ -75,6 +75,7 @@ · 74 unmodified lines | |||
| 75 | #define T_CONVERT_NS 190 /* conversion time */ | 75 | #define T_CONVERT_NS 190 /* conversion time */ |
| 76 | #define T_CONVERT_0_NS 10 /* 1st conversion start time (oversampling) */ | 76 | #define T_CONVERT_0_NS 10 /* 1st conversion start time (oversampling) */ |
| 77 | #define T_CONVERT_X_NS 500 /* xth conversion start time (oversampling) */ | 77 | #define T_CONVERT_X_NS 500 /* xth conversion start time (oversampling) */ |
| 78 | #define T_POWERUP_US 5000 /* Power up */ | ||
| 78 | 79 | ||
| 79 | struct ad7380_timing_specs { | 80 | struct ad7380_timing_specs { |
| 80 | const unsigned int t_csh_ns; /* CS minimum high time */ | 81 | const unsigned int t_csh_ns; /* CS minimum high time */ |
| @@ -86,6 +87,9 @@ struct ad7380_chip_info { · 5 unmodified lines | |||
| 86 | unsigned int num_channels; | 87 | unsigned int num_channels; |
| 87 | unsigned int num_simult_channels; | 88 | unsigned int num_simult_channels; |
| 88 | bool has_mux; | 89 | bool has_mux; |
| 90 | const char * const *supplies; | ||
| 91 | unsigned int num_supplies; | ||
| 92 | bool external_ref_only; | ||
| 89 | const char * const *vcm_supplies; | 93 | const char * const *vcm_supplies; |
| 90 | unsigned int num_vcm_supplies; | 94 | unsigned int num_vcm_supplies; |
| 91 | const unsigned long *available_scan_masks; | 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 | DEFINE_AD7380_8_CHANNEL(ad7387_4_channels, 14, 0, u); | 247 | DEFINE_AD7380_8_CHANNEL(ad7387_4_channels, 14, 0, u); |
| 244 | DEFINE_AD7380_8_CHANNEL(ad7388_4_channels, 12, 0, u); | 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 | static const char * const ad7380_2_channel_vcm_supplies[] = { | 254 | static const char * const ad7380_2_channel_vcm_supplies[] = { |
| 247 | "aina", "ainb", | 255 | "aina", "ainb", |
| 248 | }; | 256 | }; |
| @@ -338,6 +346,8 @@ static const struct ad7380_chip_info ad7380_chip_info = { · 89 unmodified lines | |||
| 338 | .channels = ad7380_channels, | 346 | .channels = ad7380_channels, |
| 339 | .num_channels = ARRAY_SIZE(ad7380_channels), | 347 | .num_channels = ARRAY_SIZE(ad7380_channels), |
| 340 | .num_simult_channels = 2, | 348 | .num_simult_channels = 2, |
| 349 | .supplies = ad7380_supplies, | ||
| 350 | .num_supplies = ARRAY_SIZE(ad7380_supplies), | ||
| 341 | .available_scan_masks = ad7380_2_channel_scan_masks, | 351 | .available_scan_masks = ad7380_2_channel_scan_masks, |
| 342 | .timing_specs = &ad7380_timing, | 352 | .timing_specs = &ad7380_timing, |
| 343 | }; | 353 | }; |
| @@ -347,6 +357,8 @@ static const struct ad7380_chip_info ad7381_chip_info = { · 3 unmodified lines | |||
| 347 | .channels = ad7381_channels, | 357 | .channels = ad7381_channels, |
| 348 | .num_channels = ARRAY_SIZE(ad7381_channels), | 358 | .num_channels = ARRAY_SIZE(ad7381_channels), |
| 349 | .num_simult_channels = 2, | 359 | .num_simult_channels = 2, |
| 360 | .supplies = ad7380_supplies, | ||
| 361 | .num_supplies = ARRAY_SIZE(ad7380_supplies), | ||
| 350 | .available_scan_masks = ad7380_2_channel_scan_masks, | 362 | .available_scan_masks = ad7380_2_channel_scan_masks, |
| 351 | .timing_specs = &ad7380_timing, | 363 | .timing_specs = &ad7380_timing, |
| 352 | }; | 364 | }; |
| @@ -356,6 +368,8 @@ static const struct ad7380_chip_info ad7383_chip_info = { · 3 unmodified lines | |||
| 356 | .channels = ad7383_channels, | 368 | .channels = ad7383_channels, |
| 357 | .num_channels = ARRAY_SIZE(ad7383_channels), | 369 | .num_channels = ARRAY_SIZE(ad7383_channels), |
| 358 | .num_simult_channels = 2, | 370 | .num_simult_channels = 2, |
| 371 | .supplies = ad7380_supplies, | ||
| 372 | .num_supplies = ARRAY_SIZE(ad7380_supplies), | ||
| 359 | .vcm_supplies = ad7380_2_channel_vcm_supplies, | 373 | .vcm_supplies = ad7380_2_channel_vcm_supplies, |
| 360 | .num_vcm_supplies = ARRAY_SIZE(ad7380_2_channel_vcm_supplies), | 374 | .num_vcm_supplies = ARRAY_SIZE(ad7380_2_channel_vcm_supplies), |
| 361 | .available_scan_masks = ad7380_2_channel_scan_masks, | 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 | .channels = ad7384_channels, | 381 | .channels = ad7384_channels, |
| 368 | .num_channels = ARRAY_SIZE(ad7384_channels), | 382 | .num_channels = ARRAY_SIZE(ad7384_channels), |
| 369 | .num_simult_channels = 2, | 383 | .num_simult_channels = 2, |
| 384 | .supplies = ad7380_supplies, | ||
| 385 | .num_supplies = ARRAY_SIZE(ad7380_supplies), | ||
| 370 | .vcm_supplies = ad7380_2_channel_vcm_supplies, | 386 | .vcm_supplies = ad7380_2_channel_vcm_supplies, |
| 371 | .num_vcm_supplies = ARRAY_SIZE(ad7380_2_channel_vcm_supplies), | 387 | .num_vcm_supplies = ARRAY_SIZE(ad7380_2_channel_vcm_supplies), |
| 372 | .available_scan_masks = ad7380_2_channel_scan_masks, | 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 | .channels = ad7386_channels, | 394 | .channels = ad7386_channels, |
| 379 | .num_channels = ARRAY_SIZE(ad7386_channels), | 395 | .num_channels = ARRAY_SIZE(ad7386_channels), |
| 380 | .num_simult_channels = 2, | 396 | .num_simult_channels = 2, |
| 397 | .supplies = ad7380_supplies, | ||
| 398 | .num_supplies = ARRAY_SIZE(ad7380_supplies), | ||
| 381 | .has_mux = true, | 399 | .has_mux = true, |
| 382 | .available_scan_masks = ad7380_2x2_channel_scan_masks, | 400 | .available_scan_masks = ad7380_2x2_channel_scan_masks, |
| 383 | .timing_specs = &ad7380_timing, | 401 | .timing_specs = &ad7380_timing, |
| @@ -388,6 +406,8 @@ static const struct ad7380_chip_info ad7387_chip_info = { · 4 unmodified lines | |||
| 388 | .channels = ad7387_channels, | 406 | .channels = ad7387_channels, |
| 389 | .num_channels = ARRAY_SIZE(ad7387_channels), | 407 | .num_channels = ARRAY_SIZE(ad7387_channels), |
| 390 | .num_simult_channels = 2, | 408 | .num_simult_channels = 2, |
| 409 | .supplies = ad7380_supplies, | ||
| 410 | .num_supplies = ARRAY_SIZE(ad7380_supplies), | ||
| 391 | .has_mux = true, | 411 | .has_mux = true, |
| 392 | .available_scan_masks = ad7380_2x2_channel_scan_masks, | 412 | .available_scan_masks = ad7380_2x2_channel_scan_masks, |
| 393 | .timing_specs = &ad7380_timing, | 413 | .timing_specs = &ad7380_timing, |
| @@ -398,6 +418,8 @@ static const struct ad7380_chip_info ad7388_chip_info = { · 4 unmodified lines | |||
| 398 | .channels = ad7388_channels, | 418 | .channels = ad7388_channels, |
| 399 | .num_channels = ARRAY_SIZE(ad7388_channels), | 419 | .num_channels = ARRAY_SIZE(ad7388_channels), |
| 400 | .num_simult_channels = 2, | 420 | .num_simult_channels = 2, |
| 421 | .supplies = ad7380_supplies, | ||
| 422 | .num_supplies = ARRAY_SIZE(ad7380_supplies), | ||
| 401 | .has_mux = true, | 423 | .has_mux = true, |
| 402 | .available_scan_masks = ad7380_2x2_channel_scan_masks, | 424 | .available_scan_masks = ad7380_2x2_channel_scan_masks, |
| 403 | .timing_specs = &ad7380_timing, | 425 | .timing_specs = &ad7380_timing, |
| @@ -408,6 +430,9 @@ static const struct ad7380_chip_info ad7380_4_chip_info = { · 4 unmodified lines | |||
| 408 | .channels = ad7380_4_channels, | 430 | .channels = ad7380_4_channels, |
| 409 | .num_channels = ARRAY_SIZE(ad7380_4_channels), | 431 | .num_channels = ARRAY_SIZE(ad7380_4_channels), |
| 410 | .num_simult_channels = 4, | 432 | .num_simult_channels = 4, |
| 433 | .supplies = ad7380_supplies, | ||
| 434 | .num_supplies = ARRAY_SIZE(ad7380_supplies), | ||
| 435 | .external_ref_only = true, | ||
| 411 | .available_scan_masks = ad7380_4_channel_scan_masks, | 436 | .available_scan_masks = ad7380_4_channel_scan_masks, |
| 412 | .timing_specs = &ad7380_4_timing, | 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 | .channels = ad7381_4_channels, | 442 | .channels = ad7381_4_channels, |
| 418 | .num_channels = ARRAY_SIZE(ad7381_4_channels), | 443 | .num_channels = ARRAY_SIZE(ad7381_4_channels), |
| 419 | .num_simult_channels = 4, | 444 | .num_simult_channels = 4, |
| 445 | .supplies = ad7380_supplies, | ||
| 446 | .num_supplies = ARRAY_SIZE(ad7380_supplies), | ||
| 420 | .available_scan_masks = ad7380_4_channel_scan_masks, | 447 | .available_scan_masks = ad7380_4_channel_scan_masks, |
| 421 | .timing_specs = &ad7380_4_timing, | 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 | .channels = ad7383_4_channels, | 453 | .channels = ad7383_4_channels, |
| 427 | .num_channels = ARRAY_SIZE(ad7383_4_channels), | 454 | .num_channels = ARRAY_SIZE(ad7383_4_channels), |
| 428 | .num_simult_channels = 4, | 455 | .num_simult_channels = 4, |
| 456 | .supplies = ad7380_supplies, | ||
| 457 | .num_supplies = ARRAY_SIZE(ad7380_supplies), | ||
| 429 | .vcm_supplies = ad7380_4_channel_vcm_supplies, | 458 | .vcm_supplies = ad7380_4_channel_vcm_supplies, |
| 430 | .num_vcm_supplies = ARRAY_SIZE(ad7380_4_channel_vcm_supplies), | 459 | .num_vcm_supplies = ARRAY_SIZE(ad7380_4_channel_vcm_supplies), |
| 431 | .available_scan_masks = ad7380_4_channel_scan_masks, | 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 | .channels = ad7384_4_channels, | 466 | .channels = ad7384_4_channels, |
| 438 | .num_channels = ARRAY_SIZE(ad7384_4_channels), | 467 | .num_channels = ARRAY_SIZE(ad7384_4_channels), |
| 439 | .num_simult_channels = 4, | 468 | .num_simult_channels = 4, |
| 469 | .supplies = ad7380_supplies, | ||
| 470 | .num_supplies = ARRAY_SIZE(ad7380_supplies), | ||
| 440 | .vcm_supplies = ad7380_4_channel_vcm_supplies, | 471 | .vcm_supplies = ad7380_4_channel_vcm_supplies, |
| 441 | .num_vcm_supplies = ARRAY_SIZE(ad7380_4_channel_vcm_supplies), | 472 | .num_vcm_supplies = ARRAY_SIZE(ad7380_4_channel_vcm_supplies), |
| 442 | .available_scan_masks = ad7380_4_channel_scan_masks, | 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 | .channels = ad7386_4_channels, | 479 | .channels = ad7386_4_channels, |
| 449 | .num_channels = ARRAY_SIZE(ad7386_4_channels), | 480 | .num_channels = ARRAY_SIZE(ad7386_4_channels), |
| 450 | .num_simult_channels = 4, | 481 | .num_simult_channels = 4, |
| 482 | .supplies = ad7380_supplies, | ||
| 483 | .num_supplies = ARRAY_SIZE(ad7380_supplies), | ||
| 451 | .has_mux = true, | 484 | .has_mux = true, |
| 452 | .available_scan_masks = ad7380_2x4_channel_scan_masks, | 485 | .available_scan_masks = ad7380_2x4_channel_scan_masks, |
| 453 | .timing_specs = &ad7380_4_timing, | 486 | .timing_specs = &ad7380_4_timing, |
| @@ -458,6 +491,8 @@ static const struct ad7380_chip_info ad7387_4_chip_info = { · 4 unmodified lines | |||
| 458 | .channels = ad7387_4_channels, | 491 | .channels = ad7387_4_channels, |
| 459 | .num_channels = ARRAY_SIZE(ad7387_4_channels), | 492 | .num_channels = ARRAY_SIZE(ad7387_4_channels), |
| 460 | .num_simult_channels = 4, | 493 | .num_simult_channels = 4, |
| 494 | .supplies = ad7380_supplies, | ||
| 495 | .num_supplies = ARRAY_SIZE(ad7380_supplies), | ||
| 461 | .has_mux = true, | 496 | .has_mux = true, |
| 462 | .available_scan_masks = ad7380_2x4_channel_scan_masks, | 497 | .available_scan_masks = ad7380_2x4_channel_scan_masks, |
| 463 | .timing_specs = &ad7380_4_timing, | 498 | .timing_specs = &ad7380_4_timing, |
| @@ -468,6 +503,8 @@ static const struct ad7380_chip_info ad7388_4_chip_info = { · 4 unmodified lines | |||
| 468 | .channels = ad7388_4_channels, | 503 | .channels = ad7388_4_channels, |
| 469 | .num_channels = ARRAY_SIZE(ad7388_4_channels), | 504 | .num_channels = ARRAY_SIZE(ad7388_4_channels), |
| 470 | .num_simult_channels = 4, | 505 | .num_simult_channels = 4, |
| 506 | .supplies = ad7380_supplies, | ||
| 507 | .num_supplies = ARRAY_SIZE(ad7380_supplies), | ||
| 471 | .has_mux = true, | 508 | .has_mux = true, |
| 472 | .available_scan_masks = ad7380_2x4_channel_scan_masks, | 509 | .available_scan_masks = ad7380_2x4_channel_scan_masks, |
| 473 | .timing_specs = &ad7380_4_timing, | 510 | .timing_specs = &ad7380_4_timing, |
| @@ -956,7 +993,7 @@ static const struct iio_info ad7380_info = { · 482 unmodified lines | |||
| 956 | .debugfs_reg_access = &ad7380_debugfs_reg_access, | 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 | int ret; | 998 | int ret; |
| 962 | 999 | ||
| @@ -968,13 +1005,13 @@ static int ad7380_init(struct ad7380_state *st, struct regulator *vref) · 5 unmodified lines | |||
| 968 | if (ret < 0) | 1005 | if (ret < 0) |
| 969 | return ret; | 1006 | return ret; |
| 970 | 1007 | ||
| 971 | /* select internal or external reference voltage */ | 1008 | if (external_ref_en) { |
| 972 | ret = regmap_update_bits(st->regmap, AD7380_REG_ADDR_CONFIG1, | 1009 | /* select external reference voltage */ |
| 973 | AD7380_CONFIG1_REFSEL, | 1010 | ret = regmap_set_bits(st->regmap, AD7380_REG_ADDR_CONFIG1, |
| 974 | FIELD_PREP(AD7380_CONFIG1_REFSEL, | 1011 | AD7380_CONFIG1_REFSEL); |
| 975 | vref ? 1 : 0)); | 1012 | if (ret < 0) |
| 976 | if (ret < 0) | 1013 | return ret; |
| 977 | return ret; | 1014 | } |
| 978 | 1015 | ||
| 979 | /* This is the default value after reset. */ | 1016 | /* This is the default value after reset. */ |
| 980 | st->oversampling_ratio = 1; | 1017 | st->oversampling_ratio = 1; |
| @@ -987,16 +1024,11 @@ static int ad7380_init(struct ad7380_state *st, struct regulator *vref) · 6 unmodified lines | |||
| 987 | FIELD_PREP(AD7380_CONFIG2_SDO, 1)); | 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 | static int ad7380_probe(struct spi_device *spi) | 1027 | static int ad7380_probe(struct spi_device *spi) |
| 996 | { | 1028 | { |
| 997 | struct iio_dev *indio_dev; | 1029 | struct iio_dev *indio_dev; |
| 998 | struct ad7380_state *st; | 1030 | struct ad7380_state *st; |
| 999 | struct regulator *vref; | 1031 | bool external_ref_en; |
| 1000 | int ret, i; | 1032 | int ret, i; |
| 1001 | 1033 | ||
| 1002 | indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*st)); | 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 | if (!st->chip_info) | 1041 | if (!st->chip_info) |
| 1010 | return dev_err_probe(&spi->dev, -EINVAL, "missing match data\n"); | 1042 | return dev_err_probe(&spi->dev, -EINVAL, "missing match data\n"); |
| 1011 | 1043 | ||
| 1012 | vref = devm_regulator_get_optional(&spi->dev, "refio"); | 1044 | ret = devm_regulator_bulk_get_enable(&spi->dev, st->chip_info->num_supplies, |
| 1013 | if (IS_ERR(vref)) { | 1045 | st->chip_info->supplies); |
| 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 | } | ||
| 1020 | 1046 | ||
| 1021 | /* | 1047 | if (ret) |
| 1022 | * If there is no REFIO supply, then it means that we are using | 1048 | return dev_err_probe(&spi->dev, ret, |
| 1023 | * the internal 2.5V reference, otherwise REFIO is reference voltage. | 1049 | "Failed to enable power supplies\n"); |
| 1024 | */ | 1050 | fsleep(T_POWERUP_US); |
| 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; | ||
| 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 | if (ret < 0) | 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 | st->vref_mv = ret / 1000; | 1059 | st->vref_mv = ret / 1000; |
| 1060 | |||
| 1061 | /* these chips don't have a register bit for this */ | ||
| 1062 | external_ref_en = false; | ||
| 1040 | } else { | 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 | if (st->chip_info->num_vcm_supplies > ARRAY_SIZE(st->vcm_mv)) | 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 | * input pin. | 1084 | * input pin. |
| 1051 | */ | 1085 | */ |
| 1052 | for (i = 0; i < st->chip_info->num_vcm_supplies; i++) { | 1086 | for (i = 0; i < st->chip_info->num_vcm_supplies; i++) { |
| 1053 | struct regulator *vcm; | 1087 | const char *vcm = st->chip_info->vcm_supplies[i]; |
| 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]); | ||
| 1061 | 1088 | ||
| 1062 | ret = regulator_enable(vcm); | 1089 | ret = devm_regulator_get_enable_read_voltage(&spi->dev, 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); | ||
| 1072 | if (ret < 0) | 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 | st->vcm_mv[i] = ret / 1000; | 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 | if (ret) | 1155 | if (ret) |
| 1136 | return ret; | 1156 | return ret; |
| 1137 | 1157 | ||
| 1138 | ret = ad7380_init(st, vref); | 1158 | ret = ad7380_init(st, external_ref_en); |
| 1139 | if (ret) | 1159 | if (ret) |
| 1140 | return ret; | 1160 | return ret; |
| 1141 | 1161 | ||
| @@ -27,6 +27,7 @@ config AD8366 · 26 unmodified lines | |||
| 27 | config ADA4250 | 27 | config ADA4250 |
| 28 | tristate "Analog Devices ADA4250 Instrumentation Amplifier" | 28 | tristate "Analog Devices ADA4250 Instrumentation Amplifier" |
| 29 | depends on SPI | 29 | depends on SPI |
| 30 | select REGMAP_SPI | ||
| 30 | help | 31 | help |
| 31 | Say yes here to build support for Analog Devices ADA4250 | 32 | Say yes here to build support for Analog Devices ADA4250 |
| 32 | SPI Amplifier's support. The driver provides direct access via | 33 | SPI Amplifier's support. The driver provides direct access via |
| @@ -80,6 +80,8 @@ config ENS160 · 79 unmodified lines | |||
| 80 | tristate "ScioSense ENS160 sensor driver" | 80 | tristate "ScioSense ENS160 sensor driver" |
| 81 | depends on (I2C || SPI) | 81 | depends on (I2C || SPI) |
| 82 | select REGMAP | 82 | select REGMAP |
| 83 | select IIO_BUFFER | ||
| 84 | select IIO_TRIGGERED_BUFFER | ||
| 83 | select ENS160_I2C if I2C | 85 | select ENS160_I2C if I2C |
| 84 | select ENS160_SPI if SPI | 86 | select ENS160_SPI if SPI |
| 85 | help | 87 | help |
| @@ -32,7 +32,7 @@ static ssize_t _hid_sensor_set_report_latency(struct device *dev, · 31 unmodified lines | |||
| 32 | latency = integer * 1000 + fract / 1000; | 32 | latency = integer * 1000 + fract / 1000; |
| 33 | ret = hid_sensor_set_report_latency(attrb, latency); | 33 | ret = hid_sensor_set_report_latency(attrb, latency); |
| 34 | if (ret < 0) | 34 | if (ret < 0) |
| 35 | return len; | 35 | return ret; |
| 36 | 36 | ||
| 37 | attrb->latency_ms = hid_sensor_get_report_latency(attrb); | 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 | config AD3552R | 9 | config AD3552R |
| 10 | tristate "Analog Devices AD3552R DAC driver" | 10 | tristate "Analog Devices AD3552R DAC driver" |
| 11 | depends on SPI_MASTER | 11 | depends on SPI_MASTER |
| 12 | select IIO_BUFFER | ||
| 13 | select IIO_TRIGGERED_BUFFER | ||
| 12 | help | 14 | help |
| 13 | Say yes here to build support for Analog Devices AD3552R | 15 | Say yes here to build support for Analog Devices AD3552R |
| 14 | Digital to Analog Converter. | 16 | Digital to Analog Converter. |
| @@ -252,6 +254,8 @@ config AD5764 · 237 unmodified lines | |||
| 252 | config AD5766 | 254 | config AD5766 |
| 253 | tristate "Analog Devices AD5766/AD5767 DAC driver" | 255 | tristate "Analog Devices AD5766/AD5767 DAC driver" |
| 254 | depends on SPI_MASTER | 256 | depends on SPI_MASTER |
| 257 | select IIO_BUFFER | ||
| 258 | select IIO_TRIGGERED_BUFFER | ||
| 255 | help | 259 | help |
| 256 | Say yes here to build support for Analog Devices AD5766, AD5767 | 260 | Say yes here to build support for Analog Devices AD5766, AD5767 |
| 257 | Digital to Analog Converter. | 261 | Digital to Analog Converter. |
| @@ -262,6 +266,7 @@ config AD5766 · 4 unmodified lines | |||
| 262 | config AD5770R | 266 | config AD5770R |
| 263 | tristate "Analog Devices AD5770R IDAC driver" | 267 | tristate "Analog Devices AD5770R IDAC driver" |
| 264 | depends on SPI_MASTER | 268 | depends on SPI_MASTER |
| 269 | select REGMAP_SPI | ||
| 265 | help | 270 | help |
| 266 | Say yes here to build support for Analog Devices AD5770R Digital to | 271 | Say yes here to build support for Analog Devices AD5770R Digital to |
| 267 | Analog Converter. | 272 | Analog Converter. |
| @@ -353,6 +358,7 @@ config LPC18XX_DAC · 85 unmodified lines | |||
| 353 | config LTC1660 | 358 | config LTC1660 |
| 354 | tristate "Linear Technology LTC1660/LTC1665 DAC SPI driver" | 359 | tristate "Linear Technology LTC1660/LTC1665 DAC SPI driver" |
| 355 | depends on SPI | 360 | depends on SPI |
| 361 | select REGMAP_SPI | ||
| 356 | help | 362 | help |
| 357 | Say yes here to build support for Linear Technology | 363 | Say yes here to build support for Linear Technology |
| 358 | LTC1660 and LTC1665 Digital to Analog Converters. | 364 | LTC1660 and LTC1665 Digital to Analog Converters. |
| @@ -374,7 +380,7 @@ config LTC2632 · 15 unmodified lines | |||
| 374 | config LTC2664 | 380 | config LTC2664 |
| 375 | tristate "Analog Devices LTC2664 and LTC2672 DAC SPI driver" | 381 | tristate "Analog Devices LTC2664 and LTC2672 DAC SPI driver" |
| 376 | depends on SPI | 382 | depends on SPI |
| 377 | select REGMAP | 383 | select REGMAP_SPI |
| 378 | help | 384 | help |
| 379 | Say yes here to build support for Analog Devices | 385 | Say yes here to build support for Analog Devices |
| 380 | LTC2664 and LTC2672 converters (DAC). | 386 | LTC2664 and LTC2672 converters (DAC). |
| @@ -483,6 +489,7 @@ config STM32_DAC · 102 unmodified lines | |||
| 483 | 489 | ||
| 484 | config STM32_DAC_CORE | 490 | config STM32_DAC_CORE |
| 485 | tristate | 491 | tristate |
| 492 | select REGMAP_MMIO | ||
| 486 | 493 | ||
| 487 | config TI_DAC082S085 | 494 | config TI_DAC082S085 |
| 488 | tristate "Texas Instruments 8/10/12-bit 2/4-channel DAC driver" | 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 | const struct ltc2664_chip_info *chip_info = st->chip_info; | 516 | const struct ltc2664_chip_info *chip_info = st->chip_info; |
| 517 | struct device *dev = &st->spi->dev; | 517 | struct device *dev = &st->spi->dev; |
| 518 | u32 reg, tmp[2], mspan; | 518 | u32 reg, tmp[2], mspan; |
| 519 | int ret, span = 0; | 519 | int ret; |
| 520 | 520 | ||
| 521 | mspan = LTC2664_MSPAN_SOFTSPAN; | 521 | mspan = LTC2664_MSPAN_SOFTSPAN; |
| 522 | ret = device_property_read_u32(dev, "adi,manual-span-operation-config", | 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 | ret = fwnode_property_read_u32_array(child, "output-range-microvolt", | 579 | ret = fwnode_property_read_u32_array(child, "output-range-microvolt", |
| 580 | tmp, ARRAY_SIZE(tmp)); | 580 | tmp, ARRAY_SIZE(tmp)); |
| 581 | if (!ret && mspan == LTC2664_MSPAN_SOFTSPAN) { | 581 | if (!ret && mspan == LTC2664_MSPAN_SOFTSPAN) { |
| 582 | chan->span = ltc2664_set_span(st, tmp[0] / 1000, | 582 | ret = ltc2664_set_span(st, tmp[0] / 1000, tmp[1] / 1000, reg); |
| 583 | tmp[1] / 1000, reg); | 583 | if (ret < 0) |
| 584 | if (span < 0) | 584 | return dev_err_probe(dev, ret, |
| 585 | return dev_err_probe(dev, span, | ||
| 586 | "Failed to set span\n"); | 585 | "Failed to set span\n"); |
| 586 | chan->span = ret; | ||
| 587 | } | 587 | } |
| 588 | 588 | ||
| 589 | ret = fwnode_property_read_u32_array(child, "output-range-microamp", | 589 | ret = fwnode_property_read_u32_array(child, "output-range-microamp", |
| 590 | tmp, ARRAY_SIZE(tmp)); | 590 | tmp, ARRAY_SIZE(tmp)); |
| 591 | if (!ret) { | 591 | if (!ret) { |
| 592 | chan->span = ltc2664_set_span(st, 0, tmp[1] / 1000, reg); | 592 | ret = ltc2664_set_span(st, 0, tmp[1] / 1000, reg); |
| 593 | if (span < 0) | 593 | if (ret < 0) |
| 594 | return dev_err_probe(dev, span, | 594 | return dev_err_probe(dev, ret, |
| 595 | "Failed to set span\n"); | 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 | config ADF4377 | 53 | config ADF4377 |
| 54 | tristate "Analog Devices ADF4377 Microwave Wideband Synthesizer" | 54 | tristate "Analog Devices ADF4377 Microwave Wideband Synthesizer" |
| 55 | depends on SPI && COMMON_CLK | 55 | depends on SPI && COMMON_CLK |
| 56 | select REGMAP_SPI | ||
| 56 | help | 57 | help |
| 57 | Say yes here to build support for Analog Devices ADF4377 Microwave | 58 | Say yes here to build support for Analog Devices ADF4377 Microwave |
| 58 | Wideband Synthesizer. | 59 | Wideband Synthesizer. |
| @@ -91,25 +92,26 @@ config ADMV1014 · 32 unmodified lines | |||
| 91 | module will be called admv1014. | 92 | module will be called admv1014. |
| 92 | 93 | ||
| 93 | config ADMV4420 | 94 | config ADMV4420 |
| 94 | tristate "Analog Devices ADMV4420 K Band Downconverter" | 95 | tristate "Analog Devices ADMV4420 K Band Downconverter" |
| 95 | depends on SPI | 96 | depends on SPI |
| 96 | help | 97 | select REGMAP_SPI |
| 97 | Say yes here to build support for Analog Devices K Band | 98 | help |
| 98 | Downconverter with integrated Fractional-N PLL and VCO. | 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 | 102 | To compile this driver as a module, choose M here: the |
| 101 | module will be called admv4420. | 103 | module will be called admv4420. |
| 102 | 104 | ||
| 103 | config ADRF6780 | 105 | config ADRF6780 |
| 104 | tristate "Analog Devices ADRF6780 Microwave Upconverter" | 106 | tristate "Analog Devices ADRF6780 Microwave Upconverter" |
| 105 | depends on SPI | 107 | depends on SPI |
| 106 | depends on COMMON_CLK | 108 | depends on COMMON_CLK |
| 107 | help | 109 | help |
| 108 | Say yes here to build support for Analog Devices ADRF6780 | 110 | Say yes here to build support for Analog Devices ADRF6780 |
| 109 | 5.9 GHz to 23.6 GHz, Wideband, Microwave Upconverter. | 111 | 5.9 GHz to 23.6 GHz, Wideband, Microwave Upconverter. |
| 110 | 112 | ||
| 111 | To compile this driver as a module, choose M here: the | 113 | To compile this driver as a module, choose M here: the |
| 112 | module will be called adrf6780. | 114 | module will be called adrf6780. |
| 113 | 115 | ||
| 114 | endmenu | 116 | endmenu |
| 115 | endmenu | 117 | endmenu |
| @@ -2172,7 +2172,6 @@ int bmi323_core_probe(struct device *dev) · 2171 unmodified lines | |||
| 2172 | } | 2172 | } |
| 2173 | EXPORT_SYMBOL_NS_GPL(bmi323_core_probe, IIO_BMI323); | 2173 | EXPORT_SYMBOL_NS_GPL(bmi323_core_probe, IIO_BMI323); |
| 2174 | 2174 | ||
| 2175 | #if defined(CONFIG_PM) | ||
| 2176 | static int bmi323_core_runtime_suspend(struct device *dev) | 2175 | static int bmi323_core_runtime_suspend(struct device *dev) |
| 2177 | { | 2176 | { |
| 2178 | struct iio_dev *indio_dev = dev_get_drvdata(dev); | 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 | for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_ext_reg_savestate); i++) { | 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], | 2201 | ret = bmi323_read_ext_reg(data, bmi323_ext_reg_savestate[i], |
| 2203 | &savestate->reg_settings[i]); | 2202 | &savestate->ext_reg_settings[i]); |
| 2204 | if (ret) { | 2203 | if (ret) { |
| 2205 | dev_err(data->dev, | 2204 | dev_err(data->dev, |
| 2206 | "Error reading bmi323 external reg 0x%x: %d\n", | 2205 | "Error reading bmi323 external reg 0x%x: %d\n", |
| 2207 | bmi323_reg_savestate[i], ret); | 2206 | bmi323_ext_reg_savestate[i], ret); |
| 2208 | return ret; | 2207 | return ret; |
| 2209 | } | 2208 | } |
| 2210 | } | 2209 | } |
| @@ -2232,8 +2231,10 @@ static int bmi323_core_runtime_resume(struct device *dev) · 21 unmodified lines | |||
| 2232 | * after being reset in the lower power state by runtime-pm. | 2231 | * after being reset in the lower power state by runtime-pm. |
| 2233 | */ | 2232 | */ |
| 2234 | ret = bmi323_init(data); | 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 | return ret; | 2236 | return ret; |
| 2237 | } | ||
| 2237 | 2238 | ||
| 2238 | /* Register must be cleared before changing an active config */ | 2239 | /* Register must be cleared before changing an active config */ |
| 2239 | ret = regmap_write(data->regmap, BMI323_FEAT_IO0_REG, 0); | 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 | for (unsigned int i = 0; i < ARRAY_SIZE(bmi323_ext_reg_savestate); i++) { | 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 | ret = bmi323_write_ext_reg(data, bmi323_ext_reg_savestate[i], |
| 2247 | savestate->reg_settings[i]); | 2248 | savestate->ext_reg_settings[i]); |
| 2248 | if (ret) { | 2249 | if (ret) { |
| 2249 | dev_err(data->dev, | 2250 | dev_err(data->dev, |
| 2250 | "Error writing bmi323 external reg 0x%x: %d\n", | 2251 | "Error writing bmi323 external reg 0x%x: %d\n", |
| 2251 | bmi323_reg_savestate[i], ret); | 2252 | bmi323_ext_reg_savestate[i], ret); |
| 2252 | return ret; | 2253 | return ret; |
| 2253 | } | 2254 | } |
| 2254 | } | 2255 | } |
| @@ -2293,11 +2294,9 @@ static int bmi323_core_runtime_resume(struct device *dev) · 38 unmodified lines | |||
| 2293 | return iio_device_resume_triggering(indio_dev); | 2294 | return iio_device_resume_triggering(indio_dev); |
| 2294 | } | 2295 | } |
| 2295 | 2296 | ||
| 2296 | #endif | ||
| 2297 | |||
| 2298 | const struct dev_pm_ops bmi323_core_pm_ops = { | 2297 | const struct dev_pm_ops bmi323_core_pm_ops = { |
| 2299 | SET_RUNTIME_PM_OPS(bmi323_core_runtime_suspend, | 2298 | RUNTIME_PM_OPS(bmi323_core_runtime_suspend, |
| 2300 | bmi323_core_runtime_resume, NULL) | 2299 | bmi323_core_runtime_resume, NULL) |
| 2301 | }; | 2300 | }; |
| 2302 | EXPORT_SYMBOL_NS_GPL(bmi323_core_pm_ops, IIO_BMI323); | 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 | if (ret) | 307 | if (ret) |
| 308 | goto err_free_out; | 308 | goto err_free_out; |
| 309 | 309 | ||
| 310 | for (i = 0; i < gts->num_itime; i++) | ||
| 311 | kfree(per_time_gains[i]); | ||
| 310 | kfree(per_time_gains); | 312 | kfree(per_time_gains); |
| 311 | gts->per_time_avail_scale_tables = per_time_scales; | 313 | gts->per_time_avail_scale_tables = per_time_scales; |
| 312 | 314 | ||
| 313 | return 0; | 315 | return 0; |
| 314 | 316 | ||
| 315 | err_free_out: | 317 | err_free_out: |
| 316 | for (i--; i; i--) { | 318 | for (i--; i >= 0; i--) { |
| 317 | kfree(per_time_scales[i]); | 319 | kfree(per_time_scales[i]); |
| 318 | kfree(per_time_gains[i]); | 320 | kfree(per_time_gains[i]); |
| 319 | } | 321 | } |
| @@ -335,6 +335,8 @@ config ROHM_BU27008 · 334 unmodified lines | |||
| 335 | depends on I2C | 335 | depends on I2C |
| 336 | select REGMAP_I2C | 336 | select REGMAP_I2C |
| 337 | select IIO_GTS_HELPER | 337 | select IIO_GTS_HELPER |
| 338 | select IIO_BUFFER | ||
| 339 | select IIO_TRIGGERED_BUFFER | ||
| 338 | help | 340 | help |
| 339 | Enable support for the ROHM BU27008 color sensor. | 341 | Enable support for the ROHM BU27008 color sensor. |
| 340 | The ROHM BU27008 is a sensor with 5 photodiodes (red, green, | 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 | .val = 20966, | 138 | .val = 20966, |
| 139 | .val2 = 400000, | 139 | .val2 = 400000, |
| 140 | }, | 140 | }, |
| 141 | { | ||
| 142 | .val = 41932, | ||
| 143 | .val2 = 800000, | ||
| 144 | }, | ||
| 141 | { | 145 | { |
| 142 | .val = 83865, | 146 | .val = 83865, |
| 143 | .val2 = 600000, | 147 | .val2 = 600000, |
| @@ -99,9 +99,8 @@ static const char * const period_values[] = { · 98 unmodified lines | |||
| 99 | static ssize_t in_illuminance_period_available_show(struct device *dev, | 99 | static ssize_t in_illuminance_period_available_show(struct device *dev, |
| 100 | struct device_attribute *attr, char *buf) | 100 | struct device_attribute *attr, char *buf) |
| 101 | { | 101 | { |
| 102 | struct veml6030_data *data = iio_priv(dev_to_iio_dev(dev)); | ||
| 102 | int ret, reg, x; | 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 | ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, ®); | 105 | ret = regmap_read(data->regmap, VEML6030_REG_ALS_CONF, ®); |
| 107 | if (ret) { | 106 | if (ret) { |
| @@ -523,7 +522,7 @@ static int veml6030_read_raw(struct iio_dev *indio_dev, · 415 unmodified lines | |||
| 523 | } | 522 | } |
| 524 | if (mask == IIO_CHAN_INFO_PROCESSED) { | 523 | if (mask == IIO_CHAN_INFO_PROCESSED) { |
| 525 | *val = (reg * data->cur_resolution) / 10000; | 524 | *val = (reg * data->cur_resolution) / 10000; |
| 526 | *val2 = (reg * data->cur_resolution) % 10000; | 525 | *val2 = (reg * data->cur_resolution) % 10000 * 100; |
| 527 | return IIO_VAL_INT_PLUS_MICRO; | 526 | return IIO_VAL_INT_PLUS_MICRO; |
| 528 | } | 527 | } |
| 529 | *val = reg; | 528 | *val = reg; |
| @@ -780,7 +779,7 @@ static int veml6030_hw_init(struct iio_dev *indio_dev) · 250 unmodified lines | |||
| 780 | 779 | ||
| 781 | /* Cache currently active measurement parameters */ | 780 | /* Cache currently active measurement parameters */ |
| 782 | data->cur_gain = 3; | 781 | data->cur_gain = 3; |
| 783 | data->cur_resolution = 4608; | 782 | data->cur_resolution = 5376; |
| 784 | data->cur_integration_time = 3; | 783 | data->cur_integration_time = 3; |
| 785 | 784 | ||
| 786 | return ret; | 785 | return ret; |
| @@ -11,6 +11,8 @@ config AF8133J · 10 unmodified lines | |||
| 11 | depends on I2C | 11 | depends on I2C |
| 12 | depends on OF | 12 | depends on OF |
| 13 | select REGMAP_I2C | 13 | select REGMAP_I2C |
| 14 | select IIO_BUFFER | ||
| 15 | select IIO_TRIGGERED_BUFFER | ||
| 14 | help | 16 | help |
| 15 | Say yes here to build support for Voltafield AF8133J I2C-based | 17 | Say yes here to build support for Voltafield AF8133J I2C-based |
| 16 | 3-axis magnetometer chip. | 18 | 3-axis magnetometer chip. |
| @@ -19,6 +19,9 @@ config ABP060MG · 18 unmodified lines | |||
| 19 | config ROHM_BM1390 | 19 | config ROHM_BM1390 |
| 20 | tristate "ROHM BM1390GLV-Z pressure sensor driver" | 20 | tristate "ROHM BM1390GLV-Z pressure sensor driver" |
| 21 | depends on I2C | 21 | depends on I2C |
| 22 | select REGMAP_I2C | ||
| 23 | select IIO_BUFFER | ||
| 24 | select IIO_TRIGGERED_BUFFER | ||
| 22 | help | 25 | help |
| 23 | Support for the ROHM BM1390 pressure sensor. The BM1390GLV-Z | 26 | Support for the ROHM BM1390 pressure sensor. The BM1390GLV-Z |
| 24 | can measure pressures ranging from 300 hPa to 1300 hPa with | 27 | can measure pressures ranging from 300 hPa to 1300 hPa with |
| @@ -253,6 +256,7 @@ config MS5637 · 228 unmodified lines | |||
| 253 | config SDP500 | 256 | config SDP500 |
| 254 | tristate "Sensirion SDP500 differential pressure sensor I2C driver" | 257 | tristate "Sensirion SDP500 differential pressure sensor I2C driver" |
| 255 | depends on I2C | 258 | depends on I2C |
| 259 | select CRC8 | ||
| 256 | help | 260 | help |
| 257 | Say Y here to build support for Sensirion SDP500 differential pressure | 261 | Say Y here to build support for Sensirion SDP500 differential pressure |
| 258 | sensor I2C driver. | 262 | sensor I2C driver. |
| @@ -86,6 +86,8 @@ config LIDAR_LITE_V2 · 85 unmodified lines | |||
| 86 | config MB1232 | 86 | config MB1232 |
| 87 | tristate "MaxSonar I2CXL family ultrasonic sensors" | 87 | tristate "MaxSonar I2CXL family ultrasonic sensors" |
| 88 | depends on I2C | 88 | depends on I2C |
| 89 | select IIO_BUFFER | ||
| 90 | select IIO_TRIGGERED_BUFFER | ||
| 89 | help | 91 | help |
| 90 | Say Y to build a driver for the ultrasonic sensors I2CXL of | 92 | Say Y to build a driver for the ultrasonic sensors I2CXL of |
| 91 | MaxBotix which have an i2c interface. It can be used to measure | 93 | MaxBotix which have an i2c interface. It can be used to measure |
| @@ -31,6 +31,9 @@ config AD2S1210 · 30 unmodified lines | |||
| 31 | depends on SPI | 31 | depends on SPI |
| 32 | depends on COMMON_CLK | 32 | depends on COMMON_CLK |
| 33 | depends on GPIOLIB || COMPILE_TEST | 33 | depends on GPIOLIB || COMPILE_TEST |
| 34 | select REGMAP | ||
| 35 | select IIO_BUFFER | ||
| 36 | select IIO_TRIGGERED_BUFFER | ||
| 34 | help | 37 | help |
| 35 | Say yes here to build support for Analog Devices spi resolver | 38 | Say yes here to build support for Analog Devices spi resolver |
| 36 | to digital converters, ad2s1210, provides direct access via sysfs. | 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 | break; | 269 | break; |
| 270 | #endif | 270 | #endif |
| 271 | } | 271 | } |
| 272 | if (!ret && dev && is_vlan_dev(dev)) | ||
| 273 | dev = vlan_dev_real_dev(dev); | ||
| 272 | return ret ? ERR_PTR(ret) : dev; | 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 | nlh = nlmsg_put(skb, 0, 0, | 2816 | nlh = nlmsg_put(skb, 0, 0, |
| 2817 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_MONITOR), | 2817 | RDMA_NL_GET_TYPE(RDMA_NL_NLDEV, RDMA_NLDEV_CMD_MONITOR), |
| 2818 | 0, 0); | 2818 | 0, 0); |
| 2819 | if (!nlh) | ||
| 2820 | goto err_free; | ||
| 2819 | 2821 | ||
| 2820 | switch (type) { | 2822 | switch (type) { |
| 2821 | case RDMA_REGISTER_EVENT: | 2823 | case RDMA_REGISTER_EVENT: |
| @@ -366,7 +366,7 @@ int bnxt_re_ib_get_hw_stats(struct ib_device *ibdev, · 365 unmodified lines | |||
| 366 | goto done; | 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 | bnxt_re_copy_db_pacing_stats(rdev, stats); | 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 | 0 : BNXT_QPLIB_RESERVED_QP_WRS; | 1307 | 0 : BNXT_QPLIB_RESERVED_QP_WRS; |
| 1308 | entries = bnxt_re_init_depth(entries + diff + 1, uctx); | 1308 | entries = bnxt_re_init_depth(entries + diff + 1, uctx); |
| 1309 | sq->max_wqe = min_t(u32, entries, dev_attr->max_qp_wqes + diff + 1); | 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 | sq->q_full_delta = diff + 1; | 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 | bnxt_re_set_db_offset(rdev); | 189 | bnxt_re_set_db_offset(rdev); |
| 190 | rc = bnxt_qplib_map_db_bar(&rdev->qplib_res); | 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 | return rc; | 194 | return rc; |
| 195 | } | ||
| 193 | 196 | ||
| 194 | if (bnxt_qplib_determine_atomics(en_dev->pdev)) | 197 | if (bnxt_qplib_determine_atomics(en_dev->pdev)) |
| 195 | ibdev_info(&rdev->ibdev, | 198 | ibdev_info(&rdev->ibdev, |
| @@ -531,6 +534,7 @@ static bool is_dbr_fifo_full(struct bnxt_re_dev *rdev) · 335 unmodified lines | |||
| 531 | static void __wait_for_fifo_occupancy_below_th(struct bnxt_re_dev *rdev) | 534 | static void __wait_for_fifo_occupancy_below_th(struct bnxt_re_dev *rdev) |
| 532 | { | 535 | { |
| 533 | struct bnxt_qplib_db_pacing_data *pacing_data = rdev->qplib_res.pacing_data; | 536 | struct bnxt_qplib_db_pacing_data *pacing_data = rdev->qplib_res.pacing_data; |
| 537 | u32 retry_fifo_check = 1000; | ||
| 534 | u32 fifo_occup; | 538 | u32 fifo_occup; |
| 535 | 539 | ||
| 536 | /* loop shouldn't run infintely as the occupancy usually goes | 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 | if (fifo_occup < pacing_data->pacing_th) | 549 | if (fifo_occup < pacing_data->pacing_th) |
| 546 | break; | 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 | return ib_register_device(ibdev, "bnxt_re%d", &rdev->en_dev->pdev->dev); | 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 | struct bnxt_en_dev *en_dev) | 973 | struct bnxt_en_dev *en_dev) |
| 962 | { | 974 | { |
| 963 | struct bnxt_re_dev *rdev; | 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 | rdev->nb.notifier_call = NULL; | 985 | rdev->nb.notifier_call = NULL; |
| 974 | rdev->netdev = en_dev->net; | 986 | rdev->netdev = en_dev->net; |
| 975 | rdev->en_dev = en_dev; | 987 | rdev->en_dev = en_dev; |
| 988 | rdev->adev = adev; | ||
| 976 | rdev->id = rdev->en_dev->pdev->devfn; | 989 | rdev->id = rdev->en_dev->pdev->devfn; |
| 977 | INIT_LIST_HEAD(&rdev->qp_list); | 990 | INIT_LIST_HEAD(&rdev->qp_list); |
| 978 | mutex_init(&rdev->qp_lock); | 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 | static int bnxt_re_handle_qp_async_event(struct creq_qp_event *qp_event, | 1038 | static int bnxt_re_handle_qp_async_event(struct creq_qp_event *qp_event, |
| 1026 | struct bnxt_re_qp *qp) | 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 | struct creq_qp_error_notification *err_event; | 1041 | struct creq_qp_error_notification *err_event; |
| 1042 | struct bnxt_re_srq *srq = NULL; | ||
| 1031 | struct ib_event event = {}; | 1043 | struct ib_event event = {}; |
| 1032 | unsigned int flags; | 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 | if (qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR && | 1050 | if (qp->qplib_qp.state == CMDQ_MODIFY_QP_NEW_STATE_ERR && |
| 1035 | rdma_is_kernel_res(&qp->ib_qp.res)) { | 1051 | rdma_is_kernel_res(&qp->ib_qp.res)) { |
| 1036 | flags = bnxt_re_lock_cqs(qp); | 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 | struct bnxt_re_cq *cq = container_of(handle, struct bnxt_re_cq, | 1275 | struct bnxt_re_cq *cq = container_of(handle, struct bnxt_re_cq, |
| 1260 | qplib_cq); | 1276 | qplib_cq); |
| 1261 | u32 *cq_ptr; | ||
| 1262 | 1277 | ||
| 1263 | if (cq->ib_cq.comp_handler) { | 1278 | 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 | } | ||
| 1268 | (*cq->ib_cq.comp_handler)(&cq->ib_cq, cq->ib_cq.cq_context); | 1279 | (*cq->ib_cq.comp_handler)(&cq->ib_cq, cq->ib_cq.cq_context); |
| 1269 | } | ||
| 1270 | 1280 | ||
| 1271 | return 0; | 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 | rtnl_lock(); | 1834 | rtnl_lock(); |
| 1825 | en_info->rdev = rdev; | 1835 | en_info->rdev = rdev; |
| 1826 | rdev->adev = adev; | ||
| 1827 | rtnl_unlock(); | 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 | en_dev = en_info->en_dev; | 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 | if (!rdev || !rdev_to_dev(rdev)) { | 1853 | if (!rdev || !rdev_to_dev(rdev)) { |
| 1845 | rc = -ENOMEM; | 1854 | rc = -ENOMEM; |
| 1846 | goto exit; | 1855 | goto exit; |
| @@ -1865,12 +1874,14 @@ static int bnxt_re_add_device(struct auxiliary_device *adev, u8 op_type) · 18 unmodified lines | |||
| 1865 | rdev->nb.notifier_call = NULL; | 1874 | rdev->nb.notifier_call = NULL; |
| 1866 | pr_err("%s: Cannot register to netdevice_notifier", | 1875 | pr_err("%s: Cannot register to netdevice_notifier", |
| 1867 | ROCE_DRV_MODULE_NAME); | 1876 | ROCE_DRV_MODULE_NAME); |
| 1868 | return rc; | 1877 | goto re_dev_unreg; |
| 1869 | } | 1878 | } |
| 1870 | bnxt_re_setup_cc(rdev, true); | 1879 | bnxt_re_setup_cc(rdev, true); |
| 1871 | 1880 | ||
| 1872 | return 0; | 1881 | return 0; |
| 1873 | 1882 | ||
| 1883 | re_dev_unreg: | ||
| 1884 | ib_unregister_device(&rdev->ibdev); | ||
| 1874 | re_dev_uninit: | 1885 | re_dev_uninit: |
| 1875 | bnxt_re_update_en_info_rdev(NULL, en_info, adev); | 1886 | bnxt_re_update_en_info_rdev(NULL, en_info, adev); |
| 1876 | bnxt_re_dev_uninit(rdev, BNXT_RE_COMPLETE_REMOVE); | 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 | auxiliary_set_drvdata(adev, en_info); | 2025 | auxiliary_set_drvdata(adev, en_info); |
| 2015 | 2026 | ||
| 2016 | rc = bnxt_re_add_device(adev, BNXT_RE_COMPLETE_INIT); | 2027 | rc = bnxt_re_add_device(adev, BNXT_RE_COMPLETE_INIT); |
| 2017 | if (rc) | ||
| 2018 | goto err; | ||
| 2019 | mutex_unlock(&bnxt_re_mutex); | 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 | return rc; | 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 | case NQ_BASE_TYPE_CQ_NOTIFICATION: | 327 | case NQ_BASE_TYPE_CQ_NOTIFICATION: |
| 328 | { | 328 | { |
| 329 | struct nq_cn *nqcne = (struct nq_cn *)nqe; | 329 | struct nq_cn *nqcne = (struct nq_cn *)nqe; |
| 330 | struct bnxt_re_cq *cq_p; | ||
| 330 | 331 | ||
| 331 | q_handle = le32_to_cpu(nqcne->cq_handle_low); | 332 | q_handle = le32_to_cpu(nqcne->cq_handle_low); |
| 332 | q_handle |= (u64)le32_to_cpu(nqcne->cq_handle_high) | 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 | cq->toggle = (le16_to_cpu(nqe->info10_type) & | 338 | cq->toggle = (le16_to_cpu(nqe->info10_type) & |
| 338 | NQ_CN_TOGGLE_MASK) >> NQ_CN_TOGGLE_SFT; | 339 | NQ_CN_TOGGLE_MASK) >> NQ_CN_TOGGLE_SFT; |
| 339 | cq->dbinfo.toggle = cq->toggle; | 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 | bnxt_qplib_armen_db(&cq->dbinfo, | 345 | bnxt_qplib_armen_db(&cq->dbinfo, |
| 341 | DBC_DBC_TYPE_CQ_ARMENA); | 346 | DBC_DBC_TYPE_CQ_ARMENA); |
| 342 | spin_lock_bh(&cq->compl_lock); | 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 | u32 tbl_indx; | 1532 | u32 tbl_indx; |
| 1528 | int rc; | 1533 | int rc; |
| 1529 | 1534 | ||
| 1535 | spin_lock_bh(&rcfw->tbl_lock); | ||
| 1530 | tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw); | 1536 | tbl_indx = map_qp_id_to_tbl_indx(qp->id, rcfw); |
| 1531 | rcfw->qp_tbl[tbl_indx].qp_id = BNXT_QPLIB_QP_ID_INVALID; | 1537 | rcfw->qp_tbl[tbl_indx].qp_id = BNXT_QPLIB_QP_ID_INVALID; |
| 1532 | rcfw->qp_tbl[tbl_indx].qp_handle = NULL; | 1538 | rcfw->qp_tbl[tbl_indx].qp_handle = NULL; |
| 1539 | spin_unlock_bh(&rcfw->tbl_lock); | ||
| 1533 | 1540 | ||
| 1534 | bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req, | 1541 | bnxt_qplib_rcfw_cmd_prep((struct cmdq_base *)&req, |
| 1535 | CMDQ_BASE_OPCODE_DESTROY_QP, | 1542 | CMDQ_BASE_OPCODE_DESTROY_QP, |
| @@ -1540,8 +1547,10 @@ int bnxt_qplib_destroy_qp(struct bnxt_qplib_res *res, · 4 unmodified lines | |||
| 1540 | sizeof(resp), 0); | 1547 | sizeof(resp), 0); |
| 1541 | rc = bnxt_qplib_rcfw_send_message(rcfw, &msg); | 1548 | rc = bnxt_qplib_rcfw_send_message(rcfw, &msg); |
| 1542 | if (rc) { | 1549 | if (rc) { |
| 1550 | spin_lock_bh(&rcfw->tbl_lock); | ||
| 1543 | rcfw->qp_tbl[tbl_indx].qp_id = qp->id; | 1551 | rcfw->qp_tbl[tbl_indx].qp_id = qp->id; |
| 1544 | rcfw->qp_tbl[tbl_indx].qp_handle = qp; | 1552 | rcfw->qp_tbl[tbl_indx].qp_handle = qp; |
| 1553 | spin_unlock_bh(&rcfw->tbl_lock); | ||
| 1545 | return rc; | 1554 | return rc; |
| 1546 | } | 1555 | } |
| 1547 | 1556 | ||
| @@ -170,7 +170,7 @@ struct bnxt_qplib_swqe { · 169 unmodified lines | |||
| 170 | }; | 170 | }; |
| 171 | u32 q_key; | 171 | u32 q_key; |
| 172 | u32 dst_qp; | 172 | u32 dst_qp; |
| 173 | u16 avid; | 173 | u32 avid; |
| 174 | } send; | 174 | } send; |
| 175 | 175 | ||
| 176 | /* Send Raw Ethernet and QP1 */ | 176 | /* Send Raw Ethernet and QP1 */ |
| @@ -290,7 +290,6 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, · 289 unmodified lines | |||
| 290 | struct bnxt_qplib_hwq *hwq; | 290 | struct bnxt_qplib_hwq *hwq; |
| 291 | u32 sw_prod, cmdq_prod; | 291 | u32 sw_prod, cmdq_prod; |
| 292 | struct pci_dev *pdev; | 292 | struct pci_dev *pdev; |
| 293 | unsigned long flags; | ||
| 294 | u16 cookie; | 293 | u16 cookie; |
| 295 | u8 *preq; | 294 | u8 *preq; |
| 296 | 295 | ||
| @@ -301,7 +300,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, · 4 unmodified lines | |||
| 301 | /* Cmdq are in 16-byte units, each request can consume 1 or more | 300 | /* Cmdq are in 16-byte units, each request can consume 1 or more |
| 302 | * cmdqe | 301 | * cmdqe |
| 303 | */ | 302 | */ |
| 304 | spin_lock_irqsave(&hwq->lock, flags); | 303 | spin_lock_bh(&hwq->lock); |
| 305 | required_slots = bnxt_qplib_get_cmd_slots(msg->req); | 304 | required_slots = bnxt_qplib_get_cmd_slots(msg->req); |
| 306 | free_slots = HWQ_FREE_SLOTS(hwq); | 305 | free_slots = HWQ_FREE_SLOTS(hwq); |
| 307 | cookie = cmdq->seq_num & RCFW_MAX_COOKIE_VALUE; | 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 | dev_info_ratelimited(&pdev->dev, | 310 | dev_info_ratelimited(&pdev->dev, |
| 312 | "CMDQ is full req/free %d/%d!", | 311 | "CMDQ is full req/free %d/%d!", |
| 313 | required_slots, free_slots); | 312 | required_slots, free_slots); |
| 314 | spin_unlock_irqrestore(&hwq->lock, flags); | 313 | spin_unlock_bh(&hwq->lock); |
| 315 | return -EAGAIN; | 314 | return -EAGAIN; |
| 316 | } | 315 | } |
| 317 | if (msg->block) | 316 | if (msg->block) |
| @@ -367,7 +366,7 @@ static int __send_message(struct bnxt_qplib_rcfw *rcfw, · 49 unmodified lines | |||
| 367 | wmb(); | 366 | wmb(); |
| 368 | writel(cmdq_prod, cmdq->cmdq_mbox.prod); | 367 | writel(cmdq_prod, cmdq->cmdq_mbox.prod); |
| 369 | writel(RCFW_CMDQ_TRIG_VAL, cmdq->cmdq_mbox.db); | 368 | writel(RCFW_CMDQ_TRIG_VAL, cmdq->cmdq_mbox.db); |
| 370 | spin_unlock_irqrestore(&hwq->lock, flags); | 369 | spin_unlock_bh(&hwq->lock); |
| 371 | /* Return the CREQ response pointer */ | 370 | /* Return the CREQ response pointer */ |
| 372 | return 0; | 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 | struct creq_qp_event *evnt = (struct creq_qp_event *)msg->resp; | 486 | struct creq_qp_event *evnt = (struct creq_qp_event *)msg->resp; |
| 488 | struct bnxt_qplib_crsqe *crsqe; | 487 | struct bnxt_qplib_crsqe *crsqe; |
| 489 | unsigned long flags; | ||
| 490 | u16 cookie; | 488 | u16 cookie; |
| 491 | int rc; | 489 | int rc; |
| 492 | u8 opcode; | 490 | u8 opcode; |
| @@ -512,12 +510,12 @@ static int __bnxt_qplib_rcfw_send_message(struct bnxt_qplib_rcfw *rcfw, · 19 unmodified lines | |||
| 512 | rc = __poll_for_resp(rcfw, cookie); | 510 | rc = __poll_for_resp(rcfw, cookie); |
| 513 | 511 | ||
| 514 | if (rc) { | 512 | if (rc) { |
| 515 | spin_lock_irqsave(&rcfw->cmdq.hwq.lock, flags); | 513 | spin_lock_bh(&rcfw->cmdq.hwq.lock); |
| 516 | crsqe = &rcfw->crsqe_tbl[cookie]; | 514 | crsqe = &rcfw->crsqe_tbl[cookie]; |
| 517 | crsqe->is_waiter_alive = false; | 515 | crsqe->is_waiter_alive = false; |
| 518 | if (rc == -ENODEV) | 516 | if (rc == -ENODEV) |
| 519 | set_bit(FIRMWARE_STALL_DETECTED, &rcfw->cmdq.flags); | 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 | return -ETIMEDOUT; | 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 | /* failed with status */ | 523 | /* failed with status */ |
| 526 | dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x status %#x\n", | 524 | dev_err(&rcfw->pdev->dev, "cmdq[%#x]=%#x status %#x\n", |
| 527 | cookie, opcode, evnt->status); | 525 | cookie, opcode, evnt->status); |
| 528 | rc = -EFAULT; | 526 | rc = -EIO; |
| 529 | } | 527 | } |
| 530 | 528 | ||
| 531 | return rc; | 529 | return rc; |
| @@ -628,7 +626,6 @@ static int bnxt_qplib_process_qp_event(struct bnxt_qplib_rcfw *rcfw, · 96 unmodified lines | |||
| 628 | u16 cookie, blocked = 0; | 626 | u16 cookie, blocked = 0; |
| 629 | bool is_waiter_alive; | 627 | bool is_waiter_alive; |
| 630 | struct pci_dev *pdev; | 628 | struct pci_dev *pdev; |
| 631 | unsigned long flags; | ||
| 632 | u32 wait_cmds = 0; | 629 | u32 wait_cmds = 0; |
| 633 | int rc = 0; | 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 | case CREQ_QP_EVENT_EVENT_QP_ERROR_NOTIFICATION: | 634 | case CREQ_QP_EVENT_EVENT_QP_ERROR_NOTIFICATION: |
| 638 | err_event = (struct creq_qp_error_notification *)qp_event; | 635 | err_event = (struct creq_qp_error_notification *)qp_event; |
| 639 | qp_id = le32_to_cpu(err_event->xid); | 636 | qp_id = le32_to_cpu(err_event->xid); |
| 637 | spin_lock(&rcfw->tbl_lock); | ||
| 640 | tbl_indx = map_qp_id_to_tbl_indx(qp_id, rcfw); | 638 | tbl_indx = map_qp_id_to_tbl_indx(qp_id, rcfw); |
| 641 | qp = rcfw->qp_tbl[tbl_indx].qp_handle; | 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 | dev_dbg(&pdev->dev, "Received QP error notification\n"); | 647 | dev_dbg(&pdev->dev, "Received QP error notification\n"); |
| 643 | dev_dbg(&pdev->dev, | 648 | dev_dbg(&pdev->dev, |
| 644 | "qpid 0x%x, req_err=0x%x, resp_err=0x%x\n", | 649 | "qpid 0x%x, req_err=0x%x, resp_err=0x%x\n", |
| 645 | qp_id, err_event->req_err_state_reason, | 650 | qp_id, err_event->req_err_state_reason, |
| 646 | err_event->res_err_state_reason); | 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 | break; | 652 | break; |
| 652 | default: | 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 | spin_lock_nested(&hwq->lock, SINGLE_DEPTH_NESTING); |
| 663 | SINGLE_DEPTH_NESTING); | ||
| 664 | cookie = le16_to_cpu(qp_event->cookie); | 664 | cookie = le16_to_cpu(qp_event->cookie); |
| 665 | blocked = cookie & RCFW_CMD_IS_BLOCKING; | 665 | blocked = cookie & RCFW_CMD_IS_BLOCKING; |
| 666 | cookie &= RCFW_MAX_COOKIE_VALUE; | 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 | dev_info(&pdev->dev, | 672 | dev_info(&pdev->dev, |
| 673 | "rcfw timedout: cookie = %#x, free_slots = %d", | 673 | "rcfw timedout: cookie = %#x, free_slots = %d", |
| 674 | cookie, crsqe->free_slots); | 674 | cookie, crsqe->free_slots); |
| 675 | spin_unlock_irqrestore(&hwq->lock, flags); | 675 | spin_unlock(&hwq->lock); |
| 676 | return rc; | 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 | __destroy_timedout_ah(rcfw, | 720 | __destroy_timedout_ah(rcfw, |
| 721 | (struct creq_create_ah_resp *) | 721 | (struct creq_create_ah_resp *) |
| 722 | qp_event); | 722 | qp_event); |
| 723 | spin_unlock_irqrestore(&hwq->lock, flags); | 723 | spin_unlock(&hwq->lock); |
| 724 | } | 724 | } |
| 725 | *num_wait += wait_cmds; | 725 | *num_wait += wait_cmds; |
| 726 | return rc; | 726 | return rc; |
| @@ -734,12 +734,11 @@ static void bnxt_qplib_service_creq(struct tasklet_struct *t) · 7 unmodified lines | |||
| 734 | u32 type, budget = CREQ_ENTRY_POLL_BUDGET; | 734 | u32 type, budget = CREQ_ENTRY_POLL_BUDGET; |
| 735 | struct bnxt_qplib_hwq *hwq = &creq->hwq; | 735 | struct bnxt_qplib_hwq *hwq = &creq->hwq; |
| 736 | struct creq_base *creqe; | 736 | struct creq_base *creqe; |
| 737 | unsigned long flags; | ||
| 738 | u32 num_wakeup = 0; | 737 | u32 num_wakeup = 0; |
| 739 | u32 hw_polled = 0; | 738 | u32 hw_polled = 0; |
| 740 | 739 | ||
| 741 | /* Service the CREQ until budget is over */ | 740 | /* Service the CREQ until budget is over */ |
| 742 | spin_lock_irqsave(&hwq->lock, flags); | 741 | spin_lock_bh(&hwq->lock); |
| 743 | while (budget > 0) { | 742 | while (budget > 0) { |
| 744 | creqe = bnxt_qplib_get_qe(hwq, hwq->cons, NULL); | 743 | creqe = bnxt_qplib_get_qe(hwq, hwq->cons, NULL); |
| 745 | if (!CREQ_CMP_VALID(creqe, creq->creq_db.dbinfo.flags)) | 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 | if (hw_polled) | 781 | if (hw_polled) |
| 783 | bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, | 782 | bnxt_qplib_ring_nq_db(&creq->creq_db.dbinfo, |
| 784 | rcfw->res->cctx, true); | 783 | rcfw->res->cctx, true); |
| 785 | spin_unlock_irqrestore(&hwq->lock, flags); | 784 | spin_unlock_bh(&hwq->lock); |
| 786 | if (num_wakeup) | 785 | if (num_wakeup) |
| 787 | wake_up_nr(&rcfw->cmdq.waitq, num_wakeup); | 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 | GFP_KERNEL); | 977 | GFP_KERNEL); |
| 979 | if (!rcfw->qp_tbl) | 978 | if (!rcfw->qp_tbl) |
| 980 | goto fail; | 979 | goto fail; |
| 980 | spin_lock_init(&rcfw->tbl_lock); | ||
| 981 | 981 | ||
| 982 | rcfw->max_timeout = res->cctx->hwrm_cmd_max_timeout; | 982 | rcfw->max_timeout = res->cctx->hwrm_cmd_max_timeout; |
| 983 | 983 | ||
| @@ -224,6 +224,8 @@ struct bnxt_qplib_rcfw { · 223 unmodified lines | |||
| 224 | struct bnxt_qplib_crsqe *crsqe_tbl; | 224 | struct bnxt_qplib_crsqe *crsqe_tbl; |
| 225 | int qp_tbl_size; | 225 | int qp_tbl_size; |
| 226 | struct bnxt_qplib_qp_node *qp_tbl; | 226 | struct bnxt_qplib_qp_node *qp_tbl; |
| 227 | /* To synchronize the qp-handle hash table */ | ||
| 228 | spinlock_t tbl_lock; | ||
| 227 | u64 oos_prev; | 229 | u64 oos_prev; |
| 228 | u32 init_oos_stats; | 230 | u32 init_oos_stats; |
| 229 | u32 cmdq_depth; | 231 | u32 cmdq_depth; |
| @@ -244,6 +244,8 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq, · 243 unmodified lines | |||
| 244 | sginfo.pgsize = npde * pg_size; | 244 | sginfo.pgsize = npde * pg_size; |
| 245 | sginfo.npages = 1; | 245 | sginfo.npages = 1; |
| 246 | rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], &sginfo); | 246 | rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_0], &sginfo); |
| 247 | if (rc) | ||
| 248 | goto fail; | ||
| 247 | 249 | ||
| 248 | /* Alloc PBL pages */ | 250 | /* Alloc PBL pages */ |
| 249 | sginfo.npages = npbl; | 251 | sginfo.npages = npbl; |
| @@ -255,22 +257,9 @@ int bnxt_qplib_alloc_init_hwq(struct bnxt_qplib_hwq *hwq, · 5 unmodified lines | |||
| 255 | dst_virt_ptr = | 257 | dst_virt_ptr = |
| 256 | (dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr; | 258 | (dma_addr_t **)hwq->pbl[PBL_LVL_0].pg_arr; |
| 257 | src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr; | 259 | src_phys_ptr = hwq->pbl[PBL_LVL_1].pg_map_arr; |
| 258 | if (hwq_attr->type == HWQ_TYPE_MR) { | 260 | for (i = 0; i < hwq->pbl[PBL_LVL_1].pg_count; i++) |
| 259 | /* For MR it is expected that we supply only 1 contigous | 261 | dst_virt_ptr[0][i] = src_phys_ptr[i] | flag; |
| 260 | * page i.e only 1 entry in the PDL that will contain | 262 | |
| 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 | } | ||
| 274 | /* Alloc or init PTEs */ | 263 | /* Alloc or init PTEs */ |
| 275 | rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_2], | 264 | rc = __alloc_pbl(res, &hwq->pbl[PBL_LVL_2], |
| 276 | hwq_attr->sginfo); | 265 | hwq_attr->sginfo); |
| @@ -140,6 +140,8 @@ int bnxt_qplib_get_dev_attr(struct bnxt_qplib_rcfw *rcfw, · 139 unmodified lines | |||
| 140 | min_t(u32, sb->max_sge_var_wqe, BNXT_VAR_MAX_SGE) : 6; | 140 | min_t(u32, sb->max_sge_var_wqe, BNXT_VAR_MAX_SGE) : 6; |
| 141 | attr->max_cq = le32_to_cpu(sb->max_cq); | 141 | attr->max_cq = le32_to_cpu(sb->max_cq); |
| 142 | attr->max_cq_wqes = le32_to_cpu(sb->max_cqe); | 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 | attr->max_cq_sges = attr->max_qp_sges; | 145 | attr->max_cq_sges = attr->max_qp_sges; |
| 144 | attr->max_mr = le32_to_cpu(sb->max_mr); | 146 | attr->max_mr = le32_to_cpu(sb->max_mr); |
| 145 | attr->max_mw = le32_to_cpu(sb->max_mw); | 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 | if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx)) | 159 | if (!bnxt_qplib_is_chip_gen_p7(rcfw->res->cctx)) |
| 158 | attr->l2_db_size = (sb->l2_db_space_size + 1) * | 160 | attr->l2_db_size = (sb->l2_db_space_size + 1) * |
| 159 | (0x01 << RCFW_DBR_BASE_PAGE_SHIFT); | 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 | attr->dev_cap_flags = le16_to_cpu(sb->dev_cap_flags); | 170 | attr->dev_cap_flags = le16_to_cpu(sb->dev_cap_flags); |
| 162 | attr->dev_cap_flags2 = le16_to_cpu(sb->dev_cap_ext_flags_2); | 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 | u32 max_qp_wqes; | 56 | u32 max_qp_wqes; |
| 57 | u32 max_qp_sges; | 57 | u32 max_qp_sges; |
| 58 | u32 max_cq; | 58 | u32 max_cq; |
| 59 | #define BNXT_QPLIB_MAX_CQ_WQES 0xfffff | ||
| 59 | u32 max_cq_wqes; | 60 | u32 max_cq_wqes; |
| 60 | u32 max_cq_sges; | 61 | u32 max_cq_sges; |
| 61 | u32 max_mr; | 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 | err = -ENOMEM; | 2086 | err = -ENOMEM; |
| 2087 | if (n->dev->flags & IFF_LOOPBACK) { | 2087 | if (n->dev->flags & IFF_LOOPBACK) { |
| 2088 | if (iptype == 4) | 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 | else if (IS_ENABLED(CONFIG_IPV6)) | 2090 | else if (IS_ENABLED(CONFIG_IPV6)) |
| 2091 | for_each_netdev(&init_net, pdev) { | 2091 | for_each_netdev(&init_net, pdev) { |
| 2092 | if (ipv6_chk_addr(&init_net, | 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 | err = -ENODEV; | 2101 | err = -ENODEV; |
| 2102 | goto out; | 2102 | goto out; |
| 2103 | } | 2103 | } |
| 2104 | if (is_vlan_dev(pdev)) | ||
| 2105 | pdev = vlan_dev_real_dev(pdev); | ||
| 2104 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, | 2106 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, |
| 2105 | n, pdev, rt_tos2priority(tos)); | 2107 | n, pdev, rt_tos2priority(tos)); |
| 2106 | if (!ep->l2t) { | 2108 | if (!ep->l2t) |
| 2107 | dev_put(pdev); | ||
| 2108 | goto out; | 2109 | goto out; |
| 2109 | } | ||
| 2110 | ep->mtu = pdev->mtu; | 2110 | ep->mtu = pdev->mtu; |
| 2111 | ep->tx_chan = cxgb4_port_chan(pdev); | 2111 | ep->tx_chan = cxgb4_port_chan(pdev); |
| 2112 | ep->smac_idx = ((struct port_info *)netdev_priv(pdev))->smt_idx; | 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 | ep->rss_qid = cdev->rdev.lldi.rxq_ids[ | 2119 | ep->rss_qid = cdev->rdev.lldi.rxq_ids[ |
| 2120 | cxgb4_port_idx(pdev) * step]; | 2120 | cxgb4_port_idx(pdev) * step]; |
| 2121 | set_tcp_window(ep, (struct port_info *)netdev_priv(pdev)); | 2121 | set_tcp_window(ep, (struct port_info *)netdev_priv(pdev)); |
| 2122 | dev_put(pdev); | ||
| 2123 | } else { | 2122 | } else { |
| 2124 | pdev = get_real_dev(n->dev); | 2123 | pdev = get_real_dev(n->dev); |
| 2125 | ep->l2t = cxgb4_l2t_get(cdev->rdev.lldi.l2t, | 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 | .fill_res_cq_entry = c4iw_fill_res_cq_entry, | 473 | .fill_res_cq_entry = c4iw_fill_res_cq_entry, |
| 474 | .fill_res_cm_id_entry = c4iw_fill_res_cm_id_entry, | 474 | .fill_res_cm_id_entry = c4iw_fill_res_cm_id_entry, |
| 475 | .fill_res_mr_entry = c4iw_fill_res_mr_entry, | 475 | .fill_res_mr_entry = c4iw_fill_res_mr_entry, |
| 476 | .fill_res_qp_entry = c4iw_fill_res_qp_entry, | ||
| 476 | .get_dev_fw_str = get_dev_fw_str, | 477 | .get_dev_fw_str = get_dev_fw_str, |
| 477 | .get_dma_mr = c4iw_get_dma_mr, | 478 | .get_dma_mr = c4iw_get_dma_mr, |
| 478 | .get_hw_stats = c4iw_get_mib, | 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 | * irdma_accept - registered call for connection to be accepted | 3632 | * irdma_accept - registered call for connection to be accepted |
| 3633 | * @cm_id: cm information for passive connection | 3633 | * @cm_id: cm information for passive connection |
| 3634 | * @conn_param: accpet parameters | 3634 | * @conn_param: accept parameters |
| 3635 | */ | 3635 | */ |
| 3636 | int irdma_accept(struct iw_cm_id *cm_id, struct iw_cm_conn_param *conn_param) | 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 | MLX5_SET(qpc, qpc, retry_count, attr->retry_cnt); | 4268 | MLX5_SET(qpc, qpc, retry_count, attr->retry_cnt); |
| 4269 | 4269 | ||
| 4270 | if (attr_mask & IB_QP_MAX_QP_RD_ATOMIC && attr->max_rd_atomic) | 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 | if (attr_mask & IB_QP_SQ_PSN) | 4273 | if (attr_mask & IB_QP_SQ_PSN) |
| 4274 | MLX5_SET(qpc, qpc, next_send_psn, attr->sq_psn); | 4274 | MLX5_SET(qpc, qpc, next_send_psn, attr->sq_psn); |
| 4275 | 4275 | ||
| 4276 | if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC && attr->max_dest_rd_atomic) | 4276 | if (attr_mask & IB_QP_MAX_DEST_RD_ATOMIC && attr->max_dest_rd_atomic) |
| 4277 | MLX5_SET(qpc, qpc, log_rra_max, | 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 | if (attr_mask & (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC)) { | 4280 | if (attr_mask & (IB_QP_ACCESS_FLAGS | IB_QP_MAX_DEST_RD_ATOMIC)) { |
| 4281 | err = set_qpc_atomic_flags(qp, attr, attr_mask, qpc); | 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 | msg.msg_flags &= ~MSG_MORE; | 331 | msg.msg_flags &= ~MSG_MORE; |
| 332 | 332 | ||
| 333 | tcp_rate_check_app_limited(sk); | 333 | tcp_rate_check_app_limited(sk); |
| 334 | if (!sendpage_ok(page[i])) | ||
| 335 | msg.msg_flags &= ~MSG_SPLICE_PAGES; | ||
| 334 | bvec_set_page(&bvec, page[i], bytes, offset); | 336 | bvec_set_page(&bvec, page[i], bytes, offset); |
| 335 | iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size); | 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 | static u64 srpt_service_guid; | 68 | static u64 srpt_service_guid; |
| 69 | static DEFINE_SPINLOCK(srpt_dev_lock); /* Protects srpt_dev_list. */ | 69 | static DEFINE_SPINLOCK(srpt_dev_lock); /* Protects srpt_dev_list. */ |
| 70 | static LIST_HEAD(srpt_dev_list); /* List of srpt_device structures. */ | 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 | static unsigned srp_max_req_size = DEFAULT_MAX_REQ_SIZE; | 74 | static unsigned srp_max_req_size = DEFAULT_MAX_REQ_SIZE; |
| 73 | module_param(srp_max_req_size, int, 0444); | 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 | static void srpt_send_done(struct ib_cq *cq, struct ib_wc *wc); | 107 | static void srpt_send_done(struct ib_cq *cq, struct ib_wc *wc); |
| 106 | static void srpt_process_wait_list(struct srpt_rdma_ch *ch); | 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 | * The only allowed channel state changes are those that change the channel | 168 | * The only allowed channel state changes are those that change the channel |
| 110 | * state into a state with a higher numerical value. Hence the new > prev test. | 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 | ch->sport->sdev, ch->rq_size, | 2178 | ch->sport->sdev, ch->rq_size, |
| 2120 | ch->rsp_buf_cache, DMA_TO_DEVICE); | 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 | srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_recv_ring, | 2183 | srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_recv_ring, |
| 2125 | sdev, ch->rq_size, | 2184 | sdev, ch->rq_size, |
| 2126 | ch->req_buf_cache, DMA_FROM_DEVICE); | 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 | kref_put(&ch->kref, srpt_free_ch); | 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 | INIT_LIST_HEAD(&ch->cmd_wait_list); | 2304 | INIT_LIST_HEAD(&ch->cmd_wait_list); |
| 2246 | ch->max_rsp_size = ch->sport->port_attrib.srp_max_rsp_size; | 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, | 2307 | ch->rsp_buf_cache = srpt_cache_get(ch->max_rsp_size); |
| 2249 | 512, 0, NULL); | ||
| 2250 | if (!ch->rsp_buf_cache) | 2308 | if (!ch->rsp_buf_cache) |
| 2251 | goto free_ch; | 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 | alignment_offset = round_up(imm_data_offset, 512) - | 2338 | alignment_offset = round_up(imm_data_offset, 512) - |
| 2281 | imm_data_offset; | 2339 | imm_data_offset; |
| 2282 | req_sz = alignment_offset + imm_data_offset + srp_max_req_size; | 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, | 2341 | ch->req_buf_cache = srpt_cache_get(req_sz); |
| 2284 | 512, 0, NULL); | ||
| 2285 | if (!ch->req_buf_cache) | 2342 | if (!ch->req_buf_cache) |
| 2286 | goto free_rsp_ring; | 2343 | goto free_rsp_ring; |
| 2287 | 2344 | ||
| @@ -2478,7 +2535,7 @@ free_recv_ring: · 190 unmodified lines | |||
| 2478 | ch->req_buf_cache, DMA_FROM_DEVICE); | 2535 | ch->req_buf_cache, DMA_FROM_DEVICE); |
| 2479 | 2536 | ||
| 2480 | free_recv_cache: | 2537 | free_recv_cache: |
| 2481 | kmem_cache_destroy(ch->req_buf_cache); | 2538 | srpt_cache_put(ch->req_buf_cache); |
| 2482 | 2539 | ||
| 2483 | free_rsp_ring: | 2540 | free_rsp_ring: |
| 2484 | srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring, | 2541 | srpt_free_ioctx_ring((struct srpt_ioctx **)ch->ioctx_ring, |
| @@ -2486,7 +2543,7 @@ free_rsp_ring: · 1 unmodified line | |||
| 2486 | ch->rsp_buf_cache, DMA_TO_DEVICE); | 2543 | ch->rsp_buf_cache, DMA_TO_DEVICE); |
| 2487 | 2544 | ||
| 2488 | free_rsp_cache: | 2545 | free_rsp_cache: |
| 2489 | kmem_cache_destroy(ch->rsp_buf_cache); | 2546 | srpt_cache_put(ch->rsp_buf_cache); |
| 2490 | 2547 | ||
| 2491 | free_ch: | 2548 | free_ch: |
| 2492 | if (rdma_cm_id) | 2549 | if (rdma_cm_id) |
| @@ -3055,7 +3112,7 @@ static void srpt_free_srq(struct srpt_device *sdev) · 562 unmodified lines | |||
| 3055 | srpt_free_ioctx_ring((struct srpt_ioctx **)sdev->ioctx_ring, sdev, | 3112 | srpt_free_ioctx_ring((struct srpt_ioctx **)sdev->ioctx_ring, sdev, |
| 3056 | sdev->srq_size, sdev->req_buf_cache, | 3113 | sdev->srq_size, sdev->req_buf_cache, |
| 3057 | DMA_FROM_DEVICE); | 3114 | DMA_FROM_DEVICE); |
| 3058 | kmem_cache_destroy(sdev->req_buf_cache); | 3115 | srpt_cache_put(sdev->req_buf_cache); |
| 3059 | sdev->srq = NULL; | 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 | pr_debug("create SRQ #wr= %d max_allow=%d dev= %s\n", sdev->srq_size, | 3139 | pr_debug("create SRQ #wr= %d max_allow=%d dev= %s\n", sdev->srq_size, |
| 3083 | sdev->device->attrs.max_srq_wr, dev_name(&device->dev)); | 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", | 3142 | sdev->req_buf_cache = srpt_cache_get(srp_max_req_size); |
| 3086 | srp_max_req_size, 0, 0, NULL); | ||
| 3087 | if (!sdev->req_buf_cache) | 3143 | if (!sdev->req_buf_cache) |
| 3088 | goto free_srq; | 3144 | goto free_srq; |
| 3089 | 3145 | ||
| @@ -3105,7 +3161,7 @@ static int srpt_alloc_srq(struct srpt_device *sdev) · 15 unmodified lines | |||
| 3105 | return 0; | 3161 | return 0; |
| 3106 | 3162 | ||
| 3107 | free_cache: | 3163 | free_cache: |
| 3108 | kmem_cache_destroy(sdev->req_buf_cache); | 3164 | srpt_cache_put(sdev->req_buf_cache); |
| 3109 | 3165 | ||
| 3110 | free_srq: | 3166 | free_srq: |
| 3111 | ib_destroy_srq(srq); | 3167 | ib_destroy_srq(srq); |
| @@ -119,12 +119,12 @@ static void input_pass_values(struct input_dev *dev, · 118 unmodified lines | |||
| 119 | 119 | ||
| 120 | handle = rcu_dereference(dev->grab); | 120 | handle = rcu_dereference(dev->grab); |
| 121 | if (handle) { | 121 | if (handle) { |
| 122 | count = handle->handler->events(handle, vals, count); | 122 | count = handle->handle_events(handle, vals, count); |
| 123 | } else { | 123 | } else { |
| 124 | list_for_each_entry_rcu(handle, &dev->h_list, d_node) | 124 | list_for_each_entry_rcu(handle, &dev->h_list, d_node) |
| 125 | if (handle->open) { | 125 | if (handle->open) { |
| 126 | count = handle->handler->events(handle, vals, | 126 | count = handle->handle_events(handle, vals, |
| 127 | count); | 127 | count); |
| 128 | if (!count) | 128 | if (!count) |
| 129 | break; | 129 | break; |
| 130 | } | 130 | } |
| @@ -2534,57 +2534,6 @@ static int input_handler_check_methods(const struct input_handler *handler) · 2403 unmodified lines | |||
| 2534 | return 0; | 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 | * input_register_handler - register a new input handler | 2538 | * input_register_handler - register a new input handler |
| 2590 | * @handler: handler to be registered | 2539 | * @handler: handler to be registered |
| @@ -2604,13 +2553,6 @@ int input_register_handler(struct input_handler *handler) · 13 unmodified lines | |||
| 2604 | 2553 | ||
| 2605 | INIT_LIST_HEAD(&handler->h_list); | 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 | error = mutex_lock_interruptible(&input_mutex); | 2556 | error = mutex_lock_interruptible(&input_mutex); |
| 2615 | if (error) | 2557 | if (error) |
| 2616 | return error; | 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 | EXPORT_SYMBOL(input_handler_for_each_handle); | 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 | * input_register_handle - register a new input handle | 2699 | * input_register_handle - register a new input handle |
| 2689 | * @handle: handle to register | 2700 | * @handle: handle to register |
| @@ -2701,6 +2712,7 @@ int input_register_handle(struct input_handle *handle) · 11 unmodified lines | |||
| 2701 | struct input_dev *dev = handle->dev; | 2712 | struct input_dev *dev = handle->dev; |
| 2702 | int error; | 2713 | int error; |
| 2703 | 2714 | ||
| 2715 | input_handle_setup_event_handler(handle); | ||
| 2704 | /* | 2716 | /* |
| 2705 | * We take dev->mutex here to prevent race with | 2717 | * We take dev->mutex here to prevent race with |
| 2706 | * input_release_device(). | 2718 | * input_release_device(). |
| @@ -218,6 +218,7 @@ static const struct xpad_device { · 217 unmodified lines | |||
| 218 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, | 218 | { 0x0c12, 0x8810, "Zeroplus Xbox Controller", 0, XTYPE_XBOX }, |
| 219 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX }, | 219 | { 0x0c12, 0x9902, "HAMA VibraX - *FAULTY HARDWARE*", 0, XTYPE_XBOX }, |
| 220 | { 0x0d2f, 0x0002, "Andamiro Pump It Up pad", MAP_DPAD_TO_BUTTONS, XTYPE_XBOX }, | 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 | { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX }, | 222 | { 0x0e4c, 0x1097, "Radica Gamester Controller", 0, XTYPE_XBOX }, |
| 222 | { 0x0e4c, 0x1103, "Radica Gamester Reflex", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX }, | 223 | { 0x0e4c, 0x1103, "Radica Gamester Reflex", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOX }, |
| 223 | { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX }, | 224 | { 0x0e4c, 0x2390, "Radica Games Jtech Controller", 0, XTYPE_XBOX }, |
| @@ -373,6 +374,7 @@ static const struct xpad_device { · 149 unmodified lines | |||
| 373 | { 0x294b, 0x3404, "Snakebyte GAMEPAD RGB X", 0, XTYPE_XBOXONE }, | 374 | { 0x294b, 0x3404, "Snakebyte GAMEPAD RGB X", 0, XTYPE_XBOXONE }, |
| 374 | { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE }, | 375 | { 0x2dc8, 0x2000, "8BitDo Pro 2 Wired Controller fox Xbox", 0, XTYPE_XBOXONE }, |
| 375 | { 0x2dc8, 0x3106, "8BitDo Pro 2 Wired Controller", 0, XTYPE_XBOX360 }, | 376 | { 0x2dc8, 0x3106, "8BitDo Pro 2 Wired Controller", 0, XTYPE_XBOX360 }, |
| 377 | { 0x2dc8, 0x310a, "8BitDo Ultimate 2C Wireless Controller", 0, XTYPE_XBOX360 }, | ||
| 376 | { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE }, | 378 | { 0x2e24, 0x0652, "Hyperkin Duke X-Box One pad", 0, XTYPE_XBOXONE }, |
| 377 | { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 }, | 379 | { 0x31e3, 0x1100, "Wooting One", 0, XTYPE_XBOX360 }, |
| 378 | { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 }, | 380 | { 0x31e3, 0x1200, "Wooting Two", 0, XTYPE_XBOX360 }, |
| @@ -492,6 +494,7 @@ static const struct usb_device_id xpad_table[] = { · 113 unmodified lines | |||
| 492 | XPAD_XBOX360_VENDOR(0x07ff), /* Mad Catz Gamepad */ | 494 | XPAD_XBOX360_VENDOR(0x07ff), /* Mad Catz Gamepad */ |
| 493 | XPAD_XBOXONE_VENDOR(0x0b05), /* ASUS controllers */ | 495 | XPAD_XBOXONE_VENDOR(0x0b05), /* ASUS controllers */ |
| 494 | XPAD_XBOX360_VENDOR(0x0c12), /* Zeroplus X-Box 360 controllers */ | 496 | XPAD_XBOX360_VENDOR(0x0c12), /* Zeroplus X-Box 360 controllers */ |
| 497 | XPAD_XBOX360_VENDOR(0x0db0), /* Micro Star International X-Box 360 controllers */ | ||
| 495 | XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f Xbox 360 controllers */ | 498 | XPAD_XBOX360_VENDOR(0x0e6f), /* 0x0e6f Xbox 360 controllers */ |
| 496 | XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f Xbox One controllers */ | 499 | XPAD_XBOXONE_VENDOR(0x0e6f), /* 0x0e6f Xbox One controllers */ |
| 497 | XPAD_XBOX360_VENDOR(0x0f0d), /* Hori controllers */ | 500 | XPAD_XBOX360_VENDOR(0x0f0d), /* Hori controllers */ |
| @@ -822,7 +822,8 @@ static int adp5588_suspend(struct device *dev) · 821 unmodified lines | |||
| 822 | { | 822 | { |
| 823 | struct i2c_client *client = to_i2c_client(dev); | 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 | return 0; | 828 | return 0; |
| 828 | } | 829 | } |
| @@ -831,7 +832,8 @@ static int adp5588_resume(struct device *dev) · 2 unmodified lines | |||
| 831 | { | 832 | { |
| 832 | struct i2c_client *client = to_i2c_client(dev); | 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 | return 0; | 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 | static void edt_ft5x06_disable_regulators(void *arg) | 1132 | static void edt_ft5x06_disable_regulators(void *arg) |
| 1125 | { | 1133 | { |
| 1126 | struct edt_ft5x06_ts_data *data = arg; | 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 | return PTR_ERR(tsdata->regmap); | 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 | chip_data = device_get_match_data(&client->dev); | 1175 | chip_data = device_get_match_data(&client->dev); |
| 1158 | if (!chip_data) | 1176 | if (!chip_data) |
| 1159 | chip_data = (const struct edt_i2c_chip_data *)id->driver_data; | 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 | struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client); | 1365 | struct edt_ft5x06_ts_data *tsdata = i2c_get_clientdata(client); |
| 1348 | 1366 | ||
| 1349 | edt_ft5x06_ts_teardown_debugfs(tsdata); | 1367 | edt_ft5x06_ts_teardown_debugfs(tsdata); |
| 1350 | regmap_exit(tsdata->regmap); | ||
| 1351 | } | 1368 | } |
| 1352 | 1369 | ||
| 1353 | static int edt_ft5x06_ts_suspend(struct device *dev) | 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 | return error; | 645 | return error; |
| 646 | } | 646 | } |
| 647 | 647 | ||
| 648 | bt541->num_keycodes = device_property_count_u32(&client->dev, "linux,keycodes"); | 648 | if (device_property_present(&client->dev, "linux,keycodes")) { |
| 649 | if (bt541->num_keycodes > ARRAY_SIZE(bt541->keycodes)) { | 649 | bt541->num_keycodes = device_property_count_u32(&client->dev, |
| 650 | dev_err(&client->dev, "too many keys defined (%d)\n", bt541->num_keycodes); | 650 | "linux,keycodes"); |
| 651 | return -EINVAL; | 651 | if (bt541->num_keycodes < 0) { |
| 652 | } | 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", | 661 | error = device_property_read_u32_array(&client->dev, |
| 655 | bt541->keycodes, | 662 | "linux,keycodes", |
| 656 | bt541->num_keycodes); | 663 | bt541->keycodes, |
| 657 | if (error) { | 664 | bt541->num_keycodes); |
| 658 | dev_err(&client->dev, | 665 | if (error) { |
| 659 | "Unable to parse \"linux,keycodes\" property: %d\n", error); | 666 | dev_err(&client->dev, |
| 660 | return error; | 667 | "Unable to parse \"linux,keycodes\" property: %d\n", |
| 668 | error); | ||
| 669 | return error; | ||
| 670 | } | ||
| 661 | } | 671 | } |
| 662 | 672 | ||
| 663 | error = zinitix_init_input_dev(bt541); | 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 | cd_table->s1fmt = STRTAB_STE_0_S1FMT_LINEAR; | 1420 | cd_table->s1fmt = STRTAB_STE_0_S1FMT_LINEAR; |
| 1421 | cd_table->linear.num_ents = max_contexts; | 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 | cd_table->linear.table = dma_alloc_coherent(smmu->dev, l1size, | 1424 | cd_table->linear.table = dma_alloc_coherent(smmu->dev, l1size, |
| 1425 | &cd_table->cdtab_dma, | 1425 | &cd_table->cdtab_dma, |
| 1426 | GFP_KERNEL); | 1426 | GFP_KERNEL); |
| @@ -3625,7 +3625,7 @@ static int arm_smmu_init_strtab_2lvl(struct arm_smmu_device *smmu) · 2198 unmodified lines | |||
| 3625 | u32 l1size; | 3625 | u32 l1size; |
| 3626 | struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg; | 3626 | struct arm_smmu_strtab_cfg *cfg = &smmu->strtab_cfg; |
| 3627 | unsigned int last_sid_idx = | 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 | /* Calculate the L1 size, capped to the SIDSIZE. */ | 3630 | /* Calculate the L1 size, capped to the SIDSIZE. */ |
| 3631 | cfg->l2.num_l1_ents = min(last_sid_idx + 1, STRTAB_MAX_L1_ENTRIES); | 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 | * Disable MMU-500's not-particularly-beneficial next-page | 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 | for (i = 0; i < smmu->num_context_banks; ++i) { | 135 | for (i = 0; i < smmu->num_context_banks; ++i) { |
| 136 | reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR); | 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 | arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_ACTLR, reg); | 138 | arm_smmu_cb_write(smmu, i, ARM_SMMU_CB_ACTLR, reg); |
| 139 | reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR); | 139 | reg = arm_smmu_cb_read(smmu, i, ARM_SMMU_CB_ACTLR); |
| 140 | if (reg & ARM_MMU500_ACTLR_CPRE) | 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 | return 0; | 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 | static void domain_context_clear(struct device_domain_info *info) | 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 | domain_context_clear_one(info, info->bus, info->devfn); | 3344 | domain_context_clear_one(info, info->bus, info->devfn); |
| 3345 | return; | ||
| 3346 | } | ||
| 3345 | 3347 | ||
| 3346 | pci_for_each_dma_alias(to_pci_dev(info->dev), | 3348 | pci_for_each_dma_alias(to_pci_dev(info->dev), |
| 3347 | &domain_context_clear_one_cb, info); | 3349 | &domain_context_clear_one_cb, info); |
| @@ -45,13 +45,6 @@ config ARM_GIC_V3_ITS · 44 unmodified lines | |||
| 45 | select IRQ_MSI_LIB | 45 | select IRQ_MSI_LIB |
| 46 | default ARM_GIC_V3 | 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 | config ARM_GIC_V3_ITS_FSL_MC | 48 | config ARM_GIC_V3_ITS_FSL_MC |
| 56 | bool | 49 | bool |
| 57 | depends on ARM_GIC_V3_ITS | 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 | its_encode_valid(cmd, desc->its_vmapp_cmd.valid); | 797 | its_encode_valid(cmd, desc->its_vmapp_cmd.valid); |
| 798 | 798 | ||
| 799 | if (!desc->its_vmapp_cmd.valid) { | 799 | if (!desc->its_vmapp_cmd.valid) { |
| 800 | alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count); | ||
| 800 | if (is_v4_1(its)) { | 801 | if (is_v4_1(its)) { |
| 801 | alloc = !atomic_dec_return(&desc->its_vmapp_cmd.vpe->vmapp_count); | ||
| 802 | its_encode_alloc(cmd, alloc); | 802 | its_encode_alloc(cmd, alloc); |
| 803 | /* | 803 | /* |
| 804 | * Unmapping a VPE is self-synchronizing on GICv4.1, | 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 | its_encode_vpt_addr(cmd, vpt_addr); | 817 | its_encode_vpt_addr(cmd, vpt_addr); |
| 818 | its_encode_vpt_size(cmd, LPI_NRBITS - 1); | 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 | if (!is_v4_1(its)) | 822 | if (!is_v4_1(its)) |
| 821 | goto out; | 823 | goto out; |
| 822 | 824 | ||
| 823 | vconf_addr = virt_to_phys(page_address(desc->its_vmapp_cmd.vpe->its_vm->vprop_page)); | 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 | its_encode_alloc(cmd, alloc); | 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 | struct cpumask *table_mask; | 3806 | struct cpumask *table_mask; |
| 3807 | unsigned long flags; | 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 | * Changing affinity is mega expensive, so let's be as lazy as | 3827 | * Changing affinity is mega expensive, so let's be as lazy as |
| 3811 | * we can and only do it if we really have to. Also, if mapped | 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 | raw_spin_lock_init(&vpe->vpe_lock); | 4480 | raw_spin_lock_init(&vpe->vpe_lock); |
| 4464 | vpe->vpe_id = vpe_id; | 4481 | vpe->vpe_id = vpe_id; |
| 4465 | vpe->vpt_page = vpt_page; | 4482 | vpe->vpt_page = vpt_page; |
| 4466 | if (gic_rdists->has_rvpeid) | 4483 | atomic_set(&vpe->vmapp_count, 0); |
| 4467 | atomic_set(&vpe->vmapp_count, 0); | 4484 | if (!gic_rdists->has_rvpeid) |
| 4468 | else | ||
| 4469 | vpe->vpe_proxy_event = -1; | 4485 | vpe->vpe_proxy_event = -1; |
| 4470 | 4486 | ||
| 4471 | return 0; | 4487 | return 0; |
| @@ -37,7 +37,7 @@ static struct chip_props ocelot_props = { · 36 unmodified lines | |||
| 37 | .reg_off_ena_clr = 0x1c, | 37 | .reg_off_ena_clr = 0x1c, |
| 38 | .reg_off_ena_set = 0x20, | 38 | .reg_off_ena_set = 0x20, |
| 39 | .reg_off_ident = 0x38, | 39 | .reg_off_ident = 0x38, |
| 40 | .reg_off_trigger = 0x5c, | 40 | .reg_off_trigger = 0x4, |
| 41 | .n_irq = 24, | 41 | .n_irq = 24, |
| 42 | }; | 42 | }; |
| 43 | 43 | ||
| @@ -70,7 +70,7 @@ static struct chip_props jaguar2_props = { · 26 unmodified lines | |||
| 70 | .reg_off_ena_clr = 0x1c, | 70 | .reg_off_ena_clr = 0x1c, |
| 71 | .reg_off_ena_set = 0x20, | 71 | .reg_off_ena_set = 0x20, |
| 72 | .reg_off_ident = 0x38, | 72 | .reg_off_ident = 0x38, |
| 73 | .reg_off_trigger = 0x5c, | 73 | .reg_off_trigger = 0x4, |
| 74 | .n_irq = 29, | 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 | u32 val; | 84 | u32 val; |
| 85 | 85 | ||
| 86 | irq_gc_lock(gc); | 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 | val = irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 0)) | | 93 | val = irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 0)) | |
| 88 | irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 1)); | 94 | irq_reg_readl(gc, ICPU_CFG_INTR_INTR_TRIGGER(p, 1)); |
| 89 | if (!(val & mask)) | 95 | if (!(val & mask)) |
| @@ -8,6 +8,7 @@ · 7 unmodified lines | |||
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/bitfield.h> | 10 | #include <linux/bitfield.h> |
| 11 | #include <linux/cleanup.h> | ||
| 11 | #include <linux/clk.h> | 12 | #include <linux/clk.h> |
| 12 | #include <linux/err.h> | 13 | #include <linux/err.h> |
| 13 | #include <linux/io.h> | 14 | #include <linux/io.h> |
| @@ -530,12 +531,12 @@ static int rzg2l_irqc_parse_interrupts(struct rzg2l_irqc_priv *priv, · 516 unmodified lines | |||
| 530 | static int rzg2l_irqc_common_init(struct device_node *node, struct device_node *parent, | 531 | static int rzg2l_irqc_common_init(struct device_node *node, struct device_node *parent, |
| 531 | const struct irq_chip *irq_chip) | 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 | struct irq_domain *irq_domain, *parent_domain; | 536 | struct irq_domain *irq_domain, *parent_domain; |
| 534 | struct platform_device *pdev; | ||
| 535 | struct reset_control *resetn; | 537 | struct reset_control *resetn; |
| 536 | int ret; | 538 | int ret; |
| 537 | 539 | ||
| 538 | pdev = of_find_device_by_node(node); | ||
| 539 | if (!pdev) | 540 | if (!pdev) |
| 540 | return -ENODEV; | 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 | register_syscore_ops(&rzg2l_irqc_syscore_ops); | 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 | return 0; | 606 | return 0; |
| 595 | 607 | ||
| 596 | pm_put: | 608 | pm_put: |
| @@ -341,7 +341,7 @@ int imsic_irqdomain_init(void) · 340 unmodified lines | |||
| 341 | imsic->fwnode, global->hart_index_bits, global->guest_index_bits); | 341 | imsic->fwnode, global->hart_index_bits, global->guest_index_bits); |
| 342 | pr_info("%pfwP: group-index-bits: %d, group-index-shift: %d\n", | 342 | pr_info("%pfwP: group-index-bits: %d, group-index-shift: %d\n", |
| 343 | imsic->fwnode, global->group_index_bits, global->group_index_shift); | 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 | imsic->fwnode, global->nr_ids, &global->base_addr); | 345 | imsic->fwnode, global->nr_ids, &global->base_addr); |
| 346 | pr_info("%pfwP: total %d interrupts available\n", | 346 | pr_info("%pfwP: total %d interrupts available\n", |
| 347 | imsic->fwnode, num_possible_cpus() * (global->nr_ids - 1)); | 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 | static u32 nr_rintc; | 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 | #define for_each_matching_plic(_plic_id) \ | 270 | #define for_each_matching_plic(_plic_id) \ |
| 271 | unsigned int _plic; \ | 271 | unsigned int _plic; \ |
| @@ -329,13 +329,30 @@ int acpi_rintc_get_imsic_mmio_info(u32 index, struct resource *res) · 57 unmodified lines | |||
| 329 | return 0; | 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 | static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header, | 338 | static int __init riscv_intc_acpi_init(union acpi_subtable_headers *header, |
| 333 | const unsigned long end) | 339 | const unsigned long end) |
| 334 | { | 340 | { |
| 335 | struct acpi_madt_rintc *rintc; | 341 | struct acpi_madt_rintc *rintc; |
| 336 | struct fwnode_handle *fn; | 342 | struct fwnode_handle *fn; |
| 343 | int count; | ||
| 337 | int rc; | 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 | rintc = (struct acpi_madt_rintc *)header; | 356 | rintc = (struct acpi_madt_rintc *)header; |
| 340 | rintc_acpi_data[nr_rintc] = kzalloc(sizeof(*rintc_acpi_data[0]), GFP_KERNEL); | 357 | rintc_acpi_data[nr_rintc] = kzalloc(sizeof(*rintc_acpi_data[0]), GFP_KERNEL); |
| 341 | if (!rintc_acpi_data[nr_rintc]) | 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 | static void plic_irq_unmask(struct irq_data *d) | 129 | static void plic_irq_unmask(struct irq_data *d) |
| 140 | { | 130 | { |
| 141 | struct plic_priv *priv = irq_data_get_irq_chip_data(d); | 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 | writel(0, priv->regs + PRIORITY_BASE + d->hwirq * PRIORITY_PER_ID); | 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 | static void plic_irq_eoi(struct irq_data *d) | 154 | static void plic_irq_eoi(struct irq_data *d) |
| 154 | { | 155 | { |
| 155 | struct plic_handler *handler = this_cpu_ptr(&plic_handlers); | 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 | handler->enable_save = kcalloc(DIV_ROUND_UP(nr_irqs, 32), | 628 | handler->enable_save = kcalloc(DIV_ROUND_UP(nr_irqs, 32), |
| 628 | sizeof(*handler->enable_save), GFP_KERNEL); | 629 | sizeof(*handler->enable_save), GFP_KERNEL); |
| 629 | if (!handler->enable_save) | 630 | if (!handler->enable_save) { |
| 631 | error = -ENOMEM; | ||
| 630 | goto fail_cleanup_contexts; | 632 | goto fail_cleanup_contexts; |
| 633 | } | ||
| 631 | done: | 634 | done: |
| 632 | for (hwirq = 1; hwirq <= nr_irqs; hwirq++) { | 635 | for (hwirq = 1; hwirq <= nr_irqs; hwirq++) { |
| 633 | plic_toggle(handler, hwirq, 0); | 636 | plic_toggle(handler, hwirq, 0); |
| @@ -639,8 +642,10 @@ done: · 5 unmodified lines | |||
| 639 | 642 | ||
| 640 | priv->irqdomain = irq_domain_create_linear(fwnode, nr_irqs + 1, | 643 | priv->irqdomain = irq_domain_create_linear(fwnode, nr_irqs + 1, |
| 641 | &plic_irqdomain_ops, priv); | 644 | &plic_irqdomain_ops, priv); |
| 642 | if (WARN_ON(!priv->irqdomain)) | 645 | if (WARN_ON(!priv->irqdomain)) { |
| 646 | error = -ENOMEM; | ||
| 643 | goto fail_cleanup_contexts; | 647 | goto fail_cleanup_contexts; |
| 648 | } | ||
| 644 | 649 | ||
| 645 | /* | 650 | /* |
| 646 | * We can have multiple PLIC instances so setup global state | 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 | return 0; | 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 | bool md_flush_request(struct mddev *mddev, struct bio *bio) | 569 | bool md_flush_request(struct mddev *mddev, struct bio *bio) |
| 550 | { | 570 | { |
| 551 | struct md_rdev *rdev; | 571 | struct md_rdev *rdev; |
| @@ -565,7 +585,9 @@ bool md_flush_request(struct mddev *mddev, struct bio *bio) · 13 unmodified lines | |||
| 565 | new = bio_alloc_bioset(rdev->bdev, 0, | 585 | new = bio_alloc_bioset(rdev->bdev, 0, |
| 566 | REQ_OP_WRITE | REQ_PREFLUSH, GFP_NOIO, | 586 | REQ_OP_WRITE | REQ_PREFLUSH, GFP_NOIO, |
| 567 | &mddev->bio_set); | 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 | submit_bio(new); | 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 | if (!mddev_is_dm(conf->mddev)) { | 4063 | if (!mddev_is_dm(conf->mddev)) { |
| 4064 | ret = raid10_set_queue_limits(mddev); | 4064 | int err = raid10_set_queue_limits(mddev); |
| 4065 | if (ret) | 4065 | |
| 4066 | if (err) { | ||
| 4067 | ret = err; | ||
| 4066 | goto out_free_conf; | 4068 | goto out_free_conf; |
| 4069 | } | ||
| 4067 | } | 4070 | } |
| 4068 | 4071 | ||
| 4069 | /* need to check that every block has at least one working mirror */ | 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 | select MFD_CORE | 16 | select MFD_CORE |
| 17 | help | 17 | help |
| 18 | This supports for Realtek PCI-Express card reader including rts5209, | 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 | Realtek card readers support access to many types of memory cards, | 21 | Realtek card readers support access to many types of memory cards, |
| 21 | such as Memory Stick, Memory Stick Pro, Secure Digital and | 22 | such as Memory Stick, Memory Stick Pro, Secure Digital and |
| 22 | MultiMediaCard. | 23 | MultiMediaCard. |
| @@ -364,6 +364,7 @@ static int pci1xxxx_otp_eeprom_probe(struct auxiliary_device *aux_dev, · 363 unmodified lines | |||
| 364 | if (is_eeprom_responsive(priv)) { | 364 | if (is_eeprom_responsive(priv)) { |
| 365 | priv->nvmem_config_eeprom.type = NVMEM_TYPE_EEPROM; | 365 | priv->nvmem_config_eeprom.type = NVMEM_TYPE_EEPROM; |
| 366 | priv->nvmem_config_eeprom.name = EEPROM_NAME; | 366 | priv->nvmem_config_eeprom.name = EEPROM_NAME; |
| 367 | priv->nvmem_config_eeprom.id = NVMEM_DEVID_AUTO; | ||
| 367 | priv->nvmem_config_eeprom.dev = &aux_dev->dev; | 368 | priv->nvmem_config_eeprom.dev = &aux_dev->dev; |
| 368 | priv->nvmem_config_eeprom.owner = THIS_MODULE; | 369 | priv->nvmem_config_eeprom.owner = THIS_MODULE; |
| 369 | priv->nvmem_config_eeprom.reg_read = pci1xxxx_eeprom_read; | 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 | priv->nvmem_config_otp.type = NVMEM_TYPE_OTP; | 385 | priv->nvmem_config_otp.type = NVMEM_TYPE_OTP; |
| 385 | priv->nvmem_config_otp.name = OTP_NAME; | 386 | priv->nvmem_config_otp.name = OTP_NAME; |
| 387 | priv->nvmem_config_otp.id = NVMEM_DEVID_AUTO; | ||
| 386 | priv->nvmem_config_otp.dev = &aux_dev->dev; | 388 | priv->nvmem_config_otp.dev = &aux_dev->dev; |
| 387 | priv->nvmem_config_otp.owner = THIS_MODULE; | 389 | priv->nvmem_config_otp.owner = THIS_MODULE; |
| 388 | priv->nvmem_config_otp.reg_read = pci1xxxx_otp_read; | 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 | return; | 321 | return; |
| 322 | 322 | ||
| 323 | list_del(&cb->list); | 323 | list_del(&cb->list); |
| 324 | kfree(cb->buf.data); | 324 | kvfree(cb->buf.data); |
| 325 | kfree(cb->ext_hdr); | 325 | kfree(cb->ext_hdr); |
| 326 | kfree(cb); | 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 | if (length == 0) | 497 | if (length == 0) |
| 498 | return cb; | 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 | if (!cb->buf.data) { | 501 | if (!cb->buf.data) { |
| 502 | mei_io_cb_free(cb); | 502 | mei_io_cb_free(cb); |
| 503 | return NULL; | 503 | return NULL; |
| @@ -258,7 +258,6 @@ static int gru_get_cpu_resources(int dsr_bytes, void **cb, void **dsr) · 257 unmodified lines | |||
| 258 | int lcpu; | 258 | int lcpu; |
| 259 | 259 | ||
| 260 | BUG_ON(dsr_bytes > GRU_NUM_KERNEL_DSR_BYTES); | 260 | BUG_ON(dsr_bytes > GRU_NUM_KERNEL_DSR_BYTES); |
| 261 | preempt_disable(); | ||
| 262 | bs = gru_lock_kernel_context(-1); | 261 | bs = gru_lock_kernel_context(-1); |
| 263 | lcpu = uv_blade_processor_id(); | 262 | lcpu = uv_blade_processor_id(); |
| 264 | *cb = bs->kernel_cb + lcpu * GRU_HANDLE_STRIDE; | 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 | static void gru_free_cpu_resources(void *cb, void *dsr) | 271 | static void gru_free_cpu_resources(void *cb, void *dsr) |
| 273 | { | 272 | { |
| 274 | gru_unlock_kernel_context(uv_numa_blade_id()); | 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 | again: | 938 | again: |
| 939 | mutex_lock(>s->ts_ctxlock); | 939 | mutex_lock(>s->ts_ctxlock); |
| 940 | preempt_disable(); | ||
| 941 | 940 | ||
| 942 | if (gru_check_context_placement(gts)) { | 941 | if (gru_check_context_placement(gts)) { |
| 943 | preempt_enable(); | ||
| 944 | mutex_unlock(>s->ts_ctxlock); | 942 | mutex_unlock(>s->ts_ctxlock); |
| 945 | gru_unload_context(gts, 1); | 943 | gru_unload_context(gts, 1); |
| 946 | return VM_FAULT_NOPAGE; | 944 | return VM_FAULT_NOPAGE; |
| @@ -949,7 +947,6 @@ again: · 2 unmodified lines | |||
| 949 | if (!gts->ts_gru) { | 947 | if (!gts->ts_gru) { |
| 950 | STAT(load_user_context); | 948 | STAT(load_user_context); |
| 951 | if (!gru_assign_gru_context(gts)) { | 949 | if (!gru_assign_gru_context(gts)) { |
| 952 | preempt_enable(); | ||
| 953 | mutex_unlock(>s->ts_ctxlock); | 950 | mutex_unlock(>s->ts_ctxlock); |
| 954 | set_current_state(TASK_INTERRUPTIBLE); | 951 | set_current_state(TASK_INTERRUPTIBLE); |
| 955 | schedule_timeout(GRU_ASSIGN_DELAY); /* true hack ZZZ */ | 952 | schedule_timeout(GRU_ASSIGN_DELAY); /* true hack ZZZ */ |
| @@ -965,7 +962,6 @@ again: · 9 unmodified lines | |||
| 965 | vma->vm_page_prot); | 962 | vma->vm_page_prot); |
| 966 | } | 963 | } |
| 967 | 964 | ||
| 968 | preempt_enable(); | ||
| 969 | mutex_unlock(>s->ts_ctxlock); | 965 | mutex_unlock(>s->ts_ctxlock); |
| 970 | 966 | ||
| 971 | return VM_FAULT_NOPAGE; | 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 | struct gru_tlb_global_handle *tgh; | 65 | struct gru_tlb_global_handle *tgh; |
| 66 | int n; | 66 | int n; |
| 67 | 67 | ||
| 68 | preempt_disable(); | ||
| 69 | if (uv_numa_blade_id() == gru->gs_blade_id) | 68 | if (uv_numa_blade_id() == gru->gs_blade_id) |
| 70 | n = get_on_blade_tgh(gru); | 69 | n = get_on_blade_tgh(gru); |
| 71 | else | 70 | else |
| @@ -79,7 +78,6 @@ static struct gru_tlb_global_handle *get_lock_tgh_handle(struct gru_state · 7 unmodified lines | |||
| 79 | static void get_unlock_tgh_handle(struct gru_tlb_global_handle *tgh) | 78 | static void get_unlock_tgh_handle(struct gru_tlb_global_handle *tgh) |
| 80 | { | 79 | { |
| 81 | unlock_tgh_handle(tgh); | 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 | blk_queue_rq_timeout(mq->queue, 60 * HZ); | 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 | INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler); | 394 | INIT_WORK(&mq->recovery_work, mmc_mq_recovery_handler); |
| 394 | INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work); | 395 | INIT_WORK(&mq->complete_work, mmc_blk_mq_complete_work); |
| @@ -38,9 +38,8 @@ struct mvsd_host { · 37 unmodified lines | |||
| 38 | unsigned int xfer_mode; | 38 | unsigned int xfer_mode; |
| 39 | unsigned int intr_en; | 39 | unsigned int intr_en; |
| 40 | unsigned int ctrl; | 40 | unsigned int ctrl; |
| 41 | bool use_pio; | ||
| 42 | struct sg_mapping_iter sg_miter; | ||
| 43 | unsigned int pio_size; | 41 | unsigned int pio_size; |
| 42 | void *pio_ptr; | ||
| 44 | unsigned int sg_frags; | 43 | unsigned int sg_frags; |
| 45 | unsigned int ns_per_clk; | 44 | unsigned int ns_per_clk; |
| 46 | unsigned int clock; | 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 | * data when the buffer is not aligned on a 64 byte | 114 | * data when the buffer is not aligned on a 64 byte |
| 116 | * boundary. | 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 | host->pio_size = data->blocks * data->blksz; | 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 | if (!nodma) | 119 | if (!nodma) |
| 128 | dev_dbg(host->dev, "fallback to PIO for data\n"); | 120 | dev_dbg(host->dev, "fallback to PIO for data at 0x%p size %d\n", |
| 129 | host->use_pio = true; | 121 | host->pio_ptr, host->pio_size); |
| 130 | return 1; | 122 | return 1; |
| 131 | } else { | 123 | } else { |
| 132 | dma_addr_t phys_addr; | 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 | phys_addr = sg_dma_address(data->sg); | 129 | phys_addr = sg_dma_address(data->sg); |
| 138 | mvsd_write(MVSD_SYS_ADDR_LOW, (u32)phys_addr & 0xffff); | 130 | mvsd_write(MVSD_SYS_ADDR_LOW, (u32)phys_addr & 0xffff); |
| 139 | mvsd_write(MVSD_SYS_ADDR_HI, (u32)phys_addr >> 16); | 131 | mvsd_write(MVSD_SYS_ADDR_HI, (u32)phys_addr >> 16); |
| 140 | host->use_pio = false; | ||
| 141 | return 0; | 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 | void __iomem *iobase = host->base; | 289 | void __iomem *iobase = host->base; |
| 299 | 290 | ||
| 300 | if (host->use_pio) { | 291 | if (host->pio_ptr) { |
| 301 | sg_miter_stop(&host->sg_miter); | 292 | host->pio_ptr = NULL; |
| 302 | host->pio_size = 0; | 293 | host->pio_size = 0; |
| 303 | } else { | 294 | } else { |
| 304 | dma_unmap_sg(mmc_dev(host->mmc), data->sg, host->sg_frags, | 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 | static irqreturn_t mvsd_irq(int irq, void *dev) | 344 | static irqreturn_t mvsd_irq(int irq, void *dev) |
| 354 | { | 345 | { |
| 355 | struct mvsd_host *host = dev; | 346 | struct mvsd_host *host = dev; |
| 356 | struct sg_mapping_iter *sgm = &host->sg_miter; | ||
| 357 | void __iomem *iobase = host->base; | 347 | void __iomem *iobase = host->base; |
| 358 | u32 intr_status, intr_done_mask; | 348 | u32 intr_status, intr_done_mask; |
| 359 | int irq_handled = 0; | 349 | int irq_handled = 0; |
| 360 | u16 *p; | ||
| 361 | int s; | ||
| 362 | 350 | ||
| 363 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); | 351 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 364 | dev_dbg(host->dev, "intr 0x%04x intr_en 0x%04x hw_state 0x%04x\n", | 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 | spin_lock(&host->lock); | 370 | spin_lock(&host->lock); |
| 383 | 371 | ||
| 384 | /* PIO handling, if needed. Messy business... */ | 372 | /* PIO handling, if needed. Messy business... */ |
| 385 | if (host->use_pio) { | 373 | if (host->pio_size && |
| 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 && | ||
| 407 | (intr_status & host->intr_en & | 374 | (intr_status & host->intr_en & |
| 408 | (MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) { | 375 | (MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W))) { |
| 409 | 376 | u16 *p = host->pio_ptr; | |
| 377 | int s = host->pio_size; | ||
| 410 | while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) { | 378 | while (s >= 32 && (intr_status & MVSD_NOR_RX_FIFO_8W)) { |
| 411 | readsw(iobase + MVSD_FIFO, p, 16); | 379 | readsw(iobase + MVSD_FIFO, p, 16); |
| 412 | p += 16; | 380 | p += 16; |
| 413 | s -= 32; | 381 | s -= 32; |
| 414 | sgm->consumed += 32; | ||
| 415 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); | 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 | put_unaligned(mvsd_read(MVSD_FIFO), p++); | 391 | put_unaligned(mvsd_read(MVSD_FIFO), p++); |
| 425 | put_unaligned(mvsd_read(MVSD_FIFO), p++); | 392 | put_unaligned(mvsd_read(MVSD_FIFO), p++); |
| 426 | s -= 4; | 393 | s -= 4; |
| 427 | sgm->consumed += 4; | ||
| 428 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); | 394 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 429 | } | 395 | } |
| 430 | if (s && s < 4 && (intr_status & MVSD_NOR_RX_READY)) { | 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 | val[0] = mvsd_read(MVSD_FIFO); | 398 | val[0] = mvsd_read(MVSD_FIFO); |
| 433 | val[1] = mvsd_read(MVSD_FIFO); | 399 | val[1] = mvsd_read(MVSD_FIFO); |
| 434 | memcpy(p, ((void *)&val) + 4 - s, s); | 400 | memcpy(p, ((void *)&val) + 4 - s, s); |
| 435 | sgm->consumed += s; | ||
| 436 | s = 0; | 401 | s = 0; |
| 437 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); | 402 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 438 | } | 403 | } |
| 439 | /* PIO transfer done */ | 404 | if (s == 0) { |
| 440 | host->pio_size -= sgm->consumed; | ||
| 441 | if (host->pio_size == 0) { | ||
| 442 | host->intr_en &= | 405 | host->intr_en &= |
| 443 | ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W); | 406 | ~(MVSD_NOR_RX_READY | MVSD_NOR_RX_FIFO_8W); |
| 444 | mvsd_write(MVSD_NOR_INTR_EN, host->intr_en); | 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 | dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n", | 414 | dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n", |
| 452 | s, intr_status, mvsd_read(MVSD_HW_STATE)); | 415 | s, intr_status, mvsd_read(MVSD_HW_STATE)); |
| 416 | host->pio_ptr = p; | ||
| 417 | host->pio_size = s; | ||
| 453 | irq_handled = 1; | 418 | irq_handled = 1; |
| 454 | } else if (host->use_pio && | 419 | } else if (host->pio_size && |
| 455 | (intr_status & host->intr_en & | 420 | (intr_status & host->intr_en & |
| 456 | (MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W))) { | 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 | * The TX_FIFO_8W bit is unreliable. When set, bursting | 425 | * The TX_FIFO_8W bit is unreliable. When set, bursting |
| 459 | * 16 halfwords all at once in the FIFO drops data. Actually | 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 | mvsd_write(MVSD_FIFO, get_unaligned(p++)); | 431 | mvsd_write(MVSD_FIFO, get_unaligned(p++)); |
| 465 | mvsd_write(MVSD_FIFO, get_unaligned(p++)); | 432 | mvsd_write(MVSD_FIFO, get_unaligned(p++)); |
| 466 | s -= 4; | 433 | s -= 4; |
| 467 | sgm->consumed += 4; | ||
| 468 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); | 434 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 469 | } | 435 | } |
| 470 | if (s < 4) { | 436 | if (s < 4) { |
| @@ -473,13 +439,10 @@ static irqreturn_t mvsd_irq(int irq, void *dev) · 2 unmodified lines | |||
| 473 | memcpy(((void *)&val) + 4 - s, p, s); | 439 | memcpy(((void *)&val) + 4 - s, p, s); |
| 474 | mvsd_write(MVSD_FIFO, val[0]); | 440 | mvsd_write(MVSD_FIFO, val[0]); |
| 475 | mvsd_write(MVSD_FIFO, val[1]); | 441 | mvsd_write(MVSD_FIFO, val[1]); |
| 476 | sgm->consumed += s; | ||
| 477 | s = 0; | 442 | s = 0; |
| 478 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); | 443 | intr_status = mvsd_read(MVSD_NOR_INTR_STATUS); |
| 479 | } | 444 | } |
| 480 | /* PIO transfer done */ | 445 | if (s == 0) { |
| 481 | host->pio_size -= sgm->consumed; | ||
| 482 | if (host->pio_size == 0) { | ||
| 483 | host->intr_en &= | 446 | host->intr_en &= |
| 484 | ~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W); | 447 | ~(MVSD_NOR_TX_AVAIL | MVSD_NOR_TX_FIFO_8W); |
| 485 | mvsd_write(MVSD_NOR_INTR_EN, host->intr_en); | 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 | dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n", | 451 | dev_dbg(host->dev, "pio %d intr 0x%04x hw_state 0x%04x\n", |
| 489 | s, intr_status, mvsd_read(MVSD_HW_STATE)); | 452 | s, intr_status, mvsd_read(MVSD_HW_STATE)); |
| 453 | host->pio_ptr = p; | ||
| 454 | host->pio_size = s; | ||
| 490 | irq_handled = 1; | 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 | sdhci_reset(host, mask); | 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 | if (priv->flags & FLAG_IO_FIXED_1V8) { | 863 | if (priv->flags & FLAG_IO_FIXED_1V8) { |
| 856 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); | 864 | ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2); |
| 857 | if (!(ctrl_2 & SDHCI_CTRL_VDD_180)) { | 865 | if (!(ctrl_2 & SDHCI_CTRL_VDD_180)) { |
| @@ -27,6 +27,7 @@ · 26 unmodified lines | |||
| 27 | #include <linux/phylink.h> | 27 | #include <linux/phylink.h> |
| 28 | #include <linux/etherdevice.h> | 28 | #include <linux/etherdevice.h> |
| 29 | #include <linux/if_bridge.h> | 29 | #include <linux/if_bridge.h> |
| 30 | #include <linux/if_vlan.h> | ||
| 30 | #include <net/dsa.h> | 31 | #include <net/dsa.h> |
| 31 | 32 | ||
| 32 | #include "b53_regs.h" | 33 | #include "b53_regs.h" |
| @@ -224,6 +225,9 @@ static const struct b53_mib_desc b53_mibs_58xx[] = { · 191 unmodified lines | |||
| 224 | 225 | ||
| 225 | #define B53_MIBS_58XX_SIZE ARRAY_SIZE(b53_mibs_58xx) | 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 | static int b53_do_vlan_op(struct b53_device *dev, u8 op) | 231 | static int b53_do_vlan_op(struct b53_device *dev, u8 op) |
| 228 | { | 232 | { |
| 229 | unsigned int i; | 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 | bool allow_10_100; | 2258 | bool allow_10_100; |
| 2255 | 2259 | ||
| 2256 | if (is5325(dev) || is5365(dev)) | 2260 | if (is5325(dev) || is5365(dev)) |
| 2257 | return -EOPNOTSUPP; | 2261 | return 0; |
| 2258 | 2262 | ||
| 2259 | if (!dsa_is_cpu_port(ds, port)) | 2263 | if (!dsa_is_cpu_port(ds, port)) |
| 2260 | return 0; | 2264 | return 0; |
| 2261 | 2265 | ||
| 2262 | enable_jumbo = (mtu >= JMS_MIN_SIZE); | 2266 | enable_jumbo = (mtu > ETH_DATA_LEN); |
| 2263 | allow_10_100 = (dev->chip_id == BCM583XX_DEVICE_ID); | 2267 | allow_10_100 = !is63xx(dev); |
| 2264 | 2268 | ||
| 2265 | return b53_set_jumbo(dev, enable_jumbo, allow_10_100); | 2269 | return b53_set_jumbo(dev, enable_jumbo, allow_10_100); |
| 2266 | } | 2270 | } |
| 2267 | 2271 | ||
| 2268 | static int b53_get_max_mtu(struct dsa_switch *ds, int port) | 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 | static const struct phylink_mac_ops b53_phylink_mac_ops = { | 2282 | static const struct phylink_mac_ops b53_phylink_mac_ops = { |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #include <linux/module.h> | 6 | #include <linux/module.h> |
| 7 | #include <linux/gpio/consumer.h> | 7 | #include <linux/gpio/consumer.h> |
| 8 | #include <linux/regmap.h> | 8 | #include <linux/regmap.h> |
| 9 | #include <linux/iopoll.h> | ||
| 9 | #include <linux/mutex.h> | 10 | #include <linux/mutex.h> |
| 10 | #include <linux/mii.h> | 11 | #include <linux/mii.h> |
| 11 | #include <linux/of.h> | 12 | #include <linux/of.h> |
| @@ -839,6 +840,8 @@ static void lan9303_handle_reset(struct lan9303 *chip) · 827 unmodified lines | |||
| 839 | if (!chip->reset_gpio) | 840 | if (!chip->reset_gpio) |
| 840 | return; | 841 | return; |
| 841 | 842 | ||
| 843 | gpiod_set_value_cansleep(chip->reset_gpio, 1); | ||
| 844 | |||
| 842 | if (chip->reset_duration != 0) | 845 | if (chip->reset_duration != 0) |
| 843 | msleep(chip->reset_duration); | 846 | msleep(chip->reset_duration); |
| 844 | 847 | ||
| @@ -864,8 +867,34 @@ static int lan9303_disable_processing(struct lan9303 *chip) · 19 unmodified lines | |||
| 864 | static int lan9303_check_device(struct lan9303 *chip) | 867 | static int lan9303_check_device(struct lan9303 *chip) |
| 865 | { | 868 | { |
| 866 | int ret; | 869 | int ret; |
| 870 | int err; | ||
| 867 | u32 reg; | 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 | ret = lan9303_read(chip->regmap, LAN9303_CHIP_REV, ®); | 898 | ret = lan9303_read(chip->regmap, LAN9303_CHIP_REV, ®); |
| 870 | if (ret) { | 899 | if (ret) { |
| 871 | dev_err(chip->dev, "failed to read chip revision register: %d\n", | 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 | return MICREL_KSZ8_P1_ERRATA; | 2733 | return MICREL_KSZ8_P1_ERRATA; |
| 2734 | break; | 2734 | break; |
| 2735 | case KSZ8567_CHIP_ID: | 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 | case KSZ9477_CHIP_ID: | 2741 | case KSZ9477_CHIP_ID: |
| 2742 | /* KSZ9477S Errata DS80000754A Module 4 */ | ||
| 2737 | case KSZ9567_CHIP_ID: | 2743 | case KSZ9567_CHIP_ID: |
| 2744 | /* KSZ9567S Errata DS80000756A Module 4 */ | ||
| 2738 | case KSZ9896_CHIP_ID: | 2745 | case KSZ9896_CHIP_ID: |
| 2746 | /* KSZ9896C Errata DS80000757A Module 3 */ | ||
| 2739 | case KSZ9897_CHIP_ID: | 2747 | case KSZ9897_CHIP_ID: |
| 2740 | /* KSZ9477 Errata DS80000754C | 2748 | /* KSZ9897R Errata DS80000758C Module 4 */ |
| 2741 | * | 2749 | /* Energy Efficient Ethernet (EEE) feature select must be manually disabled |
| 2742 | * Module 4: Energy Efficient Ethernet (EEE) feature select must | ||
| 2743 | * be manually disabled | ||
| 2744 | * The EEE feature is enabled by default, but it is not fully | 2750 | * The EEE feature is enabled by default, but it is not fully |
| 2745 | * operational. It must be manually disabled through register | 2751 | * operational. It must be manually disabled through register |
| 2746 | * controls. If not disabled, the PHY ports can auto-negotiate | 2752 | * controls. If not disabled, the PHY ports can auto-negotiate |
| 2747 | * to enable EEE, and this feature can cause link drops when | 2753 | * to enable EEE, and this feature can cause link drops when |
| 2748 | * linked to another device supporting EEE. | 2754 | * linked to another device supporting EEE. |
| 2749 | * | 2755 | * |
| 2750 | * The same item appears in the errata for the KSZ9567, KSZ9896, | 2756 | * The same item appears in the errata for all switches above. |
| 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 | */ | 2757 | */ |
| 2757 | return MICREL_NO_EEE; | 2758 | return MICREL_NO_EEE; |
| 2758 | } | 2759 | } |
| @@ -6347,7 +6347,7 @@ static const struct mv88e6xxx_info mv88e6xxx_table[] = { · 6346 unmodified lines | |||
| 6347 | .invalid_port_mask = BIT(1) | BIT(2) | BIT(8), | 6347 | .invalid_port_mask = BIT(1) | BIT(2) | BIT(8), |
| 6348 | .num_internal_phys = 5, | 6348 | .num_internal_phys = 5, |
| 6349 | .internal_phys_offset = 3, | 6349 | .internal_phys_offset = 3, |
| 6350 | .max_vid = 4095, | 6350 | .max_vid = 8191, |
| 6351 | .max_sid = 63, | 6351 | .max_sid = 63, |
| 6352 | .port_base_addr = 0x0, | 6352 | .port_base_addr = 0x0, |
| 6353 | .phy_base_addr = 0x0, | 6353 | .phy_base_addr = 0x0, |
| @@ -206,6 +206,7 @@ struct mv88e6xxx_gpio_ops; · 205 unmodified lines | |||
| 206 | struct mv88e6xxx_avb_ops; | 206 | struct mv88e6xxx_avb_ops; |
| 207 | struct mv88e6xxx_ptp_ops; | 207 | struct mv88e6xxx_ptp_ops; |
| 208 | struct mv88e6xxx_pcs_ops; | 208 | struct mv88e6xxx_pcs_ops; |
| 209 | struct mv88e6xxx_cc_coeffs; | ||
| 209 | 210 | ||
| 210 | struct mv88e6xxx_irq { | 211 | struct mv88e6xxx_irq { |
| 211 | u16 masked; | 212 | u16 masked; |
| @@ -408,6 +409,7 @@ struct mv88e6xxx_chip { · 196 unmodified lines | |||
| 408 | struct cyclecounter tstamp_cc; | 409 | struct cyclecounter tstamp_cc; |
| 409 | struct timecounter tstamp_tc; | 410 | struct timecounter tstamp_tc; |
| 410 | struct delayed_work overflow_work; | 411 | struct delayed_work overflow_work; |
| 412 | const struct mv88e6xxx_cc_coeffs *cc_coeffs; | ||
| 411 | 413 | ||
| 412 | struct ptp_clock *ptp_clock; | 414 | struct ptp_clock *ptp_clock; |
| 413 | struct ptp_clock_info ptp_clock_info; | 415 | struct ptp_clock_info ptp_clock_info; |
| @@ -731,10 +733,6 @@ struct mv88e6xxx_ptp_ops { · 317 unmodified lines | |||
| 731 | int arr1_sts_reg; | 733 | int arr1_sts_reg; |
| 732 | int dep_sts_reg; | 734 | int dep_sts_reg; |
| 733 | u32 rx_filters; | 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 | struct mv88e6xxx_pcs_ops { | 738 | struct mv88e6xxx_pcs_ops { |
| @@ -1713,6 +1713,7 @@ int mv88e6393x_port_set_policy(struct mv88e6xxx_chip *chip, int port, · 1712 unmodified lines | |||
| 1713 | ptr = shift / 8; | 1713 | ptr = shift / 8; |
| 1714 | shift %= 8; | 1714 | shift %= 8; |
| 1715 | mask >>= ptr * 8; | 1715 | mask >>= ptr * 8; |
| 1716 | ptr <<= 8; | ||
| 1716 | 1717 | ||
| 1717 | err = mv88e6393x_port_policy_read(chip, port, ptr, ®); | 1718 | err = mv88e6393x_port_policy_read(chip, port, ptr, ®); |
| 1718 | if (err) | 1719 | if (err) |
| @@ -18,6 +18,13 @@ · 17 unmodified lines | |||
| 18 | 18 | ||
| 19 | #define MV88E6XXX_MAX_ADJ_PPB 1000000 | 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 | /* Family MV88E6250: | 28 | /* Family MV88E6250: |
| 22 | * Raw timestamps are in units of 10-ns clock periods. | 29 | * Raw timestamps are in units of 10-ns clock periods. |
| 23 | * | 30 | * |
| @@ -25,22 +32,43 @@ · 1 unmodified line | |||
| 25 | * simplifies to | 32 | * simplifies to |
| 26 | * clkadj = scaled_ppm * 2^7 / 5^5 | 33 | * clkadj = scaled_ppm * 2^7 / 5^5 |
| 27 | */ | 34 | */ |
| 28 | #define MV88E6250_CC_SHIFT 28 | 35 | #define MV88E6XXX_CC_10NS_SHIFT 28 |
| 29 | #define MV88E6250_CC_MULT (10 << MV88E6250_CC_SHIFT) | 36 | static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_10ns_coeffs = { |
| 30 | #define MV88E6250_CC_MULT_NUM (1 << 7) | 37 | .cc_shift = MV88E6XXX_CC_10NS_SHIFT, |
| 31 | #define MV88E6250_CC_MULT_DEM 3125ULL | 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 | * Raw timestamps are in units of 8-ns clock periods. | 44 | * Raw timestamps are in units of 8-ns clock periods. |
| 35 | * | 45 | * |
| 36 | * clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16) | 46 | * clkadj = scaled_ppm * 8*2^28 / (10^6 * 2^16) |
| 37 | * simplifies to | 47 | * simplifies to |
| 38 | * clkadj = scaled_ppm * 2^9 / 5^6 | 48 | * clkadj = scaled_ppm * 2^9 / 5^6 |
| 39 | */ | 49 | */ |
| 40 | #define MV88E6XXX_CC_SHIFT 28 | 50 | #define MV88E6XXX_CC_8NS_SHIFT 28 |
| 41 | #define MV88E6XXX_CC_MULT (8 << MV88E6XXX_CC_SHIFT) | 51 | static const struct mv88e6xxx_cc_coeffs mv88e6xxx_cc_8ns_coeffs = { |
| 42 | #define MV88E6XXX_CC_MULT_NUM (1 << 9) | 52 | .cc_shift = MV88E6XXX_CC_8NS_SHIFT, |
| 43 | #define MV88E6XXX_CC_MULT_DEM 15625ULL | 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 | #define TAI_EVENT_WORK_INTERVAL msecs_to_jiffies(100) | 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 | return chip->info->ops->gpio_ops->set_pctl(chip, pin, func); | 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 | static u64 mv88e6352_ptp_clock_read(const struct cyclecounter *cc) | 141 | static u64 mv88e6352_ptp_clock_read(const struct cyclecounter *cc) |
| 87 | { | 142 | { |
| 88 | struct mv88e6xxx_chip *chip = cc_to_chip(cc); | 143 | struct mv88e6xxx_chip *chip = cc_to_chip(cc); |
| @@ -204,7 +259,6 @@ out: · 115 unmodified lines | |||
| 204 | static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) | 259 | static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) |
| 205 | { | 260 | { |
| 206 | struct mv88e6xxx_chip *chip = ptp_to_chip(ptp); | 261 | struct mv88e6xxx_chip *chip = ptp_to_chip(ptp); |
| 207 | const struct mv88e6xxx_ptp_ops *ptp_ops = chip->info->ops->ptp_ops; | ||
| 208 | int neg_adj = 0; | 262 | int neg_adj = 0; |
| 209 | u32 diff, mult; | 263 | u32 diff, mult; |
| 210 | u64 adj; | 264 | u64 adj; |
| @@ -214,10 +268,10 @@ static int mv88e6xxx_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) · 3 unmodified lines | |||
| 214 | scaled_ppm = -scaled_ppm; | 268 | scaled_ppm = -scaled_ppm; |
| 215 | } | 269 | } |
| 216 | 270 | ||
| 217 | mult = ptp_ops->cc_mult; | 271 | mult = chip->cc_coeffs->cc_mult; |
| 218 | adj = ptp_ops->cc_mult_num; | 272 | adj = chip->cc_coeffs->cc_mult_num; |
| 219 | adj *= scaled_ppm; | 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 | mv88e6xxx_reg_lock(chip); | 276 | mv88e6xxx_reg_lock(chip); |
| 223 | 277 | ||
| @@ -364,10 +418,6 @@ const struct mv88e6xxx_ptp_ops mv88e6165_ptp_ops = { · 140 unmodified lines | |||
| 364 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | | 418 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 365 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | | 419 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 366 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), | 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 | const struct mv88e6xxx_ptp_ops mv88e6250_ptp_ops = { | 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 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | | 441 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 392 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | | 442 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 393 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), | 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 | const struct mv88e6xxx_ptp_ops mv88e6352_ptp_ops = { | 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 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | | 464 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 419 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | | 465 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 420 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), | 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 | const struct mv88e6xxx_ptp_ops mv88e6390_ptp_ops = { | 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 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | | 488 | (1 << HWTSTAMP_FILTER_PTP_V2_EVENT) | |
| 447 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | | 489 | (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) | |
| 448 | (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ), | 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 | static u64 mv88e6xxx_ptp_clock_read(const struct cyclecounter *cc) | 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 | return 0; | 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 | * seconds; this task forces periodic reads so that we don't miss any. | 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 | static void mv88e6xxx_ptp_overflow_check(struct work_struct *work) | 507 | static void mv88e6xxx_ptp_overflow_check(struct work_struct *work) |
| 470 | { | 508 | { |
| 471 | struct delayed_work *dw = to_delayed_work(work); | 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 | int i; | 522 | int i; |
| 485 | 523 | ||
| 486 | /* Set up the cycle counter */ | 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 | memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc)); | 529 | memset(&chip->tstamp_cc, 0, sizeof(chip->tstamp_cc)); |
| 488 | chip->tstamp_cc.read = mv88e6xxx_ptp_clock_read; | 530 | chip->tstamp_cc.read = mv88e6xxx_ptp_clock_read; |
| 489 | chip->tstamp_cc.mask = CYCLECOUNTER_MASK(32); | 531 | chip->tstamp_cc.mask = CYCLECOUNTER_MASK(32); |
| 490 | chip->tstamp_cc.mult = ptp_ops->cc_mult; | 532 | chip->tstamp_cc.mult = chip->cc_coeffs->cc_mult; |
| 491 | chip->tstamp_cc.shift = ptp_ops->cc_shift; | 533 | chip->tstamp_cc.shift = chip->cc_coeffs->cc_shift; |
| 492 | 534 | ||
| 493 | timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc, | 535 | timecounter_init(&chip->tstamp_tc, &chip->tstamp_cc, |
| 494 | ktime_to_ns(ktime_get_real())); | 536 | ktime_to_ns(ktime_get_real())); |
| @@ -3158,7 +3158,6 @@ static int sja1105_setup(struct dsa_switch *ds) · 3157 unmodified lines | |||
| 3158 | * TPID is ETH_P_SJA1105, and the VLAN ID is the port pvid. | 3158 | * TPID is ETH_P_SJA1105, and the VLAN ID is the port pvid. |
| 3159 | */ | 3159 | */ |
| 3160 | ds->vlan_filtering_is_global = true; | 3160 | ds->vlan_filtering_is_global = true; |
| 3161 | ds->untag_bridge_pvid = true; | ||
| 3162 | ds->fdb_isolation = true; | 3161 | ds->fdb_isolation = true; |
| 3163 | ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES; | 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 | dev_info(vsc->dev, "set up the switch\n"); | 852 | dev_info(vsc->dev, "set up the switch\n"); |
| 853 | 853 | ||
| 854 | ds->untag_bridge_pvid = true; | ||
| 855 | ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES; | 854 | ds->max_num_bridges = DSA_TAG_8021Q_MAX_NUM_BRIDGES; |
| 856 | ds->fdb_isolation = true; | 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 | * from the ADIN1110 frame header. | 318 | * from the ADIN1110 frame header. |
| 319 | */ | 319 | */ |
| 320 | if (frame_size < ADIN1110_FRAME_HEADER_LEN + ADIN1110_FEC_LEN) | 320 | if (frame_size < ADIN1110_FRAME_HEADER_LEN + ADIN1110_FEC_LEN) |
| 321 | return ret; | 321 | return -EINVAL; |
| 322 | 322 | ||
| 323 | round_len = adin1110_round_len(frame_size); | 323 | round_len = adin1110_round_len(frame_size); |
| 324 | if (round_len < 0) | 324 | if (round_len < 0) |
| 325 | return ret; | 325 | return -EINVAL; |
| 326 | 326 | ||
| 327 | frame_size_no_fcs = frame_size - ADIN1110_FRAME_HEADER_LEN - ADIN1110_FEC_LEN; | 327 | frame_size_no_fcs = frame_size - ADIN1110_FRAME_HEADER_LEN - ADIN1110_FEC_LEN; |
| 328 | memset(priv->data, 0, ADIN1110_RD_HEADER_LEN); | 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 | if (unlikely(skb->len > MAX_FRAME_SIZE)) { | 485 | if (unlikely(skb->len > MAX_FRAME_SIZE)) { |
| 486 | dev->stats.tx_errors++; | 486 | dev->stats.tx_errors++; |
| 487 | goto out; | 487 | goto len_error; |
| 488 | } | 488 | } |
| 489 | 489 | ||
| 490 | /* Save skb pointer. */ | 490 | /* Save skb pointer. */ |
| @@ -575,6 +575,7 @@ frag_map_error: · 84 unmodified lines | |||
| 575 | map_error: | 575 | map_error: |
| 576 | if (net_ratelimit()) | 576 | if (net_ratelimit()) |
| 577 | dev_warn(greth->dev, "Could not create TX DMA mapping\n"); | 577 | dev_warn(greth->dev, "Could not create TX DMA mapping\n"); |
| 578 | len_error: | ||
| 578 | dev_kfree_skb(skb); | 579 | dev_kfree_skb(skb); |
| 579 | out: | 580 | out: |
| 580 | return err; | 581 | return err; |
| @@ -105,10 +105,6 @@ static struct net_device * __init mvme147lance_probe(void) · 104 unmodified lines | |||
| 105 | macaddr[3] = address&0xff; | 105 | macaddr[3] = address&0xff; |
| 106 | eth_hw_addr_set(dev, macaddr); | 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 | lp = netdev_priv(dev); | 108 | lp = netdev_priv(dev); |
| 113 | lp->ram = __get_dma_pages(GFP_ATOMIC, 3); /* 32K */ | 109 | lp->ram = __get_dma_pages(GFP_ATOMIC, 3); /* 32K */ |
| 114 | if (!lp->ram) { | 110 | if (!lp->ram) { |
| @@ -138,6 +134,9 @@ static struct net_device * __init mvme147lance_probe(void) · 23 unmodified lines | |||
| 138 | return ERR_PTR(err); | 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 | return dev; | 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 | /* Rewind so we do not have a hole */ | 323 | /* Rewind so we do not have a hole */ |
| 324 | spb_index = intf->tx_spb_index; | 324 | spb_index = intf->tx_spb_index; |
| 325 | dev_kfree_skb(skb); | ||
| 325 | return NETDEV_TX_OK; | 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 | netif_err(priv, tx_err, dev, "DMA map failed at %p (len=%d)\n", | 1359 | netif_err(priv, tx_err, dev, "DMA map failed at %p (len=%d)\n", |
| 1360 | skb->data, skb_len); | 1360 | skb->data, skb_len); |
| 1361 | ret = NETDEV_TX_OK; | 1361 | ret = NETDEV_TX_OK; |
| 1362 | dev_kfree_skb_any(skb); | ||
| 1362 | goto out; | 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 | if (!bnxt_get_rx_ts_p5(bp, &ts, cmpl_ts)) { | 2255 | if (!bnxt_get_rx_ts_p5(bp, &ts, cmpl_ts)) { |
| 2256 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; | 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 | ns = timecounter_cyc2time(&ptp->tc, ts); | 2260 | ns = timecounter_cyc2time(&ptp->tc, ts); |
| 2260 | spin_unlock_bh(&ptp->ptp_lock); | 2261 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 2261 | memset(skb_hwtstamps(skb), 0, | 2262 | memset(skb_hwtstamps(skb), 0, |
| 2262 | sizeof(*skb_hwtstamps(skb))); | 2263 | sizeof(*skb_hwtstamps(skb))); |
| 2263 | skb_hwtstamps(skb)->hwtstamp = ns_to_ktime(ns); | 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 | case ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_FLAGS_PHC_RTC_UPDATE: | 2758 | case ASYNC_EVENT_CMPL_PHC_UPDATE_EVENT_DATA1_FLAGS_PHC_RTC_UPDATE: |
| 2758 | if (BNXT_PTP_USE_RTC(bp)) { | 2759 | if (BNXT_PTP_USE_RTC(bp)) { |
| 2759 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; | 2760 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; |
| 2761 | unsigned long flags; | ||
| 2760 | u64 ns; | 2762 | u64 ns; |
| 2761 | 2763 | ||
| 2762 | if (!ptp) | 2764 | if (!ptp) |
| 2763 | goto async_event_process_exit; | 2765 | goto async_event_process_exit; |
| 2764 | 2766 | ||
| 2765 | spin_lock_bh(&ptp->ptp_lock); | 2767 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 2766 | bnxt_ptp_update_current_time(bp); | 2768 | bnxt_ptp_update_current_time(bp); |
| 2767 | ns = (((u64)BNXT_EVENT_PHC_RTC_UPDATE(data1) << | 2769 | ns = (((u64)BNXT_EVENT_PHC_RTC_UPDATE(data1) << |
| 2768 | BNXT_PHC_BITS) | ptp->current_time); | 2770 | BNXT_PHC_BITS) | ptp->current_time); |
| 2769 | bnxt_ptp_rtc_timecounter_init(ptp, ns); | 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 | break; | 2774 | break; |
| 2773 | } | 2775 | } |
| @@ -13494,9 +13496,11 @@ static void bnxt_force_fw_reset(struct bnxt *bp) · 10720 unmodified lines | |||
| 13494 | return; | 13496 | return; |
| 13495 | 13497 | ||
| 13496 | if (ptp) { | 13498 | if (ptp) { |
| 13497 | spin_lock_bh(&ptp->ptp_lock); | 13499 | unsigned long flags; |
| 13500 | |||
| 13501 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ||
| 13498 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); | 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 | } else { | 13504 | } else { |
| 13501 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); | 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 | int n = 0, tmo; | 13565 | int n = 0, tmo; |
| 13562 | 13566 | ||
| 13563 | if (ptp) { | 13567 | if (ptp) { |
| 13564 | spin_lock_bh(&ptp->ptp_lock); | 13568 | unsigned long flags; |
| 13569 | |||
| 13570 | spin_lock_irqsave(&ptp->ptp_lock, flags); | ||
| 13565 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); | 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 | } else { | 13573 | } else { |
| 13568 | set_bit(BNXT_STATE_IN_FW_RESET, &bp->state); | 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 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, | 62 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 63 | ptp_info); | 63 | ptp_info); |
| 64 | u64 ns = timespec64_to_ns(ts); | 64 | u64 ns = timespec64_to_ns(ts); |
| 65 | unsigned long flags; | ||
| 65 | 66 | ||
| 66 | if (BNXT_PTP_USE_RTC(ptp->bp)) | 67 | if (BNXT_PTP_USE_RTC(ptp->bp)) |
| 67 | return bnxt_ptp_cfg_settime(ptp->bp, ns); | 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 | timecounter_init(&ptp->tc, &ptp->cc, ns); | 71 | timecounter_init(&ptp->tc, &ptp->cc, ns); |
| 71 | spin_unlock_bh(&ptp->ptp_lock); | 72 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 72 | return 0; | 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 | static void bnxt_ptp_get_current_time(struct bnxt *bp) | 101 | static void bnxt_ptp_get_current_time(struct bnxt *bp) |
| 101 | { | 102 | { |
| 102 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; | 103 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; |
| 104 | unsigned long flags; | ||
| 103 | 105 | ||
| 104 | if (!ptp) | 106 | if (!ptp) |
| 105 | return; | 107 | return; |
| 106 | spin_lock_bh(&ptp->ptp_lock); | 108 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 107 | WRITE_ONCE(ptp->old_time, ptp->current_time); | 109 | WRITE_ONCE(ptp->old_time, ptp->current_time); |
| 108 | bnxt_refclk_read(bp, NULL, &ptp->current_time); | 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 | static int bnxt_hwrm_port_ts_query(struct bnxt *bp, u32 flags, u64 *ts, | 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 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, | 152 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 151 | ptp_info); | 153 | ptp_info); |
| 154 | unsigned long flags; | ||
| 152 | u64 ns, cycles; | 155 | u64 ns, cycles; |
| 153 | int rc; | 156 | int rc; |
| 154 | 157 | ||
| 155 | spin_lock_bh(&ptp->ptp_lock); | 158 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 156 | rc = bnxt_refclk_read(ptp->bp, sts, &cycles); | 159 | rc = bnxt_refclk_read(ptp->bp, sts, &cycles); |
| 157 | if (rc) { | 160 | if (rc) { |
| 158 | spin_unlock_bh(&ptp->ptp_lock); | 161 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 159 | return rc; | 162 | return rc; |
| 160 | } | 163 | } |
| 161 | ns = timecounter_cyc2time(&ptp->tc, cycles); | 164 | ns = timecounter_cyc2time(&ptp->tc, cycles); |
| 162 | spin_unlock_bh(&ptp->ptp_lock); | 165 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 163 | *ts = ns_to_timespec64(ns); | 166 | *ts = ns_to_timespec64(ns); |
| 164 | 167 | ||
| 165 | return 0; | 168 | return 0; |
| @@ -177,6 +180,7 @@ void bnxt_ptp_update_current_time(struct bnxt *bp) · 11 unmodified lines | |||
| 177 | static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta) | 180 | static int bnxt_ptp_adjphc(struct bnxt_ptp_cfg *ptp, s64 delta) |
| 178 | { | 181 | { |
| 179 | struct hwrm_port_mac_cfg_input *req; | 182 | struct hwrm_port_mac_cfg_input *req; |
| 183 | unsigned long flags; | ||
| 180 | int rc; | 184 | int rc; |
| 181 | 185 | ||
| 182 | rc = hwrm_req_init(ptp->bp, req, HWRM_PORT_MAC_CFG); | 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 | if (rc) { | 194 | if (rc) { |
| 191 | netdev_err(ptp->bp->dev, "ptp adjphc failed. rc = %x\n", rc); | 195 | netdev_err(ptp->bp->dev, "ptp adjphc failed. rc = %x\n", rc); |
| 192 | } else { | 196 | } else { |
| 193 | spin_lock_bh(&ptp->ptp_lock); | 197 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 194 | bnxt_ptp_update_current_time(ptp->bp); | 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 | return rc; | 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 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, | 207 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 204 | ptp_info); | 208 | ptp_info); |
| 209 | unsigned long flags; | ||
| 205 | 210 | ||
| 206 | if (BNXT_PTP_USE_RTC(ptp->bp)) | 211 | if (BNXT_PTP_USE_RTC(ptp->bp)) |
| 207 | return bnxt_ptp_adjphc(ptp, delta); | 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 | timecounter_adjtime(&ptp->tc, delta); | 215 | timecounter_adjtime(&ptp->tc, delta); |
| 211 | spin_unlock_bh(&ptp->ptp_lock); | 216 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 212 | return 0; | 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 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, | 241 | struct bnxt_ptp_cfg *ptp = container_of(ptp_info, struct bnxt_ptp_cfg, |
| 237 | ptp_info); | 242 | ptp_info); |
| 238 | struct bnxt *bp = ptp->bp; | 243 | struct bnxt *bp = ptp->bp; |
| 244 | unsigned long flags; | ||
| 239 | 245 | ||
| 240 | if (!BNXT_MH(bp)) | 246 | if (!BNXT_MH(bp)) |
| 241 | return bnxt_ptp_adjfine_rtc(bp, scaled_ppm); | 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 | timecounter_read(&ptp->tc); | 250 | timecounter_read(&ptp->tc); |
| 245 | ptp->cc.mult = adjust_by_scaled_ppm(ptp->cmult, scaled_ppm); | 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 | return 0; | 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 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; | 258 | struct bnxt_ptp_cfg *ptp = bp->ptp_cfg; |
| 253 | struct ptp_clock_event event; | 259 | struct ptp_clock_event event; |
| 260 | unsigned long flags; | ||
| 254 | u64 ns, pps_ts; | 261 | u64 ns, pps_ts; |
| 255 | 262 | ||
| 256 | pps_ts = EVENT_PPS_TS(data2, data1); | 263 | pps_ts = EVENT_PPS_TS(data2, data1); |
| 257 | spin_lock_bh(&ptp->ptp_lock); | 264 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 258 | ns = timecounter_cyc2time(&ptp->tc, pps_ts); | 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 | switch (EVENT_DATA2_PPS_EVENT_TYPE(data2)) { | 268 | switch (EVENT_DATA2_PPS_EVENT_TYPE(data2)) { |
| 262 | case ASYNC_EVENT_CMPL_PPS_TIMESTAMP_EVENT_DATA2_EVENT_TYPE_INTERNAL: | 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 | u64 cycles_now; | 401 | u64 cycles_now; |
| 395 | u64 nsec_now, nsec_delta; | 402 | u64 nsec_now, nsec_delta; |
| 403 | unsigned long flags; | ||
| 396 | int rc; | 404 | int rc; |
| 397 | 405 | ||
| 398 | spin_lock_bh(&ptp->ptp_lock); | 406 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 399 | rc = bnxt_refclk_read(ptp->bp, NULL, &cycles_now); | 407 | rc = bnxt_refclk_read(ptp->bp, NULL, &cycles_now); |
| 400 | if (rc) { | 408 | if (rc) { |
| 401 | spin_unlock_bh(&ptp->ptp_lock); | 409 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 402 | return rc; | 410 | return rc; |
| 403 | } | 411 | } |
| 404 | nsec_now = timecounter_cyc2time(&ptp->tc, cycles_now); | 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 | nsec_delta = target_ns - nsec_now; | 415 | nsec_delta = target_ns - nsec_now; |
| 408 | *cycles_delta = div64_u64(nsec_delta << ptp->cc.shift, ptp->cc.mult); | 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 | struct skb_shared_hwtstamps timestamp; | 697 | struct skb_shared_hwtstamps timestamp; |
| 690 | struct bnxt_ptp_tx_req *txts_req; | 698 | struct bnxt_ptp_tx_req *txts_req; |
| 691 | unsigned long now = jiffies; | 699 | unsigned long now = jiffies; |
| 700 | unsigned long flags; | ||
| 692 | u64 ts = 0, ns = 0; | 701 | u64 ts = 0, ns = 0; |
| 693 | u32 tmo = 0; | 702 | u32 tmo = 0; |
| 694 | int rc; | 703 | int rc; |
| @@ -702,9 +711,9 @@ static int bnxt_stamp_tx_skb(struct bnxt *bp, int slot) · 7 unmodified lines | |||
| 702 | tmo, slot); | 711 | tmo, slot); |
| 703 | if (!rc) { | 712 | if (!rc) { |
| 704 | memset(×tamp, 0, sizeof(timestamp)); | 713 | memset(×tamp, 0, sizeof(timestamp)); |
| 705 | spin_lock_bh(&ptp->ptp_lock); | 714 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 706 | ns = timecounter_cyc2time(&ptp->tc, ts); | 715 | ns = timecounter_cyc2time(&ptp->tc, ts); |
| 707 | spin_unlock_bh(&ptp->ptp_lock); | 716 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 708 | timestamp.hwtstamp = ns_to_ktime(ns); | 717 | timestamp.hwtstamp = ns_to_ktime(ns); |
| 709 | skb_tstamp_tx(txts_req->tx_skb, ×tamp); | 718 | skb_tstamp_tx(txts_req->tx_skb, ×tamp); |
| 710 | ptp->stats.ts_pkts++; | 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 | unsigned long now = jiffies; | 739 | unsigned long now = jiffies; |
| 731 | struct bnxt *bp = ptp->bp; | 740 | struct bnxt *bp = ptp->bp; |
| 732 | u16 cons = ptp->txts_cons; | 741 | u16 cons = ptp->txts_cons; |
| 742 | unsigned long flags; | ||
| 733 | u32 num_requests; | 743 | u32 num_requests; |
| 734 | int rc = 0; | 744 | int rc = 0; |
| 735 | 745 | ||
| @@ -757,9 +767,9 @@ next_slot: · 21 unmodified lines | |||
| 757 | bnxt_ptp_get_current_time(bp); | 767 | bnxt_ptp_get_current_time(bp); |
| 758 | ptp->next_period = now + HZ; | 768 | ptp->next_period = now + HZ; |
| 759 | if (time_after_eq(now, ptp->next_overflow_check)) { | 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 | timecounter_read(&ptp->tc); | 771 | timecounter_read(&ptp->tc); |
| 762 | spin_unlock_bh(&ptp->ptp_lock); | 772 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 763 | ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD; | 773 | ptp->next_overflow_check = now + BNXT_PHC_OVERFLOW_PERIOD; |
| 764 | } | 774 | } |
| 765 | if (rc == -EAGAIN) | 775 | if (rc == -EAGAIN) |
| @@ -819,6 +829,7 @@ void bnxt_tx_ts_cmp(struct bnxt *bp, struct bnxt_napi *bnapi, · 53 unmodified lines | |||
| 819 | u32 opaque = tscmp->tx_ts_cmp_opaque; | 829 | u32 opaque = tscmp->tx_ts_cmp_opaque; |
| 820 | struct bnxt_tx_ring_info *txr; | 830 | struct bnxt_tx_ring_info *txr; |
| 821 | struct bnxt_sw_tx_bd *tx_buf; | 831 | struct bnxt_sw_tx_bd *tx_buf; |
| 832 | unsigned long flags; | ||
| 822 | u64 ts, ns; | 833 | u64 ts, ns; |
| 823 | u16 cons; | 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 | le32_to_cpu(tscmp->tx_ts_cmp_flags_type), | 844 | le32_to_cpu(tscmp->tx_ts_cmp_flags_type), |
| 834 | le32_to_cpu(tscmp->tx_ts_cmp_errors_v)); | 845 | le32_to_cpu(tscmp->tx_ts_cmp_errors_v)); |
| 835 | } else { | 846 | } else { |
| 836 | spin_lock_bh(&ptp->ptp_lock); | 847 | spin_lock_irqsave(&ptp->ptp_lock, flags); |
| 837 | ns = timecounter_cyc2time(&ptp->tc, ts); | 848 | ns = timecounter_cyc2time(&ptp->tc, ts); |
| 838 | spin_unlock_bh(&ptp->ptp_lock); | 849 | spin_unlock_irqrestore(&ptp->ptp_lock, flags); |
| 839 | timestamp.hwtstamp = ns_to_ktime(ns); | 850 | timestamp.hwtstamp = ns_to_ktime(ns); |
| 840 | skb_tstamp_tx(tx_buf->skb, ×tamp); | 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 | int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg) | 986 | int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg) |
| 976 | { | 987 | { |
| 977 | struct timespec64 tsp; | 988 | struct timespec64 tsp; |
| 989 | unsigned long flags; | ||
| 978 | u64 ns; | 990 | u64 ns; |
| 979 | int rc; | 991 | int rc; |
| 980 | 992 | ||
| @@ -993,9 +1005,9 @@ int bnxt_ptp_init_rtc(struct bnxt *bp, bool phc_cfg) · 12 unmodified lines | |||
| 993 | if (rc) | 1005 | if (rc) |
| 994 | return rc; | 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 | bnxt_ptp_rtc_timecounter_init(bp->ptp_cfg, ns); | 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 | return 0; | 1012 | return 0; |
| 1001 | } | 1013 | } |
| @@ -1063,10 +1075,12 @@ int bnxt_ptp_init(struct bnxt *bp, bool phc_cfg) · 61 unmodified lines | |||
| 1063 | atomic64_set(&ptp->stats.ts_err, 0); | 1075 | atomic64_set(&ptp->stats.ts_err, 0); |
| 1064 | 1076 | ||
| 1065 | if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) { | 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 | bnxt_refclk_read(bp, NULL, &ptp->current_time); | 1081 | bnxt_refclk_read(bp, NULL, &ptp->current_time); |
| 1068 | WRITE_ONCE(ptp->old_time, ptp->current_time); | 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 | ptp_schedule_worker(ptp->ptp_clock, 0); | 1084 | ptp_schedule_worker(ptp->ptp_clock, 0); |
| 1071 | } | 1085 | } |
| 1072 | ptp->txts_tmo = BNXT_PTP_DFLT_TX_TMO; | 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 | #if BITS_PER_LONG == 32 | 148 | #if BITS_PER_LONG == 32 |
| 149 | #define BNXT_READ_TIME64(ptp, dst, src) \ | 149 | #define BNXT_READ_TIME64(ptp, dst, src) \ |
| 150 | do { \ | 150 | do { \ |
| 151 | spin_lock_bh(&(ptp)->ptp_lock); \ | 151 | unsigned long flags; \ |
| 152 | (dst) = (src); \ | 152 | \ |
| 153 | spin_unlock_bh(&(ptp)->ptp_lock); \ | 153 | spin_lock_irqsave(&(ptp)->ptp_lock, flags); \ |
| 154 | (dst) = (src); \ | ||
| 155 | spin_unlock_irqrestore(&(ptp)->ptp_lock, flags); \ | ||
| 154 | } while (0) | 156 | } while (0) |
| 155 | #else | 157 | #else |
| 156 | #define BNXT_READ_TIME64(ptp, dst, src) \ | 158 | #define BNXT_READ_TIME64(ptp, dst, src) \ |
| @@ -930,9 +930,6 @@ static int macb_mdiobus_register(struct macb *bp) · 929 unmodified lines | |||
| 930 | return ret; | 930 | return ret; |
| 931 | } | 931 | } |
| 932 | 932 | ||
| 933 | if (of_phy_is_fixed_link(np)) | ||
| 934 | return mdiobus_register(bp->mii_bus); | ||
| 935 | |||
| 936 | /* Only create the PHY from the device tree if at least one PHY is | 933 | /* Only create the PHY from the device tree if at least one PHY is |
| 937 | * described. Otherwise scan the entire MDIO bus. We do this to support | 934 | * described. Otherwise scan the entire MDIO bus. We do this to support |
| 938 | * old device tree that did not follow the best practices and did not | 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 | static int macb_mii_init(struct macb *bp) | 951 | static int macb_mii_init(struct macb *bp) |
| 955 | { | 952 | { |
| 953 | struct device_node *child, *np = bp->pdev->dev.of_node; | ||
| 956 | int err = -ENXIO; | 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 | /* Enable management port */ | 966 | /* Enable management port */ |
| 959 | macb_writel(bp, NCR, MACB_BIT(MPE)); | 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 | be_get_wrb_params_from_skb(adapter, skb, &wrb_params); | 1381 | be_get_wrb_params_from_skb(adapter, skb, &wrb_params); |
| 1382 | 1382 | ||
| 1383 | wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); | 1383 | wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); |
| 1384 | if (unlikely(!wrb_cnt)) { | 1384 | if (unlikely(!wrb_cnt)) |
| 1385 | dev_kfree_skb_any(skb); | 1385 | goto drop_skb; |
| 1386 | goto drop; | ||
| 1387 | } | ||
| 1388 | 1386 | ||
| 1389 | /* if os2bmc is enabled and if the pkt is destined to bmc, | 1387 | /* if os2bmc is enabled and if the pkt is destined to bmc, |
| 1390 | * enqueue the pkt a 2nd time with mgmt bit set. | 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 | BE_WRB_F_SET(wrb_params.features, OS2BMC, 1); | 1391 | BE_WRB_F_SET(wrb_params.features, OS2BMC, 1); |
| 1394 | wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); | 1392 | wrb_cnt = be_xmit_enqueue(adapter, txo, skb, &wrb_params); |
| 1395 | if (unlikely(!wrb_cnt)) | 1393 | if (unlikely(!wrb_cnt)) |
| 1396 | goto drop; | 1394 | goto drop_skb; |
| 1397 | else | 1395 | else |
| 1398 | skb_get(skb); | 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 | be_xmit_flush(adapter, txo); | 1405 | be_xmit_flush(adapter, txo); |
| 1408 | 1406 | ||
| 1409 | return NETDEV_TX_OK; | 1407 | return NETDEV_TX_OK; |
| 1408 | drop_skb: | ||
| 1409 | dev_kfree_skb_any(skb); | ||
| 1410 | drop: | 1410 | drop: |
| 1411 | tx_stats(txo)->tx_drv_drops++; | 1411 | tx_stats(txo)->tx_drv_drops++; |
| 1412 | /* Flush the already enqueued tx requests */ | 1412 | /* Flush the already enqueued tx requests */ |
| @@ -1906,7 +1906,12 @@ static int ftgmac100_probe(struct platform_device *pdev) · 1905 unmodified lines | |||
| 1906 | goto err_phy_connect; | 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 | err = phy_connect_direct(netdev, phydev, ftgmac100_adjust_link, | 1915 | err = phy_connect_direct(netdev, phydev, ftgmac100_adjust_link, |
| 1911 | PHY_INTERFACE_MODE_MII); | 1916 | PHY_INTERFACE_MODE_MII); |
| 1912 | if (err) { | 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 | if (unlikely(tx_frm_cnt && netif_carrier_ok(ndev) && | 903 | if (unlikely(tx_frm_cnt && netif_carrier_ok(ndev) && |
| 904 | __netif_subqueue_stopped(ndev, tx_ring->index) && | 904 | __netif_subqueue_stopped(ndev, tx_ring->index) && |
| 905 | !test_bit(ENETC_TX_DOWN, &priv->flags) && | ||
| 905 | (enetc_bd_unused(tx_ring) >= ENETC_TXBDS_MAX_NEEDED))) { | 906 | (enetc_bd_unused(tx_ring) >= ENETC_TXBDS_MAX_NEEDED))) { |
| 906 | netif_wake_subqueue(ndev, tx_ring->index); | 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 | int xdp_tx_bd_cnt, i, k; | 1378 | int xdp_tx_bd_cnt, i, k; |
| 1378 | int xdp_tx_frm_cnt = 0; | 1379 | int xdp_tx_frm_cnt = 0; |
| 1379 | 1380 | ||
| 1381 | if (unlikely(test_bit(ENETC_TX_DOWN, &priv->flags))) | ||
| 1382 | return -ENETDOWN; | ||
| 1383 | |||
| 1380 | enetc_lock_mdio(); | 1384 | enetc_lock_mdio(); |
| 1381 | 1385 | ||
| 1382 | tx_ring = priv->xdp_tx_ring[smp_processor_id()]; | 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 | &rx_ring->rx_swbd[rx_ring_first]); | 1525 | &rx_ring->rx_swbd[rx_ring_first]); |
| 1522 | enetc_bdr_idx_inc(rx_ring, &rx_ring_first); | 1526 | enetc_bdr_idx_inc(rx_ring, &rx_ring_first); |
| 1523 | } | 1527 | } |
| 1524 | rx_ring->stats.xdp_drops++; | ||
| 1525 | } | 1528 | } |
| 1526 | 1529 | ||
| 1527 | static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, | 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 | fallthrough; | 1589 | fallthrough; |
| 1587 | case XDP_DROP: | 1590 | case XDP_DROP: |
| 1588 | enetc_xdp_drop(rx_ring, orig_i, i); | 1591 | enetc_xdp_drop(rx_ring, orig_i, i); |
| 1592 | rx_ring->stats.xdp_drops++; | ||
| 1589 | break; | 1593 | break; |
| 1590 | case XDP_PASS: | 1594 | case XDP_PASS: |
| 1591 | rxbd = orig_rxbd; | 1595 | rxbd = orig_rxbd; |
| @@ -1602,6 +1606,12 @@ static int enetc_clean_rx_ring_xdp(struct enetc_bdr *rx_ring, · 10 unmodified lines | |||
| 1602 | break; | 1606 | break; |
| 1603 | case XDP_TX: | 1607 | case XDP_TX: |
| 1604 | tx_ring = priv->xdp_tx_ring[rx_ring->index]; | 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 | xdp_tx_bd_cnt = enetc_rx_swbd_to_xdp_tx_swbd(xdp_tx_arr, | 1615 | xdp_tx_bd_cnt = enetc_rx_swbd_to_xdp_tx_swbd(xdp_tx_arr, |
| 1606 | rx_ring, | 1616 | rx_ring, |
| 1607 | orig_i, i); | 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 | enetc_rxbdr_wr(hw, idx, ENETC_RBMR, rbmr); | 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 | struct enetc_hw *hw = &priv->si->hw; | 2238 | struct enetc_hw *hw = &priv->si->hw; |
| 2229 | int i; | 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 | for (i = 0; i < priv->num_rx_rings; i++) | 2241 | for (i = 0; i < priv->num_rx_rings; i++) |
| 2235 | enetc_enable_rxbdr(hw, priv->rx_ring[i]); | 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 | static void enetc_disable_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) | 2254 | static void enetc_disable_rxbdr(struct enetc_hw *hw, struct enetc_bdr *rx_ring) |
| 2239 | { | 2255 | { |
| 2240 | int idx = rx_ring->index; | 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 | enetc_txbdr_wr(hw, idx, ENETC_TBMR, 0); | 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 | struct enetc_hw *hw = &priv->si->hw; | 2272 | struct enetc_hw *hw = &priv->si->hw; |
| 2257 | int i; | 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 | for (i = 0; i < priv->num_rx_rings; i++) | 2275 | for (i = 0; i < priv->num_rx_rings; i++) |
| 2263 | enetc_disable_rxbdr(hw, priv->rx_ring[i]); | 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 | static void enetc_wait_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring) | 2288 | static void enetc_wait_txbdr(struct enetc_hw *hw, struct enetc_bdr *tx_ring) |
| 2267 | { | 2289 | { |
| 2268 | int delay = 8, timeout = 100; | 2290 | int delay = 8, timeout = 100; |
| @@ -2460,9 +2482,13 @@ void enetc_start(struct net_device *ndev) · 191 unmodified lines | |||
| 2460 | enable_irq(irq); | 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 | netif_tx_start_all_queues(ndev); | 2489 | netif_tx_start_all_queues(ndev); |
| 2490 | |||
| 2491 | clear_bit(ENETC_TX_DOWN, &priv->flags); | ||
| 2466 | } | 2492 | } |
| 2467 | EXPORT_SYMBOL_GPL(enetc_start); | 2493 | EXPORT_SYMBOL_GPL(enetc_start); |
| 2468 | 2494 | ||
| @@ -2520,9 +2546,15 @@ void enetc_stop(struct net_device *ndev) · 51 unmodified lines | |||
| 2520 | struct enetc_ndev_priv *priv = netdev_priv(ndev); | 2546 | struct enetc_ndev_priv *priv = netdev_priv(ndev); |
| 2521 | int i; | 2547 | int i; |
| 2522 | 2548 | ||
| 2549 | set_bit(ENETC_TX_DOWN, &priv->flags); | ||
| 2550 | |||
| 2523 | netif_tx_stop_all_queues(ndev); | 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 | for (i = 0; i < priv->bdr_int_num; i++) { | 2559 | for (i = 0; i < priv->bdr_int_num; i++) { |
| 2528 | int irq = pci_irq_vector(priv->si->pdev, | 2560 | int irq = pci_irq_vector(priv->si->pdev, |
| @@ -2533,8 +2565,6 @@ void enetc_stop(struct net_device *ndev) · 4 unmodified lines | |||
| 2533 | napi_disable(&priv->int_vector[i]->napi); | 2565 | napi_disable(&priv->int_vector[i]->napi); |
| 2534 | } | 2566 | } |
| 2535 | 2567 | ||
| 2536 | enetc_wait_bdrs(priv); | ||
| 2537 | |||
| 2538 | enetc_clear_interrupts(priv); | 2568 | enetc_clear_interrupts(priv); |
| 2539 | } | 2569 | } |
| 2540 | EXPORT_SYMBOL_GPL(enetc_stop); | 2570 | EXPORT_SYMBOL_GPL(enetc_stop); |
| @@ -325,6 +325,7 @@ enum enetc_active_offloads { · 324 unmodified lines | |||
| 325 | 325 | ||
| 326 | enum enetc_flags_bit { | 326 | enum enetc_flags_bit { |
| 327 | ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS = 0, | 327 | ENETC_TX_ONESTEP_TSTAMP_IN_PROGRESS = 0, |
| 328 | ENETC_TX_DOWN, | ||
| 328 | }; | 329 | }; |
| 329 | 330 | ||
| 330 | /* interrupt coalescing modes */ | 331 | /* interrupt coalescing modes */ |
| @@ -1077,7 +1077,8 @@ fec_restart(struct net_device *ndev) · 1076 unmodified lines | |||
| 1077 | u32 rcntl = OPT_FRAME_SIZE | 0x04; | 1077 | u32 rcntl = OPT_FRAME_SIZE | 0x04; |
| 1078 | u32 ecntl = FEC_ECR_ETHEREN; | 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 | /* Whack a reset. We should wait for this. | 1083 | /* Whack a reset. We should wait for this. |
| 1083 | * For i.MX6SX SOC, enet use AXI bus, we use disable MAC | 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 | netdev_err(ndev, "Graceful transmit stop did not complete!\n"); | 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 | /* Whack a reset. We should wait for this. | 1347 | /* Whack a reset. We should wait for this. |
| 1346 | * For i.MX6SX SOC, enet use AXI bus, we use disable MAC | 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 | err = -EINVAL; | 197 | err = -EINVAL; |
| 198 | goto _return_of_node_put; | 198 | goto _return_of_node_put; |
| 199 | } | 199 | } |
| 200 | mac_dev->fman_dev = &of_dev->dev; | ||
| 200 | 201 | ||
| 201 | /* Get the FMan cell-index */ | 202 | /* Get the FMan cell-index */ |
| 202 | err = of_property_read_u32(dev_node, "cell-index", &val); | 203 | err = of_property_read_u32(dev_node, "cell-index", &val); |
| 203 | if (err) { | 204 | if (err) { |
| 204 | dev_err(dev, "failed to read cell-index for %pOF\n", dev_node); | 205 | dev_err(dev, "failed to read cell-index for %pOF\n", dev_node); |
| 205 | err = -EINVAL; | 206 | err = -EINVAL; |
| 206 | goto _return_of_node_put; | 207 | goto _return_dev_put; |
| 207 | } | 208 | } |
| 208 | /* cell-index 0 => FMan id 1 */ | 209 | /* cell-index 0 => FMan id 1 */ |
| 209 | fman_id = (u8)(val + 1); | 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 | if (!priv->fman) { | 213 | if (!priv->fman) { |
| 213 | dev_err(dev, "fman_bind(%pOF) failed\n", dev_node); | 214 | dev_err(dev, "fman_bind(%pOF) failed\n", dev_node); |
| 214 | err = -ENODEV; | 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 | of_node_put(dev_node); | 224 | of_node_put(dev_node); |
| 225 | dev_node = NULL; | ||
| 219 | 226 | ||
| 220 | /* Get the address of the memory mapped registers */ | 227 | /* Get the address of the memory mapped registers */ |
| 221 | mac_dev->res = platform_get_mem_or_io(_of_dev, 0); | 228 | mac_dev->res = platform_get_mem_or_io(_of_dev, 0); |
| 222 | if (!mac_dev->res) { | 229 | if (!mac_dev->res) { |
| 223 | dev_err(dev, "could not get registers\n"); | 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 | err = devm_request_resource(dev, fman_get_mem_region(priv->fman), | 235 | err = devm_request_resource(dev, fman_get_mem_region(priv->fman), |
| 228 | mac_dev->res); | 236 | mac_dev->res); |
| 229 | if (err) { | 237 | if (err) { |
| 230 | dev_err_probe(dev, err, "could not request resource\n"); | 238 | dev_err_probe(dev, err, "could not request resource\n"); |
| 231 | return err; | 239 | goto _return_dev_put; |
| 232 | } | 240 | } |
| 233 | 241 | ||
| 234 | mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start, | 242 | mac_dev->vaddr = devm_ioremap(dev, mac_dev->res->start, |
| 235 | resource_size(mac_dev->res)); | 243 | resource_size(mac_dev->res)); |
| 236 | if (!mac_dev->vaddr) { | 244 | if (!mac_dev->vaddr) { |
| 237 | dev_err(dev, "devm_ioremap() failed\n"); | 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)) | 250 | if (!of_device_is_available(mac_node)) { |
| 242 | return -ENODEV; | 251 | err = -ENODEV; |
| 252 | goto _return_dev_put; | ||
| 253 | } | ||
| 243 | 254 | ||
| 244 | /* Get the cell-index */ | 255 | /* Get the cell-index */ |
| 245 | err = of_property_read_u32(mac_node, "cell-index", &val); | 256 | err = of_property_read_u32(mac_node, "cell-index", &val); |
| 246 | if (err) { | 257 | if (err) { |
| 247 | dev_err(dev, "failed to read cell-index for %pOF\n", mac_node); | 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 | priv->cell_index = (u8)val; | 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 | if (unlikely(nph < 0)) { | 271 | if (unlikely(nph < 0)) { |
| 260 | dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n", | 272 | dev_err(dev, "of_count_phandle_with_args(%pOF, fsl,fman-ports) failed\n", |
| 261 | mac_node); | 273 | mac_node); |
| 262 | return nph; | 274 | err = nph; |
| 275 | goto _return_dev_put; | ||
| 263 | } | 276 | } |
| 264 | 277 | ||
| 265 | if (nph != ARRAY_SIZE(mac_dev->port)) { | 278 | if (nph != ARRAY_SIZE(mac_dev->port)) { |
| 266 | dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n", | 279 | dev_err(dev, "Not supported number of fman-ports handles of mac node %pOF from device tree\n", |
| 267 | mac_node); | 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 | /* Find the port node */ | 287 | /* Find the port node */ |
| 273 | dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i); | 288 | dev_node = of_parse_phandle(mac_node, "fsl,fman-ports", i); |
| 274 | if (!dev_node) { | 289 | if (!dev_node) { |
| 275 | dev_err(dev, "of_parse_phandle(%pOF, fsl,fman-ports) failed\n", | 290 | dev_err(dev, "of_parse_phandle(%pOF, fsl,fman-ports) failed\n", |
| 276 | mac_node); | 291 | mac_node); |
| 277 | return -EINVAL; | 292 | err = -EINVAL; |
| 293 | goto _return_dev_arr_put; | ||
| 278 | } | 294 | } |
| 279 | 295 | ||
| 280 | of_dev = of_find_device_by_node(dev_node); | 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 | dev_err(dev, "of_find_device_by_node(%pOF) failed\n", | 298 | dev_err(dev, "of_find_device_by_node(%pOF) failed\n", |
| 283 | dev_node); | 299 | dev_node); |
| 284 | err = -EINVAL; | 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 | if (!mac_dev->port[i]) { | 306 | if (!mac_dev->port[i]) { |
| 290 | dev_err(dev, "dev_get_drvdata(%pOF) failed\n", | 307 | dev_err(dev, "dev_get_drvdata(%pOF) failed\n", |
| 291 | dev_node); | 308 | dev_node); |
| 292 | err = -EINVAL; | 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 | of_node_put(dev_node); | 317 | of_node_put(dev_node); |
| 318 | dev_node = NULL; | ||
| 296 | } | 319 | } |
| 297 | 320 | ||
| 298 | /* Get the PHY connection type */ | 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 | err = init(mac_dev, mac_node, ¶ms); | 336 | err = init(mac_dev, mac_node, ¶ms); |
| 314 | if (err < 0) | 337 | if (err < 0) |
| 315 | return err; | 338 | goto _return_dev_arr_put; |
| 316 | 339 | ||
| 317 | if (!is_zero_ether_addr(mac_dev->addr)) | 340 | if (!is_zero_ether_addr(mac_dev->addr)) |
| 318 | dev_info(dev, "FMan MAC address: %pM\n", mac_dev->addr); | 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 | return err; | 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 | _return_of_node_put: | 359 | _return_of_node_put: |
| 331 | of_node_put(dev_node); | 360 | of_node_put(dev_node); |
| 332 | return err; | 361 | return err; |
| @@ -335,6 +364,11 @@ _return_of_node_put: · 2 unmodified lines | |||
| 335 | static void mac_remove(struct platform_device *pdev) | 364 | static void mac_remove(struct platform_device *pdev) |
| 336 | { | 365 | { |
| 337 | struct mac_device *mac_dev = platform_get_drvdata(pdev); | 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 | platform_device_unregister(mac_dev->priv->eth_dev); | 373 | platform_device_unregister(mac_dev->priv->eth_dev); |
| 340 | } | 374 | } |
| @@ -19,12 +19,13 @@ · 18 unmodified lines | |||
| 19 | struct fman_mac; | 19 | struct fman_mac; |
| 20 | struct mac_priv_s; | 20 | struct mac_priv_s; |
| 21 | 21 | ||
| 22 | #define PORT_NUM 2 | ||
| 22 | struct mac_device { | 23 | struct mac_device { |
| 23 | void __iomem *vaddr; | 24 | void __iomem *vaddr; |
| 24 | struct device *dev; | 25 | struct device *dev; |
| 25 | struct resource *res; | 26 | struct resource *res; |
| 26 | u8 addr[ETH_ALEN]; | 27 | u8 addr[ETH_ALEN]; |
| 27 | struct fman_port *port[2]; | 28 | struct fman_port *port[PORT_NUM]; |
| 28 | struct phylink *phylink; | 29 | struct phylink *phylink; |
| 29 | struct phylink_config phylink_config; | 30 | struct phylink_config phylink_config; |
| 30 | phy_interface_t phy_if; | 31 | phy_interface_t phy_if; |
| @@ -52,6 +53,9 @@ struct mac_device { · 21 unmodified lines | |||
| 52 | 53 | ||
| 53 | struct fman_mac *fman_mac; | 54 | struct fman_mac *fman_mac; |
| 54 | struct mac_priv_s *priv; | 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 | static inline struct mac_device | 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 | /* save the buffer addr until the last read operation */ | 1294 | /* save the buffer addr until the last read operation */ |
| 1295 | *save_buf = read_buf; | 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 | ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd, | 1300 | ret = hns3_dbg_read_cmd(dbg_data, hns3_dbg_cmd[index].cmd, |
| 1299 | read_buf, hns3_dbg_cmd[index].buf_len); | 1301 | read_buf, hns3_dbg_cmd[index].buf_len); |
| 1300 | if (ret) | 1302 | if (ret) |
| @@ -11,6 +11,7 @@ · 10 unmodified lines | |||
| 11 | #include <linux/irq.h> | 11 | #include <linux/irq.h> |
| 12 | #include <linux/ip.h> | 12 | #include <linux/ip.h> |
| 13 | #include <linux/ipv6.h> | 13 | #include <linux/ipv6.h> |
| 14 | #include <linux/iommu.h> | ||
| 14 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 15 | #include <linux/pci.h> | 16 | #include <linux/pci.h> |
| 16 | #include <linux/skbuff.h> | 17 | #include <linux/skbuff.h> |
| @@ -380,6 +381,24 @@ static const struct hns3_rx_ptype hns3_rx_ptype_tbl[] = { · 363 unmodified lines | |||
| 380 | #define HNS3_INVALID_PTYPE \ | 381 | #define HNS3_INVALID_PTYPE \ |
| 381 | ARRAY_SIZE(hns3_rx_ptype_tbl) | 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 | static irqreturn_t hns3_irq_handle(int irq, void *vector) | 402 | static irqreturn_t hns3_irq_handle(int irq, void *vector) |
| 384 | { | 403 | { |
| 385 | struct hns3_enet_tqp_vector *tqp_vector = vector; | 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 | static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring) | 1051 | static void hns3_init_tx_spare_buffer(struct hns3_enet_ring *ring) |
| 1033 | { | 1052 | { |
| 1034 | u32 alloc_size = ring->tqp->handle->kinfo.tx_spare_buf_size; | 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 | struct hns3_tx_spare *tx_spare; | 1056 | struct hns3_tx_spare *tx_spare; |
| 1036 | struct page *page; | 1057 | struct page *page; |
| 1037 | dma_addr_t dma; | 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 | tx_spare->buf = page_address(page); | 1094 | tx_spare->buf = page_address(page); |
| 1074 | tx_spare->len = PAGE_SIZE << order; | 1095 | tx_spare->len = PAGE_SIZE << order; |
| 1075 | ring->tx_spare = tx_spare; | 1096 | ring->tx_spare = tx_spare; |
| 1097 | ring->tx_copybreak = priv->tx_copybreak; | ||
| 1076 | return; | 1098 | return; |
| 1077 | 1099 | ||
| 1078 | dma_mapping_error: | 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 | unsigned int type) | 1746 | unsigned int type) |
| 1725 | { | 1747 | { |
| 1726 | struct hns3_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use]; | 1748 | struct hns3_desc_cb *desc_cb = &ring->desc_cb[ring->next_to_use]; |
| 1749 | struct hnae3_handle *handle = ring->tqp->handle; | ||
| 1727 | struct device *dev = ring_to_dev(ring); | 1750 | struct device *dev = ring_to_dev(ring); |
| 1751 | struct hnae3_ae_dev *ae_dev; | ||
| 1728 | unsigned int size; | 1752 | unsigned int size; |
| 1729 | dma_addr_t dma; | 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 | return -ENOMEM; | 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 | desc_cb->priv = priv; | 1790 | desc_cb->priv = priv; |
| 1760 | desc_cb->length = size; | 1791 | desc_cb->length = size; |
| 1761 | desc_cb->dma = dma; | 1792 | desc_cb->dma = dma; |
| @@ -2452,7 +2483,6 @@ static int hns3_nic_set_features(struct net_device *netdev, · 690 unmodified lines | |||
| 2452 | return ret; | 2483 | return ret; |
| 2453 | } | 2484 | } |
| 2454 | 2485 | ||
| 2455 | netdev->features = features; | ||
| 2456 | return 0; | 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 | devm_kfree(&pdev->dev, priv->tqp_vector); | 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 | static void hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv, | 4925 | static void hns3_ring_get_cfg(struct hnae3_queue *q, struct hns3_nic_priv *priv, |
| 4872 | unsigned int ring_type) | 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 | int i, j; | 5155 | int i, j; |
| 5102 | int ret; | 5156 | int ret; |
| 5103 | 5157 | ||
| 5158 | hns3_update_tx_spare_buf_config(priv); | ||
| 5104 | for (i = 0; i < ring_num; i++) { | 5159 | for (i = 0; i < ring_num; i++) { |
| 5105 | ret = hns3_alloc_ring_memory(&priv->ring[i]); | 5160 | ret = hns3_alloc_ring_memory(&priv->ring[i]); |
| 5106 | if (ret) { | 5161 | if (ret) { |
| @@ -5305,6 +5360,8 @@ static int hns3_client_init(struct hnae3_handle *handle) · 198 unmodified lines | |||
| 5305 | priv->ae_handle = handle; | 5360 | priv->ae_handle = handle; |
| 5306 | priv->tx_timeout_count = 0; | 5361 | priv->tx_timeout_count = 0; |
| 5307 | priv->max_non_tso_bd_num = ae_dev->dev_specs.max_non_tso_bd_num; | 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 | set_bit(HNS3_NIC_STATE_DOWN, &priv->state); | 5365 | set_bit(HNS3_NIC_STATE_DOWN, &priv->state); |
| 5309 | 5366 | ||
| 5310 | handle->msg_enable = netif_msg_init(debug, DEFAULT_MSG_LEVEL); | 5367 | handle->msg_enable = netif_msg_init(debug, DEFAULT_MSG_LEVEL); |
| @@ -596,6 +596,8 @@ struct hns3_nic_priv { · 595 unmodified lines | |||
| 596 | struct hns3_enet_coalesce rx_coal; | 596 | struct hns3_enet_coalesce rx_coal; |
| 597 | u32 tx_copybreak; | 597 | u32 tx_copybreak; |
| 598 | u32 rx_copybreak; | 598 | u32 rx_copybreak; |
| 599 | u32 min_tx_copybreak; | ||
| 600 | u32 min_tx_spare_buf_size; | ||
| 599 | }; | 601 | }; |
| 600 | 602 | ||
| 601 | union l3_hdr_info { | 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 | return ret; | 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 | static int hns3_set_tunable(struct net_device *netdev, | 1961 | static int hns3_set_tunable(struct net_device *netdev, |
| 1937 | const struct ethtool_tunable *tuna, | 1962 | const struct ethtool_tunable *tuna, |
| 1938 | const void *data) | 1963 | const void *data) |
| @@ -1949,6 +1974,10 @@ static int hns3_set_tunable(struct net_device *netdev, · 10 unmodified lines | |||
| 1949 | 1974 | ||
| 1950 | switch (tuna->id) { | 1975 | switch (tuna->id) { |
| 1951 | case ETHTOOL_TX_COPYBREAK: | 1976 | case ETHTOOL_TX_COPYBREAK: |
| 1977 | ret = hns3_check_tx_copybreak(netdev, *(u32 *)data); | ||
| 1978 | if (ret) | ||
| 1979 | return ret; | ||
| 1980 | |||
| 1952 | priv->tx_copybreak = *(u32 *)data; | 1981 | priv->tx_copybreak = *(u32 *)data; |
| 1953 | 1982 | ||
| 1954 | for (i = 0; i < h->kinfo.num_tqps; i++) | 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 | break; | 1993 | break; |
| 1965 | case ETHTOOL_TX_COPYBREAK_BUF_SIZE: | 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 | old_tx_spare_buf_size = h->kinfo.tx_spare_buf_size; | 1999 | old_tx_spare_buf_size = h->kinfo.tx_spare_buf_size; |
| 1967 | new_tx_spare_buf_size = *(u32 *)data; | 2000 | new_tx_spare_buf_size = *(u32 *)data; |
| 1968 | netdev_info(netdev, "request to set tx spare buf size from %u to %u\n", | 2001 | netdev_info(netdev, "request to set tx spare buf size from %u to %u\n", |
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | #include <linux/etherdevice.h> | 6 | #include <linux/etherdevice.h> |
| 7 | #include <linux/init.h> | 7 | #include <linux/init.h> |
| 8 | #include <linux/interrupt.h> | 8 | #include <linux/interrupt.h> |
| 9 | #include <linux/irq.h> | ||
| 9 | #include <linux/kernel.h> | 10 | #include <linux/kernel.h> |
| 10 | #include <linux/module.h> | 11 | #include <linux/module.h> |
| 11 | #include <linux/netdevice.h> | 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 | return ret; | 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 | static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) | 3599 | static u32 hclge_check_event_cause(struct hclge_dev *hdev, u32 *clearval) |
| 3588 | { | 3600 | { |
| 3589 | u32 cmdq_src_reg, msix_src_reg, hw_err_src_reg; | 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 | if (BIT(HCLGE_VECTOR0_IMPRESET_INT_B) & msix_src_reg) { | 3617 | if (BIT(HCLGE_VECTOR0_IMPRESET_INT_B) & msix_src_reg) { |
| 3606 | dev_info(&hdev->pdev->dev, "IMP reset interrupt\n"); | 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 | set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state); | 3620 | set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state); |
| 3609 | *clearval = BIT(HCLGE_VECTOR0_IMPRESET_INT_B); | 3621 | *clearval = BIT(HCLGE_VECTOR0_IMPRESET_INT_B); |
| 3610 | hdev->rst_stats.imp_rst_cnt++; | 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 | if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & msix_src_reg) { | 3626 | if (BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B) & msix_src_reg) { |
| 3615 | dev_info(&hdev->pdev->dev, "global reset interrupt\n"); | 3627 | dev_info(&hdev->pdev->dev, "global reset interrupt\n"); |
| 3616 | set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state); | 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 | *clearval = BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B); | 3630 | *clearval = BIT(HCLGE_VECTOR0_GLOBALRESET_INT_B); |
| 3619 | hdev->rst_stats.global_rst_cnt++; | 3631 | hdev->rst_stats.global_rst_cnt++; |
| 3620 | return HCLGE_VECTOR0_EVENT_RST; | 3632 | return HCLGE_VECTOR0_EVENT_RST; |
| @@ -3769,7 +3781,7 @@ static int hclge_misc_irq_init(struct hclge_dev *hdev) · 148 unmodified lines | |||
| 3769 | snprintf(hdev->misc_vector.name, HNAE3_INT_NAME_LEN, "%s-misc-%s", | 3781 | snprintf(hdev->misc_vector.name, HNAE3_INT_NAME_LEN, "%s-misc-%s", |
| 3770 | HCLGE_NAME, pci_name(hdev->pdev)); | 3782 | HCLGE_NAME, pci_name(hdev->pdev)); |
| 3771 | ret = request_irq(hdev->misc_vector.vector_irq, hclge_misc_irq_handle, | 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 | if (ret) { | 3785 | if (ret) { |
| 3774 | hclge_free_vector(hdev, 0); | 3786 | hclge_free_vector(hdev, 0); |
| 3775 | dev_err(&hdev->pdev->dev, "request misc irq(%d) fail\n", | 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 | case HNAE3_FUNC_RESET: | 4074 | case HNAE3_FUNC_RESET: |
| 4063 | dev_info(&pdev->dev, "PF reset requested\n"); | 4075 | dev_info(&pdev->dev, "PF reset requested\n"); |
| 4064 | /* schedule again to check later */ | 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 | hclge_reset_task_schedule(hdev); | 4078 | hclge_reset_task_schedule(hdev); |
| 4067 | break; | 4079 | break; |
| 4068 | default: | 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 | clear_bit(HNAE3_FLR_RESET, addr); | 4108 | clear_bit(HNAE3_FLR_RESET, addr); |
| 4097 | } | 4109 | } |
| 4098 | 4110 | ||
| 4111 | clear_bit(HNAE3_NONE_RESET, addr); | ||
| 4112 | |||
| 4099 | if (hdev->reset_type != HNAE3_NONE_RESET && | 4113 | if (hdev->reset_type != HNAE3_NONE_RESET && |
| 4100 | rst_level < hdev->reset_type) | 4114 | rst_level < hdev->reset_type) |
| 4101 | return HNAE3_NONE_RESET; | 4115 | return HNAE3_NONE_RESET; |
| @@ -4237,7 +4251,7 @@ static bool hclge_reset_err_handle(struct hclge_dev *hdev) · 135 unmodified lines | |||
| 4237 | return false; | 4251 | return false; |
| 4238 | } else if (hdev->rst_stats.reset_fail_cnt < MAX_RESET_FAIL_CNT) { | 4252 | } else if (hdev->rst_stats.reset_fail_cnt < MAX_RESET_FAIL_CNT) { |
| 4239 | hdev->rst_stats.reset_fail_cnt++; | 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 | dev_info(&hdev->pdev->dev, | 4255 | dev_info(&hdev->pdev->dev, |
| 4242 | "re-schedule reset task(%u)\n", | 4256 | "re-schedule reset task(%u)\n", |
| 4243 | hdev->rst_stats.reset_fail_cnt); | 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 | static void hclge_set_def_reset_request(struct hnae3_ae_dev *ae_dev, | 4494 | static void hclge_set_def_reset_request(struct hnae3_ae_dev *ae_dev, |
| 4481 | enum hnae3_reset_type rst_type) | 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 | struct hclge_dev *hdev = ae_dev->priv; | 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 | set_bit(rst_type, &hdev->default_reset_request); | 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 | hclge_init_rxd_adv_layout(hdev); | 11918 | hclge_init_rxd_adv_layout(hdev); |
| 11893 | 11919 | ||
| 11894 | /* Enable MISC vector(vector0) */ | ||
| 11895 | hclge_enable_vector(&hdev->misc_vector, true); | ||
| 11896 | |||
| 11897 | ret = hclge_init_wol(hdev); | 11920 | ret = hclge_init_wol(hdev); |
| 11898 | if (ret) | 11921 | if (ret) |
| 11899 | dev_warn(&pdev->dev, | 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 | hclge_state_init(hdev); | 11929 | hclge_state_init(hdev); |
| 11907 | hdev->last_reset_time = jiffies; | 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 | dev_info(&hdev->pdev->dev, "%s driver initialization finished.\n", | 11936 | dev_info(&hdev->pdev->dev, "%s driver initialization finished.\n", |
| 11910 | HCLGE_DRIVER_NAME); | 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 | /* Disable MISC vector(vector0) */ | 12339 | /* Disable MISC vector(vector0) */ |
| 12313 | hclge_enable_vector(&hdev->misc_vector, false); | 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 | /* Disable all hw interrupts */ | 12343 | /* Disable all hw interrupts */ |
| 12317 | hclge_config_mac_tnl_int(hdev, false); | 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 | struct hclge_dev *hdev = vport->back; | 58 | struct hclge_dev *hdev = vport->back; |
| 59 | struct hclge_ptp *ptp = hdev->ptp; | 59 | struct hclge_ptp *ptp = hdev->ptp; |
| 60 | 60 | ||
| 61 | if (!ptp) | ||
| 62 | return false; | ||
| 63 | |||
| 61 | if (!test_bit(HCLGE_PTP_FLAG_TX_EN, &ptp->flags) || | 64 | if (!test_bit(HCLGE_PTP_FLAG_TX_EN, &ptp->flags) || |
| 62 | test_and_set_bit(HCLGE_STATE_PTP_TX_HANDLING, &hdev->state)) { | 65 | test_and_set_bit(HCLGE_STATE_PTP_TX_HANDLING, &hdev->state)) { |
| 63 | ptp->tx_skipped++; | 66 | ptp->tx_skipped++; |
| @@ -510,9 +510,9 @@ out: · 509 unmodified lines | |||
| 510 | static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data, | 510 | static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data, |
| 511 | struct hnae3_knic_private_info *kinfo) | 511 | struct hnae3_knic_private_info *kinfo) |
| 512 | { | 512 | { |
| 513 | #define HCLGE_RING_REG_OFFSET 0x200 | ||
| 514 | #define HCLGE_RING_INT_REG_OFFSET 0x4 | 513 | #define HCLGE_RING_INT_REG_OFFSET 0x4 |
| 515 | 514 | ||
| 515 | struct hnae3_queue *tqp; | ||
| 516 | int i, j, reg_num; | 516 | int i, j, reg_num; |
| 517 | int data_num_sum; | 517 | int data_num_sum; |
| 518 | u32 *reg = data; | 518 | u32 *reg = data; |
| @@ -533,10 +533,11 @@ static int hclge_fetch_pf_reg(struct hclge_dev *hdev, void *data, · 14 unmodified lines | |||
| 533 | reg_num = ARRAY_SIZE(ring_reg_addr_list); | 533 | reg_num = ARRAY_SIZE(ring_reg_addr_list); |
| 534 | for (j = 0; j < kinfo->num_tqps; j++) { | 534 | for (j = 0; j < kinfo->num_tqps; j++) { |
| 535 | reg += hclge_reg_get_tlv(HCLGE_REG_TAG_RING, reg_num, reg); | 535 | reg += hclge_reg_get_tlv(HCLGE_REG_TAG_RING, reg_num, reg); |
| 536 | tqp = kinfo->tqp[j]; | ||
| 536 | for (i = 0; i < reg_num; i++) | 537 | for (i = 0; i < reg_num; i++) |
| 537 | *reg++ = hclge_read_dev(&hdev->hw, | 538 | *reg++ = readl_relaxed(tqp->io_base - |
| 538 | ring_reg_addr_list[i] + | 539 | HCLGE_TQP_REG_OFFSET + |
| 539 | HCLGE_RING_REG_OFFSET * j); | 540 | ring_reg_addr_list[i]); |
| 540 | } | 541 | } |
| 541 | data_num_sum += (reg_num + HCLGE_REG_TLV_SPACE) * kinfo->num_tqps; | 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 | return ret; | 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 | static int hclgevf_reset_wait(struct hclgevf_dev *hdev) | 1409 | static int hclgevf_reset_wait(struct hclgevf_dev *hdev) |
| 1399 | { | 1410 | { |
| 1400 | #define HCLGEVF_RESET_WAIT_US 20000 | 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 | hdev->rst_stats.rst_fail_cnt); | 1555 | hdev->rst_stats.rst_fail_cnt); |
| 1545 | 1556 | ||
| 1546 | if (hdev->rst_stats.rst_fail_cnt < HCLGEVF_RESET_MAX_FAIL_CNT) | 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 | if (hclgevf_is_reset_pending(hdev)) { | 1560 | if (hclgevf_is_reset_pending(hdev)) { |
| 1550 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); | 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 | clear_bit(HNAE3_FLR_RESET, addr); | 1675 | clear_bit(HNAE3_FLR_RESET, addr); |
| 1665 | } | 1676 | } |
| 1666 | 1677 | ||
| 1678 | clear_bit(HNAE3_NONE_RESET, addr); | ||
| 1679 | |||
| 1667 | return rst_level; | 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 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev); | 1686 | struct hnae3_ae_dev *ae_dev = pci_get_drvdata(pdev); |
| 1674 | struct hclgevf_dev *hdev = ae_dev->priv; | 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 | if (hdev->default_reset_request) | 1689 | if (hdev->default_reset_request) |
| 1679 | hdev->reset_level = | 1690 | hdev->reset_level = |
| 1680 | hclgevf_get_reset_level(&hdev->default_reset_request); | 1691 | hclgevf_get_reset_level(&hdev->default_reset_request); |
| 1681 | else | 1692 | else |
| 1682 | hdev->reset_level = HNAE3_VF_FUNC_RESET; | 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 | /* reset of this VF requested */ | 1698 | /* reset of this VF requested */ |
| 1685 | set_bit(HCLGEVF_RESET_REQUESTED, &hdev->reset_state); | 1699 | set_bit(HCLGEVF_RESET_REQUESTED, &hdev->reset_state); |
| 1686 | hclgevf_reset_task_schedule(hdev); | 1700 | hclgevf_reset_task_schedule(hdev); |
| @@ -1691,8 +1705,20 @@ static void hclgevf_reset_event(struct pci_dev *pdev, · 4 unmodified lines | |||
| 1691 | static void hclgevf_set_def_reset_request(struct hnae3_ae_dev *ae_dev, | 1705 | static void hclgevf_set_def_reset_request(struct hnae3_ae_dev *ae_dev, |
| 1692 | enum hnae3_reset_type rst_type) | 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 | struct hclgevf_dev *hdev = ae_dev->priv; | 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 | set_bit(rst_type, &hdev->default_reset_request); | 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 | if (hdev->reset_attempts > HCLGEVF_MAX_RESET_ATTEMPTS_CNT) { | 1876 | if (hdev->reset_attempts > HCLGEVF_MAX_RESET_ATTEMPTS_CNT) { |
| 1851 | /* prepare for full reset of stack + pcie interface */ | 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 | /* "defer" schedule the reset task again */ | 1880 | /* "defer" schedule the reset task again */ |
| 1855 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); | 1881 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); |
| 1856 | } else { | 1882 | } else { |
| 1857 | hdev->reset_attempts++; | 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 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); | 1886 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); |
| 1861 | } | 1887 | } |
| 1862 | hclgevf_reset_task_schedule(hdev); | 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 | rst_ing_reg = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING); | 2005 | rst_ing_reg = hclgevf_read_dev(&hdev->hw, HCLGEVF_RST_ING); |
| 1980 | dev_info(&hdev->pdev->dev, | 2006 | dev_info(&hdev->pdev->dev, |
| 1981 | "receive reset interrupt 0x%x!\n", rst_ing_reg); | 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 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); | 2009 | set_bit(HCLGEVF_RESET_PENDING, &hdev->reset_state); |
| 1984 | set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state); | 2010 | set_bit(HCLGE_COMM_STATE_CMD_DISABLE, &hdev->hw.hw.comm_state); |
| 1985 | *clearval = ~(1U << HCLGEVF_VECTOR0_RST_INT_B); | 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 | clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state); | 2315 | clear_bit(HCLGEVF_STATE_RST_FAIL, &hdev->state); |
| 2290 | 2316 | ||
| 2291 | INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task); | 2317 | INIT_DELAYED_WORK(&hdev->service_task, hclgevf_service_task); |
| 2318 | timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); | ||
| 2292 | 2319 | ||
| 2293 | mutex_init(&hdev->mbx_resp.mbx_mutex); | 2320 | mutex_init(&hdev->mbx_resp.mbx_mutex); |
| 2294 | sema_init(&hdev->reset_sem, 1); | 2321 | sema_init(&hdev->reset_sem, 1); |
| @@ -2988,7 +3015,6 @@ static int hclgevf_init_hdev(struct hclgevf_dev *hdev) · 693 unmodified lines | |||
| 2988 | HCLGEVF_DRIVER_NAME); | 3015 | HCLGEVF_DRIVER_NAME); |
| 2989 | 3016 | ||
| 2990 | hclgevf_task_schedule(hdev, round_jiffies_relative(HZ)); | 3017 | hclgevf_task_schedule(hdev, round_jiffies_relative(HZ)); |
| 2991 | timer_setup(&hdev->reset_timer, hclgevf_reset_timer, 0); | ||
| 2992 | 3018 | ||
| 2993 | return 0; | 3019 | return 0; |
| 2994 | 3020 | ||
| @@ -123,10 +123,10 @@ int hclgevf_get_regs_len(struct hnae3_handle *handle) · 122 unmodified lines | |||
| 123 | void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, | 123 | void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, |
| 124 | void *data) | 124 | void *data) |
| 125 | { | 125 | { |
| 126 | #define HCLGEVF_RING_REG_OFFSET 0x200 | ||
| 127 | #define HCLGEVF_RING_INT_REG_OFFSET 0x4 | 126 | #define HCLGEVF_RING_INT_REG_OFFSET 0x4 |
| 128 | 127 | ||
| 129 | struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); | 128 | struct hclgevf_dev *hdev = hclgevf_ae_get_hdev(handle); |
| 129 | struct hnae3_queue *tqp; | ||
| 130 | int i, j, reg_um; | 130 | int i, j, reg_um; |
| 131 | u32 *reg = data; | 131 | u32 *reg = data; |
| 132 | 132 | ||
| @@ -147,10 +147,11 @@ void hclgevf_get_regs(struct hnae3_handle *handle, u32 *version, · 14 unmodified lines | |||
| 147 | reg_um = ARRAY_SIZE(ring_reg_addr_list); | 147 | reg_um = ARRAY_SIZE(ring_reg_addr_list); |
| 148 | for (j = 0; j < hdev->num_tqps; j++) { | 148 | for (j = 0; j < hdev->num_tqps; j++) { |
| 149 | reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_um, reg); | 149 | reg += hclgevf_reg_get_tlv(HCLGEVF_REG_TAG_RING, reg_um, reg); |
| 150 | tqp = &hdev->htqp[j].q; | ||
| 150 | for (i = 0; i < reg_um; i++) | 151 | for (i = 0; i < reg_um; i++) |
| 151 | *reg++ = hclgevf_read_dev(&hdev->hw, | 152 | *reg++ = readl_relaxed(tqp->io_base - |
| 152 | ring_reg_addr_list[i] + | 153 | HCLGEVF_TQP_REG_OFFSET + |
| 153 | HCLGEVF_RING_REG_OFFSET * j); | 154 | ring_reg_addr_list[i]); |
| 154 | } | 155 | } |
| 155 | 156 | ||
| 156 | reg_um = ARRAY_SIZE(tqp_intr_reg_addr_list); | 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 | if(skb->len > XMIT_BUFF_SIZE) | 1012 | if(skb->len > XMIT_BUFF_SIZE) |
| 1013 | { | 1013 | { |
| 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); | 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 | return NETDEV_TX_OK; | 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 | printk(KERN_ERR "%pOF: Support for 405EZ not enabled!\n", | 578 | printk(KERN_ERR "%pOF: Support for 405EZ not enabled!\n", |
| 579 | ofdev->dev.of_node); | 579 | ofdev->dev.of_node); |
| 580 | err = -ENODEV; | 580 | err = -ENODEV; |
| 581 | goto fail; | 581 | goto fail_unmap; |
| 582 | #endif | 582 | #endif |
| 583 | } | 583 | } |
| 584 | 584 | ||
| @@ -742,6 +742,8 @@ static void mal_remove(struct platform_device *ofdev) · 157 unmodified lines | |||
| 742 | 742 | ||
| 743 | free_netdev(mal->dummy_dev); | 743 | free_netdev(mal->dummy_dev); |
| 744 | 744 | ||
| 745 | dcr_unmap(mal->dcr_host, 0x100); | ||
| 746 | |||
| 745 | dma_free_coherent(&ofdev->dev, | 747 | dma_free_coherent(&ofdev->dev, |
| 746 | sizeof(struct mal_descriptor) * | 748 | sizeof(struct mal_descriptor) * |
| 747 | (NUM_TX_BUFF * mal->num_tx_chans + | 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 | /* if we are going to send_subcrq_direct this then we need to | 2472 | /* if we are going to send_subcrq_direct this then we need to |
| 2473 | * update the checksum before copying the data into ltb. Essentially | 2473 | * update the checksum before copying the data into ltb. Essentially |
| 2474 | * these packets force disable CSO so that we can guarantee that | 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 | use_scrq_send_direct = true; | 2480 | use_scrq_send_direct = true; |
| 2479 | if (skb->ip_summed == CHECKSUM_PARTIAL && | 2481 | if (skb->ip_summed == CHECKSUM_PARTIAL && |
| 2480 | skb_checksum_help(skb)) | 2482 | skb_checksum_help(skb)) |
| @@ -108,8 +108,8 @@ struct e1000_hw; · 107 unmodified lines | |||
| 108 | #define E1000_DEV_ID_PCH_RPL_I219_V22 0x0DC8 | 108 | #define E1000_DEV_ID_PCH_RPL_I219_V22 0x0DC8 |
| 109 | #define E1000_DEV_ID_PCH_MTP_I219_LM18 0x550A | 109 | #define E1000_DEV_ID_PCH_MTP_I219_LM18 0x550A |
| 110 | #define E1000_DEV_ID_PCH_MTP_I219_V18 0x550B | 110 | #define E1000_DEV_ID_PCH_MTP_I219_V18 0x550B |
| 111 | #define E1000_DEV_ID_PCH_MTP_I219_LM19 0x550C | 111 | #define E1000_DEV_ID_PCH_ADP_I219_LM19 0x550C |
| 112 | #define E1000_DEV_ID_PCH_MTP_I219_V19 0x550D | 112 | #define E1000_DEV_ID_PCH_ADP_I219_V19 0x550D |
| 113 | #define E1000_DEV_ID_PCH_LNP_I219_LM20 0x550E | 113 | #define E1000_DEV_ID_PCH_LNP_I219_LM20 0x550E |
| 114 | #define E1000_DEV_ID_PCH_LNP_I219_V20 0x550F | 114 | #define E1000_DEV_ID_PCH_LNP_I219_V20 0x550F |
| 115 | #define E1000_DEV_ID_PCH_LNP_I219_LM21 0x5510 | 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 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V17), board_pch_adp }, | 7899 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_ADP_I219_V17), board_pch_adp }, |
| 7900 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_LM22), board_pch_adp }, | 7900 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_LM22), board_pch_adp }, |
| 7901 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_RPL_I219_V22), board_pch_adp }, | 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 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM18), board_pch_mtp }, | 7904 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_LM18), board_pch_mtp }, |
| 7903 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_MTP_I219_V18), board_pch_mtp }, | 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 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM20), board_pch_mtp }, | 7906 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM20), board_pch_mtp }, |
| 7907 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V20), board_pch_mtp }, | 7907 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_V20), board_pch_mtp }, |
| 7908 | { PCI_VDEVICE(INTEL, E1000_DEV_ID_PCH_LNP_I219_LM21), board_pch_mtp }, | 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 | struct hlist_node *h; | 1734 | struct hlist_node *h; |
| 1735 | int bkt; | 1735 | int bkt; |
| 1736 | 1736 | ||
| 1737 | lockdep_assert_held(&vsi->mac_filter_hash_lock); | ||
| 1737 | if (vsi->info.pvid) | 1738 | if (vsi->info.pvid) |
| 1738 | return i40e_add_filter(vsi, macaddr, | 1739 | return i40e_add_filter(vsi, macaddr, |
| 1739 | le16_to_cpu(vsi->info.pvid)); | 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 | vfres->vsi_res[0].qset_handle | 2213 | vfres->vsi_res[0].qset_handle |
| 2214 | = le16_to_cpu(vsi->info.qs_handle[0]); | 2214 | = le16_to_cpu(vsi->info.qs_handle[0]); |
| 2215 | if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_USO) && !vf->pf_set_mac) { | 2215 | if (!(vf->driver_caps & VIRTCHNL_VF_OFFLOAD_USO) && !vf->pf_set_mac) { |
| 2216 | spin_lock_bh(&vsi->mac_filter_hash_lock); | ||
| 2216 | i40e_del_mac_filter(vsi, vf->default_lan_addr.addr); | 2217 | i40e_del_mac_filter(vsi, vf->default_lan_addr.addr); |
| 2217 | eth_zero_addr(vf->default_lan_addr.addr); | 2218 | eth_zero_addr(vf->default_lan_addr.addr); |
| 2219 | spin_unlock_bh(&vsi->mac_filter_hash_lock); | ||
| 2218 | } | 2220 | } |
| 2219 | ether_addr_copy(vfres->vsi_res[0].default_mac_addr, | 2221 | ether_addr_copy(vfres->vsi_res[0].default_mac_addr, |
| 2220 | vf->default_lan_addr.addr); | 2222 | vf->default_lan_addr.addr); |
| @@ -989,5 +989,11 @@ ice_devlink_port_new(struct devlink *devlink, · 988 unmodified lines | |||
| 989 | if (err) | 989 | if (err) |
| 990 | return err; | 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 | return ice_alloc_dynamic_port(pf, new_attr, extack, devlink_port); | 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 | * Verifies various attributes of the package file, including length, format | 31 | * Verifies various attributes of the package file, including length, format |
| 32 | * version, and the requirement of at least one segment. | 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 | u32 seg_count; | 36 | u32 seg_count; |
| 37 | u32 i; | 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 | /* all segments must fit within length */ | 57 | /* all segments must fit within length */ |
| 58 | for (i = 0; i < seg_count; i++) { | 58 | for (i = 0; i < seg_count; i++) { |
| 59 | u32 off = le32_to_cpu(pkg->seg_offset[i]); | 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 | /* segment header must fit */ | 62 | /* segment header must fit */ |
| 63 | if (len < off + sizeof(*seg)) | 63 | if (len < off + sizeof(*seg)) |
| 64 | return ICE_DDP_PKG_INVALID_FILE; | 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 | /* segment body must fit */ | 68 | /* segment body must fit */ |
| 69 | if (len < off + le32_to_cpu(seg->seg_size)) | 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 | * This helper function validates a buffer's header. | 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 | u16 section_count; | 125 | u16 section_count; |
| 126 | u16 data_end; | 126 | u16 data_end; |
| 127 | 127 | ||
| 128 | hdr = (struct ice_buf_hdr *)buf->buf; | 128 | hdr = (const struct ice_buf_hdr *)buf->buf; |
| 129 | /* verify data */ | 129 | /* verify data */ |
| 130 | section_count = le16_to_cpu(hdr->section_count); | 130 | section_count = le16_to_cpu(hdr->section_count); |
| 131 | if (section_count < ICE_MIN_S_COUNT || section_count > ICE_MAX_S_COUNT) | 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 | * unexpected value has been detected (for example an invalid section count or | 165 | * unexpected value has been detected (for example an invalid section count or |
| 166 | * an invalid buffer end value). | 166 | * an invalid buffer end value). |
| 167 | */ | 167 | */ |
| 168 | static struct ice_buf_hdr *ice_pkg_enum_buf(struct ice_seg *ice_seg, | 168 | static const struct ice_buf_hdr *ice_pkg_enum_buf(struct ice_seg *ice_seg, |
| 169 | struct ice_pkg_enum *state) | 169 | struct ice_pkg_enum *state) |
| 170 | { | 170 | { |
| 171 | if (ice_seg) { | 171 | if (ice_seg) { |
| 172 | state->buf_table = ice_find_buf_table(ice_seg); | 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 | * success it returns a pointer to the segment header, otherwise it will | 1800 | * success it returns a pointer to the segment header, otherwise it will |
| 1801 | * return NULL. | 1801 | * return NULL. |
| 1802 | */ | 1802 | */ |
| 1803 | static struct ice_generic_seg_hdr * | 1803 | static const struct ice_generic_seg_hdr * |
| 1804 | ice_find_seg_in_pkg(struct ice_hw *hw, u32 seg_type, | 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 | u32 i; | 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 | /* Search all package segments for the requested segment type */ | 1814 | /* Search all package segments for the requested segment type */ |
| 1815 | for (i = 0; i < le32_to_cpu(pkg_hdr->seg_count); i++) { | 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 | 1818 | seg = (void *)pkg_hdr + le32_to_cpu(pkg_hdr->seg_offset[i]); |
| 1819 | *)((u8 *)pkg_hdr + | ||
| 1820 | le32_to_cpu(pkg_hdr->seg_offset[i])); | ||
| 1821 | 1819 | ||
| 1822 | if (le32_to_cpu(seg->seg_type) == seg_type) | 1820 | if (le32_to_cpu(seg->seg_type) == seg_type) |
| 1823 | return seg; | 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 | * Return: zero when update was successful, negative values otherwise. | 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; | 2357 | u8 *new_topo = NULL, *topo __free(kfree) = NULL; |
| 2360 | struct ice_run_time_cfg_seg *seg; | 2358 | const struct ice_run_time_cfg_seg *seg; |
| 2361 | struct ice_buf_hdr *section; | 2359 | const struct ice_buf_hdr *section; |
| 2362 | struct ice_pkg_hdr *pkg_hdr; | 2360 | const struct ice_pkg_hdr *pkg_hdr; |
| 2363 | enum ice_ddp_state state; | 2361 | enum ice_ddp_state state; |
| 2364 | u16 offset, size = 0; | 2362 | u16 offset, size = 0; |
| 2365 | u32 reg = 0; | 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 | return -EOPNOTSUPP; | 2373 | return -EOPNOTSUPP; |
| 2376 | } | 2374 | } |
| 2377 | 2375 | ||
| 2378 | current_topo = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL); | 2376 | topo = kzalloc(ICE_AQ_MAX_BUF_LEN, GFP_KERNEL); |
| 2379 | if (!current_topo) | 2377 | if (!topo) |
| 2380 | return -ENOMEM; | 2378 | return -ENOMEM; |
| 2381 | 2379 | ||
| 2382 | /* Get the current Tx topology */ | 2380 | /* Get the current Tx topology flags */ |
| 2383 | status = ice_get_set_tx_topo(hw, current_topo, ICE_AQ_MAX_BUF_LEN, NULL, | 2381 | status = ice_get_set_tx_topo(hw, topo, ICE_AQ_MAX_BUF_LEN, NULL, &flags, |
| 2384 | &flags, false); | 2382 | false); |
| 2385 | |||
| 2386 | kfree(current_topo); | ||
| 2387 | 2383 | ||
| 2388 | if (status) { | 2384 | if (status) { |
| 2389 | ice_debug(hw, ICE_DBG_INIT, "Get current topology is failed\n"); | 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 | goto update_topo; | 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 | state = ice_verify_pkg(pkg_hdr, len); | 2419 | state = ice_verify_pkg(pkg_hdr, len); |
| 2424 | if (state) { | 2420 | if (state) { |
| 2425 | ice_debug(hw, ICE_DBG_INIT, "Failed to verify pkg (err: %d)\n", | 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 | /* Find runtime configuration segment */ | 2426 | /* Find runtime configuration segment */ |
| 2431 | seg = (struct ice_run_time_cfg_seg *) | 2427 | seg = (const struct ice_run_time_cfg_seg *) |
| 2432 | ice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE_RUN_TIME_CFG, pkg_hdr); | 2428 | ice_find_seg_in_pkg(hw, SEGMENT_TYPE_ICE_RUN_TIME_CFG, pkg_hdr); |
| 2433 | if (!seg) { | 2429 | if (!seg) { |
| 2434 | ice_debug(hw, ICE_DBG_INIT, "5 layer topology segment is missing\n"); | 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 | return -EIO; | 2457 | return -EIO; |
| 2462 | } | 2458 | } |
| 2463 | 2459 | ||
| 2464 | /* Get the new topology buffer */ | 2460 | /* Get the new topology buffer, reuse current topo copy mem */ |
| 2465 | new_topo = ((u8 *)section) + offset; | 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 | update_topo: | 2465 | update_topo: |
| 2468 | /* Acquire global lock to make sure that set topology issued | 2466 | /* Acquire global lock to make sure that set topology issued |
| @@ -438,7 +438,7 @@ struct ice_pkg_enum { · 437 unmodified lines | |||
| 438 | u32 buf_idx; | 438 | u32 buf_idx; |
| 439 | 439 | ||
| 440 | u32 type; | 440 | u32 type; |
| 441 | struct ice_buf_hdr *buf; | 441 | const struct ice_buf_hdr *buf; |
| 442 | u32 sect_idx; | 442 | u32 sect_idx; |
| 443 | void *sect; | 443 | void *sect; |
| 444 | u32 sect_type; | 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 | void *ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state, | 467 | void *ice_pkg_enum_section(struct ice_seg *ice_seg, struct ice_pkg_enum *state, |
| 468 | u32 sect_type); | 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 | #endif | 472 | #endif |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | |||
| 10 | #define ICE_DPLL_PIN_IDX_INVALID 0xff | 10 | #define ICE_DPLL_PIN_IDX_INVALID 0xff |
| 11 | #define ICE_DPLL_RCLK_NUM_PER_PF 1 | 11 | #define ICE_DPLL_RCLK_NUM_PER_PF 1 |
| 12 | #define ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT 25 | 12 | #define ICE_DPLL_PIN_ESYNC_PULSE_HIGH_PERCENT 25 |
| 13 | #define ICE_DPLL_PIN_GEN_RCLK_FREQ 1953125 | ||
| 13 | 14 | ||
| 14 | /** | 15 | /** |
| 15 | * enum ice_dpll_pin_type - enumerate ice pin types: | 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 | struct ice_dpll_pin *p = pin_priv; | 657 | struct ice_dpll_pin *p = pin_priv; |
| 657 | struct ice_dpll *d = dpll_priv; | 658 | struct ice_dpll *d = dpll_priv; |
| 658 | 659 | ||
| 660 | if (state == DPLL_PIN_STATE_SELECTABLE) | ||
| 661 | return -EINVAL; | ||
| 659 | if (!enable && p->state[d->dpll_idx] == DPLL_PIN_STATE_DISCONNECTED) | 662 | if (!enable && p->state[d->dpll_idx] == DPLL_PIN_STATE_DISCONNECTED) |
| 660 | return 0; | 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 | struct dpll_pin *parent; | 1846 | struct dpll_pin *parent; |
| 1844 | int ret, i; | 1847 | int ret, i; |
| 1845 | 1848 | ||
| 1849 | if (WARN_ON((!vsi || !vsi->netdev))) | ||
| 1850 | return -EINVAL; | ||
| 1846 | ret = ice_dpll_get_pins(pf, pin, start_idx, ICE_DPLL_RCLK_NUM_PER_PF, | 1851 | ret = ice_dpll_get_pins(pf, pin, start_idx, ICE_DPLL_RCLK_NUM_PER_PF, |
| 1847 | pf->dplls.clock_id); | 1852 | pf->dplls.clock_id); |
| 1848 | if (ret) | 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 | if (ret) | 1863 | if (ret) |
| 1859 | goto unregister_pins; | 1864 | goto unregister_pins; |
| 1860 | } | 1865 | } |
| 1861 | if (WARN_ON((!vsi || !vsi->netdev))) | ||
| 1862 | return -EINVAL; | ||
| 1863 | dpll_netdev_pin_set(vsi->netdev, pf->dplls.rclk.pin); | 1866 | dpll_netdev_pin_set(vsi->netdev, pf->dplls.rclk.pin); |
| 1864 | 1867 | ||
| 1865 | return 0; | 1868 | return 0; |
| @@ -2061,6 +2064,73 @@ static int ice_dpll_init_worker(struct ice_pf *pf) · 195 unmodified lines | |||
| 2061 | return 0; | 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 | * ice_dpll_init_info_direct_pins - initializes direct pins info | 2135 | * ice_dpll_init_info_direct_pins - initializes direct pins info |
| 2066 | * @pf: board private structure | 2136 | * @pf: board private structure |
| @@ -2099,6 +2169,8 @@ ice_dpll_init_info_direct_pins(struct ice_pf *pf, · 32 unmodified lines | |||
| 2099 | default: | 2169 | default: |
| 2100 | return -EINVAL; | 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 | for (i = 0; i < num_pins; i++) { | 2175 | for (i = 0; i < num_pins; i++) { |
| 2104 | caps = 0; | 2176 | caps = 0; |
| @@ -582,10 +582,13 @@ ice_eswitch_br_switchdev_event(struct notifier_block *nb, · 581 unmodified lines | |||
| 582 | return NOTIFY_DONE; | 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 | struct ice_esw_br_fdb_entry *entry, *tmp; | 587 | struct ice_esw_br_fdb_entry *entry, *tmp; |
| 588 | 588 | ||
| 589 | if (!bridge) | ||
| 590 | return; | ||
| 591 | |||
| 589 | list_for_each_entry_safe(entry, tmp, &bridge->fdb_list, list) | 592 | list_for_each_entry_safe(entry, tmp, &bridge->fdb_list, list) |
| 590 | ice_eswitch_br_fdb_entry_notify_and_cleanup(bridge, entry); | 593 | ice_eswitch_br_fdb_entry_notify_and_cleanup(bridge, entry); |
| 591 | } | 594 | } |
| @@ -117,5 +117,6 @@ void · 116 unmodified lines | |||
| 117 | ice_eswitch_br_offloads_deinit(struct ice_pf *pf); | 117 | ice_eswitch_br_offloads_deinit(struct ice_pf *pf); |
| 118 | int | 118 | int |
| 119 | ice_eswitch_br_offloads_init(struct ice_pf *pf); | 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 | #endif /* _ICE_ESWITCH_BR_H_ */ | 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 | bool netif_is_ice(const struct net_device *dev) | 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 | pf->vf_agg_node[node].num_vsis = 0; | 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 | * ice_prepare_for_reset - prep for reset | 525 | * ice_prepare_for_reset - prep for reset |
| 544 | * @pf: board private structure | 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 | mutex_unlock(&pf->vfs.table_lock); | 557 | mutex_unlock(&pf->vfs.table_lock); |
| 576 | 558 | ||
| 577 | if (ice_is_eswitch_mode_switchdev(pf)) { | 559 | if (ice_is_eswitch_mode_switchdev(pf)) { |
| 578 | if (reset_type != ICE_RESET_PFR) | 560 | rtnl_lock(); |
| 579 | ice_clear_sw_switch_recipes(pf); | 561 | ice_eswitch_br_fdb_flush(pf->eswitch.br_offloads->bridge); |
| 562 | rtnl_unlock(); | ||
| 580 | } | 563 | } |
| 581 | 564 | ||
| 582 | /* release ADQ specific HW and SW resources */ | 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 | u8 num_tx_sched_layers = hw->num_tx_sched_layers; | 4519 | u8 num_tx_sched_layers = hw->num_tx_sched_layers; |
| 4537 | struct ice_pf *pf = hw->back; | 4520 | struct ice_pf *pf = hw->back; |
| 4538 | struct device *dev; | 4521 | struct device *dev; |
| 4539 | u8 *buf_copy; | ||
| 4540 | int err; | 4522 | int err; |
| 4541 | 4523 | ||
| 4542 | dev = ice_pf_to_dev(pf); | 4524 | dev = ice_pf_to_dev(pf); |
| 4543 | /* ice_cfg_tx_topo buf argument is not a constant, | 4525 | err = ice_cfg_tx_topo(hw, firmware->data, firmware->size); |
| 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); | ||
| 4549 | if (!err) { | 4526 | if (!err) { |
| 4550 | if (hw->num_tx_sched_layers > num_tx_sched_layers) | 4527 | if (hw->num_tx_sched_layers > num_tx_sched_layers) |
| 4551 | dev_info(dev, "Tx scheduling layers switching feature disabled\n"); | 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 | ice_init_feature_support(pf); | 4750 | ice_init_feature_support(pf); |
| 4774 | 4751 | ||
| 4775 | err = ice_init_ddp_config(hw, pf); | 4752 | err = ice_init_ddp_config(hw, pf); |
| 4776 | if (err) | ||
| 4777 | return err; | ||
| 4778 | 4753 | ||
| 4779 | /* if ice_init_ddp_config fails, ICE_FLAG_ADV_FEATURES bit won't be | 4754 | /* if ice_init_ddp_config fails, ICE_FLAG_ADV_FEATURES bit won't be |
| 4780 | * set in pf->state, which will cause ice_is_safe_mode to return | 4755 | * set in pf->state, which will cause ice_is_safe_mode to return |
| 4781 | * true | 4756 | * true |
| 4782 | */ | 4757 | */ |
| 4783 | if (ice_is_safe_mode(pf)) { | 4758 | if (err || ice_is_safe_mode(pf)) { |
| 4784 | /* we already got function/device capabilities but these don't | 4759 | /* we already got function/device capabilities but these don't |
| 4785 | * reflect what the driver needs to do in safe mode. Instead of | 4760 | * reflect what the driver needs to do in safe mode. Instead of |
| 4786 | * adding conditional logic everywhere to ignore these | 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 | ARRAY_SIZE(ice_cgu_pin_freq_common), ice_cgu_pin_freq_common }, | 34 | ARRAY_SIZE(ice_cgu_pin_freq_common), ice_cgu_pin_freq_common }, |
| 35 | { "GNSS-1PPS", ZL_REF4P, DPLL_PIN_TYPE_GNSS, | 35 | { "GNSS-1PPS", ZL_REF4P, DPLL_PIN_TYPE_GNSS, |
| 36 | ARRAY_SIZE(ice_cgu_pin_freq_1_hz), ice_cgu_pin_freq_1_hz }, | 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 | static const struct ice_cgu_pin_desc ice_e810t_qsfp_cgu_inputs[] = { | 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 | ARRAY_SIZE(ice_cgu_pin_freq_common), ice_cgu_pin_freq_common }, | 51 | ARRAY_SIZE(ice_cgu_pin_freq_common), ice_cgu_pin_freq_common }, |
| 53 | { "GNSS-1PPS", ZL_REF4P, DPLL_PIN_TYPE_GNSS, | 52 | { "GNSS-1PPS", ZL_REF4P, DPLL_PIN_TYPE_GNSS, |
| 54 | ARRAY_SIZE(ice_cgu_pin_freq_1_hz), ice_cgu_pin_freq_1_hz }, | 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 | static const struct ice_cgu_pin_desc ice_e810t_sfp_cgu_outputs[] = { | 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 | return t; | 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 | * ice_cgu_get_pin_type - get pin's type | 5985 | * ice_cgu_get_pin_type - get pin's type |
| 5969 | * @hw: pointer to the hw struct | 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 | int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data); | 404 | int ice_write_sma_ctrl_e810t(struct ice_hw *hw, u8 data); |
| 405 | int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data); | 405 | int ice_read_pca9575_reg_e810t(struct ice_hw *hw, u8 offset, u8 *data); |
| 406 | bool ice_is_pca9575_present(struct ice_hw *hw); | 406 | bool ice_is_pca9575_present(struct ice_hw *hw); |
| 407 | int ice_cgu_get_num_pins(struct ice_hw *hw, bool input); | ||
| 407 | enum dpll_pin_type ice_cgu_get_pin_type(struct ice_hw *hw, u8 pin, bool input); | 408 | enum dpll_pin_type ice_cgu_get_pin_type(struct ice_hw *hw, u8 pin, bool input); |
| 408 | struct dpll_pin_frequency * | 409 | struct dpll_pin_frequency * |
| 409 | ice_cgu_get_pin_freq_supp(struct ice_hw *hw, u8 pin, bool input, u8 *num); | 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 | return -ENOENT; | 1096 | return -ENOENT; |
| 1097 | 1097 | ||
| 1098 | vsi = ice_get_vf_vsi(vf); | 1098 | vsi = ice_get_vf_vsi(vf); |
| 1099 | if (!vsi) | 1099 | if (!vsi) { |
| 1100 | ice_put_vf(vf); | ||
| 1100 | return -ENOENT; | 1101 | return -ENOENT; |
| 1102 | } | ||
| 1101 | 1103 | ||
| 1102 | prev_msix = vf->num_msix; | 1104 | prev_msix = vf->num_msix; |
| 1103 | prev_queues = vf->num_vf_qs; | 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 | if (vf->first_vector_idx < 0) | 1121 | if (vf->first_vector_idx < 0) |
| 1120 | goto unroll; | 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 | /* Try to rebuild with previous values */ | 1128 | /* Try to rebuild with previous values */ |
| 1124 | needs_rebuild = true; | 1129 | needs_rebuild = true; |
| 1125 | goto unroll; | 1130 | goto unroll; |
| @@ -1142,12 +1147,16 @@ unroll: · 16 unmodified lines | |||
| 1142 | vf->num_msix = prev_msix; | 1147 | vf->num_msix = prev_msix; |
| 1143 | vf->num_vf_qs = prev_queues; | 1148 | vf->num_vf_qs = prev_queues; |
| 1144 | vf->first_vector_idx = ice_sriov_get_irqs(pf, vf->num_msix); | 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 | return -EINVAL; | 1152 | return -EINVAL; |
| 1153 | } | ||
| 1147 | 1154 | ||
| 1148 | if (needs_rebuild) { | 1155 | if (needs_rebuild) { |
| 1149 | ice_vf_reconfig_vsi(vf); | 1156 | vsi->req_txq = prev_queues; |
| 1150 | ice_vf_init_host_cfg(vf, vsi); | 1157 | vsi->req_rxq = prev_queues; |
| 1158 | |||
| 1159 | ice_vsi_rebuild(vsi, ICE_VSI_FLAG_NO_INIT); | ||
| 1151 | } | 1160 | } |
| 1152 | 1161 | ||
| 1153 | ice_ena_vf_mappings(vf); | 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 | if (!itr->vsi_list_info || | 6322 | if (!itr->vsi_list_info || |
| 6323 | !test_bit(vsi_handle, itr->vsi_list_info->vsi_map)) | 6323 | !test_bit(vsi_handle, itr->vsi_list_info->vsi_map)) |
| 6324 | continue; | 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 | f_entry.fltr_info.vsi_handle = vsi_handle; | 6325 | f_entry.fltr_info.vsi_handle = vsi_handle; |
| 6328 | f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; | 6326 | f_entry.fltr_info.fltr_act = ICE_FWD_TO_VSI; |
| 6329 | /* update the src in case it is VSI num */ | 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 | rule_info.sw_act.flag |= ICE_FLTR_TX; | 819 | rule_info.sw_act.flag |= ICE_FLTR_TX; |
| 820 | rule_info.sw_act.src = vsi->idx; | 820 | rule_info.sw_act.src = vsi->idx; |
| 821 | rule_info.flags_info.act = ICE_SINGLE_ACT_LAN_ENABLE; | 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 | } else { | 833 | } else { |
| 823 | /* VF to VF */ | 834 | /* VF to VF */ |
| 824 | rule_info.sw_act.flag |= ICE_FLTR_TX; | 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 | * It brings the VSI down and then reconfigures it with the hardware. | 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 | struct ice_vsi *vsi = ice_get_vf_vsi(vf); | 261 | struct ice_vsi *vsi = ice_get_vf_vsi(vf); |
| 262 | struct ice_pf *pf = vf->pf; | 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 | err = vlan_ops->add_vlan(vsi, &vf->port_vlan_info); | 336 | err = vlan_ops->add_vlan(vsi, &vf->port_vlan_info); |
| 337 | } else { | 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 | err = ice_vsi_add_vlan_zero(vsi); | 345 | err = ice_vsi_add_vlan_zero(vsi); |
| 339 | } | 346 | } |
| 340 | 347 | ||
| @@ -23,7 +23,6 @@ · 22 unmodified lines | |||
| 23 | #warning "Only include ice_vf_lib_private.h in CONFIG_PCI_IOV virtualization files" | 23 | #warning "Only include ice_vf_lib_private.h in CONFIG_PCI_IOV virtualization files" |
| 24 | #endif | 24 | #endif |
| 25 | 25 | ||
| 26 | int ice_vf_reconfig_vsi(struct ice_vf *vf); | ||
| 27 | void ice_initialize_vf_entry(struct ice_vf *vf); | 26 | void ice_initialize_vf_entry(struct ice_vf *vf); |
| 28 | void ice_dis_vf_qs(struct ice_vf *vf); | 27 | void ice_dis_vf_qs(struct ice_vf *vf); |
| 29 | int ice_check_vf_init(struct ice_vf *vf); | 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 | kfree(ctxt); | 787 | kfree(ctxt); |
| 788 | return err; | 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 | int ice_vsi_dis_outer_insertion(struct ice_vsi *vsi); | 36 | int ice_vsi_dis_outer_insertion(struct ice_vsi *vsi); |
| 37 | int ice_vsi_set_outer_port_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan); | 37 | int ice_vsi_set_outer_port_vlan(struct ice_vsi *vsi, struct ice_vlan *vlan); |
| 38 | int ice_vsi_clear_outer_port_vlan(struct ice_vsi *vsi); | 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 | #endif /* _ICE_VSI_VLAN_LIB_H_ */ | 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 | intr->dyn_ctl_intena_m = VF_INT_DYN_CTLN_INTENA_M; | 99 | intr->dyn_ctl_intena_m = VF_INT_DYN_CTLN_INTENA_M; |
| 100 | intr->dyn_ctl_intena_msk_m = VF_INT_DYN_CTLN_INTENA_MSK_M; | 100 | intr->dyn_ctl_intena_msk_m = VF_INT_DYN_CTLN_INTENA_MSK_M; |
| 101 | intr->dyn_ctl_itridx_s = VF_INT_DYN_CTLN_ITR_INDX_S; | 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 | intr->dyn_ctl_wb_on_itr_m = VF_INT_DYN_CTLN_WB_ON_ITR_M; | 103 | intr->dyn_ctl_wb_on_itr_m = VF_INT_DYN_CTLN_WB_ON_ITR_M; |
| 103 | 104 | ||
| 104 | spacing = IDPF_ITR_IDX_SPACING(reg_vals[vec_id].itrn_index_spacing, | 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 | if (ctlq_msg->data_len) { | 667 | if (ctlq_msg->data_len) { |
| 668 | payload = ctlq_msg->ctx.indirect.payload->va; | 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 | xn->reply_sz = payload_size; | 672 | xn->reply_sz = payload_size; |
| @@ -1295,10 +1295,6 @@ int idpf_send_create_vport_msg(struct idpf_adapter *adapter, · 622 unmodified lines | |||
| 1295 | err = reply_sz; | 1295 | err = reply_sz; |
| 1296 | goto free_vport_params; | 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 | return 0; | 1299 | return 0; |
| 1304 | 1300 | ||
| @@ -2602,9 +2598,6 @@ int idpf_send_get_rx_ptype_msg(struct idpf_vport *vport) · 1297 unmodified lines | |||
| 2602 | if (reply_sz < 0) | 2598 | if (reply_sz < 0) |
| 2603 | return reply_sz; | 2599 | return reply_sz; |
| 2604 | 2600 | ||
| 2605 | if (reply_sz < IDPF_CTLQ_MAX_BUF_LEN) | ||
| 2606 | return -EIO; | ||
| 2607 | |||
| 2608 | ptypes_recvd += le16_to_cpu(ptype_info->num_ptypes); | 2601 | ptypes_recvd += le16_to_cpu(ptype_info->num_ptypes); |
| 2609 | if (ptypes_recvd > max_ptype) | 2602 | if (ptypes_recvd > max_ptype) |
| 2610 | return -EINVAL; | 2603 | return -EINVAL; |
| @@ -3088,9 +3081,9 @@ void idpf_vc_core_deinit(struct idpf_adapter *adapter) · 477 unmodified lines | |||
| 3088 | if (!test_bit(IDPF_VC_CORE_INIT, adapter->flags)) | 3081 | if (!test_bit(IDPF_VC_CORE_INIT, adapter->flags)) |
| 3089 | return; | 3082 | return; |
| 3090 | 3083 | ||
| 3091 | idpf_vc_xn_shutdown(adapter->vcxn_mngr); | ||
| 3092 | idpf_deinit_task(adapter); | 3084 | idpf_deinit_task(adapter); |
| 3093 | idpf_intr_rel(adapter); | 3085 | idpf_intr_rel(adapter); |
| 3086 | idpf_vc_xn_shutdown(adapter->vcxn_mngr); | ||
| 3094 | 3087 | ||
| 3095 | cancel_delayed_work_sync(&adapter->serv_task); | 3088 | cancel_delayed_work_sync(&adapter->serv_task); |
| 3096 | cancel_delayed_work_sync(&adapter->mbx_task); | 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 | int i, err = 0, vector = 0, free_vector = 0; | 907 | int i, err = 0, vector = 0, free_vector = 0; |
| 908 | 908 | ||
| 909 | err = request_irq(adapter->msix_entries[vector].vector, | 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 | if (err) | 911 | if (err) |
| 912 | goto err_out; | 912 | goto err_out; |
| 913 | 913 | ||
| @@ -9651,6 +9651,10 @@ static void igb_io_resume(struct pci_dev *pdev) · 8737 unmodified lines | |||
| 9651 | struct igb_adapter *adapter = netdev_priv(netdev); | 9651 | struct igb_adapter *adapter = netdev_priv(netdev); |
| 9652 | 9652 | ||
| 9653 | if (netif_running(netdev)) { | 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 | if (igb_up(adapter)) { | 9658 | if (igb_up(adapter)) { |
| 9655 | dev_err(&pdev->dev, "igb_up failed after reset\n"); | 9659 | dev_err(&pdev->dev, "igb_up failed after reset\n"); |
| 9656 | return; | 9660 | return; |
| @@ -336,6 +336,51 @@ static int octep_oq_check_hw_for_pkts(struct octep_device *oct, · 335 unmodified lines | |||
| 336 | return new_pkts; | 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 | * __octep_oq_process_rx() - Process hardware Rx queue and push to stack. | 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 | desc_used = 0; | 412 | desc_used = 0; |
| 368 | for (pkt = 0; pkt < pkts_to_process; pkt++) { | 413 | for (pkt = 0; pkt < pkts_to_process; pkt++) { |
| 369 | buff_info = (struct octep_rx_buffer *)&oq->buff_info[read_idx]; | 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 | resp_hw = page_address(buff_info->page); | 415 | resp_hw = page_address(buff_info->page); |
| 373 | buff_info->page = NULL; | ||
| 374 | 416 | ||
| 375 | /* Swap the length field that is in Big-Endian to CPU */ | 417 | /* Swap the length field that is in Big-Endian to CPU */ |
| 376 | buff_info->len = be64_to_cpu(resp_hw->length); | 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 | data_offset = OCTEP_OQ_RESP_HW_SIZE; | 436 | data_offset = OCTEP_OQ_RESP_HW_SIZE; |
| 395 | rx_ol_flags = 0; | 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 | rx_bytes += buff_info->len; | 451 | rx_bytes += buff_info->len; |
| 398 | 452 | ||
| 399 | if (buff_info->len <= oq->max_single_buffer_size) { | 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 | skb_put(skb, buff_info->len); | 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 | } else { | 455 | } else { |
| 408 | struct skb_shared_info *shinfo; | 456 | struct skb_shared_info *shinfo; |
| 409 | u16 data_len; | 457 | u16 data_len; |
| 410 | 458 | ||
| 411 | skb = build_skb((void *)resp_hw, PAGE_SIZE); | ||
| 412 | skb_reserve(skb, data_offset); | ||
| 413 | /* Head fragment includes response header(s); | 459 | /* Head fragment includes response header(s); |
| 414 | * subsequent fragments contains only data. | 460 | * subsequent fragments contains only data. |
| 415 | */ | 461 | */ |
| 416 | skb_put(skb, oq->max_single_buffer_size); | 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 | shinfo = skb_shinfo(skb); | 463 | shinfo = skb_shinfo(skb); |
| 423 | data_len = buff_info->len - oq->max_single_buffer_size; | 464 | data_len = buff_info->len - oq->max_single_buffer_size; |
| 424 | while (data_len) { | 465 | while (data_len) { |
| 425 | dma_unmap_page(oq->dev, oq->desc_ring[read_idx].buffer_ptr, | ||
| 426 | PAGE_SIZE, DMA_FROM_DEVICE); | ||
| 427 | buff_info = (struct octep_rx_buffer *) | 466 | buff_info = (struct octep_rx_buffer *) |
| 428 | &oq->buff_info[read_idx]; | 467 | &oq->buff_info[read_idx]; |
| 429 | if (data_len < oq->buffer_size) { | 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 | buff_info->page, 0, | 477 | buff_info->page, 0, |
| 439 | buff_info->len, | 478 | buff_info->len, |
| 440 | buff_info->len); | 479 | buff_info->len); |
| 441 | buff_info->page = NULL; | 480 | |
| 442 | read_idx++; | 481 | octep_oq_next_pkt(oq, buff_info, &read_idx, &desc_used); |
| 443 | desc_used++; | ||
| 444 | if (read_idx == oq->max_count) | ||
| 445 | read_idx = 0; | ||
| 446 | } | 482 | } |
| 447 | } | 483 | } |
| 448 | 484 | ||
| @@ -2411,7 +2411,7 @@ static int nix_smq_flush(struct rvu *rvu, int blkaddr, · 2410 unmodified lines | |||
| 2411 | NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link)); | 2411 | NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link)); |
| 2412 | if (!(cfg & BIT_ULL(12))) | 2412 | if (!(cfg & BIT_ULL(12))) |
| 2413 | continue; | 2413 | continue; |
| 2414 | bmap |= (1 << i); | 2414 | bmap |= BIT_ULL(i); |
| 2415 | cfg &= ~BIT_ULL(12); | 2415 | cfg &= ~BIT_ULL(12); |
| 2416 | rvu_write64(rvu, blkaddr, | 2416 | rvu_write64(rvu, blkaddr, |
| 2417 | NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link), cfg); | 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 | /* Set NIX_AF_TL3_TL2_LINKX_CFG[ENA] for the TL3/TL2 queue */ | 2433 | /* Set NIX_AF_TL3_TL2_LINKX_CFG[ENA] for the TL3/TL2 queue */ |
| 2434 | for (i = 0; i < (rvu->hw->cgx_links + rvu->hw->lbk_links); i++) { | 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 | continue; | 2436 | continue; |
| 2437 | cfg = rvu_read64(rvu, blkaddr, | 2437 | cfg = rvu_read64(rvu, blkaddr, |
| 2438 | NIX_AF_TL3_TL2X_LINKX_CFG(tl2_tl3_link_schq, link)); | 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 | e->dma_addr = addr; | 2471 | e->dma_addr = addr; |
| 2472 | e->dma_len = len; | 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 | data = skb_frag_address(frag); | 2474 | data = skb_frag_address(frag); |
| 2479 | len = skb_frag_size(frag); | 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 | q->queued += i; | 2479 | q->queued += i; |
| 2484 | 2480 | ||
| 2485 | skb_tx_timestamp(skb); | 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 | if (q->ndesc - q->queued < q->free_thr) | 2487 | if (q->ndesc - q->queued < q->free_thr) |
| 2487 | netif_tx_stop_queue(txq); | 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 | if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) | 1171 | if (unlikely(dma_mapping_error(eth->dma_dev, dma_addr))) |
| 1172 | return -ENOMEM; | 1172 | return -ENOMEM; |
| 1173 | 1173 | ||
| 1174 | for (i = 0; i < cnt; i++) { | 1174 | for (i = 0; i < len; i++) { |
| 1175 | struct mtk_tx_dma_v2 *txd; | 1175 | struct mtk_tx_dma_v2 *txd; |
| 1176 | 1176 | ||
| 1177 | txd = eth->scratch_ring + (j * MTK_FQ_DMA_LENGTH + i) * soc->tx.desc_size; | 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 | #define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin" | 91 | #define MT7981_FIRMWARE_WO "mediatek/mt7981_wo.bin" |
| 92 | #define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin" | 92 | #define MT7986_FIRMWARE_WO0 "mediatek/mt7986_wo_0.bin" |
| 93 | #define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin" | 93 | #define MT7986_FIRMWARE_WO1 "mediatek/mt7986_wo_1.bin" |
| 94 | #define MT7988_FIRMWARE_WO0 "mediatek/mt7988_wo_0.bin" | 94 | #define MT7988_FIRMWARE_WO0 "mediatek/mt7988/mt7988_wo_0.bin" |
| 95 | #define MT7988_FIRMWARE_WO1 "mediatek/mt7988_wo_1.bin" | 95 | #define MT7988_FIRMWARE_WO1 "mediatek/mt7988/mt7988_wo_1.bin" |
| 96 | 96 | ||
| 97 | #define MTK_WO_MCU_CFG_LS_BASE 0 | 97 | #define MTK_WO_MCU_CFG_LS_BASE 0 |
| 98 | #define MTK_WO_MCU_CFG_LS_HW_VER_ADDR (MTK_WO_MCU_CFG_LS_BASE + 0x000) | 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 | static void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev) | 1772 | static void mlx5_cmd_trigger_completions(struct mlx5_core_dev *dev) |
| 1769 | { | 1773 | { |
| 1770 | struct mlx5_cmd *cmd = &dev->cmd; | 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 | /* wait for pending handlers to complete */ | 1780 | /* wait for pending handlers to complete */ |
| 1777 | mlx5_eq_synchronize_cmd_irq(dev); | 1781 | mlx5_eq_synchronize_cmd_irq(dev); |
| 1778 | spin_lock_irqsave(&dev->cmd.alloc_lock, flags); | 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 | if (!vector) | 1784 | if (!vector) |
| 1781 | goto no_trig; | 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 | cmd->state = MLX5_CMDIF_STATE_DOWN; | 2366 | cmd->state = MLX5_CMDIF_STATE_DOWN; |
| 2363 | cmd->vars.max_reg_cmds = (1 << cmd->vars.log_sz) - 1; | 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 | sema_init(&cmd->vars.sem, cmd->vars.max_reg_cmds); | 2370 | sema_init(&cmd->vars.sem, cmd->vars.max_reg_cmds); |
| 2367 | sema_init(&cmd->vars.pages_sem, 1); | 2371 | sema_init(&cmd->vars.pages_sem, 1); |
| @@ -6509,7 +6509,9 @@ static void _mlx5e_remove(struct auxiliary_device *adev) · 6508 unmodified lines | |||
| 6509 | mlx5e_dcbnl_delete_app(priv); | 6509 | mlx5e_dcbnl_delete_app(priv); |
| 6510 | unregister_netdev(priv->netdev); | 6510 | unregister_netdev(priv->netdev); |
| 6511 | _mlx5e_suspend(adev, false); | 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 | mlx5e_destroy_netdev(priv); | 6515 | mlx5e_destroy_netdev(priv); |
| 6514 | mlx5e_devlink_port_unregister(mlx5e_dev); | 6516 | mlx5e_devlink_port_unregister(mlx5e_dev); |
| 6515 | mlx5e_destroy_devlink(mlx5e_dev); | 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 | struct mlx5_eq_comp *eq; | 1061 | struct mlx5_eq_comp *eq; |
| 1062 | int ret = 0; | 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 | mutex_lock(&table->comp_lock); | 1070 | mutex_lock(&table->comp_lock); |
| 1065 | eq = xa_load(&table->comp_eqs, vecidx); | 1071 | eq = xa_load(&table->comp_eqs, vecidx); |
| 1066 | if (eq) { | 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 | if (err) | 1491 | if (err) |
| 1492 | goto abort; | 1492 | goto err_esw_enable; |
| 1493 | 1493 | ||
| 1494 | esw->fdb_table.flags |= MLX5_ESW_FDB_CREATED; | 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 | return 0; | 1504 | return 0; |
| 1505 | 1505 | ||
| 1506 | abort: | 1506 | err_esw_enable: |
| 1507 | mlx5_eq_notifier_unregister(esw->dev, &esw->nb); | ||
| 1507 | mlx5_esw_acls_ns_cleanup(esw); | 1508 | mlx5_esw_acls_ns_cleanup(esw); |
| 1508 | return err; | 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 | static int | 691 | static int |
| 692 | hws_bwc_matcher_rehash_size(struct mlx5hws_bwc_matcher *bwc_matcher) | 692 | hws_bwc_matcher_rehash_size(struct mlx5hws_bwc_matcher *bwc_matcher) |
| 693 | { | 693 | { |
| 694 | u32 num_of_rules; | ||
| 695 | int ret; | 694 | int ret; |
| 696 | 695 | ||
| 697 | /* If the current matcher size is already at its max size, we can't | 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 | * Need to check again if we really need rehash. | 704 | * Need to check again if we really need rehash. |
| 706 | * If the reason for rehash was size, but not any more - skip rehash. | 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); | 707 | if (!hws_bwc_matcher_rehash_size_needed(bwc_matcher, bwc_matcher->num_of_rules)) |
| 709 | if (!hws_bwc_matcher_rehash_size_needed(bwc_matcher, num_of_rules)) | ||
| 710 | return 0; | 708 | return 0; |
| 711 | 709 | ||
| 712 | /* Now we're done all the checking - do the rehash: | 710 | /* Now we're done all the checking - do the rehash: |
| @@ -46,6 +46,7 @@ struct mlx5hws_context { · 45 unmodified lines | |||
| 46 | struct mlx5hws_send_engine *send_queue; | 46 | struct mlx5hws_send_engine *send_queue; |
| 47 | size_t queues; | 47 | size_t queues; |
| 48 | struct mutex *bwc_send_queue_locks; /* protect BWC queues */ | 48 | struct mutex *bwc_send_queue_locks; /* protect BWC queues */ |
| 49 | struct lock_class_key *bwc_lock_class_keys; | ||
| 49 | struct list_head tbl_list; | 50 | struct list_head tbl_list; |
| 50 | struct mlx5hws_context_debug_info debug_info; | 51 | struct mlx5hws_context_debug_info debug_info; |
| 51 | struct xarray peer_ctx_xa; | 52 | struct xarray peer_ctx_xa; |
| @@ -1925,7 +1925,7 @@ mlx5hws_definer_calc_layout(struct mlx5hws_context *ctx, · 1924 unmodified lines | |||
| 1925 | ret = hws_definer_conv_match_params_to_hl(ctx, mt, match_hl); | 1925 | ret = hws_definer_conv_match_params_to_hl(ctx, mt, match_hl); |
| 1926 | if (ret) { | 1926 | if (ret) { |
| 1927 | mlx5hws_err(ctx, "Failed to convert items to header layout\n"); | 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 | /* Find the match definer layout for header layout match union */ | 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 | free_fc: | 1947 | free_fc: |
| 1948 | kfree(mt->fc); | 1948 | kfree(mt->fc); |
| 1949 | 1949 | free_match_hl: | |
| 1950 | kfree(match_hl); | 1950 | kfree(match_hl); |
| 1951 | return ret; | 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 | static void hws_send_queues_bwc_locks_destroy(struct mlx5hws_context *ctx) | 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 | int i; | 945 | int i; |
| 946 | 946 | ||
| 947 | if (!mlx5hws_context_bwc_supported(ctx)) | 947 | if (!mlx5hws_context_bwc_supported(ctx)) |
| 948 | return; | 948 | return; |
| 949 | 949 | ||
| 950 | for (i = 0; i < bwc_queues; i++) | 950 | for (i = 0; i < bwc_queues; i++) { |
| 951 | mutex_destroy(&ctx->bwc_send_queue_locks[i]); | 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 | kfree(ctx->bwc_send_queue_locks); | 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 | if (!ctx->bwc_send_queue_locks) | 981 | if (!ctx->bwc_send_queue_locks) |
| 978 | return -ENOMEM; | 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 | mutex_init(&ctx->bwc_send_queue_locks[i]); | 991 | mutex_init(&ctx->bwc_send_queue_locks[i]); |
| 992 | lockdep_register_key(ctx->bwc_lock_class_keys + i); | ||
| 993 | } | ||
| 982 | 994 | ||
| 983 | return 0; | 995 | return 0; |
| 996 | |||
| 997 | err_lock_class_keys: | ||
| 998 | kfree(ctx->bwc_send_queue_locks); | ||
| 999 | return -ENOMEM; | ||
| 984 | } | 1000 | } |
| 985 | 1001 | ||
| 986 | int mlx5hws_send_queues_open(struct mlx5hws_context *ctx, | 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 | dma_unmap_single(&pdev->dev, mapaddr, frag_len, direction); | 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 | u16 byte_count) | 394 | u16 byte_count) |
| 394 | { | 395 | { |
| 396 | struct mlxsw_pci_queue *cq = q->u.rdq.cq; | ||
| 395 | unsigned int linear_data_size; | 397 | unsigned int linear_data_size; |
| 398 | struct page_pool *page_pool; | ||
| 396 | struct sk_buff *skb; | 399 | struct sk_buff *skb; |
| 397 | int page_index = 0; | 400 | int page_index = 0; |
| 398 | bool linear_only; | 401 | bool linear_only; |
| 399 | void *data; | 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 | data = page_address(pages[page_index]); | 413 | data = page_address(pages[page_index]); |
| 402 | net_prefetch(data); | 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 | if (unlikely(!skb)) | 417 | if (unlikely(!skb)) |
| 406 | return ERR_PTR(-ENOMEM); | 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 | skb_reserve(skb, MLXSW_PCI_SKB_HEADROOM); | 420 | skb_reserve(skb, MLXSW_PCI_SKB_HEADROOM); |
| 414 | skb_put(skb, linear_data_size); | 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 | page = pages[page_index]; | 433 | page = pages[page_index]; |
| 427 | frag_size = min(byte_count, PAGE_SIZE); | 434 | frag_size = min(byte_count, PAGE_SIZE); |
| 435 | page_pool_dma_sync_for_cpu(page_pool, page, 0, frag_size); | ||
| 428 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, | 436 | skb_add_rx_frag(skb, skb_shinfo(skb)->nr_frags, |
| 429 | page, 0, frag_size, PAGE_SIZE); | 437 | page, 0, frag_size, PAGE_SIZE); |
| 430 | byte_count -= frag_size; | 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 | if (err) | 768 | if (err) |
| 761 | goto out; | 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 | if (IS_ERR(skb)) { | 772 | if (IS_ERR(skb)) { |
| 765 | dev_err_ratelimited(&pdev->dev, "Failed to build skb for RDQ\n"); | 773 | dev_err_ratelimited(&pdev->dev, "Failed to build skb for RDQ\n"); |
| 766 | mlxsw_pci_rdq_pages_recycle(q, pages, num_sg_entries); | 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 | if (cq_type != MLXSW_PCI_CQ_RDQ) | 996 | if (cq_type != MLXSW_PCI_CQ_RDQ) |
| 989 | return 0; | 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 | pp_params.pool_size = MLXSW_PCI_WQE_COUNT * mlxsw_pci->num_sg_entries; | 1000 | pp_params.pool_size = MLXSW_PCI_WQE_COUNT * mlxsw_pci->num_sg_entries; |
| 993 | pp_params.nid = dev_to_node(&mlxsw_pci->pdev->dev); | 1001 | pp_params.nid = dev_to_node(&mlxsw_pci->pdev->dev); |
| 994 | pp_params.dev = &mlxsw_pci->pdev->dev; | 1002 | pp_params.dev = &mlxsw_pci->pdev->dev; |
| 995 | pp_params.napi = &q->u.cq.napi; | 1003 | pp_params.napi = &q->u.cq.napi; |
| 996 | pp_params.dma_dir = DMA_FROM_DEVICE; | 1004 | pp_params.dma_dir = DMA_FROM_DEVICE; |
| 1005 | pp_params.max_len = PAGE_SIZE; | ||
| 997 | 1006 | ||
| 998 | page_pool = page_pool_create(&pp_params); | 1007 | page_pool = page_pool_create(&pp_params); |
| 999 | if (IS_ERR(page_pool)) | 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 | struct mlxsw_sp_ipip_entry *ipip_entry, | 481 | struct mlxsw_sp_ipip_entry *ipip_entry, |
| 482 | struct netlink_ext_ack *extack) | 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 | struct mlxsw_sp_ipip_parms new_parms; | 486 | struct mlxsw_sp_ipip_parms new_parms; |
| 487 | int err; | ||
| 485 | 488 | ||
| 486 | new_parms = mlxsw_sp_ipip_netdev_parms_init_gre6(ipip_entry->ol_dev); | 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, | 490 | |
| 488 | &new_parms, extack); | 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 | static int | 513 | static int |
| @@ -16,6 +16,7 @@ · 15 unmodified lines | |||
| 16 | #include "spectrum.h" | 16 | #include "spectrum.h" |
| 17 | #include "spectrum_ptp.h" | 17 | #include "spectrum_ptp.h" |
| 18 | #include "core.h" | 18 | #include "core.h" |
| 19 | #include "txheader.h" | ||
| 19 | 20 | ||
| 20 | #define MLXSW_SP1_PTP_CLOCK_CYCLES_SHIFT 29 | 21 | #define MLXSW_SP1_PTP_CLOCK_CYCLES_SHIFT 29 |
| 21 | #define MLXSW_SP1_PTP_CLOCK_FREQ_KHZ 156257 /* 6.4nSec */ | 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 | struct sk_buff *skb, | 1685 | struct sk_buff *skb, |
| 1685 | const struct mlxsw_tx_info *tx_info) | 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 | mlxsw_sp_txhdr_construct(skb, tx_info); | 1694 | mlxsw_sp_txhdr_construct(skb, tx_info); |
| 1688 | return 0; | 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 | struct mlxsw_sp_nexthop_group *nh_grp = nh->nhgi->nh_grp; | 3198 | struct mlxsw_sp_nexthop_group *nh_grp = nh->nhgi->nh_grp; |
| 3199 | struct mlxsw_sp_nexthop_counter *nhct; | 3199 | struct mlxsw_sp_nexthop_counter *nhct; |
| 3200 | void *ptr; | ||
| 3201 | int err; | 3200 | int err; |
| 3202 | 3201 | ||
| 3203 | nhct = xa_load(&nh_grp->nhgi->nexthop_counters, nh->id); | 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 | if (IS_ERR(nhct)) | 3209 | if (IS_ERR(nhct)) |
| 3211 | return nhct; | 3210 | return nhct; |
| 3212 | 3211 | ||
| 3213 | ptr = xa_store(&nh_grp->nhgi->nexthop_counters, nh->id, nhct, | 3212 | err = xa_err(xa_store(&nh_grp->nhgi->nexthop_counters, nh->id, nhct, |
| 3214 | GFP_KERNEL); | 3213 | GFP_KERNEL)); |
| 3215 | if (IS_ERR(ptr)) { | 3214 | if (err) |
| 3216 | err = PTR_ERR(ptr); | ||
| 3217 | goto err_store; | 3215 | goto err_store; |
| 3218 | } | ||
| 3219 | 3216 | ||
| 3220 | return nhct; | 3217 | return nhct; |
| 3221 | 3218 | ||
| @@ -401,28 +401,21 @@ static int lan743x_ptpci_settime64(struct ptp_clock_info *ptpci, · 400 unmodified lines | |||
| 401 | u32 nano_seconds = 0; | 401 | u32 nano_seconds = 0; |
| 402 | u32 seconds = 0; | 402 | u32 seconds = 0; |
| 403 | 403 | ||
| 404 | if (ts) { | 404 | if (ts->tv_sec > 0xFFFFFFFFLL) { |
| 405 | if (ts->tv_sec > 0xFFFFFFFFLL || | 405 | netif_warn(adapter, drv, adapter->netdev, |
| 406 | ts->tv_sec < 0) { | 406 | "ts->tv_sec out of range, %lld\n", |
| 407 | netif_warn(adapter, drv, adapter->netdev, | 407 | ts->tv_sec); |
| 408 | "ts->tv_sec out of range, %lld\n", | 408 | return -ERANGE; |
| 409 | ts->tv_sec); | 409 | } |
| 410 | return -ERANGE; | 410 | if (ts->tv_nsec < 0) { |
| 411 | } | 411 | netif_warn(adapter, drv, adapter->netdev, |
| 412 | if (ts->tv_nsec >= 1000000000L || | 412 | "ts->tv_nsec out of range, %ld\n", |
| 413 | ts->tv_nsec < 0) { | 413 | ts->tv_nsec); |
| 414 | netif_warn(adapter, drv, adapter->netdev, | 414 | return -ERANGE; |
| 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; | ||
| 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 | return 0; | 420 | return 0; |
| 428 | } | 421 | } |
| @@ -31,10 +31,10 @@ static u64 sparx5_mirror_port_get(struct sparx5 *sparx5, u32 idx) · 30 unmodified lines | |||
| 31 | /* Add port to mirror (only front ports) */ | 31 | /* Add port to mirror (only front ports) */ |
| 32 | static void sparx5_mirror_port_add(struct sparx5 *sparx5, u32 idx, u32 portno) | 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(do_div(reg, 32)); |
| 37 | val = BIT(portno % BITS_PER_BYTE); | ||
| 38 | 38 | ||
| 39 | if (reg == 0) | 39 | if (reg == 0) |
| 40 | return spx5_rmw(val, val, sparx5, ANA_AC_PROBE_PORT_CFG(idx)); | 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 | /* Delete port from mirror (only front ports) */ | 45 | /* Delete port from mirror (only front ports) */ |
| 46 | static void sparx5_mirror_port_del(struct sparx5 *sparx5, u32 idx, u32 portno) | 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(do_div(reg, 32)); |
| 51 | val = BIT(portno % BITS_PER_BYTE); | ||
| 52 | 52 | ||
| 53 | if (reg == 0) | 53 | if (reg == 0) |
| 54 | return spx5_rmw(0, val, sparx5, ANA_AC_PROBE_PORT_CFG(idx)); | 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 | ret = vcap_del_rule(&test_vctrl, &test_netdev, id); | 1445 | ret = vcap_del_rule(&test_vctrl, &test_netdev, id); |
| 1446 | KUNIT_EXPECT_EQ(test, 0, ret); | 1446 | KUNIT_EXPECT_EQ(test, 0, ret); |
| 1447 | |||
| 1448 | vcap_free_rule(rule); | ||
| 1447 | } | 1449 | } |
| 1448 | 1450 | ||
| 1449 | static void vcap_api_set_rule_counter_test(struct kunit *test) | 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 | if ((status & 0xffff) == 0xffff || !(status & tp->irq_mask)) | 4682 | if ((status & 0xffff) == 0xffff || !(status & tp->irq_mask)) |
| 4683 | return IRQ_NONE; | 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 | rtl8169_pcierr_interrupt(tp->dev); | 4688 | rtl8169_pcierr_interrupt(tp->dev); |
| 4687 | goto out; | 4689 | goto out; |
| 4688 | } | 4690 | } |
| @@ -1750,20 +1750,19 @@ static int ravb_get_ts_info(struct net_device *ndev, · 1749 unmodified lines | |||
| 1750 | struct ravb_private *priv = netdev_priv(ndev); | 1750 | struct ravb_private *priv = netdev_priv(ndev); |
| 1751 | const struct ravb_hw_info *hw_info = priv->info; | 1751 | const struct ravb_hw_info *hw_info = priv->info; |
| 1752 | 1752 | ||
| 1753 | info->so_timestamping = | 1753 | if (hw_info->gptp || hw_info->ccc_gac) { |
| 1754 | SOF_TIMESTAMPING_TX_SOFTWARE | | 1754 | info->so_timestamping = |
| 1755 | SOF_TIMESTAMPING_TX_HARDWARE | | 1755 | SOF_TIMESTAMPING_TX_SOFTWARE | |
| 1756 | SOF_TIMESTAMPING_RX_HARDWARE | | 1756 | SOF_TIMESTAMPING_TX_HARDWARE | |
| 1757 | SOF_TIMESTAMPING_RAW_HARDWARE; | 1757 | SOF_TIMESTAMPING_RX_HARDWARE | |
| 1758 | info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON); | 1758 | SOF_TIMESTAMPING_RAW_HARDWARE; |
| 1759 | info->rx_filters = | 1759 | info->tx_types = (1 << HWTSTAMP_TX_OFF) | (1 << HWTSTAMP_TX_ON); |
| 1760 | (1 << HWTSTAMP_FILTER_NONE) | | 1760 | info->rx_filters = |
| 1761 | (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | | 1761 | (1 << HWTSTAMP_FILTER_NONE) | |
| 1762 | (1 << HWTSTAMP_FILTER_ALL); | 1762 | (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) | |
| 1763 | if (hw_info->gptp || hw_info->ccc_gac) | 1763 | (1 << HWTSTAMP_FILTER_ALL); |
| 1764 | info->phc_index = ptp_clock_index(priv->ptp.clock); | 1764 | info->phc_index = ptp_clock_index(priv->ptp.clock); |
| 1765 | else | 1765 | } |
| 1766 | info->phc_index = 0; | ||
| 1767 | 1766 | ||
| 1768 | return 0; | 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 | if (skb->len >= TX_DS) { | 1057 | if (skb->len >= TX_DS) { |
| 1058 | priv->stats.tx_dropped++; | 1058 | priv->stats.tx_dropped++; |
| 1059 | priv->stats.tx_errors++; | 1059 | priv->stats.tx_errors++; |
| 1060 | dev_kfree_skb_any(skb); | ||
| 1060 | goto out; | 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 | spent = efx_process_channel(channel, budget); | 1261 | spent = efx_process_channel(channel, budget); |
| 1262 | 1262 | ||
| 1263 | xdp_do_flush(); | 1263 | if (budget) |
| 1264 | xdp_do_flush(); | ||
| 1264 | 1265 | ||
| 1265 | if (spent < budget) { | 1266 | if (spent < budget) { |
| 1266 | if (efx_channel_has_rx_queue(channel) && | 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 | spent = efx_process_channel(channel, budget); | 1286 | spent = efx_process_channel(channel, budget); |
| 1287 | 1287 | ||
| 1288 | xdp_do_flush(); | 1288 | if (budget) |
| 1289 | xdp_do_flush(); | ||
| 1289 | 1290 | ||
| 1290 | if (spent < budget) { | 1291 | if (spent < budget) { |
| 1291 | if (efx_channel_has_rx_queue(channel) && | 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 | value &= ~XPCS_WRAP_UPHY_RX_CONTROL_AUX_RX_IDDQ; | 127 | value &= ~XPCS_WRAP_UPHY_RX_CONTROL_AUX_RX_IDDQ; |
| 128 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 131 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 131 | value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_SLEEP; | 132 | value &= ~XPCS_WRAP_UPHY_RX_CONTROL_RX_SLEEP; |
| 132 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 136 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 135 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CAL_EN; | 137 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_CAL_EN; |
| 136 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | return err; | 145 | return err; |
| 144 | } | 146 | } |
| 145 | 147 | ||
| 148 | usleep_range(10, 20); /* 50ns min delay needed as per HW design */ | ||
| 146 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 149 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 147 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_DATA_EN; | 150 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_DATA_EN; |
| 148 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 151 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 149 | 152 | ||
| 150 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 163 | value = readl(mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); |
| 159 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_PCS_PHY_RDY; | 164 | value |= XPCS_WRAP_UPHY_RX_CONTROL_RX_PCS_PHY_RDY; |
| 160 | writel(value, mgbe->xpcs + XPCS_WRAP_UPHY_RX_CONTROL); | 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 | err = readl_poll_timeout(mgbe->xpcs + XPCS_WRAP_IRQ_STATUS, value, | 172 | err = readl_poll_timeout(mgbe->xpcs + XPCS_WRAP_IRQ_STATUS, value, |
| 163 | value & XPCS_WRAP_IRQ_STATUS_PCS_LINK_STS, | 173 | value & XPCS_WRAP_IRQ_STATUS_PCS_LINK_STS, |
| 164 | 500, 500 * 2000); | 174 | 500, 500 * 2000); |
| @@ -203,8 +203,12 @@ static void _dwmac4_dump_dma_regs(struct stmmac_priv *priv, · 202 unmodified lines | |||
| 203 | readl(ioaddr + DMA_CHAN_TX_CONTROL(dwmac4_addrs, channel)); | 203 | readl(ioaddr + DMA_CHAN_TX_CONTROL(dwmac4_addrs, channel)); |
| 204 | reg_space[DMA_CHAN_RX_CONTROL(default_addrs, channel) / 4] = | 204 | reg_space[DMA_CHAN_RX_CONTROL(default_addrs, channel) / 4] = |
| 205 | readl(ioaddr + DMA_CHAN_RX_CONTROL(dwmac4_addrs, channel)); | 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 | reg_space[DMA_CHAN_TX_BASE_ADDR(default_addrs, channel) / 4] = | 208 | reg_space[DMA_CHAN_TX_BASE_ADDR(default_addrs, channel) / 4] = |
| 207 | readl(ioaddr + DMA_CHAN_TX_BASE_ADDR(dwmac4_addrs, channel)); | 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 | reg_space[DMA_CHAN_RX_BASE_ADDR(default_addrs, channel) / 4] = | 212 | reg_space[DMA_CHAN_RX_BASE_ADDR(default_addrs, channel) / 4] = |
| 209 | readl(ioaddr + DMA_CHAN_RX_BASE_ADDR(dwmac4_addrs, channel)); | 213 | readl(ioaddr + DMA_CHAN_RX_BASE_ADDR(dwmac4_addrs, channel)); |
| 210 | reg_space[DMA_CHAN_TX_END_ADDR(default_addrs, channel) / 4] = | 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 | readl(ioaddr + DMA_CHAN_CUR_TX_DESC(dwmac4_addrs, channel)); | 229 | readl(ioaddr + DMA_CHAN_CUR_TX_DESC(dwmac4_addrs, channel)); |
| 226 | reg_space[DMA_CHAN_CUR_RX_DESC(default_addrs, channel) / 4] = | 230 | reg_space[DMA_CHAN_CUR_RX_DESC(default_addrs, channel) / 4] = |
| 227 | readl(ioaddr + DMA_CHAN_CUR_RX_DESC(dwmac4_addrs, channel)); | 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 | reg_space[DMA_CHAN_CUR_TX_BUF_ADDR(default_addrs, channel) / 4] = | 234 | reg_space[DMA_CHAN_CUR_TX_BUF_ADDR(default_addrs, channel) / 4] = |
| 229 | readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR(dwmac4_addrs, channel)); | 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 | reg_space[DMA_CHAN_CUR_RX_BUF_ADDR(default_addrs, channel) / 4] = | 238 | reg_space[DMA_CHAN_CUR_RX_BUF_ADDR(default_addrs, channel) / 4] = |
| 231 | readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR(dwmac4_addrs, channel)); | 239 | readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR(dwmac4_addrs, channel)); |
| 232 | reg_space[DMA_CHAN_STATUS(default_addrs, channel) / 4] = | 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 | #define DMA_CHAN_SLOT_CTRL_STATUS(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x3c) | 127 | #define DMA_CHAN_SLOT_CTRL_STATUS(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x3c) |
| 128 | #define DMA_CHAN_CUR_TX_DESC(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x44) | 128 | #define DMA_CHAN_CUR_TX_DESC(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x44) |
| 129 | #define DMA_CHAN_CUR_RX_DESC(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x4c) | 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 | #define DMA_CHAN_CUR_TX_BUF_ADDR(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x54) | 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 | #define DMA_CHAN_CUR_RX_BUF_ADDR(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x5c) | 133 | #define DMA_CHAN_CUR_RX_BUF_ADDR(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x5c) |
| 132 | #define DMA_CHAN_STATUS(addrs, x) (dma_chanx_base_addr(addrs, x) + 0x60) | 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 | rx_q->queue_index = queue; | 2035 | rx_q->queue_index = queue; |
| 2036 | rx_q->priv_data = priv; | 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 | pp_params.pool_size = dma_conf->dma_rx_size; | 2039 | pp_params.pool_size = dma_conf->dma_rx_size; |
| 2040 | num_pages = DIV_ROUND_UP(dma_conf->dma_buf_sz, PAGE_SIZE); | 2040 | num_pages = DIV_ROUND_UP(dma_conf->dma_buf_sz, PAGE_SIZE); |
| 2041 | pp_params.order = ilog2(num_pages); | 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 | if (dma_mapping_error(priv->device, des)) | 4304 | if (dma_mapping_error(priv->device, des)) |
| 4305 | goto dma_map_err; | 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 | if (priv->dma_cap.addr64 <= 32) { | 4307 | if (priv->dma_cap.addr64 <= 32) { |
| 4313 | first->des0 = cpu_to_le32(des); | 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 | stmmac_tso_allocator(priv, des, tmp_pay_len, (nfrags == 0), queue); | 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 | /* Prepare fragments */ | 4342 | /* Prepare fragments */ |
| 4331 | for (i = 0; i < nfrags; i++) { | 4343 | for (i = 0; i < nfrags; i++) { |
| 4332 | const skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; | 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 | return 0; | 2744 | return 0; |
| 2745 | 2745 | ||
| 2746 | /* alloc netdev */ | 2746 | /* alloc netdev */ |
| 2747 | port->ndev = devm_alloc_etherdev_mqs(common->dev, | 2747 | port->ndev = alloc_etherdev_mqs(sizeof(struct am65_cpsw_ndev_priv), |
| 2748 | sizeof(struct am65_cpsw_ndev_priv), | 2748 | AM65_CPSW_MAX_QUEUES, |
| 2749 | AM65_CPSW_MAX_QUEUES, | 2749 | AM65_CPSW_MAX_QUEUES); |
| 2750 | AM65_CPSW_MAX_QUEUES); | ||
| 2751 | if (!port->ndev) { | 2750 | if (!port->ndev) { |
| 2752 | dev_err(dev, "error allocating slave net_device %u\n", | 2751 | dev_err(dev, "error allocating slave net_device %u\n", |
| 2753 | port->port_id); | 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 | for (i = 0; i < common->port_num; i++) { | 2868 | for (i = 0; i < common->port_num; i++) { |
| 2870 | port = &common->ports[i]; | 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 | unregister_netdev(port->ndev); | 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 | ret = am65_cpsw_nuss_init_ndevs(common); | 3617 | ret = am65_cpsw_nuss_init_ndevs(common); |
| 3615 | if (ret) | 3618 | if (ret) |
| 3616 | goto err_free_phylink; | 3619 | goto err_ndevs_clear; |
| 3617 | 3620 | ||
| 3618 | ret = am65_cpsw_nuss_register_ndevs(common); | 3621 | ret = am65_cpsw_nuss_register_ndevs(common); |
| 3619 | if (ret) | 3622 | if (ret) |
| 3620 | goto err_free_phylink; | 3623 | goto err_ndevs_clear; |
| 3621 | 3624 | ||
| 3622 | pm_runtime_put(dev); | 3625 | pm_runtime_put(dev); |
| 3623 | return 0; | 3626 | return 0; |
| 3624 | 3627 | ||
| 3625 | err_free_phylink: | 3628 | err_ndevs_clear: |
| 3629 | am65_cpsw_nuss_cleanup_ndev(common); | ||
| 3626 | am65_cpsw_nuss_phylink_cleanup(common); | 3630 | am65_cpsw_nuss_phylink_cleanup(common); |
| 3627 | am65_cpts_release(common->cpts); | 3631 | am65_cpts_release(common->cpts); |
| 3628 | err_of_clear: | 3632 | err_of_clear: |
| @@ -3652,13 +3656,13 @@ static void am65_cpsw_nuss_remove(struct platform_device *pdev) · 23 unmodified lines | |||
| 3652 | return; | 3656 | return; |
| 3653 | } | 3657 | } |
| 3654 | 3658 | ||
| 3655 | am65_cpsw_unregister_devlink(common); | ||
| 3656 | am65_cpsw_unregister_notifiers(common); | 3659 | am65_cpsw_unregister_notifiers(common); |
| 3657 | 3660 | ||
| 3658 | /* must unregister ndevs here because DD release_driver routine calls | 3661 | /* must unregister ndevs here because DD release_driver routine calls |
| 3659 | * dma_deconfigure(dev) before devres_release_all(dev) | 3662 | * dma_deconfigure(dev) before devres_release_all(dev) |
| 3660 | */ | 3663 | */ |
| 3661 | am65_cpsw_nuss_cleanup_ndev(common); | 3664 | am65_cpsw_nuss_cleanup_ndev(common); |
| 3665 | am65_cpsw_unregister_devlink(common); | ||
| 3662 | am65_cpsw_nuss_phylink_cleanup(common); | 3666 | am65_cpsw_nuss_phylink_cleanup(common); |
| 3663 | am65_cpts_release(common->cpts); | 3667 | am65_cpts_release(common->cpts); |
| 3664 | am65_cpsw_disable_serdes_phy(common); | 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 | u8 fid_c1; | 735 | u8 fid_c1; |
| 736 | 736 | ||
| 737 | tbl = prueth->vlan_tbl; | 737 | tbl = prueth->vlan_tbl; |
| 738 | spin_lock(&prueth->vtbl_lock); | ||
| 738 | fid_c1 = tbl[vid].fid_c1; | 739 | fid_c1 = tbl[vid].fid_c1; |
| 739 | 740 | ||
| 740 | /* FID_C1: bit0..2 port membership mask, | 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 | tbl[vid].fid_c1 = fid_c1; | 753 | tbl[vid].fid_c1 = fid_c1; |
| 754 | spin_unlock(&prueth->vtbl_lock); | ||
| 753 | } | 755 | } |
| 754 | EXPORT_SYMBOL_GPL(icssg_vtbl_modify); | 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 | icss_iep_init_fw(prueth->iep1); | 1442 | icss_iep_init_fw(prueth->iep1); |
| 1443 | } | 1443 | } |
| 1444 | 1444 | ||
| 1445 | spin_lock_init(&prueth->vtbl_lock); | ||
| 1445 | /* setup netdev interfaces */ | 1446 | /* setup netdev interfaces */ |
| 1446 | if (eth0_node) { | 1447 | if (eth0_node) { |
| 1447 | ret = prueth_netdev_init(prueth, eth0_node); | 1448 | ret = prueth_netdev_init(prueth, eth0_node); |
| @@ -296,6 +296,8 @@ struct prueth { · 295 unmodified lines | |||
| 296 | bool is_switchmode_supported; | 296 | bool is_switchmode_supported; |
| 297 | unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN]; | 297 | unsigned char switch_id[MAX_PHYS_ITEM_ID_LEN]; |
| 298 | int default_vlan; | 298 | int default_vlan; |
| 299 | /** @vtbl_lock: Lock for vtbl in shared memory */ | ||
| 300 | spinlock_t vtbl_lock; | ||
| 299 | }; | 301 | }; |
| 300 | 302 | ||
| 301 | struct emac_tx_ts_response { | 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 | if (net_ratelimit()) | 1051 | if (net_ratelimit()) |
| 1052 | netdev_err(ndev, "TX DMA mapping error\n"); | 1052 | netdev_err(ndev, "TX DMA mapping error\n"); |
| 1053 | ndev->stats.tx_dropped++; | 1053 | ndev->stats.tx_dropped++; |
| 1054 | dev_kfree_skb_any(skb); | ||
| 1054 | return NETDEV_TX_OK; | 1055 | return NETDEV_TX_OK; |
| 1055 | } | 1056 | } |
| 1056 | desc_set_phys_addr(lp, phys, cur_p); | 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 | ndev->stats.tx_dropped++; | 1072 | ndev->stats.tx_dropped++; |
| 1072 | axienet_free_tx_chain(lp, orig_tail_ptr, ii + 1, | 1073 | axienet_free_tx_chain(lp, orig_tail_ptr, ii + 1, |
| 1073 | true, NULL, 0); | 1074 | true, NULL, 0); |
| 1075 | dev_kfree_skb_any(skb); | ||
| 1074 | return NETDEV_TX_OK; | 1076 | return NETDEV_TX_OK; |
| 1075 | } | 1077 | } |
| 1076 | desc_set_phys_addr(lp, phys, cur_p); | 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 | return -EINVAL; | 1702 | return -EINVAL; |
| 1703 | 1703 | ||
| 1704 | if (data[IFLA_GTP_FD0]) { | 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); | 1707 | if (fd0 >= 0) { |
| 1708 | if (IS_ERR(sk0)) | 1708 | sk0 = gtp_encap_enable_socket(fd0, UDP_ENCAP_GTP0, gtp); |
| 1709 | return PTR_ERR(sk0); | 1709 | if (IS_ERR(sk0)) |
| 1710 | return PTR_ERR(sk0); | ||
| 1711 | } | ||
| 1710 | } | 1712 | } |
| 1711 | 1713 | ||
| 1712 | if (data[IFLA_GTP_FD1]) { | 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); | 1717 | if (fd1 >= 0) { |
| 1716 | if (IS_ERR(sk1u)) { | 1718 | sk1u = gtp_encap_enable_socket(fd1, UDP_ENCAP_GTP1U, gtp); |
| 1717 | gtp_encap_disable_sock(sk0); | 1719 | if (IS_ERR(sk1u)) { |
| 1718 | return PTR_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 | * On Hyper-V, every VF interface is matched with a corresponding | 2827 | * On Hyper-V, every VF interface is matched with a corresponding |
| 2803 | * synthetic interface. The synthetic interface is presented first | 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 | struct net_device *event_dev = netdev_notifier_info_to_dev(ptr); | 2835 | struct net_device *event_dev = netdev_notifier_info_to_dev(ptr); |
| 2811 | int ret = 0; | 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 | ret = check_dev_is_matching_vf(event_dev); | 2843 | ret = check_dev_is_matching_vf(event_dev); |
| 2814 | if (ret != 0) | 2844 | if (ret != 0) |
| 2815 | return NOTIFY_DONE; | 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 | return sa; | 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 | static void free_rx_sc_rcu(struct rcu_head *head) | 157 | static void free_rx_sc_rcu(struct rcu_head *head) |
| 171 | { | 158 | { |
| 172 | struct macsec_rx_sc *rx_sc = container_of(head, struct macsec_rx_sc, rcu_head); | 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 | /* If validateFrames is Strict or the C bit in the | 1195 | /* If validateFrames is Strict or the C bit in the |
| 1209 | * SecTAG is set, discard | 1196 | * SecTAG is set, discard |
| 1210 | */ | 1197 | */ |
| 1211 | struct macsec_rx_sa *active_rx_sa = macsec_active_rxsa_get(rx_sc); | ||
| 1212 | if (hdr->tci_an & MACSEC_TCI_C || | 1198 | if (hdr->tci_an & MACSEC_TCI_C || |
| 1213 | secy->validate_frames == MACSEC_VALIDATE_STRICT) { | 1199 | secy->validate_frames == MACSEC_VALIDATE_STRICT) { |
| 1214 | u64_stats_update_begin(&rxsc_stats->syncp); | 1200 | u64_stats_update_begin(&rxsc_stats->syncp); |
| 1215 | rxsc_stats->stats.InPktsNotUsingSA++; | 1201 | rxsc_stats->stats.InPktsNotUsingSA++; |
| 1216 | u64_stats_update_end(&rxsc_stats->syncp); | 1202 | u64_stats_update_end(&rxsc_stats->syncp); |
| 1217 | DEV_STATS_INC(secy->netdev, rx_errors); | 1203 | DEV_STATS_INC(secy->netdev, rx_errors); |
| 1218 | if (active_rx_sa) | ||
| 1219 | this_cpu_inc(active_rx_sa->stats->InPktsNotUsingSA); | ||
| 1220 | goto drop_nosa; | 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 | u64_stats_update_begin(&rxsc_stats->syncp); | 1210 | u64_stats_update_begin(&rxsc_stats->syncp); |
| 1227 | rxsc_stats->stats.InPktsUnusedSA++; | 1211 | rxsc_stats->stats.InPktsUnusedSA++; |
| 1228 | u64_stats_update_end(&rxsc_stats->syncp); | 1212 | u64_stats_update_end(&rxsc_stats->syncp); |
| 1229 | if (active_rx_sa) | ||
| 1230 | this_cpu_inc(active_rx_sa->stats->InPktsUnusedSA); | ||
| 1231 | goto deliver; | 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 | struct macsec_dev *macsec = macsec_priv(dev); | 3799 | struct macsec_dev *macsec = macsec_priv(dev); |
| 3818 | 3800 | ||
| 3819 | if (macsec->secy.tx_sc.md_dst) | 3801 | dst_release(&macsec->secy.tx_sc.md_dst->dst); |
| 3820 | metadata_dst_free(macsec->secy.tx_sc.md_dst); | ||
| 3821 | free_percpu(macsec->stats); | 3802 | free_percpu(macsec->stats); |
| 3822 | free_percpu(macsec->secy.tx_sc.stats); | 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 | if (len > MCTP_I2C_MAXMTU) | 588 | if (len > MCTP_I2C_MAXMTU) |
| 589 | return -EMSGSIZE; | 589 | return -EMSGSIZE; |
| 590 | 590 | ||
| 591 | if (!daddr || !saddr) | ||
| 592 | return -EINVAL; | ||
| 593 | |||
| 591 | lldst = *((u8 *)daddr); | 594 | lldst = *((u8 *)daddr); |
| 592 | llsrc = *((u8 *)saddr); | 595 | llsrc = *((u8 *)saddr); |
| 593 | 596 | ||
| @@ -337,6 +337,7 @@ static const struct of_device_id unimac_mdio_ids[] = { · 336 unmodified lines | |||
| 337 | { .compatible = "brcm,asp-v2.2-mdio", }, | 337 | { .compatible = "brcm,asp-v2.2-mdio", }, |
| 338 | { .compatible = "brcm,asp-v2.1-mdio", }, | 338 | { .compatible = "brcm,asp-v2.1-mdio", }, |
| 339 | { .compatible = "brcm,asp-v2.0-mdio", }, | 339 | { .compatible = "brcm,asp-v2.0-mdio", }, |
| 340 | { .compatible = "brcm,bcm6846-mdio", }, | ||
| 340 | { .compatible = "brcm,genet-mdio-v5", }, | 341 | { .compatible = "brcm,genet-mdio-v5", }, |
| 341 | { .compatible = "brcm,genet-mdio-v4", }, | 342 | { .compatible = "brcm,genet-mdio-v4", }, |
| 342 | { .compatible = "brcm,genet-mdio-v3", }, | 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 | this_chunk = min(userdata_len - sent_userdata, | 1162 | this_chunk = min(userdata_len - sent_userdata, |
| 1163 | MAX_PRINT_CHUNK - preceding_bytes); | 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 | return; | 1170 | return; |
| 1171 | |||
| 1166 | memcpy(buf + this_header + this_offset, | 1172 | memcpy(buf + this_header + this_offset, |
| 1167 | userdata + sent_userdata, | 1173 | userdata + sent_userdata, |
| 1168 | this_chunk); | 1174 | this_chunk); |
| @@ -836,7 +836,8 @@ static void nsim_dev_trap_report_work(struct work_struct *work) · 835 unmodified lines | |||
| 836 | nsim_dev = nsim_trap_data->nsim_dev; | 836 | nsim_dev = nsim_trap_data->nsim_dev; |
| 837 | 837 | ||
| 838 | if (!devl_trylock(priv_to_devlink(nsim_dev))) { | 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 | return; | 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 | continue; | 849 | continue; |
| 849 | 850 | ||
| 850 | nsim_dev_trap_report(nsim_dev_port); | 851 | nsim_dev_trap_report(nsim_dev_port); |
| 852 | cond_resched(); | ||
| 851 | } | 853 | } |
| 852 | devl_unlock(priv_to_devlink(nsim_dev)); | 854 | devl_unlock(priv_to_devlink(nsim_dev)); |
| 853 | 855 | queue_delayed_work(system_unbound_wq, | |
| 854 | schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, | 856 | &nsim_dev->trap_data->trap_report_dw, |
| 855 | msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); | 857 | msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); |
| 856 | } | 858 | } |
| 857 | 859 | ||
| 858 | static int nsim_dev_traps_init(struct devlink *devlink) | 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 | INIT_DELAYED_WORK(&nsim_dev->trap_data->trap_report_dw, | 910 | INIT_DELAYED_WORK(&nsim_dev->trap_data->trap_report_dw, |
| 909 | nsim_dev_trap_report_work); | 911 | nsim_dev_trap_report_work); |
| 910 | schedule_delayed_work(&nsim_dev->trap_data->trap_report_dw, | 912 | queue_delayed_work(system_unbound_wq, |
| 911 | msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); | 913 | &nsim_dev->trap_data->trap_report_dw, |
| 914 | msecs_to_jiffies(NSIM_TRAP_REPORT_INTERVAL_MS)); | ||
| 912 | 915 | ||
| 913 | return 0; | 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 | if (pos != 0) | 1378 | if (pos != 0) |
| 1379 | return -EINVAL; | 1379 | return -EINVAL; |
| 1380 | if (size > sizeof(buf)) | 1380 | if (size > sizeof(buf) - 1) |
| 1381 | return -EINVAL; | 1381 | return -EINVAL; |
| 1382 | if (copy_from_user(buf, user_buf, size)) | 1382 | if (copy_from_user(buf, user_buf, size)) |
| 1383 | return -EFAULT; | 1383 | return -EFAULT; |
| 1384 | buf[size] = 0; | ||
| 1385 | |||
| 1384 | if (sscanf(buf, "%u %hu", &nhid, &bucket_index) != 2) | 1386 | if (sscanf(buf, "%u %hu", &nhid, &bucket_index) != 2) |
| 1385 | return -EINVAL; | 1387 | return -EINVAL; |
| 1386 | 1388 | ||
| @@ -537,12 +537,6 @@ static int aqcs109_config_init(struct phy_device *phydev) · 536 unmodified lines | |||
| 537 | if (!ret) | 537 | if (!ret) |
| 538 | aqr107_chip_info(phydev); | 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 | return aqr107_set_downshift(phydev, MDIO_AN_VEND_PROV_DOWNSHIFT_DFLT); | 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 | return aqr107_fill_interface_modes(phydev); | 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 | static int aqr113c_config_init(struct phy_device *phydev) | 753 | static int aqr113c_config_init(struct phy_device *phydev) |
| 735 | { | 754 | { |
| 736 | int ret; | 755 | int ret; |
| @@ -767,15 +786,6 @@ static int aqr107_probe(struct phy_device *phydev) · 30 unmodified lines | |||
| 767 | return aqr_hwmon_probe(phydev); | 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 | static struct phy_driver aqr_driver[] = { | 790 | static struct phy_driver aqr_driver[] = { |
| 781 | { | 791 | { |
| @@ -853,6 +863,7 @@ static struct phy_driver aqr_driver[] = { · 71 unmodified lines | |||
| 853 | .get_sset_count = aqr107_get_sset_count, | 863 | .get_sset_count = aqr107_get_sset_count, |
| 854 | .get_strings = aqr107_get_strings, | 864 | .get_strings = aqr107_get_strings, |
| 855 | .get_stats = aqr107_get_stats, | 865 | .get_stats = aqr107_get_stats, |
| 866 | .get_features = aqr115c_get_features, | ||
| 856 | .link_change_notify = aqr107_link_change_notify, | 867 | .link_change_notify = aqr107_link_change_notify, |
| 857 | .led_brightness_set = aqr_phy_led_brightness_set, | 868 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 858 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, | 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 | .name = "Aquantia AQR111", | 876 | .name = "Aquantia AQR111", |
| 866 | .probe = aqr107_probe, | 877 | .probe = aqr107_probe, |
| 867 | .get_rate_matching = aqr107_get_rate_matching, | 878 | .get_rate_matching = aqr107_get_rate_matching, |
| 868 | .config_init = aqr111_config_init, | 879 | .config_init = aqr107_config_init, |
| 869 | .config_aneg = aqr_config_aneg, | 880 | .config_aneg = aqr_config_aneg, |
| 870 | .config_intr = aqr_config_intr, | 881 | .config_intr = aqr_config_intr, |
| 871 | .handle_interrupt = aqr_handle_interrupt, | 882 | .handle_interrupt = aqr_handle_interrupt, |
| @@ -877,6 +888,7 @@ static struct phy_driver aqr_driver[] = { · 5 unmodified lines | |||
| 877 | .get_sset_count = aqr107_get_sset_count, | 888 | .get_sset_count = aqr107_get_sset_count, |
| 878 | .get_strings = aqr107_get_strings, | 889 | .get_strings = aqr107_get_strings, |
| 879 | .get_stats = aqr107_get_stats, | 890 | .get_stats = aqr107_get_stats, |
| 891 | .get_features = aqr111_get_features, | ||
| 880 | .link_change_notify = aqr107_link_change_notify, | 892 | .link_change_notify = aqr107_link_change_notify, |
| 881 | .led_brightness_set = aqr_phy_led_brightness_set, | 893 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 882 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, | 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 | .name = "Aquantia AQR111B0", | 901 | .name = "Aquantia AQR111B0", |
| 890 | .probe = aqr107_probe, | 902 | .probe = aqr107_probe, |
| 891 | .get_rate_matching = aqr107_get_rate_matching, | 903 | .get_rate_matching = aqr107_get_rate_matching, |
| 892 | .config_init = aqr111_config_init, | 904 | .config_init = aqr107_config_init, |
| 893 | .config_aneg = aqr_config_aneg, | 905 | .config_aneg = aqr_config_aneg, |
| 894 | .config_intr = aqr_config_intr, | 906 | .config_intr = aqr_config_intr, |
| 895 | .handle_interrupt = aqr_handle_interrupt, | 907 | .handle_interrupt = aqr_handle_interrupt, |
| @@ -901,6 +913,7 @@ static struct phy_driver aqr_driver[] = { · 5 unmodified lines | |||
| 901 | .get_sset_count = aqr107_get_sset_count, | 913 | .get_sset_count = aqr107_get_sset_count, |
| 902 | .get_strings = aqr107_get_strings, | 914 | .get_strings = aqr107_get_strings, |
| 903 | .get_stats = aqr107_get_stats, | 915 | .get_stats = aqr107_get_stats, |
| 916 | .get_features = aqr111_get_features, | ||
| 904 | .link_change_notify = aqr107_link_change_notify, | 917 | .link_change_notify = aqr107_link_change_notify, |
| 905 | .led_brightness_set = aqr_phy_led_brightness_set, | 918 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 906 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, | 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 | .name = "Aquantia AQR114C", | 1023 | .name = "Aquantia AQR114C", |
| 1011 | .probe = aqr107_probe, | 1024 | .probe = aqr107_probe, |
| 1012 | .get_rate_matching = aqr107_get_rate_matching, | 1025 | .get_rate_matching = aqr107_get_rate_matching, |
| 1013 | .config_init = aqr111_config_init, | 1026 | .config_init = aqr107_config_init, |
| 1014 | .config_aneg = aqr_config_aneg, | 1027 | .config_aneg = aqr_config_aneg, |
| 1015 | .config_intr = aqr_config_intr, | 1028 | .config_intr = aqr_config_intr, |
| 1016 | .handle_interrupt = aqr_handle_interrupt, | 1029 | .handle_interrupt = aqr_handle_interrupt, |
| @@ -1022,6 +1035,7 @@ static struct phy_driver aqr_driver[] = { · 5 unmodified lines | |||
| 1022 | .get_sset_count = aqr107_get_sset_count, | 1035 | .get_sset_count = aqr107_get_sset_count, |
| 1023 | .get_strings = aqr107_get_strings, | 1036 | .get_strings = aqr107_get_strings, |
| 1024 | .get_stats = aqr107_get_stats, | 1037 | .get_stats = aqr107_get_stats, |
| 1038 | .get_features = aqr111_get_features, | ||
| 1025 | .link_change_notify = aqr107_link_change_notify, | 1039 | .link_change_notify = aqr107_link_change_notify, |
| 1026 | .led_brightness_set = aqr_phy_led_brightness_set, | 1040 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 1027 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, | 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 | .get_sset_count = aqr107_get_sset_count, | 1060 | .get_sset_count = aqr107_get_sset_count, |
| 1047 | .get_strings = aqr107_get_strings, | 1061 | .get_strings = aqr107_get_strings, |
| 1048 | .get_stats = aqr107_get_stats, | 1062 | .get_stats = aqr107_get_stats, |
| 1063 | .get_features = aqr115c_get_features, | ||
| 1049 | .link_change_notify = aqr107_link_change_notify, | 1064 | .link_change_notify = aqr107_link_change_notify, |
| 1050 | .led_brightness_set = aqr_phy_led_brightness_set, | 1065 | .led_brightness_set = aqr_phy_led_brightness_set, |
| 1051 | .led_hw_is_supported = aqr_phy_led_hw_is_supported, | 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 | bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR); | 133 | bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR); |
| 134 | if (bmsr < 0) | 134 | if (bmsr < 0) |
| 135 | return val; | 135 | return bmsr; |
| 136 | 136 | ||
| 137 | return !!(val & MDIO_AN_STAT1_COMPLETE) && | 137 | return !!(val & MDIO_AN_STAT1_COMPLETE) && |
| 138 | !!(bmsr & BMSR_ANEGCOMPLETE); | 138 | !!(bmsr & BMSR_ANEGCOMPLETE); |
| @@ -158,7 +158,7 @@ static int bcm84881_read_status(struct phy_device *phydev) · 19 unmodified lines | |||
| 158 | 158 | ||
| 159 | bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR); | 159 | bmsr = phy_read_mmd(phydev, MDIO_MMD_AN, MDIO_AN_C22 + MII_BMSR); |
| 160 | if (bmsr < 0) | 160 | if (bmsr < 0) |
| 161 | return val; | 161 | return bmsr; |
| 162 | 162 | ||
| 163 | phydev->autoneg_complete = !!(val & MDIO_AN_STAT1_COMPLETE) && | 163 | phydev->autoneg_complete = !!(val & MDIO_AN_STAT1_COMPLETE) && |
| 164 | !!(bmsr & BMSR_ANEGCOMPLETE); | 164 | !!(bmsr & BMSR_ANEGCOMPLETE); |
| @@ -45,8 +45,8 @@ · 44 unmodified lines | |||
| 45 | /* Control Register 2 bits */ | 45 | /* Control Register 2 bits */ |
| 46 | #define DP83822_FX_ENABLE BIT(14) | 46 | #define DP83822_FX_ENABLE BIT(14) |
| 47 | 47 | ||
| 48 | #define DP83822_HW_RESET BIT(15) | 48 | #define DP83822_SW_RESET BIT(15) |
| 49 | #define DP83822_SW_RESET BIT(14) | 49 | #define DP83822_DIG_RESTART BIT(14) |
| 50 | 50 | ||
| 51 | /* PHY STS bits */ | 51 | /* PHY STS bits */ |
| 52 | #define DP83822_PHYSTS_DUPLEX BIT(2) | 52 | #define DP83822_PHYSTS_DUPLEX BIT(2) |
| @@ -645,7 +645,6 @@ static int dp83869_configure_fiber(struct phy_device *phydev, · 644 unmodified lines | |||
| 645 | phydev->supported); | 645 | phydev->supported); |
| 646 | 646 | ||
| 647 | linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); | 647 | linkmode_set_bit(ETHTOOL_LINK_MODE_FIBRE_BIT, phydev->supported); |
| 648 | linkmode_set_bit(ADVERTISED_FIBRE, phydev->advertising); | ||
| 649 | 648 | ||
| 650 | if (dp83869->mode == DP83869_RGMII_1000_BASE) { | 649 | if (dp83869->mode == DP83869_RGMII_1000_BASE) { |
| 651 | linkmode_set_bit(ETHTOOL_LINK_MODE_1000baseX_Full_BIT, | 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 | static void phy_leds_unregister(struct phy_device *phydev) | 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 | led_classdev_unregister(&phyled->led_cdev); | 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 | return rtlgen_is_c45_match(phydev, RTL_8221B_VN_CG, true); | 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 | static int rtlgen_resume(struct phy_device *phydev) | 1094 | static int rtlgen_resume(struct phy_device *phydev) |
| 1085 | { | 1095 | { |
| 1086 | int ret = genphy_resume(phydev); | 1096 | int ret = genphy_resume(phydev); |
| @@ -1418,7 +1428,7 @@ static struct phy_driver realtek_drvs[] = { · 331 unmodified lines | |||
| 1418 | .suspend = genphy_c45_pma_suspend, | 1428 | .suspend = genphy_c45_pma_suspend, |
| 1419 | .resume = rtlgen_c45_resume, | 1429 | .resume = rtlgen_c45_resume, |
| 1420 | }, { | 1430 | }, { |
| 1421 | PHY_ID_MATCH_EXACT(0x001cc862), | 1431 | .match_phy_device = rtl8251b_c45_match_phy_device, |
| 1422 | .name = "RTL8251B 5Gbps PHY", | 1432 | .name = "RTL8251B 5Gbps PHY", |
| 1423 | .get_features = rtl822x_get_features, | 1433 | .get_features = rtl822x_get_features, |
| 1424 | .config_aneg = rtl822x_config_aneg, | 1434 | .config_aneg = rtl822x_config_aneg, |
| @@ -1427,6 +1437,18 @@ static struct phy_driver realtek_drvs[] = { · 2 unmodified lines | |||
| 1427 | .resume = rtlgen_resume, | 1437 | .resume = rtlgen_resume, |
| 1428 | .read_page = rtl821x_read_page, | 1438 | .read_page = rtl821x_read_page, |
| 1429 | .write_page = rtl821x_write_page, | 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 | PHY_ID_MATCH_EXACT(0x001ccad0), | 1453 | PHY_ID_MATCH_EXACT(0x001ccad0), |
| 1432 | .name = "RTL8224 2.5Gbps PHY", | 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 | return HS_TIMEOUT; | 815 | return HS_TIMEOUT; |
| 816 | } | 816 | } |
| 817 | } | 817 | } |
| 818 | break; | 818 | fallthrough; |
| 819 | 819 | ||
| 820 | case PLIP_PK_LENGTH_LSB: | 820 | case PLIP_PK_LENGTH_LSB: |
| 821 | if (plip_send(nibble_timeout, dev, | 821 | if (plip_send(nibble_timeout, dev, |
| @@ -542,7 +542,7 @@ ppp_async_encode(struct asyncppp *ap) · 541 unmodified lines | |||
| 542 | * and 7 (code-reject) must be sent as though no options | 542 | * and 7 (code-reject) must be sent as though no options |
| 543 | * had been negotiated. | 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 | if (i == 0) { | 547 | if (i == 0) { |
| 548 | if (islcp) | 548 | if (islcp) |
| @@ -113,7 +113,7 @@ static void pse_release_pis(struct pse_controller_dev *pcdev) · 112 unmodified lines | |||
| 113 | { | 113 | { |
| 114 | int i; | 114 | int i; |
| 115 | 115 | ||
| 116 | for (i = 0; i <= pcdev->nr_lines; i++) { | 116 | for (i = 0; i < pcdev->nr_lines; i++) { |
| 117 | of_node_put(pcdev->pi[i].pairset[0].np); | 117 | of_node_put(pcdev->pi[i].pairset[0].np); |
| 118 | of_node_put(pcdev->pi[i].pairset[1].np); | 118 | of_node_put(pcdev->pi[i].pairset[1].np); |
| 119 | of_node_put(pcdev->pi[i].np); | 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 | int i; | 648 | int i; |
| 649 | 649 | ||
| 650 | for (i = 0; i <= pcdev->nr_lines; i++) { | 650 | for (i = 0; i < pcdev->nr_lines; i++) { |
| 651 | if (pcdev->pi[i].np == np) | 651 | if (pcdev->pi[i].np == np) |
| 652 | return i; | 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 | switch (config->c33_admin_control) { | 786 | switch (config->c33_admin_control) { |
| 787 | case ETHTOOL_C33_PSE_ADMIN_STATE_ENABLED: | 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 | if (!psec->pcdev->pi[psec->id].admin_state_enabled) | 799 | if (!psec->pcdev->pi[psec->id].admin_state_enabled) |
| 789 | err = regulator_enable(psec->ps); | 800 | err = regulator_enable(psec->ps); |
| 790 | break; | 801 | break; |
| @@ -643,46 +643,57 @@ bad: · 642 unmodified lines | |||
| 643 | int | 643 | int |
| 644 | slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) | 644 | slhc_remember(struct slcompress *comp, unsigned char *icp, int isize) |
| 645 | { | 645 | { |
| 646 | struct cstate *cs; | 646 | const struct tcphdr *th; |
| 647 | unsigned ihl; | ||
| 648 | |||
| 649 | unsigned char index; | 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 | comp->sls_i_runt++; | 657 | comp->sls_i_runt++; |
| 654 | return slhc_toss( comp ); | 658 | return slhc_toss(comp); |
| 655 | } | 659 | } |
| 660 | iph = (struct iphdr *)icp; | ||
| 656 | /* Peek at the IP header's IHL field to find its length */ | 661 | /* Peek at the IP header's IHL field to find its length */ |
| 657 | ihl = icp[0] & 0xf; | 662 | ihl = iph->ihl; |
| 658 | if(ihl < 20 / 4){ | 663 | /* The IP header length field is too small, |
| 659 | /* The IP header length field is too small */ | 664 | * or packet is shorter than the IP header followed |
| 660 | comp->sls_i_runt++; | 665 | * by minimal tcp header. |
| 661 | return slhc_toss( comp ); | 666 | */ |
| 662 | } | 667 | if (ihl < 5 || isize < ihl * 4 + sizeof(struct tcphdr)) |
| 663 | index = icp[9]; | 668 | goto runt; |
| 664 | icp[9] = IPPROTO_TCP; | 669 | |
| 670 | index = iph->protocol; | ||
| 671 | iph->protocol = IPPROTO_TCP; | ||
| 665 | 672 | ||
| 666 | if (ip_fast_csum(icp, ihl)) { | 673 | if (ip_fast_csum(icp, ihl)) { |
| 667 | /* Bad IP header checksum; discard */ | 674 | /* Bad IP header checksum; discard */ |
| 668 | comp->sls_i_badcheck++; | 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 | comp->sls_i_error++; | 679 | comp->sls_i_error++; |
| 673 | return slhc_toss(comp); | 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 | /* Update local state */ | 687 | /* Update local state */ |
| 677 | cs = &comp->rstate[comp->recv_current = index]; | 688 | cs = &comp->rstate[comp->recv_current = index]; |
| 678 | comp->flags &=~ SLF_TOSS; | 689 | comp->flags &=~ SLF_TOSS; |
| 679 | memcpy(&cs->cs_ip,icp,20); | 690 | memcpy(&cs->cs_ip, iph, sizeof(*iph)); |
| 680 | memcpy(&cs->cs_tcp,icp + ihl*4,20); | 691 | memcpy(&cs->cs_tcp, th, sizeof(*th)); |
| 681 | if (ihl > 5) | 692 | if (ihl > 5) |
| 682 | memcpy(cs->cs_ipopt, icp + sizeof(struct iphdr), (ihl - 5) * 4); | 693 | memcpy(cs->cs_ipopt, &iph[1], (ihl - 5) * 4); |
| 683 | if (cs->cs_tcp.doff > 5) | 694 | if (th->doff > 5) |
| 684 | memcpy(cs->cs_tcpopt, icp + ihl*4 + sizeof(struct tcphdr), (cs->cs_tcp.doff - 5) * 4); | 695 | memcpy(cs->cs_tcpopt, &th[1], (th->doff - 5) * 4); |
| 685 | cs->cs_hsize = ihl*2 + cs->cs_tcp.doff*2; | 696 | cs->cs_hsize = ihl*2 + th->doff*2; |
| 686 | cs->initialized = true; | 697 | cs->initialized = true; |
| 687 | /* Put headers back on packet | 698 | /* Put headers back on packet |
| 688 | * Neither header checksum is recalculated | 699 | * Neither header checksum is recalculated |
| @@ -1076,6 +1076,7 @@ static const struct usb_device_id products[] = { · 1075 unmodified lines | |||
| 1076 | USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7), | 1076 | USB_DEVICE_AND_INTERFACE_INFO(0x03f0, 0x581d, USB_CLASS_VENDOR_SPEC, 1, 7), |
| 1077 | .driver_info = (unsigned long)&qmi_wwan_info, | 1077 | .driver_info = (unsigned long)&qmi_wwan_info, |
| 1078 | }, | 1078 | }, |
| 1079 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0122)}, /* Quectel RG650V */ | ||
| 1079 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ | 1080 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0125)}, /* Quectel EC25, EC20 R2.0 Mini PCIe */ |
| 1080 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ | 1081 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0306)}, /* Quectel EP06/EG06/EM06 */ |
| 1081 | {QMI_MATCH_FF_FF_FF(0x2c7c, 0x0512)}, /* Quectel EG12/EM12 */ | 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 | {QMI_FIXED_INTF(0x2c7c, 0x0296, 4)}, /* Quectel BG96 */ | 1427 | {QMI_FIXED_INTF(0x2c7c, 0x0296, 4)}, /* Quectel BG96 */ |
| 1427 | {QMI_QUIRK_SET_DTR(0x2c7c, 0x030e, 4)}, /* Quectel EM05GV2 */ | 1428 | {QMI_QUIRK_SET_DTR(0x2c7c, 0x030e, 4)}, /* Quectel EM05GV2 */ |
| 1428 | {QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */ | 1429 | {QMI_QUIRK_SET_DTR(0x2cb7, 0x0104, 4)}, /* Fibocom NL678 series */ |
| 1430 | {QMI_QUIRK_SET_DTR(0x2cb7, 0x0112, 0)}, /* Fibocom FG132 */ | ||
| 1429 | {QMI_FIXED_INTF(0x0489, 0xe0b4, 0)}, /* Foxconn T77W968 LTE */ | 1431 | {QMI_FIXED_INTF(0x0489, 0xe0b4, 0)}, /* Foxconn T77W968 LTE */ |
| 1430 | {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/ | 1432 | {QMI_FIXED_INTF(0x0489, 0xe0b5, 0)}, /* Foxconn T77W968 LTE with eSIM support*/ |
| 1431 | {QMI_FIXED_INTF(0x2692, 0x9025, 4)}, /* Cellient MPL200 (rebranded Qualcomm 05c6:9025) */ | 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 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x3062) }, | 10069 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x3062) }, |
| 10070 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x3069) }, | 10070 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x3069) }, |
| 10071 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x3082) }, | 10071 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x3082) }, |
| 10072 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x3098) }, | ||
| 10072 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x7205) }, | 10073 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x7205) }, |
| 10073 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x720c) }, | 10074 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x720c) }, |
| 10074 | { USB_DEVICE(VENDOR_ID_LENOVO, 0x7214) }, | 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 | // can rename the link if it knows better. | 1767 | // can rename the link if it knows better. |
| 1768 | if ((dev->driver_info->flags & FLAG_ETHER) != 0 && | 1768 | if ((dev->driver_info->flags & FLAG_ETHER) != 0 && |
| 1769 | ((dev->driver_info->flags & FLAG_POINTTOPOINT) == 0 || | 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 | strscpy(net->name, "eth%d", sizeof(net->name)); | 1772 | strscpy(net->name, "eth%d", sizeof(net->name)); |
| 1772 | /* WLAN devices should always be named "wlan%d" */ | 1773 | /* WLAN devices should always be named "wlan%d" */ |
| 1773 | if ((dev->driver_info->flags & FLAG_WLAN) != 0) | 1774 | if ((dev->driver_info->flags & FLAG_WLAN) != 0) |
| @@ -1870,6 +1871,7 @@ out1: · 96 unmodified lines | |||
| 1870 | * may trigger an error resubmitting itself and, worse, | 1871 | * may trigger an error resubmitting itself and, worse, |
| 1871 | * schedule a timer. So we kill it all just in case. | 1872 | * schedule a timer. So we kill it all just in case. |
| 1872 | */ | 1873 | */ |
| 1874 | usbnet_mark_going_away(dev); | ||
| 1873 | cancel_work_sync(&dev->kevent); | 1875 | cancel_work_sync(&dev->kevent); |
| 1874 | del_timer_sync(&dev->delay); | 1876 | del_timer_sync(&dev->delay); |
| 1875 | free_netdev(net); | 1877 | free_netdev(net); |
| @@ -4155,7 +4155,7 @@ struct virtnet_stats_ctx { · 4154 unmodified lines | |||
| 4155 | u32 desc_num[3]; | 4155 | u32 desc_num[3]; |
| 4156 | 4156 | ||
| 4157 | /* The actual supported stat types. */ | 4157 | /* The actual supported stat types. */ |
| 4158 | u32 bitmap[3]; | 4158 | u64 bitmap[3]; |
| 4159 | 4159 | ||
| 4160 | /* Used to calculate the reply buffer size. */ | 4160 | /* Used to calculate the reply buffer size. */ |
| 4161 | u32 size[3]; | 4161 | u32 size[3]; |
| @@ -148,7 +148,7 @@ vmxnet3_xdp_xmit_frame(struct vmxnet3_adapter *adapter, · 147 unmodified lines | |||
| 148 | } else { /* XDP buffer from page pool */ | 148 | } else { /* XDP buffer from page pool */ |
| 149 | page = virt_to_page(xdpf->data); | 149 | page = virt_to_page(xdpf->data); |
| 150 | tbi->dma_addr = page_pool_get_dma_addr(page) + | 150 | tbi->dma_addr = page_pool_get_dma_addr(page) + |
| 151 | VMXNET3_XDP_HEADROOM; | 151 | (xdpf->data - (void *)xdpf); |
| 152 | dma_sync_single_for_device(&adapter->pdev->dev, | 152 | dma_sync_single_for_device(&adapter->pdev->dev, |
| 153 | tbi->dma_addr, buf_size, | 153 | tbi->dma_addr, buf_size, |
| 154 | DMA_TO_DEVICE); | 154 | DMA_TO_DEVICE); |
| @@ -4913,9 +4913,13 @@ static int __init vxlan_init_module(void) · 4912 unmodified lines | |||
| 4913 | if (rc) | 4913 | if (rc) |
| 4914 | goto out4; | 4914 | goto out4; |
| 4915 | 4915 | ||
| 4916 | vxlan_vnifilter_init(); | 4916 | rc = vxlan_vnifilter_init(); |
| 4917 | if (rc) | ||
| 4918 | goto out5; | ||
| 4917 | 4919 | ||
| 4918 | return 0; | 4920 | return 0; |
| 4921 | out5: | ||
| 4922 | rtnl_link_unregister(&vxlan_link_ops); | ||
| 4919 | out4: | 4923 | out4: |
| 4920 | unregister_switchdev_notifier(&vxlan_switchdev_notifier_block); | 4924 | unregister_switchdev_notifier(&vxlan_switchdev_notifier_block); |
| 4921 | out3: | 4925 | out3: |
| @@ -202,7 +202,7 @@ int vxlan_vni_in_use(struct net *src_net, struct vxlan_dev *vxlan, · 201 unmodified lines | |||
| 202 | int vxlan_vnigroup_init(struct vxlan_dev *vxlan); | 202 | int vxlan_vnigroup_init(struct vxlan_dev *vxlan); |
| 203 | void vxlan_vnigroup_uninit(struct vxlan_dev *vxlan); | 203 | void vxlan_vnigroup_uninit(struct vxlan_dev *vxlan); |
| 204 | 204 | ||
| 205 | void vxlan_vnifilter_init(void); | 205 | int vxlan_vnifilter_init(void); |
| 206 | void vxlan_vnifilter_uninit(void); | 206 | void vxlan_vnifilter_uninit(void); |
| 207 | void vxlan_vnifilter_count(struct vxlan_dev *vxlan, __be32 vni, | 207 | void vxlan_vnifilter_count(struct vxlan_dev *vxlan, __be32 vni, |
| 208 | struct vxlan_vni_node *vninode, | 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 | return err; | 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, | 1003 | return rtnl_register_many(vxlan_vnifilter_rtnl_msg_handlers); |
| 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 | } | 1004 | } |
| 1004 | 1005 | ||
| 1005 | void vxlan_vnifilter_uninit(void) | 1006 | void vxlan_vnifilter_uninit(void) |
| 1006 | { | 1007 | { |
| 1007 | rtnl_unregister(PF_BRIDGE, RTM_GETTUNNEL); | 1008 | rtnl_unregister_many(vxlan_vnifilter_rtnl_msg_handlers); |
| 1008 | rtnl_unregister(PF_BRIDGE, RTM_NEWTUNNEL); | ||
| 1009 | rtnl_unregister(PF_BRIDGE, RTM_DELTUNNEL); | ||
| 1010 | } | 1009 | } |
| @@ -3043,9 +3043,14 @@ ath10k_wmi_tlv_op_cleanup_mgmt_tx_send(struct ath10k *ar, · 3042 unmodified lines | |||
| 3043 | struct sk_buff *msdu) | 3043 | struct sk_buff *msdu) |
| 3044 | { | 3044 | { |
| 3045 | struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); | 3045 | struct ath10k_skb_cb *cb = ATH10K_SKB_CB(msdu); |
| 3046 | struct ath10k_mgmt_tx_pkt_addr *pkt_addr; | ||
| 3046 | struct ath10k_wmi *wmi = &ar->wmi; | 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 | return 0; | 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 | dma_unmap_single(ar->dev, pkt_addr->paddr, | 2441 | dma_unmap_single(ar->dev, pkt_addr->paddr, |
| 2442 | msdu->len, DMA_TO_DEVICE); | 2442 | msdu->len, DMA_TO_DEVICE); |
| 2443 | info = IEEE80211_SKB_CB(msdu); | 2443 | info = IEEE80211_SKB_CB(msdu); |
| 2444 | kfree(pkt_addr); | ||
| 2444 | 2445 | ||
| 2445 | if (param->status) { | 2446 | if (param->status) { |
| 2446 | info->flags &= ~IEEE80211_TX_STAT_ACK; | 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 | dma_unmap_single(ar->dev, pkt_addr->paddr, | 9613 | dma_unmap_single(ar->dev, pkt_addr->paddr, |
| 9613 | msdu->len, DMA_TO_DEVICE); | 9614 | msdu->len, DMA_TO_DEVICE); |
| 9614 | ieee80211_free_txskb(ar->hw, msdu); | 9615 | ieee80211_free_txskb(ar->hw, msdu); |
| 9616 | kfree(pkt_addr); | ||
| 9615 | 9617 | ||
| 9616 | return 0; | 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 | hal_status == HAL_TLV_STATUS_PPDU_DONE) { | 5291 | hal_status == HAL_TLV_STATUS_PPDU_DONE) { |
| 5292 | rx_mon_stats->status_ppdu_done++; | 5292 | rx_mon_stats->status_ppdu_done++; |
| 5293 | pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE; | 5293 | pmon->mon_ppdu_status = DP_PPDU_STATUS_DONE; |
| 5294 | ath11k_dp_rx_mon_dest_process(ar, mac_id, budget, napi); | 5294 | if (!ab->hw_params.full_monitor_mode) { |
| 5295 | pmon->mon_ppdu_status = DP_PPDU_STATUS_START; | 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 | if (ppdu_info->peer_id == HAL_INVALID_PEERID || | 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 | struct sk_buff *skb) | 306 | struct sk_buff *skb) |
| 307 | { | 307 | { |
| 308 | struct wil6210_rtap { | 308 | struct wil6210_rtap { |
| 309 | struct ieee80211_radiotap_header rthdr; | 309 | struct ieee80211_radiotap_header_fixed rthdr; |
| 310 | /* fields should be in the order of bits in rthdr.it_present */ | 310 | /* fields should be in the order of bits in rthdr.it_present */ |
| 311 | /* flags */ | 311 | /* flags */ |
| 312 | u8 flags; | 312 | u8 flags; |
| @@ -27,6 +27,7 @@ source "drivers/net/wireless/broadcom/brcm80211/brcmfmac/Kconfig" · 26 unmodified lines | |||
| 27 | config BRCM_TRACING | 27 | config BRCM_TRACING |
| 28 | bool "Broadcom device tracing" | 28 | bool "Broadcom device tracing" |
| 29 | depends on BRCMSMAC || BRCMFMAC | 29 | depends on BRCMSMAC || BRCMFMAC |
| 30 | depends on TRACING | ||
| 30 | help | 31 | help |
| 31 | If you say Y here, the Broadcom wireless drivers will register | 32 | If you say Y here, the Broadcom wireless drivers will register |
| 32 | with ftrace to dump event information into the trace ringbuffer. | 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 | * to build this manually element by element, we can write it much | 2518 | * to build this manually element by element, we can write it much |
| 2519 | * more efficiently than we can parse it. ORDER MATTERS HERE */ | 2519 | * more efficiently than we can parse it. ORDER MATTERS HERE */ |
| 2520 | struct ipw_rt_hdr { | 2520 | struct ipw_rt_hdr { |
| 2521 | struct ieee80211_radiotap_header rt_hdr; | 2521 | struct ieee80211_radiotap_header_fixed rt_hdr; |
| 2522 | s8 rt_dbmsignal; /* signal in dbM, kluged to signed */ | 2522 | s8 rt_dbmsignal; /* signal in dbM, kluged to signed */ |
| 2523 | } *ipw_rt; | 2523 | } *ipw_rt; |
| 2524 | 2524 | ||
| @@ -1143,7 +1143,7 @@ struct ipw_prom_priv { · 1142 unmodified lines | |||
| 1143 | * structure is provided regardless of any bits unset. | 1143 | * structure is provided regardless of any bits unset. |
| 1144 | */ | 1144 | */ |
| 1145 | struct ipw_rt_hdr { | 1145 | struct ipw_rt_hdr { |
| 1146 | struct ieee80211_radiotap_header rt_hdr; | 1146 | struct ieee80211_radiotap_header_fixed rt_hdr; |
| 1147 | u64 rt_tsf; /* TSF */ /* XXX */ | 1147 | u64 rt_tsf; /* TSF */ /* XXX */ |
| 1148 | u8 rt_flags; /* radiotap packet flags */ | 1148 | u8 rt_flags; /* radiotap packet flags */ |
| 1149 | u8 rt_rate; /* rate in 500kb/s */ | 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 | struct il_cmd_meta *out_meta; | 3122 | struct il_cmd_meta *out_meta; |
| 3123 | dma_addr_t phys_addr; | 3123 | dma_addr_t phys_addr; |
| 3124 | unsigned long flags; | 3124 | unsigned long flags; |
| 3125 | u8 *out_payload; | ||
| 3125 | u32 idx; | 3126 | u32 idx; |
| 3126 | u16 fix_size; | 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 | out_cmd = txq->cmd[idx]; | 3158 | out_cmd = txq->cmd[idx]; |
| 3158 | out_meta = &txq->meta[idx]; | 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 | if (WARN_ON(out_meta->flags & CMD_MAPPED)) { | 3171 | if (WARN_ON(out_meta->flags & CMD_MAPPED)) { |
| 3161 | spin_unlock_irqrestore(&il->hcmd_lock, flags); | 3172 | spin_unlock_irqrestore(&il->hcmd_lock, flags); |
| 3162 | return -ENOSPC; | 3173 | return -ENOSPC; |
| @@ -3170,7 +3181,7 @@ il_enqueue_hcmd(struct il_priv *il, struct il_host_cmd *cmd) · 7 unmodified lines | |||
| 3170 | out_meta->callback = cmd->callback; | 3181 | out_meta->callback = cmd->callback; |
| 3171 | 3182 | ||
| 3172 | out_cmd->hdr.cmd = cmd->id; | 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 | /* At this point, the out_cmd now has all of the incoming cmd | 3186 | /* At this point, the out_cmd now has all of the incoming cmd |
| 3176 | * information */ | 3187 | * information */ |
| @@ -4962,6 +4973,8 @@ il_pci_resume(struct device *device) · 1785 unmodified lines | |||
| 4962 | */ | 4973 | */ |
| 4963 | pci_write_config_byte(pdev, PCI_CFG_RETRY_TIMEOUT, 0x00); | 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 | il_enable_interrupts(il); | 4978 | il_enable_interrupts(il); |
| 4966 | 4979 | ||
| 4967 | if (!(_il_rd(il, CSR_GP_CNTRL) & CSR_GP_CNTRL_REG_FLAG_HW_RF_KILL_SW)) | 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 | #define TFD_MAX_PAYLOAD_SIZE (sizeof(struct il_device_cmd)) | 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 | struct il_host_cmd { | 575 | struct il_host_cmd { |
| 564 | const void *data; | 576 | const void *data; |
| 565 | unsigned long reply_page; | 577 | unsigned long reply_page; |
| @@ -429,38 +429,28 @@ out_free: · 428 unmodified lines | |||
| 429 | return ret; | 429 | return ret; |
| 430 | } | 430 | } |
| 431 | 431 | ||
| 432 | static int iwl_acpi_sar_set_profile(union acpi_object *table, | 432 | static int |
| 433 | struct iwl_sar_profile *profile, | 433 | iwl_acpi_parse_chains_table(union acpi_object *table, |
| 434 | bool enabled, u8 num_chains, | 434 | struct iwl_sar_profile_chain *chains, |
| 435 | u8 num_sub_bands) | 435 | u8 num_chains, u8 num_sub_bands) |
| 436 | { | 436 | { |
| 437 | int i, j, idx = 0; | 437 | for (u8 chain = 0; chain < num_chains; chain++) { |
| 438 | 438 | for (u8 subband = 0; subband < BIOS_SAR_MAX_SUB_BANDS_NUM; | |
| 439 | /* | 439 | subband++) { |
| 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++) { | ||
| 445 | /* if we don't have the values, use the default */ | 440 | /* if we don't have the values, use the default */ |
| 446 | if (i >= num_chains || j >= num_sub_bands) { | 441 | if (subband >= num_sub_bands) { |
| 447 | profile->chains[i].subbands[j] = 0; | 442 | chains[chain].subbands[subband] = 0; |
| 443 | } else if (table->type != ACPI_TYPE_INTEGER || | ||
| 444 | table->integer.value > U8_MAX) { | ||
| 445 | return -EINVAL; | ||
| 448 | } else { | 446 | } else { |
| 449 | if (table[idx].type != ACPI_TYPE_INTEGER || | 447 | chains[chain].subbands[subband] = |
| 450 | table[idx].integer.value > U8_MAX) | 448 | table->integer.value; |
| 451 | return -EINVAL; | 449 | table++; |
| 452 | |||
| 453 | profile->chains[i].subbands[j] = | ||
| 454 | table[idx].integer.value; | ||
| 455 | |||
| 456 | idx++; | ||
| 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 | return 0; | 454 | return 0; |
| 465 | } | 455 | } |
| 466 | 456 | ||
| @@ -543,9 +533,11 @@ read_table: · 76 unmodified lines | |||
| 543 | /* The profile from WRDS is officially profile 1, but goes | 533 | /* The profile from WRDS is officially profile 1, but goes |
| 544 | * into sar_profiles[0] (because we don't have a profile 0). | 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], | 536 | ret = iwl_acpi_parse_chains_table(table, fwrt->sar_profiles[0].chains, |
| 547 | flags & IWL_SAR_ENABLE_MSK, | 537 | num_chains, num_sub_bands); |
| 548 | num_chains, num_sub_bands); | 538 | if (!ret && flags & IWL_SAR_ENABLE_MSK) |
| 539 | fwrt->sar_profiles[0].enabled = true; | ||
| 540 | |||
| 549 | out_free: | 541 | out_free: |
| 550 | kfree(data); | 542 | kfree(data); |
| 551 | return ret; | 543 | return ret; |
| @@ -557,7 +549,7 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt) · 5 unmodified lines | |||
| 557 | bool enabled; | 549 | bool enabled; |
| 558 | int i, n_profiles, tbl_rev, pos; | 550 | int i, n_profiles, tbl_rev, pos; |
| 559 | int ret = 0; | 551 | int ret = 0; |
| 560 | u8 num_chains, num_sub_bands; | 552 | u8 num_sub_bands; |
| 561 | 553 | ||
| 562 | data = iwl_acpi_get_object(fwrt->dev, ACPI_EWRD_METHOD); | 554 | data = iwl_acpi_get_object(fwrt->dev, ACPI_EWRD_METHOD); |
| 563 | if (IS_ERR(data)) | 555 | if (IS_ERR(data)) |
| @@ -573,7 +565,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt) · 9 unmodified lines | |||
| 573 | goto out_free; | 565 | goto out_free; |
| 574 | } | 566 | } |
| 575 | 567 | ||
| 576 | num_chains = ACPI_SAR_NUM_CHAINS_REV2; | ||
| 577 | num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV2; | 568 | num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV2; |
| 578 | 569 | ||
| 579 | goto read_table; | 570 | goto read_table; |
| @@ -589,7 +580,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt) · 9 unmodified lines | |||
| 589 | goto out_free; | 580 | goto out_free; |
| 590 | } | 581 | } |
| 591 | 582 | ||
| 592 | num_chains = ACPI_SAR_NUM_CHAINS_REV1; | ||
| 593 | num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV1; | 583 | num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV1; |
| 594 | 584 | ||
| 595 | goto read_table; | 585 | goto read_table; |
| @@ -605,7 +595,6 @@ int iwl_acpi_get_ewrd_table(struct iwl_fw_runtime *fwrt) · 9 unmodified lines | |||
| 605 | goto out_free; | 595 | goto out_free; |
| 606 | } | 596 | } |
| 607 | 597 | ||
| 608 | num_chains = ACPI_SAR_NUM_CHAINS_REV0; | ||
| 609 | num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV0; | 598 | num_sub_bands = ACPI_SAR_NUM_SUB_BANDS_REV0; |
| 610 | 599 | ||
| 611 | goto read_table; | 600 | goto read_table; |
| @@ -637,23 +626,54 @@ read_table: · 25 unmodified lines | |||
| 637 | /* the tables start at element 3 */ | 626 | /* the tables start at element 3 */ |
| 638 | pos = 3; | 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 | for (i = 0; i < n_profiles; i++) { | 633 | for (i = 0; i < n_profiles; i++) { |
| 641 | union acpi_object *table = &wifi_pkg->package.elements[pos]; | 634 | union acpi_object *table = &wifi_pkg->package.elements[pos]; |
| 635 | |||
| 642 | /* The EWRD profiles officially go from 2 to 4, but we | 636 | /* The EWRD profiles officially go from 2 to 4, but we |
| 643 | * save them in sar_profiles[1-3] (because we don't | 637 | * save them in sar_profiles[1-3] (because we don't |
| 644 | * have profile 0). So in the array we start from 1. | 638 | * have profile 0). So in the array we start from 1. |
| 645 | */ | 639 | */ |
| 646 | ret = iwl_acpi_sar_set_profile(table, | 640 | ret = iwl_acpi_parse_chains_table(table, |
| 647 | &fwrt->sar_profiles[i + 1], | 641 | fwrt->sar_profiles[i + 1].chains, |
| 648 | enabled, num_chains, | 642 | ACPI_SAR_NUM_CHAINS_REV0, |
| 649 | num_sub_bands); | 643 | num_sub_bands); |
| 650 | if (ret < 0) | 644 | if (ret < 0) |
| 651 | break; | 645 | goto out_free; |
| 652 | 646 | ||
| 653 | /* go to the next table */ | 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 | out_free: | 677 | out_free: |
| 658 | kfree(data); | 678 | kfree(data); |
| 659 | return ret; | 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 | IWL_EXPORT_SYMBOL(iwl_fw_runtime_init); | 40 | IWL_EXPORT_SYMBOL(iwl_fw_runtime_init); |
| 41 | 41 | ||
| 42 | /* Assumes the appropriate lock is held by the caller */ | ||
| 42 | void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt) | 43 | void iwl_fw_runtime_suspend(struct iwl_fw_runtime *fwrt) |
| 43 | { | 44 | { |
| 44 | iwl_fw_suspend_timestamp(fwrt); | 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 | IWL_EXPORT_SYMBOL(iwl_fw_runtime_suspend); | 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 | const struct iwl_op_mode_ops *ops = op->ops; | 1413 | const struct iwl_op_mode_ops *ops = op->ops; |
| 1414 | struct dentry *dbgfs_dir = NULL; | 1414 | struct dentry *dbgfs_dir = NULL; |
| 1415 | struct iwl_op_mode *op_mode = NULL; | 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 | /* also protects start/stop from racing against each other */ | 1418 | /* also protects start/stop from racing against each other */ |
| 1418 | lockdep_assert_held(&iwlwifi_opmode_table_mtx); | 1419 | lockdep_assert_held(&iwlwifi_opmode_table_mtx); |
| 1419 | 1420 | ||
| 1421 | for (retry = 0; retry <= max_retry; retry++) { | ||
| 1422 | |||
| 1420 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1423 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 1421 | drv->dbgfs_op_mode = debugfs_create_dir(op->name, | 1424 | drv->dbgfs_op_mode = debugfs_create_dir(op->name, |
| 1422 | drv->dbgfs_drv); | 1425 | drv->dbgfs_drv); |
| 1423 | dbgfs_dir = drv->dbgfs_op_mode; | 1426 | dbgfs_dir = drv->dbgfs_op_mode; |
| 1424 | #endif | 1427 | #endif |
| 1425 | 1428 | ||
| 1426 | op_mode = ops->start(drv->trans, drv->trans->cfg, | 1429 | op_mode = ops->start(drv->trans, drv->trans->cfg, |
| 1427 | &drv->fw, dbgfs_dir); | 1430 | &drv->fw, dbgfs_dir); |
| 1428 | if (op_mode) | 1431 | |
| 1429 | return op_mode; | 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 | #ifdef CONFIG_IWLWIFI_DEBUGFS | 1440 | #ifdef CONFIG_IWLWIFI_DEBUGFS |
| 1432 | debugfs_remove_recursive(drv->dbgfs_op_mode); | 1441 | debugfs_remove_recursive(drv->dbgfs_op_mode); |
| 1433 | drv->dbgfs_op_mode = NULL; | 1442 | drv->dbgfs_op_mode = NULL; |
| 1434 | #endif | 1443 | #endif |
| 1444 | } | ||
| 1435 | 1445 | ||
| 1436 | return NULL; | 1446 | return NULL; |
| 1437 | } | 1447 | } |
| @@ -98,6 +98,9 @@ void iwl_drv_stop(struct iwl_drv *drv); · 97 unmodified lines | |||
| 98 | #define VISIBLE_IF_IWLWIFI_KUNIT static | 98 | #define VISIBLE_IF_IWLWIFI_KUNIT static |
| 99 | #endif | 99 | #endif |
| 100 | 100 | ||
| 101 | /* max retry for init flow */ | ||
| 102 | #define IWL_MAX_INIT_RETRY 2 | ||
| 103 | |||
| 101 | #define FW_NAME_PRE_BUFSIZE 64 | 104 | #define FW_NAME_PRE_BUFSIZE 64 |
| 102 | struct iwl_trans; | 105 | struct iwl_trans; |
| 103 | const char *iwl_drv_get_fwname_pre(struct iwl_trans *trans, char *buf); | 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 | iwl_mvm_pause_tcm(mvm, true); | 1399 | iwl_mvm_pause_tcm(mvm, true); |
| 1400 | 1400 | ||
| 1401 | mutex_lock(&mvm->mutex); | ||
| 1401 | iwl_fw_runtime_suspend(&mvm->fwrt); | 1402 | iwl_fw_runtime_suspend(&mvm->fwrt); |
| 1403 | mutex_unlock(&mvm->mutex); | ||
| 1402 | 1404 | ||
| 1403 | return __iwl_mvm_suspend(hw, wowlan, false); | 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 | void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags) | 1307 | void iwl_mvm_send_recovery_cmd(struct iwl_mvm *mvm, u32 flags) |
| 1308 | { | 1308 | { |
| 1309 | u32 error_log_size = mvm->fw->ucode_capa.error_log_size; | 1309 | u32 error_log_size = mvm->fw->ucode_capa.error_log_size; |
| 1310 | u32 status = 0; | ||
| 1310 | int ret; | 1311 | int ret; |
| 1311 | u32 resp; | ||
| 1312 | 1312 | ||
| 1313 | struct iwl_fw_error_recovery_cmd recovery_cmd = { | 1313 | struct iwl_fw_error_recovery_cmd recovery_cmd = { |
| 1314 | .flags = cpu_to_le32(flags), | 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 | struct iwl_host_cmd host_cmd = { | 1317 | struct iwl_host_cmd host_cmd = { |
| 1318 | .id = WIDE_ID(SYSTEM_GROUP, FW_ERROR_RECOVERY_CMD), | 1318 | .id = WIDE_ID(SYSTEM_GROUP, FW_ERROR_RECOVERY_CMD), |
| 1319 | .flags = CMD_WANT_SKB, | ||
| 1320 | .data = {&recovery_cmd, }, | 1319 | .data = {&recovery_cmd, }, |
| 1321 | .len = {sizeof(recovery_cmd), }, | 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 | recovery_cmd.buf_size = cpu_to_le32(error_log_size); | 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 | kfree(mvm->error_recovery_buf); | 1339 | kfree(mvm->error_recovery_buf); |
| 1341 | mvm->error_recovery_buf = NULL; | 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 | /* skb respond is only relevant in ERROR_RECOVERY_UPDATE_DB */ | 1347 | /* skb respond is only relevant in ERROR_RECOVERY_UPDATE_DB */ |
| 1349 | if (flags & ERROR_RECOVERY_UPDATE_DB) { | 1348 | if (flags & ERROR_RECOVERY_UPDATE_DB) { |
| 1350 | resp = le32_to_cpu(*(__le32 *)host_cmd.resp_pkt->data); | 1349 | if (status) { |
| 1351 | if (resp) { | ||
| 1352 | IWL_ERR(mvm, | 1350 | IWL_ERR(mvm, |
| 1353 | "Failed to send recovery cmd blob was invalid %d\n", | 1351 | "Failed to send recovery cmd blob was invalid %d\n", |
| 1354 | resp); | 1352 | status); |
| 1355 | 1353 | ||
| 1356 | ieee80211_iterate_interfaces(mvm->hw, 0, | 1354 | ieee80211_iterate_interfaces(mvm->hw, 0, |
| 1357 | iwl_mvm_disconnect_iterator, | 1355 | iwl_mvm_disconnect_iterator, |
| @@ -1293,12 +1293,14 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw) · 1292 unmodified lines | |||
| 1293 | { | 1293 | { |
| 1294 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); | 1294 | struct iwl_mvm *mvm = IWL_MAC80211_GET_MVM(hw); |
| 1295 | int ret; | 1295 | int ret; |
| 1296 | int retry, max_retry = 0; | ||
| 1296 | 1297 | ||
| 1297 | mutex_lock(&mvm->mutex); | 1298 | mutex_lock(&mvm->mutex); |
| 1298 | 1299 | ||
| 1299 | /* we are starting the mac not in error flow, and restart is enabled */ | 1300 | /* we are starting the mac not in error flow, and restart is enabled */ |
| 1300 | if (!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) && | 1301 | if (!test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) && |
| 1301 | iwlwifi_mod_params.fw_restart) { | 1302 | iwlwifi_mod_params.fw_restart) { |
| 1303 | max_retry = IWL_MAX_INIT_RETRY; | ||
| 1302 | /* | 1304 | /* |
| 1303 | * This will prevent mac80211 recovery flows to trigger during | 1305 | * This will prevent mac80211 recovery flows to trigger during |
| 1304 | * init failures | 1306 | * init failures |
| @@ -1306,7 +1308,13 @@ int iwl_mvm_mac_start(struct ieee80211_hw *hw) · 1 unmodified line | |||
| 1306 | set_bit(IWL_MVM_STATUS_STARTING, &mvm->status); | 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 | clear_bit(IWL_MVM_STATUS_STARTING, &mvm->status); | 1318 | clear_bit(IWL_MVM_STATUS_STARTING, &mvm->status); |
| 1311 | 1319 | ||
| 1312 | mutex_unlock(&mvm->mutex); | 1320 | mutex_unlock(&mvm->mutex); |
| @@ -1970,7 +1978,6 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, · 657 unmodified lines | |||
| 1970 | mvm->p2p_device_vif = NULL; | 1978 | mvm->p2p_device_vif = NULL; |
| 1971 | } | 1979 | } |
| 1972 | 1980 | ||
| 1973 | iwl_mvm_unset_link_mapping(mvm, vif, &vif->bss_conf); | ||
| 1974 | iwl_mvm_mac_ctxt_remove(mvm, vif); | 1981 | iwl_mvm_mac_ctxt_remove(mvm, vif); |
| 1975 | 1982 | ||
| 1976 | RCU_INIT_POINTER(mvm->vif_id_to_mac[mvmvif->id], NULL); | 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 | mvm->monitor_on = false; | 1986 | mvm->monitor_on = false; |
| 1980 | 1987 | ||
| 1981 | out: | 1988 | out: |
| 1989 | iwl_mvm_unset_link_mapping(mvm, vif, &vif->bss_conf); | ||
| 1982 | if (vif->type == NL80211_IFTYPE_AP || | 1990 | if (vif->type == NL80211_IFTYPE_AP || |
| 1983 | vif->type == NL80211_IFTYPE_ADHOC) { | 1991 | vif->type == NL80211_IFTYPE_ADHOC) { |
| 1984 | iwl_mvm_dealloc_int_sta(mvm, &mvmvif->deflink.mcast_sta); | 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 | /* reset deflink MLO parameters */ | 41 | /* reset deflink MLO parameters */ |
| 42 | mvmvif->deflink.fw_link_id = IWL_MVM_FW_LINK_ID_INVALID; | 42 | mvmvif->deflink.fw_link_id = IWL_MVM_FW_LINK_ID_INVALID; |
| 43 | mvmvif->deflink.active = 0; | 43 | mvmvif->deflink.active = 0; |
| 44 | /* the first link always points to the default one */ | ||
| 45 | mvmvif->link[0] = &mvmvif->deflink; | ||
| 46 | 44 | ||
| 47 | ret = iwl_mvm_mld_mac_ctxt_add(mvm, vif); | 45 | ret = iwl_mvm_mld_mac_ctxt_add(mvm, vif); |
| 48 | if (ret) | 46 | if (ret) |
| @@ -60,9 +58,19 @@ static int iwl_mvm_mld_mac_add_interface(struct ieee80211_hw *hw, · 11 unmodified lines | |||
| 60 | IEEE80211_VIF_SUPPORTS_CQM_RSSI; | 58 | IEEE80211_VIF_SUPPORTS_CQM_RSSI; |
| 61 | } | 59 | } |
| 62 | 60 | ||
| 63 | ret = iwl_mvm_add_link(mvm, vif, &vif->bss_conf); | 61 | /* We want link[0] to point to the default link, unless we have MLO and |
| 64 | if (ret) | 62 | * in this case this will be modified later by .change_vif_links() |
| 65 | goto out_free_bf; | 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 | /* Save a pointer to p2p device vif, so it can later be used to | 75 | /* Save a pointer to p2p device vif, so it can later be used to |
| 68 | * update the p2p device MAC when a GO is started/stopped | 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 | rcu_read_unlock(); | 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 | /* then activate */ | 361 | /* then activate */ |
| 359 | ret = iwl_mvm_link_changed(mvm, vif, link_conf, | 362 | ret = iwl_mvm_link_changed(mvm, vif, link_conf, |
| 360 | LINK_CONTEXT_MODIFY_ACTIVE | | 363 | LINK_CONTEXT_MODIFY_ACTIVE | |
| @@ -363,6 +366,11 @@ __iwl_mvm_mld_assign_vif_chanctx(struct iwl_mvm *mvm, · 2 unmodified lines | |||
| 363 | if (ret) | 366 | if (ret) |
| 364 | goto out; | 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 | * Power state must be updated before quotas, | 375 | * Power state must be updated before quotas, |
| 368 | * otherwise fw will complain. | 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 | mutex_lock(&mvm->mutex); | 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 | err = iwl_mvm_disable_link(mvm, vif, &vif->bss_conf); | 1210 | err = iwl_mvm_disable_link(mvm, vif, &vif->bss_conf); |
| 1199 | if (err) | 1211 | if (err) |
| 1200 | goto out_err; | 1212 | goto out_err; |
| @@ -1774,7 +1774,7 @@ iwl_mvm_umac_scan_cfg_channels_v7_6g(struct iwl_mvm *mvm, · 1773 unmodified lines | |||
| 1774 | &cp->channel_config[ch_cnt]; | 1774 | &cp->channel_config[ch_cnt]; |
| 1775 | 1775 | ||
| 1776 | u32 s_ssid_bitmap = 0, bssid_bitmap = 0, flags = 0; | 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 | u8 max_s_ssids, max_bssids; | 1778 | u8 max_s_ssids, max_bssids; |
| 1779 | bool force_passive = false, found = false, allow_passive = true, | 1779 | bool force_passive = false, found = false, allow_passive = true, |
| 1780 | unsolicited_probe_on_chan = false, psc_no_listen = false; | 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 | cfg->v5.iter_count = 1; | 1799 | cfg->v5.iter_count = 1; |
| 1800 | cfg->v5.iter_interval = 0; | 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 | s8 tmp_psd_20; | 1803 | s8 tmp_psd_20; |
| 1804 | 1804 | ||
| 1805 | if (!(scan_6ghz_params[j].channel_idx == i)) | 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 | * SSID. | 1873 | * SSID. |
| 1874 | * TODO: improve this logic | 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 | if (!(scan_6ghz_params[j].channel_idx == i)) | 1877 | if (!(scan_6ghz_params[j].channel_idx == i)) |
| 1878 | continue; | 1878 | continue; |
| 1879 | 1879 | ||
| @@ -2,7 +2,7 @@ · 1 unmodified line | |||
| 2 | #include <net/ieee80211_radiotap.h> | 2 | #include <net/ieee80211_radiotap.h> |
| 3 | 3 | ||
| 4 | struct tx_radiotap_hdr { | 4 | struct tx_radiotap_hdr { |
| 5 | struct ieee80211_radiotap_header hdr; | 5 | struct ieee80211_radiotap_header_fixed hdr; |
| 6 | u8 rate; | 6 | u8 rate; |
| 7 | u8 txpower; | 7 | u8 txpower; |
| 8 | u8 rts_retries; | 8 | u8 rts_retries; |
| @@ -31,7 +31,7 @@ struct tx_radiotap_hdr { · 22 unmodified lines | |||
| 31 | #define IEEE80211_FC_DSTODS 0x0300 | 31 | #define IEEE80211_FC_DSTODS 0x0300 |
| 32 | 32 | ||
| 33 | struct rx_radiotap_hdr { | 33 | struct rx_radiotap_hdr { |
| 34 | struct ieee80211_radiotap_header hdr; | 34 | struct ieee80211_radiotap_header_fixed hdr; |
| 35 | u8 flags; | 35 | u8 flags; |
| 36 | u8 rate; | 36 | u8 rate; |
| 37 | u8 antsignal; | 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 | mutex_lock(&dev->mcu.mutex); | 84 | mutex_lock(&dev->mcu.mutex); |
| 85 | 85 | ||
| 86 | if (dev->mcu_ops->mcu_skb_prepare_msg) { | 86 | if (dev->mcu_ops->mcu_skb_prepare_msg) { |
| 87 | orig_skb = skb; | ||
| 87 | ret = dev->mcu_ops->mcu_skb_prepare_msg(dev, skb, cmd, &seq); | 88 | ret = dev->mcu_ops->mcu_skb_prepare_msg(dev, skb, cmd, &seq); |
| 88 | if (ret < 0) | 89 | if (ret < 0) |
| 89 | goto out; | 90 | goto out; |
| 90 | } | 91 | } |
| 91 | 92 | ||
| 92 | retry: | 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 | ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, &seq); | 97 | ret = dev->mcu_ops->mcu_skb_send_msg(dev, skb, cmd, &seq); |
| 95 | if (ret < 0) | 98 | if (ret < 0) |
| 96 | goto out; | 99 | goto out; |
| @@ -105,7 +108,7 @@ retry: · 8 unmodified lines | |||
| 105 | do { | 108 | do { |
| 106 | skb = mt76_mcu_get_response(dev, expires); | 109 | skb = mt76_mcu_get_response(dev, expires); |
| 107 | if (!skb && !test_bit(MT76_MCU_RESET, &dev->phy.state) && | 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 | dev_err(dev->dev, "Retry message %08x (seq %d)\n", | 112 | dev_err(dev->dev, "Retry message %08x (seq %d)\n", |
| 110 | cmd, seq); | 113 | cmd, seq); |
| 111 | skb = orig_skb; | 114 | skb = orig_skb; |
| @@ -7,12 +7,12 @@ · 6 unmodified lines | |||
| 7 | #include "cfg80211.h" | 7 | #include "cfg80211.h" |
| 8 | 8 | ||
| 9 | struct wilc_wfi_radiotap_hdr { | 9 | struct wilc_wfi_radiotap_hdr { |
| 10 | struct ieee80211_radiotap_header hdr; | 10 | struct ieee80211_radiotap_header_fixed hdr; |
| 11 | u8 rate; | 11 | u8 rate; |
| 12 | } __packed; | 12 | } __packed; |
| 13 | 13 | ||
| 14 | struct wilc_wfi_radiotap_cb_hdr { | 14 | struct wilc_wfi_radiotap_cb_hdr { |
| 15 | struct ieee80211_radiotap_header hdr; | 15 | struct ieee80211_radiotap_header_fixed hdr; |
| 16 | u8 rate; | 16 | u8 rate; |
| 17 | u8 dump; | 17 | u8 dump; |
| 18 | u16 tx_flags; | 18 | u16 tx_flags; |
| @@ -352,7 +352,6 @@ static const struct usb_device_id rtl8192d_usb_ids[] = { · 351 unmodified lines | |||
| 352 | {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8194, rtl92du_hal_cfg)}, | 352 | {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8194, rtl92du_hal_cfg)}, |
| 353 | {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8111, rtl92du_hal_cfg)}, | 353 | {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x8111, rtl92du_hal_cfg)}, |
| 354 | {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0x0193, rtl92du_hal_cfg)}, | 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 | {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0xe194, rtl92du_hal_cfg)}, | 355 | {RTL_USB_DEVICE(USB_VENDOR_ID_REALTEK, 0xe194, rtl92du_hal_cfg)}, |
| 357 | {RTL_USB_DEVICE(0x2019, 0xab2c, rtl92du_hal_cfg)}, | 356 | {RTL_USB_DEVICE(0x2019, 0xab2c, rtl92du_hal_cfg)}, |
| 358 | {RTL_USB_DEVICE(0x2019, 0xab2d, rtl92du_hal_cfg)}, | 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 | u8 size, timeout; | 771 | u8 size, timeout; |
| 772 | u16 val16; | 772 | u16 val16; |
| 773 | 773 | ||
| 774 | rtw_write32_set(rtwdev, REG_RXDMA_AGG_PG_TH, BIT_EN_PRE_CALC); | ||
| 775 | rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); | 774 | rtw_write8_set(rtwdev, REG_TXDMA_PQ_MAP, BIT_RXDMA_AGG_EN); |
| 776 | rtw_write8_clr(rtwdev, REG_RXDMA_AGG_PG_TH + 3, BIT(7)); | 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 | /* todo DBCC related event */ | 6446 | /* todo DBCC related event */ |
| 6447 | rtw89_debug(rtwdev, RTW89_DBG_BTC, "[BTC] wl_info phy_now=%d\n", phy_now); | 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 | if (wl_rinfo->dbcc_en != rtwdev->dbcc_en) { | 6451 | if (wl_rinfo->dbcc_en != rtwdev->dbcc_en) { |
| 6450 | wl_rinfo->dbcc_chg = 1; | 6452 | wl_rinfo->dbcc_chg = 1; |
| @@ -3026,24 +3026,54 @@ static void rtw89_pci_declaim_device(struct rtw89_dev *rtwdev, · 3025 unmodified lines | |||
| 3026 | pci_disable_device(pdev); | 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 | const struct rtw89_chip_info *chip = rtwdev->chip; | 3031 | const struct rtw89_chip_info *chip = rtwdev->chip; |
| 3033 | 3032 | ||
| 3034 | if (!rtwpci->enable_dac) | ||
| 3035 | return; | ||
| 3036 | |||
| 3037 | switch (chip->chip_id) { | 3033 | switch (chip->chip_id) { |
| 3038 | case RTL8852A: | 3034 | case RTL8852A: |
| 3039 | case RTL8852B: | 3035 | case RTL8852B: |
| 3040 | case RTL8851B: | 3036 | case RTL8851B: |
| 3041 | case RTL8852BT: | 3037 | case RTL8852BT: |
| 3042 | break; | 3038 | return true; |
| 3043 | default: | 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 | rtw89_pci_config_byte_set(rtwdev, RTW89_PCIE_L1_CTRL, RTW89_PCIE_BIT_EN_64BITS); | 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 | goto err; | 3091 | goto err; |
| 3062 | } | 3092 | } |
| 3063 | 3093 | ||
| 3094 | if (!rtw89_pci_is_dac_compatible_bridge(rtwdev)) | ||
| 3095 | goto no_dac; | ||
| 3096 | |||
| 3064 | ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36)); | 3097 | ret = dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(36)); |
| 3065 | if (!ret) { | 3098 | if (!ret) { |
| 3066 | rtwpci->enable_dac = true; | 3099 | rtwpci->enable_dac = true; |
| @@ -3073,6 +3106,7 @@ static int rtw89_pci_setup_mapping(struct rtw89_dev *rtwdev, · 6 unmodified lines | |||
| 3073 | goto err_release_regions; | 3106 | goto err_release_regions; |
| 3074 | } | 3107 | } |
| 3075 | } | 3108 | } |
| 3109 | no_dac: | ||
| 3076 | 3110 | ||
| 3077 | resource_len = pci_resource_len(pdev, bar_id); | 3111 | resource_len = pci_resource_len(pdev, bar_id); |
| 3078 | rtwpci->mmap = pci_iomap(pdev, bar_id, resource_len); | 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 | struct hwsim_radiotap_hdr { | 765 | struct hwsim_radiotap_hdr { |
| 766 | struct ieee80211_radiotap_header hdr; | 766 | struct ieee80211_radiotap_header_fixed hdr; |
| 767 | __le64 rt_tsft; | 767 | __le64 rt_tsft; |
| 768 | u8 rt_flags; | 768 | u8 rt_flags; |
| 769 | u8 rt_rate; | 769 | u8 rt_rate; |
| @@ -772,7 +772,7 @@ struct hwsim_radiotap_hdr { · 2 unmodified lines | |||
| 772 | } __packed; | 772 | } __packed; |
| 773 | 773 | ||
| 774 | struct hwsim_radiotap_ack_hdr { | 774 | struct hwsim_radiotap_ack_hdr { |
| 775 | struct ieee80211_radiotap_header hdr; | 775 | struct ieee80211_radiotap_header_fixed hdr; |
| 776 | u8 rt_flags; | 776 | u8 rt_flags; |
| 777 | u8 pad; | 777 | u8 pad; |
| 778 | __le16 rt_channel; | 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 | static struct rtnl_link_ops wwan_rtnl_link_ops __read_mostly = { | 1039 | static struct rtnl_link_ops wwan_rtnl_link_ops __read_mostly = { |
| 1040 | .kind = "wwan", | 1040 | .kind = "wwan", |
| 1041 | .maxtype = __IFLA_WWAN_MAX, | 1041 | .maxtype = IFLA_WWAN_MAX, |
| 1042 | .alloc = wwan_rtnl_alloc, | 1042 | .alloc = wwan_rtnl_alloc, |
| 1043 | .validate = wwan_rtnl_validate, | 1043 | .validate = wwan_rtnl_validate, |
| 1044 | .newlink = wwan_rtnl_newlink, | 1044 | .newlink = wwan_rtnl_newlink, |
| @@ -91,6 +91,17 @@ module_param(apst_secondary_latency_tol_us, ulong, 0644); · 90 unmodified lines | |||
| 91 | MODULE_PARM_DESC(apst_secondary_latency_tol_us, | 91 | MODULE_PARM_DESC(apst_secondary_latency_tol_us, |
| 92 | "secondary APST latency tolerance in us"); | 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 | * nvme_wq - hosts nvme related works that are not reset or delete | 106 | * nvme_wq - hosts nvme related works that are not reset or delete |
| 96 | * nvme_reset_wq - hosts nvme reset works | 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 | queue_delayed_work(nvme_wq, &ctrl->ka_work, delay); | 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, | 1306 | static void nvme_keep_alive_finish(struct request *rq, |
| 1296 | blk_status_t status) | 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 | unsigned long rtt = jiffies - (rq->deadline - rq->timeout); | 1309 | unsigned long rtt = jiffies - (rq->deadline - rq->timeout); |
| 1302 | unsigned long delay = nvme_keep_alive_work_period(ctrl); | 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 | * Subtract off the keepalive RTT so nvme_keep_alive_work runs | 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 | delay = 0; | 1322 | delay = 0; |
| 1314 | } | 1323 | } |
| 1315 | 1324 | ||
| 1316 | blk_mq_free_request(rq); | ||
| 1317 | |||
| 1318 | if (status) { | 1325 | if (status) { |
| 1319 | dev_err(ctrl->device, | 1326 | dev_err(ctrl->device, |
| 1320 | "failed nvme_keep_alive_end_io error=%d\n", | 1327 | "failed nvme_keep_alive_end_io error=%d\n", |
| 1321 | status); | 1328 | status); |
| 1322 | return RQ_END_IO_NONE; | 1329 | return; |
| 1323 | } | 1330 | } |
| 1324 | 1331 | ||
| 1325 | ctrl->ka_last_check_time = jiffies; | 1332 | ctrl->ka_last_check_time = jiffies; |
| 1326 | ctrl->comp_seen = false; | 1333 | ctrl->comp_seen = false; |
| 1327 | spin_lock_irqsave(&ctrl->lock, flags); | 1334 | if (state == NVME_CTRL_LIVE || state == NVME_CTRL_CONNECTING) |
| 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) | ||
| 1333 | queue_delayed_work(nvme_wq, &ctrl->ka_work, delay); | 1335 | queue_delayed_work(nvme_wq, &ctrl->ka_work, delay); |
| 1334 | return RQ_END_IO_NONE; | ||
| 1335 | } | 1336 | } |
| 1336 | 1337 | ||
| 1337 | static void nvme_keep_alive_work(struct work_struct *work) | 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 | struct nvme_ctrl, ka_work); | 1341 | struct nvme_ctrl, ka_work); |
| 1341 | bool comp_seen = ctrl->comp_seen; | 1342 | bool comp_seen = ctrl->comp_seen; |
| 1342 | struct request *rq; | 1343 | struct request *rq; |
| 1344 | blk_status_t status; | ||
| 1343 | 1345 | ||
| 1344 | ctrl->ka_last_check_time = jiffies; | 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 | nvme_init_request(rq, &ctrl->ka_cmd); | 1364 | nvme_init_request(rq, &ctrl->ka_cmd); |
| 1363 | 1365 | ||
| 1364 | rq->timeout = ctrl->kato * HZ; | 1366 | rq->timeout = ctrl->kato * HZ; |
| 1365 | rq->end_io = nvme_keep_alive_end_io; | 1367 | status = blk_execute_rq(rq, false); |
| 1366 | rq->end_io_data = ctrl; | 1368 | nvme_keep_alive_finish(rq, status, ctrl); |
| 1367 | blk_execute_rq_nowait(rq, false); | 1369 | blk_mq_free_request(rq); |
| 1368 | } | 1370 | } |
| 1369 | 1371 | ||
| 1370 | static void nvme_start_keep_alive(struct nvme_ctrl *ctrl) | 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 | nvme_start_keep_alive(ctrl); | 1401 | nvme_start_keep_alive(ctrl); |
| 1400 | } | 1402 | } |
| 1401 | 1403 | ||
| 1402 | /* | 1404 | static bool nvme_id_cns_ok(struct nvme_ctrl *ctrl, u8 cns) |
| 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) | ||
| 1409 | { | 1405 | { |
| 1410 | if (ctrl->quirks & NVME_QUIRK_IDENTIFY_CNS) | 1406 | /* |
| 1411 | return ctrl->vs < NVME_VS(1, 2, 0); | 1407 | * The CNS field occupies a full byte starting with NVMe 1.2 |
| 1412 | return ctrl->vs < NVME_VS(1, 1, 0); | 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 | static int nvme_identify_ctrl(struct nvme_ctrl *dev, struct nvme_id_ctrl **id) | 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 | if (head->pi_size && head->ms >= head->pi_size) | 1938 | if (head->pi_size && head->ms >= head->pi_size) |
| 1924 | head->pi_type = id->dps & NVME_NS_DPS_PI_MASK; | 1939 | head->pi_type = id->dps & NVME_NS_DPS_PI_MASK; |
| 1925 | if (!(id->dps & NVME_NS_DPS_PI_FIRST)) | 1940 | if (!(id->dps & NVME_NS_DPS_PI_FIRST)) { |
| 1926 | info->pi_offset = head->ms - head->pi_size; | 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 | if (ctrl->ops->flags & NVME_F_FABRICS) { | 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 | else | 2477 | else |
| 2459 | ctrl->ctrl_config = NVME_CC_CSS_NVM; | 2478 | ctrl->ctrl_config = NVME_CC_CSS_NVM; |
| 2460 | 2479 | ||
| 2461 | if (ctrl->cap & NVME_CAP_CRMS_CRWMS && ctrl->cap & NVME_CAP_CRMS_CRIMS) | 2480 | /* |
| 2462 | ctrl->ctrl_config |= NVME_CC_CRIME; | 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 | ctrl->ctrl_config |= (NVME_CTRL_PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT; | 2488 | ctrl->ctrl_config |= (NVME_CTRL_PAGE_SHIFT - 12) << NVME_CC_MPS_SHIFT; |
| 2465 | ctrl->ctrl_config |= NVME_CC_AMS_RR | NVME_CC_SHN_NONE; | 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 | * devices are known to get this wrong. Use the larger of the | 2513 | * devices are known to get this wrong. Use the larger of the |
| 2490 | * two values. | 2514 | * two values. |
| 2491 | */ | 2515 | */ |
| 2492 | if (ctrl->ctrl_config & NVME_CC_CRIME) | 2516 | ready_timeout = NVME_CRTO_CRWMT(crto); |
| 2493 | ready_timeout = NVME_CRTO_CRIMT(crto); | ||
| 2494 | else | ||
| 2495 | ready_timeout = NVME_CRTO_CRWMT(crto); | ||
| 2496 | 2517 | ||
| 2497 | if (ready_timeout < timeout) | 2518 | if (ready_timeout < timeout) |
| 2498 | dev_warn_once(ctrl->device, "bad crto:%x cap:%llx\n", | 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 | ctrl->max_zeroes_sectors = 0; | 3132 | ctrl->max_zeroes_sectors = 0; |
| 3112 | 3133 | ||
| 3113 | if (ctrl->subsys->subtype != NVME_NQN_NVME || | 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 | test_bit(NVME_CTRL_SKIP_ID_CNS_CS, &ctrl->flags)) | 3136 | test_bit(NVME_CTRL_SKIP_ID_CNS_CS, &ctrl->flags)) |
| 3116 | return 0; | 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 | mutex_lock(&ctrl->scan_lock); | 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 | nvme_scan_ns_sequential(ctrl); | 4232 | nvme_scan_ns_sequential(ctrl); |
| 4212 | } else { | 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 | struct io_uring_cmd *ioucmd = req->end_io_data; | 421 | struct io_uring_cmd *ioucmd = req->end_io_data; |
| 422 | struct nvme_uring_cmd_pdu *pdu = nvme_uring_cmd_pdu(ioucmd); | 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 | pdu->status = -EINTR; | 425 | pdu->status = -EINTR; |
| 426 | else | 426 | } else { |
| 427 | pdu->status = nvme_req(req)->status; | 427 | pdu->status = nvme_req(req)->status; |
| 428 | if (!pdu->status) | ||
| 429 | pdu->status = blk_status_to_errno(err); | ||
| 430 | } | ||
| 428 | pdu->result = le64_to_cpu(nvme_req(req)->result.u64); | 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 | case NVME_CTRL_LIVE: | 431 | case NVME_CTRL_LIVE: |
| 432 | case NVME_CTRL_RESETTING: | 432 | case NVME_CTRL_RESETTING: |
| 433 | case NVME_CTRL_CONNECTING: | 433 | case NVME_CTRL_CONNECTING: |
| 434 | /* fallthru */ | ||
| 435 | return true; | 434 | return true; |
| 436 | default: | 435 | default: |
| 437 | break; | 436 | break; |
| @@ -580,6 +579,20 @@ static int nvme_add_ns_head_cdev(struct nvme_ns_head *head) · 142 unmodified lines | |||
| 580 | return ret; | 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 | static void nvme_requeue_work(struct work_struct *work) | 596 | static void nvme_requeue_work(struct work_struct *work) |
| 584 | { | 597 | { |
| 585 | struct nvme_ns_head *head = | 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 | bio_list_init(&head->requeue_list); | 619 | bio_list_init(&head->requeue_list); |
| 607 | spin_lock_init(&head->requeue_lock); | 620 | spin_lock_init(&head->requeue_lock); |
| 608 | INIT_WORK(&head->requeue_work, nvme_requeue_work); | 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 | * Add a multipath node if the subsystems supports multiple controllers. | 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 | return PTR_ERR(head->disk); | 643 | return PTR_ERR(head->disk); |
| 630 | head->disk->fops = &nvme_ns_head_ops; | 644 | head->disk->fops = &nvme_ns_head_ops; |
| 631 | head->disk->private_data = head; | 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 | sprintf(head->disk->disk_name, "nvme%dn%d", | 656 | sprintf(head->disk->disk_name, "nvme%dn%d", |
| 633 | ctrl->subsys->instance, head->instance); | 657 | ctrl->subsys->instance, head->instance); |
| 634 | return 0; | 658 | return 0; |
| @@ -655,6 +679,7 @@ static void nvme_mpath_set_live(struct nvme_ns *ns) · 20 unmodified lines | |||
| 655 | return; | 679 | return; |
| 656 | } | 680 | } |
| 657 | nvme_add_ns_head_cdev(head); | 681 | nvme_add_ns_head_cdev(head); |
| 682 | kblockd_schedule_work(&head->partition_scan_work); | ||
| 658 | } | 683 | } |
| 659 | 684 | ||
| 660 | mutex_lock(&head->lock); | 685 | mutex_lock(&head->lock); |
| @@ -974,14 +999,14 @@ void nvme_mpath_shutdown_disk(struct nvme_ns_head *head) · 313 unmodified lines | |||
| 974 | return; | 999 | return; |
| 975 | if (test_and_clear_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) { | 1000 | if (test_and_clear_bit(NVME_NSHEAD_DISK_LIVE, &head->flags)) { |
| 976 | nvme_cdev_del(&head->cdev, &head->cdev_device); | 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 | del_gendisk(head->disk); | 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 | void nvme_mpath_remove_disk(struct nvme_ns_head *head) | 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 | /* make sure all pending bios are cleaned up */ | 1016 | /* make sure all pending bios are cleaned up */ |
| 992 | kblockd_schedule_work(&head->requeue_work); | 1017 | kblockd_schedule_work(&head->requeue_work); |
| 993 | flush_work(&head->requeue_work); | 1018 | flush_work(&head->requeue_work); |
| 1019 | flush_work(&head->partition_scan_work); | ||
| 994 | put_disk(head->disk); | 1020 | put_disk(head->disk); |
| 995 | } | 1021 | } |
| 996 | 1022 | ||
| @@ -494,6 +494,7 @@ struct nvme_ns_head { · 493 unmodified lines | |||
| 494 | struct bio_list requeue_list; | 494 | struct bio_list requeue_list; |
| 495 | spinlock_t requeue_lock; | 495 | spinlock_t requeue_lock; |
| 496 | struct work_struct requeue_work; | 496 | struct work_struct requeue_work; |
| 497 | struct work_struct partition_scan_work; | ||
| 497 | struct mutex lock; | 498 | struct mutex lock; |
| 498 | unsigned long flags; | 499 | unsigned long flags; |
| 499 | #define NVME_NSHEAD_DISK_LIVE 0 | 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 | return 1; | 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 | if (!dev->ctrl.tagset) { | 2511 | if (!dev->ctrl.tagset) { |
| 2512 | nvme_alloc_io_tag_set(&dev->ctrl, &dev->tagset, &nvme_mq_ops, | 2512 | nvme_alloc_io_tag_set(&dev->ctrl, &dev->tagset, &nvme_mq_ops, |
| 2513 | nvme_pci_nr_maps(dev), sizeof(struct nvme_iod)); | 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 | blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1); | 2527 | blk_mq_update_nr_hw_queues(&dev->tagset, dev->online_queues - 1); |
| 2518 | /* free previously allocated queues that are no longer usable */ | 2528 | /* free previously allocated queues that are no longer usable */ |
| 2519 | nvme_free_queues(dev, dev->online_queues); | 2529 | nvme_free_queues(dev, dev->online_queues); |
| 2530 | mutex_unlock(&dev->shutdown_lock); | ||
| 2531 | return true; | ||
| 2520 | } | 2532 | } |
| 2521 | 2533 | ||
| 2522 | static int nvme_pci_enable(struct nvme_dev *dev) | 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 | nvme_dbbuf_set(dev); | 2809 | nvme_dbbuf_set(dev); |
| 2798 | nvme_unquiesce_io_queues(&dev->ctrl); | 2810 | nvme_unquiesce_io_queues(&dev->ctrl); |
| 2799 | nvme_wait_freeze(&dev->ctrl); | 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 | nvme_unfreeze(&dev->ctrl); | 2814 | nvme_unfreeze(&dev->ctrl); |
| 2802 | } else { | 2815 | } else { |
| 2803 | dev_warn(dev->ctrl.device, "IO queues lost\n"); | 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 | len = nvmf_get_address(ctrl, buf, size); | 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 | mutex_lock(&queue->queue_lock); | 2650 | mutex_lock(&queue->queue_lock); |
| 2648 | 2651 | ||
| 2649 | if (!test_bit(NVME_TCP_Q_LIVE, &queue->flags)) | ||
| 2650 | goto done; | ||
| 2651 | ret = kernel_getsockname(queue->sock, (struct sockaddr *)&src_addr); | 2652 | ret = kernel_getsockname(queue->sock, (struct sockaddr *)&src_addr); |
| 2652 | if (ret > 0) { | 2653 | if (ret > 0) { |
| 2653 | if (len > 0) | 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 | len += scnprintf(buf + len, size - len, "%ssrc_addr=%pISc\n", | 2656 | len += scnprintf(buf + len, size - len, "%ssrc_addr=%pISc\n", |
| 2656 | (len) ? "," : "", &src_addr); | 2657 | (len) ? "," : "", &src_addr); |
| 2657 | } | 2658 | } |
| 2658 | done: | 2659 | |
| 2659 | mutex_unlock(&queue->queue_lock); | 2660 | mutex_unlock(&queue->queue_lock); |
| 2660 | 2661 | ||
| 2661 | return len; | 2662 | return len; |
| @@ -115,6 +115,7 @@ int nvmet_setup_dhgroup(struct nvmet_ctrl *ctrl, u8 dhgroup_id) · 114 unmodified lines | |||
| 115 | pr_debug("%s: ctrl %d failed to generate private key, err %d\n", | 115 | pr_debug("%s: ctrl %d failed to generate private key, err %d\n", |
| 116 | __func__, ctrl->cntlid, ret); | 116 | __func__, ctrl->cntlid, ret); |
| 117 | kfree_sensitive(ctrl->dh_key); | 117 | kfree_sensitive(ctrl->dh_key); |
| 118 | ctrl->dh_key = NULL; | ||
| 118 | return ret; | 119 | return ret; |
| 119 | } | 120 | } |
| 120 | ctrl->dh_keysize = crypto_kpp_maxsize(ctrl->dh_tfm); | 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 | if (!test_and_clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[0].flags)) | 266 | if (!test_and_clear_bit(NVME_LOOP_Q_LIVE, &ctrl->queues[0].flags)) |
| 267 | return; | 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 | nvmet_sq_destroy(&ctrl->queues[0].nvme_sq); | 275 | nvmet_sq_destroy(&ctrl->queues[0].nvme_sq); |
| 269 | nvme_remove_admin_tag_set(&ctrl->ctrl); | 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 | nvmet_sq_destroy(&ctrl->queues[i].nvme_sq); | 304 | nvmet_sq_destroy(&ctrl->queues[i].nvme_sq); |
| 298 | } | 305 | } |
| 299 | ctrl->ctrl.queue_count = 1; | 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 | static int nvme_loop_init_io_queues(struct nvme_loop_ctrl *ctrl) | 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 | break; | 535 | break; |
| 536 | case nvme_admin_identify: | 536 | case nvme_admin_identify: |
| 537 | switch (req->cmd->identify.cns) { | 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 | case NVME_ID_CNS_CS_CTRL: | 538 | case NVME_ID_CNS_CS_CTRL: |
| 543 | switch (req->cmd->identify.csi) { | 539 | switch (req->cmd->identify.csi) { |
| 544 | case NVME_CSI_ZNS: | 540 | case NVME_CSI_ZNS: |
| @@ -547,7 +543,9 @@ u16 nvmet_parse_passthru_admin_cmd(struct nvmet_req *req) · 2 unmodified lines | |||
| 547 | return NVME_SC_SUCCESS; | 543 | return NVME_SC_SUCCESS; |
| 548 | } | 544 | } |
| 549 | return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; | 545 | return NVME_SC_INVALID_OPCODE | NVME_STATUS_DNR; |
| 546 | case NVME_ID_CNS_CTRL: | ||
| 550 | case NVME_ID_CNS_NS: | 547 | case NVME_ID_CNS_NS: |
| 548 | case NVME_ID_CNS_NS_DESC_LIST: | ||
| 551 | req->execute = nvmet_passthru_execute_cmd; | 549 | req->execute = nvmet_passthru_execute_cmd; |
| 552 | req->p.use_workqueue = true; | 550 | req->p.use_workqueue = true; |
| 553 | return NVME_SC_SUCCESS; | 551 | return NVME_SC_SUCCESS; |
| @@ -39,6 +39,8 @@ · 38 unmodified lines | |||
| 39 | 39 | ||
| 40 | #define NVMET_RDMA_BACKLOG 128 | 40 | #define NVMET_RDMA_BACKLOG 128 |
| 41 | 41 | ||
| 42 | #define NVMET_RDMA_DISCRETE_RSP_TAG -1 | ||
| 43 | |||
| 42 | struct nvmet_rdma_srq; | 44 | struct nvmet_rdma_srq; |
| 43 | 45 | ||
| 44 | struct nvmet_rdma_cmd { | 46 | struct nvmet_rdma_cmd { |
| @@ -75,7 +77,7 @@ struct nvmet_rdma_rsp { · 30 unmodified lines | |||
| 75 | u32 invalidate_rkey; | 77 | u32 invalidate_rkey; |
| 76 | 78 | ||
| 77 | struct list_head wait_list; | 79 | struct list_head wait_list; |
| 78 | struct list_head free_list; | 80 | int tag; |
| 79 | }; | 81 | }; |
| 80 | 82 | ||
| 81 | enum nvmet_rdma_queue_state { | 83 | enum nvmet_rdma_queue_state { |
| @@ -98,8 +100,7 @@ struct nvmet_rdma_queue { · 16 unmodified lines | |||
| 98 | struct nvmet_sq nvme_sq; | 100 | struct nvmet_sq nvme_sq; |
| 99 | 101 | ||
| 100 | struct nvmet_rdma_rsp *rsps; | 102 | struct nvmet_rdma_rsp *rsps; |
| 101 | struct list_head free_rsps; | 103 | struct sbitmap rsp_tags; |
| 102 | spinlock_t rsps_lock; | ||
| 103 | struct nvmet_rdma_cmd *cmds; | 104 | struct nvmet_rdma_cmd *cmds; |
| 104 | 105 | ||
| 105 | struct work_struct release_work; | 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 | static void nvmet_rdma_free_rsp(struct nvmet_rdma_device *ndev, | 173 | static void nvmet_rdma_free_rsp(struct nvmet_rdma_device *ndev, |
| 173 | struct nvmet_rdma_rsp *r); | 174 | struct nvmet_rdma_rsp *r); |
| 174 | static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev, | 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 | static const struct nvmet_fabrics_ops nvmet_rdma_ops; | 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 | static inline struct nvmet_rdma_rsp * | 212 | static inline struct nvmet_rdma_rsp * |
| 211 | nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue) | 213 | nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue) |
| 212 | { | 214 | { |
| 213 | struct nvmet_rdma_rsp *rsp; | 215 | struct nvmet_rdma_rsp *rsp = NULL; |
| 214 | unsigned long flags; | 216 | int tag; |
| 215 | 217 | ||
| 216 | spin_lock_irqsave(&queue->rsps_lock, flags); | 218 | tag = sbitmap_get(&queue->rsp_tags); |
| 217 | rsp = list_first_entry_or_null(&queue->free_rsps, | 219 | if (tag >= 0) |
| 218 | struct nvmet_rdma_rsp, free_list); | 220 | rsp = &queue->rsps[tag]; |
| 219 | if (likely(rsp)) | ||
| 220 | list_del(&rsp->free_list); | ||
| 221 | spin_unlock_irqrestore(&queue->rsps_lock, flags); | ||
| 222 | 221 | ||
| 223 | if (unlikely(!rsp)) { | 222 | if (unlikely(!rsp)) { |
| 224 | int ret; | 223 | int ret; |
| @@ -226,13 +225,12 @@ nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue) · 1 unmodified line | |||
| 226 | rsp = kzalloc(sizeof(*rsp), GFP_KERNEL); | 225 | rsp = kzalloc(sizeof(*rsp), GFP_KERNEL); |
| 227 | if (unlikely(!rsp)) | 226 | if (unlikely(!rsp)) |
| 228 | return NULL; | 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 | if (unlikely(ret)) { | 230 | if (unlikely(ret)) { |
| 231 | kfree(rsp); | 231 | kfree(rsp); |
| 232 | return NULL; | 232 | return NULL; |
| 233 | } | 233 | } |
| 234 | |||
| 235 | rsp->allocated = true; | ||
| 236 | } | 234 | } |
| 237 | 235 | ||
| 238 | return rsp; | 236 | return rsp; |
| @@ -241,17 +239,13 @@ nvmet_rdma_get_rsp(struct nvmet_rdma_queue *queue) · 2 unmodified lines | |||
| 241 | static inline void | 239 | static inline void |
| 242 | nvmet_rdma_put_rsp(struct nvmet_rdma_rsp *rsp) | 240 | nvmet_rdma_put_rsp(struct nvmet_rdma_rsp *rsp) |
| 243 | { | 241 | { |
| 244 | unsigned long flags; | 242 | if (unlikely(rsp->tag == NVMET_RDMA_DISCRETE_RSP_TAG)) { |
| 245 | |||
| 246 | if (unlikely(rsp->allocated)) { | ||
| 247 | nvmet_rdma_free_rsp(rsp->queue->dev, rsp); | 243 | nvmet_rdma_free_rsp(rsp->queue->dev, rsp); |
| 248 | kfree(rsp); | 244 | kfree(rsp); |
| 249 | return; | 245 | return; |
| 250 | } | 246 | } |
| 251 | 247 | ||
| 252 | spin_lock_irqsave(&rsp->queue->rsps_lock, flags); | 248 | sbitmap_clear_bit(&rsp->queue->rsp_tags, rsp->tag); |
| 253 | list_add_tail(&rsp->free_list, &rsp->queue->free_rsps); | ||
| 254 | spin_unlock_irqrestore(&rsp->queue->rsps_lock, flags); | ||
| 255 | } | 249 | } |
| 256 | 250 | ||
| 257 | static void nvmet_rdma_free_inline_pages(struct nvmet_rdma_device *ndev, | 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 | static int nvmet_rdma_alloc_rsp(struct nvmet_rdma_device *ndev, | 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 | /* NVMe CQE / RDMA SEND */ | 403 | /* NVMe CQE / RDMA SEND */ |
| 410 | r->req.cqe = kmalloc(sizeof(*r->req.cqe), GFP_KERNEL); | 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 | r->read_cqe.done = nvmet_rdma_read_data_done; | 426 | r->read_cqe.done = nvmet_rdma_read_data_done; |
| 433 | /* Data Out / RDMA WRITE */ | 427 | /* Data Out / RDMA WRITE */ |
| 434 | r->write_cqe.done = nvmet_rdma_write_data_done; | 428 | r->write_cqe.done = nvmet_rdma_write_data_done; |
| 429 | r->tag = tag; | ||
| 435 | 430 | ||
| 436 | return 0; | 431 | return 0; |
| 437 | 432 | ||
| @@ -454,21 +449,23 @@ nvmet_rdma_alloc_rsps(struct nvmet_rdma_queue *queue) · 16 unmodified lines | |||
| 454 | { | 449 | { |
| 455 | struct nvmet_rdma_device *ndev = queue->dev; | 450 | struct nvmet_rdma_device *ndev = queue->dev; |
| 456 | int nr_rsps = queue->recv_queue_size * 2; | 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 | queue->rsps = kcalloc(nr_rsps, sizeof(struct nvmet_rdma_rsp), | 458 | queue->rsps = kcalloc(nr_rsps, sizeof(struct nvmet_rdma_rsp), |
| 460 | GFP_KERNEL); | 459 | GFP_KERNEL); |
| 461 | if (!queue->rsps) | 460 | if (!queue->rsps) |
| 462 | goto out; | 461 | goto out_free_sbitmap; |
| 463 | 462 | ||
| 464 | for (i = 0; i < nr_rsps; i++) { | 463 | for (i = 0; i < nr_rsps; i++) { |
| 465 | struct nvmet_rdma_rsp *rsp = &queue->rsps[i]; | 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 | if (ret) | 467 | if (ret) |
| 469 | goto out_free; | 468 | goto out_free; |
| 470 | |||
| 471 | list_add_tail(&rsp->free_list, &queue->free_rsps); | ||
| 472 | } | 469 | } |
| 473 | 470 | ||
| 474 | return 0; | 471 | return 0; |
| @@ -477,6 +474,8 @@ out_free: · 2 unmodified lines | |||
| 477 | while (--i >= 0) | 474 | while (--i >= 0) |
| 478 | nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); | 475 | nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); |
| 479 | kfree(queue->rsps); | 476 | kfree(queue->rsps); |
| 477 | out_free_sbitmap: | ||
| 478 | sbitmap_free(&queue->rsp_tags); | ||
| 480 | out: | 479 | out: |
| 481 | return ret; | 480 | return ret; |
| 482 | } | 481 | } |
| @@ -489,6 +488,7 @@ static void nvmet_rdma_free_rsps(struct nvmet_rdma_queue *queue) · 6 unmodified lines | |||
| 489 | for (i = 0; i < nr_rsps; i++) | 488 | for (i = 0; i < nr_rsps; i++) |
| 490 | nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); | 489 | nvmet_rdma_free_rsp(ndev, &queue->rsps[i]); |
| 491 | kfree(queue->rsps); | 490 | kfree(queue->rsps); |
| 491 | sbitmap_free(&queue->rsp_tags); | ||
| 492 | } | 492 | } |
| 493 | 493 | ||
| 494 | static int nvmet_rdma_post_recv(struct nvmet_rdma_device *ndev, | 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 | INIT_LIST_HEAD(&queue->rsp_wait_list); | 1447 | INIT_LIST_HEAD(&queue->rsp_wait_list); |
| 1448 | INIT_LIST_HEAD(&queue->rsp_wr_wait_list); | 1448 | INIT_LIST_HEAD(&queue->rsp_wr_wait_list); |
| 1449 | spin_lock_init(&queue->rsp_wr_wait_lock); | 1449 | spin_lock_init(&queue->rsp_wr_wait_lock); |
| 1450 | INIT_LIST_HEAD(&queue->free_rsps); | ||
| 1451 | spin_lock_init(&queue->rsps_lock); | ||
| 1452 | INIT_LIST_HEAD(&queue->queue_list); | 1450 | INIT_LIST_HEAD(&queue->queue_list); |
| 1453 | 1451 | ||
| 1454 | queue->idx = ida_alloc(&nvmet_rdma_queue_ida, GFP_KERNEL); | 1452 | queue->idx = ida_alloc(&nvmet_rdma_queue_ida, GFP_KERNEL); |
| @@ -10,6 +10,19 @@ · 9 unmodified lines | |||
| 10 | #include <kunit/test.h> | 10 | #include <kunit/test.h> |
| 11 | #include <kunit/resource.h> | 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 | #if defined(CONFIG_OF_OVERLAY) && defined(CONFIG_OF_EARLY_FLATTREE) | 26 | #if defined(CONFIG_OF_OVERLAY) && defined(CONFIG_OF_EARLY_FLATTREE) |
| 14 | 27 | ||
| 15 | static void of_overlay_fdt_apply_kunit_exit(void *ovcs_id) | 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 | int ret; | 49 | int ret; |
| 37 | int *copy_id; | 50 | int *copy_id; |
| 38 | 51 | ||
| 52 | of_root_kunit_skip(test); | ||
| 53 | |||
| 39 | copy_id = kunit_kmalloc(test, sizeof(*copy_id), GFP_KERNEL); | 54 | copy_id = kunit_kmalloc(test, sizeof(*copy_id), GFP_KERNEL); |
| 40 | if (!copy_id) | 55 | if (!copy_id) |
| 41 | return -ENOMEM; | 56 | return -ENOMEM; |
| @@ -42,6 +42,9 @@ extern raw_spinlock_t devtree_lock; · 41 unmodified lines | |||
| 42 | extern struct list_head aliases_lookup; | 42 | extern struct list_head aliases_lookup; |
| 43 | extern struct kset *of_kset; | 43 | extern struct kset *of_kset; |
| 44 | 44 | ||
| 45 | struct kunit; | ||
| 46 | extern void of_root_kunit_skip(struct kunit *test); | ||
| 47 | |||
| 45 | #if defined(CONFIG_OF_DYNAMIC) | 48 | #if defined(CONFIG_OF_DYNAMIC) |
| 46 | extern int of_property_notify(int action, struct device_node *np, | 49 | extern int of_property_notify(int action, struct device_node *np, |
| 47 | struct property *prop, struct property *old_prop); | 50 | struct property *prop, struct property *old_prop); |
| @@ -7,6 +7,8 @@ · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | #include <kunit/test.h> | 8 | #include <kunit/test.h> |
| 9 | 9 | ||
| 10 | #include "of_private.h" | ||
| 11 | |||
| 10 | /* | 12 | /* |
| 11 | * Test that the root node "/" can be found by path. | 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 | static int of_dtb_test_init(struct kunit *test) | 39 | static int of_dtb_test_init(struct kunit *test) |
| 38 | { | 40 | { |
| 41 | of_root_kunit_skip(test); | ||
| 39 | if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE)) | 42 | if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE)) |
| 40 | kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE"); | 43 | kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE"); |
| 41 | 44 | ||
| @@ -11,6 +11,8 @@ · 10 unmodified lines | |||
| 11 | #include <kunit/of.h> | 11 | #include <kunit/of.h> |
| 12 | #include <kunit/test.h> | 12 | #include <kunit/test.h> |
| 13 | 13 | ||
| 14 | #include "of_private.h" | ||
| 15 | |||
| 14 | static const char * const kunit_node_name = "kunit-test"; | 16 | static const char * const kunit_node_name = "kunit-test"; |
| 15 | static const char * const kunit_compatible = "test,empty"; | 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 | struct device *dev; | 64 | struct device *dev; |
| 63 | struct device_node *np; | 65 | struct device_node *np; |
| 64 | 66 | ||
| 67 | of_root_kunit_skip(test); | ||
| 65 | if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE)) | 68 | if (!IS_ENABLED(CONFIG_OF_EARLY_FLATTREE)) |
| 66 | kunit_skip(test, "requires CONFIG_OF_EARLY_FLATTREE for root node"); | 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 | np = of_find_node_by_name(NULL, kunit_node_name); | 77 | np = of_find_node_by_name(NULL, kunit_node_name); |
| 75 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, np); | 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 | pdev = of_find_device_by_node(np); | 81 | pdev = of_find_device_by_node(np); |
| 79 | KUNIT_ASSERT_NOT_ERR_OR_NULL(test, pdev); | 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 | /* Attach genpds */ | 2631 | /* Attach genpds */ |
| 2632 | if (config->genpd_names) { | 2632 | if (config->genpd_names) { |
| 2633 | if (config->required_devs) | 2633 | if (config->required_devs) { |
| 2634 | ret = -EINVAL; | ||
| 2634 | goto err; | 2635 | goto err; |
| 2636 | } | ||
| 2635 | 2637 | ||
| 2636 | ret = _opp_attach_genpd(opp_table, dev, config->genpd_names, | 2638 | ret = _opp_attach_genpd(opp_table, dev, config->genpd_names, |
| 2637 | config->virt_devs); | 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 | for (dev = port->devices; dev ; dev = dev->next) { | 52 | for (dev = port->devices; dev ; dev = dev->next) { |
| 53 | if(dev == port->cad) { | 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 | if(!len) { | 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 | if (len > *lenp) | 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 | if ((str = info->class_name) != NULL) | 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 | if ((str = info->model) != NULL) | 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 | if ((str = info->mfr) != NULL) | 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 | if ((str = info->description) != NULL) | 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 | if ((str = info->cmdset) != NULL) | 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 | if (len > *lenp) | 104 | if (len > *lenp) |
| 105 | len = *lenp; | 105 | len = *lenp; |
| @@ -128,7 +128,7 @@ static int do_hardware_base_addr(const struct ctl_table *table, int write, · 22 unmodified lines | |||
| 128 | if (write) /* permissions prevent this anyway */ | 128 | if (write) /* permissions prevent this anyway */ |
| 129 | return -EACCES; | 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 | if (len > *lenp) | 133 | if (len > *lenp) |
| 134 | len = *lenp; | 134 | len = *lenp; |
| @@ -155,7 +155,7 @@ static int do_hardware_irq(const struct ctl_table *table, int write, · 20 unmodified lines | |||
| 155 | if (write) /* permissions prevent this anyway */ | 155 | if (write) /* permissions prevent this anyway */ |
| 156 | return -EACCES; | 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 | if (len > *lenp) | 160 | if (len > *lenp) |
| 161 | len = *lenp; | 161 | len = *lenp; |
| @@ -182,7 +182,7 @@ static int do_hardware_dma(const struct ctl_table *table, int write, · 20 unmodified lines | |||
| 182 | if (write) /* permissions prevent this anyway */ | 182 | if (write) /* permissions prevent this anyway */ |
| 183 | return -EACCES; | 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 | if (len > *lenp) | 187 | if (len > *lenp) |
| 188 | len = *lenp; | 188 | len = *lenp; |
| @@ -213,7 +213,7 @@ static int do_hardware_modes(const struct ctl_table *table, int write, · 24 unmodified lines | |||
| 213 | #define printmode(x) \ | 213 | #define printmode(x) \ |
| 214 | do { \ | 214 | do { \ |
| 215 | if (port->modes & PARPORT_MODE_##x) \ | 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 | } while (0) | 217 | } while (0) |
| 218 | int f = 0; | 218 | int f = 0; |
| 219 | printmode(PCSPP); | 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 | static void pci_enable_acs(struct pci_dev *dev) | 1067 | static void pci_enable_acs(struct pci_dev *dev) |
| 1068 | { | 1068 | { |
| 1069 | struct pci_acs caps; | 1069 | struct pci_acs caps; |
| 1070 | bool enable_acs = false; | ||
| 1070 | int pos; | 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 | pos = dev->acs_cap; | 1079 | pos = dev->acs_cap; |
| 1073 | if (!pos) | 1080 | if (!pos) |
| 1074 | return; | 1081 | return; |
| @@ -1077,11 +1084,8 @@ static void pci_enable_acs(struct pci_dev *dev) · 2 unmodified lines | |||
| 1077 | pci_read_config_word(dev, pos + PCI_ACS_CTRL, &caps.ctrl); | 1084 | pci_read_config_word(dev, pos + PCI_ACS_CTRL, &caps.ctrl); |
| 1078 | caps.fw_ctrl = caps.ctrl; | 1085 | caps.fw_ctrl = caps.ctrl; |
| 1079 | 1086 | ||
| 1080 | /* If an iommu is present we start with kernel default caps */ | 1087 | if (enable_acs) |
| 1081 | if (pci_acs_enable) { | 1088 | pci_std_enable_acs(dev, &caps); |
| 1082 | if (pci_dev_specific_enable_acs(dev)) | ||
| 1083 | pci_std_enable_acs(dev, &caps); | ||
| 1084 | } | ||
| 1085 | 1089 | ||
| 1086 | /* | 1090 | /* |
| 1087 | * Always apply caps from the command line, even if there is no iommu. | 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 | list_for_each_entry(child, &bus->children, node) | 3105 | list_for_each_entry(child, &bus->children, node) |
| 3106 | pcie_bus_configure_settings(child); | 3106 | pcie_bus_configure_settings(child); |
| 3107 | 3107 | ||
| 3108 | pci_lock_rescan_remove(); | ||
| 3108 | pci_bus_add_devices(bus); | 3109 | pci_bus_add_devices(bus); |
| 3110 | pci_unlock_rescan_remove(); | ||
| 3109 | return 0; | 3111 | return 0; |
| 3110 | } | 3112 | } |
| 3111 | EXPORT_SYMBOL_GPL(pci_host_probe); | 3113 | EXPORT_SYMBOL_GPL(pci_host_probe); |
| @@ -6,9 +6,9 @@ · 5 unmodified lines | |||
| 6 | #include <linux/device.h> | 6 | #include <linux/device.h> |
| 7 | #include <linux/mod_devicetable.h> | 7 | #include <linux/mod_devicetable.h> |
| 8 | #include <linux/module.h> | 8 | #include <linux/module.h> |
| 9 | #include <linux/of.h> | ||
| 10 | #include <linux/pci-pwrctl.h> | 9 | #include <linux/pci-pwrctl.h> |
| 11 | #include <linux/platform_device.h> | 10 | #include <linux/platform_device.h> |
| 11 | #include <linux/property.h> | ||
| 12 | #include <linux/pwrseq/consumer.h> | 12 | #include <linux/pwrseq/consumer.h> |
| 13 | #include <linux/slab.h> | 13 | #include <linux/slab.h> |
| 14 | #include <linux/types.h> | 14 | #include <linux/types.h> |
| @@ -18,6 +18,40 @@ struct pci_pwrctl_pwrseq_data { · 3 unmodified lines | |||
| 18 | struct pwrseq_desc *pwrseq; | 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 | static void devm_pci_pwrctl_pwrseq_power_off(void *data) | 55 | static void devm_pci_pwrctl_pwrseq_power_off(void *data) |
| 22 | { | 56 | { |
| 23 | struct pwrseq_desc *pwrseq = data; | 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 | static int pci_pwrctl_pwrseq_probe(struct platform_device *pdev) | 62 | static int pci_pwrctl_pwrseq_probe(struct platform_device *pdev) |
| 29 | { | 63 | { |
| 64 | const struct pci_pwrctl_pwrseq_pdata *pdata; | ||
| 30 | struct pci_pwrctl_pwrseq_data *data; | 65 | struct pci_pwrctl_pwrseq_data *data; |
| 31 | struct device *dev = &pdev->dev; | 66 | struct device *dev = &pdev->dev; |
| 32 | int ret; | 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 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); | 79 | data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); |
| 35 | if (!data) | 80 | if (!data) |
| 36 | return -ENOMEM; | 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 | if (IS_ERR(data->pwrseq)) | 84 | if (IS_ERR(data->pwrseq)) |
| 40 | return dev_err_probe(dev, PTR_ERR(data->pwrseq), | 85 | return dev_err_probe(dev, PTR_ERR(data->pwrseq), |
| 41 | "Failed to get the power sequencer\n"); | 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 | /* ATH11K in QCA6390 package. */ | 110 | /* ATH11K in QCA6390 package. */ |
| 66 | .compatible = "pci17cb,1101", | 111 | .compatible = "pci17cb,1101", |
| 67 | .data = "wlan", | 112 | .data = &pci_pwrctl_pwrseq_qcom_wcn_pdata, |
| 68 | }, | 113 | }, |
| 69 | { | 114 | { |
| 70 | /* ATH11K in WCN6855 package. */ | 115 | /* ATH11K in WCN6855 package. */ |
| 71 | .compatible = "pci17cb,1103", | 116 | .compatible = "pci17cb,1103", |
| 72 | .data = "wlan", | 117 | .data = &pci_pwrctl_pwrseq_qcom_wcn_pdata, |
| 73 | }, | 118 | }, |
| 74 | { | 119 | { |
| 75 | /* ATH12K in WCN7850 package. */ | 120 | /* ATH12K in WCN7850 package. */ |
| 76 | .compatible = "pci17cb,1107", | 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 | } else { | 153 | } else { |
| 154 | USB_CTRL_SET(ctrl, USB_PM, XHC_SOFT_RESETB); | 154 | USB_CTRL_SET(ctrl, USB_PM, XHC_SOFT_RESETB); |
| 155 | /* Required for COMMONONN to be set */ | 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 | /* 1 millisecond - for USB clocks to settle down */ | 330 | /* 1 millisecond - for USB clocks to settle down */ |
| 329 | usleep_range(1000, 2000); | 331 | usleep_range(1000, 2000); |
| 330 | 332 | ||
| 331 | /* Disable PHY when port is suspended */ | 333 | /* |
| 332 | USB_CTRL_SET(ctrl, P0_U2PHY_CFG1, COMMONONN); | 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 | usb_wake_enable_7216(params, false); | 340 | usb_wake_enable_7216(params, false); |
| 335 | usb_init_common(params); | 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 | 0, /* USB_CTRL_SETUP_SCB2_EN_MASK */ | 220 | 0, /* USB_CTRL_SETUP_SCB2_EN_MASK */ |
| 221 | 0, /* USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK */ | 221 | 0, /* USB_CTRL_SETUP_SS_EHCI64BIT_EN_MASK */ |
| 222 | 0, /* USB_CTRL_SETUP_STRAP_IPP_SEL_MASK */ | 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 | 0, /* USB_CTRL_SETUP_OC3_DISABLE_MASK */ | 225 | 0, /* USB_CTRL_SETUP_OC3_DISABLE_MASK */ |
| 224 | 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ | 226 | 0, /* USB_CTRL_PLL_CTL_PLL_IDDQ_PWRDN_MASK */ |
| 225 | 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ | 227 | 0, /* USB_CTRL_USB_PM_BDC_SOFT_RESETB_MASK */ |
| @@ -174,8 +174,9 @@ · 173 unmodified lines | |||
| 174 | #define SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG 0x150 | 174 | #define SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG 0x150 |
| 175 | #define SIERRA_DEQ_TAU_CTRL2_PREG 0x151 | 175 | #define SIERRA_DEQ_TAU_CTRL2_PREG 0x151 |
| 176 | #define SIERRA_DEQ_TAU_CTRL3_PREG 0x152 | 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 | #define SIERRA_DEQ_CONCUR_EPIOFFSET_MODE_PREG 0x159 | 178 | #define SIERRA_DEQ_CONCUR_EPIOFFSET_MODE_PREG 0x159 |
| 179 | #define SIERRA_DEQ_OPENEYE_CTRL_PREG 0x15C | ||
| 179 | #define SIERRA_DEQ_PICTRL_PREG 0x161 | 180 | #define SIERRA_DEQ_PICTRL_PREG 0x161 |
| 180 | #define SIERRA_CPICAL_TMRVAL_MODE1_PREG 0x170 | 181 | #define SIERRA_CPICAL_TMRVAL_MODE1_PREG 0x170 |
| 181 | #define SIERRA_CPICAL_TMRVAL_MODE0_PREG 0x171 | 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 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, | 1734 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 1734 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, | 1735 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 1735 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, | 1736 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 1736 | {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | 1737 | {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, |
| 1737 | {0x002B, SIERRA_CPI_TRIM_PREG}, | 1738 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 1738 | {0x0003, SIERRA_EPI_CTRL_PREG}, | 1739 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 1739 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, | 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 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, | 1798 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 1798 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, | 1799 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 1799 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, | 1800 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 1800 | {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | 1801 | {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, |
| 1801 | {0x002B, SIERRA_CPI_TRIM_PREG}, | 1802 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 1802 | {0x0003, SIERRA_EPI_CTRL_PREG}, | 1803 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 1803 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, | 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 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, | 1875 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 1875 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, | 1876 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 1876 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, | 1877 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 1877 | {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | 1878 | {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, |
| 1878 | {0x002B, SIERRA_CPI_TRIM_PREG}, | 1879 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 1879 | {0x0003, SIERRA_EPI_CTRL_PREG}, | 1880 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 1880 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, | 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 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, | 1942 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 1942 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, | 1943 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 1943 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, | 1944 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 1944 | {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | 1945 | {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, |
| 1945 | {0x002B, SIERRA_CPI_TRIM_PREG}, | 1946 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 1946 | {0x0003, SIERRA_EPI_CTRL_PREG}, | 1947 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 1947 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, | 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 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, | 2013 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 2013 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, | 2014 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 2014 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, | 2015 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 2015 | {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | 2016 | {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, |
| 2016 | {0x002B, SIERRA_CPI_TRIM_PREG}, | 2017 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 2017 | {0x0003, SIERRA_EPI_CTRL_PREG}, | 2018 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 2018 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, | 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 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, | 2080 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 2080 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, | 2081 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 2081 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, | 2082 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 2082 | {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | 2083 | {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, |
| 2083 | {0x002B, SIERRA_CPI_TRIM_PREG}, | 2084 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 2084 | {0x0003, SIERRA_EPI_CTRL_PREG}, | 2085 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 2085 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, | 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 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, | 2141 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 2141 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, | 2142 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 2142 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, | 2143 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 2143 | {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | 2144 | {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, |
| 2144 | {0x002B, SIERRA_CPI_TRIM_PREG}, | 2145 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 2145 | {0x0003, SIERRA_EPI_CTRL_PREG}, | 2146 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 2146 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, | 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 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, | 2216 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 2216 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, | 2217 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 2217 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, | 2218 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 2218 | {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | 2219 | {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, |
| 2219 | {0x002B, SIERRA_CPI_TRIM_PREG}, | 2220 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 2220 | {0x0003, SIERRA_EPI_CTRL_PREG}, | 2221 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 2221 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, | 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 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, | 2285 | {0x3C0F, SIERRA_DEQ_TAU_CTRL1_SLOW_MAINT_PREG}, |
| 2285 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, | 2286 | {0x1C0C, SIERRA_DEQ_TAU_CTRL2_PREG}, |
| 2286 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, | 2287 | {0x0100, SIERRA_DEQ_TAU_CTRL3_PREG}, |
| 2287 | {0x5E82, SIERRA_DEQ_OPENEYE_CTRL_PREG}, | 2288 | {0x5E82, SIERRA_DEQ_TAU_EPIOFFSET_MODE_PREG}, |
| 2288 | {0x002B, SIERRA_CPI_TRIM_PREG}, | 2289 | {0x002B, SIERRA_CPI_TRIM_PREG}, |
| 2289 | {0x0003, SIERRA_EPI_CTRL_PREG}, | 2290 | {0x0003, SIERRA_EPI_CTRL_PREG}, |
| 2290 | {0x803F, SIERRA_SDFILT_H2L_A_PREG}, | 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 | IMX8MM_GPR_PCIE_REF_CLK_PLL); | 141 | IMX8MM_GPR_PCIE_REF_CLK_PLL); |
| 142 | usleep_range(100, 200); | 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 | switch (imx8_phy->drvdata->variant) { | 144 | switch (imx8_phy->drvdata->variant) { |
| 150 | case IMX8MP: | 145 | case IMX8MP: |
| 151 | reset_control_deassert(imx8_phy->perst); | 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 | break; | 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 | /* Polling to check the phy is ready or not. */ | 159 | /* Polling to check the phy is ready or not. */ |
| 160 | ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG075, | 160 | ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG075, |
| 161 | val, val == ANA_PLL_DONE, 10, 20000); | 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 | return -ENOMEM; | 3673 | return -ENOMEM; |
| 3674 | 3674 | ||
| 3675 | qmp->dev = dev; | 3675 | qmp->dev = dev; |
| 3676 | dev_set_drvdata(dev, qmp); | ||
| 3676 | 3677 | ||
| 3677 | qmp->orientation = TYPEC_ORIENTATION_NORMAL; | 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 | phy_set_drvdata(qmp->dp_phy, qmp); | 3751 | phy_set_drvdata(qmp->dp_phy, qmp); |
| 3751 | 3752 | ||
| 3752 | dev_set_drvdata(dev, qmp); | ||
| 3753 | |||
| 3754 | if (usb_np == dev->of_node) | 3753 | if (usb_np == dev->of_node) |
| 3755 | phy_provider = devm_of_phy_provider_register(dev, qmp_combo_phy_xlate); | 3754 | phy_provider = devm_of_phy_provider_register(dev, qmp_combo_phy_xlate); |
| 3756 | else | 3755 | else |
| @@ -3661,8 +3661,8 @@ static const struct qmp_phy_cfg x1e80100_qmp_gen4x2_pciephy_cfg = { · 3660 unmodified lines | |||
| 3661 | 3661 | ||
| 3662 | .reset_list = sdm845_pciephy_reset_l, | 3662 | .reset_list = sdm845_pciephy_reset_l, |
| 3663 | .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), | 3663 | .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), |
| 3664 | .vreg_list = sm8550_qmp_phy_vreg_l, | 3664 | .vreg_list = qmp_phy_vreg_l, |
| 3665 | .num_vregs = ARRAY_SIZE(sm8550_qmp_phy_vreg_l), | 3665 | .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), |
| 3666 | .regs = pciephy_v6_regs_layout, | 3666 | .regs = pciephy_v6_regs_layout, |
| 3667 | 3667 | ||
| 3668 | .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, | 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 | .reset_list = sdm845_pciephy_reset_l, | 3696 | .reset_list = sdm845_pciephy_reset_l, |
| 3697 | .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), | 3697 | .num_resets = ARRAY_SIZE(sdm845_pciephy_reset_l), |
| 3698 | .vreg_list = sm8550_qmp_phy_vreg_l, | 3698 | .vreg_list = qmp_phy_vreg_l, |
| 3699 | .num_vregs = ARRAY_SIZE(sm8550_qmp_phy_vreg_l), | 3699 | .num_vregs = ARRAY_SIZE(qmp_phy_vreg_l), |
| 3700 | .regs = pciephy_v6_regs_layout, | 3700 | .regs = pciephy_v6_regs_layout, |
| 3701 | 3701 | ||
| 3702 | .pwrdn_ctrl = SW_PWRDN | REFCLK_DRV_DSBL, | 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 | return -ENOMEM; | 1248 | return -ENOMEM; |
| 1249 | 1249 | ||
| 1250 | qmp->dev = dev; | 1250 | qmp->dev = dev; |
| 1251 | dev_set_drvdata(dev, qmp); | ||
| 1251 | 1252 | ||
| 1252 | qmp->cfg = of_device_get_match_data(dev); | 1253 | qmp->cfg = of_device_get_match_data(dev); |
| 1253 | if (!qmp->cfg) | 1254 | if (!qmp->cfg) |
| @@ -2179,6 +2179,7 @@ static int qmp_usb_probe(struct platform_device *pdev) · 2178 unmodified lines | |||
| 2179 | return -ENOMEM; | 2179 | return -ENOMEM; |
| 2180 | 2180 | ||
| 2181 | qmp->dev = dev; | 2181 | qmp->dev = dev; |
| 2182 | dev_set_drvdata(dev, qmp); | ||
| 2182 | 2183 | ||
| 2183 | qmp->cfg = of_device_get_match_data(dev); | 2184 | qmp->cfg = of_device_get_match_data(dev); |
| 2184 | if (!qmp->cfg) | 2185 | if (!qmp->cfg) |
| @@ -1050,6 +1050,7 @@ static int qmp_usbc_probe(struct platform_device *pdev) · 1049 unmodified lines | |||
| 1050 | return -ENOMEM; | 1050 | return -ENOMEM; |
| 1051 | 1051 | ||
| 1052 | qmp->dev = dev; | 1052 | qmp->dev = dev; |
| 1053 | dev_set_drvdata(dev, qmp); | ||
| 1053 | 1054 | ||
| 1054 | qmp->orientation = TYPEC_ORIENTATION_NORMAL; | 1055 | qmp->orientation = TYPEC_ORIENTATION_NORMAL; |
| 1055 | 1056 | ||
| @@ -86,6 +86,7 @@ config PHY_ROCKCHIP_PCIE · 85 unmodified lines | |||
| 86 | config PHY_ROCKCHIP_SAMSUNG_HDPTX | 86 | config PHY_ROCKCHIP_SAMSUNG_HDPTX |
| 87 | tristate "Rockchip Samsung HDMI/eDP Combo PHY driver" | 87 | tristate "Rockchip Samsung HDMI/eDP Combo PHY driver" |
| 88 | depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF | 88 | depends on (ARCH_ROCKCHIP || COMPILE_TEST) && OF |
| 89 | depends on COMMON_CLK | ||
| 89 | depends on HAS_IOMEM | 90 | depends on HAS_IOMEM |
| 90 | select GENERIC_PHY | 91 | select GENERIC_PHY |
| 91 | select MFD_SYSCON | 92 | select MFD_SYSCON |
| @@ -10,18 +10,24 @@ · 9 unmodified lines | |||
| 10 | #include <linux/clk.h> | 10 | #include <linux/clk.h> |
| 11 | #include <linux/err.h> | 11 | #include <linux/err.h> |
| 12 | #include <linux/io.h> | 12 | #include <linux/io.h> |
| 13 | #include <linux/mfd/syscon.h> | ||
| 13 | #include <linux/module.h> | 14 | #include <linux/module.h> |
| 14 | #include <linux/phy/phy.h> | 15 | #include <linux/phy/phy.h> |
| 15 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
| 17 | #include <linux/regmap.h> | ||
| 16 | #include <linux/usb/of.h> | 18 | #include <linux/usb/of.h> |
| 17 | 19 | ||
| 18 | #define USB_125M_CLK_RATE 125000000 | 20 | #define USB_125M_CLK_RATE 125000000 |
| 19 | #define USB_LS_KEEPALIVE_OFF 0x4 | 21 | #define USB_LS_KEEPALIVE_OFF 0x4 |
| 20 | #define USB_LS_KEEPALIVE_ENABLE BIT(4) | 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 | struct jh7110_usb2_phy { | 27 | struct jh7110_usb2_phy { |
| 23 | struct phy *phy; | 28 | struct phy *phy; |
| 24 | void __iomem *regs; | 29 | void __iomem *regs; |
| 30 | struct regmap *sys_syscon; | ||
| 25 | struct clk *usb_125m_clk; | 31 | struct clk *usb_125m_clk; |
| 26 | struct clk *app_125m; | 32 | struct clk *app_125m; |
| 27 | enum phy_mode mode; | 33 | enum phy_mode mode; |
| @@ -61,6 +67,10 @@ static int usb2_phy_set_mode(struct phy *_phy, · 33 unmodified lines | |||
| 61 | usb2_set_ls_keepalive(phy, (mode != PHY_MODE_USB_DEVICE)); | 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 | return 0; | 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 | phy_set_drvdata(phy->phy, phy); | 139 | phy_set_drvdata(phy->phy, phy); |
| 130 | phy_provider = devm_of_phy_provider_register(dev, of_phy_simple_xlate); | 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 | return PTR_ERR_OR_ZERO(phy_provider); | 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 | return -ENOMEM; | 699 | return -ENOMEM; |
| 700 | 700 | ||
| 701 | lane = tegra_xusb_find_lane(port->padctl, "usb2", port->index); | 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 | * Assign phy dev to usb-phy dev. Host/device drivers can use phy | 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 | } else if (wiz->lane_phy_type[i] == PHY_TYPE_USXGMII) { | 450 | } else if (wiz->lane_phy_type[i] == PHY_TYPE_USXGMII) { |
| 451 | ret = regmap_field_write(wiz->p0_mac_src_sel[i], 0x3); | 451 | ret = regmap_field_write(wiz->p0_mac_src_sel[i], 0x3); |
| 452 | ret = regmap_field_write(wiz->p0_rxfclk_sel[i], 0x3); | 452 | ret = regmap_field_write(wiz->p0_rxfclk_sel[i], 0x3); |
| 453 | ret = regmap_field_write(wiz->p0_refclk_sel[i], 0x3); | 453 | ret = regmap_field_write(wiz->p0_refclk_sel[i], 0x2); |
| 454 | mode = LANE_MODE_GEN1; | 454 | mode = LANE_MODE_GEN2; |
| 455 | } else { | 455 | } else { |
| 456 | continue; | 456 | continue; |
| 457 | } | 457 | } |
| @@ -46,6 +46,7 @@ config PINCTRL_INTEL_PLATFORM · 45 unmodified lines | |||
| 46 | of Intel PCH pins and using them as GPIOs. Currently the following | 46 | of Intel PCH pins and using them as GPIOs. Currently the following |
| 47 | Intel SoCs / platforms require this to be functional: | 47 | Intel SoCs / platforms require this to be functional: |
| 48 | - Lunar Lake | 48 | - Lunar Lake |
| 49 | - Panther Lake | ||
| 49 | 50 | ||
| 50 | config PINCTRL_ALDERLAKE | 51 | config PINCTRL_ALDERLAKE |
| 51 | tristate "Intel Alder Lake pinctrl and GPIO driver" | 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 | struct intel_community *community, | 90 | struct intel_community *community, |
| 91 | struct intel_platform_pins *pins) | 91 | struct intel_platform_pins *pins) |
| 92 | { | 92 | { |
| 93 | struct fwnode_handle *child; | ||
| 94 | struct intel_padgroup *gpps; | 93 | struct intel_padgroup *gpps; |
| 95 | unsigned int group; | 94 | unsigned int group; |
| 96 | size_t ngpps; | 95 | size_t ngpps; |
| @@ -131,7 +130,7 @@ static int intel_platform_pinctrl_prepare_community(struct device *dev, · 34 unmodified lines | |||
| 131 | return -ENOMEM; | 130 | return -ENOMEM; |
| 132 | 131 | ||
| 133 | group = 0; | 132 | group = 0; |
| 134 | device_for_each_child_node(dev, child) { | 133 | device_for_each_child_node_scoped(dev, child) { |
| 135 | struct intel_padgroup *gpp = &gpps[group]; | 134 | struct intel_padgroup *gpp = &gpps[group]; |
| 136 | 135 | ||
| 137 | gpp->reg_num = group; | 136 | gpp->reg_num = group; |
| @@ -159,7 +158,7 @@ static int intel_platform_pinctrl_prepare_soc_data(struct device *dev, · 21 unmodified lines | |||
| 159 | int ret; | 158 | int ret; |
| 160 | 159 | ||
| 161 | /* Version 1.0 of the specification assumes only a single community per device node */ | 160 | /* Version 1.0 of the specification assumes only a single community per device node */ |
| 162 | ncommunities = 1, | 161 | ncommunities = 1; |
| 163 | communities = devm_kcalloc(dev, ncommunities, sizeof(*communities), GFP_KERNEL); | 162 | communities = devm_kcalloc(dev, ncommunities, sizeof(*communities), GFP_KERNEL); |
| 164 | if (!communities) | 163 | if (!communities) |
| 165 | return -ENOMEM; | 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 | map_num += grp->npins; | 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 | if (!new_map) | 222 | if (!new_map) |
| 223 | return -ENOMEM; | 223 | return -ENOMEM; |
| 224 | 224 | ||
| @@ -474,6 +474,9 @@ static int apple_gpio_pinctrl_probe(struct platform_device *pdev) · 473 unmodified lines | |||
| 474 | for (i = 0; i < npins; i++) { | 474 | for (i = 0; i < npins; i++) { |
| 475 | pins[i].number = i; | 475 | pins[i].number = i; |
| 476 | pins[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "PIN%u", i); | 476 | pins[i].name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "PIN%u", i); |
| 477 | if (!pins[i].name) | ||
| 478 | return -ENOMEM; | ||
| 479 | |||
| 477 | pins[i].drv_data = pctl; | 480 | pins[i].drv_data = pctl; |
| 478 | pin_names[i] = pins[i].name; | 481 | pin_names[i] = pins[i].name; |
| 479 | pin_nums[i] = i; | 482 | pin_nums[i] = i; |
| @@ -987,8 +987,10 @@ static int aw9523_probe(struct i2c_client *client) · 986 unmodified lines | |||
| 987 | lockdep_set_subclass(&awi->i2c_lock, i2c_adapter_depth(client->adapter)); | 987 | lockdep_set_subclass(&awi->i2c_lock, i2c_adapter_depth(client->adapter)); |
| 988 | 988 | ||
| 989 | pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL); | 989 | pdesc = devm_kzalloc(dev, sizeof(*pdesc), GFP_KERNEL); |
| 990 | if (!pdesc) | 990 | if (!pdesc) { |
| 991 | return -ENOMEM; | 991 | ret = -ENOMEM; |
| 992 | goto err_disable_vregs; | ||
| 993 | } | ||
| 992 | 994 | ||
| 993 | ret = aw9523_hw_init(awi); | 995 | ret = aw9523_hw_init(awi); |
| 994 | if (ret) | 996 | if (ret) |
| @@ -1955,21 +1955,21 @@ static void ocelot_irq_handler(struct irq_desc *desc) · 1954 unmodified lines | |||
| 1955 | unsigned int reg = 0, irq, i; | 1955 | unsigned int reg = 0, irq, i; |
| 1956 | unsigned long irqs; | 1956 | unsigned long irqs; |
| 1957 | 1957 | ||
| 1958 | chained_irq_enter(parent_chip, desc); | ||
| 1959 | |||
| 1958 | for (i = 0; i < info->stride; i++) { | 1960 | for (i = 0; i < info->stride; i++) { |
| 1959 | regmap_read(info->map, id_reg + 4 * i, ®); | 1961 | regmap_read(info->map, id_reg + 4 * i, ®); |
| 1960 | if (!reg) | 1962 | if (!reg) |
| 1961 | continue; | 1963 | continue; |
| 1962 | 1964 | ||
| 1963 | chained_irq_enter(parent_chip, desc); | ||
| 1964 | |||
| 1965 | irqs = reg; | 1965 | irqs = reg; |
| 1966 | 1966 | ||
| 1967 | for_each_set_bit(irq, &irqs, | 1967 | for_each_set_bit(irq, &irqs, |
| 1968 | min(32U, info->desc->npins - 32 * i)) | 1968 | min(32U, info->desc->npins - 32 * i)) |
| 1969 | generic_handle_domain_irq(chip->irq.domain, irq + 32 * i); | 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 | static int ocelot_gpiochip_register(struct platform_device *pdev, | 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 | if (!grpnames) | 221 | if (!grpnames) |
| 222 | return -ENOMEM; | 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 | if (!map) | 225 | if (!map) |
| 226 | return -ENOMEM; | 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 | for (i = 0; i < npins; i++) { | 1375 | for (i = 0; i < npins; i++) { |
| 1376 | stm32_pin = stm32_pctrl_get_desc_pin_from_gpio(pctl, bank, i); | 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 | names[i] = devm_kasprintf(dev, GFP_KERNEL, "%s", stm32_pin->pin.name); | 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 | names[i] = NULL; | 1384 | names[i] = NULL; |
| 1385 | } | ||
| 1381 | } | 1386 | } |
| 1382 | 1387 | ||
| 1383 | bank->gpio_chip.names = (const char * const *)names; | 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 | if (!asus->throttle_thermal_policy_dev) | 3908 | if (!asus->throttle_thermal_policy_dev) |
| 3909 | return 0; | 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 | dev_info(dev, "Using throttle_thermal_policy for platform_profile support\n"); | 3921 | dev_info(dev, "Using throttle_thermal_policy for platform_profile support\n"); |
| 3912 | 3922 | ||
| 3913 | asus->platform_profile_handler.profile_get = asus_wmi_platform_profile_get; | 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 | /*Speaker Mute*/ | 264 | /*Speaker Mute*/ |
| 265 | { KE_KEY, 0x109, { KEY_MUTE} }, | 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 | /* Mic mute */ | 276 | /* Mic mute */ |
| 268 | { KE_KEY, 0x150, { KEY_MICMUTE } }, | 277 | { KE_KEY, 0x150, { KEY_MICMUTE } }, |
| 269 | 278 | ||
| @@ -295,8 +295,6 @@ const struct pmc_reg_map adl_reg_map = { · 294 unmodified lines | |||
| 295 | .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES, | 295 | .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES, |
| 296 | .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, | 296 | .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, |
| 297 | .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, | 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 | .ltr_ignore_max = ADL_NUM_IP_IGN_ALLOWED, | 298 | .ltr_ignore_max = ADL_NUM_IP_IGN_ALLOWED, |
| 301 | .lpm_num_modes = ADL_LPM_NUM_MODES, | 299 | .lpm_num_modes = ADL_LPM_NUM_MODES, |
| 302 | .lpm_num_maps = ADL_LPM_NUM_MAPS, | 300 | .lpm_num_maps = ADL_LPM_NUM_MAPS, |
| @@ -200,8 +200,6 @@ const struct pmc_reg_map cnp_reg_map = { · 199 unmodified lines | |||
| 200 | .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES, | 200 | .ppfear_buckets = CNP_PPFEAR_NUM_ENTRIES, |
| 201 | .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, | 201 | .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, |
| 202 | .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, | 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 | .ltr_ignore_max = CNP_NUM_IP_IGN_ALLOWED, | 203 | .ltr_ignore_max = CNP_NUM_IP_IGN_ALLOWED, |
| 206 | .etr3_offset = ETR3_OFFSET, | 204 | .etr3_offset = ETR3_OFFSET, |
| 207 | }; | 205 | }; |
| @@ -11,7 +11,6 @@ · 10 unmodified lines | |||
| 11 | 11 | ||
| 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | 12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
| 13 | 13 | ||
| 14 | #include <linux/acpi_pmtmr.h> | ||
| 15 | #include <linux/bitfield.h> | 14 | #include <linux/bitfield.h> |
| 16 | #include <linux/debugfs.h> | 15 | #include <linux/debugfs.h> |
| 17 | #include <linux/delay.h> | 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 | return val == 1; | 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 | static void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev) | 1260 | static void pmc_core_dbgfs_unregister(struct pmc_dev *pmcdev) |
| 1295 | { | 1261 | { |
| 1296 | debugfs_remove_recursive(pmcdev->dbgfs_dir); | 1262 | debugfs_remove_recursive(pmcdev->dbgfs_dir); |
| @@ -1486,7 +1452,6 @@ static int pmc_core_probe(struct platform_device *pdev) · 189 unmodified lines | |||
| 1486 | struct pmc_dev *pmcdev; | 1452 | struct pmc_dev *pmcdev; |
| 1487 | const struct x86_cpu_id *cpu_id; | 1453 | const struct x86_cpu_id *cpu_id; |
| 1488 | int (*core_init)(struct pmc_dev *pmcdev); | 1454 | int (*core_init)(struct pmc_dev *pmcdev); |
| 1489 | const struct pmc_reg_map *map; | ||
| 1490 | struct pmc *primary_pmc; | 1455 | struct pmc *primary_pmc; |
| 1491 | int ret; | 1456 | int ret; |
| 1492 | 1457 | ||
| @@ -1545,11 +1510,6 @@ static int pmc_core_probe(struct platform_device *pdev) · 52 unmodified lines | |||
| 1545 | pm_report_max_hw_sleep(FIELD_MAX(SLP_S0_RES_COUNTER_MASK) * | 1510 | pm_report_max_hw_sleep(FIELD_MAX(SLP_S0_RES_COUNTER_MASK) * |
| 1546 | pmc_core_adjust_slp_s0_step(primary_pmc, 1)); | 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 | device_initialized = true; | 1513 | device_initialized = true; |
| 1554 | dev_info(&pdev->dev, " initialized\n"); | 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 | static void pmc_core_remove(struct platform_device *pdev) | 1519 | static void pmc_core_remove(struct platform_device *pdev) |
| 1560 | { | 1520 | { |
| 1561 | struct pmc_dev *pmcdev = platform_get_drvdata(pdev); | 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 | pmc_core_dbgfs_unregister(pmcdev); | 1522 | pmc_core_dbgfs_unregister(pmcdev); |
| 1569 | pmc_core_clean_structure(pdev); | 1523 | pmc_core_clean_structure(pdev); |
| 1570 | } | 1524 | } |
| @@ -68,8 +68,6 @@ struct telem_endpoint; · 67 unmodified lines | |||
| 68 | #define SPT_PMC_LTR_SCC 0x3A0 | 68 | #define SPT_PMC_LTR_SCC 0x3A0 |
| 69 | #define SPT_PMC_LTR_ISH 0x3A4 | 69 | #define SPT_PMC_LTR_ISH 0x3A4 |
| 70 | 70 | ||
| 71 | #define SPT_PMC_ACPI_PM_TMR_CTL_OFFSET 0x18FC | ||
| 72 | |||
| 73 | /* Sunrise Point: PGD PFET Enable Ack Status Registers */ | 71 | /* Sunrise Point: PGD PFET Enable Ack Status Registers */ |
| 74 | enum ppfear_regs { | 72 | enum ppfear_regs { |
| 75 | SPT_PMC_XRAM_PPFEAR0A = 0x590, | 73 | SPT_PMC_XRAM_PPFEAR0A = 0x590, |
| @@ -150,8 +148,6 @@ enum ppfear_regs { · 74 unmodified lines | |||
| 150 | #define SPT_PMC_VRIC1_SLPS0LVEN BIT(13) | 148 | #define SPT_PMC_VRIC1_SLPS0LVEN BIT(13) |
| 151 | #define SPT_PMC_VRIC1_XTALSDQDIS BIT(22) | 149 | #define SPT_PMC_VRIC1_XTALSDQDIS BIT(22) |
| 152 | 150 | ||
| 153 | #define SPT_PMC_BIT_ACPI_PM_TMR_DISABLE BIT(1) | ||
| 154 | |||
| 155 | /* Cannonlake Power Management Controller register offsets */ | 151 | /* Cannonlake Power Management Controller register offsets */ |
| 156 | #define CNP_PMC_SLPS0_DBG_OFFSET 0x10B4 | 152 | #define CNP_PMC_SLPS0_DBG_OFFSET 0x10B4 |
| 157 | #define CNP_PMC_PM_CFG_OFFSET 0x1818 | 153 | #define CNP_PMC_PM_CFG_OFFSET 0x1818 |
| @@ -355,8 +351,6 @@ struct pmc_reg_map { · 197 unmodified lines | |||
| 355 | const u8 *lpm_reg_index; | 351 | const u8 *lpm_reg_index; |
| 356 | const u32 pson_residency_offset; | 352 | const u32 pson_residency_offset; |
| 357 | const u32 pson_residency_counter_step; | 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 | u32 die_c6_offset; | 426 | u32 die_c6_offset; |
| 433 | struct telem_endpoint *punit_ep; | 427 | struct telem_endpoint *punit_ep; |
| 434 | struct pmc_info *regmap_list; | 428 | struct pmc_info *regmap_list; |
| 435 | |||
| 436 | bool enable_acpi_pm_timer_on_resume; | ||
| 437 | }; | 429 | }; |
| 438 | 430 | ||
| 439 | enum pmc_index { | 431 | enum pmc_index { |
| @@ -29,7 +29,7 @@ · 28 unmodified lines | |||
| 29 | #define LPM_REG_COUNT 28 | 29 | #define LPM_REG_COUNT 28 |
| 30 | #define LPM_MODE_OFFSET 1 | 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 | static u32 pmc_core_find_guid(struct pmc_info *list, const struct pmc_reg_map *map) | 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 | ssram_base = ssram_pcidev->resource[0].start; | 263 | ssram_base = ssram_pcidev->resource[0].start; |
| 264 | tmp_ssram = ioremap(ssram_base, SSRAM_HDR_SIZE); | 264 | tmp_ssram = ioremap(ssram_base, SSRAM_HDR_SIZE); |
| 265 | if (!tmp_ssram) | ||
| 266 | return -ENOMEM; | ||
| 265 | 267 | ||
| 266 | if (pmc_idx != PMC_IDX_MAIN) { | 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 | .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES, | 46 | .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES, |
| 47 | .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, | 47 | .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, |
| 48 | .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, | 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 | .ltr_ignore_max = ICL_NUM_IP_IGN_ALLOWED, | 49 | .ltr_ignore_max = ICL_NUM_IP_IGN_ALLOWED, |
| 52 | .etr3_offset = ETR3_OFFSET, | 50 | .etr3_offset = ETR3_OFFSET, |
| 53 | }; | 51 | }; |
| @@ -462,8 +462,6 @@ const struct pmc_reg_map mtl_socm_reg_map = { · 461 unmodified lines | |||
| 462 | .ppfear_buckets = MTL_SOCM_PPFEAR_NUM_ENTRIES, | 462 | .ppfear_buckets = MTL_SOCM_PPFEAR_NUM_ENTRIES, |
| 463 | .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, | 463 | .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, |
| 464 | .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, | 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 | .lpm_num_maps = ADL_LPM_NUM_MAPS, | 465 | .lpm_num_maps = ADL_LPM_NUM_MAPS, |
| 468 | .ltr_ignore_max = MTL_SOCM_NUM_IP_IGN_ALLOWED, | 466 | .ltr_ignore_max = MTL_SOCM_NUM_IP_IGN_ALLOWED, |
| 469 | .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2, | 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 | .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES, | 197 | .ppfear_buckets = ICL_PPFEAR_NUM_ENTRIES, |
| 198 | .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, | 198 | .pm_cfg_offset = CNP_PMC_PM_CFG_OFFSET, |
| 199 | .pm_read_disable_bit = CNP_PMC_READ_DISABLE_BIT, | 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 | .ltr_ignore_max = TGL_NUM_IP_IGN_ALLOWED, | 200 | .ltr_ignore_max = TGL_NUM_IP_IGN_ALLOWED, |
| 203 | .lpm_num_maps = TGL_LPM_NUM_MAPS, | 201 | .lpm_num_maps = TGL_LPM_NUM_MAPS, |
| 204 | .lpm_res_counter_step_x2 = TGL_PMC_LPM_RES_COUNTER_STEP_X2, | 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 | of_parse_phandle(child_np, "required-opps", 0); | 1052 | of_parse_phandle(child_np, "required-opps", 0); |
| 1053 | 1053 | ||
| 1054 | if (child_req_np == ref_np) { | 1054 | if (child_req_np == ref_np) { |
| 1055 | u64 rate; | 1055 | u64 rate = 0; |
| 1056 | 1056 | ||
| 1057 | of_property_read_u64(child_np, "opp-hz", &rate); | 1057 | of_property_read_u64(child_np, "opp-hz", &rate); |
| 1058 | return (unsigned long) rate; | 1058 | return (unsigned long) rate; |
| @@ -178,7 +178,7 @@ static int __dtpm_devfreq_setup(struct devfreq *devfreq, struct dtpm *parent) · 177 unmodified lines | |||
| 178 | ret = dev_pm_qos_add_request(dev, &dtpm_devfreq->qos_req, | 178 | ret = dev_pm_qos_add_request(dev, &dtpm_devfreq->qos_req, |
| 179 | DEV_PM_QOS_MAX_FREQUENCY, | 179 | DEV_PM_QOS_MAX_FREQUENCY, |
| 180 | PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE); | 180 | PM_QOS_MAX_FREQUENCY_DEFAULT_VALUE); |
| 181 | if (ret) { | 181 | if (ret < 0) { |
| 182 | pr_err("Failed to add QoS request: %d\n", ret); | 182 | pr_err("Failed to add QoS request: %d\n", ret); |
| 183 | goto out_dtpm_unregister; | 183 | goto out_dtpm_unregister; |
| 184 | } | 184 | } |
| @@ -147,6 +147,8 @@ static const struct x86_cpu_id pl4_support_ids[] = { · 146 unmodified lines | |||
| 147 | X86_MATCH_VFM(INTEL_RAPTORLAKE_P, NULL), | 147 | X86_MATCH_VFM(INTEL_RAPTORLAKE_P, NULL), |
| 148 | X86_MATCH_VFM(INTEL_METEORLAKE, NULL), | 148 | X86_MATCH_VFM(INTEL_METEORLAKE, NULL), |
| 149 | X86_MATCH_VFM(INTEL_METEORLAKE_L, NULL), | 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 | #include <linux/module.h> | 15 | #include <linux/module.h> |
| 16 | #include <linux/slab.h> | 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 | /* 1 header + 10 registers + 5 reserved. 8 bytes for each. */ | 21 | /* 1 header + 10 registers + 5 reserved. 8 bytes for each. */ |
| 21 | #define TPMI_RAPL_DOMAIN_SIZE 128 | 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 | tpmi_domain_size = tpmi_domain_header >> 16 & 0xff; | 155 | tpmi_domain_size = tpmi_domain_header >> 16 & 0xff; |
| 155 | tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff; | 156 | tpmi_domain_flags = tpmi_domain_header >> 32 & 0xffff; |
| 156 | 157 | ||
| 157 | if (tpmi_domain_version != TPMI_RAPL_VERSION) { | 158 | if (tpmi_domain_version == TPMI_VERSION_INVALID) { |
| 158 | pr_warn(FW_BUG "Unsupported version:%d\n", tpmi_domain_version); | 159 | pr_warn(FW_BUG "Invalid version\n"); |
| 159 | return -ENODEV; | 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 | /* Domain size: in unit of 128 Bytes */ | 173 | /* Domain size: in unit of 128 Bytes */ |
| 163 | if (tpmi_domain_size != 1) { | 174 | if (tpmi_domain_size != 1) { |
| 164 | pr_warn(FW_BUG "Invalid Domain size %d\n", tpmi_domain_size); | 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 | pr_warn(FW_BUG "System domain must support Domain Info register\n"); | 192 | pr_warn(FW_BUG "System domain must support Domain Info register\n"); |
| 182 | return -ENODEV; | 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 | if (!(tpmi_domain_info & TPMI_RAPL_DOMAIN_ROOT)) | 196 | if (!(tpmi_domain_info & TPMI_RAPL_DOMAIN_ROOT)) |
| 186 | return 0; | 197 | return 0; |
| 187 | domain_type = RAPL_DOMAIN_PLATFORM; | 198 | domain_type = RAPL_DOMAIN_PLATFORM; |
| @@ -405,8 +405,8 @@ static int npcm_rc_probe(struct platform_device *pdev) · 404 unmodified lines | |||
| 405 | if (!of_property_read_u32(pdev->dev.of_node, "nuvoton,sw-reset-number", | 405 | if (!of_property_read_u32(pdev->dev.of_node, "nuvoton,sw-reset-number", |
| 406 | &rc->sw_reset_number)) { | 406 | &rc->sw_reset_number)) { |
| 407 | if (rc->sw_reset_number && rc->sw_reset_number < 5) { | 407 | if (rc->sw_reset_number && rc->sw_reset_number < 5) { |
| 408 | rc->restart_nb.priority = 192, | 408 | rc->restart_nb.priority = 192; |
| 409 | rc->restart_nb.notifier_call = npcm_rc_restart, | 409 | rc->restart_nb.notifier_call = npcm_rc_restart; |
| 410 | ret = register_restart_handler(&rc->restart_nb); | 410 | ret = register_restart_handler(&rc->restart_nb); |
| 411 | if (ret) | 411 | if (ret) |
| 412 | dev_warn(&pdev->dev, "failed to register restart handler\n"); | 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 | void __iomem *reg_status = data->status + offset * sizeof(u32); | 94 | void __iomem *reg_status = data->status + offset * sizeof(u32); |
| 95 | u32 value = readl(reg_status); | 95 | u32 value = readl(reg_status); |
| 96 | 96 | ||
| 97 | if (!data->asserted) | ||
| 98 | return !(value & mask); | ||
| 99 | |||
| 97 | return !((value ^ data->asserted[offset]) & mask); | 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 | static struct notifier_block sclp_reboot_notifier = { | 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 | static ssize_t con_pages_show(struct device_driver *dev, char *buf) | 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 | buffer = (void *) ((addr_t) sccb + sccb->header.length); | 319 | buffer = (void *) ((addr_t) sccb + sccb->header.length); |
| 320 | 320 | ||
| 321 | if (convertlf) { | 321 | if (convertlf) { |
| 322 | /* Perform Linefeed conversion (0x0a -> 0x0a 0x0d)*/ | 322 | /* Perform Linefeed conversion (0x0a -> 0x0d 0x0a)*/ |
| 323 | for (from=0, to=0; | 323 | for (from=0, to=0; |
| 324 | (from < count) && (to < sclp_vt220_space_left(request)); | 324 | (from < count) && (to < sclp_vt220_space_left(request)); |
| 325 | from++) { | 325 | from++) { |
| @@ -328,8 +328,8 @@ sclp_vt220_add_msg(struct sclp_vt220_request *request, · 2 unmodified lines | |||
| 328 | /* Perform conversion */ | 328 | /* Perform conversion */ |
| 329 | if (c == 0x0a) { | 329 | if (c == 0x0a) { |
| 330 | if (to + 1 < sclp_vt220_space_left(request)) { | 330 | if (to + 1 < sclp_vt220_space_left(request)) { |
| 331 | ((unsigned char *) buffer)[to++] = c; | ||
| 332 | ((unsigned char *) buffer)[to++] = 0x0d; | 331 | ((unsigned char *) buffer)[to++] = 0x0d; |
| 332 | ((unsigned char *) buffer)[to++] = c; | ||
| 333 | } else | 333 | } else |
| 334 | break; | 334 | break; |
| 335 | 335 | ||
| @@ -1864,13 +1864,12 @@ static inline void ap_scan_domains(struct ap_card *ac) · 1863 unmodified lines | |||
| 1864 | } | 1864 | } |
| 1865 | /* if no queue device exists, create a new one */ | 1865 | /* if no queue device exists, create a new one */ |
| 1866 | if (!aq) { | 1866 | if (!aq) { |
| 1867 | aq = ap_queue_create(qid, ac->ap_dev.device_type); | 1867 | aq = ap_queue_create(qid, ac); |
| 1868 | if (!aq) { | 1868 | if (!aq) { |
| 1869 | AP_DBF_WARN("%s(%d,%d) ap_queue_create() failed\n", | 1869 | AP_DBF_WARN("%s(%d,%d) ap_queue_create() failed\n", |
| 1870 | __func__, ac->id, dom); | 1870 | __func__, ac->id, dom); |
| 1871 | continue; | 1871 | continue; |
| 1872 | } | 1872 | } |
| 1873 | aq->card = ac; | ||
| 1874 | aq->config = !decfg; | 1873 | aq->config = !decfg; |
| 1875 | aq->chkstop = chkstop; | 1874 | aq->chkstop = chkstop; |
| 1876 | aq->se_bstate = hwinfo.bs; | 1875 | aq->se_bstate = hwinfo.bs; |
| @@ -272,7 +272,7 @@ int ap_test_config_usage_domain(unsigned int domain); · 271 unmodified lines | |||
| 272 | int ap_test_config_ctrl_domain(unsigned int domain); | 272 | int ap_test_config_ctrl_domain(unsigned int domain); |
| 273 | 273 | ||
| 274 | void ap_queue_init_reply(struct ap_queue *aq, struct ap_message *ap_msg); | 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 | void ap_queue_prepare_remove(struct ap_queue *aq); | 276 | void ap_queue_prepare_remove(struct ap_queue *aq); |
| 277 | void ap_queue_remove(struct ap_queue *aq); | 277 | void ap_queue_remove(struct ap_queue *aq); |
| 278 | void ap_queue_init_state(struct ap_queue *aq); | 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 | * some AP queue helper functions | 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 | static inline bool ap_q_supports_bind(struct ap_queue *aq) | 30 | static inline bool ap_q_supports_bind(struct ap_queue *aq) |
| 26 | { | 31 | { |
| 27 | return aq->card->hwinfo.ep11 || aq->card->hwinfo.accel; | 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 | kfree(aq); | 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 | struct ap_queue *aq; | 1114 | struct ap_queue *aq; |
| 1110 | 1115 | ||
| 1111 | aq = kzalloc(sizeof(*aq), GFP_KERNEL); | 1116 | aq = kzalloc(sizeof(*aq), GFP_KERNEL); |
| 1112 | if (!aq) | 1117 | if (!aq) |
| 1113 | return NULL; | 1118 | return NULL; |
| 1119 | aq->card = ac; | ||
| 1114 | aq->ap_dev.device.release = ap_queue_device_release; | 1120 | aq->ap_dev.device.release = ap_queue_device_release; |
| 1115 | aq->ap_dev.device.type = &ap_queue_type; | 1121 | aq->ap_dev.device.type = &ap_queue_type; |
| 1116 | aq->ap_dev.device_type = device_type; | 1122 | aq->ap_dev.device_type = ac->ap_dev.device_type; |
| 1117 | // add optional SE secure binding attributes group | 1123 | /* in SE environment add bind/associate attributes group */ |
| 1118 | if (ap_sb_available() && is_prot_virt_guest()) | 1124 | if (ap_is_se_guest() && ap_q_supported_in_se(aq)) |
| 1119 | aq->ap_dev.device.groups = ap_queue_dev_sb_attr_groups; | 1125 | aq->ap_dev.device.groups = ap_queue_dev_sb_attr_groups; |
| 1120 | aq->qid = qid; | 1126 | aq->qid = qid; |
| 1121 | spin_lock_init(&aq->lock); | 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 | /* SE guest's queues additionally need to be bound */ | 1204 | /* SE guest's queues additionally need to be bound */ |
| 1199 | if (ap_q_needs_bind(aq) && | 1205 | if (ap_is_se_guest()) { |
| 1200 | !(aq->se_bstate == AP_BS_Q_USABLE || | 1206 | if (!ap_q_supported_in_se(aq)) { |
| 1201 | aq->se_bstate == AP_BS_Q_USABLE_NO_SECURE_KEY)) | 1207 | rc = false; |
| 1202 | 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 | unlock_and_out: | 1216 | unlock_and_out: |
| 1205 | spin_unlock_bh(&aq->lock); | 1217 | spin_unlock_bh(&aq->lock); |
| @@ -324,6 +324,7 @@ static int pckmo_key2protkey(const u8 *key, u32 keylen, · 323 unmodified lines | |||
| 324 | memcpy(protkey, t->protkey, t->len); | 324 | memcpy(protkey, t->protkey, t->len); |
| 325 | *protkeylen = t->len; | 325 | *protkeylen = t->len; |
| 326 | *protkeytype = t->keytype; | 326 | *protkeytype = t->keytype; |
| 327 | rc = 0; | ||
| 327 | break; | 328 | break; |
| 328 | } | 329 | } |
| 329 | case TOKVER_CLEAR_KEY: { | 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 | spin_lock_init(&fnic->vlans_lock); | 830 | spin_lock_init(&fnic->vlans_lock); |
| 831 | INIT_WORK(&fnic->fip_frame_work, fnic_handle_fip_frame); | 831 | INIT_WORK(&fnic->fip_frame_work, fnic_handle_fip_frame); |
| 832 | INIT_WORK(&fnic->event_work, fnic_handle_event); | 832 | INIT_WORK(&fnic->event_work, fnic_handle_event); |
| 833 | INIT_WORK(&fnic->flush_work, fnic_flush_tx); | ||
| 834 | skb_queue_head_init(&fnic->fip_frame_queue); | 833 | skb_queue_head_init(&fnic->fip_frame_queue); |
| 835 | INIT_LIST_HEAD(&fnic->evlist); | 834 | INIT_LIST_HEAD(&fnic->evlist); |
| 836 | INIT_LIST_HEAD(&fnic->vlans); | 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 | INIT_WORK(&fnic->link_work, fnic_handle_link); | 948 | INIT_WORK(&fnic->link_work, fnic_handle_link); |
| 950 | INIT_WORK(&fnic->frame_work, fnic_handle_frame); | 949 | INIT_WORK(&fnic->frame_work, fnic_handle_frame); |
| 950 | INIT_WORK(&fnic->flush_work, fnic_flush_tx); | ||
| 951 | skb_queue_head_init(&fnic->frame_queue); | 951 | skb_queue_head_init(&fnic->frame_queue); |
| 952 | skb_queue_head_init(&fnic->tx_queue); | 952 | skb_queue_head_init(&fnic->tx_queue); |
| 953 | 953 | ||
| @@ -542,8 +542,8 @@ struct mpi3mr_hba_port { · 541 unmodified lines | |||
| 542 | * @port_list: List of ports belonging to a SAS node | 542 | * @port_list: List of ports belonging to a SAS node |
| 543 | * @num_phys: Number of phys associated with port | 543 | * @num_phys: Number of phys associated with port |
| 544 | * @marked_responding: used while refresing the sas ports | 544 | * @marked_responding: used while refresing the sas ports |
| 545 | * @lowest_phy: lowest phy ID 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 | 546 | * @phy_mask: phy_mask of current sas port, valid for controller port |
| 547 | * @hba_port: HBA port entry | 547 | * @hba_port: HBA port entry |
| 548 | * @remote_identify: Attached device identification | 548 | * @remote_identify: Attached device identification |
| 549 | * @rphy: SAS transport layer rphy object | 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 | * @mrioc: Adapter instance reference | 590 | * @mrioc: Adapter instance reference |
| 591 | * @mr_sas_port: Internal Port object | 591 | * @mr_sas_port: Internal Port object |
| 592 | * @mr_sas_phy: Internal Phy object | 592 | * @mr_sas_phy: Internal Phy object |
| 593 | * @host_node: Flag to indicate this is a host_node | ||
| 593 | * | 594 | * |
| 594 | * Return: None. | 595 | * Return: None. |
| 595 | */ | 596 | */ |
| 596 | static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc, | 597 | static void mpi3mr_delete_sas_phy(struct mpi3mr_ioc *mrioc, |
| 597 | struct mpi3mr_sas_port *mr_sas_port, | 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 | u64 sas_address = mr_sas_port->remote_identify.sas_address; | 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 | list_del(&mr_sas_phy->port_siblings); | 607 | list_del(&mr_sas_phy->port_siblings); |
| 607 | mr_sas_port->num_phys--; | 608 | mr_sas_port->num_phys--; |
| 608 | mr_sas_port->phy_mask &= ~(1 << mr_sas_phy->phy_id); | 609 | |
| 609 | if (mr_sas_port->lowest_phy == mr_sas_phy->phy_id) | 610 | if (host_node) { |
| 610 | mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | 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 | sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy); | 616 | sas_port_delete_phy(mr_sas_port->port, mr_sas_phy->phy); |
| 612 | mr_sas_phy->phy_belongs_to_port = 0; | 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 | * @mrioc: Adapter instance reference | 622 | * @mrioc: Adapter instance reference |
| 618 | * @mr_sas_port: Internal Port object | 623 | * @mr_sas_port: Internal Port object |
| 619 | * @mr_sas_phy: Internal Phy object | 624 | * @mr_sas_phy: Internal Phy object |
| 625 | * @host_node: Flag to indicate this is a host_node | ||
| 620 | * | 626 | * |
| 621 | * Return: None. | 627 | * Return: None. |
| 622 | */ | 628 | */ |
| 623 | static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc, | 629 | static void mpi3mr_add_sas_phy(struct mpi3mr_ioc *mrioc, |
| 624 | struct mpi3mr_sas_port *mr_sas_port, | 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 | u64 sas_address = mr_sas_port->remote_identify.sas_address; | 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 | list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list); | 639 | list_add_tail(&mr_sas_phy->port_siblings, &mr_sas_port->phy_list); |
| 634 | mr_sas_port->num_phys++; | 640 | mr_sas_port->num_phys++; |
| 635 | mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id); | 641 | if (host_node) { |
| 636 | if (mr_sas_phy->phy_id < mr_sas_port->lowest_phy) | 642 | mr_sas_port->phy_mask |= (1 << mr_sas_phy->phy_id); |
| 637 | mr_sas_port->lowest_phy = ffs(mr_sas_port->phy_mask) - 1; | 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 | sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy); | 647 | sas_port_add_phy(mr_sas_port->port, mr_sas_phy->phy); |
| 639 | mr_sas_phy->phy_belongs_to_port = 1; | 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 | if (srch_phy == mr_sas_phy) | 684 | if (srch_phy == mr_sas_phy) |
| 676 | return; | 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 | return; | 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 | mpi3mr_delete_sas_port(mrioc, mr_sas_port); | 745 | mpi3mr_delete_sas_port(mrioc, mr_sas_port); |
| 737 | else | 746 | else |
| 738 | mpi3mr_delete_sas_phy(mrioc, mr_sas_port, | 747 | mpi3mr_delete_sas_phy(mrioc, mr_sas_port, |
| 739 | mr_sas_phy); | 748 | mr_sas_phy, mr_sas_node->host_node); |
| 740 | return; | 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 | * mpi3mr_get_hba_port_by_id - find hba port by id | 1038 | * mpi3mr_get_hba_port_by_id - find hba port by id |
| 1030 | * @mrioc: Adapter instance reference | 1039 | * @mrioc: Adapter instance reference |
| 1031 | * @port_id - Port ID to search | 1040 | * @port_id: Port ID to search |
| 1032 | * | 1041 | * |
| 1033 | * Return: mpi3mr_hba_port reference for the matched port | 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 | mpi3mr_sas_port_sanity_check(mrioc, mr_sas_node, | 1376 | mpi3mr_sas_port_sanity_check(mrioc, mr_sas_node, |
| 1368 | mr_sas_port->remote_identify.sas_address, hba_port); | 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 | ioc_info(mrioc, "max port count %u could be too high\n", | 1381 | ioc_info(mrioc, "max port count %u could be too high\n", |
| 1372 | mr_sas_node->num_phys); | 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 | (mr_sas_node->phy[i].hba_port != hba_port)) | 1387 | (mr_sas_node->phy[i].hba_port != hba_port)) |
| 1378 | continue; | 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 | ioc_warn(mrioc, "skipping port %u, max allowed value is %zu\n", | 1391 | ioc_warn(mrioc, "skipping port %u, max allowed value is %zu\n", |
| 1382 | i, sizeof(mr_sas_port->phy_mask) * 8); | 1392 | i, sizeof(mr_sas_port->phy_mask) * 8); |
| 1383 | goto out_fail; | 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 | list_add_tail(&mr_sas_node->phy[i].port_siblings, | 1395 | list_add_tail(&mr_sas_node->phy[i].port_siblings, |
| 1386 | &mr_sas_port->phy_list); | 1396 | &mr_sas_port->phy_list); |
| 1387 | mr_sas_port->num_phys++; | 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 | if (!mr_sas_port->num_phys) { | 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 | goto out_fail; | 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 | if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { | 1411 | if (mr_sas_port->remote_identify.device_type == SAS_END_DEVICE) { |
| 1400 | tgtdev = mpi3mr_get_tgtdev_by_addr(mrioc, | 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 | enum dma_data_direction dir; | 3651 | enum dma_data_direction dir; |
| 3652 | struct scsi_data_buffer *sdb = &scp->sdb; | 3652 | struct scsi_data_buffer *sdb = &scp->sdb; |
| 3653 | u8 *fsp; | 3653 | u8 *fsp; |
| 3654 | int i; | 3654 | int i, total = 0; |
| 3655 | 3655 | ||
| 3656 | /* | 3656 | /* |
| 3657 | * Even though reads are inherently atomic (in this driver), we expect | 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 | fsp + (block * sdebug_sector_size), | 3688 | fsp + (block * sdebug_sector_size), |
| 3689 | sdebug_sector_size, sg_skip, do_write); | 3689 | sdebug_sector_size, sg_skip, do_write); |
| 3690 | sdeb_data_sector_unlock(sip, do_write); | 3690 | sdeb_data_sector_unlock(sip, do_write); |
| 3691 | if (ret != sdebug_sector_size) { | 3691 | total += ret; |
| 3692 | ret += (i * sdebug_sector_size); | 3692 | if (ret != sdebug_sector_size) |
| 3693 | break; | 3693 | break; |
| 3694 | } | ||
| 3695 | sg_skip += sdebug_sector_size; | 3694 | sg_skip += sdebug_sector_size; |
| 3696 | if (++block >= sdebug_store_sectors) | 3695 | if (++block >= sdebug_store_sectors) |
| 3697 | block = 0; | 3696 | block = 0; |
| 3698 | } | 3697 | } |
| 3699 | ret = num * sdebug_sector_size; | ||
| 3700 | sdeb_data_unlock(sip, atomic); | 3698 | sdeb_data_unlock(sip, atomic); |
| 3701 | 3699 | ||
| 3702 | return ret; | 3700 | return total; |
| 3703 | } | 3701 | } |
| 3704 | 3702 | ||
| 3705 | /* Returns number of bytes copied or -1 if error. */ | 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 | if (rport->port_state == FC_PORTSTATE_ONLINE) | 1251 | if (rport->port_state == FC_PORTSTATE_ONLINE) |
| 1252 | rport->port_state = port_state; | 1252 | rport->port_state = port_state; |
| 1253 | else | 1253 | else if (port_state != rport->port_state) |
| 1254 | return -EINVAL; | 1254 | return -EINVAL; |
| 1255 | } else if (port_state == FC_PORTSTATE_ONLINE) { | 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 | if (rport->port_state == FC_PORTSTATE_MARGINAL) | 1261 | if (rport->port_state == FC_PORTSTATE_MARGINAL) |
| 1262 | rport->port_state = port_state; | 1262 | rport->port_state = port_state; |
| 1263 | else | 1263 | else if (port_state != rport->port_state) |
| 1264 | return -EINVAL; | 1264 | return -EINVAL; |
| 1265 | } else | 1265 | } else |
| 1266 | return -EINVAL; | 1266 | return -EINVAL; |
| @@ -831,7 +831,7 @@ wd33c93_intr(struct Scsi_Host *instance) · 830 unmodified lines | |||
| 831 | /* construct an IDENTIFY message with correct disconnect bit */ | 831 | /* construct an IDENTIFY message with correct disconnect bit */ |
| 832 | 832 | ||
| 833 | hostdata->outgoing_msg[0] = IDENTIFY(0, cmd->device->lun); | 833 | hostdata->outgoing_msg[0] = IDENTIFY(0, cmd->device->lun); |
| 834 | if (scsi_pointer->phase) | 834 | if (WD33C93_scsi_pointer(cmd)->phase) |
| 835 | hostdata->outgoing_msg[0] |= 0x40; | 835 | hostdata->outgoing_msg[0] |= 0x40; |
| 836 | 836 | ||
| 837 | if (hostdata->sync_stat[cmd->device->id] == SS_FIRST) { | 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 | info = devm_qe_muram_alloc(qmc->dev, UCC_SLOW_PRAM_SIZE + 2 * 64, | 1762 | info = devm_qe_muram_alloc(qmc->dev, UCC_SLOW_PRAM_SIZE + 2 * 64, |
| 1763 | ALIGNMENT_OF_UCC_SLOW_PRAM); | 1763 | ALIGNMENT_OF_UCC_SLOW_PRAM); |
| 1764 | if (IS_ERR_VALUE(info)) { | 1764 | if (info < 0) |
| 1765 | dev_err(qmc->dev, "cannot allocate MURAM for PRAM"); | 1765 | return info; |
| 1766 | return -ENOMEM; | 1766 | |
| 1767 | } | ||
| 1768 | if (!qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, qmc->qe_subblock, | 1767 | if (!qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, qmc->qe_subblock, |
| 1769 | QE_CR_PROTOCOL_UNSPECIFIED, info)) { | 1768 | QE_CR_PROTOCOL_UNSPECIFIED, info)) { |
| 1770 | dev_err(qmc->dev, "QE_ASSIGN_PAGE_TO_DEVICE cmd failed"); | 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 | qmc_exit_xcc(qmc); | 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 | .version = QMC_CPM1, | 2059 | .version = QMC_CPM1, |
| 2061 | .tstate = 0x30000000, | 2060 | .tstate = 0x30000000, |
| 2062 | .rstate = 0x31000000, | 2061 | .rstate = 0x31000000, |
| @@ -2066,7 +2065,7 @@ static const struct qmc_data qmc_data_cpm1 = { · 3 unmodified lines | |||
| 2066 | .rpack = 0x00000000, | 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 | .version = QMC_QE, | 2069 | .version = QMC_QE, |
| 2071 | .tstate = 0x30000000, | 2070 | .tstate = 0x30000000, |
| 2072 | .rstate = 0x30000000, | 2071 | .rstate = 0x30000000, |
| @@ -376,11 +376,12 @@ static int intel_hw_params(struct snd_pcm_substream *substream, · 375 unmodified lines | |||
| 376 | static int intel_prepare(struct snd_pcm_substream *substream, | 376 | static int intel_prepare(struct snd_pcm_substream *substream, |
| 377 | struct snd_soc_dai *dai) | 377 | struct snd_soc_dai *dai) |
| 378 | { | 378 | { |
| 379 | struct snd_soc_pcm_runtime *rtd = snd_soc_substream_to_rtd(substream); | ||
| 379 | struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); | 380 | struct sdw_cdns *cdns = snd_soc_dai_get_drvdata(dai); |
| 380 | struct sdw_intel *sdw = cdns_to_intel(cdns); | 381 | struct sdw_intel *sdw = cdns_to_intel(cdns); |
| 381 | struct sdw_cdns_dai_runtime *dai_runtime; | 382 | struct sdw_cdns_dai_runtime *dai_runtime; |
| 383 | struct snd_pcm_hw_params *hw_params; | ||
| 382 | int ch, dir; | 384 | int ch, dir; |
| 383 | int ret = 0; | ||
| 384 | 385 | ||
| 385 | dai_runtime = cdns->dai_runtime_array[dai->id]; | 386 | dai_runtime = cdns->dai_runtime_array[dai->id]; |
| 386 | if (!dai_runtime) { | 387 | if (!dai_runtime) { |
| @@ -389,12 +390,8 @@ static int intel_prepare(struct snd_pcm_substream *substream, · 2 unmodified lines | |||
| 389 | return -EIO; | 390 | return -EIO; |
| 390 | } | 391 | } |
| 391 | 392 | ||
| 393 | hw_params = &rtd->dpcm[substream->stream].hw_params; | ||
| 392 | if (dai_runtime->suspended) { | 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 | dai_runtime->suspended = false; | 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 | /* the SHIM will be configured in the callback functions */ | 412 | /* the SHIM will be configured in the callback functions */ |
| 416 | 413 | ||
| 417 | sdw_cdns_config_stream(cdns, ch, dir, dai_runtime->pdi); | 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 | static int | 422 | static int |
| @@ -1003,6 +1003,7 @@ static int dspi_setup(struct spi_device *spi) · 1002 unmodified lines | |||
| 1003 | u32 cs_sck_delay = 0, sck_cs_delay = 0; | 1003 | u32 cs_sck_delay = 0, sck_cs_delay = 0; |
| 1004 | struct fsl_dspi_platform_data *pdata; | 1004 | struct fsl_dspi_platform_data *pdata; |
| 1005 | unsigned char pasc = 0, asc = 0; | 1005 | unsigned char pasc = 0, asc = 0; |
| 1006 | struct gpio_desc *gpio_cs; | ||
| 1006 | struct chip_data *chip; | 1007 | struct chip_data *chip; |
| 1007 | unsigned long clkrate; | 1008 | unsigned long clkrate; |
| 1008 | bool cs = true; | 1009 | bool cs = true; |
| @@ -1077,7 +1078,10 @@ static int dspi_setup(struct spi_device *spi) · 68 unmodified lines | |||
| 1077 | chip->ctar_val |= SPI_CTAR_LSBFE; | 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 | dspi_deassert_cs(spi, &cs); | 1085 | dspi_deassert_cs(spi, &cs); |
| 1082 | 1086 | ||
| 1083 | spi_set_ctldata(spi, chip); | 1087 | spi_set_ctldata(spi, chip); |
| @@ -1116,6 +1116,11 @@ static int spi_geni_probe(struct platform_device *pdev) · 1115 unmodified lines | |||
| 1116 | init_completion(&mas->tx_reset_done); | 1116 | init_completion(&mas->tx_reset_done); |
| 1117 | init_completion(&mas->rx_reset_done); | 1117 | init_completion(&mas->rx_reset_done); |
| 1118 | spin_lock_init(&mas->lock); | 1118 | spin_lock_init(&mas->lock); |
| 1119 | |||
| 1120 | ret = geni_icc_get(&mas->se, NULL); | ||
| 1121 | if (ret) | ||
| 1122 | return ret; | ||
| 1123 | |||
| 1119 | pm_runtime_use_autosuspend(&pdev->dev); | 1124 | pm_runtime_use_autosuspend(&pdev->dev); |
| 1120 | pm_runtime_set_autosuspend_delay(&pdev->dev, 250); | 1125 | pm_runtime_set_autosuspend_delay(&pdev->dev, 250); |
| 1121 | ret = devm_pm_runtime_enable(dev); | 1126 | ret = devm_pm_runtime_enable(dev); |
| @@ -1125,9 +1130,6 @@ static int spi_geni_probe(struct platform_device *pdev) · 3 unmodified lines | |||
| 1125 | if (device_property_read_bool(&pdev->dev, "spi-slave")) | 1130 | if (device_property_read_bool(&pdev->dev, "spi-slave")) |
| 1126 | spi->target = true; | 1131 | spi->target = true; |
| 1127 | 1132 | ||
| 1128 | ret = geni_icc_get(&mas->se, NULL); | ||
| 1129 | if (ret) | ||
| 1130 | return ret; | ||
| 1131 | /* Set the bus quota to a reasonable value for register access */ | 1133 | /* Set the bus quota to a reasonable value for register access */ |
| 1132 | mas->se.icc_paths[GENI_TO_CORE].avg_bw = Bps_to_icc(CORE_2X_50_MHZ); | 1134 | mas->se.icc_paths[GENI_TO_CORE].avg_bw = Bps_to_icc(CORE_2X_50_MHZ); |
| 1133 | mas->se.icc_paths[CPU_TO_GENI].avg_bw = GENI_DEFAULT_BW; | 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 | * mtk_snand_is_page_ops() - check if the op is a controller supported page op. | 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 | * Check whether op can be executed with read_from_cache or program_load | 1192 | * Check whether op can be executed with read_from_cache or program_load |
| 1193 | * mode in the controller. | 1193 | * mode in the controller. |
| @@ -2044,6 +2044,7 @@ static const struct stm32_spi_cfg stm32mp25_spi_cfg = { · 2043 unmodified lines | |||
| 2044 | .baud_rate_div_max = STM32H7_SPI_MBR_DIV_MAX, | 2044 | .baud_rate_div_max = STM32H7_SPI_MBR_DIV_MAX, |
| 2045 | .has_fifo = true, | 2045 | .has_fifo = true, |
| 2046 | .prevent_dma_burst = true, | 2046 | .prevent_dma_burst = true, |
| 2047 | .has_device_mode = true, | ||
| 2047 | }; | 2048 | }; |
| 2048 | 2049 | ||
| 2049 | static const struct of_device_id stm32_spi_of_match[] = { | 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 | static int ad9832_write_frequency(struct ad9832_state *st, | 129 | static int ad9832_write_frequency(struct ad9832_state *st, |
| 130 | unsigned int addr, unsigned long fout) | 130 | unsigned int addr, unsigned long fout) |
| 131 | { | 131 | { |
| 132 | unsigned long clk_freq; | ||
| 132 | unsigned long regval; | 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 | return -EINVAL; | 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 | st->freq_data[0] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | | 142 | st->freq_data[0] = cpu_to_be16((AD9832_CMD_FRE8BITSW << CMD_SHIFT) | |
| 140 | (addr << ADD_SHIFT) | | 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 | dev->queues = kcalloc(nr_cpu_ids, sizeof(*dev->queues), GFP_KERNEL); | 692 | dev->queues = kcalloc(nr_cpu_ids, sizeof(*dev->queues), GFP_KERNEL); |
| 693 | if (!dev->queues) { | 693 | if (!dev->queues) { |
| 694 | dev->transport->free_device(dev); | 694 | hba->backend->ops->free_device(dev); |
| 695 | return NULL; | 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 | ret = genlmsg_multicast_allns(&tcmu_genl_family, skb, 0, | 2132 | ret = genlmsg_multicast_allns(&tcmu_genl_family, skb, 0, |
| 2133 | TCMU_MCGRP_CONFIG, GFP_KERNEL); | 2133 | TCMU_MCGRP_CONFIG); |
| 2134 | 2134 | ||
| 2135 | /* Wait during an add as the listener may not be up yet */ | 2135 | /* Wait during an add as the listener may not be up yet */ |
| 2136 | if (ret == 0 || | 2136 | if (ret == 0 || |
| @@ -416,7 +416,6 @@ err_del_legacy: · 415 unmodified lines | |||
| 416 | if (!pci_info->no_legacy) | 416 | if (!pci_info->no_legacy) |
| 417 | proc_thermal_remove(proc_priv); | 417 | proc_thermal_remove(proc_priv); |
| 418 | proc_thermal_mmio_remove(pdev, proc_priv); | 418 | proc_thermal_mmio_remove(pdev, proc_priv); |
| 419 | pci_disable_device(pdev); | ||
| 420 | 419 | ||
| 421 | return ret; | 420 | return ret; |
| 422 | } | 421 | } |
| @@ -438,7 +437,6 @@ static void proc_thermal_pci_remove(struct pci_dev *pdev) · 15 unmodified lines | |||
| 438 | proc_thermal_mmio_remove(pdev, pci_info->proc_priv); | 437 | proc_thermal_mmio_remove(pdev, pci_info->proc_priv); |
| 439 | if (!pci_info->no_legacy) | 438 | if (!pci_info->no_legacy) |
| 440 | proc_thermal_remove(proc_priv); | 439 | proc_thermal_remove(proc_priv); |
| 441 | pci_disable_device(pdev); | ||
| 442 | } | 440 | } |
| 443 | 441 | ||
| 444 | #ifdef CONFIG_PM_SLEEP | 442 | #ifdef CONFIG_PM_SLEEP |
| @@ -13,48 +13,12 @@ static struct rapl_if_priv rapl_mmio_priv; · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | static const struct rapl_mmio_regs rapl_mmio_default = { | 14 | static const struct rapl_mmio_regs rapl_mmio_default = { |
| 15 | .reg_unit = 0x5938, | 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 | .regs[RAPL_DOMAIN_DRAM] = { 0x58e0, 0x58e8, 0x58ec, 0, 0}, | 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 | .limits[RAPL_DOMAIN_DRAM] = BIT(POWER_LIMIT2), | 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 | static int rapl_mmio_read_raw(int cpu, struct reg_action *ra) | 22 | static int rapl_mmio_read_raw(int cpu, struct reg_action *ra) |
| 59 | { | 23 | { |
| 60 | if (!ra->reg.mmio) | 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 | int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv) | 46 | int proc_thermal_rapl_add(struct pci_dev *pdev, struct proc_thermal_device *proc_priv) |
| 83 | { | 47 | { |
| 84 | const struct rapl_mmio_regs *rapl_regs = &rapl_mmio_default; | 48 | const struct rapl_mmio_regs *rapl_regs = &rapl_mmio_default; |
| 49 | struct rapl_package *rp; | ||
| 85 | enum rapl_domain_reg_id reg; | 50 | enum rapl_domain_reg_id reg; |
| 86 | enum rapl_domain_type domain; | 51 | enum rapl_domain_type domain; |
| 87 | int ret; | 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 | return PTR_ERR(rapl_mmio_priv.control_type); | 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", | 77 | /* Register a RAPL package device for package 0 which is always online */ |
| 113 | rapl_mmio_cpu_online, rapl_mmio_cpu_down_prep); | 78 | rp = rapl_find_package_domain(0, &rapl_mmio_priv, false); |
| 114 | if (ret < 0) { | 79 | if (rp) { |
| 115 | powercap_unregister_control_type(rapl_mmio_priv.control_type); | 80 | ret = -EEXIST; |
| 116 | rapl_mmio_priv.control_type = NULL; | 81 | goto err; |
| 117 | return ret; | 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 | return 0; | 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 | EXPORT_SYMBOL_GPL(proc_thermal_rapl_add); | 97 | EXPORT_SYMBOL_GPL(proc_thermal_rapl_add); |
| 124 | 98 | ||
| 125 | void proc_thermal_rapl_remove(void) | 99 | void proc_thermal_rapl_remove(void) |
| 126 | { | 100 | { |
| 101 | struct rapl_package *rp; | ||
| 102 | |||
| 127 | if (IS_ERR_OR_NULL(rapl_mmio_priv.control_type)) | 103 | if (IS_ERR_OR_NULL(rapl_mmio_priv.control_type)) |
| 128 | return; | 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 | powercap_unregister_control_type(rapl_mmio_priv.control_type); | 109 | powercap_unregister_control_type(rapl_mmio_priv.control_type); |
| 132 | } | 110 | } |
| 133 | EXPORT_SYMBOL_GPL(proc_thermal_rapl_remove); | 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 | mutex_lock(&thermal_list_lock); | 728 | mutex_lock(&thermal_list_lock); |
| 729 | list_for_each_entry(tz, &thermal_tz_list, node) { | 729 | list_for_each_entry(tz, &thermal_tz_list, node) { |
| 730 | if (tz->id == id) { | 730 | if (tz->id == id) { |
| 731 | get_device(&tz->device); | ||
| 731 | match = tz; | 732 | match = tz; |
| 732 | break; | 733 | break; |
| 733 | } | 734 | } |
| @@ -1605,14 +1606,12 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz) · 871 unmodified lines | |||
| 1605 | ida_destroy(&tz->ida); | 1606 | ida_destroy(&tz->ida); |
| 1606 | 1607 | ||
| 1607 | device_del(&tz->device); | 1608 | device_del(&tz->device); |
| 1608 | |||
| 1609 | kfree(tz->tzp); | ||
| 1610 | |||
| 1611 | put_device(&tz->device); | 1609 | put_device(&tz->device); |
| 1612 | 1610 | ||
| 1613 | thermal_notify_tz_delete(tz); | 1611 | thermal_notify_tz_delete(tz); |
| 1614 | 1612 | ||
| 1615 | wait_for_completion(&tz->removal); | 1613 | wait_for_completion(&tz->removal); |
| 1614 | kfree(tz->tzp); | ||
| 1616 | kfree(tz); | 1615 | kfree(tz); |
| 1617 | } | 1616 | } |
| 1618 | EXPORT_SYMBOL_GPL(thermal_zone_device_unregister); | 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 | struct thermal_zone_device *thermal_zone_get_by_id(int id); | 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 | static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) | 200 | static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) |
| 198 | { | 201 | { |
| 199 | return cdev->ops->get_requested_power && cdev->ops->state2power && | 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 | struct sk_buff *msg = p->msg; | 444 | struct sk_buff *msg = p->msg; |
| 445 | const struct thermal_trip_desc *td; | 445 | const struct thermal_trip_desc *td; |
| 446 | struct thermal_zone_device *tz; | ||
| 447 | struct nlattr *start_trip; | 446 | struct nlattr *start_trip; |
| 448 | int id; | 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 | id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]); | 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 | if (!tz) | 455 | if (!tz) |
| 457 | return -EINVAL; | 456 | return -EINVAL; |
| 458 | 457 | ||
| @@ -488,7 +487,6 @@ out_cancel_nest: · 29 unmodified lines | |||
| 488 | static int thermal_genl_cmd_tz_get_temp(struct param *p) | 487 | static int thermal_genl_cmd_tz_get_temp(struct param *p) |
| 489 | { | 488 | { |
| 490 | struct sk_buff *msg = p->msg; | 489 | struct sk_buff *msg = p->msg; |
| 491 | struct thermal_zone_device *tz; | ||
| 492 | int temp, ret, id; | 490 | int temp, ret, id; |
| 493 | 491 | ||
| 494 | if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID]) | 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 | id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]); | 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 | if (!tz) | 498 | if (!tz) |
| 501 | return -EINVAL; | 499 | return -EINVAL; |
| 502 | 500 | ||
| @@ -514,7 +512,6 @@ static int thermal_genl_cmd_tz_get_temp(struct param *p) · 11 unmodified lines | |||
| 514 | static int thermal_genl_cmd_tz_get_gov(struct param *p) | 512 | static int thermal_genl_cmd_tz_get_gov(struct param *p) |
| 515 | { | 513 | { |
| 516 | struct sk_buff *msg = p->msg; | 514 | struct sk_buff *msg = p->msg; |
| 517 | struct thermal_zone_device *tz; | ||
| 518 | int id, ret = 0; | 515 | int id, ret = 0; |
| 519 | 516 | ||
| 520 | if (!p->attrs[THERMAL_GENL_ATTR_TZ_ID]) | 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 | id = nla_get_u32(p->attrs[THERMAL_GENL_ATTR_TZ_ID]); | 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 | if (!tz) | 523 | if (!tz) |
| 527 | return -EINVAL; | 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 | tb_retimer_set_inbound_sbtx(port); | 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 | * Last retimer is true only for the last on-board | 521 | * Last retimer is true only for the last on-board |
| 522 | * retimer (the one connected directly to the Type-C | 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 | last_idx = i; | 527 | last_idx = i; |
| 528 | else if (ret < 0) | 528 | else if (ret < 0) |
| 529 | break; | 529 | break; |
| 530 | |||
| 531 | max = i; | ||
| 530 | } | 532 | } |
| 531 | 533 | ||
| 532 | max = i; | ||
| 533 | ret = 0; | 534 | ret = 0; |
| 534 | 535 | ||
| 535 | /* Add retimers if they do not exist already */ | 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 | device_for_each_child(&sw->dev, NULL, tb_increase_switch_tmu_accuracy); | 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 | static int tb_enable_tmu(struct tb_switch *sw) | 309 | static int tb_enable_tmu(struct tb_switch *sw) |
| 292 | { | 310 | { |
| 293 | int ret; | 311 | int ret; |
| @@ -302,12 +320,30 @@ static int tb_enable_tmu(struct tb_switch *sw) · 8 unmodified lines | |||
| 302 | ret = tb_switch_tmu_configure(sw, | 320 | ret = tb_switch_tmu_configure(sw, |
| 303 | TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI); | 321 | TB_SWITCH_TMU_MODE_MEDRES_ENHANCED_UNI); |
| 304 | if (ret == -EOPNOTSUPP) { | 322 | if (ret == -EOPNOTSUPP) { |
| 305 | if (tb_switch_clx_is_enabled(sw, TB_CL1)) | 323 | if (tb_switch_clx_is_enabled(sw, TB_CL1)) { |
| 306 | ret = tb_switch_tmu_configure(sw, | 324 | /* |
| 307 | TB_SWITCH_TMU_MODE_LOWRES); | 325 | * Figure out uni-directional HiFi TMU requirements |
| 308 | else | 326 | * currently in the domain. If there are no |
| 309 | ret = tb_switch_tmu_configure(sw, | 327 | * uni-directional HiFi requirements we can put the TMU |
| 310 | TB_SWITCH_TMU_MODE_HIFI_BI); | 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 | if (ret) | 348 | if (ret) |
| 313 | return ret; | 349 | return ret; |
| @@ -3157,6 +3157,8 @@ static void gsm_cleanup_mux(struct gsm_mux *gsm, bool disc) · 3156 unmodified lines | |||
| 3157 | mutex_unlock(&gsm->mutex); | 3157 | mutex_unlock(&gsm->mutex); |
| 3158 | /* Now wipe the queues */ | 3158 | /* Now wipe the queues */ |
| 3159 | tty_ldisc_flush(gsm->tty); | 3159 | tty_ldisc_flush(gsm->tty); |
| 3160 | |||
| 3161 | guard(spinlock_irqsave)(&gsm->tx_lock); | ||
| 3160 | list_for_each_entry_safe(txq, ntxq, &gsm->tx_ctrl_list, list) | 3162 | list_for_each_entry_safe(txq, ntxq, &gsm->tx_ctrl_list, list) |
| 3161 | kfree(txq); | 3163 | kfree(txq); |
| 3162 | INIT_LIST_HEAD(&gsm->tx_ctrl_list); | 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 | imx_uart_writel(sport, USR1_RTSD, USR1); | 763 | imx_uart_writel(sport, USR1_RTSD, USR1); |
| 764 | usr1 = imx_uart_readl(sport, USR1) & USR1_RTSS; | 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 | uart_handle_cts_change(&sport->port, usr1); | 780 | uart_handle_cts_change(&sport->port, usr1); |
| 766 | wake_up_interruptible(&sport->port.state->port.delta_msr_wait); | 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 | static void __qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport); | 148 | static void __qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport); |
| 149 | static void qcom_geni_serial_cancel_tx_cmd(struct uart_port *uport); | 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 | static inline struct qcom_geni_serial_port *to_dev_port(struct uart_port *uport) | 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 | writel(c, uport->membase + SE_GENI_TX_FIFOn); | 396 | writel(c, uport->membase + SE_GENI_TX_FIFOn); |
| 396 | qcom_geni_serial_poll_tx_done(uport); | 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 | #endif | 416 | #endif |
| 399 | 417 | ||
| 400 | #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE | 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 | #endif /* CONFIG_SERIAL_QCOM_GENI_CONSOLE */ | 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 | struct qcom_geni_serial_port *port = to_dev_port(uport); | 585 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
| 568 | struct tty_port *tport = &uport->state->port; | 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 | ret = tty_insert_flip_string(tport, port->rx_buf, bytes); | 589 | ret = tty_insert_flip_string(tport, port->rx_buf, bytes); |
| 572 | if (ret != bytes) { | 590 | if (ret != bytes) { |
| 573 | dev_err(uport->dev, "%s:Unable to push data ret %d_bytes %d\n", | 591 | dev_err_ratelimited(uport->dev, "failed to push data (%d < %u)\n", |
| 574 | __func__, ret, bytes); | 592 | ret, bytes); |
| 575 | WARN_ON_ONCE(1); | ||
| 576 | } | 593 | } |
| 577 | uport->icount.rx += ret; | 594 | uport->icount.rx += ret; |
| 578 | tty_flip_buffer_push(tport); | 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 | static void qcom_geni_serial_stop_rx_dma(struct uart_port *uport) | 804 | static void qcom_geni_serial_stop_rx_dma(struct uart_port *uport) |
| 788 | { | 805 | { |
| 789 | struct qcom_geni_serial_port *port = to_dev_port(uport); | 806 | struct qcom_geni_serial_port *port = to_dev_port(uport); |
| 807 | bool done; | ||
| 790 | 808 | ||
| 791 | if (!qcom_geni_serial_secondary_active(uport)) | 809 | if (!qcom_geni_serial_secondary_active(uport)) |
| 792 | return; | 810 | return; |
| 793 | 811 | ||
| 794 | geni_se_cancel_s_cmd(&port->se); | 812 | geni_se_cancel_s_cmd(&port->se); |
| 795 | qcom_geni_serial_poll_bit(uport, SE_GENI_S_IRQ_STATUS, | 813 | done = qcom_geni_serial_poll_bit(uport, SE_DMA_RX_IRQ_STAT, |
| 796 | S_CMD_CANCEL_EN, true); | 814 | RX_EOT, true); |
| 797 | 815 | if (done) { | |
| 798 | if (qcom_geni_serial_secondary_active(uport)) | 816 | writel(RX_EOT | RX_DMA_DONE, |
| 817 | uport->membase + SE_DMA_RX_IRQ_CLR); | ||
| 818 | } else { | ||
| 799 | qcom_geni_serial_abort_rx(uport); | 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 | if (port->rx_dma_addr) { | 828 | if (port->rx_dma_addr) { |
| 802 | geni_se_rx_dma_unprep(&port->se, port->rx_dma_addr, | 829 | geni_se_rx_dma_unprep(&port->se, port->rx_dma_addr, |
| 803 | DMA_RX_BUF_SIZE); | 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 | if (!drop) | 875 | if (!drop) |
| 849 | handle_rx_uart(uport, rx_in, drop); | 876 | handle_rx_uart(uport, rx_in); |
| 850 | 877 | ||
| 851 | ret = geni_se_rx_dma_prep(&port->se, port->rx_buf, | 878 | ret = geni_se_rx_dma_prep(&port->se, port->rx_buf, |
| 852 | DMA_RX_BUF_SIZE, | 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 | disable_irq(uport->irq); | 1124 | disable_irq(uport->irq); |
| 1098 | 1125 | ||
| 1126 | uart_port_lock_irq(uport); | ||
| 1099 | qcom_geni_serial_stop_tx(uport); | 1127 | qcom_geni_serial_stop_tx(uport); |
| 1100 | qcom_geni_serial_stop_rx(uport); | 1128 | qcom_geni_serial_stop_rx(uport); |
| 1101 | 1129 | ||
| 1102 | qcom_geni_serial_cancel_tx_cmd(uport); | 1130 | qcom_geni_serial_cancel_tx_cmd(uport); |
| 1131 | uart_port_unlock_irq(uport); | ||
| 1103 | } | 1132 | } |
| 1104 | 1133 | ||
| 1105 | static void qcom_geni_serial_flush_buffer(struct uart_port *uport) | 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 | false, true, true); | 1181 | false, true, true); |
| 1153 | geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2); | 1182 | geni_se_init(&port->se, UART_RX_WM, port->rx_fifo_depth - 2); |
| 1154 | geni_se_select_mode(&port->se, port->dev_data->mode); | 1183 | geni_se_select_mode(&port->se, port->dev_data->mode); |
| 1155 | qcom_geni_serial_start_rx(uport); | ||
| 1156 | port->setup = true; | 1184 | port->setup = true; |
| 1157 | 1185 | ||
| 1158 | return 0; | 1186 | return 0; |
| @@ -1168,6 +1196,11 @@ static int qcom_geni_serial_startup(struct uart_port *uport) · 9 unmodified lines | |||
| 1168 | if (ret) | 1196 | if (ret) |
| 1169 | return ret; | 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 | enable_irq(uport->irq); | 1204 | enable_irq(uport->irq); |
| 1172 | 1205 | ||
| 1173 | return 0; | 1206 | return 0; |
| @@ -1253,7 +1286,6 @@ static void qcom_geni_serial_set_termios(struct uart_port *uport, · 79 unmodified lines | |||
| 1253 | unsigned int avg_bw_core; | 1286 | unsigned int avg_bw_core; |
| 1254 | unsigned long timeout; | 1287 | unsigned long timeout; |
| 1255 | 1288 | ||
| 1256 | qcom_geni_serial_stop_rx(uport); | ||
| 1257 | /* baud rate */ | 1289 | /* baud rate */ |
| 1258 | baud = uart_get_baud_rate(uport, termios, old, 300, 4000000); | 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 | dev_err(port->se.dev, | 1301 | dev_err(port->se.dev, |
| 1270 | "Couldn't find suitable clock rate for %u\n", | 1302 | "Couldn't find suitable clock rate for %u\n", |
| 1271 | baud * sampling_rate); | 1303 | baud * sampling_rate); |
| 1272 | goto out_restart_rx; | 1304 | return; |
| 1273 | } | 1305 | } |
| 1274 | 1306 | ||
| 1275 | dev_dbg(port->se.dev, "desired_rate = %u, clk_rate = %lu, clk_div = %u\n", | 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 | writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN); | 1392 | writel(stop_bit_len, uport->membase + SE_UART_TX_STOP_BIT_LEN); |
| 1361 | writel(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG); | 1393 | writel(ser_clk_cfg, uport->membase + GENI_SER_M_CLK_CFG); |
| 1362 | writel(ser_clk_cfg, uport->membase + GENI_SER_S_CLK_CFG); | 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 | #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE | 1397 | #ifdef CONFIG_SERIAL_QCOM_GENI_CONSOLE |
| @@ -1582,7 +1612,7 @@ static const struct uart_ops qcom_geni_console_pops = { · 214 unmodified lines | |||
| 1582 | #ifdef CONFIG_CONSOLE_POLL | 1612 | #ifdef CONFIG_CONSOLE_POLL |
| 1583 | .poll_get_char = qcom_geni_serial_get_char, | 1613 | .poll_get_char = qcom_geni_serial_get_char, |
| 1584 | .poll_put_char = qcom_geni_serial_poll_put_char, | 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 | #endif | 1616 | #endif |
| 1587 | .pm = qcom_geni_serial_pm, | 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 | uart_remove_one_port(drv, &port->uport); | 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 | struct qcom_geni_serial_port *port = dev_get_drvdata(dev); | 1784 | struct qcom_geni_serial_port *port = dev_get_drvdata(dev); |
| 1755 | struct uart_port *uport = &port->uport; | 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 | return uart_suspend_port(private_data->drv, uport); | 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 | int ret; | 1801 | int ret; |
| 1772 | struct qcom_geni_serial_port *port = dev_get_drvdata(dev); | 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 | return ret; | 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 | static const struct qcom_geni_device_data qcom_geni_console_data = { | 1814 | static const struct qcom_geni_device_data qcom_geni_console_data = { |
| 1817 | .console = true, | 1815 | .console = true, |
| 1818 | .mode = GENI_SE_FIFO, | 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 | static const struct dev_pm_ops qcom_geni_serial_pm_ops = { | 1824 | static const struct dev_pm_ops qcom_geni_serial_pm_ops = { |
| 1827 | .suspend = pm_sleep_ptr(qcom_geni_serial_sys_suspend), | 1825 | SYSTEM_SLEEP_PM_OPS(qcom_geni_serial_suspend, qcom_geni_serial_resume) |
| 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), | ||
| 1833 | }; | 1826 | }; |
| 1834 | 1827 | ||
| 1835 | static const struct of_device_id qcom_geni_serial_match_table[] = { | 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 | return -EINVAL; | 4726 | return -EINVAL; |
| 4727 | 4727 | ||
| 4728 | if (op->data) { | 4728 | if (op->data) { |
| 4729 | font.data = kvmalloc(max_font_size, GFP_KERNEL); | 4729 | font.data = kvzalloc(max_font_size, GFP_KERNEL); |
| 4730 | if (!font.data) | 4730 | if (!font.data) |
| 4731 | return -ENOMEM; | 4731 | return -ENOMEM; |
| 4732 | } else | 4732 | } else |
| @@ -539,7 +539,7 @@ int ufshcd_mcq_sq_cleanup(struct ufs_hba *hba, int task_tag) · 538 unmodified lines | |||
| 539 | struct scsi_cmnd *cmd = lrbp->cmd; | 539 | struct scsi_cmnd *cmd = lrbp->cmd; |
| 540 | struct ufs_hw_queue *hwq; | 540 | struct ufs_hw_queue *hwq; |
| 541 | void __iomem *reg, *opr_sqd_base; | 541 | void __iomem *reg, *opr_sqd_base; |
| 542 | u32 nexus, id, val; | 542 | u32 nexus, id, val, rtc; |
| 543 | int err; | 543 | int err; |
| 544 | 544 | ||
| 545 | if (hba->quirks & UFSHCD_QUIRK_MCQ_BROKEN_RTC) | 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 | opr_sqd_base = mcq_opr_base(hba, OPR_SQD, id); | 569 | opr_sqd_base = mcq_opr_base(hba, OPR_SQD, id); |
| 570 | writel(nexus, opr_sqd_base + REG_SQCTI); | 570 | writel(nexus, opr_sqd_base + REG_SQCTI); |
| 571 | 571 | ||
| 572 | /* SQRTCy.ICU = 1 */ | 572 | /* Initiate Cleanup */ |
| 573 | writel(SQ_ICU, opr_sqd_base + REG_SQRTC); | 573 | writel(readl(opr_sqd_base + REG_SQRTC) | SQ_ICU, |
| 574 | opr_sqd_base + REG_SQRTC); | ||
| 574 | 575 | ||
| 575 | /* Poll SQRTSy.CUS = 1. Return result from SQRTSy.RTC */ | 576 | /* Poll SQRTSy.CUS = 1. Return result from SQRTSy.RTC */ |
| 576 | reg = opr_sqd_base + REG_SQRTS; | 577 | reg = opr_sqd_base + REG_SQRTS; |
| 577 | err = read_poll_timeout(readl, val, val & SQ_CUS, 20, | 578 | err = read_poll_timeout(readl, val, val & SQ_CUS, 20, |
| 578 | MCQ_POLL_US, false, reg); | 579 | MCQ_POLL_US, false, reg); |
| 579 | if (err) | 580 | rtc = FIELD_GET(SQ_ICU_ERR_CODE_MASK, readl(reg)); |
| 580 | dev_err(hba->dev, "%s: failed. hwq=%d, tag=%d err=%ld\n", | 581 | if (err || rtc) |
| 581 | __func__, id, task_tag, | 582 | dev_err(hba->dev, "%s: failed. hwq=%d, tag=%d err=%d RTC=%d\n", |
| 582 | FIELD_GET(SQ_ICU_ERR_CODE_MASK, readl(reg))); | 583 | __func__, id, task_tag, err, rtc); |
| 583 | 584 | ||
| 584 | if (ufshcd_mcq_sq_start(hba, hwq)) | 585 | if (ufshcd_mcq_sq_start(hba, hwq)) |
| 585 | err = -ETIMEDOUT; | 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 | struct utp_transfer_req_desc *utrdlp = hba->utrdl_base_addr; | 2933 | struct utp_transfer_req_desc *utrdlp = hba->utrdl_base_addr; |
| 2934 | dma_addr_t cmd_desc_element_addr = hba->ucdl_dma_addr + | 2934 | dma_addr_t cmd_desc_element_addr = hba->ucdl_dma_addr + |
| 2935 | i * ufshcd_get_ucd_size(hba); | 2935 | i * ufshcd_get_ucd_size(hba); |
| 2936 | u16 response_offset = offsetof(struct utp_transfer_cmd_desc, | 2936 | u16 response_offset = le16_to_cpu(utrdlp[i].response_upiu_offset); |
| 2937 | response_upiu); | 2937 | u16 prdt_offset = le16_to_cpu(utrdlp[i].prd_table_offset); |
| 2938 | u16 prdt_offset = offsetof(struct utp_transfer_cmd_desc, prd_table); | ||
| 2939 | 2938 | ||
| 2940 | lrb->utr_descriptor_ptr = utrdlp + i; | 2939 | lrb->utr_descriptor_ptr = utrdlp + i; |
| 2941 | lrb->utrd_dma_addr = hba->utrdl_dma_addr + | 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 | break; | 5417 | break; |
| 5419 | case OCS_ABORTED: | 5418 | case OCS_ABORTED: |
| 5420 | result |= DID_ABORT << 16; | ||
| 5421 | break; | ||
| 5422 | case OCS_INVALID_COMMAND_STATUS: | 5419 | case OCS_INVALID_COMMAND_STATUS: |
| 5423 | result |= DID_REQUEUE << 16; | 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 | break; | 5425 | break; |
| 5425 | case OCS_INVALID_CMD_TABLE_ATTR: | 5426 | case OCS_INVALID_CMD_TABLE_ATTR: |
| 5426 | case OCS_INVALID_PRDT_ATTR: | 5427 | case OCS_INVALID_PRDT_ATTR: |
| @@ -6466,26 +6467,12 @@ static bool ufshcd_abort_one(struct request *rq, void *priv) · 1039 unmodified lines | |||
| 6466 | struct scsi_device *sdev = cmd->device; | 6467 | struct scsi_device *sdev = cmd->device; |
| 6467 | struct Scsi_Host *shost = sdev->host; | 6468 | struct Scsi_Host *shost = sdev->host; |
| 6468 | struct ufs_hba *hba = shost_priv(shost); | 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 | *ret = ufshcd_try_to_abort_task(hba, tag); | 6471 | *ret = ufshcd_try_to_abort_task(hba, tag); |
| 6474 | dev_err(hba->dev, "Aborting tag %d / CDB %#02x %s\n", tag, | 6472 | dev_err(hba->dev, "Aborting tag %d / CDB %#02x %s\n", tag, |
| 6475 | hba->lrb[tag].cmd ? hba->lrb[tag].cmd->cmnd[0] : -1, | 6473 | hba->lrb[tag].cmd ? hba->lrb[tag].cmd->cmnd[0] : -1, |
| 6476 | *ret ? "failed" : "succeeded"); | 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 | return *ret == 0; | 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 | err = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, QUERY_ATTR_IDN_SECONDS_PASSED, | 8220 | err = ufshcd_query_attr(hba, UPIU_QUERY_OPCODE_WRITE_ATTR, QUERY_ATTR_IDN_SECONDS_PASSED, |
| 8234 | 0, 0, &val); | 8221 | 0, 0, &val); |
| 8235 | ufshcd_rpm_put_sync(hba); | 8222 | ufshcd_rpm_put(hba); |
| 8236 | 8223 | ||
| 8237 | if (err) | 8224 | if (err) |
| 8238 | dev_err(hba->dev, "%s: Failed to update rtc %d\n", __func__, err); | 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 | shost_for_each_device(sdev, hba->host) { | 10197 | shost_for_each_device(sdev, hba->host) { |
| 10211 | if (sdev == hba->ufs_device_wlun) | 10198 | if (sdev == hba->ufs_device_wlun) |
| 10212 | continue; | 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 | __ufshcd_wl_suspend(hba, UFS_SHUTDOWN_PM); | 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 | struct fwnode_handle *nhi_fwnode __free(fwnode_handle) = | 170 | struct fwnode_handle *nhi_fwnode __free(fwnode_handle) = |
| 171 | fwnode_find_reference(dev_fwnode(&port_dev->dev), "usb4-host-interface", 0); | 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 | return 0; | 174 | return 0; |
| 175 | 175 | ||
| 176 | link = device_link_add(&port_dev->child->dev, nhi_fwnode->dev, | 176 | link = device_link_add(&port_dev->child->dev, nhi_fwnode->dev, |
| 177 | DL_FLAG_AUTOREMOVE_CONSUMER | | 177 | DL_FLAG_STATELESS | |
| 178 | DL_FLAG_RPM_ACTIVE | | 178 | DL_FLAG_RPM_ACTIVE | |
| 179 | DL_FLAG_PM_RUNTIME); | 179 | DL_FLAG_PM_RUNTIME); |
| 180 | if (!link) { | 180 | if (!link) { |
| @@ -23,7 +23,6 @@ static void dwc2_set_bcm_params(struct dwc2_hsotg *hsotg) · 22 unmodified lines | |||
| 23 | p->max_transfer_size = 65535; | 23 | p->max_transfer_size = 65535; |
| 24 | p->max_packet_count = 511; | 24 | p->max_packet_count = 511; |
| 25 | p->ahbcfg = 0x10; | 25 | p->ahbcfg = 0x10; |
| 26 | p->no_clock_gating = true; | ||
| 27 | } | 26 | } |
| 28 | 27 | ||
| 29 | static void dwc2_set_his_params(struct dwc2_hsotg *hsotg) | 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 | int dwc3_event_buffers_setup(struct dwc3 *dwc) | 544 | int dwc3_event_buffers_setup(struct dwc3 *dwc) |
| 545 | { | 545 | { |
| 546 | struct dwc3_event_buffer *evt; | 546 | struct dwc3_event_buffer *evt; |
| 547 | u32 reg; | ||
| 547 | 548 | ||
| 548 | if (!dwc->ev_buf) | 549 | if (!dwc->ev_buf) |
| 549 | return 0; | 550 | return 0; |
| @@ -556,8 +557,10 @@ int dwc3_event_buffers_setup(struct dwc3 *dwc) · 6 unmodified lines | |||
| 556 | upper_32_bits(evt->dma)); | 557 | upper_32_bits(evt->dma)); |
| 557 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), | 558 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), |
| 558 | DWC3_GEVNTSIZ_SIZE(evt->length)); | 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 | return 0; | 564 | return 0; |
| 562 | } | 565 | } |
| 563 | 566 | ||
| @@ -584,7 +587,10 @@ void dwc3_event_buffers_cleanup(struct dwc3 *dwc) · 20 unmodified lines | |||
| 584 | dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0); | 587 | dwc3_writel(dwc->regs, DWC3_GEVNTADRHI(0), 0); |
| 585 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK | 588 | dwc3_writel(dwc->regs, DWC3_GEVNTSIZ(0), DWC3_GEVNTSIZ_INTMASK |
| 586 | | DWC3_GEVNTSIZ_SIZE(0)); | 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 | static void dwc3_core_num_eps(struct dwc3 *dwc) | 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 | u32 reg; | 2342 | u32 reg; |
| 2337 | int i; | 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 | switch (dwc->current_dr_role) { | 2350 | switch (dwc->current_dr_role) { |
| 2340 | case DWC3_GCTL_PRTCAP_DEVICE: | 2351 | case DWC3_GCTL_PRTCAP_DEVICE: |
| 2341 | if (pm_runtime_suspended(dwc->dev)) | 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 | break; | 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 | return 0; | 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 | break; | 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 | return 0; | 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 | switch (dwc->current_dr_role) { | 2525 | switch (dwc->current_dr_role) { |
| 2501 | case DWC3_GCTL_PRTCAP_DEVICE: | 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 | break; | 2532 | break; |
| 2504 | case DWC3_GCTL_PRTCAP_HOST: | 2533 | case DWC3_GCTL_PRTCAP_HOST: |
| 2505 | default: | 2534 | default: |
| @@ -2552,7 +2581,7 @@ static int dwc3_suspend(struct device *dev) · 46 unmodified lines | |||
| 2552 | static int dwc3_resume(struct device *dev) | 2581 | static int dwc3_resume(struct device *dev) |
| 2553 | { | 2582 | { |
| 2554 | struct dwc3 *dwc = dev_get_drvdata(dev); | 2583 | struct dwc3 *dwc = dev_get_drvdata(dev); |
| 2555 | int ret; | 2584 | int ret = 0; |
| 2556 | 2585 | ||
| 2557 | pinctrl_pm_select_default_state(dev); | 2586 | pinctrl_pm_select_default_state(dev); |
| 2558 | 2587 | ||
| @@ -2560,14 +2589,12 @@ static int dwc3_resume(struct device *dev) · 1 unmodified line | |||
| 2560 | pm_runtime_set_active(dev); | 2589 | pm_runtime_set_active(dev); |
| 2561 | 2590 | ||
| 2562 | ret = dwc3_resume_common(dwc, PMSG_RESUME); | 2591 | ret = dwc3_resume_common(dwc, PMSG_RESUME); |
| 2563 | if (ret) { | 2592 | if (ret) |
| 2564 | pm_runtime_set_suspended(dev); | 2593 | pm_runtime_set_suspended(dev); |
| 2565 | return ret; | ||
| 2566 | } | ||
| 2567 | 2594 | ||
| 2568 | pm_runtime_enable(dev); | 2595 | pm_runtime_enable(dev); |
| 2569 | 2596 | ||
| 2570 | return 0; | 2597 | return ret; |
| 2571 | } | 2598 | } |
| 2572 | 2599 | ||
| 2573 | static void dwc3_complete(struct device *dev) | 2600 | static void dwc3_complete(struct device *dev) |
| @@ -2589,6 +2616,12 @@ static void dwc3_complete(struct device *dev) · 15 unmodified lines | |||
| 2589 | static const struct dev_pm_ops dwc3_dev_pm_ops = { | 2616 | static const struct dev_pm_ops dwc3_dev_pm_ops = { |
| 2590 | SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume) | 2617 | SET_SYSTEM_SLEEP_PM_OPS(dwc3_suspend, dwc3_resume) |
| 2591 | .complete = dwc3_complete, | 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 | SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume, | 2625 | SET_RUNTIME_PM_OPS(dwc3_runtime_suspend, dwc3_runtime_resume, |
| 2593 | dwc3_runtime_idle) | 2626 | dwc3_runtime_idle) |
| 2594 | }; | 2627 | }; |
| @@ -1150,6 +1150,8 @@ struct dwc3_scratchpad_array { · 1149 unmodified lines | |||
| 1150 | * @sys_wakeup: set if the device may do system wakeup. | 1150 | * @sys_wakeup: set if the device may do system wakeup. |
| 1151 | * @wakeup_configured: set if the device is configured for remote wakeup. | 1151 | * @wakeup_configured: set if the device is configured for remote wakeup. |
| 1152 | * @suspended: set to track suspend event due to U3/L2. | 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 | * @imod_interval: set the interrupt moderation interval in 250ns | 1155 | * @imod_interval: set the interrupt moderation interval in 250ns |
| 1154 | * increments or 0 to disable. | 1156 | * increments or 0 to disable. |
| 1155 | * @max_cfg_eps: current max number of IN eps used across all USB configs. | 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 | unsigned sys_wakeup:1; | 1384 | unsigned sys_wakeup:1; |
| 1383 | unsigned wakeup_configured:1; | 1385 | unsigned wakeup_configured:1; |
| 1384 | unsigned suspended:1; | 1386 | unsigned suspended:1; |
| 1387 | unsigned susphy_state:1; | ||
| 1385 | 1388 | ||
| 1386 | u16 imod_interval; | 1389 | u16 imod_interval; |
| 1387 | 1390 | ||
| @@ -1675,7 +1678,6 @@ static inline void dwc3_otg_host_init(struct dwc3 *dwc) · 287 unmodified lines | |||
| 1675 | #if !IS_ENABLED(CONFIG_USB_DWC3_HOST) | 1678 | #if !IS_ENABLED(CONFIG_USB_DWC3_HOST) |
| 1676 | int dwc3_gadget_suspend(struct dwc3 *dwc); | 1679 | int dwc3_gadget_suspend(struct dwc3 *dwc); |
| 1677 | int dwc3_gadget_resume(struct dwc3 *dwc); | 1680 | int dwc3_gadget_resume(struct dwc3 *dwc); |
| 1678 | void dwc3_gadget_process_pending_events(struct dwc3 *dwc); | ||
| 1679 | #else | 1681 | #else |
| 1680 | static inline int dwc3_gadget_suspend(struct dwc3 *dwc) | 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 | return 0; | 1689 | return 0; |
| 1688 | } | 1690 | } |
| 1689 | 1691 | ||
| 1690 | static inline void dwc3_gadget_process_pending_events(struct dwc3 *dwc) | ||
| 1691 | { | ||
| 1692 | } | ||
| 1693 | #endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */ | 1692 | #endif /* !IS_ENABLED(CONFIG_USB_DWC3_HOST) */ |
| 1694 | 1693 | ||
| 1695 | #if IS_ENABLED(CONFIG_USB_DWC3_ULPI) | 1694 | #if IS_ENABLED(CONFIG_USB_DWC3_ULPI) |
| @@ -438,6 +438,10 @@ skip_status: · 437 unmodified lines | |||
| 438 | dwc3_gadget_ep_get_transfer_index(dep); | 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 | if (saved_config) { | 445 | if (saved_config) { |
| 442 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); | 446 | reg = dwc3_readl(dwc->regs, DWC3_GUSB2PHYCFG(0)); |
| 443 | reg |= saved_config; | 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 | WARN_ON_ONCE(ret); | 1719 | WARN_ON_ONCE(ret); |
| 1716 | dep->resource_index = 0; | 1720 | dep->resource_index = 0; |
| 1717 | 1721 | ||
| 1718 | if (!interrupt) { | 1722 | if (!interrupt) |
| 1719 | mdelay(1); | ||
| 1720 | dep->flags &= ~DWC3_EP_TRANSFER_STARTED; | 1723 | dep->flags &= ~DWC3_EP_TRANSFER_STARTED; |
| 1721 | } else if (!ret) { | 1724 | else if (!ret) |
| 1722 | dep->flags |= DWC3_EP_END_TRANSFER_PENDING; | 1725 | dep->flags |= DWC3_EP_END_TRANSFER_PENDING; |
| 1723 | } | ||
| 1724 | 1726 | ||
| 1725 | dep->flags &= ~DWC3_EP_DELAY_STOP; | 1727 | dep->flags &= ~DWC3_EP_DELAY_STOP; |
| 1726 | return ret; | 1728 | return ret; |
| @@ -4728,14 +4730,3 @@ int dwc3_gadget_resume(struct dwc3 *dwc) · 3001 unmodified lines | |||
| 4728 | 4730 | ||
| 4729 | return dwc3_gadget_soft_connect(dwc); | 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 | const char *page, size_t len) \ | 2061 | const char *page, size_t len) \ |
| 2062 | { \ | 2062 | { \ |
| 2063 | struct f_uac2_opts *opts = to_f_uac2_opts(item); \ | 2063 | struct f_uac2_opts *opts = to_f_uac2_opts(item); \ |
| 2064 | int ret = 0; \ | 2064 | int ret = len; \ |
| 2065 | \ | 2065 | \ |
| 2066 | mutex_lock(&opts->lock); \ | 2066 | mutex_lock(&opts->lock); \ |
| 2067 | if (opts->refcnt) { \ | 2067 | if (opts->refcnt) { \ |
| @@ -2072,8 +2072,8 @@ static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \ · 4 unmodified lines | |||
| 2072 | if (len && page[len - 1] == '\n') \ | 2072 | if (len && page[len - 1] == '\n') \ |
| 2073 | len--; \ | 2073 | len--; \ |
| 2074 | \ | 2074 | \ |
| 2075 | ret = scnprintf(opts->name, min(sizeof(opts->name), len + 1), \ | 2075 | scnprintf(opts->name, min(sizeof(opts->name), len + 1), \ |
| 2076 | "%s", page); \ | 2076 | "%s", page); \ |
| 2077 | \ | 2077 | \ |
| 2078 | end: \ | 2078 | end: \ |
| 2079 | mutex_unlock(&opts->lock); \ | 2079 | mutex_unlock(&opts->lock); \ |
| @@ -1696,6 +1696,7 @@ int usb_gadget_register_driver_owner(struct usb_gadget_driver *driver, · 1695 unmodified lines | |||
| 1696 | driver->driver.bus = &gadget_bus_type; | 1696 | driver->driver.bus = &gadget_bus_type; |
| 1697 | driver->driver.owner = owner; | 1697 | driver->driver.owner = owner; |
| 1698 | driver->driver.mod_name = mod_name; | 1698 | driver->driver.mod_name = mod_name; |
| 1699 | driver->driver.probe_type = PROBE_FORCE_SYNCHRONOUS; | ||
| 1699 | ret = driver_register(&driver->driver); | 1700 | ret = driver_register(&driver->driver); |
| 1700 | if (ret) { | 1701 | if (ret) { |
| 1701 | pr_warn("%s: driver registration failed: %d\n", | 1702 | pr_warn("%s: driver registration failed: %d\n", |
| @@ -254,6 +254,7 @@ struct dummy_hcd { · 253 unmodified lines | |||
| 254 | u32 stream_en_ep; | 254 | u32 stream_en_ep; |
| 255 | u8 num_stream[30 / 2]; | 255 | u8 num_stream[30 / 2]; |
| 256 | 256 | ||
| 257 | unsigned timer_pending:1; | ||
| 257 | unsigned active:1; | 258 | unsigned active:1; |
| 258 | unsigned old_active:1; | 259 | unsigned old_active:1; |
| 259 | unsigned resuming:1; | 260 | unsigned resuming:1; |
| @@ -1303,9 +1304,11 @@ static int dummy_urb_enqueue( · 1043 unmodified lines | |||
| 1303 | urb->error_count = 1; /* mark as a new urb */ | 1304 | urb->error_count = 1; /* mark as a new urb */ |
| 1304 | 1305 | ||
| 1305 | /* kick the scheduler, it'll do the rest */ | 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 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), | 1309 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), |
| 1308 | HRTIMER_MODE_REL_SOFT); | 1310 | HRTIMER_MODE_REL_SOFT); |
| 1311 | } | ||
| 1309 | 1312 | ||
| 1310 | done: | 1313 | done: |
| 1311 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); | 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 | spin_lock_irqsave(&dum_hcd->dum->lock, flags); | 1327 | spin_lock_irqsave(&dum_hcd->dum->lock, flags); |
| 1325 | 1328 | ||
| 1326 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); | 1329 | rc = usb_hcd_check_unlink_urb(hcd, urb, status); |
| 1327 | if (!rc && dum_hcd->rh_state != DUMMY_RH_RUNNING && | 1330 | if (rc == 0 && !dum_hcd->timer_pending) { |
| 1328 | !list_empty(&dum_hcd->urbp_list)) | 1331 | dum_hcd->timer_pending = 1; |
| 1329 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); | 1332 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); |
| 1333 | } | ||
| 1330 | 1334 | ||
| 1331 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); | 1335 | spin_unlock_irqrestore(&dum_hcd->dum->lock, flags); |
| 1332 | return rc; | 1336 | return rc; |
| @@ -1813,6 +1817,7 @@ static enum hrtimer_restart dummy_timer(struct hrtimer *t) · 480 unmodified lines | |||
| 1813 | 1817 | ||
| 1814 | /* look at each urb queued by the host side driver */ | 1818 | /* look at each urb queued by the host side driver */ |
| 1815 | spin_lock_irqsave(&dum->lock, flags); | 1819 | spin_lock_irqsave(&dum->lock, flags); |
| 1820 | dum_hcd->timer_pending = 0; | ||
| 1816 | 1821 | ||
| 1817 | if (!dum_hcd->udev) { | 1822 | if (!dum_hcd->udev) { |
| 1818 | dev_err(dummy_dev(dum_hcd), | 1823 | dev_err(dummy_dev(dum_hcd), |
| @@ -1994,8 +1999,10 @@ return_urb: · 175 unmodified lines | |||
| 1994 | if (list_empty(&dum_hcd->urbp_list)) { | 1999 | if (list_empty(&dum_hcd->urbp_list)) { |
| 1995 | usb_put_dev(dum_hcd->udev); | 2000 | usb_put_dev(dum_hcd->udev); |
| 1996 | dum_hcd->udev = NULL; | 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 | /* want a 1 msec delay here */ | 2004 | /* want a 1 msec delay here */ |
| 2005 | dum_hcd->timer_pending = 1; | ||
| 1999 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), | 2006 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(DUMMY_TIMER_INT_NSECS), |
| 2000 | HRTIMER_MODE_REL_SOFT); | 2007 | HRTIMER_MODE_REL_SOFT); |
| 2001 | } | 2008 | } |
| @@ -2390,8 +2397,10 @@ static int dummy_bus_resume(struct usb_hcd *hcd) · 388 unmodified lines | |||
| 2390 | } else { | 2397 | } else { |
| 2391 | dum_hcd->rh_state = DUMMY_RH_RUNNING; | 2398 | dum_hcd->rh_state = DUMMY_RH_RUNNING; |
| 2392 | set_link_state(dum_hcd); | 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 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); | 2402 | hrtimer_start(&dum_hcd->timer, ns_to_ktime(0), HRTIMER_MODE_REL_SOFT); |
| 2403 | } | ||
| 2395 | hcd->state = HC_STATE_RUNNING; | 2404 | hcd->state = HC_STATE_RUNNING; |
| 2396 | } | 2405 | } |
| 2397 | spin_unlock_irq(&dum_hcd->dum->lock); | 2406 | spin_unlock_irq(&dum_hcd->dum->lock); |
| @@ -2522,6 +2531,7 @@ static void dummy_stop(struct usb_hcd *hcd) · 124 unmodified lines | |||
| 2522 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); | 2531 | struct dummy_hcd *dum_hcd = hcd_to_dummy_hcd(hcd); |
| 2523 | 2532 | ||
| 2524 | hrtimer_cancel(&dum_hcd->timer); | 2533 | hrtimer_cancel(&dum_hcd->timer); |
| 2534 | dum_hcd->timer_pending = 0; | ||
| 2525 | device_remove_file(dummy_dev(dum_hcd), &dev_attr_urbs); | 2535 | device_remove_file(dummy_dev(dum_hcd), &dev_attr_urbs); |
| 2526 | dev_info(dummy_dev(dum_hcd), "stopped\n"); | 2536 | dev_info(dummy_dev(dum_hcd), "stopped\n"); |
| 2527 | } | 2537 | } |
| @@ -110,6 +110,7 @@ struct dbc_port { · 109 unmodified lines | |||
| 110 | struct tasklet_struct push; | 110 | struct tasklet_struct push; |
| 111 | 111 | ||
| 112 | struct list_head write_pool; | 112 | struct list_head write_pool; |
| 113 | unsigned int tx_boundary; | ||
| 113 | 114 | ||
| 114 | bool registered; | 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 | return dbc->priv; | 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 | static int dbc_start_tx(struct dbc_port *port) | 50 | static int dbc_start_tx(struct dbc_port *port) |
| 28 | __releases(&port->port_lock) | 51 | __releases(&port->port_lock) |
| 29 | __acquires(&port->port_lock) | 52 | __acquires(&port->port_lock) |
| @@ -36,7 +59,7 @@ static int dbc_start_tx(struct dbc_port *port) · 6 unmodified lines | |||
| 36 | 59 | ||
| 37 | while (!list_empty(pool)) { | 60 | while (!list_empty(pool)) { |
| 38 | req = list_entry(pool->next, struct dbc_request, list_pool); | 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 | if (len == 0) | 63 | if (len == 0) |
| 41 | break; | 64 | break; |
| 42 | do_tty_wake = true; | 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 | struct dbc_port *port = tty->driver_data; | 224 | struct dbc_port *port = tty->driver_data; |
| 202 | unsigned long flags; | 225 | unsigned long flags; |
| 226 | unsigned int written = 0; | ||
| 203 | 227 | ||
| 204 | spin_lock_irqsave(&port->port_lock, flags); | 228 | spin_lock_irqsave(&port->port_lock, flags); |
| 205 | if (count) | 229 | |
| 206 | count = kfifo_in(&port->port.xmit_fifo, buf, count); | 230 | /* |
| 207 | dbc_start_tx(port); | 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 | spin_unlock_irqrestore(&port->port_lock, flags); | 249 | spin_unlock_irqrestore(&port->port_lock, flags); |
| 209 | 250 | ||
| 210 | return count; | 251 | return written; |
| 211 | } | 252 | } |
| 212 | 253 | ||
| 213 | static int dbc_tty_put_char(struct tty_struct *tty, u8 ch) | 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 | spin_lock_irqsave(&port->port_lock, flags); | 283 | spin_lock_irqsave(&port->port_lock, flags); |
| 243 | room = kfifo_avail(&port->port.xmit_fifo); | 284 | room = kfifo_avail(&port->port.xmit_fifo); |
| 285 | |||
| 286 | if (port->tx_boundary) | ||
| 287 | room = 0; | ||
| 288 | |||
| 244 | spin_unlock_irqrestore(&port->port_lock, flags); | 289 | spin_unlock_irqrestore(&port->port_lock, flags); |
| 245 | 290 | ||
| 246 | return room; | 291 | return room; |
| @@ -79,6 +79,7 @@ · 78 unmodified lines | |||
| 79 | #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 | 79 | #define PCI_DEVICE_ID_ASMEDIA_1042A_XHCI 0x1142 |
| 80 | #define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242 | 80 | #define PCI_DEVICE_ID_ASMEDIA_1142_XHCI 0x1242 |
| 81 | #define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142 | 81 | #define PCI_DEVICE_ID_ASMEDIA_2142_XHCI 0x2142 |
| 82 | #define PCI_DEVICE_ID_ASMEDIA_3042_XHCI 0x3042 | ||
| 82 | #define PCI_DEVICE_ID_ASMEDIA_3242_XHCI 0x3242 | 83 | #define PCI_DEVICE_ID_ASMEDIA_3242_XHCI 0x3242 |
| 83 | 84 | ||
| 84 | #define PCI_DEVICE_ID_CADENCE 0x17CD | 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 | pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) | 452 | pdev->device == PCI_DEVICE_ID_ASMEDIA_1042A_XHCI) |
| 452 | xhci->quirks |= XHCI_ASMEDIA_MODIFY_FLOWCONTROL; | 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 | if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241) | 459 | if (pdev->vendor == PCI_VENDOR_ID_TI && pdev->device == 0x8241) |
| 455 | xhci->quirks |= XHCI_LIMIT_ENDPOINT_INTERVAL_7; | 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 | pm_runtime_put_noidle(&dev->dev); | 640 | pm_runtime_put_noidle(&dev->dev); |
| 636 | 641 | ||
| 637 | if (pci_choose_state(dev, PMSG_SUSPEND) == PCI_D0) | 642 | if (pci_choose_state(dev, PMSG_SUSPEND) == PCI_D0) |
| 638 | pm_runtime_forbid(&dev->dev); | 643 | pm_runtime_get(&dev->dev); |
| 639 | else if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW) | 644 | else if (xhci->quirks & XHCI_DEFAULT_PM_RUNTIME_ALLOW) |
| 640 | pm_runtime_allow(&dev->dev); | 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 | xhci->xhc_state |= XHCI_STATE_REMOVING; | 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 | pm_runtime_forbid(&dev->dev); | 689 | pm_runtime_forbid(&dev->dev); |
| 683 | 690 | ||
| 684 | if (xhci->shared_hcd) { | 691 | if (xhci->shared_hcd) { |
| @@ -1023,7 +1023,7 @@ static int xhci_invalidate_cancelled_tds(struct xhci_virt_ep *ep) · 1022 unmodified lines | |||
| 1023 | td_to_noop(xhci, ring, cached_td, false); | 1023 | td_to_noop(xhci, ring, cached_td, false); |
| 1024 | cached_td->cancel_status = TD_CLEARED; | 1024 | cached_td->cancel_status = TD_CLEARED; |
| 1025 | } | 1025 | } |
| 1026 | 1026 | td_to_noop(xhci, ring, td, false); | |
| 1027 | td->cancel_status = TD_CLEARING_CACHE; | 1027 | td->cancel_status = TD_CLEARING_CACHE; |
| 1028 | cached_td = td; | 1028 | cached_td = td; |
| 1029 | break; | 1029 | break; |
| @@ -1718,6 +1718,14 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, · 688 unmodified lines | |||
| 1718 | 1718 | ||
| 1719 | trace_xhci_handle_command(xhci->cmd_ring, &cmd_trb->generic); | 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 | cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, | 1729 | cmd_dequeue_dma = xhci_trb_virt_to_dma(xhci->cmd_ring->deq_seg, |
| 1722 | cmd_trb); | 1730 | cmd_trb); |
| 1723 | /* | 1731 | /* |
| @@ -1734,14 +1742,6 @@ static void handle_cmd_completion(struct xhci_hcd *xhci, · 10 unmodified lines | |||
| 1734 | 1742 | ||
| 1735 | cancel_delayed_work(&xhci->cmd_timer); | 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 | if (cmd->command_trb != xhci->cmd_ring->dequeue) { | 1745 | if (cmd->command_trb != xhci->cmd_ring->dequeue) { |
| 1746 | xhci_err(xhci, | 1746 | xhci_err(xhci, |
| 1747 | "Command completion event does not match command\n"); | 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 | return 0; | 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 | if (list_empty(&ep_ring->td_list)) { | 2801 | if (list_empty(&ep_ring->td_list)) { |
| 2779 | /* | 2802 | /* |
| 2780 | * Don't print wanings if ring is empty due to a stopped endpoint generating an | 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 | return 0; | 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.